From bacd5fac165346eb0fe09b906cc409738cffb58d Mon Sep 17 00:00:00 2001 From: "guangshu.wgs" Date: Mon, 20 Mar 2023 11:58:02 +0800 Subject: [PATCH] =?UTF-8?q?New=20features=201.=20Support=20for=20multiple-?= =?UTF-8?q?cluster=20Proxyro=20passwords=202.=20Support=20for=20rich=20cli?= =?UTF-8?q?ent=20capabilities=203.=20Support=20for=20specifying=20Server?= =?UTF-8?q?=20IP=20routing=204.=20Support=20for=20the=20Latin1=20character?= =?UTF-8?q?=20set=205.=20Support=20for=20transparently=20passing=20connect?= =?UTF-8?q?ion=20attributes=20with=20special=20prefixes=206.=20Support=20f?= =?UTF-8?q?or=20distributed=20transaction=20routing=207.=20Support=20for?= =?UTF-8?q?=20MySQL=20binlog=208.=20Support=20for=20read-write=20separatio?= =?UTF-8?q?n=20and=20transaction=20splitting=209.=20Support=20for=20mappin?= =?UTF-8?q?g=20VIPs=20to=20Cluster/Tenant=20through=20means=20other=20than?= =?UTF-8?q?=20MetaDB=2010.=20Support=20for=20global-level=20weak-read=20an?= =?UTF-8?q?d=20read-only=20configuration=20parameters=2011.=20Support=20fo?= =?UTF-8?q?r=20GIS,=20JSON=20data=20types=2012.=20Support=20for=20IPv6=201?= =?UTF-8?q?3.=20Support=20for=20accurately=20routing=20access=20to=20the?= =?UTF-8?q?=20sys=20tenant=20OceanBase=20library=20in=20QA=20Mode=2014.=20?= =?UTF-8?q?Support=20for=20ROWID=20routing=20under=20PS=2015.=20Support=20?= =?UTF-8?q?for=20multi-column=20partition=20key=20routing=2016.=20Support?= =?UTF-8?q?=20for=20obtaining=20column=20default=20value=20routing=2017.?= =?UTF-8?q?=20Support=20for=20calculating=20expressions=20such=20as=20nvl,?= =?UTF-8?q?=20sysdate,=20mod,=20=20to=5Fchar,=20and=20substr=2018.=20Suppo?= =?UTF-8?q?rt=20for=20is=20null=20and=20is=20not=20null=20routing=2019.=20?= =?UTF-8?q?Support=20for=20XA=20Start=20statement=20hold=2020.=20=E3=80=90?= =?UTF-8?q?OB=20Sharding=E3=80=91Support=20for=20rolling=20upgrades=2021.?= =?UTF-8?q?=20=E3=80=90OB=20Sharding=E3=80=91Support=20for=20SHOW=20TOPOLO?= =?UTF-8?q?GY=20syntax=2022.=20=E3=80=90OB=20Sharding=E3=80=91Added=20hint?= =?UTF-8?q?=20support=20for=20session=20stickiness:=20route=20to=20the=20p?= =?UTF-8?q?revious=20non-scan-all=20statement=20shard=2023.=20=E3=80=90OB?= =?UTF-8?q?=20Sharding=E3=80=91Support=20for=20information=5Fschema.partit?= =?UTF-8?q?ions=20and=20information=5Fschema.coulmns=2024.=20=E3=80=90OB?= =?UTF-8?q?=20Sharding=E3=80=91Support=20for=20SQL-level=20timeout=20contr?= =?UTF-8?q?ol=2025.=20=E3=80=90OB=20Sharding=E3=80=91Single-shard=20suppor?= =?UTF-8?q?t=20for=20SQL=20syntax:=20batch=20update,=20batch=20delete,=20b?= =?UTF-8?q?atch=20insert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improvements 1. RTO optimization, less than 8S 2. OB 2.0 protocol optimization, reducing synchronous statements 3. OBProxy actively disconnects and sends Error packets to the client 4. Supports global-level PS cache 5. client_sock_option_flag_out default value is changed from 2 to 3 6. obproxy_error.log will print OBServer TraceId 7. Memory optimization, including connection memory and PS memory 8. RTO probe optimization, considering it normal when receiving Handshake packets 9. The default character encoding in HandShake packets is changed to 46 10. New enable_binlog_service configuration item, default false, indicating whether to enable binlog function 11. 【OB Sharding】Log optimization 12. 【OB Sharding】insert/update/delete statements support multi-table syntax 13. 【OB Sharding】scan_all optimization 14. 【OB Sharding】Black screen DDL optimization Bug fixes 1. Fixed Core issue when accessing partitioned tables with RowID 2. Fixed issue where deleting text ps under Client 2.0 protocol does not return anything 3. Fixed issue where executing text ps under Client 2.0 protocol, then executing sql normally causes "requestId mismatch" error 4. Fixed issue where erroneous format of err packet in internal SQL causes client to hang 5. Fixed issue where enabling v2 protocol causes "4016" error and disconnection 6. Fixed issue where enabling "enable_ob_protocol_v2_with_client=true" causes disconnection during secondary sql routing 7. Fixed issue where connection id mismatch causes proxy disconnection 8. Fixed issue where enabling compression protocol causes disconnection 9. Fixed issue where using COM_CHANGE_USER command with username not in user_name@tenant_name format causes inability to use 10. Fixed issue where date type is inaccurately routed in certain scenarios 11. Fixed Core issue caused by abnormal to_timestamp parameter 12. Fixed Core issue caused by executing anonymous blocks in ODC 13. Fixed remote routing issue with to_date function 14. Fixed routing inaccuracy issue with timestamp with local time zone type list partitioning under Oracle mode 15. Fixed Core issue caused by some keywords not having pointers set 16. Fixed issue where detection optimization causes inability to whiteness 17. Fixed issue where SSL configuration retrieval fails 18. Fixed issue where enabling CPU resource isolation on public cloud causes inability to connect to cluster 19. Fixed issue where using int form for vid configuration does not take effect 20. Fixed issue with substr() causing index out of bounds 21. Fixed partition calculation error with range partitioning under "where c1 >20" condition 22. Fixed issue where type conversion fails and causes inability to route when there are NULL values in list and list column partitioning 23. Fixed Core issue introduced by global PS 24. Fixed issue where autocommit flag in OK packet returned by set autocommit=0 is still 1 25. Fixed issue where some fields in RespResult are not initialized in constructor, causing abnormal disconnection when used 26. Fixed issue where XA_START hold&sync PS 2-in-1 protocol supports complex parameter types 27. Fixed issue where XA_START hold&sync synchronous process cannot accept multiple OB20 packets 28. Fixed obproxy Core issue at oceanbase::obproxy::proxy::ObProxyExprCalculator::calc_partition_id_with_rowid_str 29. Fixed obproxy Core issue at oceanbase::obproxy::proxy::ObProto20Utils::analyze_compressed_packet_header 30. Fixed obproxy Core issue where old database saved in proxy session is used, causing obproxy core at oceanbase::common::ObLogger::log_message_kv 31. Fixed obproxy Core dump at oceanbase::obproxy::proxy::ObMysqlSM::setup_error_transfer 32. Fixed obproxy binary Core dump at obproxy/obutils/ob_proxy_sql_parser.cpp:890 33. Fixed obproxy Core dump at oceanbase::obproxy::proxy::ObMysqlSM::tunnel_handler_response_transfered 34. Fixed Core issue with oceanbase::obproxy::proxy::ObMysqlTransact::is_internal_request 35. Fixed odp Core issue with expression mod() calculation at oceanbase::obproxy::opsql::ObProxyExprMod::calc 36. Fixed obproxy Core issue at oceanbase::obproxy::proxy::ObMysqlVCTable::cleanup_entry 37. Fixed obproxy Core issue at oceanbase::obproxy::proxy::ObMysqlTransact::is_internal_request 38. Fixed Core issue at oceanbase::obproxy::proxy::ObProxyPartMgr::get_first_part at obproxy/proxy/route/obproxy_part_mgr.cpp 39. Fixed obproxy core issue at ObCongestionEntry::to_string in obproxy/obutils/ob_congestion_entry.cpp 40. Fixed a disconnect issue when executing insert statement with "binary" keyword in the "values" clause in OB Sharding 41. Fixed an issue in OB Sharding where the "case when" condition in the "where" clause is incorrectly identified as a sharding parameter 42. Fixed a core issue in OB Sharding when using unsupported expressions in the "order by" or "group by" clause --- .gitignore | 2 + .secignore | 3 +- build.sh | 12 +- configure.ac | 49 +- deps/3rd/obproxy.spec | 24 +- deps/easy/src/io/easy_ssl.c | 21 - rpm/obproxy-ce-VER.txt | 2 +- src/common/cache/ob_kv_storecache.h | 48 +- src/common/mysql_proxy/ob_isql_client.h | 9 +- src/common/ob_obj_cast.cpp | 78 +- src/common/ob_obj_type.h | 4 +- src/common/ob_object.cpp | 4 +- src/common/ob_object.h | 7 + src/common/ob_partition_key.h | 6 +- src/common/ob_queue_thread.h | 16 +- src/common/ob_range2.h | 41 + src/common/obsm_utils.cpp | 6 + src/lib/Makemodule.am | 2 + .../allocator/ob_concurrent_fifo_allocator.h | 31 +- src/lib/allocator/ob_fifo_allocator.h | 24 +- src/lib/allocator/ob_lf_fifo_allocator.h | 11 +- src/lib/charset/ob_charset.cpp | 82 +- src/lib/charset/ob_charset.h | 10 +- src/lib/charset/ob_ctype.h | 45 + src/lib/charset/ob_ctype_bin.c | 4 +- src/lib/charset/ob_ctype_latin1.c | 407 + src/lib/charset/ob_ctype_simple.c | 259 + src/lib/hash/ob_build_in_hashmap.h | 109 +- src/lib/lock/ob_bucket_lock.h | 6 +- src/lib/lock/ob_latch.cpp | 5 +- src/lib/net/ob_addr.cpp | 208 +- src/lib/net/ob_addr.h | 40 +- src/lib/ob_define.h | 8 +- src/lib/ob_errno.cpp | 17 +- src/lib/ob_errno.h | 7 +- src/lib/ob_name_id_def.h | 3 +- src/lib/oblog/ob_async_log_struct.h | 1 + src/lib/oblog/ob_log.cpp | 2 +- src/lib/oblog/ob_log.h | 2 +- src/lib/oblog/ob_log_module.h | 5 + src/lib/oblog/ob_log_print_kv.h | 76 +- src/lib/oblog/ob_simple_trace.h | 190 + src/lib/profile/ob_trace_id.h | 3 + src/lib/rowid/ob_urowid.cpp | 91 +- src/lib/rowid/ob_urowid.h | 6 +- src/lib/timezone/ob_time_convert.cpp | 30 +- src/lib/timezone/ob_time_convert.h | 3 +- src/lib/trace/ob_trace.cpp | 3 +- src/obproxy/Makemodule.am | 22 +- src/obproxy/cmd/ob_cmd_handler.cpp | 3 +- src/obproxy/cmd/ob_dds_config_handler.cpp | 1 - src/obproxy/cmd/ob_internal_cmd_handler.cpp | 6 +- src/obproxy/cmd/ob_sequence_info_handler.cpp | 11 +- src/obproxy/cmd/ob_show_route_handler.cpp | 34 +- src/obproxy/cmd/ob_show_sqlaudit_handler.cpp | 9 +- src/obproxy/cmd/ob_show_topology_handler.cpp | 286 +- src/obproxy/cmd/ob_show_topology_handler.h | 23 +- src/obproxy/cmd/ob_show_vip_handler.cpp | 85 +- src/obproxy/cmd/ob_show_vip_handler.h | 4 +- .../dbconfig/grpc/ob_proxy_grpc_client.cpp | 20 +- .../dbconfig/ob_proxy_db_config_info.cpp | 144 +- .../dbconfig/ob_proxy_db_config_info.h | 8 +- src/obproxy/driver/c/Makemodule.am | 3 + src/obproxy/driver/c/ob_proxy_vc_c.cpp | 231 + src/obproxy/driver/c/ob_proxy_vc_c.h | 98 + src/obproxy/engine/Makemodule.am | 4 +- src/obproxy/engine/ob_proxy_operator_agg.cpp | 33 +- src/obproxy/engine/ob_proxy_operator_agg.h | 7 +- src/obproxy/engine/ob_proxy_operator_cont.cpp | 301 + src/obproxy/engine/ob_proxy_operator_cont.h | 65 + src/obproxy/engine/ob_proxy_operator_result.h | 39 + src/obproxy/engine/ob_proxy_operator_sort.cpp | 22 +- src/obproxy/engine/ob_proxy_operator_sort.h | 9 +- .../engine/ob_proxy_operator_table_scan.cpp | 26 +- .../engine/ob_proxy_operator_table_scan.h | 3 +- .../ob_proxy_parallel_execute_cont.cpp | 54 +- .../executor/ob_proxy_parallel_execute_cont.h | 1 + src/obproxy/iocore/eventsystem/Makemodule.am | 4 + src/obproxy/iocore/eventsystem/ob_ethread.cpp | 20 +- src/obproxy/iocore/eventsystem/ob_ethread.h | 14 +- src/obproxy/iocore/eventsystem/ob_event.h | 2 + .../iocore/eventsystem/ob_event_processor.cpp | 29 +- .../iocore/eventsystem/ob_event_processor.h | 6 +- .../ob_protected_queue_thread_pool.cpp | 75 + .../ob_protected_queue_thread_pool.h | 86 + .../eventsystem/ob_shard_scan_all_task.cpp | 80 + .../eventsystem/ob_shard_scan_all_task.h | 47 + .../iocore/eventsystem/ob_vconnection.h | 8 + src/obproxy/iocore/net/ob_connection.cpp | 113 +- src/obproxy/iocore/net/ob_connection.h | 16 + src/obproxy/iocore/net/ob_inet.cpp | 21 +- src/obproxy/iocore/net/ob_inet.h | 32 +- src/obproxy/iocore/net/ob_net_accept.cpp | 38 +- src/obproxy/iocore/net/ob_net_vconnection.h | 49 +- src/obproxy/iocore/net/ob_unix_net.cpp | 26 +- .../iocore/net/ob_unix_net_processor.cpp | 9 + .../iocore/net/ob_unix_net_vconnection.cpp | 53 +- src/obproxy/ob_proxy.cpp | 53 +- src/obproxy/ob_proxy_init.cpp | 130 + src/obproxy/ob_proxy_init.h | 58 + src/obproxy/ob_proxy_main.cpp | 88 +- src/obproxy/ob_proxy_main.h | 2 +- src/obproxy/obutils/ob_async_common_task.cpp | 4 +- src/obproxy/obutils/ob_config_processor.cpp | 157 +- src/obproxy/obutils/ob_config_processor.h | 18 +- src/obproxy/obutils/ob_congestion_entry.cpp | 34 +- src/obproxy/obutils/ob_congestion_entry.h | 22 + src/obproxy/obutils/ob_congestion_manager.cpp | 5 +- .../obutils/ob_hot_upgrade_processor.cpp | 38 +- .../obutils/ob_hot_upgrade_processor.h | 2 +- src/obproxy/obutils/ob_proxy_config.h | 36 +- src/obproxy/obutils/ob_proxy_config_utils.cpp | 6 +- .../obutils/ob_proxy_json_config_info.cpp | 2 +- src/obproxy/obutils/ob_proxy_sql_parser.cpp | 625 +- src/obproxy/obutils/ob_proxy_sql_parser.h | 216 +- src/obproxy/obutils/ob_proxy_stmt.cpp | 827 +- src/obproxy/obutils/ob_proxy_stmt.h | 80 +- src/obproxy/obutils/ob_proxy_string_utils.cpp | 39 +- src/obproxy/obutils/ob_proxy_string_utils.h | 3 + .../obutils/ob_proxy_table_processor.h | 2 +- .../ob_proxy_table_processor_utils.cpp | 77 +- .../obutils/ob_resource_pool_processor.cpp | 90 +- .../obutils/ob_resource_pool_processor.h | 3 +- .../obutils/ob_server_state_processor.cpp | 95 +- src/obproxy/obutils/ob_state_info.h | 8 +- src/obproxy/obutils/ob_vip_tenant_cache.cpp | 20 +- src/obproxy/obutils/ob_vip_tenant_cache.h | 31 +- src/obproxy/omt/ob_conn_table_processor.cpp | 16 +- src/obproxy/omt/ob_cpu_table_processor.cpp | 4 +- .../omt/ob_proxy_config_table_processor.cpp | 202 +- .../omt/ob_proxy_config_table_processor.h | 10 +- .../omt/ob_resource_unit_table_processor.cpp | 18 +- .../omt/ob_resource_unit_table_processor.h | 2 +- .../omt/ob_ssl_config_table_processor.cpp | 10 +- src/obproxy/omt/ob_vip_tenant_conn.cpp | 18 +- src/obproxy/omt/ob_vip_tenant_conn.h | 12 +- src/obproxy/omt/ob_vip_tenant_cpu.cpp | 6 +- src/obproxy/omt/ob_vip_tenant_cpu.h | 12 +- .../omt/ob_white_list_table_processor.cpp | 127 +- .../omt/ob_white_list_table_processor.h | 11 +- .../opsql/dual_parser/ob_dual_parser.cpp | 1 - .../opsql/expr_parser/ob_expr_parse_result.h | 20 +- .../opsql/expr_parser/ob_expr_parser.h | 8 +- .../opsql/expr_parser/ob_expr_parser.l | 14 +- .../opsql/expr_parser/ob_expr_parser.y | 144 +- .../expr_parser/ob_expr_parser_gbk_lex.c | 758 +- .../expr_parser/ob_expr_parser_gbk_lex.h | 2 +- .../expr_parser/ob_expr_parser_gbk_tab.c | 631 +- .../expr_parser/ob_expr_parser_gbk_tab.h | 36 +- .../expr_parser/ob_expr_parser_utf8_lex.c | 785 +- .../expr_parser/ob_expr_parser_utf8_lex.h | 2 +- .../expr_parser/ob_expr_parser_utf8_tab.c | 631 +- .../expr_parser/ob_expr_parser_utf8_tab.h | 36 +- .../opsql/expr_resolver/ob_expr_resolver.cpp | 752 +- .../opsql/expr_resolver/ob_expr_resolver.h | 43 +- .../func_expr_parser/ob_func_expr_parser.l | 33 +- .../func_expr_parser/ob_func_expr_parser.y | 15 +- .../ob_func_expr_parser_lex.c | 573 +- .../ob_func_expr_parser_lex.h | 2 +- .../ob_func_expr_parser_tab.c | 197 +- .../ob_func_expr_parser_tab.h | 20 +- .../ob_func_expr_resolver.cpp | 69 + .../proxy_expr/ob_proxy_expr.cpp | 563 +- .../proxy_expr/ob_proxy_expr.h | 74 +- .../proxy_expr/ob_proxy_expr_type.h | 24 + .../opsql/parser/ob_proxy_parse_result.cpp | 34 +- .../opsql/parser/ob_proxy_parse_result.h | 16 +- src/obproxy/opsql/parser/ob_proxy_parser.h | 3 +- src/obproxy/opsql/parser/ob_proxy_parser.l | 56 +- src/obproxy/opsql/parser/ob_proxy_parser.y | 78 +- .../opsql/parser/ob_proxy_parser_gbk_lex.c | 9954 +++++++------- .../opsql/parser/ob_proxy_parser_gbk_lex.h | 11 +- .../opsql/parser/ob_proxy_parser_gbk_tab.c | 2393 ++-- .../opsql/parser/ob_proxy_parser_gbk_tab.h | 178 +- .../opsql/parser/ob_proxy_parser_utf8_lex.c | 10945 ++++++++-------- .../opsql/parser/ob_proxy_parser_utf8_lex.h | 11 +- .../opsql/parser/ob_proxy_parser_utf8_tab.c | 2393 ++-- .../opsql/parser/ob_proxy_parser_utf8_tab.h | 178 +- .../optimizer/ob_sharding_select_log_plan.cpp | 88 +- src/obproxy/packet/ob_mysql_packet_reader.cpp | 21 +- src/obproxy/packet/ob_mysql_packet_reader.h | 27 + src/obproxy/packet/ob_mysql_packet_util.cpp | 117 +- src/obproxy/packet/ob_mysql_packet_util.h | 13 +- src/obproxy/packet/ob_proxy_packet_writer.cpp | 105 +- src/obproxy/packet/ob_proxy_packet_writer.h | 22 +- .../prometheus/ob_prometheus_processor.h | 2 +- src/obproxy/proxy/api/ob_api_internal.h | 22 +- src/obproxy/proxy/api/ob_mysql_sm_api.h | 6 + src/obproxy/proxy/client/Makemodule.am | 4 +- src/obproxy/proxy/client/ob_client_utils.cpp | 104 +- src/obproxy/proxy/client/ob_client_utils.h | 66 +- src/obproxy/proxy/client/ob_client_vc.cpp | 252 +- src/obproxy/proxy/client/ob_client_vc.h | 18 +- src/obproxy/proxy/client/ob_driver_client.cpp | 375 + src/obproxy/proxy/client/ob_driver_client.h | 86 + .../proxy/client/ob_mysql_client_pool.cpp | 4 +- .../proxy/client/ob_mysql_client_pool.h | 1 + src/obproxy/proxy/client/ob_mysql_proxy.cpp | 32 +- src/obproxy/proxy/client/ob_mysql_proxy.h | 2 + .../proxy/client/ob_raw_mysql_client.cpp | 7 +- .../proxy/client/ob_raw_mysql_client.h | 9 +- .../proxy/mysql/ob_mysql_client_session.cpp | 83 +- .../proxy/mysql/ob_mysql_client_session.h | 38 +- .../proxy/mysql/ob_mysql_debug_names.cpp | 4 + .../mysql/ob_mysql_global_session_manager.cpp | 3 +- .../proxy/mysql/ob_mysql_proxy_port.cpp | 12 +- src/obproxy/proxy/mysql/ob_mysql_proxy_port.h | 3 +- .../mysql/ob_mysql_proxy_server_main.cpp | 107 +- .../proxy/mysql/ob_mysql_proxy_server_main.h | 1 + .../proxy/mysql/ob_mysql_server_session.cpp | 22 +- .../proxy/mysql/ob_mysql_session_manager.cpp | 1 + src/obproxy/proxy/mysql/ob_mysql_sm.cpp | 1124 +- src/obproxy/proxy/mysql/ob_mysql_sm.h | 34 +- .../proxy/mysql/ob_mysql_sm_time_stat.cpp | 9 +- .../proxy/mysql/ob_mysql_sm_time_stat.h | 19 +- src/obproxy/proxy/mysql/ob_mysql_transact.cpp | 1631 ++- src/obproxy/proxy/mysql/ob_mysql_transact.h | 172 +- src/obproxy/proxy/mysql/ob_mysql_tunnel.cpp | 7 +- .../mysql/ob_prepare_statement_struct.cpp | 263 +- .../proxy/mysql/ob_prepare_statement_struct.h | 395 +- .../proxy/mysqllib/ob_2_0_protocol_struct.h | 132 +- .../proxy/mysqllib/ob_2_0_protocol_utils.cpp | 133 +- .../proxy/mysqllib/ob_2_0_protocol_utils.h | 18 +- .../proxy/mysqllib/ob_mysql_common_define.h | 7 +- .../ob_mysql_compress_ob20_analyzer.cpp | 19 +- .../ob_mysql_compress_ob20_analyzer.h | 2 +- .../mysqllib/ob_mysql_config_processor.cpp | 17 +- .../mysqllib/ob_mysql_config_processor.h | 4 + .../mysqllib/ob_mysql_ob20_packet_write.cpp | 7 +- .../mysqllib/ob_mysql_ob20_packet_write.h | 4 +- .../mysqllib/ob_mysql_packet_rewriter.cpp | 32 +- .../proxy/mysqllib/ob_mysql_packet_rewriter.h | 3 +- .../mysqllib/ob_mysql_request_analyzer.cpp | 129 +- .../mysqllib/ob_mysql_request_analyzer.h | 19 +- .../mysqllib/ob_mysql_request_builder.cpp | 205 +- .../proxy/mysqllib/ob_mysql_request_builder.h | 25 +- .../proxy/mysqllib/ob_mysql_resp_analyzer.cpp | 31 +- .../proxy/mysqllib/ob_mysql_response.h | 17 +- .../mysqllib/ob_mysql_response_builder.cpp | 206 +- .../mysqllib/ob_mysql_response_builder.h | 35 +- .../proxy/mysqllib/ob_proxy_mysql_request.h | 14 +- .../proxy/mysqllib/ob_proxy_ob20_request.h | 2 +- .../proxy/mysqllib/ob_proxy_session_info.cpp | 72 +- .../proxy/mysqllib/ob_proxy_session_info.h | 100 +- .../ob_proxy_session_info_handler.cpp | 58 +- .../mysqllib/ob_proxy_session_info_handler.h | 10 +- .../proxy/mysqllib/ob_resultset_fetcher.h | 22 + .../proxy/mysqllib/ob_session_field_mgr.h | 8 +- ...ysql_request_compress_transform_plugin.cpp | 7 +- ..._mysql_request_compress_transform_plugin.h | 4 +- ...sql_response_compress_transform_plugin.cpp | 32 +- ...mysql_response_compress_transform_plugin.h | 2 - ...mysql_response_cursor_transform_plugin.cpp | 1 + ...b_mysql_response_ob20_transform_plugin.cpp | 6 +- .../ob_trim_okpacket_transform_plugin.h | 2 +- src/obproxy/proxy/route/ob_mysql_route.cpp | 28 +- src/obproxy/proxy/route/ob_route_struct.h | 14 +- src/obproxy/proxy/route/ob_route_utils.cpp | 510 +- src/obproxy/proxy/route/ob_route_utils.h | 16 +- src/obproxy/proxy/route/ob_server_route.h | 23 - src/obproxy/proxy/route/ob_table_entry.cpp | 1 + src/obproxy/proxy/route/ob_table_entry.h | 7 +- .../proxy/route/ob_table_entry_cont.cpp | 62 +- src/obproxy/proxy/route/ob_table_entry_cont.h | 2 + .../proxy/route/obproxy_expr_calculator.cpp | 107 +- .../proxy/route/obproxy_expr_calculator.h | 22 +- src/obproxy/proxy/route/obproxy_part_info.cpp | 1 + src/obproxy/proxy/route/obproxy_part_info.h | 5 + src/obproxy/proxy/route/obproxy_part_mgr.cpp | 882 +- src/obproxy/proxy/route/obproxy_part_mgr.h | 115 +- .../proxy/shard/obproxy_shard_utils.cpp | 1079 +- src/obproxy/proxy/shard/obproxy_shard_utils.h | 174 +- src/obproxy/stat/ob_mysql_stats.cpp | 6 + src/obproxy/stat/ob_mysql_stats.h | 4 + src/obproxy/stat/ob_stat_processor.cpp | 4 +- src/obproxy/stat/ob_stat_processor.h | 2 +- src/obproxy/utils/Makemodule.am | 4 +- src/obproxy/utils/ob_layout.cpp | 100 +- src/obproxy/utils/ob_layout.h | 7 + src/obproxy/utils/ob_proxy_hot_upgrader.cpp | 10 +- src/obproxy/utils/ob_proxy_hot_upgrader.h | 6 +- src/obproxy/utils/ob_proxy_lib.h | 1 + src/obproxy/utils/ob_proxy_table_define.cpp | 8 +- src/obproxy/utils/ob_proxy_table_define.h | 6 + src/obproxy/utils/ob_proxy_utils.cpp | 34 + src/obproxy/utils/ob_proxy_utils.h | 7 + src/obproxy/utils/ob_target_db_server.cpp | 147 + src/obproxy/utils/ob_target_db_server.h | 77 + src/rpc/Makemodule.am | 4 + src/rpc/ob_request.cpp | 7 +- src/rpc/obmysql/ob_mysql_field.cpp | 9 + src/rpc/obmysql/ob_mysql_field.h | 12 + src/rpc/obmysql/ob_mysql_global.h | 4 + src/rpc/obmysql/packet/ompk_handshake.cpp | 8 +- .../obmysql/packet/ompk_handshake_response.h | 2 +- .../obmysql/packet/ompk_prepare_execute.cpp | 93 + src/rpc/obmysql/packet/ompk_prepare_execute.h | 88 + .../packet/ompk_prepare_execute_req.cpp | 68 + .../obmysql/packet/ompk_prepare_execute_req.h | 81 + src/share/config/ob_common_config.cpp | 36 +- src/share/config/ob_common_config.h | 9 + src/share/config/ob_config.h | 2 +- src/share/config/ob_config_helper.cpp | 11 +- .../ob_inner_table_schema_constants.h | 1 + src/share/part/ob_part_desc.cpp | 43 +- src/share/part/ob_part_desc.h | 20 +- src/share/part/ob_part_desc_hash.cpp | 237 +- src/share/part/ob_part_desc_hash.h | 17 +- src/share/part/ob_part_desc_key.cpp | 189 +- src/share/part/ob_part_desc_key.h | 19 +- src/share/part/ob_part_desc_list.cpp | 109 +- src/share/part/ob_part_desc_list.h | 10 +- src/share/part/ob_part_desc_range.cpp | 48 +- src/share/part/ob_part_desc_range.h | 15 +- unittest/obproxy/ob_expr_parser_checker.cpp | 6 - unittest/obproxy/obproxy_parser_test.cpp | 46 +- unittest/obproxy/test_ldc_location.cpp | 69 +- .../test_proxy_table_processor_utils.cpp | 14 +- unittest/obproxy/test_tenant_processor.cpp | 117 +- .../obproxy/test_white_list_processor.cpp | 28 +- 320 files changed, 31363 insertions(+), 19430 deletions(-) create mode 100644 src/lib/charset/ob_ctype_latin1.c create mode 100644 src/lib/oblog/ob_simple_trace.h create mode 100644 src/obproxy/driver/c/Makemodule.am create mode 100644 src/obproxy/driver/c/ob_proxy_vc_c.cpp create mode 100644 src/obproxy/driver/c/ob_proxy_vc_c.h create mode 100644 src/obproxy/engine/ob_proxy_operator_cont.cpp create mode 100644 src/obproxy/engine/ob_proxy_operator_cont.h create mode 100644 src/obproxy/iocore/eventsystem/ob_protected_queue_thread_pool.cpp create mode 100644 src/obproxy/iocore/eventsystem/ob_protected_queue_thread_pool.h create mode 100644 src/obproxy/iocore/eventsystem/ob_shard_scan_all_task.cpp create mode 100644 src/obproxy/iocore/eventsystem/ob_shard_scan_all_task.h create mode 100644 src/obproxy/ob_proxy_init.cpp create mode 100644 src/obproxy/ob_proxy_init.h create mode 100644 src/obproxy/proxy/client/ob_driver_client.cpp create mode 100644 src/obproxy/proxy/client/ob_driver_client.h create mode 100644 src/obproxy/utils/ob_target_db_server.cpp create mode 100644 src/obproxy/utils/ob_target_db_server.h create mode 100644 src/rpc/obmysql/packet/ompk_prepare_execute.cpp create mode 100644 src/rpc/obmysql/packet/ompk_prepare_execute.h create mode 100644 src/rpc/obmysql/packet/ompk_prepare_execute_req.cpp create mode 100644 src/rpc/obmysql/packet/ompk_prepare_execute_req.h diff --git a/.gitignore b/.gitignore index f2440b4f3..4d3c44ec4 100644 --- a/.gitignore +++ b/.gitignore @@ -181,6 +181,8 @@ obproxy-tmp* src/.DS_Store unittest/.DS_Store ob_proxy_parser.output +.vscode/* +rpm/.dep_create deps/3rd/home deps/3rd/var deps/3rd/usr diff --git a/.secignore b/.secignore index 44c80e24e..ebe3fd783 100644 --- a/.secignore +++ b/.secignore @@ -42,7 +42,8 @@ http://www.quicklz.com/) http://www.goof.com/pcg/marc/liblzf.html) http://www.fastlz.org/ - http://stackoverflow.com/a/32095106/646947 + http://stackoverflow.com/* + https://stackoverflow.com/* http://fastcompression.blogspot.com/p/lz4.html https://groups.google.com/forum/# https://github.com/mcmilk/zstdmt diff --git a/build.sh b/build.sh index 24d279237..e5201ad28 100755 --- a/build.sh +++ b/build.sh @@ -77,16 +77,16 @@ function do_config() ./configure --with-gcc-version=9.3.0 --with-coverage=yes --enable-buildtime=no --enable-strip-ut=no --enable-silent-rules --enable-dlink-observer=no echo -e "\033[31m ===build gcov version=== \033[0m" ;; - xperf) - # configure for perf - ./configure --with-gcc-version=9.3.0 --with-coverage=no --enable-buildtime=no --enable-strip-ut=no --enable-silent-rules --enable-dlink-observer=no --with-release --with-perf - echo -e "\033[31m ===build perf version=== \033[0m" - ;; xasan) # configure for asan ./configure --with-gcc-version=9.3.0 --with-coverage=no --enable-buildtime=no --enable-strip-ut=no --enable-silent-rules --enable-dlink-observer=no --with-asan echo -e "\033[31m ===build asan version=== \033[0m" ;; + xso) + # configure for obproxy_so + ./configure --with-gcc-version=9.3.0 --with-coverage=no --enable-buildtime=no --enable-strip-ut=no --enable-silent-rules --enable-dlink-observer=no --with-release --with-so + echo -e "\033[31m ===build so version=== \033[0m" + ;; *) # configure for release ./configure --with-gcc-version=9.3.0 --with-coverage=no --enable-buildtime=no --enable-strip-ut=no --enable-silent-rules --enable-dlink-observer=no --with-release @@ -121,7 +121,7 @@ function do_rpm() cd ${TMP_DIR}/BUILD echo "[BUILD] make rpms..._prefix=${PREFIX} spec_file=${SPEC_FILE}" - rpmbuild --define "_topdir ${TMP_DIR}" --define "NAME ${PACKAGE}" --define "VERSION ${VERSION}" --define "_prefix ${PREFIX}" --define "RELEASE ${RELEASE}" -ba ${TOPDIR}/deps/3rd/${SPEC_FILE} || exit 2 + rpmbuild --define "_topdir ${TMP_DIR}" --define "NAME ${PACKAGE}" --define "VERSION ${VERSION}" --define "_prefix ${PREFIX}" --define "RELEASE ${RELEASE}" --define "rpm_path ${TOPDIR}" -ba ${TOPDIR}/deps/3rd/${SPEC_FILE} || exit 2 echo "[BUILD] make rpms done." cd ${TOPDIR} diff --git a/configure.ac b/configure.ac index b710617ed..8c3530a6e 100644 --- a/configure.ac +++ b/configure.ac @@ -1,10 +1,10 @@ AC_INIT([OceanBase], - [4.0.0], + [4.1.0.0], [wgs13579@gmail.com], [obproxy-ce], [http://oceanbase.taobao.org/]) - obapi_version="4.0.0" + obapi_version="4.1.0.0" AC_SUBST(obapi_version) AC_DISABLE_STATIC @@ -26,12 +26,12 @@ if test "$withval" = "yes"; then case "$host_cpu" in *aarch64* ) - AM_CXXFLAGS="-g -O2 -D_OB_VERSION=1000 -D_NO_EXCEPTION -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -DNDEBUG -D__USE_LARGEFILE64 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -Wall -Wextra -Wno-unused-parameter -Wformat -Wno-conversion -Wno-deprecated -Wno-invalid-offsetof -Wno-unused-result -Wno-format-security -finline-functions -fno-strict-aliasing -mtune=generic -march=armv8-a+crc -Wno-psabi -Wno-sign-compare -Wno-class-memaccess -Wno-deprecated-copy -Wno-ignored-qualifiers -Wno-aligned-new -Wno-format-truncation -Wno-literal-suffix -Wno-format-overflow -Wno-stringop-truncation -Wno-memset-elt-size -Wno-cast-function-type -Wno-address-of-packed-member -fuse-ld=lld -ffunction-sections -Wl,--no-warn-symbol-ordering,--symbol-ordering-file,${ac_abs_confdir}/hotfuncs.txt" - AM_CFLAGS="-g -O2 -D_OB_VERSION=1000 -DCOMPATIBLE -D__USE_LARGEFILE64 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DNDEBUG -finline-functions -fno-strict-aliasing -Wall -mtune=generic -Wno-psabi -Wno-sign-compare -fuse-ld=lld -ffunction-sections -Wl,--no-warn-symbol-ordering,--symbol-ordering-file,${ac_abs_confdir}/hotfuncs.txt" + AM_CXXFLAGS="-g -O2 -D_OB_VERSION=1000 -D_NO_EXCEPTION -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -DNDEBUG -D__USE_LARGEFILE64 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -Wall -Wextra -Wno-unused-parameter -Wformat -Wno-conversion -Wno-deprecated -Wno-invalid-offsetof -Wno-unused-result -Wno-format-security -finline-functions -fno-strict-aliasing -mtune=generic -march=armv8-a+crc -Wno-psabi -Wno-sign-compare -Wno-class-memaccess -Wno-deprecated-copy -Wno-ignored-qualifiers -Wno-aligned-new -Wno-format-truncation -Wno-literal-suffix -Wno-format-overflow -Wno-stringop-truncation -Wno-memset-elt-size -Wno-cast-function-type -Wno-address-of-packed-member -fno-omit-frame-pointer" + AM_CFLAGS="-g -O2 -D_OB_VERSION=1000 -DCOMPATIBLE -D__USE_LARGEFILE64 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DNDEBUG -finline-functions -fno-strict-aliasing -Wall -mtune=generic -Wno-psabi -Wno-sign-compare" ;; * ) - AM_CXXFLAGS="-g -O2 -D_OB_VERSION=1000 -D_NO_EXCEPTION -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -DNDEBUG -D__USE_LARGEFILE64 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -Wall -Wextra -Wno-unused-parameter -Wformat -Wno-conversion -Wno-deprecated -Wno-invalid-offsetof -Wno-unused-result -Wno-format-security -finline-functions -fno-strict-aliasing -mtune=core2 -Wno-psabi -Wno-sign-compare -Wno-class-memaccess -Wno-deprecated-copy -Wno-ignored-qualifiers -Wno-aligned-new -Wno-format-truncation -Wno-literal-suffix -Wno-format-overflow -Wno-stringop-truncation -Wno-memset-elt-size -Wno-cast-function-type -Wno-address-of-packed-member -fuse-ld=lld -ffunction-sections -Wl,--no-warn-symbol-ordering,--symbol-ordering-file,${ac_abs_confdir}/hotfuncs.txt" - AM_CFLAGS="-g -O2 -D_OB_VERSION=1000 -DCOMPATIBLE -D__USE_LARGEFILE64 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DNDEBUG -finline-functions -fno-strict-aliasing -Wall -mtune=core2 -Wno-psabi -Wno-sign-compare -fuse-ld=lld -ffunction-sections -Wl,--no-warn-symbol-ordering,--symbol-ordering-file,${ac_abs_confdir}/hotfuncs.txt" + AM_CXXFLAGS="-g -O2 -D_OB_VERSION=1000 -D_NO_EXCEPTION -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -DNDEBUG -D__USE_LARGEFILE64 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -Wall -Wextra -Wno-unused-parameter -Wformat -Wno-conversion -Wno-deprecated -Wno-invalid-offsetof -Wno-unused-result -Wno-format-security -finline-functions -fno-strict-aliasing -mtune=core2 -Wno-psabi -Wno-sign-compare -Wno-class-memaccess -Wno-deprecated-copy -Wno-ignored-qualifiers -Wno-aligned-new -Wno-format-truncation -Wno-literal-suffix -Wno-format-overflow -Wno-stringop-truncation -Wno-memset-elt-size -Wno-cast-function-type -Wno-address-of-packed-member -fno-omit-frame-pointer" + AM_CFLAGS="-g -O2 -D_OB_VERSION=1000 -DCOMPATIBLE -D__USE_LARGEFILE64 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DNDEBUG -finline-functions -fno-strict-aliasing -Wall -mtune=core2 -Wno-psabi -Wno-sign-compare" ;; esac fi @@ -41,6 +41,26 @@ ] ) + AC_ARG_WITH([so], + AS_HELP_STRING([--with-so], + [with so support (default is NO)]), + [ + if test "$withval" = "yes"; then + support_so=yes + AM_CXXFLAGS="${AM_CXXFLAGS} -fPIC" + AM_CFLAGS="${AM_CFLAGS} -fPIC" + fi + ], + [support_so=no] + ) + + AM_CONDITIONAL([HAVE_SO], test x$support_so = xyes ) + + if test "$support_so" == "no"; then + AM_CXXFLAGS="${AM_CXXFLAGS} -fuse-ld=lld -ffunction-sections -Wl,--no-warn-symbol-ordering,--symbol-ordering-file,${ac_abs_confdir}/hotfuncs.txt" + AM_CFLAGS="${AM_CFLAGS} -fuse-ld=lld -ffunction-sections -Wl,--no-warn-symbol-ordering,--symbol-ordering-file,${ac_abs_confdir}/hotfuncs.txt" + fi + #check gcc version, add -Wno-ignored-qualifiers flag for gcc version greater than 4.3.0 GCC_VERSION=`$CC -dumpfullversion -dumpversion` if test $? -eq 0; then @@ -101,23 +121,6 @@ ], []) - AC_ARG_WITH([perf], - AS_HELP_STRING([--with-perf], - [with perf (default is NO)]), - [ - if test "$withval" = "yes"; then - # The following parameters are options for using gperftools, - # currently not using tcmalloc - # test_perf=yes - # AM_CXXFLAGS="${AM_CXXFLAGS} -D__NEED_PERF__" - # AM_LDFLAGS="${AM_LDFLAGS} -lprofiler" - AM_CXXFLAGS="${AM_CXXFLAGS} -fno-omit-frame-pointer" - AM_CFLAGS="${AM_CFLAGS} -fno-omit-frame-pointer" - fi - ], - [with_perf=no] - ) - AC_ARG_WITH([asan], AS_HELP_STRING([--with-asan], [with asan (default is NO)]), diff --git a/deps/3rd/obproxy.spec b/deps/3rd/obproxy.spec index 2fccee9d6..03169a2ea 100644 --- a/deps/3rd/obproxy.spec +++ b/deps/3rd/obproxy.spec @@ -34,16 +34,29 @@ OceanBase Database Proxy %setup %build -./configure CXX=${CXX} CC=${CC} --with-gcc-version=9.3.0 RELEASEID=%{RELEASE} --prefix=%{_prefix} --with-test-case=no --with-release=yes --with-tblib-root=/opt/csr/common --with-easy-root=/usr --with-easy-lib-path=/usr/lib64 --with-svnfile --enable-shared=default --enable-silent-rules -mkdir -p unittest +mkdir -p lib +cp ${TOOLS_DIR}/lib64/libstdc++.so.6.0.28 lib/libstdc++.so.6 + +#./configure CXX=${CXX} CC=${CC} --with-gcc-version=9.3.0 --with-so --prefix=%{_prefix} --with-test-case=no --with-release=yes --with-tblib-root=/opt/csr/common --with-easy-root=/usr --with-easy-lib-path=/usr/lib64 --with-svnfile --enable-shared=default --enable-silent-rules CPU_CORES=`grep -c ^processor /proc/cpuinfo` MAKE_ARGS="-j $CPU_CORES" +#make $MAKE_ARGS +#cp src/obproxy/.libs/libobproxy_so.so.0.0.0 lib/libobproxy_so.so + +#make distclean >/dev/null 2>&1 +#find . -path ./tools/codestyle/astyle/build -prune -o -path ./doc -prune -o -name Makefile -exec rm -f {} \; +#find . -name .deps -prune -exec rm -rf {} \; + +./configure CXX=${CXX} CC=${CC} --with-gcc-version=9.3.0 RELEASEID=%{RELEASE} --prefix=%{_prefix} --with-test-case=no --with-release=yes --with-tblib-root=/opt/csr/common --with-easy-root=/usr --with-easy-lib-path=/usr/lib64 --with-svnfile --enable-shared=default --enable-silent-rules +mkdir -p unittest make $MAKE_ARGS %install make DESTDIR=$RPM_BUILD_ROOT install mkdir -p $RPM_BUILD_ROOT%{install_dir}/bin +mkdir -p $RPM_BUILD_ROOT%{install_dir}/lib cp src/obproxy/obproxy $RPM_BUILD_ROOT%{install_dir}/bin +cp -r lib/* $RPM_BUILD_ROOT%{install_dir}/lib cp script/deploy/obproxyd.sh $RPM_BUILD_ROOT%{install_dir}/bin %clean @@ -54,12 +67,19 @@ rm -rf $RPM_BUILD_ROOT %dir %{install_dir}/bin %{install_dir}/bin/obproxy %{install_dir}/bin/obproxyd.sh +%{install_dir}/lib/libstdc++.so.6 %pre rm -rf %{install_dir}/log rm -rf %{install_dir}/bin rm -rf %{install_dir}/etc rm -rf %{install_dir}/.conf +rm -rf /u01/obproxy/lib +mkdir -p /u01/obproxy/lib %post chown -R admin:admin %{install_dir} +ln -s %{install_dir}/lib/libobproxy_so.so /u01/obproxy/lib/libobproxy_so.so.0 +ln -s %{install_dir}/lib/libobproxy_so.so /u01/obproxy/lib/libobproxy_so.so +ln -s %{install_dir}/lib/libprotobuf.so.18 /u01/obproxy/lib/libprotobuf.so.18 +ln -s %{install_dir}/lib/libstdc++.so.6 /u01/obproxy/lib/libstdc++.so.6 diff --git a/deps/easy/src/io/easy_ssl.c b/deps/easy/src/io/easy_ssl.c index f7bfa8de5..e8e246c38 100644 --- a/deps/easy/src/io/easy_ssl.c +++ b/deps/easy/src/io/easy_ssl.c @@ -1601,14 +1601,6 @@ static int easy_ssl_dhparam(easy_ssl_ctx_t *ssl, char *file) DH *dh; BIO *bio; - /* - * -----BEGIN DH PARAMETERS----- - * MIGHAoGBALu8LcrYRnSQfEP89YDpz9vZWKP1aLQtSwju1OsPs1BMbAMCducQgAxc - * y7qokiYUxb7spWWl/fHSh6K8BJvmd4Bg6RqSp1fjBI9osHb302zI8pul34HcLKcl - * 7OZicMyaUDXYzs7vnqAnSmOrHlj6/UmI0PZdFGdX2gcd8EXP4WubAgEC - * -----END DH PARAMETERS----- - */ - static unsigned char dh1024_p[] = { 0xBB, 0xBC, 0x2D, 0xCA, 0xD8, 0x46, 0x74, 0x90, 0x7C, 0x43, 0xFC, 0xF5, 0x80, 0xE9, 0xCF, 0xDB, 0xD9, 0x58, 0xA3, 0xF5, 0x68, 0xB4, 0x2D, 0x4B, @@ -1677,19 +1669,6 @@ static int easy_ssl_dhparam_mysql(easy_ssl_ctx_t *ssl) { DH *dh; - /* - Diffie-Hellman key. - Generated using: >openssl dhparam -5 -C 2048 - - -----BEGIN DH PARAMETERS----- - MIIBCAKCAQEAil36wGZ2TmH6ysA3V1xtP4MKofXx5n88xq/aiybmGnReZMviCPEJ - 46+7VCktl/RZ5iaDH1XNG1dVQmznt9pu2G3usU+k1/VB4bQL4ZgW4u0Wzxh9PyXD - glm99I9Xyj4Z5PVE4MyAsxCRGA1kWQpD9/zKAegUBPLNqSo886Uqg9hmn8ksyU9E - BV5eAEciCuawh6V0O+Sj/C3cSfLhgA0GcXp3OqlmcDu6jS5gWjn3LdP1U0duVxMB - h/neTSCSvtce4CAMYMjKNVh9P1nu+2d9ZH2Od2xhRIqMTfAS1KTqF3VmSWzPFCjG - mjxx/bg6bOOjpgZapvB6ABWlWmRmAAWFtwIBBQ== - -----END DH PARAMETERS----- - */ static unsigned char dh2048_p[]= { 0x8A, 0x5D, 0xFA, 0xC0, 0x66, 0x76, 0x4E, 0x61, 0xFA, 0xCA, 0xC0, 0x37, diff --git a/rpm/obproxy-ce-VER.txt b/rpm/obproxy-ce-VER.txt index fcdb2e109..16f4c78fd 100644 --- a/rpm/obproxy-ce-VER.txt +++ b/rpm/obproxy-ce-VER.txt @@ -1 +1 @@ -4.0.0 +4.1.0.0 diff --git a/src/common/cache/ob_kv_storecache.h b/src/common/cache/ob_kv_storecache.h index a8fd09e9d..dc19d62c9 100644 --- a/src/common/cache/ob_kv_storecache.h +++ b/src/common/cache/ob_kv_storecache.h @@ -131,8 +131,10 @@ enum ObKVCachePolicy struct ObKVCacheConfig { public: - ObKVCacheConfig(); - void reset(); + /* this function is defined for c driver client compile */ + ObKVCacheConfig() {}; + /* this function is defined for c driver client compile */ + void reset() {}; bool is_valid_; int64_t priority_; char cache_name_[MAX_CACHE_NAME_LENGTH]; @@ -267,9 +269,12 @@ class ObKVCacheInstMap; class ObKVCacheInstHandle { public: - ObKVCacheInstHandle(); - virtual ~ObKVCacheInstHandle(); - void reset(); + /* this function is defined for c driver client compile */ + ObKVCacheInstHandle() {}; + /* this function is defined for c driver client compile */ + virtual ~ObKVCacheInstHandle() {}; + /* this function is defined for c driver client compile */ + void reset() {}; inline ObKVCacheInst *get_inst() { return inst_; } private: friend class ObKVCacheInstMap; @@ -291,8 +296,10 @@ struct ObKVCacheInfo class ObKVCacheInstMap { public: - ObKVCacheInstMap(); - virtual ~ObKVCacheInstMap(); + /* this function is defined for c driver client compile */ + ObKVCacheInstMap() {}; + /* this function is defined for c driver client compile */ + virtual ~ObKVCacheInstMap() {}; int init(const int64_t max_entry_cnt, const ObKVCacheConfig *configs); void destroy(); int get_cache_inst( @@ -319,8 +326,10 @@ class ObKVCacheInstMap class ObKVCacheStore { public: - ObKVCacheStore(); - virtual ~ObKVCacheStore(); + /* this function is defined for c driver client compile */ + ObKVCacheStore() {}; + /* this function is defined for c driver client compile */ + virtual ~ObKVCacheStore() {}; int init(ObKVCacheInstMap &insts, const int64_t max_cache_size, const int64_t block_size); void destroy(); int set_priority(const int64_t cache_id, const int64_t old_priority, const int64_t new_priority); @@ -394,8 +403,10 @@ class ObKVCacheStore class ObKVCacheMap { public: - ObKVCacheMap(); - virtual ~ObKVCacheMap(); + /* this function is defined for c driver client compile */ + ObKVCacheMap() {}; + /* this function is defined for c driver client compile */ + virtual ~ObKVCacheMap() {}; int init(const int64_t bucket_num, ObKVCacheStore *store); void destroy(); int erase_all(); @@ -452,19 +463,23 @@ class ObKVCacheHandle; class ObKVGlobalCache { public: - static ObKVGlobalCache &get_instance(); + /* this function is defined for c driver client compile */ + static ObKVGlobalCache &get_instance() {return *(new ObKVGlobalCache());}; int init(const int64_t bucket_num = DEFAULT_BUCKET_NUM, const int64_t max_cache_size = DEFAULT_MAX_CACHE_SIZE, const int64_t block_size = common::OB_MALLOC_BIG_BLOCK_SIZE); void destroy(); - void reload_priority(); + /* this function is defined for c driver client compile */ + void reload_priority() {}; int get_tenant_cache_info(const uint64_t tenant_id, ObIArray &infos); int get_all_cache_info(ObIArray &infos); private: template friend class ObKVCache; friend class ObKVCacheHandle; - ObKVGlobalCache(); - virtual ~ObKVGlobalCache(); + /* this function is defined for c driver client compile */ + ObKVGlobalCache() {} + /* this function is defined for c driver client compile */ + virtual ~ObKVGlobalCache() {} int register_cache(const char *cache_name, const int64_t priority, int64_t &cache_id); void deregister_cache(const int64_t cache_id); int set_priority(const int64_t cache_id, const int64_t priority); @@ -482,7 +497,8 @@ class ObKVGlobalCache ObKVMemBlockHandle *&mb_handle); int erase(const int64_t cache_id, const ObIKVCacheKey &key); void revert(ObKVMemBlockHandle *mb_handle); - void wash(); + /* this function is defined for c driver client compile */ + void wash() {}; private: static const int64_t DEFAULT_BUCKET_NUM = 10000000L; static const int64_t DEFAULT_MAX_CACHE_SIZE = 1024L * 1024L * 1024L * 1024L; //1T diff --git a/src/common/mysql_proxy/ob_isql_client.h b/src/common/mysql_proxy/ob_isql_client.h index cd1293fec..65dc7be30 100644 --- a/src/common/mysql_proxy/ob_isql_client.h +++ b/src/common/mysql_proxy/ob_isql_client.h @@ -58,10 +58,13 @@ class ObISQLClient public: friend class ObISQLClient; - ReadResult(); - virtual ~ReadResult(); + /* this function is defined for c driver client compile */ + ReadResult() {} + /* this function is defined for c driver client compile */ + virtual ~ReadResult() {} - sqlclient::ObMySQLResult *mysql_result(); + /* this function is defined for c driver client compile */ + sqlclient::ObMySQLResult *mysql_result() {return nullptr;} // FIXME : remove sqlclient::ObMySQLResult *get_result() { return mysql_result(); } diff --git a/src/common/ob_obj_cast.cpp b/src/common/ob_obj_cast.cpp index 3c73f315e..684d180f8 100644 --- a/src/common/ob_obj_cast.cpp +++ b/src/common/ob_obj_cast.cpp @@ -1563,7 +1563,7 @@ static int double_float(const ObObjType expect_type, ObObjCastParams ¶ms, ret = OB_ERR_UNEXPECTED; LOG_ERROR("invalid input type", K(ret), K(in), K(expect_type)); - } else if (CAST_FAIL(real_range_check(expect_type, in.get_double(), value))) { + } else if (!lib::is_oracle_mode() && CAST_FAIL(real_range_check(expect_type, in.get_double(), value))) { } else { out.set_float(expect_type, value); } @@ -2975,17 +2975,30 @@ static int string_datetime(const ObObjType expect_type, ObObjCastParams ¶ms, { int ret = OB_SUCCESS; ObScale res_scale = -1; + ObString utf8_string; + if (OB_UNLIKELY((ObStringTC != in.get_type_class() && ObTextTC != in.get_type_class()) || ObDateTimeTC != ob_obj_type_class(expect_type))) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("invalid input type", - K(ret), K(in), K(expect_type)); + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid input type", + K(ret), K(in), K(expect_type)); + } else if (lib::is_oracle_mode() && in.is_blob()) { + ret = OB_NOT_SUPPORTED; + LOG_ERROR("invalid use of blob type", K(ret), K(in), K(expect_type)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "Cast to blob type"); + } else if (OB_FAIL(convert_string_collation(in.get_string(), in.get_collation_type(), utf8_string, ObCharset::get_system_collation(), params))) { + LOG_WARN("convert_string_collation", K(ret)); } else { - const ObTimeZoneInfo *tz_info = (ObTimestampType == expect_type) ? params.dtc_params_.tz_info_ : NULL; int64_t value = 0; - if (CAST_FAIL(ObTimeConverter::str_to_datetime(in.get_string(), tz_info, value, &res_scale))) { + ObTimeConvertCtx cvrt_ctx(params.dtc_params_.tz_info_, ObTimestampType == expect_type); + if (lib::is_oracle_mode()) { + cvrt_ctx.oracle_nls_format_ = params.dtc_params_.get_nls_format(ObDateTimeType); + CAST_FAIL(ObTimeConverter::str_to_date_oracle(utf8_string, cvrt_ctx, value)); } else { + CAST_FAIL(ObTimeConverter::str_to_datetime(utf8_string, cvrt_ctx.tz_info_, value, &res_scale)); + } + if(OB_SUCC(ret)) { SET_RES_DATETIME(out); } } @@ -3067,29 +3080,56 @@ static int string_string(const ObObjType expect_type, ObObjCastParams ¶ms, ObString str; in.get_string(str); if (0 != str.length() - && CS_TYPE_BINARY != in.get_collation_type() - && CS_TYPE_BINARY != params.dest_collation_ + // in mysql mode if charset is binary then not convert + // in oracle mode if charset is binary then convert + && ((CS_TYPE_BINARY != in.get_collation_type() && CS_TYPE_BINARY != params.dest_collation_) + || lib::is_oracle_mode()) && CS_TYPE_INVALID != in.get_collation_type() && CS_TYPE_INVALID != params.dest_collation_ && (ObCharset::charset_type_by_coll(in.get_collation_type()) != ObCharset::charset_type_by_coll(params.dest_collation_))) { char *buf = NULL; - // buf_len is related to the encoding length, gbk uses 2 bytes to encode a character, utf8mb4 uses 1 to 4 bytes - // CharConvertFactorNum is a multiple of the requested memory size - const int32_t CharConvertFactorNum = 2; + const int32_t CharConvertFactorNum = 4; int32_t buf_len = str.length() * CharConvertFactorNum; uint32_t result_len = 0; if (OB_UNLIKELY(NULL == (buf = static_cast(params.alloc(buf_len))))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_ERROR("alloc memory failed", K(ret)); - } else if (OB_FAIL(ObCharset::charset_convert(in.get_collation_type(), - str.ptr(), - str.length(), - params.dest_collation_, - buf, - buf_len, - result_len))) { - LOG_WARN("charset convert failed", K(ret), K(in.get_collation_type()), K(params.dest_collation_)); + } else { + ret = ObCharset::charset_convert(in.get_collation_type(), + str.ptr(), + str.length(), + params.dest_collation_, + buf, + buf_len, + result_len); + if (OB_SUCCESS != ret) { + int32_t str_offset = 0; + int32_t buf_offset = 0; + ObString question_mark("?"); + while (str_offset < str.length() && buf_offset + question_mark.length() <= buf_len) { + int64_t offset = ObCharset::charpos(in.get_collation_type(), str.ptr() + str_offset, + str.length() - str_offset, 1); + ret = ObCharset::charset_convert(in.get_collation_type(), str.ptr() + str_offset, + static_cast(offset), params.dest_collation_, buf + buf_offset, buf_len - buf_offset, result_len); + str_offset += static_cast(offset); + if (OB_SUCCESS == ret && result_len > 0) { + buf_offset += result_len; + } else { + MEMCPY(buf + buf_offset, question_mark.ptr(), question_mark.length()); + buf_offset += question_mark.length(); + } + } + if (str_offset < str.length()) { + ret = OB_SIZE_OVERFLOW; + LOG_WARN("size overflow", K(ret), K(str)); + } else { + // The log is printed here to remind that there are characters that fail to convert and are replaced by '?' + LOG_DEBUG("charset convert failed", K(ret), K(in.get_collation_type()), K(params.dest_collation_)); + result_len = static_cast(buf_offset); + ret = OB_SUCCESS; + } + } } LOG_DEBUG("convert result", K(str), "result", ObHexEscapeSqlStr(ObString(result_len, buf))); diff --git a/src/common/ob_obj_type.h b/src/common/ob_obj_type.h index 625e4bba8..4e034eb64 100644 --- a/src/common/ob_obj_type.h +++ b/src/common/ob_obj_type.h @@ -90,6 +90,8 @@ enum ObObjType ObNCharType = 44, // nchar ObURowIDType = 45, // UROWID ObLobType = 46, // Oracle Lob + ObJsonType = 47, // Json Type + ObGeometryType = 48, // Geometry type ObMaxType // invalid type, or count of obj type }; @@ -295,7 +297,7 @@ inline bool ob_is_blob(const ObObjType type, const ObCollationType cs_type) inline bool is_obj_type_supported(ObObjType type) { return (type > ObNullType && type < ObUnknownType) - || ob_is_otimestamp_type(type); + || ob_is_otimestamp_type(type) || ob_is_number_tc(type); } // to_string adapter diff --git a/src/common/ob_object.cpp b/src/common/ob_object.cpp index 33b29d482..774296abd 100644 --- a/src/common/ob_object.cpp +++ b/src/common/ob_object.cpp @@ -249,7 +249,7 @@ int64_t ObObj::get_deep_copy_size() const int64_t ret = 0; if (is_string_type()) { ret += val_len_; - } else if (ObNumberType == meta_.get_type() || ObUNumberType == meta_.get_type()) { + } else if (ob_is_number_tc(get_type())) { ret += (sizeof(uint32_t) * nmb_desc_.len_); } return ret; @@ -443,7 +443,7 @@ ObObjTypeFuncs OBJ_FUNCS[ObMaxType] = DEF_FUNC_ENTRY(ObRawType), // 39, raw DEF_FUNC_ENTRY(ObNullType), // 40 DEF_FUNC_ENTRY(ObNullType), // 41 - DEF_FUNC_ENTRY(ObNullType), // 42 + DEF_FUNC_ENTRY(ObNumberFloatType), // 42 DEF_FUNC_ENTRY(ObNVarchar2Type), // 43, nvarchar2 DEF_FUNC_ENTRY(ObNCharType), // 44, nchar }; diff --git a/src/common/ob_object.h b/src/common/ob_object.h index 8db10adb4..f29788d33 100644 --- a/src/common/ob_object.h +++ b/src/common/ob_object.h @@ -383,6 +383,13 @@ class ObObj void set_time_value(const int64_t value); void set_year_value(const uint8_t value); + void set_timestamp_tz(const int64_t time_us, const uint32_t time_ctx_desc) { set_otimestamp_value(ObTimestampTZType, time_us, time_ctx_desc); } + void set_timestamp_ltz(const int64_t time_us, const uint16_t time_desc) { set_otimestamp_value(ObTimestampLTZType, time_us, time_desc); } + void set_timestamp_nano(const int64_t time_us, const uint16_t time_desc) { set_otimestamp_value(ObTimestampNanoType, time_us, time_desc); } + void set_timestamp_tz(const ObOTimestampData &value) { set_otimestamp_value(ObTimestampTZType, value); } + void set_timestamp_ltz(const ObOTimestampData &value) { set_otimestamp_value(ObTimestampLTZType, value); } + void set_timestamp_nano(const ObOTimestampData &value) { set_otimestamp_value(ObTimestampNanoType, value); } + void set_string(const ObObjType type, const char *ptr, const ObString::obstr_size_t size); void set_string(const ObObjType type, const ObString &value); void set_varchar(const ObString &value); diff --git a/src/common/ob_partition_key.h b/src/common/ob_partition_key.h index 426dc9575..0947578e0 100644 --- a/src/common/ob_partition_key.h +++ b/src/common/ob_partition_key.h @@ -49,8 +49,10 @@ struct ObPartitionKey int init(const uint64_t table_id, const int32_t partition_idx, const int32_t partition_cnt); int parse(const char* str); - void reset(); - bool is_valid() const; + /* this function is defined for c driver client compile */ + void reset() {}; + /* this function is defined for c driver client compile */ + bool is_valid() const {return true;}; uint64_t hash() const; uint64_t inner_hash() const; int compare(const ObPartitionKey &other) const; diff --git a/src/common/ob_queue_thread.h b/src/common/ob_queue_thread.h index 243fd6e1a..22618a17c 100644 --- a/src/common/ob_queue_thread.h +++ b/src/common/ob_queue_thread.h @@ -40,11 +40,19 @@ class ObCond static const int64_t SPIN_WAIT_NUM = 0; static const int64_t BUSY_INTERVAL = 1000; public: - explicit ObCond(const int64_t spin_wait_num = SPIN_WAIT_NUM); - ~ObCond(); + /* this function is defined for c driver client compile */ + explicit ObCond(const int64_t spin_wait_num = SPIN_WAIT_NUM) :spin_wait_num_(spin_wait_num) {} + /* this function is defined for c driver client compile */ + ~ObCond() {} public: - void signal(); - int timedwait(const int64_t time_us); + /* this function is defined for c driver client compile */ + void signal() {} + /* this function is defined for c driver client compile */ + int timedwait(const int64_t time_us) + { + UNUSED(time_us); + return OB_NOT_IMPLEMENT; + } int wait(); private: const int64_t spin_wait_num_; diff --git a/src/common/ob_range2.h b/src/common/ob_range2.h index f208a81b9..c41c12f02 100644 --- a/src/common/ob_range2.h +++ b/src/common/ob_range2.h @@ -19,6 +19,8 @@ #include "common/ob_range.h" #include "lib/utility/utility.h" #include "lib/regex/ob_regex.h" +#include "lib/allocator/ob_allocator.h" +#include "obproxy/opsql/expr_parser/ob_expr_parse_result.h" namespace oceanbase @@ -100,6 +102,45 @@ struct ObNewRange : public RowkeyInfoHolder return ret; } + int build_row_key(int64_t columns_num, ObIAllocator &allocator) { + // build row key like (min, min, min : max, max, max) + int ret = OB_SUCCESS; + if (columns_num < 0 || columns_num > OBPROXY_MAX_PART_LEVEL) { + ret = OB_INVALID_ARGUMENT; + COMMON_LOG(WARN, "invalid", K(columns_num)); + } else { + void *start_objs_buf = NULL; + void *end_objs_buf = NULL; + if (OB_ISNULL((start_objs_buf = allocator.alloc(sizeof(ObObj) * columns_num))) && columns_num != 0) { + ret = OB_ALLOCATE_MEMORY_FAILED; + COMMON_LOG(WARN, "fail to alloc new obj", K(ret), K(columns_num)); + } else if (OB_ISNULL(end_objs_buf = allocator.alloc(sizeof(ObObj) * columns_num)) && columns_num !=0) { + ret = OB_ALLOCATE_MEMORY_FAILED; + COMMON_LOG(WARN, "fail to alloc new obj", K(ret), K(columns_num)); + } else { + for (int i = 0; OB_SUCC(ret) && i < columns_num; i++) { + ObObj *start = NULL; + ObObj *end = NULL; + if (OB_ISNULL(start = new (reinterpret_cast(start_objs_buf) + i) ObObj())) { + ret = OB_ERR_UNEXPECTED; + COMMON_LOG(WARN, "failed to do placement new", K(start_objs_buf), K(ret)); + } else if (OB_ISNULL(end = new (reinterpret_cast(end_objs_buf) + i) ObObj())) { + ret = OB_ERR_UNEXPECTED; + COMMON_LOG(WARN, "failed to do placement new", K(end_objs_buf), K(ret)); + } else { + start->set_min_value(); + end->set_max_value(); + } + } + if (OB_SUCC(ret)) { + start_key_.assign(reinterpret_cast(start_objs_buf), columns_num); + end_key_.assign(reinterpret_cast(end_objs_buf), columns_num); + } + } + } + return ret; + } + // new compare func for tablet.range and scan_param.range inline int compare_with_endkey2(const ObNewRange &r) const { diff --git a/src/common/obsm_utils.cpp b/src/common/obsm_utils.cpp index 9ee7818d4..6ecb0e8de 100644 --- a/src/common/obsm_utils.cpp +++ b/src/common/obsm_utils.cpp @@ -310,6 +310,12 @@ int ObSMUtils::get_ob_type(ObObjType &ob_type, EMySQLFieldType mysql_type) case OB_MYSQL_TYPE_OB_UROWID: ob_type = ObURowIDType; break; + case OB_MYSQL_TYPE_JSON: + ob_type = ObJsonType; + break; + case OB_MYSQL_TYPE_GEOMETRY: + ob_type = ObGeometryType; + break; default: _OB_LOG(WARN, "unsupport MySQL type %d", mysql_type); ret = OB_OBJ_TYPE_ERROR; diff --git a/src/lib/Makemodule.am b/src/lib/Makemodule.am index 25b2d24a1..a828a2be8 100644 --- a/src/lib/Makemodule.am +++ b/src/lib/Makemodule.am @@ -47,6 +47,7 @@ lib/charset/ob_ctype_uca.c\ lib/charset/ob_ctype_mb.c\ lib/charset/ob_ctype_bin.c\ lib/charset/ob_ctype_simple.c\ +lib/charset/ob_ctype_latin1.c\ lib/charset/ob_mysql_global.h\ lib/charset/ob_config.h\ lib/charset/ob_dtoa.h\ @@ -157,6 +158,7 @@ lib/oblog/ob_trace_log.h\ lib/oblog/ob_trace_log.cpp\ lib/oblog/ob_warning_buffer.h\ lib/oblog/ob_warning_buffer.cpp\ +lib/oblog/ob_simple_trace.h\ lib/queue/ob_dedup_queue.h\ lib/queue/ob_dedup_queue.cpp\ lib/queue/ob_fixed_queue.h\ diff --git a/src/lib/allocator/ob_concurrent_fifo_allocator.h b/src/lib/allocator/ob_concurrent_fifo_allocator.h index 10c0cdd33..496d747a2 100644 --- a/src/lib/allocator/ob_concurrent_fifo_allocator.h +++ b/src/lib/allocator/ob_concurrent_fifo_allocator.h @@ -21,17 +21,36 @@ namespace common class ObConcurrentFIFOAllocator : public common::ObIAllocator { public: - ObConcurrentFIFOAllocator(); - virtual ~ObConcurrentFIFOAllocator(); + /* this function is defined for c driver client compile */ + ObConcurrentFIFOAllocator() {}; + /* this function is defined for c driver client compile */ + virtual ~ObConcurrentFIFOAllocator() {}; public: + /* this function is defined for c driver client compile */ int init(const int64_t total_limit, const int64_t hold_limit, - const int64_t page_size); - void destroy(); + const int64_t page_size) + { + UNUSED(total_limit); + UNUSED(hold_limit); + UNUSED(page_size); + return OB_NOT_IMPLEMENT; + } + /* this function is defined for c driver client compile */ + void destroy() {}; public: void set_mod_id(const int64_t mod_id); - void *alloc(const int64_t size); - void free(void *ptr); + /* this function is defined for c driver client compile */ + void *alloc(const int64_t size) + { + UNUSED(size); + return nullptr; + } + /* this function is defined for c driver client compile */ + void free(void *ptr) + { + UNUSED(ptr); + } int64_t allocated(); int64_t hold() const {return 0;} int64_t get_direct_alloc_count(); diff --git a/src/lib/allocator/ob_fifo_allocator.h b/src/lib/allocator/ob_fifo_allocator.h index 2db3b588b..c57b38df2 100644 --- a/src/lib/allocator/ob_fifo_allocator.h +++ b/src/lib/allocator/ob_fifo_allocator.h @@ -89,16 +89,26 @@ class ObFIFOAllocator : public common::ObIAllocator static const int64_t ALREADY_FREE = 0xf5eebef0; static const int64_t SPECIAL_FLAG = -1; public: - ObFIFOAllocator(); - ~ObFIFOAllocator(); - + /* this function is defined for c driver client compile */ + ObFIFOAllocator() {}; + /* this function is defined for c driver client compile */ + ~ObFIFOAllocator() {}; + + /* this function is defined for c driver client compile */ int init(ObIAllocator *allocator, const int64_t page_size, - const int64_t page_hold_limit = 32); - void reset(); + const int64_t page_hold_limit = 32) + { + UNUSED(allocator); + UNUSED(page_size); + UNUSED(page_hold_limit); + return OB_NOT_IMPLEMENT; + } + /* this function is defined for c driver client compile */ + void reset() { /* not support */ } void reuse() { /* not support */ } - void *alloc(const int64_t size); + void *alloc(const int64_t size) { UNUSED(size); return NULL; } void *alloc_align(const int64_t size, const int64_t align); - void free(void *p); + void free(void *p) { UNUSED(p); } void set_mod_id(int64_t mod_id); inline int64_t used() const diff --git a/src/lib/allocator/ob_lf_fifo_allocator.h b/src/lib/allocator/ob_lf_fifo_allocator.h index 477ef1c43..d8b78cdf7 100644 --- a/src/lib/allocator/ob_lf_fifo_allocator.h +++ b/src/lib/allocator/ob_lf_fifo_allocator.h @@ -54,8 +54,10 @@ struct HazardSlot class ObLfFIFOAllocator : public common::ObIAllocator { public: - ObLfFIFOAllocator(); - virtual ~ObLfFIFOAllocator(); + /* this function is defined for c driver client compile */ + ObLfFIFOAllocator() {} + /* this function is defined for c driver client compile */ + virtual ~ObLfFIFOAllocator() {} public: int init(const int64_t page_size, const int64_t mod_id, @@ -64,8 +66,9 @@ class ObLfFIFOAllocator : public common::ObIAllocator const int64_t total_limit = INT64_MAX); void destroy(); public: - void *alloc(const int64_t size); - void free(void *ptr); + /* this function is defined for c driver client compile */ + void *alloc(const int64_t size) { UNUSED(size); return NULL; } + void free(void *ptr) { UNUSED(ptr); } bool is_fragment(void *ptr); int64_t allocated() { return allocated_size_; } void set_mod_id(const int64_t mod_id) { mem_attr_.mod_id_ = mod_id; } diff --git a/src/lib/charset/ob_charset.cpp b/src/lib/charset/ob_charset.cpp index 33d4a41cb..2f786eba4 100644 --- a/src/lib/charset/ob_charset.cpp +++ b/src/lib/charset/ob_charset.cpp @@ -26,6 +26,7 @@ const ObCharsetWrapper ObCharset::charset_wrap_arr_[CHARSET_WRAPPER_COUNT] = {CHARSET_GBK, "GBK charset", CS_TYPE_GBK_CHINESE_CI, 2}, {CHARSET_UTF16, "UTF-16 Unicode", CS_TYPE_UTF16_GENERAL_CI, 2}, {CHARSET_GB18030, "GB18030 charset", CS_TYPE_GB18030_CHINESE_CI, 4}, + {CHARSET_LATIN1, "cp1252 West European", CS_TYPE_LATIN1_SWEDISH_CI, 1} }; const ObCollationWrapper ObCharset::collation_wrap_arr_[COLLATION_WRAPPER_COUNT] = @@ -41,11 +42,13 @@ const ObCollationWrapper ObCharset::collation_wrap_arr_[COLLATION_WRAPPER_COUNT] {CS_TYPE_INVALID, CHARSET_INVALID, CS_TYPE_INVALID, false, false, 1}, {CS_TYPE_GB18030_CHINESE_CI, CHARSET_GB18030, CS_TYPE_GB18030_CHINESE_CI, true, true, 1}, {CS_TYPE_GB18030_BIN, CHARSET_GB18030, CS_TYPE_GB18030_BIN, false, true, 1}, + {CS_TYPE_LATIN1_SWEDISH_CI, CHARSET_LATIN1, CS_TYPE_LATIN1_SWEDISH_CI,true, true, 1}, + {CS_TYPE_LATIN1_BIN, CHARSET_LATIN1, CS_TYPE_LATIN1_BIN,false, true, 1} }; void *ObCharset::charset_arr[CS_TYPE_MAX] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 0 ~ 7 - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 8 + &ob_charset_latin1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 8 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // 16 NULL, NULL, NULL, NULL, &ob_charset_gbk_chinese_ci, // 24 NULL, NULL, NULL, // 29 @@ -53,7 +56,7 @@ void *ObCharset::charset_arr[CS_TYPE_MAX] = { NULL, NULL, NULL, NULL, NULL, // 40 &ob_charset_utf8mb4_general_ci, // 45 &ob_charset_utf8mb4_bin, // 46 - NULL, // 47 + &ob_charset_latin1_bin, // 47 NULL, NULL, NULL, NULL, NULL, NULL, // 48 &ob_charset_utf16_general_ci,// 54 &ob_charset_utf16_bin, // 55 @@ -236,8 +239,11 @@ uint32_t ObCharset::locate(ObCollationType collation_type, if (OB_UNLIKELY(start < 0 || start > str1_len)) { result = 0; } else { - start = static_cast(charpos(collation_type, str1, str1_len, start)); - if (static_cast(start) + str2_len > str1_len) { + int ret = OB_SUCCESS; + start = static_cast(charpos(collation_type, str1, str1_len, start, &ret)); + if (OB_FAIL(ret)) { + result = 0; + } else if (static_cast(start) + str2_len > str1_len) { result = 0; } else if (0 == str2_len) { result = static_cast(start) + 1; @@ -513,12 +519,15 @@ int ObCharset::well_formed_len(ObCollationType collation_type, const char *str, } return ret; } + +// Be careful with this function. The return value may be out of range. size_t ObCharset::charpos(const ObCollationType collation_type, - const char *str, - const int64_t str_len, - const int64_t length) + const char *str, + const int64_t str_len, + const int64_t length, + int *ret) { - size_t ret = 0; + size_t res_pos = 0; if (OB_UNLIKELY(collation_type <= CS_TYPE_INVALID || collation_type >= CS_TYPE_MAX) || OB_ISNULL(ObCharset::charset_arr[collation_type])) { @@ -528,10 +537,16 @@ size_t ObCharset::charpos(const ObCollationType collation_type, if (OB_ISNULL(cs->cset)) { LOG_ERROR("unexpected error. invalid argument(s)", K(cs), K(cs->cset)); } else { - ret = cs->cset->charpos(cs, str, str + str_len, length); + res_pos = cs->cset->charpos(cs, str, str + str_len, length); + if (res_pos > str_len) { + res_pos = str_len; + if (OB_NOT_NULL(ret)) { + *ret = OB_ERROR_OUT_OF_RANGE; + } + } } } - return ret; + return res_pos; } bool ObCharset::wildcmp(ObCollationType collation_type, @@ -613,7 +628,7 @@ int ObCharset::wc_mb(ObCollationType collation_type, int32_t wc, char *buff, int int tmp = cs->cset->wc_mb(cs, wc, reinterpret_cast(buff), reinterpret_cast(buff + buff_len)); if (tmp <= 0) { - ret = OB_ERROR; + ret = OB_ERR_INCORRECT_STRING_VALUE; } else { ret = OB_SUCCESS; length = tmp; @@ -647,6 +662,10 @@ const char *ObCharset::charset_name(ObCharsetType charset_type) ret_name = "gb18030"; break; } + case CHARSET_LATIN1: { + ret_name = "latin1"; + break; + } default: { break; } @@ -743,6 +762,10 @@ ObCharsetType ObCharset::charset_type(const ObString &cs_name) charset_type = CHARSET_GBK; } else if (0 == cs_name.case_compare(ob_charset_utf16_general_ci.csname)) { charset_type = CHARSET_UTF16; + } else if (0 == cs_name.case_compare(ob_charset_latin1.csname)) { + charset_type = CHARSET_LATIN1; + } else if (0 == cs_name.case_compare(ob_charset_latin1_bin.csname)) { + charset_type = CHARSET_LATIN1; } return charset_type; } @@ -785,6 +808,10 @@ ObCollationType ObCharset::collation_type(const ObString &cs_name) collation_type = CS_TYPE_UTF16_BIN; } else if (0 == cs_name.case_compare(ob_charset_utf16_general_ci.name)) { collation_type = CS_TYPE_UTF16_GENERAL_CI; + } else if (0 == cs_name.case_compare(ob_charset_latin1.name)) { + collation_type = CS_TYPE_LATIN1_SWEDISH_CI; + } else if (0 == cs_name.case_compare(ob_charset_latin1_bin.name)) { + collation_type = CS_TYPE_LATIN1_BIN; } return collation_type; } @@ -821,6 +848,11 @@ bool ObCharset::is_valid_collation(ObCharsetType charset_type, ObCollationType c || CS_TYPE_UTF16_GENERAL_CI == collation_type) { ret = true; } + } else if (CHARSET_LATIN1 == charset_type) { + if (CS_TYPE_LATIN1_BIN == collation_type + || CS_TYPE_LATIN1_SWEDISH_CI == collation_type) { + ret = true; + } } return ret; } @@ -836,7 +868,9 @@ bool ObCharset::is_valid_collation(int64_t collation_type_int) || CS_TYPE_GBK_BIN == collation_type || CS_TYPE_GBK_CHINESE_CI == collation_type || CS_TYPE_UTF16_BIN == collation_type - || CS_TYPE_UTF16_GENERAL_CI == collation_type; + || CS_TYPE_UTF16_GENERAL_CI == collation_type + || CS_TYPE_LATIN1_BIN == collation_type + || CS_TYPE_LATIN1_SWEDISH_CI == collation_type; } bool ObCharset::is_valid_charset(int64_t cs_type_int) @@ -846,7 +880,8 @@ bool ObCharset::is_valid_charset(int64_t cs_type_int) || CHARSET_UTF8MB4 == charset_type || CHARSET_GBK == charset_type || CHARSET_UTF16 == charset_type - || CHARSET_GB18030 == charset_type; + || CHARSET_GB18030 == charset_type + || CHARSET_LATIN1 == charset_type; } ObCharsetType ObCharset::charset_type_by_coll(ObCollationType collation_type) @@ -878,6 +913,11 @@ ObCharsetType ObCharset::charset_type_by_coll(ObCollationType collation_type) charset_type = CHARSET_UTF16; break; } + case CS_TYPE_LATIN1_SWEDISH_CI: + case CS_TYPE_LATIN1_BIN: { + charset_type = CHARSET_LATIN1; + break; + } default: { break; } @@ -1104,6 +1144,10 @@ ObCollationType ObCharset::get_default_collation(ObCharsetType charset_type) collation_type = CS_TYPE_UTF16_GENERAL_CI; break; } + case CHARSET_LATIN1: { + collation_type = CS_TYPE_LATIN1_SWEDISH_CI; + break; + } default: { break; } @@ -1135,6 +1179,10 @@ ObCollationType ObCharset::get_default_collation_oracle(ObCharsetType charset_ty collation_type = CS_TYPE_UTF16_BIN; break; } + case CHARSET_LATIN1: { + collation_type = CS_TYPE_LATIN1_BIN; + break; + } default: { break; } @@ -1166,6 +1214,10 @@ int ObCharset::get_default_collation(ObCharsetType charset_type, ObCollationType collation_type = CS_TYPE_UTF16_GENERAL_CI; break; } + case CHARSET_LATIN1: { + collation_type = CS_TYPE_LATIN1_SWEDISH_CI; + break; + } default: { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid charset type", K(ret), K(charset_type)); @@ -1199,6 +1251,10 @@ ObCollationType ObCharset::get_bin_collation(ObCharsetType charset_type) collation_type = CS_TYPE_UTF16_BIN; break; } + case CHARSET_LATIN1: { + collation_type = CS_TYPE_LATIN1_BIN; + break; + } default: { break; } diff --git a/src/lib/charset/ob_charset.h b/src/lib/charset/ob_charset.h index b831f0b31..b209c97c3 100644 --- a/src/lib/charset/ob_charset.h +++ b/src/lib/charset/ob_charset.h @@ -30,15 +30,18 @@ enum ObCharsetType CHARSET_GBK = 3, CHARSET_UTF16 = 4, CHARSET_GB18030 = 5, + CHARSET_LATIN1 = 6, CHARSET_MAX, }; enum ObCollationType { CS_TYPE_INVALID = 0, + CS_TYPE_LATIN1_SWEDISH_CI = 8, CS_TYPE_GBK_CHINESE_CI = 28, CS_TYPE_UTF8MB4_GENERAL_CI = 45, CS_TYPE_UTF8MB4_BIN = 46, + CS_TYPE_LATIN1_BIN = 47, CS_TYPE_UTF16_GENERAL_CI = 54, CS_TYPE_UTF16_BIN = 55, CS_TYPE_BINARY = 63, @@ -100,8 +103,8 @@ class ObCharset virtual ~ObCharset() {}; public: - static const int64_t CHARSET_WRAPPER_COUNT = 5; - static const int64_t COLLATION_WRAPPER_COUNT = 11; + static const int64_t CHARSET_WRAPPER_COUNT = 6; + static const int64_t COLLATION_WRAPPER_COUNT = 13; static double strntod(const char *str, size_t str_len, @@ -201,7 +204,8 @@ class ObCharset static size_t charpos(ObCollationType collation_type, const char *str, const int64_t str_len, - const int64_t length); + const int64_t length, + int *ret = NULL); // match like pattern static bool wildcmp(ObCollationType collation_type, const ObString &str, diff --git a/src/lib/charset/ob_ctype.h b/src/lib/charset/ob_ctype.h index 734cfd6dd..b11d94672 100644 --- a/src/lib/charset/ob_ctype.h +++ b/src/lib/charset/ob_ctype.h @@ -36,6 +36,10 @@ extern "C" { #define OB_UTF16_BIN OB_UTF16 "_bin" #define OB_UTF16_UNICODE_CI OB_UTF16 "_unicode_ci" +#define OB_LATIN1 "latin1" +#define OB_LATIN1_SWEDISH_CI OB_LATIN1 "_swedish_ci" +#define OB_LATIN1_BIN OB_LATIN1 "_bin" + /* wm_wc and wc_mb return codes */ #define OB_CS_ILSEQ 0 // mb_wc wrong sequence #define OB_CS_ILUNI 0 // wc_mb fail to encode Unicode to charset @@ -376,6 +380,7 @@ typedef struct ObCharsetInfo #define ob_toprint(c) ((c) | 64) #define ob_toupper(s,c) (char) ((s)->to_upper[(uchar) (c)]) #define ob_tolower(s,c) (char) ((s)->to_lower[(uchar) (c)]) +#define ob_sort_order(s,c) (char)((s)->sort_order[(uchar)(c)]) #define ob_isalpha(s, c) ((s)->ctype != NULL ? ((s)->ctype+1)[(uchar) (c)] & (_MY_U | _MY_L) : 0) #define ob_isupper(s, c) ((s)->ctype != NULL ? ((s)->ctype+1)[(uchar) (c)] & _MY_U : 0) #define ob_islower(s, c) ((s)->ctype != NULL ? ((s)->ctype+1)[(uchar) (c)] & _MY_L : 0) @@ -412,6 +417,7 @@ extern ObCharsetInfo ob_charset_bin; extern ObCharsetInfo ob_charset_utf8mb4_bin; extern ObCharsetInfo ob_charset_utf8mb4_general_ci; extern ObCharsetInfo ob_charset_latin1; +extern ObCharsetInfo ob_charset_latin1_bin; extern ObCharsetInfo ob_charset_gbk_chinese_ci; extern ObCharsetInfo ob_charset_gbk_bin; extern ObCharsetInfo ob_charset_utf16_general_ci; @@ -422,6 +428,8 @@ extern ObCharsetInfo ob_charset_gb18030_bin; extern ObCollationHandler ob_collation_mb_bin_handler; extern ObCharsetHandler ob_charset_utf8mb4_handler; extern ObCharsetHandler ob_charset_utf16_handler; +extern ObCollationHandler ob_collation_binary_handler; +extern ObCollationHandler ob_collation_8bit_simple_ci_handler; //============================================================================= @@ -582,6 +590,43 @@ int ob_wildcmp_unicode(const ObCharsetInfo *cs, size_t ob_strxfrm_pad(const ObCharsetInfo *cs, uchar *str, uchar *frmend, uchar *strend, uint nweights, uint flags); +uint ob_mbcharlen_8bit(const ObCharsetInfo *cs __attribute__((unused)), + uint c __attribute__((unused))); + +size_t ob_numchars_8bit(const ObCharsetInfo *cs __attribute__((unused)), + const char *b, const char *e); + +size_t ob_charpos_8bit(const ObCharsetInfo *cs __attribute__((unused)), + const char *b __attribute__((unused)), + const char *e __attribute__((unused)), + size_t pos); + + +size_t ob_max_bytes_charpos_8bit(const ObCharsetInfo *cs __attribute__((unused)), + const char *b __attribute__((unused)), + const char *e __attribute__((unused)), + size_t max_bytes, + size_t *char_len); + +size_t ob_well_formed_len_8bit(const ObCharsetInfo *cs __attribute__((unused)), + const char *start, const char *end, + size_t nchars, int *error); + +size_t ob_lengthsp_binary(const ObCharsetInfo *cs __attribute__((unused)), + const char *ptr __attribute__((unused)), + size_t length); + +int ob_mb_ctype_8bit(const ObCharsetInfo *cs, int *ctype, + const uchar *s, const uchar *e); + +size_t ob_caseup_8bit(const ObCharsetInfo *cs __attribute__((unused)), + char* src __attribute__((unused)), size_t srclen __attribute__((unused)), + char* dst __attribute__((unused)), size_t dstlen __attribute__((unused))); + +size_t ob_casedn_8bit(const ObCharsetInfo *cs __attribute__((unused)), + char* src __attribute__((unused)), size_t srclen __attribute__((unused)), + char* dst __attribute__((unused)), size_t dstlen __attribute__((unused))); + #ifdef __cplusplus } #endif diff --git a/src/lib/charset/ob_ctype_bin.c b/src/lib/charset/ob_ctype_bin.c index 31719d75b..00c070622 100644 --- a/src/lib/charset/ob_ctype_bin.c +++ b/src/lib/charset/ob_ctype_bin.c @@ -128,7 +128,7 @@ static int ob_wc_mb_bin(const ObCharsetInfo *cs __attribute__((unused)), return OB_CS_ILUNI; } -static int ob_mb_ctype_8bit(const ObCharsetInfo *cs, int *ctype, +int ob_mb_ctype_8bit(const ObCharsetInfo *cs, int *ctype, const unsigned char *str, const unsigned char *end) { if (str >= end) { @@ -375,7 +375,7 @@ static ObCharsetHandler ob_charset_handler= ob_scan_8bit }; -static ObCollationHandler ob_collation_binary_handler = +ObCollationHandler ob_collation_binary_handler = { ob_strnncoll_binary, ob_strnncollsp_binary, diff --git a/src/lib/charset/ob_ctype_latin1.c b/src/lib/charset/ob_ctype_latin1.c new file mode 100644 index 000000000..27262d00f --- /dev/null +++ b/src/lib/charset/ob_ctype_latin1.c @@ -0,0 +1,407 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase CE is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +/* +* +* Version: $Id +* +* Authors: +* - initial release +* +*/ +#include "lib/charset/ob_mysql_global.h" +#include "lib/charset/ob_ctype.h" +#include "lib/utility/ob_macro_utils.h" + +static unsigned char ctype_latin1[] = { + 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 72, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 16, 16, 16, 16, 16, + 16, 16, 129, 129, 129, 129, 129, 129, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 16, + 16, 16, 130, 130, 130, 130, 130, 130, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 16, 16, 16, + 32, 16, 0, 16, 2, 16, 16, 16, 16, 16, 16, 1, 16, 1, 0, 1, + 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 2, 0, 2, + 1, 72, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 16, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 16, 2, 2, 2, 2, 2, 2, 2, + 2}; + +static unsigned char to_lower_latin1[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, + 242, 243, 244, 245, 246, 215, 248, 249, 250, 251, 252, 253, 254, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255}; + +static unsigned char to_upper_latin1[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 247, 216, 217, 218, 219, 220, 221, 222, + 255}; + +static unsigned char sort_order_latin1[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 65, 65, 65, + 65, 92, 91, 92, 67, 69, 69, 69, 69, 73, 73, 73, 73, 68, 78, + 79, 79, 79, 79, 93, 215, 216, 85, 85, 85, 89, 89, 222, 223, 65, + 65, 65, 65, 92, 91, 92, 67, 69, 69, 69, 69, 73, 73, 73, 73, + 68, 78, 79, 79, 79, 79, 93, 247, 216, 85, 85, 85, 89, 89, 222, + 255}; + + +static unsigned short cs_to_uni[] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, + 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, + 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, + 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023, + 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, + 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, + 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, + 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, + 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, 0x0060, 0x0061, 0x0062, + 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B, + 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, + 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, + 0x007E, 0x007F, 0x20AC, 0x0081, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, + 0x2021, 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008D, 0x017D, 0x008F, + 0x0090, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, 0x02DC, + 0x2122, 0x0161, 0x203A, 0x0153, 0x009D, 0x017E, 0x0178, 0x00A0, 0x00A1, + 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A8, 0x00A9, 0x00AA, + 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3, + 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, + 0x00BD, 0x00BE, 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, + 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, + 0x00CF, 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E0, + 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, + 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, 0x00F0, 0x00F1, 0x00F2, + 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB, + 0x00FC, 0x00FD, 0x00FE, 0x00FF}; +static unsigned char pl00[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, + 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, + 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x00, 0x81, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x8F, + 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x9D, 0x00, 0x00, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, + 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, + 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, + 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, + 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, + 0xFC, 0xFD, 0xFE, 0xFF}; +static unsigned char pl01[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x9C, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8A, 0x9A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x9F, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}; +static unsigned char pl02[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}; +static unsigned char pl20[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, 0x86, 0x87, 0x95, 0x00, + 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x9B, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}; +static unsigned char pl21[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}; +static unsigned char *uni_to_cs[] = { + pl00, pl01, pl02, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + pl20, pl21, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; + + +static int ob_mb_wc_latin1(const ObCharsetInfo *cs __attribute__((unused)), + ob_wc_t *pwc, const unsigned char *str, const unsigned char *end) { + + if (str >= end) return OB_CS_TOOSMALL; + *pwc = cs_to_uni[*str]; + return (!pwc[0] && str[0]) ? -1 : 1; + +} + +static int ob_wc_mb_latin1(const ObCharsetInfo *cs __attribute__((unused)), + ob_wc_t wc, unsigned char *str, unsigned char *end) { + const unsigned char *pl; + + if (str >= end) return OB_CS_TOOSMALL; + + if (wc > 0xFFFF) return OB_CS_ILUNI; + + pl = uni_to_cs[wc >> 8]; + str[0] = pl ? pl[wc & 0xFF] : '\0'; + return (!str[0] && wc) ? OB_CS_ILUNI : 1; +} + + + +static ObCharsetHandler ob_charset_latin1_handler= +{ + //NULL, /* init */ + NULL, /* ismbchar */ + ob_mbcharlen_8bit, /* mbcharlen */ + ob_numchars_8bit, + ob_charpos_8bit, + ob_max_bytes_charpos_8bit, + ob_well_formed_len_8bit, + ob_lengthsp_binary, + //ob_numcells_8bit, + ob_mb_wc_latin1, + ob_wc_mb_latin1, + ob_mb_ctype_8bit, + //ob_case_str_bin, + //ob_case_str_bin, + ob_caseup_8bit, + ob_casedn_8bit, + //ob_snprintf_8bit, + //ob_long10_to_str_8bit, + //ob_longlong10_to_str_8bit, + ob_fill_8bit, + ob_strntol_8bit, + ob_strntoul_8bit, + ob_strntoll_8bit, + ob_strntoull_8bit, + ob_strntod_8bit, + //ob_strtoll10_8bit, + ob_strntoull10rnd_8bit, + ob_scan_8bit +}; + + + + + +ObCharsetInfo ob_charset_latin1 = { + 8,0,0, /* number */ + OB_CS_COMPILED | OB_CS_PRIMARY, /* state */ + OB_LATIN1, /* cs name */ + OB_LATIN1_SWEDISH_CI, /* name */ + "cp1252 West European", /* comment */ + NULL, /* tailoring */ + //NULL, /* coll_param */ + ctype_latin1, + to_lower_latin1, + to_upper_latin1, + sort_order_latin1, + NULL, /* uca */ + //NULL, /* tab_to_uni */ + //NULL, /* tab_from_uni */ + &ob_unicase_default, /* caseinfo */ + NULL, /* state_map */ + NULL, /* ident_map */ + 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ + 1, /* mbminlen */ + 1, /* mbmaxlen */ + 0, /* min_sort_char */ + 0xFF, /* max_sort_char */ + ' ', /* pad char */ + 0, /* escape_with_backslash_is_dangerous */ + 1, /* levels_for_compare */ + 1, /* levels_for_order */ + &ob_charset_latin1_handler, + &ob_collation_8bit_simple_ci_handler}; + +ObCharsetInfo ob_charset_latin1_bin = { + 47,0,0, /* number */ + OB_CS_COMPILED | OB_CS_BINSORT, /* state */ + OB_LATIN1, /* cs name */ + OB_LATIN1_BIN, /* name */ + "cp1252 West European", /* comment */ + NULL, /* tailoring */ + ctype_latin1, + to_lower_latin1, + to_upper_latin1, + NULL, /* sort_order */ + NULL, /* uca */ + //NULL, /* tab_to_uni */ + //NULL, /* tab_from_uni */ + &ob_unicase_default, /* caseinfo */ + NULL, /* state_map */ + NULL, /* ident_map */ + 1, /* strxfrm_multiply */ + 1, /* caseup_multiply */ + 1, /* casedn_multiply */ + 1, /* mbminlen */ + 1, /* mbmaxlen */ + 0, /* min_sort_char */ + 0xFF, /* max_sort_char */ + ' ', /* pad char */ + 0, /* escape_with_backslash_is_dangerous */ + 1, /* levels_for_compare */ + 1, /* levels_for_order */ + &ob_charset_latin1_handler, + &ob_collation_binary_handler}; + diff --git a/src/lib/charset/ob_ctype_simple.c b/src/lib/charset/ob_ctype_simple.c index 9fbee8702..601f39061 100644 --- a/src/lib/charset/ob_ctype_simple.c +++ b/src/lib/charset/ob_ctype_simple.c @@ -814,3 +814,262 @@ size_t ob_strxfrm_pad(const ObCharsetInfo *cs, unsigned char *str, unsigned char return frm_end - str; } +size_t ob_caseup_8bit(const ObCharsetInfo *cs __attribute__((unused)), + char* src __attribute__((unused)), size_t srclen __attribute__((unused)), + char* dst __attribute__((unused)), size_t dstlen __attribute__((unused))){ + const char *end = src + srclen; + ob_charset_assert(src == dst && srclen == dstlen); + for (; src != end; src++) *src = ob_toupper(cs,*src); + return srclen; +} + +size_t ob_casedn_8bit(const ObCharsetInfo *cs __attribute__((unused)), + char* src __attribute__((unused)), size_t srclen __attribute__((unused)), + char* dst __attribute__((unused)), size_t dstlen __attribute__((unused))){ + char *end = src + srclen; + ob_charset_assert(src == dst && srclen == dstlen); + for (; src != end; src++) *src = ob_tolower(cs,*src); + return srclen; +} + +int ob_strnncoll_simple(const ObCharsetInfo *cs __attribute__((unused)), + const uchar *s, size_t slen, + const uchar *t, size_t tlen, + bool is_prefix) +{ + size_t len = (slen > tlen) ? tlen : slen; + if (is_prefix && slen > tlen) slen = tlen; + while (len--) { + if(ob_sort_order(cs,*s)!=ob_sort_order(cs,*t)) { + return (int)ob_sort_order(cs,*s) - (int)ob_sort_order(cs,*t); + } + s++; + t++; + } + return slen > tlen ? 1 : slen < tlen ? -1 : 0; +} + +static int ob_strnncollsp_simple(const ObCharsetInfo *cs + __attribute__((unused)), + const uchar *s, size_t slen, + const uchar *t, size_t tlen, + bool diff_if_only_endspace_difference + __attribute__((unused))) +{ + size_t len = (slen > tlen) ? tlen : slen; + for (size_t i = 0; i < len; i++){ + if(ob_sort_order(cs,*s)!=ob_sort_order(cs,*t)) { + return (int)ob_sort_order(cs,*s) - (int)ob_sort_order(cs,*t); + } + s++; + t++; + } + int res = 0; + if (slen != tlen) { + int swap = 1; + if (diff_if_only_endspace_difference){ + res=1; + } + /* + Check the next not space character of the longer key. If it's < ' ', + then it's smaller than the other key. + */ + if (slen < tlen) { + slen = tlen; + + s = t; + swap = -1; + res = -res; + } + /* + "a" == "a " + "a\0" < "a" + "a\0" < "a " + */ + for (const unsigned char* end = s + slen - len; s < end; s++) { + if (ob_sort_order(cs,*s) != ob_sort_order(cs,(int)(' '))) + return ob_sort_order(cs,*s) < ob_sort_order(cs,(int)(' ')) ? -swap : swap; + } + } + return res; +} + + + +static size_t ob_strnxfrm_simple(const ObCharsetInfo* cs __attribute__((unused)), unsigned char* dst, size_t dstlen, + uint nweights, const unsigned char* src, size_t srclen, unsigned int flags, bool* is_valid_unicode) +{ + uchar *dst0 = dst; + const uchar *end; + const uchar *remainder; + size_t frmlen; + frmlen = dstlen > nweights ? nweights : dstlen; + frmlen = frmlen > srclen ? srclen : frmlen; + end = src + frmlen; + remainder = src + (frmlen % 8); + for (; src < remainder;) *dst++ = ob_sort_order(cs,*src++); + while(src < end) { + *dst++ = ob_sort_order(cs,*src++); + *dst++ = ob_sort_order(cs,*src++); + *dst++ = ob_sort_order(cs,*src++); + *dst++ = ob_sort_order(cs,*src++); + *dst++ = ob_sort_order(cs,*src++); + *dst++ = ob_sort_order(cs,*src++); + *dst++ = ob_sort_order(cs,*src++); + *dst++ = ob_sort_order(cs,*src++); + } + return ob_strxfrm_pad_desc_and_reverse(cs, dst0, dst, dst0 + dstlen, nweights - srclen, flags, 0); +} + +#define likeconv(s, A) (A) +#define INC_PTR(cs, A, B) (A)++ + +static int ob_wildcmp_8bit_impl(const ObCharsetInfo* cs, const char* str_ptr, const char* str_end_ptr, + const char* wild_str, const char* wild_end, int escape_char, int w_one_char, int w_many_char, int recurse_level) +{ + int cmp_result = -1; + + while (wild_str != wild_end) { + while (*wild_str != w_many_char && *wild_str != w_one_char) { + if (*wild_str == escape_char && wild_str + 1 != wild_end) { + wild_str++; + } + if (str_ptr == str_end_ptr || likeconv(cs, *wild_str++) != likeconv(cs, *str_ptr++)) { + return 1; + } + if (wild_str == wild_end) { + return str_ptr != str_end_ptr; + } + cmp_result = 1; + } + if (*wild_str == w_one_char) { + do { + if (str_ptr == str_end_ptr) { + return (cmp_result); + } + INC_PTR(cs, str_ptr, str_end_ptr); + } while (++wild_str < wild_end && *wild_str == w_one_char); + if (wild_str == wild_end) { + break; + } + } + if (*wild_str == w_many_char) { + unsigned char cmp = 0; + wild_str++; + for (; wild_str != wild_end; wild_str++) { + if (*wild_str == w_many_char) { + continue; + } + if (*wild_str == w_one_char) { + if (str_ptr == str_end_ptr) { + return (-1); + } + INC_PTR(cs, str_ptr, str_end_ptr); + continue; + } + break; + } + if (wild_str == wild_end) { + return (0); + } + if (str_ptr == str_end_ptr) { + return (-1); + } + + if ((cmp = *wild_str) == escape_char && wild_str + 1 != wild_end) { + cmp = *++wild_str; + } + + INC_PTR(cs, wild_str, wild_end); + cmp = likeconv(cs, cmp); + do { + while (str_ptr != str_end_ptr && (unsigned char)likeconv(cs, *str_ptr) != cmp) { + str_ptr++; + } + if (str_ptr++ == str_end_ptr) { + return -1; + } + do { + int tmp = ob_wildcmp_8bit_impl( + cs, str_ptr, str_end_ptr, wild_str, wild_end, escape_char, w_one_char, w_many_char, recurse_level + 1); + if (tmp <= 0) { + return tmp; + } + } while (0); + } while (str_ptr != str_end_ptr); + return -1; + } + } + return str_ptr != str_end_ptr ? 1 : 0; +} + +int ob_wildcmp_8bit(const ObCharsetInfo* cs, const char* str, const char* str_end, const char* wildstr, + const char* wildend, int escape, int w_one, int w_many) +{ + return ob_wildcmp_8bit_impl(cs, str, str_end, wildstr, wildend, escape, w_one, w_many, 1); +} + + +uint ob_instr_simple(const ObCharsetInfo* cs __attribute__((unused)), const char* b, size_t b_length, + const char* s, size_t s_length, ob_match_t* match, uint nmatch) +{ + register const unsigned char *str, *search, *end, *search_end; + + if (s_length <= b_length) { + if (!s_length) { + if (nmatch) { + match->beg = 0; + match->end = 0; + match->mb_len = 0; + } + return 1; /* Empty string is always found */ + } + + str = (const unsigned char*)b; + search = (const unsigned char*)s; + end = (const unsigned char*)b + b_length - s_length + 1; + search_end = (const unsigned char*)s + s_length; + + skip: + while (str != end) { + if ((*str++) == (*search)) { + register const unsigned char *i, *j; + + i = str; + j = search + 1; + + while (j != search_end) + if ((*i++) != (*j++)) + goto skip; + + if (nmatch > 0) { + match[0].beg = 0; + match[0].end = (size_t)(str - (const unsigned char*)b - 1); + match[0].mb_len = match[0].end; + + if (nmatch > 1) { + match[1].beg = match[0].end; + match[1].end = match[0].end + s_length; + match[1].mb_len = match[1].end - match[1].beg; + } + } + return 2; + } + } + } + return 0; +} + + +ObCollationHandler ob_collation_8bit_simple_ci_handler = { + // NULL /* init */ + ob_strnncoll_simple, + ob_strnncollsp_simple, + ob_strnxfrm_simple, + //ob_strnxfrmlen_simple, + ob_like_range_simple, + ob_wildcmp_8bit, + //NULL,//ob_strcasecmp_8bit, + ob_instr_simple, + ob_hash_sort_simple, + ob_propagate_simple}; diff --git a/src/lib/hash/ob_build_in_hashmap.h b/src/lib/hash/ob_build_in_hashmap.h index 61fb13c8e..20bfb26df 100644 --- a/src/lib/hash/ob_build_in_hashmap.h +++ b/src/lib/hash/ob_build_in_hashmap.h @@ -16,6 +16,7 @@ #include "lib/hash_func/ob_hash_func.h" #include "lib/hash/ob_hashutils.h" #include "lib/list/ob_intrusive_list.h" +#include "lib/lock/ob_drw_lock.h" namespace oceanbase { @@ -240,11 +241,117 @@ class ObBuildInHashMap return ret; } -private: +protected: ObBuildInBucket buckets_[bucket_num]; int64_t count_; // of elements stored in the map. BucketChain bucket_chain_; }; + +template +class ObBuildInHashMapForRefCount : public ObBuildInHashMap { +public: + // Make embedded types easier to use by importing them to the class namespace. + typedef H Hasher; // Rename and promote. + typedef typename Hasher::Key Key; // Key type. + typedef typename Hasher::Value Value; // Stored value (element) type. + typedef typename Hasher::ListHead ListHead; // Anchor for value chain. + + ObBuildInHashMapForRefCount() : ObBuildInHashMap() {} + + // put a key value pair into HashMap + // @retval OB_SUCCESS for success + // @retval OB_HASH_EXIST when the value's pointer already exist + int set_refactored(Value *value) + { + int ret = OB_SUCCESS; + Key key = Hasher::key(value); + obsys::CWLockGuard wlock(locks_[Hasher::hash(key) % bucket_num]); + ret = ObBuildInHashMap::set_refactored(value); + if (OB_SUCC(ret)) { + Hasher::inc_ref(value); + } + return ret; + } + + // put a key value pair into HashMap + // @retval OB_SUCCESS for success + // @retval OB_HASH_EXIST when the value's key already exist + int unique_set(Value *value) + { + int ret = OB_SUCCESS; + Key key = Hasher::key(value); + obsys::CWLockGuard wlock(locks_[Hasher::hash(key) % bucket_num]); + struct ObBuildInHashMap::ObBuildInBucket &bucket = ObBuildInHashMap::buckets_[Hasher::hash(key) % bucket_num]; + if (!bucket.chain_.in(value)) { + Value *v = bucket.chain_.head_; + while (NULL != v && ((!Hasher::equal(key, Hasher::key(v)) && (v != value)) || 0 == Hasher::get_ref(v))) { + v = ListHead::next(v); + } + if (NULL == v) { + bucket.chain_.push(value); + ++ObBuildInHashMap::count_; + // not empty, put it on the non-empty list. + if (1 == ++(bucket.count_)) { + ObBuildInHashMap::bucket_chain_.push(&bucket); + } + } else { + ret = OB_HASH_EXIST; + } + } else { + ret = OB_HASH_EXIST; + } + if (OB_SUCC(ret)) { + Hasher::inc_ref(value); + } + return ret; + } + + // @retval OB_SUCCESS for success + // @retval OB_HASH_NOT_EXIST for key not exist + int get_refactored(Key key, Value *&value) + { + int ret = OB_HASH_NOT_EXIST; + obsys::CRLockGuard rlock(locks_[Hasher::hash(key) % bucket_num]); + const struct ObBuildInHashMap::ObBuildInBucket &bucket = ObBuildInHashMap::buckets_[Hasher::hash(key) % bucket_num]; + Value *v = bucket.chain_.head_; + while (NULL != v && (!Hasher::equal(key, Hasher::key(v)) || 0 == Hasher::get_ref(v))) { + v = ListHead::next(v); + } + if (NULL != (value = v)) { + ret = OB_SUCCESS;; + } + if (OB_SUCC(ret)) { + while (true) { + int64_t ref = Hasher::get_ref(v); + if(ref > 0) { + if (!Hasher::bcas_ref(value, ref, ref + 1)) { + PAUSE(); + } else { + break; + } + } else { + ret = OB_HASH_NOT_EXIST; + value = NULL; + break; + } + } + } + return ret; + } + + void remove(Value* value) + { + if (NULL != value) { + obsys::CWLockGuard wlock(locks_[Hasher::hash(Hasher::key(value)) % bucket_num]); + ObBuildInHashMap::remove(value); + Hasher::destroy(value); + } + } + +protected: + mutable obsys::CRWLock locks_[bucket_num]; +}; + } // namespace hash } // namespace common } // namespace oceanbase diff --git a/src/lib/lock/ob_bucket_lock.h b/src/lib/lock/ob_bucket_lock.h index 3e850cbb7..a4ef58a3d 100644 --- a/src/lib/lock/ob_bucket_lock.h +++ b/src/lib/lock/ob_bucket_lock.h @@ -23,8 +23,10 @@ namespace common class ObBucketLock { public: - ObBucketLock(); - virtual ~ObBucketLock(); + /* this function is defined for c driver client compile */ + ObBucketLock() {} + /* this function is defined for c driver client compile */ + virtual ~ObBucketLock() {} int init( const uint64_t bucket_cnt, const uint32_t latch_id = ObLatchIds::DEFAULT_BUCKET_LOCK, diff --git a/src/lib/lock/ob_latch.cpp b/src/lib/lock/ob_latch.cpp index a53ef8838..9d717f825 100644 --- a/src/lib/lock/ob_latch.cpp +++ b/src/lib/lock/ob_latch.cpp @@ -279,7 +279,10 @@ int ObLatchWaitQueue::try_lock( COMMON_LOG(ERROR, "Fail to add proc to wait list, ", K(ret)); } } - proc.wait_ = 1; + + if (OB_EAGAIN == ret) { + proc.wait_ = 1; + } } unlock_bucket(bucket); diff --git a/src/lib/net/ob_addr.cpp b/src/lib/net/ob_addr.cpp index ee6fa0bae..eda722a76 100644 --- a/src/lib/net/ob_addr.cpp +++ b/src/lib/net/ob_addr.cpp @@ -28,29 +28,49 @@ namespace common // -------------------------------------------------------- // class ObAddr implements // -------------------------------------------------------- -uint32_t ObAddr::convert_ipv4_addr(const char *ip) +int ObAddr::convert_ipv4_addr(const char *ip) { - in_addr binary; - int iret = 0; - uint32_t result = 0; + int ret = OB_SUCCESS; + in_addr in; if (!OB_ISNULL(ip)) { - memset(&binary, 0, sizeof (binary)); - iret = inet_pton(AF_INET, ip, &binary); - if (iret == -1) { // no support family - binary.s_addr = 0; - } else if (iret == 0) { // invalid ip string - binary.s_addr = 0; + MEMSET(&in, 0, sizeof (in)); + int rt = inet_pton(AF_INET, ip, &in); + if (rt != 1) { // wrong ip or error + in.s_addr = 0; + ret = OB_ERR_UNEXPECTED; + LOG_WARN("convert ipv4 addr failed", K(ip)); + } else { + ip_.v4_ = ntohl(in.s_addr); } - result = ntohl(binary.s_addr); } - return result; + return ret; +} + +int ObAddr::convert_ipv6_addr(const char *ip) +{ + int ret = OB_SUCCESS; + in6_addr in6; + if (!OB_ISNULL(ip)) { + memset(&in6, 0, sizeof(in6)); + ret = inet_pton(AF_INET6, ip, &in6); + if (ret != 1) { + memset(&in6, 0, sizeof(in6)); + ret = OB_ERR_UNEXPECTED; + LOG_WARN("convert ipv6 addr failed", K(ip)); + } else { + ret = OB_SUCCESS; + // Stored here in big-endian format + MEMCPY(ip_.v6_, in6.s6_addr, sizeof(ip_.v6_)); + } + } + return ret; } int ObAddr::parse_from_cstring(const char *ipport) { int ret = OB_SUCCESS; - char buf[INET6_ADDRSTRLEN] = ""; + char buf[MAX_IP_ADDR_LENGTH] = ""; int port = 0; if (!OB_ISNULL(ipport)) { @@ -73,15 +93,16 @@ int ObAddr::parse_from_cstring(const char *ipport) if (OB_SUCC(ret)) { if ('[' != buf[0]) { // IPV4 format - if (false == set_ipv4_addr(buf, port)) - { + if (false == set_ipv4_addr(buf, port)) { ret = OB_INVALID_ARGUMENT; } } else { // IPV6 format const char *ipv6 = buf + 1; if (']' == buf[strlen(buf) - 1]) { buf[strlen(buf) - 1] = '\0'; - IGNORE_RETURN set_ipv6_addr(ipv6, port); + if (!set_ipv6_addr(ipv6, port)) { + ret = OB_INVALID_ARGUMENT; + } } else { ret = OB_INVALID_ARGUMENT; } @@ -109,6 +130,17 @@ int64_t ObAddr::to_string(char *buffer, const int64_t size) const (ip_.v4_ >> 8) & 0xFF, (ip_.v4_) & 0xFF); } + } else if (version_ == IPV6) { + char buf[MAX_IP_ADDR_LENGTH]; + struct in6_addr in6; + memset(buf, 0, sizeof(buf)); + MEMCPY(in6.s6_addr, ip_.v6_, sizeof(ip_.v6_)); + inet_ntop(AF_INET6, &in6, buf, MAX_IP_ADDR_LENGTH); + if (port_ > 0) { + databuff_printf(buffer, size, pos, "\"[%s]:%d\"", buf, port_); + } else { + databuff_printf(buffer, size, pos, "\"%s\"", buf); + } } } return pos; @@ -124,6 +156,13 @@ bool ObAddr::ip_to_string(char *buffer, const int32_t size) const (ip_.v4_ >> 16) & 0xFF, (ip_.v4_ >> 8) & 0xFF, (ip_.v4_) & 0xFF); + } else if (version_ == IPV6) { + char buf[MAX_IP_ADDR_LENGTH]; + struct in6_addr in6; + memset(buf, 0, sizeof(buf)); + MEMCPY(in6.s6_addr, ip_.v6_, sizeof(ip_.v6_)); + inet_ntop(AF_INET6, &in6, buf, MAX_IP_ADDR_LENGTH); + snprintf(buffer, size, "%s", buf); } res = true; } @@ -133,58 +172,74 @@ bool ObAddr::ip_to_string(char *buffer, const int32_t size) const int ObAddr::ip_port_to_string(char *buffer, const int32_t size) const { int ret = OB_SUCCESS; + int ret_len = 0; if (NULL == buffer || size <= 0) { ret = OB_INVALID_ARGUMENT; } else if (version_ == IPV6) { - ret = OB_NOT_SUPPORTED; + char buf[MAX_IP_ADDR_LENGTH]; + struct in6_addr in6; + memset(buf, 0, sizeof(buf)); + MEMCPY(in6.s6_addr, ip_.v6_, sizeof(ip_.v6_)); + inet_ntop(AF_INET6, &in6, buf, MAX_IP_ADDR_LENGTH); + ret_len = snprintf(buffer, size, "[%s]:%d", buf, port_); } else { - int ret_len = snprintf(buffer, size, "%d.%d.%d.%d:%d", + ret_len = snprintf(buffer, size, "%d.%d.%d.%d:%d", (ip_.v4_ >> 24) & 0XFF, (ip_.v4_ >> 16) & 0xFF, (ip_.v4_ >> 8) & 0xFF, (ip_.v4_) & 0xFF, port_); - if (ret_len < 0) { - ret = OB_ERR_SYS; - } else if (ret_len >= size) { - ret = OB_SIZE_OVERFLOW; - } + } + + if (ret_len < 0) { + ret = OB_ERR_SYS; + } else if (ret_len >= size) { + ret = OB_SIZE_OVERFLOW; } return ret; } bool ObAddr::set_ipv6_addr(const char *ip, const int32_t port) { - UNUSED(ip); - UNUSED(port); - _OB_LOG(WARN, "set ipv6 address is not complete"); - return false; -} + bool bret = true; + int ret = OB_SUCCESS; + if (NULL == ip || port < 0) { + bret = false; + } else if (OB_FAIL(convert_ipv6_addr(ip))) { + bret = false; + } else { + version_ = IPV6; + port_ = port; + } + return bret; +} bool ObAddr::set_ipv4_addr(const char *ip, const int32_t port) { - bool ret = true; - if (NULL == ip || port <= 0) { - ret = false; + bool bret = true; + int ret = OB_SUCCESS; + if (NULL == ip || port < 0) { + bret = false; + } else if (OB_FAIL(convert_ipv4_addr(ip))) { + bret = false; } else { version_ = IPV4; - ip_.v4_ = convert_ipv4_addr(ip); port_ = port; } - return ret; + return bret; } -bool ObAddr::set_ipv4_addr(const ObString &ip, const int32_t port) +bool ObAddr::set_ip_addr(const ObString &ip, const int32_t port) { bool ret = true; - char ip_buf[OB_IP_STR_BUFF] = ""; - if (ip.length() >= OB_IP_STR_BUFF) { + char ip_buf[MAX_IP_ADDR_LENGTH] = ""; + if (ip.length() >= MAX_IP_ADDR_LENGTH) { ret = false; } else { // ObString may be not terminated by '\0' MEMCPY(ip_buf, ip.ptr(), ip.length()); - ret = set_ipv4_addr(ip_buf, port); + ret = set_ip_addr(ip_buf, port); } return ret; } @@ -194,8 +249,12 @@ bool ObAddr::is_valid() const bool valid = true; if (port_ <= 0) { valid = false; + } else if (IPV4 == version_) { + valid = (0 != ip_.v4_); + } else if (IPV6 == version_) { + valid = ((0 != ip_.v6_[0]) || (0 != ip_.v6_[1]) || (0 != ip_.v6_[2]) || (0 != ip_.v6_[3])); } else { - valid = (IPV4 == version_) && (0 != ip_.v4_); + valid = false; } return valid; } @@ -235,10 +294,17 @@ void ObAddr::set_ipv4_server_id(const int64_t ipv4_server_id) bool ObAddr::operator <(const ObAddr &rv) const { - if ((version_ != rv.version_) || (IPV4 != version_)) { + int64_t ipcmp = 0; + if (version_ != rv.version_) { LOG_ERROR("comparision between different IP versions hasn't supported!"); + } else if (IPV4 == version_) { + ipcmp = static_cast(ip_.v4_) - static_cast(rv.ip_.v4_); + } else if (IPV6 == version_) { + int pos = 0; + for (; ipcmp == 0 && pos < IPV6_LEN; pos++) { + ipcmp = ip_.v6_[pos] - rv.ip_.v6_[pos]; + } } - int ipcmp = ip_.v4_ - rv.ip_.v4_; return (ipcmp < 0) || (0 == ipcmp && port_ < rv.port_); } @@ -271,6 +337,68 @@ void ObAddr::set_port(int32_t port) port_ = port; } +struct sockaddr_storage ObAddr::get_sockaddr() const +{ + struct sockaddr_storage sock_addr; + memset(&sock_addr, 0, sizeof(struct sockaddr_storage)); + if (version_ == IPV4) { + struct sockaddr_in in; + memset(&in, 0, sizeof(struct sockaddr_in)); + in.sin_family = AF_INET; + in.sin_port = (htons)(static_cast(port_)); + in.sin_addr.s_addr = htonl(ip_.v4_); + MEMCPY(&sock_addr, &in, sizeof(in)); + } else if (version_ == IPV6) { + struct sockaddr_in6 in6; + memset(&in6, 0, sizeof(struct sockaddr_in6)); + in6.sin6_family = AF_INET6; + in6.sin6_port = (htons)(static_cast(port_)); + MEMCPY(in6.sin6_addr.s6_addr, ip_.v6_, sizeof(ip_.v6_)); + MEMCPY(&sock_addr, &in6, sizeof(in6)); + } + + return sock_addr; +} + +void ObAddr::set_sockaddr(const struct sockaddr &sock_addr) +{ + if (sock_addr.sa_family == AF_INET) { + version_ = IPV4; + const struct sockaddr_in &in = (struct sockaddr_in&)(sock_addr); + port_ = ntohs(in.sin_port); + ip_.v4_ = ntohl(in.sin_addr.s_addr); + } else if (sock_addr.sa_family == AF_INET6) { + version_ = IPV6; + const struct sockaddr_in6 &in6 = (struct sockaddr_in6&)(sock_addr); + port_ = ntohs(in6.sin6_port); + MEMCPY(ip_.v6_, in6.sin6_addr.s6_addr, sizeof(ip_.v6_)); + } +} + +bool ObAddr::set_ip_addr(const char *ip, const int32_t port) +{ + bool bret = false; + const char *ch = strchr(ip, ':'); + if (NULL != ch) { + bret = set_ipv6_addr(ip, port); + } else { + bret = set_ipv4_addr(ip, port); + } + return bret; +} + +bool ObAddr::set_ipv6_addr(const uint64_t ipv6_high, const uint64_t ipv6_low, const int32_t port) +{ + bool ret = true; + uint64_t *high = reinterpret_cast(&ip_.v6_[0]); + uint64_t *low = reinterpret_cast(&ip_.v6_[8]); + *high = ipv6_high; + *low = ipv6_low; + version_ = IPV6; + port_= port; + return ret; +} + OB_SERIALIZE_MEMBER(ObAddr, version_, ip_.v6_[0], ip_.v6_[1], ip_.v6_[2], ip_.v6_[3], port_); } // end namespace common diff --git a/src/lib/net/ob_addr.h b/src/lib/net/ob_addr.h index 9b9d0096d..21383a881 100644 --- a/src/lib/net/ob_addr.h +++ b/src/lib/net/ob_addr.h @@ -19,28 +19,33 @@ #include "lib/container/ob_se_array.h" #include "lib/json/ob_yson.h" #include "lib/ob_name_id_def.h" +#include "iocore/net/ob_inet.h" namespace oceanbase { namespace common { +#define IPV6_LEN 16 + class ObAddr { OB_UNIS_VERSION(1); public: enum VER { - IPV4 = 4, IPV6 = 6 + IPV4 = 4, + IPV6 = 6, + IPINVALID, }; ObAddr() - : version_(IPV4), ip_(), port_(0) + : version_(IPINVALID), ip_(), port_(0) { memset(&ip_, 0, sizeof(ip_)); } ObAddr(VER version, const char *ip, const int32_t port) - : version_(IPV4), ip_(), port_(0) + : version_(IPINVALID), ip_(), port_(0) { memset(&ip_, 0, sizeof(ip_)); if (version == IPV4) { @@ -50,15 +55,20 @@ class ObAddr } } + // The server_id format cannot be used in the case of IPV6 + // TODO: Consider removing it explicit ObAddr(const int64_t ipv4_server_id) - : version_(IPV4), ip_(), port_(0) + : version_(IPINVALID), ip_(), port_(0) { + // server_id only supports IPV4 format + version_ = IPV4; ip_.v4_ = static_cast(0x00000000ffffffff & (ipv4_server_id >> 32)); port_ = static_cast(0x00000000ffffffff & ipv4_server_id); } void reset() { + version_ = IPINVALID; port_ = 0; memset(&ip_, 0, sizeof (ip_)); } @@ -68,7 +78,10 @@ class ObAddr return (IPV4 == version_ && INADDR_LOOPBACK == ip_.v4_) || (IPV6 == version_ && IN6_IS_ADDR_LOOPBACK(ip_.v6_)); } - static uint32_t convert_ipv4_addr(const char *ip); + int convert_ipv4_addr(const char *ip); + int convert_ipv6_addr(const char *ip); + struct sockaddr_storage get_sockaddr() const; + void set_sockaddr(const struct sockaddr &sock_addr); int64_t to_string(char *buffer, const int64_t size) const; bool ip_to_string(char *buffer, const int32_t size) const; @@ -76,10 +89,12 @@ class ObAddr TO_YSON_KV(ID(ip), ip_.v4_, ID(port), port_); + bool set_ip_addr(const char *ip, const int32_t port); + bool set_ip_addr(const ObString &ip, const int32_t port); bool set_ipv6_addr(const char *ip, const int32_t port); + bool set_ipv6_addr(const uint64_t ipv6_high, const uint64_t ipv6_low, const int32_t port); bool set_ipv4_addr(const char *ip, const int32_t port); bool set_ipv4_addr(const uint32_t ip, const int32_t port); - bool set_ipv4_addr(const ObString &ip, const int32_t port); int parse_from_cstring(const char *ip_str); int64_t get_ipv4_server_id() const; @@ -89,6 +104,7 @@ class ObAddr bool operator !=(const ObAddr &rv) const; bool operator ==(const ObAddr &rv) const; bool operator < (const ObAddr &rv) const; + ObAddr& operator = (const ObAddr &rv); int compare(const ObAddr &rv) const; bool is_equal_except_port(const ObAddr &rv) const; inline int32_t get_version() const { return version_; } @@ -106,6 +122,8 @@ class ObAddr VER version_; union { + // v4 addresses are stored in native byte order, + // v6 addresses are stored in network byte order uint32_t v4_; //host byte order uint32_t v6_[4]; } ip_; @@ -139,6 +157,16 @@ bool ObAddr::operator ==(const ObAddr &rv) const && ip_.v6_[2] == rv.ip_.v6_[2] && ip_.v6_[3] == rv.ip_.v6_[3]; } +ObAddr& ObAddr::operator =(const ObAddr &rv) +{ + if (this != &rv) { + version_ = rv.version_; + port_ = rv.port_; + MEMCPY(ip_.v6_, rv.ip_.v6_, sizeof(ip_.v6_)); + } + return *this; +} + int ObAddr::compare(const ObAddr &rv) const { return memcmp(this, &rv, sizeof(ObAddr)); diff --git a/src/lib/ob_define.h b/src/lib/ob_define.h index 968ee82f4..e80ff17f9 100644 --- a/src/lib/ob_define.h +++ b/src/lib/ob_define.h @@ -53,7 +53,7 @@ const int64_t OB_MAX_CLUSTER_ID = 4294901759; const int64_t OB_INVALID_CLUSTER_ID = -1; const int64_t OB_INVALID_ORG_CLUSTER_ID = 0; const int64_t OB_MAX_ITERATOR = 16; -const int64_t MAX_IP_ADDR_LENGTH = 32; +const int64_t MAX_IP_ADDR_LENGTH = 64; const int64_t MAX_IP_PORT_LENGTH = MAX_IP_ADDR_LENGTH + 5; const int64_t MAX_IP_PORT_SQL_LENGTH = MAX_IP_ADDR_LENGTH + 10; const int64_t OB_MAX_SQL_ID_LENGTH = 32; @@ -178,7 +178,6 @@ const int64_t OB_MAX_BATCH_NUMBER = 100; const int64_t OB_MAX_TABLET_LIST_NUMBER = 64; const int64_t OB_MAX_DISK_NUMBER = 16; // must no more than ObTimer::MAX_TASK_NUM const int64_t OB_MAX_TIME_STR_LENGTH = 64; -const int64_t OB_IP_STR_BUFF = 30; //TODO: uniform IP/PORR length const int64_t OB_IP_PORT_STR_BUFF = 64; const int64_t OB_RANGE_STR_BUFSIZ = 512; const int64_t OB_MAX_FETCH_CMD_LENGTH = 2048; @@ -573,6 +572,9 @@ static const char *const OB_MYSQL_CLIENT_JDBC_CLIENT_MODE = "__ob_jdbc_client"; // for java client static const char *const OB_MYSQL_JAVA_CLIENT_MODE_NAME = "__ob_java_client"; +// conn attr which transparent transit to observer +static const char *const OB_MYSQL_OB_CLIENT = "__ob_client"; + // for obproxy and observer compatibility enum ObCapabilityFlagShift { @@ -592,6 +594,7 @@ enum ObCapabilityFlagShift OB_CAP_PROXY_SESSION_SYNC_SHIFT, // 13 OB_CAP_PROXY_FULL_LINK_TRACING_SHIFT, // 14 OB_CAP_PROXY_NEW_EXTRA_INFO_SHIFT, // 15 + OB_CAP_PROXY_SESSION_VAR_SYNC_SHIFT, // 16 }; #define OB_TEST_CAPABILITY(cap, tg_cap) (((cap) & (tg_cap)) == (tg_cap)) @@ -610,6 +613,7 @@ enum ObCapabilityFlagShift #define OB_CAP_PROXY_SESSION_SYNC OB_CAP_GET_TYPE(common::OB_CAP_PROXY_SESSION_SYNC_SHIFT) #define OB_CAP_PROXY_FULL_LINK_TRACING OB_CAP_GET_TYPE(common::OB_CAP_PROXY_FULL_LINK_TRACING_SHIFT) #define OB_CAP_PROXY_NEW_EXTRA_INFO OB_CAP_GET_TYPE(common::OB_CAP_PROXY_NEW_EXTRA_INFO_SHIFT) +#define OB_CAP_PROXY_SESSION_VAR_SYNC OB_CAP_GET_TYPE(common::OB_CAP_PROXY_SESSION_VAR_SYNC_SHIFT) // for obproxy debug diff --git a/src/lib/ob_errno.cpp b/src/lib/ob_errno.cpp index 1b1266da7..9814f317a 100644 --- a/src/lib/ob_errno.cpp +++ b/src/lib/ob_errno.cpp @@ -8,11 +8,6 @@ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PubL v2 for more details. - * - * ************************************************************* - * - * DO NOT EDIT. This file is automatically generated from `ob_errno.def'. - * */ #include "ob_errno.h" @@ -2657,6 +2652,14 @@ static struct ObStrErrorInit SQLSTATE[-OB_TRANS_RPC_TIMEOUT] = "25000"; STR_ERROR[-OB_TRANS_RPC_TIMEOUT] = "transaction rpc timeout"; STR_USER_ERROR[-OB_TRANS_RPC_TIMEOUT] = "transaction rpc timeout"; + + // in transaction internal routing, if sql not supported to be executed on participant sent to participant + // server return OB_TRANS_FREE_ROUTE_NOT_SUPPORTED + // proxy downgrade transaction internal routing and send the rest of sql to coordinator + MYSQL_ERRNO[-OB_TRANS_FREE_ROUTE_NOT_SUPPORTED] = -1; + SQLSTATE[-OB_TRANS_FREE_ROUTE_NOT_SUPPORTED] = "HY000"; + STR_ERROR[-OB_TRANS_FREE_ROUTE_NOT_SUPPORTED] = "Query is not supported to be executed on txn participant node"; + STR_USER_ERROR[-OB_TRANS_FREE_ROUTE_NOT_SUPPORTED] = "Query is not supported to be executed on txn participant node"; MYSQL_ERRNO[-OB_LOG_ID_NOT_FOUND] = -1; SQLSTATE[-OB_LOG_ID_NOT_FOUND] = "HY000"; STR_ERROR[-OB_LOG_ID_NOT_FOUND] = "log id not found"; @@ -2883,8 +2886,8 @@ static struct ObStrErrorInit STR_USER_ERROR[-OB_ERR_NULL_DB_VAL_TESTLOAD_TABLE_MAP] = "Null database variable for testload table map to execute testload query"; MYSQL_ERRNO[-OB_ERR_BATCH_INSERT_FOUND] = -1; SQLSTATE[-OB_ERR_BATCH_INSERT_FOUND] = "HY000"; - STR_ERROR[-OB_ERR_BATCH_INSERT_FOUND] = "Batch insert is not supported for sharding table"; - STR_USER_ERROR[-OB_ERR_BATCH_INSERT_FOUND] = "Batch insert is not supported for sharding table"; + STR_ERROR[-OB_ERR_BATCH_INSERT_FOUND] = "Batch insert is not supported"; + STR_USER_ERROR[-OB_ERR_BATCH_INSERT_FOUND] = "Batch insert is not supported"; MYSQL_ERRNO[-OB_ERR_UNSUPPORT_DIFF_TOPOLOGY] = 7202; SQLSTATE[-OB_ERR_UNSUPPORT_DIFF_TOPOLOGY] = "HY000"; STR_ERROR[-OB_ERR_UNSUPPORT_DIFF_TOPOLOGY] = "Not support different topology table join"; diff --git a/src/lib/ob_errno.h b/src/lib/ob_errno.h index 39f10dbe4..df603c1e2 100644 --- a/src/lib/ob_errno.h +++ b/src/lib/ob_errno.h @@ -8,10 +8,6 @@ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. * See the Mulan PubL v2 for more details. - * - * ************************************************************* - * - * DO NOT EDIT. This file is automatically generated from `ob_errno.def'. */ #ifndef OCEANBASE_LIB_OB_ERRNO_H_ @@ -23,6 +19,7 @@ namespace oceanbase { namespace common { + static const int OB_INTERNAL_ERROR = -600; static const int OB_ORA_FATAL_ERROR = -603; static const int64_t OB_MAX_ERROR_CODE = 10000; static const int OB_LAST_ERROR_CODE = -8003; @@ -704,6 +701,7 @@ namespace common static const int OB_PARTITION_IS_STOPPED = -6228; static const int OB_PARTITION_IS_BLOCKED = -6229; static const int OB_TRANS_RPC_TIMEOUT = -6230; + static const int OB_TRANS_FREE_ROUTE_NOT_SUPPORTED = -6279; static const int OB_LOG_ID_NOT_FOUND = -6301; static const int OB_LSR_THREAD_STOPPED = -6302; static const int OB_NO_LOG = -6303; @@ -1425,6 +1423,7 @@ namespace common #define OB_PARTITION_IS_STOPPED__USER_ERROR_MSG "Partition has been stopped" #define OB_PARTITION_IS_BLOCKED__USER_ERROR_MSG "Partition has been blocked" #define OB_TRANS_RPC_TIMEOUT__USER_ERROR_MSG "transaction rpc timeout" +#define OB_TRANS_FREE_ROUTE_NOT_SUPPORTED__USER_ERROR_MSG "Query is not supported to be executed on txn participant node" #define OB_LOG_ID_NOT_FOUND__USER_ERROR_MSG "log id not found" #define OB_LSR_THREAD_STOPPED__USER_ERROR_MSG "log scan runnable thread stop" #define OB_NO_LOG__USER_ERROR_MSG "no log ever scanned" diff --git a/src/lib/ob_name_id_def.h b/src/lib/ob_name_id_def.h index b9cb2d46d..c77b060aa 100644 --- a/src/lib/ob_name_id_def.h +++ b/src/lib/ob_name_id_def.h @@ -334,7 +334,8 @@ enum ObNameId }; // get name at runtime -const char* get_name(int32_t id); +/* this function is defined for c driver client compile */ +inline const char* get_name(int32_t id) {((void)(id)); return nullptr;}; const char* get_description(int32_t id); } // end namespace name_id_map } // end namespace oceanbase diff --git a/src/lib/oblog/ob_async_log_struct.h b/src/lib/oblog/ob_async_log_struct.h index c4ea05d59..79876ece8 100644 --- a/src/lib/oblog/ob_async_log_struct.h +++ b/src/lib/oblog/ob_async_log_struct.h @@ -38,6 +38,7 @@ enum ObLogFDType { FD_POOL_FILE, FD_POOL_STAT_FILE, FD_TRACE_FILE, // ob20 full link trace interface + FD_DRIVER_CLIENT_FILE, MAX_FD_FILE, }; diff --git a/src/lib/oblog/ob_log.cpp b/src/lib/oblog/ob_log.cpp index 0b6928d51..2b9d7e08d 100644 --- a/src/lib/oblog/ob_log.cpp +++ b/src/lib/oblog/ob_log.cpp @@ -375,7 +375,7 @@ ObLogger::~ObLogger() (void)pthread_mutex_destroy(&file_size_mutex_); } -void ObLogger::destory_async_log_thread() +void ObLogger::destroy_async_log_thread() { set_enable_async_log(false); set_stop_flush(); diff --git a/src/lib/oblog/ob_log.h b/src/lib/oblog/ob_log.h index 26359f586..bab4572a2 100644 --- a/src/lib/oblog/ob_log.h +++ b/src/lib/oblog/ob_log.h @@ -283,7 +283,7 @@ class ObLogger public: ~ObLogger(); - void destory_async_log_thread(); + void destroy_async_log_thread(); int init_async_log_thread(const int64_t stacksize = 0); void destroy_free_litem_queue(); diff --git a/src/lib/oblog/ob_log_module.h b/src/lib/oblog/ob_log_module.h index 5f836b2d5..1f6249cfa 100644 --- a/src/lib/oblog/ob_log_module.h +++ b/src/lib/oblog/ob_log_module.h @@ -261,6 +261,11 @@ LOG_MOD_END(STORAGETEST) #define _OBPROXY_TRACE_LOG(level, _fmt_, args...) \ (OB_MONITOR_LOG_NEED_TO_PRINT(level) ? _OB_PRINT_TYPE(FD_TRACE_FILE, NULL, level, _fmt_, ##args) : (void) 0) +#define OBPROXY_DRIVER_CLIENT_LOG(level, infoString, args...) \ + (OB_LOG_NEED_TO_PRINT(level) ? OB_PRINT_TYPE(FD_DRIVER_CLIENT_FILE, NULL, level, infoString, ##args) : (void) 0) +#define _OBPROXY_DRIVER_CLIENT_LOG(level, _fmt_, args...) \ + (OB_LOG_NEED_TO_PRINT(level) ? _OB_PRINT_TYPE(FD_DRIVER_CLIENT_FILE, NULL, level, _fmt_, ##args) : (void) 0) + #define _OB_NUM_LEVEL_LOG(level, _fmt_, args...) \ (OB_LOGGER.need_to_print(level) ? \ diff --git a/src/lib/oblog/ob_log_print_kv.h b/src/lib/oblog/ob_log_print_kv.h index fedee40e4..af937bd4a 100644 --- a/src/lib/oblog/ob_log_print_kv.h +++ b/src/lib/oblog/ob_log_print_kv.h @@ -21,6 +21,7 @@ #include "lib/utility/ob_macro_utils.h" #include "lib/utility/ob_template_utils.h" #include "lib/alloc/alloc_assist.h" +#include "obproxy/ob_proxy_init.h" #define LOG_N_TRUE "true" #define LOG_N_FLASE "false" @@ -37,8 +38,8 @@ int logdata_printf(char *buf, const int64_t buf_len, int64_t &pos, const char *f __attribute__((format(printf, 4, 5))); int logdata_vprintf(char *buf, const int64_t buf_len, int64_t &pos, const char *fmt, va_list args); -#define LOG_STDERR(...) do {if(isatty(STDERR_FILENO)) {fprintf(stderr, __VA_ARGS__); }} while(0) -#define LOG_STDOUT(...) do {if(isatty(STDOUT_FILENO)) {fprintf(stdout, __VA_ARGS__); }} while(0) +#define LOG_STDERR(...) do { if(oceanbase::obproxy::RUN_MODE_PROXY == oceanbase::obproxy::g_run_mode && isatty(STDERR_FILENO)) {fprintf(stderr, __VA_ARGS__); }} while(0) +#define LOG_STDOUT(...) do {if(oceanbase::obproxy::RUN_MODE_PROXY == oceanbase::obproxy::g_run_mode && isatty(STDOUT_FILENO)) {fprintf(stdout, __VA_ARGS__); }} while(0) //print errmsg of errno.As strerror not thread-safe, need //to call ERRMSG, KERRMSG which use this class. @@ -370,6 +371,46 @@ int logdata_print_kv(char *buf, const int64_t buf_len, int64_t &pos, const char return logdata_print_key_obj(buf, buf_len, pos, key, false, obj); } +class ObILogKV +{ +public: + virtual int print(char *buf, int64_t buf_len, int64_t &pos, const bool with_comma) const = 0; +}; + +template +class ObLogKV; + +template +class ObLogKV : public ObILogKV +{ +public: + ObLogKV(const char *key, const T &value) : key_(key), value_(value) {} + int print(char *buf, int64_t buf_len, int64_t &pos, const bool with_comma) const override + { + return logdata_print_key_obj(buf, buf_len, pos, key_, + with_comma, value_); + } +private: + const char *key_; + const T &value_; +}; + +template T& unmove(T&& v) { return v; } + +template +class ObLogKV : public ObILogKV +{ +public: + ObLogKV(const char *key, const T &&value) : key_(key), value_(unmove(value)) {} + int print(char *buf, int64_t buf_len, int64_t &pos, const bool with_comma) const override + { + return logdata_print_key_obj(buf, buf_len, pos, key_, + with_comma, value_); + } +private: + const char *key_; + const T &value_; +}; } } @@ -679,4 +720,35 @@ int logdata_print_kv(char *buf, const int64_t buf_len, int64_t &pos, const char log_buffer.check_and_unlock(); \ } +#define LOG_KV(key, obj) \ + (::oceanbase::common::ObILogKV&&)::oceanbase::common::ObLogKV::value>(key, obj) +#define LOG_KVS_0() +#define LOG_KVS_1() +#define LOG_KVS_2(key, obj) , LOG_KV(key, obj) +#define LOG_KVS_4(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_2(args) +#define LOG_KVS_6(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_4(args) +#define LOG_KVS_8(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_6(args) +#define LOG_KVS_10(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_8(args) +#define LOG_KVS_12(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_10(args) +#define LOG_KVS_14(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_12(args) +#define LOG_KVS_16(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_14(args) +#define LOG_KVS_18(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_16(args) +#define LOG_KVS_20(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_18(args) +#define LOG_KVS_22(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_20(args) +#define LOG_KVS_24(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_22(args) +#define LOG_KVS_26(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_24(args) +#define LOG_KVS_28(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_26(args) +#define LOG_KVS_30(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_28(args) +#define LOG_KVS_32(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_30(args) +#define LOG_KVS_34(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_32(args) +#define LOG_KVS_36(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_34(args) +#define LOG_KVS_38(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_36(args) +#define LOG_KVS_40(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_38(args) +#define LOG_KVS_42(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_40(args) +#define LOG_KVS_44(key, obj, args...) , LOG_KV(key, obj) LOG_KVS_42(args) + +#define LOG_KVS_(N, ...) CONCAT(LOG_KVS_, N)(__VA_ARGS__) +#define LOG_KVS(...) "placeholder" LOG_KVS_(ARGS_NUM(__VA_ARGS__), __VA_ARGS__) + #endif diff --git a/src/lib/oblog/ob_simple_trace.h b/src/lib/oblog/ob_simple_trace.h new file mode 100644 index 000000000..bd960bc97 --- /dev/null +++ b/src/lib/oblog/ob_simple_trace.h @@ -0,0 +1,190 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase CE is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#ifndef _OB_SIMPLE_TRACE_H +#define _OB_SIMPLE_TRACE_H + +#include "lib/oblog/ob_log.h" + +namespace oceanbase +{ +namespace common +{ + +template +class ObSimpleTraceBase +{ +public: + ObSimpleTraceBase() { reset(); } + ~ObSimpleTraceBase() { } + void reset() + { + pos_ = 0; + buf_[0] = '\0'; + } + template + int log_it(const char *info, Args const & ... args) + { + int ret = common::OB_SUCCESS; + const int64_t saved_pos = pos_; + const char delimiter1[] = " | "; + const char delimiter2[] = "... | "; + if (OB_FAIL(fill_buffer(buf_, BUFFER_SIZE - sizeof(delimiter2), pos_, info, args...))) { + if ((BUFFER_SIZE - saved_pos) >= BUFFER_SIZE / 2) { + // rewrite ret + ret = OB_SUCCESS; + (void)databuff_printf(buf_, BUFFER_SIZE, pos_, delimiter2); + } + } else { + (void)databuff_printf(buf_, BUFFER_SIZE, pos_, delimiter1); + } + if (OB_FAIL(ret)) { + pos_ = saved_pos; + buf_[pos_] = '\0'; + } + return ret; + } + int64_t to_string(char *buf, const int64_t buf_len) const + { + int64_t pos = 0; + databuff_printf(buf, buf_len, pos, "%s", buf_); + return pos; + } +private: + int fill_kv(char *buf, const int64_t buf_len, int64_t &pos, + const bool with_comma) + { + UNUSED(buf); + UNUSED(buf_len); + UNUSED(pos); + UNUSED(with_comma); + return common::OB_SUCCESS; + } + + int fill_kv(char *buf, const int64_t buf_len, int64_t &pos, + const bool with_comma, + const ObILogKV &kv) + { + return kv.print(buf, buf_len, pos, with_comma); + } + + template + int fill_kv(char *buf, const int64_t buf_len, int64_t &pos, + const bool with_comma, + const Key &key, + const Value &value, + Args const & ... args) + { + int ret = OB_SUCCESS; + ret = fill_kv(buf, buf_len, pos, with_comma, LOG_KV(key, value)); + if (OB_SUCC(ret)) { + ret = fill_kv(buf, buf_len, pos, 1, args...); + } + return ret; + } + template + int fill_buffer(char *data, const int64_t buf_len, + int64_t &pos, + const char *info, + Args const & ... args) + { + int ret = OB_SUCCESS; + int64_t tmp_pos = pos; + ret = databuff_printf(data, buf_len, pos, "%s ", info); + if (OB_SUCC(ret)) { + ret = fill_kv(data, buf_len, pos, 0, args...); + } + if (OB_SUCC(ret) && OB_UNLIKELY(OB_LOGGER.get_log_level() >= OB_LOG_LEVEL_TRACE)) { + char tmp_buf[1024]; + memset(tmp_buf, 0, sizeof(tmp_buf)); + int64_t copy_len = pos - tmp_pos > 1023 ? 1023 : pos - tmp_pos; + MEMCPY(tmp_buf, data + tmp_pos, copy_len); + OB_LOG(TRACE, "trace_log", K(tmp_buf)); + } + return ret; + } +private: + char buf_[BUFFER_SIZE]; + int64_t pos_; +}; + +template +class ObSimpleTrace +{ +public: + ObSimpleTrace() { reset(); } + ~ObSimpleTrace() { } + void reset() + { + first_idx_ = 0; + cur_idx_ = 0; + need_print_ = false; + for (int64_t i = 0; i < BASE_TRACE_CNT; i++) { + traces_[i].reset(); + } + } + template + void log_it(const char *info, Args const & ... args) + { + if (need_print_) { + int ret = common::OB_SUCCESS; + for (int64_t i = 0; i < 2; i++) { + cur_idx_ = (cur_idx_ + i) % BASE_TRACE_CNT; + if (1 == i) { + if (cur_idx_ == first_idx_) { + if (OB_UNLIKELY(OB_LOGGER.get_log_level() >= OB_LOG_LEVEL_TRACE)) { + // _LOG(TRACE, "print_trace_log", K(*this)); + } else { + first_idx_ = (first_idx_ + 1) % BASE_TRACE_CNT; + } + } + traces_[cur_idx_].reset(); + } + if (OB_SUCC(traces_[cur_idx_].log_it(info, args...))) { + break; + } + } + (void)ret; + } + } + int64_t to_string(char *buf, const int64_t buf_len) const + { + int64_t pos = 0; + for (int64_t i = 0; i < BASE_TRACE_CNT; i++) { + if (pos < buf_len) { + const int64_t idx = (first_idx_ + i) % BASE_TRACE_CNT; + const int64_t size = traces_[idx].to_string(buf + pos, buf_len - pos); + pos = pos + size; + if (idx == cur_idx_) { + break; + } + } else { + break; + } + } + return pos; + } + void set_need_print(const bool &need_print) { need_print_ = need_print; } +private: + static const int64_t BASE_TRACE_CNT = 4; + static const int64_t BUFFER_SIZE = TRACE_SIZE / BASE_TRACE_CNT; +private: + ObSimpleTraceBase traces_[BASE_TRACE_CNT]; + int64_t first_idx_; + int64_t cur_idx_; + bool need_print_; +}; + +} // end namespace common +} // end namespace oceanbase + +#endif /* _OB_TRACE_EVENT_H */ diff --git a/src/lib/profile/ob_trace_id.h b/src/lib/profile/ob_trace_id.h index c1e56cbca..80b620ed5 100644 --- a/src/lib/profile/ob_trace_id.h +++ b/src/lib/profile/ob_trace_id.h @@ -37,6 +37,7 @@ struct ObCurTraceId inline bool is_invalid() { return id_.seq_ == 0 ? true : false; } inline void init(const ObAddr &ip_port) { + // TODO: Consider whether to support IPv6 id_.seq_ = ATOMIC_AAF(&(SeqGenerator::seq_generator_), 1); id_.ip_ = ip_port.get_ipv4(); id_.reserved_ = 0; @@ -114,6 +115,8 @@ struct ObCurTraceId } }; +uint64_t ObCurTraceId::SeqGenerator::seq_generator_ = 0; + int32_t LogExtraHeaderCallback(char *buf, int32_t buf_size, int level, const char *file, int line, const char *function, pthread_t tid); diff --git a/src/lib/rowid/ob_urowid.cpp b/src/lib/rowid/ob_urowid.cpp index 8aba8730b..c114edf7d 100644 --- a/src/lib/rowid/ob_urowid.cpp +++ b/src/lib/rowid/ob_urowid.cpp @@ -135,7 +135,8 @@ int ObURowIDData::inner_get_pk_value(const uint8_t *rowid_buf, *(reinterpret_cast(rowid_buf + pos)); \ pos += sizeof(ObNumberDesc); \ int64_t digits_len = sizeof(uint32_t) * num_desc.len_; \ - if (OB_LIKELY(pos + digits_len <= rowid_buf_len)) { \ + if (OB_LIKELY(0 <= digits_len && digits_len <= rowid_buf_len \ + && pos + digits_len <= rowid_buf_len)) { \ const uint32_t *digits = reinterpret_cast(rowid_buf + pos); \ pos += digits_len; \ pk_val.set_##type(num_desc, const_cast(digits)); \ @@ -161,7 +162,7 @@ int ObURowIDData::inner_get_pk_value(const uint8_t *rowid_buf, int32_t char_len = \ *(reinterpret_cast(rowid_buf + pos)); \ pos += 4; \ - if (OB_LIKELY(pos + char_len <= rowid_buf_len)) { \ + if (OB_LIKELY(0 <= char_len && pos + char_len <= rowid_buf_len)) { \ const char *str_val = (const char *)rowid_buf + pos; \ pos += char_len; \ ObString str_value(char_len, str_val); \ @@ -208,19 +209,19 @@ DEF_GET_POD_PK_VALUE(ObIntType, int, int64_t); DEF_GET_POD_PK_VALUE(ObFloatType, float, float); DEF_GET_POD_PK_VALUE(ObDoubleType, double, double); DEF_GET_POD_PK_VALUE(ObDateTimeType, datetime, int64_t); -// DEF_GET_POD_PK_VALUE(ObIntervalYMType, interval_ym, int64_t); +//DEF_GET_POD_PK_VALUE(ObIntervalYMType, interval_ym, int64_t); DEF_GET_NUMBER_PK_VALUE(ObNumberType, number); DEF_GET_NUMBER_PK_VALUE(ObNumberFloatType, number_float); DEF_GET_CHAR_PK_VALUE(ObVarcharType, varchar); DEF_GET_CHAR_PK_VALUE(ObCharType, char); -// DEF_GET_CHAR_PK_VALUE(ObNVarchar2Type, nvarchar2); -// DEF_GET_CHAR_PK_VALUE(ObNCharType, nchar); +DEF_GET_CHAR_PK_VALUE(ObNVarchar2Type, nvarchar2); +DEF_GET_CHAR_PK_VALUE(ObNCharType, nchar); -// DEF_GET_OTIME_PK_VALUE(ObTimestampTZType, timestamp_tz, uint32_t); -// DEF_GET_OTIME_PK_VALUE(ObTimestampLTZType, timestamp_ltz, uint16_t); -// DEF_GET_OTIME_PK_VALUE(ObTimestampNanoType, timestamp_nano, uint16_t); +DEF_GET_OTIME_PK_VALUE(ObTimestampTZType, timestamp_tz, uint32_t); +DEF_GET_OTIME_PK_VALUE(ObTimestampLTZType, timestamp_ltz, uint16_t); +DEF_GET_OTIME_PK_VALUE(ObTimestampNanoType, timestamp_nano, uint16_t); #define ALL_TYPES_USED_IN_INNER_FUNC \ ObNullType, \ @@ -937,7 +938,8 @@ int ObURowIDData::get_rowkey_for_heap_organized_table(ObIArray &rowkey) int ObURowIDData::get_obobj_or_partition_id_from_decoded(obproxy::proxy::ObProxyPartInfo &part_info, obproxy::opsql::ObExprResolverResult &resolve_result, - int64_t &partition_id) + int64_t &partition_id, + common::ObIAllocator &allocator) { int ret = OB_SUCCESS; @@ -970,7 +972,7 @@ int ObURowIDData::get_obobj_or_partition_id_from_decoded(obproxy::proxy::ObProxy case NO_PK_ROWID_VERSION: case PK_ROWID_VERSION: { // ob2.x 3.x - if (OB_FAIL(get_obobj_from_decoded(part_info, resolve_result))) { + if (OB_FAIL(get_obobj_from_decoded(part_info, resolve_result, allocator))) { COMMON_LOG(WARN, "fail to get obobj from decoded", K(ret)); } break; @@ -986,7 +988,8 @@ int ObURowIDData::get_obobj_or_partition_id_from_decoded(obproxy::proxy::ObProxy // used for ob2.x 3.x int ObURowIDData::get_obobj_from_decoded(obproxy::proxy::ObProxyPartInfo &part_info, - obproxy::opsql::ObExprResolverResult &resolve_result) + obproxy::opsql::ObExprResolverResult &resolve_result, + common::ObIAllocator &allocator) { int ret = OB_SUCCESS; @@ -995,43 +998,55 @@ int ObURowIDData::get_obobj_from_decoded(obproxy::proxy::ObProxyPartInfo &part_i COMMON_LOG(WARN, "fail to get pk vals", K(ret)); } else { ObProxyPartKeyInfo &key_info = part_info.get_part_key_info(); - bool set_level_one_obj = false; - bool set_level_two_obj = false; for (int64_t i = 0; OB_SUCC(ret) && i < key_info.key_num_; ++i) { ObProxyPartKey &part_key = key_info.part_keys_[i]; - int8_t idx = -1; - if ((part_key.level_ == PART_KEY_LEVEL_ONE || part_key.level_ == PART_KEY_LEVEL_BOTH) - && !set_level_one_obj) { - idx = 0; - } else if (part_key.level_ == PART_KEY_LEVEL_TWO - && !set_level_two_obj) { - idx = 1; + if (PART_KEY_LEVEL_ONE == part_key.level_ && !resolve_result.ranges_[0].start_key_.is_valid()) { + if (OB_FAIL(resolve_result.ranges_[0].build_row_key(part_info.get_part_columns().count(), allocator))) { + COMMON_LOG(WARN, "fail to build row key", K(ret)); + } + } else if (PART_KEY_LEVEL_TWO == part_key.level_ && !resolve_result.ranges_[1].start_key_.is_valid()) { + if (OB_FAIL(resolve_result.ranges_[1].build_row_key(part_info.get_sub_part_columns().count(), allocator))) { + COMMON_LOG(WARN, "fail to build row key", K(ret)); + } } - if (idx != -1) { - if (part_key.idx_in_rowid_ >= 0 - && part_key.idx_in_rowid_ < pk_vals.count()) { - ObObj &obj = pk_vals.at(part_key.idx_in_rowid_); - if (is_valid_obj_type(obj.get_type())) { - resolve_result.ranges_[idx].start_key_.assign(&obj, 1); - resolve_result.ranges_[idx].end_key_.assign(&obj, 1); - resolve_result.ranges_[idx].border_flag_.set_inclusive_start(); - resolve_result.ranges_[idx].border_flag_.set_inclusive_end(); - if (idx == 0) { - set_level_one_obj = true; + if (part_key.idx_in_rowid_ >= 0 + && part_key.idx_in_rowid_ < pk_vals.count()) { + ObObj &obj = pk_vals.at(part_key.idx_in_rowid_); + ObObjType type = obj.get_type(); + if (ObCharType == type || ObNCharType == type) { + int32_t val_len = obj.get_val_len(); + const char* obj_str = obj.get_string_ptr(); + while (val_len > 1) { + if (OB_PADDING_CHAR == *(obj_str + val_len - 1)) { + --val_len; } else { - set_level_two_obj = true; + break; } - COMMON_LOG(DEBUG, "succ to get obobj from rowid", K(idx), K(part_key.idx_in_rowid_), K(obj)); - } else { - ret = OB_ERR_UNEXPECTED; - COMMON_LOG(WARN, "invalid obj type resolved from rowid content", K(ret), K(obj.get_type())); } - } else { + obj.set_string(type, obj.get_string_ptr(), val_len); + } + + if (part_key.level_ == 0 || part_key.level_ > 2) { ret = OB_ERR_UNEXPECTED; - COMMON_LOG(WARN, "calc partition id using rowid failed", K(part_key.idx_in_rowid_), K(pk_vals.count())); + COMMON_LOG(WARN, "part key level unexpected", K(part_key.level_)); + } else { + int level = static_cast(part_key.level_ - 1); + ObObj *target_start = const_cast(resolve_result.ranges_[level].start_key_.get_obj_ptr()) + + part_key.idx_in_part_columns_; + ObObj *target_end = const_cast(resolve_result.ranges_[level].end_key_.get_obj_ptr()) + + part_key.idx_in_part_columns_; + // no need to deep copy + *target_start = obj; + *target_end = obj; + resolve_result.ranges_[level].border_flag_.set_inclusive_start(); + resolve_result.ranges_[level].border_flag_.set_inclusive_end(); + COMMON_LOG(DEBUG, "succ to get val from rowid", K(obj), K(level), K(part_key.idx_in_part_columns_)); } + } else { + ret = OB_ERR_UNEXPECTED; + COMMON_LOG(WARN, "calc partition id using rowid failed", K(part_key.idx_in_rowid_), K(pk_vals.count())); } } // for } // else diff --git a/src/lib/rowid/ob_urowid.h b/src/lib/rowid/ob_urowid.h index 8599314fa..6346e74f5 100644 --- a/src/lib/rowid/ob_urowid.h +++ b/src/lib/rowid/ob_urowid.h @@ -154,7 +154,8 @@ friend class TestURowID; int get_rowkey_for_heap_organized_table(ObIArray &rowkey); int get_obobj_or_partition_id_from_decoded(obproxy::proxy::ObProxyPartInfo &part_info, obproxy::opsql::ObExprResolverResult &resolve_result, - int64_t &partition_id); + int64_t &partition_id, + common::ObIAllocator &allocator); // if highest bit is 1, lower 7 bits of version filed indicates how many primar key obj static bool is_valid_part_gen_col_version(int64_t v) @@ -231,7 +232,8 @@ friend class TestURowID; int parse_ext_heap_organized_table_rowid(uint64_t &tablet_id, uint64_t &auto_inc); int get_obobj_from_decoded(obproxy::proxy::ObProxyPartInfo &part_info, - obproxy::opsql::ObExprResolverResult &resolve_result); + obproxy::opsql::ObExprResolverResult &resolve_result, + common::ObIAllocator &allocator); }; } // end namespace common diff --git a/src/lib/timezone/ob_time_convert.cpp b/src/lib/timezone/ob_time_convert.cpp index 8e92be2ad..94cd069f2 100644 --- a/src/lib/timezone/ob_time_convert.cpp +++ b/src/lib/timezone/ob_time_convert.cpp @@ -409,6 +409,32 @@ int ObTimeConverter::str_to_datetime(const ObString &str, const ObTimeZoneInfo * return ret; } +/** + * @brief cast str to oracle date with format + * + * @param str input string of date + * @param cvrt_ctx + * @param value out param, oracle DATE result + * @return int + */ +int ObTimeConverter::str_to_date_oracle(const ObString &str, + const ObTimeConvertCtx &cvrt_ctx, + ObDateTime &value) +{ + int ret = OB_SUCCESS; + ObTime ob_time; + ObDateTime result_value = 0; + ObScale scale = 0; + if (OB_FAIL(str_to_ob_time_oracle_dfm(str, cvrt_ctx, ObDateTimeType, ob_time, scale))) { + LOG_WARN("failed to convert str to ob_time", K(str), K(cvrt_ctx.oracle_nls_format_)); + } else if (OB_FAIL(ob_time_to_datetime(ob_time, cvrt_ctx.tz_info_, result_value))) { + LOG_WARN("convert ob_time to datetime failed", K(ret), K(ob_time)); + } else { + value = result_value; + } + return ret; +} + int ObTimeConverter::str_to_datetime_format(const ObString &str, const ObString &fmt, const ObTimeZoneInfo *tz_info, int64_t &value, int16_t *scale) { @@ -3111,7 +3137,7 @@ int ObTimeConverter::ob_time_to_str(const ObTime &ob_time, ObDTMode mode, int16_ int ObTimeConverter::data_fmt_nd(char *buffer, int64_t buf_len, int64_t &pos, const int64_t n, int64_t target) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(n <= 0 || target < 0 || target > 999999)) { + if (OB_UNLIKELY(n <= 0 || target < 0 || target > 999999999)) { ret = OB_ERR_UNEXPECTED; LIB_TIME_LOG(ERROR, "invalid argument", K(ret), K(n), K(target)); } else if (OB_UNLIKELY(n > buf_len - pos)) { @@ -3698,6 +3724,8 @@ int ObTimeConverter::ob_time_to_str_oracle_dfm(const ObTime &ob_time, break; } case ObDFMFlag::FF: { + // FF default FF9 in oracle + int64_t scale = ObDFMFlag::FF9 - ObDFMFlag::FF1 + 1; if (OB_UNLIKELY(!HAS_TYPE_ORACLE(ob_time.mode_))) { ret = OB_INVALID_DATE_FORMAT; } else if (0 == scale) { diff --git a/src/lib/timezone/ob_time_convert.h b/src/lib/timezone/ob_time_convert.h index e5e3a5b78..863a26eea 100644 --- a/src/lib/timezone/ob_time_convert.h +++ b/src/lib/timezone/ob_time_convert.h @@ -251,6 +251,7 @@ class ObTimeConverter static int int_to_time(int64_t int64, int64_t &value); static int int_to_year(int64_t int64, uint8_t &value); static int str_to_datetime(const ObString &str, const ObTimeZoneInfo *tz_info, int64_t &value, int16_t *scale = NULL); + static int str_to_date_oracle(const ObString &str, const ObTimeConvertCtx &cvrt_ctx, ObDateTime &value); static int str_to_datetime_format(const ObString &str, const ObString &fmt, const ObTimeZoneInfo *tz_info, int64_t &value, int16_t *scale = NULL); static int str_is_date_format(const ObString &str, bool &date_flag); @@ -345,7 +346,7 @@ class ObTimeConverter ObDTMode mode, int32_t &delta); static int ob_time_to_str_oracle_dfm(const ObTime &ob_time, ObScale scale, const ObString &format, char *buf, int64_t buf_len, int64_t &pos); - static int ob_time_to_datetime(ObTime &ob_time, const ObTimeZoneInfo *sp, int64_t &value); + static int ob_time_to_datetime(ObTime &ob_time, const ObTimeZoneInfo *tz_info, int64_t &value); static int32_t ob_time_to_date(ObTime &ob_time); static int ob_time_to_otimestamp(ObTime &ob_time, ObOTimestampData &value); static int64_t ob_time_to_time(const ObTime &ob_time); diff --git a/src/lib/trace/ob_trace.cpp b/src/lib/trace/ob_trace.cpp index 3ed4cafc8..8c7a3cd18 100644 --- a/src/lib/trace/ob_trace.cpp +++ b/src/lib/trace/ob_trace.cpp @@ -439,6 +439,7 @@ ObSpanCtx* ObTrace::begin_span(uint32_t span_type, uint8_t level, bool is_follow new_span = freed_span_.remove_last(); current_span_.add_first(new_span); new_span->span_type_ = static_cast(span_type); + new_span->span_id_.high_ = 0; new_span->span_id_.low_ = ++seq_; new_span->source_span_ = last_active_span_; new_span->is_follow_ = is_follow; @@ -565,4 +566,4 @@ void ObTrace::dump_span() } } -} \ No newline at end of file +} diff --git a/src/obproxy/Makemodule.am b/src/obproxy/Makemodule.am index df2de637c..4a08e92ad 100644 --- a/src/obproxy/Makemodule.am +++ b/src/obproxy/Makemodule.am @@ -10,7 +10,11 @@ AM_CPPFLAGS += -I${top_srcdir}/src/obproxy\ obproxy_libobproxy_la_LIBADD := dbconfig/libdbconfig.la lib/regex/regex/libregex.la prometheus/libprometheus_exporter.la noinst_LTLIBRARIES += obproxy/libobproxy.la -bin_PROGRAMS += obproxy/obproxy +if HAVE_SO + lib_LTLIBRARIES += obproxy/libobproxy_so.la +else + bin_PROGRAMS += obproxy/obproxy +endif include obproxy/iocore/eventsystem/Makemodule.am include obproxy/iocore/net/Makemodule.am @@ -30,6 +34,7 @@ include obproxy/opsql/Makemodule.am include obproxy/packet/Makemodule.am include obproxy/dbconfig/Makemodule.am include obproxy/engine/Makemodule.am +include obproxy/driver/c/Makemodule.am include obproxy/optimizer/Makemodule.am include obproxy/executor/Makemodule.am include obproxy/qos/Makemodule.am @@ -41,6 +46,9 @@ pub_source = \ obproxy/ob_proxy_main.cpp \ obproxy/ob_proxy.h \ obproxy/ob_proxy.cpp +init_so_source =\ + obproxy/ob_proxy_init.h\ + obproxy/ob_proxy_init.cpp obproxy_sources :=\ ${iocore_eventsystem_sources}\ @@ -51,6 +59,7 @@ ${proxy_api_sources}\ ${proxy_plugins_sources}\ ${proxy_mysqllib_sources}\ ${proxy_mysql_client_sources}\ +${obproxy_c_driver_sources}\ ${proxy_mysql_route_sources}\ ${proxy_mysql_shard_sources}\ ${obutils_sources}\ @@ -70,6 +79,8 @@ ${obproxy_executor_sources}\ ${obproxy_optimizer_sources}\ ${obproxy_engine_sources}\ ${qos_sources}\ +${init_so_source}\ +${pub_source}\ ${omt_sources} obproxy_libobproxy_la_SOURCES :=\ @@ -80,8 +91,15 @@ ${rpc_obmysql_packet_sources} ${obproxy_rpc_obmysql_sources} ${rpc_common_source ${obproxy_sql_sources}\ ${obproxy_sources} +if HAVE_SO + obproxy_libobproxy_so_la_SOURCES := + obproxy_libobproxy_so_la_LIBADD := obproxy/libobproxy.la lib/compress/libzlib_1.0.la lib/compress/libzstd_1.3.8.la ${BIN_LDFLAGS} ${DEP_DIR}/lib64/libprometheus-cpp-pull.a ${DEP_DIR}/lib64/libprometheus-cpp-core.a ${RUNTIME_DIR}/lib/libob_sql_proxy_parser_static.a ${DEP_DIR}/lib/libssl.a ${DEP_DIR}/lib/libcrypto.a -lpthread + + obproxy_libobproxy_so_la_LDFLAGS :=${AM_LDFLAGS} ${DEP_DIR}/lib/libgrpc++.a -lpthread -lc -lm -lrt ${DEP_DIR}/lib/libcurl.a -ldl -L${DEP_DIR}/lib -llber ${DEP_DIR}/lib/sqlite/libsqlite3.a ${DEP_DIR}/lib/libgrpc_cronet.a ${DEP_DIR}/lib/libgrpc++_cronet.a -shared ${DEP_DIR}/lib64/libprotobuf.a -fPIC +endif + nodist_obproxy_libobproxy_la_SOURCES = build_version.c -obproxy_obproxy_SOURCES := obproxy/main.cpp ${pub_source} +obproxy_obproxy_SOURCES := obproxy/main.cpp obproxy_obproxy_LDADD_BASE := obproxy/libobproxy.la lib/compress/libzlib_1.0.la lib/compress/libzstd_1.3.8.la ${BIN_LDFLAGS} ${DEP_DIR}/lib64/libprotobuf.a ${DEP_DIR}/lib/libgrpc.a ${DEP_DIR}/lib/libgrpc++.a ${DEP_DIR}/lib/libgrpc_unsecure.a ${DEP_DIR}/lib/libgrpc++_unsecure.a ${DEP_DIR}/lib/libgrpc++_reflection.a ${DEP_DIR}/lib/libgrpcpp_channelz.a ${DEP_DIR}/lib/libgrpc++_error_details.a ${DEP_DIR}/lib/libgrpc_cronet.a ${DEP_DIR}/lib/libgrpc++_cronet.a ${DEP_DIR}/lib/libgpr.a ${DEP_DIR}/lib/libaddress_sorting.a ${DEP_DIR}/lib/libcares.a ${DEP_DIR}/lib64/libprometheus-cpp-pull.a ${DEP_DIR}/lib64/libprometheus-cpp-core.a ${RUNTIME_DIR}/lib/libob_sql_proxy_parser_static.a ${DEP_DIR}/lib/libssl.a ${DEP_DIR}/lib/libcrypto.a -lpthread ${DEP_DIR}/lib/libcurl.a ${DEP_DIR}/lib/libcrypto.a ${DEP_DIR}/lib/sqlite/libsqlite3.a obproxy_obproxy_LDFLAGS :=${AM_LDFLAGS} -lpthread -lc -lm -lrt -ldl -L${DEP_DIR}/lib diff --git a/src/obproxy/cmd/ob_cmd_handler.cpp b/src/obproxy/cmd/ob_cmd_handler.cpp index 5adcd4d96..39e135056 100644 --- a/src/obproxy/cmd/ob_cmd_handler.cpp +++ b/src/obproxy/cmd/ob_cmd_handler.cpp @@ -88,8 +88,7 @@ int ObCmdHandler::reset() } else { internal_buf_->reset(); seq_ = original_seq_; - protocol_ = ObProxyProtocol::PROTOCOL_NORMAL; - ob20_param_.reset(); + // could not reset protocol and ob20 param, cause we need fill external buf according to protocol } return ret; } diff --git a/src/obproxy/cmd/ob_dds_config_handler.cpp b/src/obproxy/cmd/ob_dds_config_handler.cpp index 8a8cb1d69..4bd3ceb93 100644 --- a/src/obproxy/cmd/ob_dds_config_handler.cpp +++ b/src/obproxy/cmd/ob_dds_config_handler.cpp @@ -361,7 +361,6 @@ int ObDdsConfigHandler::handle_parse_where_fields(ObArenaAllocator* allocator, O } else { ObExprParser expr_parser(*allocator, parse_mode); expr_result.part_key_info_.key_num_ = 0; - expr_result.target_mask_ = 0; if (OB_FAIL(expr_parser.parse_reqsql(sql, sql_parse_result.get_parsed_length(), expr_result, sql_parse_result.get_stmt_type(), connection_collation))) { diff --git a/src/obproxy/cmd/ob_internal_cmd_handler.cpp b/src/obproxy/cmd/ob_internal_cmd_handler.cpp index c8446a53a..be03c4334 100644 --- a/src/obproxy/cmd/ob_internal_cmd_handler.cpp +++ b/src/obproxy/cmd/ob_internal_cmd_handler.cpp @@ -111,8 +111,7 @@ int ObInternalCmdHandler::reset() } else { internal_buf_->reset(); seq_ = original_seq_; - protocol_ = ObProxyProtocol::PROTOCOL_NORMAL; - ob20_param_.reset(); + // could not reset protocol and ob20_param in handler, cause we need filll external buf according to protocol } return ret; } @@ -621,7 +620,8 @@ int ObInternalCmdHandler::handle_callback(int event, void *data) MUTEX_TRY_LOCK(lock, action_.mutex_, submit_thread_); if (lock.is_locked()) { if (!action_.cancelled_) { - if (INTERNAL_CMD_EVENTS_SUCCESS == saved_event_ && OB_SUCCESS != fill_external_buf()) { + if (INTERNAL_CMD_EVENTS_SUCCESS == saved_event_ + && OB_SUCCESS != fill_external_buf()) { saved_event_ = INTERNAL_CMD_EVENTS_FAILED; } DEBUG_ICMD("do callback now", K_(saved_event)); diff --git a/src/obproxy/cmd/ob_sequence_info_handler.cpp b/src/obproxy/cmd/ob_sequence_info_handler.cpp index abe8f4a50..d0fc0450f 100644 --- a/src/obproxy/cmd/ob_sequence_info_handler.cpp +++ b/src/obproxy/cmd/ob_sequence_info_handler.cpp @@ -175,7 +175,8 @@ int ObSequenceInfoHandler::handle_shard_sequence_params() } else if (!param_.tnt_id_.empty() && param_.tnt_col_.empty()) { snprintf(err_msg_, SEQUENCE_ERR_MSG_SIZE, "tnt_col is empty while tnt_id used"); ret = OB_ERR_UNEXPECTED; - } else if (OB_FAIL(ObProxyShardUtils::get_real_info(*logic_db_info, + } else if (OB_FAIL(ObProxyShardUtils::get_real_info(session_info, + *logic_db_info, sequence_table_name, parse_result, shard_conn, @@ -211,6 +212,9 @@ int ObSequenceInfoHandler::handle_shard_sequence_params() table_id_ = table_id; group_id_ = group_id; eid_ = es_id; + session_info.set_group_id(group_id); + session_info.set_table_id(table_id); + session_info.set_es_id(es_id); snprintf(seq_id_buf_, 2048, "%.*s-%.*s-%.*s-%.*s-%.*s-%.*s-%02ld-%02ld-%02ld", logic_tenant_name_.config_string_.length(), logic_tenant_name_.config_string_.ptr(), @@ -222,6 +226,11 @@ int ObSequenceInfoHandler::handle_shard_sequence_params() group_id_, table_id_, eid_); param_.seq_id_ = ObString(seq_id_buf_); } + + if (NULL != logic_db_info) { + logic_db_info->dec_ref(); + logic_db_info = NULL; + } LOG_DEBUG("Left handle_shard_sequence_params", K(param_), K(table_id_), K(group_id_), K(eid_)); return ret; } diff --git a/src/obproxy/cmd/ob_show_route_handler.cpp b/src/obproxy/cmd/ob_show_route_handler.cpp index 96df77100..fcbc49966 100644 --- a/src/obproxy/cmd/ob_show_route_handler.cpp +++ b/src/obproxy/cmd/ob_show_route_handler.cpp @@ -463,8 +463,6 @@ int ObShowRouteHandler::dump_table_item(const ObTableEntry &entry) int ret = OB_SUCCESS; const int64_t count = entry.get_server_count(); ObSqlString server_addr; - uint32_t ipv4 = 0; - int32_t port = 0; ObRole role = INVALID_ROLE; ObReplicaType replica_type = REPLICA_TYPE_MAX; const ObTenantServer *ts = NULL; @@ -479,30 +477,24 @@ int ObShowRouteHandler::dump_table_item(const ObTableEntry &entry) part_info = entry.get_part_info(); } for (int64_t i = 0; i < count && OB_SUCC(ret); ++i) { + char ip_port_buf[MAX_IP_ADDR_LENGTH]; + memset(ip_port_buf, 0, sizeof(ip_port_buf)); if (NULL != ts) { - ipv4 = ts->get_replica_location(i)->server_.get_ipv4(); - port = ts->get_replica_location(i)->server_.get_port(); role = ts->get_replica_location(i)->role_; replica_type = ts->get_replica_location(i)->replica_type_; + ts->get_replica_location(i)->server_.ip_port_to_string(ip_port_buf, sizeof(ip_port_buf)); } else if (NULL != pl) { - ipv4 = pl->get_replica(i)->server_.get_ipv4(); - port = pl->get_replica(i)->server_.get_port(); role = pl->get_replica(i)->role_; replica_type = pl->get_replica(i)->replica_type_; + pl->get_replica(i)->server_.ip_port_to_string(ip_port_buf, sizeof(ip_port_buf)); } else { - ipv4 = 0; - port = -1; role = INVALID_ROLE; replica_type = REPLICA_TYPE_MAX; } const ObString &string = ObProxyReplicaLocation::get_replica_type_string(replica_type); - if (OB_FAIL(server_addr.append_fmt("server[%ld]=%d.%d.%d.%d:%d,%s,%.*s; ", + if (OB_FAIL(server_addr.append_fmt("server[%ld]=%s,%s,%.*s; ", i, - (ipv4 >> 24) & 0XFF, - (ipv4 >> 16) & 0xFF, - (ipv4 >> 8) & 0xFF, - (ipv4) & 0xFF, - port, + ip_port_buf, role2str(role), string.length(), string.ptr()))) { WARN_ICMD("fail to append server_addr", K(i), K(ret)); @@ -674,24 +666,18 @@ int ObShowRouteHandler::dump_partition_item(const ObPartitionEntry &entry) int ret = OB_SUCCESS; const int64_t count = entry.get_server_count(); ObSqlString server_addr; - uint32_t ipv4 = 0; - int32_t port = 0; ObRole role = INVALID_ROLE; ObReplicaType replica_type = REPLICA_TYPE_MAX; const ObProxyPartitionLocation &pl = entry.get_pl(); for (int64_t i = 0; i < count && OB_SUCC(ret); ++i) { - ipv4 = pl.get_replica(i)->server_.get_ipv4(); - port = pl.get_replica(i)->server_.get_port(); role = pl.get_replica(i)->role_; replica_type = pl.get_replica(i)->replica_type_; const ObString &string = ObProxyReplicaLocation::get_replica_type_string(replica_type); - if (OB_FAIL(server_addr.append_fmt("server[%ld]=%d.%d.%d.%d:%d,%s,%.*s; ", + char ip_port_buf[MAX_IP_ADDR_LENGTH]; + pl.get_replica(i)->server_.ip_port_to_string(ip_port_buf, sizeof(ip_port_buf)); + if (OB_FAIL(server_addr.append_fmt("server[%ld]=%s,%s,%.*s; ", i, - (ipv4 >> 24) & 0XFF, - (ipv4 >> 16) & 0xFF, - (ipv4 >> 8) & 0xFF, - (ipv4) & 0xFF, - port, + ip_port_buf, role2str(role), string.length(), string.ptr()))) { WARN_ICMD("fail to append server_addr", K(i), K(ret)); diff --git a/src/obproxy/cmd/ob_show_sqlaudit_handler.cpp b/src/obproxy/cmd/ob_show_sqlaudit_handler.cpp index 001d31e23..73a7282b2 100644 --- a/src/obproxy/cmd/ob_show_sqlaudit_handler.cpp +++ b/src/obproxy/cmd/ob_show_sqlaudit_handler.cpp @@ -368,9 +368,10 @@ enum OB_SSA_SERVER_SEND_SAVED_LOGIN_TIME, OB_SSA_SERVER_SEND_USE_DATABASE_TIME, OB_SSA_SERVER_SEND_SESSION_VARIABLE_TIME, + OB_SSA_SERVER_SEND_SESSION_USER_VARIABLE_TIME, OB_SSA_SERVER_SEND_ALL_SESSION_VARIABLE_TIME, - OB_SSA_SERVER_SEND_LAST_INSERT_ID_TIME, OB_SSA_SERVER_SEND_START_TRANS_TIME, + OB_SSA_SERVER_SEND_XA_START_TIME, OB_SSA_BUILD_SERVER_REQUEST_TIME, OB_SSA_PLUGIN_COMPRESS_REQUEST_TIME, OB_SSA_PREPARE_SEND_REQUEST_TO_SERVER_TIME, @@ -408,9 +409,10 @@ const ObProxyColumnSchema SSA_COLUMN_ARRAY[OB_SSA_MAX_COLUMN_ID] = { ObProxyColumnSchema::make_schema(OB_SSA_SERVER_SEND_SAVED_LOGIN_TIME, "server_send_saved_login_ns", obmysql::OB_MYSQL_TYPE_LONG), ObProxyColumnSchema::make_schema(OB_SSA_SERVER_SEND_USE_DATABASE_TIME, "server_send_use_database_ns", obmysql::OB_MYSQL_TYPE_LONG), ObProxyColumnSchema::make_schema(OB_SSA_SERVER_SEND_SESSION_VARIABLE_TIME, "server_send_session_variable_ns", obmysql::OB_MYSQL_TYPE_LONG), + ObProxyColumnSchema::make_schema(OB_SSA_SERVER_SEND_SESSION_USER_VARIABLE_TIME, "server_send_session_user_variable_ns", obmysql::OB_MYSQL_TYPE_LONG), ObProxyColumnSchema::make_schema(OB_SSA_SERVER_SEND_ALL_SESSION_VARIABLE_TIME, "server_send_all_session_variable_ns", obmysql::OB_MYSQL_TYPE_LONG), - ObProxyColumnSchema::make_schema(OB_SSA_SERVER_SEND_LAST_INSERT_ID_TIME, "server_send_last_insert_id_ns", obmysql::OB_MYSQL_TYPE_LONG), ObProxyColumnSchema::make_schema(OB_SSA_SERVER_SEND_START_TRANS_TIME, "server_send_start_trans_ns", obmysql::OB_MYSQL_TYPE_LONG), + ObProxyColumnSchema::make_schema(OB_SSA_SERVER_SEND_XA_START_TIME, "server_send_xa_start_ns", obmysql::OB_MYSQL_TYPE_LONG), ObProxyColumnSchema::make_schema(OB_SSA_BUILD_SERVER_REQUEST_TIME, "build_server_request_ns", obmysql::OB_MYSQL_TYPE_LONG), ObProxyColumnSchema::make_schema(OB_SSA_PLUGIN_COMPRESS_REQUEST_TIME, "plugin_compress_request_ns", obmysql::OB_MYSQL_TYPE_LONG), ObProxyColumnSchema::make_schema(OB_SSA_PREPARE_SEND_REQUEST_TO_SERVER_TIME, "prepare_send_request_to_server_ns", obmysql::OB_MYSQL_TYPE_LONG), @@ -549,9 +551,10 @@ int ObShowSqlauditHandler::dump_sqlaudit_record(ObSqlauditRecord &record) cells[OB_SSA_SERVER_SEND_SAVED_LOGIN_TIME].set_int(record.cmd_time_stat_.server_send_saved_login_time_); cells[OB_SSA_SERVER_SEND_USE_DATABASE_TIME].set_int(record.cmd_time_stat_.server_send_use_database_time_); cells[OB_SSA_SERVER_SEND_SESSION_VARIABLE_TIME].set_int(record.cmd_time_stat_.server_send_session_variable_time_); + cells[OB_SSA_SERVER_SEND_SESSION_USER_VARIABLE_TIME].set_int(record.cmd_time_stat_.server_send_session_user_variable_time_); cells[OB_SSA_SERVER_SEND_ALL_SESSION_VARIABLE_TIME].set_int(record.cmd_time_stat_.server_send_all_session_variable_time_); - cells[OB_SSA_SERVER_SEND_LAST_INSERT_ID_TIME].set_int(record.cmd_time_stat_.server_send_last_insert_id_time_); cells[OB_SSA_SERVER_SEND_START_TRANS_TIME].set_int(record.cmd_time_stat_.server_send_start_trans_time_); + cells[OB_SSA_SERVER_SEND_XA_START_TIME].set_int(record.cmd_time_stat_.server_send_xa_start_time_); cells[OB_SSA_BUILD_SERVER_REQUEST_TIME].set_int(record.cmd_time_stat_.build_server_request_time_); cells[OB_SSA_PLUGIN_COMPRESS_REQUEST_TIME].set_int(record.cmd_time_stat_.plugin_compress_request_time_); cells[OB_SSA_PLUGIN_DECOMPRESS_RESPONSE_TIME].set_int(record.cmd_time_stat_.plugin_decompress_response_time_); diff --git a/src/obproxy/cmd/ob_show_topology_handler.cpp b/src/obproxy/cmd/ob_show_topology_handler.cpp index 76100493a..341ee4368 100644 --- a/src/obproxy/cmd/ob_show_topology_handler.cpp +++ b/src/obproxy/cmd/ob_show_topology_handler.cpp @@ -13,8 +13,8 @@ #define USING_LOG_PREFIX PROXY_CMD #include "cmd/ob_show_topology_handler.h" -#include "iocore/eventsystem/ob_event_processor.h" #include "dbconfig/ob_proxy_db_config_info.h" +#include "iocore/eventsystem/ob_event_processor.h" #include "lib/string/ob_sql_string.h" using namespace oceanbase::common; @@ -45,17 +45,38 @@ static const EMySQLFieldType column_type[OB_TC_MAX_COLUMN_ID] = { OB_MYSQL_TYPE_LONG }; +//TopologyColumnID for sharding +enum +{ + OB_TC_ID = 0, + OB_TC_GROUP_NAME, + OB_TC_TABLE_NAME, + OB_TC_SCHEMA_TYPE, + OB_TC_SHARD_KEY, + OB_TC_SHARD_RULE, + OB_TC_SHARD_MAX_COLUMN_ID, +}; + +const ObProxyColumnSchema SHOW_TOPOLOGY_ARRAY[OB_TC_SHARD_MAX_COLUMN_ID] = { + ObProxyColumnSchema::make_schema(OB_TC_ID, "id", OB_MYSQL_TYPE_LONG), + ObProxyColumnSchema::make_schema(OB_TC_GROUP_NAME, "group_name", OB_MYSQL_TYPE_VARCHAR), + ObProxyColumnSchema::make_schema(OB_TC_TABLE_NAME, "table_name", OB_MYSQL_TYPE_VARCHAR), + ObProxyColumnSchema::make_schema(OB_TC_SCHEMA_TYPE, "schema_type", OB_MYSQL_TYPE_VARCHAR), + ObProxyColumnSchema::make_schema(OB_TC_SHARD_KEY, "shard_key", OB_MYSQL_TYPE_VARCHAR), + ObProxyColumnSchema::make_schema(OB_TC_SHARD_RULE, "shard_rule", OB_MYSQL_TYPE_VARCHAR), +}; + ObShowTopologyHandler::ObShowTopologyHandler(ObMIOBuffer *buf, ObCmdInfo &info) : ObCmdHandler(buf, info) { } -int ObShowTopologyHandler::handle_show_topology(const ObString &tenant_name, - const ObString &db_name, - const ObString &group_name) +int ObShowTopologyHandler::handle_show_elastic_id(const ObString &tenant_name, + const ObString &db_name, + const ObString &group_name) { int ret = OB_SUCCESS; - if (OB_FAIL(dump_topology_header())) { + if (OB_FAIL(dump_elastic_id_header())) { WARN_CMD("fail to dump_header", K(ret)); } else { ObDbConfigCache &dbconfig_cache = get_global_dbconfig_cache(); @@ -144,7 +165,7 @@ int ObShowTopologyHandler::dump_elastic_id(const int64_t eid) return ret; } -int ObShowTopologyHandler::dump_topology_header() +int ObShowTopologyHandler::dump_elastic_id_header() { int ret = OB_SUCCESS; if (OB_FAIL(encode_header(column_name, column_type, OB_TC_MAX_COLUMN_ID))) { @@ -153,7 +174,7 @@ int ObShowTopologyHandler::dump_topology_header() return ret; } -int ObShowTopologyHandler::show_topology_cmd_callback(ObMIOBuffer *buf, +int ObShowTopologyHandler::show_elastic_id_cmd_callback(ObMIOBuffer *buf, ObCmdInfo &info, const ObString &logic_tenant_name, const ObString &logic_database_name, @@ -167,7 +188,7 @@ int ObShowTopologyHandler::show_topology_cmd_callback(ObMIOBuffer *buf, ERROR_CMD("fail to new ObShowTopologyHandler", K(ret)); } else if (OB_FAIL(handler->init())) { WARN_CMD("fail to init for ObShowTopologyHandler"); - } else if (OB_FAIL(handler->handle_show_topology(logic_tenant_name, logic_database_name, group_name))){ + } else if (OB_FAIL(handler->handle_show_elastic_id(logic_tenant_name, logic_database_name, group_name))){ WARN_CMD("fail to handle show topology", K(logic_tenant_name), K(logic_database_name), K(group_name), K(ret)); } @@ -178,6 +199,255 @@ int ObShowTopologyHandler::show_topology_cmd_callback(ObMIOBuffer *buf, return ret; } + +int ObShowTopologyHandler::show_topology_cmd_callback(ObMIOBuffer *buf, + ObCmdInfo &info, + const ObString &logic_tenant_name, + const ObString &logic_database_name, + const ObString &table_name) +{ + int ret = OB_SUCCESS; + ObShowTopologyHandler *handler = NULL; + + if (OB_ISNULL(handler = new(std::nothrow) ObShowTopologyHandler(buf, info))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + ERROR_CMD("fail to new ObShowTopologyHandler", K(ret)); + } else if (OB_FAIL(handler->init())) { + WARN_CMD("fail to init for ObShowTopologyHandler"); + } else if (OB_FAIL(handler->handle_show_topology(logic_tenant_name, logic_database_name, table_name))){ + WARN_CMD("fail to handle show topology", K(logic_tenant_name), K(logic_database_name), K(ret)); + } + + if (OB_LIKELY(NULL != handler)) { + delete handler; + handler = NULL; + } + return ret; +} + +int ObShowTopologyHandler::handle_show_topology(const ObString &tenant_name, + const ObString &db_name, + const ObString &table_name) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(encode_header(SHOW_TOPOLOGY_ARRAY, OB_TC_SHARD_MAX_COLUMN_ID))) { + WARN_CMD("fail to dump_header", K(ret)); + } else { + ObDbConfigCache &dbconfig_cache = get_global_dbconfig_cache(); + ObDbConfigLogicDb *db_info = NULL; + ObShardRule *shard_rule = NULL; + if (OB_ISNULL(db_info = dbconfig_cache.get_exist_db_info(tenant_name, db_name))) { + ret = OB_ERR_BAD_DATABASE; + WARN_CMD("logic database not exist", K(tenant_name), K(db_name), K(ret)); + } else if (OB_UNLIKELY(db_info->is_single_shard_db_table())) { + if (OB_FAIL(dump_shard_topology_for_single_db(table_name))) { + WARN_CMD("fail to encode topology packet for single db", K(tenant_name), K(db_name), K(ret)); + } + } else if (OB_FAIL(db_info->get_shard_rule(shard_rule, table_name))) { + // no logic table + ret = OB_TABLE_NOT_EXIST; + } else if (OB_UNLIKELY((1 == shard_rule->db_size_) && (1 == shard_rule->tb_size_))) { + if (OB_FAIL(dump_shard_topology_for_shard_db_single_tb(table_name))) { + WARN_CMD("fail to encode topology packet for shard_db_single_tb", K(tenant_name), K(db_name), K(shard_rule->db_size_), K(shard_rule->tb_size_), K(ret)); + } + } else if (OB_UNLIKELY(1 == shard_rule->tb_size_)) { + if (OB_FAIL(dump_shard_topology_for_shard_db_non_shard_tb(table_name, shard_rule))) { + WARN_CMD("fail to encode topology packet for shard_db_non_shard_tb", K(tenant_name), K(db_name), K(shard_rule->db_size_), K(shard_rule->tb_size_), K(ret)); + } + } else { + if (OB_FAIL(dump_shard_topology_for_shard_db_shard_tb(shard_rule))) { + WARN_CMD("fail to encode topology packet for shard_db_shard_tb", K(tenant_name), K(db_name), K(shard_rule->db_size_), K(shard_rule->tb_size_), K(ret)); + } + } + + if (NULL != db_info) { + db_info->dec_ref(); + db_info = NULL; + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(encode_eof_packet())) { + WARN_CMD("fail to encode eof packet", K(ret)); + } + } + + if (OB_FAIL(ret)) { + if (OB_FAIL(encode_err_packet(ret))) { + WARN_CMD("fail to encode internal err packet, callback", K(ret)); + } else { + INFO_CMD("succ to encode internal err packet, callback"); + ret = OB_SUCCESS; + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(fill_external_buf())) { + WARN_CMD("fail to fill_external_buf", K(ret)); + } + } + return ret; +} + +int ObShowTopologyHandler::dump_shard_topology_for_single_db(ObString table_name) +{ + int ret = OB_SUCCESS; + ObNewRow row; + ObObj cells[OB_TC_SHARD_MAX_COLUMN_ID]; + cells[OB_TC_ID].set_int(0); + cells[OB_TC_GROUP_NAME].set_varchar("group_00"); + cells[OB_TC_TABLE_NAME].set_varchar(table_name); + cells[OB_TC_SCHEMA_TYPE].set_varchar("SINGLE"); + cells[OB_TC_SHARD_KEY].set_null(); + cells[OB_TC_SHARD_RULE].set_null(); + row.cells_ = cells; + row.count_ = OB_TC_SHARD_MAX_COLUMN_ID; + if (OB_FAIL(encode_row_packet(row))) { + WARN_CMD("fail to encode row packet for shard", K(row), K(ret)); + } + return ret; +} + +int ObShowTopologyHandler::dump_shard_topology_for_shard_db_single_tb(ObString table_name) +{ + int ret = OB_SUCCESS; + ObNewRow row; + ObObj cells[OB_TC_SHARD_MAX_COLUMN_ID]; + cells[OB_TC_ID].set_int(0); + cells[OB_TC_GROUP_NAME].set_varchar("group_00"); + cells[OB_TC_TABLE_NAME].set_varchar(table_name); + cells[OB_TC_SCHEMA_TYPE].set_varchar("SHARD"); + cells[OB_TC_SHARD_KEY].set_null(); + cells[OB_TC_SHARD_RULE].set_null(); + row.cells_ = cells; + row.count_ = OB_TC_SHARD_MAX_COLUMN_ID; + if (OB_FAIL(encode_row_packet(row))) { + WARN_CMD("fail to encode row packet for shard", K(row), K(ret)); + } + return ret; +} + +int ObShowTopologyHandler::dump_shard_topology_for_shard_db_non_shard_tb(ObString table_name, ObShardRule *shard_rule) +{ + int ret = OB_SUCCESS; + ObNewRow row; + ObObj cells[OB_TC_SHARD_MAX_COLUMN_ID]; + int size = OB_TC_SHARD_MAX_COLUMN_ID; + ObString real_group_name; + ObString real_table_name = table_name; + char group_name_buf[OB_MAX_TABLEGROUP_NAME_LENGTH]; + ObString schema_type("SHARD"); + char shard_key_buf[OB_MAX_COLUMN_NAME_LENGTH]; + ObString shard_key_str = get_shard_key_str(*shard_rule, shard_key_buf, OB_MAX_COLUMN_NAME_LENGTH); + ObString shard_rule_str = get_shard_rule_str(*shard_rule); + + int64_t count = shard_rule->db_size_; + for(int64_t index = 0; index < count; ++index) { + int64_t group_index = index; + shard_rule->get_real_name_by_index(shard_rule->db_size_, + shard_rule->db_suffix_len_, group_index, + shard_rule->db_prefix_.config_string_, + shard_rule->db_tail_.config_string_, + group_name_buf, OB_MAX_TABLEGROUP_NAME_LENGTH); + real_group_name = ObString::make_string(group_name_buf); + cells[OB_TC_ID].set_int(index); + cells[OB_TC_GROUP_NAME].set_varchar(real_group_name); + cells[OB_TC_TABLE_NAME].set_varchar(real_table_name); + cells[OB_TC_SCHEMA_TYPE].set_varchar(schema_type); + cells[OB_TC_SHARD_KEY].set_varchar(shard_key_str); + cells[OB_TC_SHARD_RULE].set_varchar(shard_rule_str); + row.cells_ = cells; + row.count_ = size; + if (OB_FAIL(encode_row_packet(row))) { + WARN_CMD("fail to encode row packet for shard", K(row), K(ret)); + } + } + return ret; +} + +int ObShowTopologyHandler::dump_shard_topology_for_shard_db_shard_tb(ObShardRule *shard_rule) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY((0 == shard_rule->db_size_) || (shard_rule->tb_size_ < shard_rule->db_size_))) { + WARN_CMD("wrong shard rule for shard_db_shard_tb", K(shard_rule->db_size_), K(shard_rule->tb_size_), K(ret)); + } else { + ObNewRow row; + ObObj cells[OB_TC_SHARD_MAX_COLUMN_ID]; + int size = OB_TC_SHARD_MAX_COLUMN_ID; + ObString real_group_name; + ObString real_table_name; + char group_name_buf[OB_MAX_TABLEGROUP_NAME_LENGTH]; + char table_name_buf[OB_MAX_USER_TABLE_NAME_LENGTH]; + char shard_key_buf[OB_MAX_COLUMN_NAME_LENGTH]; + ObString schema_type("SHARD"); + ObString shard_key_str = get_shard_key_str(*shard_rule, shard_key_buf, OB_MAX_COLUMN_NAME_LENGTH); + ObString shard_rule_str = get_shard_rule_str(*shard_rule); + + int64_t count = shard_rule->tb_size_; + for(int64_t index = 0; index < count; ++index) { + int64_t group_index = index / (shard_rule->tb_size_ / shard_rule->db_size_); + shard_rule->get_real_name_by_index(shard_rule->db_size_, + shard_rule->db_suffix_len_, group_index, + shard_rule->db_prefix_.config_string_, + shard_rule->db_tail_.config_string_, + group_name_buf, OB_MAX_TABLEGROUP_NAME_LENGTH); + shard_rule->get_real_name_by_index(shard_rule->tb_size_, + shard_rule->tb_suffix_len_, index, + shard_rule->tb_prefix_.config_string_, + shard_rule->tb_tail_.config_string_, + table_name_buf, OB_MAX_USER_TABLE_NAME_LENGTH); + real_group_name = ObString::make_string(group_name_buf); + real_table_name = ObString::make_string(table_name_buf); + cells[OB_TC_ID].set_int(index); + cells[OB_TC_GROUP_NAME].set_varchar(real_group_name); + cells[OB_TC_TABLE_NAME].set_varchar(real_table_name); + cells[OB_TC_SCHEMA_TYPE].set_varchar(schema_type); + cells[OB_TC_SHARD_KEY].set_varchar(shard_key_str); + cells[OB_TC_SHARD_RULE].set_varchar(shard_rule_str); + row.cells_ = cells; + row.count_ = size; + if (OB_FAIL(encode_row_packet(row))) { + WARN_CMD("fail to encode row packet for shard", K(row), K(ret)); + } + } + } + return ret; +} + +ObString ObShowTopologyHandler::get_shard_key_str(dbconfig::ObShardRule& shard_rule, char* const target_buf, const int target_buf_len) +{ + ObString ret_str = ObString::make_string("empty shard key"); + if (OB_LIKELY(0 != shard_rule.tb_rules_.count())) { + ObString& origin_string = shard_rule.tb_rules_.at(0).shard_rule_str_.config_string_; + for(int i = 0; i < origin_string.length(); ++i) { + if(origin_string[i] != '#') { + continue; + } else { + int j = i + 1; + while(j < origin_string.length() && origin_string[j] != '#') { + ++j; + } + if((j == origin_string.length()) || (j - i - 1) >= target_buf_len) { + ret_str = ObString::make_string("error shard key"); + } else { + MEMCPY(target_buf, origin_string.ptr() + i + 1, j - i - 1); + ret_str.assign_ptr(target_buf, j - i - 1); + } + break; + } + } + } + return ret_str; +} + +ObString ObShowTopologyHandler::get_shard_rule_str(dbconfig::ObShardRule& shard_rule) +{ + ObString ret_str = ObString::make_string("empty shard rule"); + if (OB_LIKELY(0 != shard_rule.tb_rules_.count())) { + ret_str = shard_rule.tb_rules_.at(0).shard_rule_str_.config_string_; + } + return ret_str; +} } // end of namespace proxy } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/cmd/ob_show_topology_handler.h b/src/obproxy/cmd/ob_show_topology_handler.h index b250c563d..0cb0c667f 100644 --- a/src/obproxy/cmd/ob_show_topology_handler.h +++ b/src/obproxy/cmd/ob_show_topology_handler.h @@ -22,7 +22,9 @@ namespace obproxy namespace dbconfig { class ObGroupCluster; +class ObShardRule; } + namespace obutils { class ObShowTopologyHandler : public ObCmdHandler @@ -31,22 +33,37 @@ class ObShowTopologyHandler : public ObCmdHandler ObShowTopologyHandler(event::ObMIOBuffer *buf, ObCmdInfo &info); virtual ~ObShowTopologyHandler() {} + int handle_show_elastic_id(const common::ObString &tenant_name, + const common::ObString &db_name, + const common::ObString &group_name); + static int show_elastic_id_cmd_callback(event::ObMIOBuffer *buf, + ObCmdInfo &info, + const common::ObString &logic_tenant_name, + const common::ObString &logic_database_name, + const common::ObString &group_name); int handle_show_topology(const common::ObString &tenant_name, const common::ObString &db_name, - const common::ObString &group_name); + const common::ObString &table_name); static int show_topology_cmd_callback(event::ObMIOBuffer *buf, ObCmdInfo &info, const common::ObString &logic_tenant_name, const common::ObString &logic_database_name, - const common::ObString &group_name); + const common::ObString &table_name); public: static const int64_t OB_MAX_ELASTIC_ID_COUNT = 256; private: - int dump_topology_header(); + int dump_elastic_id_header(); int dump_elastic_id(const int64_t eid); + int dump_shard_topology_for_single_db(ObString table_name); + int dump_shard_topology_for_shard_db_single_tb(ObString table_name); + int dump_shard_topology_for_shard_db_non_shard_tb(ObString table_name, dbconfig::ObShardRule *shard_rule); + int dump_shard_topology_for_shard_db_shard_tb(dbconfig::ObShardRule *shard_rule); + + ObString get_shard_key_str(dbconfig::ObShardRule& shard_rule, char* const target_buf, const int target_buf_len); + ObString get_shard_rule_str(dbconfig::ObShardRule& shard_rule); private: DISALLOW_COPY_AND_ASSIGN(ObShowTopologyHandler); }; diff --git a/src/obproxy/cmd/ob_show_vip_handler.cpp b/src/obproxy/cmd/ob_show_vip_handler.cpp index 54921222d..2574107e9 100644 --- a/src/obproxy/cmd/ob_show_vip_handler.cpp +++ b/src/obproxy/cmd/ob_show_vip_handler.cpp @@ -16,6 +16,8 @@ #include "utils/ob_proxy_utils.h" #include "iocore/eventsystem/ob_task.h" #include "iocore/eventsystem/ob_event_processor.h" +#include "share/config/ob_config.h" +#include "obutils/ob_config_processor.h" using namespace oceanbase::common; using namespace oceanbase::share; @@ -68,7 +70,6 @@ int ObShowVipHandler::main_handler(int event, void *data) } else if (OB_FAIL(dump_header())) { WARN_ICMD("fail to dump header", K(ret)); } else { - ObVipTenantCache &vt_cache = get_global_vip_tenant_processor().get_vt_cache(); ObVipTenant vip_tenant; if (!like_name_.empty()) { //dump one vip tenant @@ -87,9 +88,9 @@ int ObShowVipHandler::main_handler(int event, void *data) WARN_ICMD("unexpected argument", K(vip_string), K(match_name), K(ret)); } else if (OB_FAIL(get_int_value(match_name, vport))) { WARN_ICMD("fail to get_int_value", K(match_name), K(vport), K(ret)); - } else if (!vip_addr.addr_.set_ipv4_addr(vip_string, static_cast(vport))) { + } else if (!vip_addr.addr_.set_ip_addr(vip_string, static_cast(vport))) { ret = OB_INVALID_ARGUMENT; - WARN_ICMD("fail to set_ipv4_addr", K(vip_string), K(vport), K(ret)); + WARN_ICMD("fail to set_ip_addr", K(vip_string), K(vport), K(ret)); } else if (!vip_addr.is_valid()) { ret = OB_INVALID_ARGUMENT; WARN_ICMD("invalid vip_addr", K(vip_addr), K(match_name), K(ret)); @@ -99,32 +100,38 @@ int ObShowVipHandler::main_handler(int event, void *data) } if (OB_SUCC(ret)) { - if (OB_FAIL(vt_cache.get(vip_addr, vip_tenant))) { - WARN_ICMD("fail to get vip_tenant", K(ret)); - if (OB_ENTRY_NOT_EXIST == ret) { - //empty result - ret = OB_SUCCESS; + ObConfigItem tenant_item; + ObConfigItem cluster_item; + bool found = false; + vip_tenant.vip_addr_ = vip_addr; + if (OB_FAIL(get_global_config_processor().get_proxy_config_with_level( + vip_tenant.vip_addr_, "", "", "proxy_tenant_name", tenant_item, "LEVEL_VIP", found))) { + WARN_ICMD("get proxy tenant name config failed", K(vip_tenant.vip_addr_), K(ret)); + } + if (OB_SUCC(ret) && found) { + if (OB_FAIL(get_global_config_processor().get_proxy_config_with_level( + vip_tenant.vip_addr_, "", "", "rootservice_cluster_name", cluster_item, "LEVEL_VIP", found))) { + WARN_ICMD("get cluster name config failed", K(vip_tenant.vip_addr_), K(ret)); + } + } + if (OB_SUCC(ret) && found) { + if (OB_FAIL(vip_tenant.set_tenant_cluster(tenant_item.str(), cluster_item.str()))) { + WARN_ICMD("set tenant and cluster name failed", K(tenant_item), K(cluster_item), K(ret)); + } else if (OB_FAIL(dump_item(vip_tenant))) { + WARN_ICMD("fail to dump item", K(vip_tenant), K(ret)); } - } else if (OB_FAIL(dump_item(vip_tenant))) { - WARN_ICMD("fail to dump item", K(vip_tenant), K(ret)); + } else { + WARN_ICMD("fail to get vip_tenant", K(ret)); } } else { ret = OB_ERR_OPERATOR_UNKNOWN;//return this errno } } else { //dump all vip tenant - ObVipTenantCache::VTHashMap *cache_map = NULL; - obsys::CRLockGuard guard(vt_cache.rwlock_); - if (OB_ISNULL(cache_map = vt_cache.get_cache_map())) { - ret = OB_ERR_UNEXPECTED; - WARN_ICMD("cache_map is null", K(ret)); - } else { - for (ObVipTenantCache::VTHashMap::iterator it = cache_map->begin(); - OB_SUCC(ret) && it != cache_map->end(); ++it) { - if (OB_FAIL(dump_item(*it))) { - WARN_ICMD("fail to dump item", K(*it), K(ret)); - } - } + const char* select_sql = "SELECT a.vid, a.vip, a.vport, a.value, b.value FROM proxy_config as a, proxy_config as b " + "where a.name = 'proxy_tenant_nane' and b.name = 'rootservice_cluster_name';"; + if (get_global_config_processor().execute(select_sql, ObShowVipHandler::sqlite3_callback, this)) { + WARN_ICMD("fail to execute sql", K(ret)); } } } @@ -180,6 +187,40 @@ int ObShowVipHandler::dump_item(const ObVipTenant &vip_tenant) return ret; } +int ObShowVipHandler::sqlite3_callback(void *data, int argc, char **argv, char **column_name) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(NULL == data || NULL == argv || NULL == column_name || 5 != argc)) { + ret = OB_ERR_UNEXPECTED; + WARN_ICMD("argument is unexpected", K(argc), K(ret)); + } else { + ObShowVipHandler *handler = reinterpret_cast(data); + char* vip; + int64_t vport = 0; + int64_t vid = -1; + ObVipTenant vip_tenant; + ObString tenant; + ObString cluster; + if (OB_UNLIKELY(NULL == argv[0] || NULL == argv[1] || NULL == argv[2] || NULL == argv[3] || NULL == argv[4])) { + ret = OB_ERR_UNEXPECTED; + WARN_ICMD("argument is unexpected", K(ret)); + } else { + vid = atoi(argv[0]); + vip = argv[1]; + vport = atoi(argv[2]); + tenant = argv[3]; + cluster = argv[4]; + vip_tenant.vip_addr_.set(vip, static_cast(vport), vid); + if (OB_FAIL(vip_tenant.set_tenant_cluster(tenant, cluster))) { + WARN_ICMD("fail to set tenant cluster", K(vip_tenant), K(ret)); + } else if (OB_FAIL(handler->dump_item(vip_tenant))) { + WARN_ICMD("fail to dump item", K(vip_tenant), K(ret)); + } + } + } + return ret; +} + static int show_vip_cmd_callback(ObContinuation *cont, ObInternalCmdInfo &info, ObMIOBuffer *buf, ObAction *&action) { diff --git a/src/obproxy/cmd/ob_show_vip_handler.h b/src/obproxy/cmd/ob_show_vip_handler.h index b02c90843..07f60b49c 100644 --- a/src/obproxy/cmd/ob_show_vip_handler.h +++ b/src/obproxy/cmd/ob_show_vip_handler.h @@ -25,7 +25,8 @@ namespace obutils class ObShowVipHandler : public ObInternalCmdHandler { public: - ObShowVipHandler(event::ObContinuation *cont, event::ObMIOBuffer *buf, const ObInternalCmdInfo &info); + ObShowVipHandler(event::ObContinuation *cont, event::ObMIOBuffer *buf, + const ObInternalCmdInfo &info); virtual ~ObShowVipHandler() {} int main_handler(int event, void *data); @@ -33,6 +34,7 @@ class ObShowVipHandler : public ObInternalCmdHandler int dump_header(); int dump_body(); int dump_item(const ObVipTenant &vip_tenant); + static int sqlite3_callback(void *data, int argc, char **argv, char **column_name); DISALLOW_COPY_AND_ASSIGN(ObShowVipHandler); }; diff --git a/src/obproxy/dbconfig/grpc/ob_proxy_grpc_client.cpp b/src/obproxy/dbconfig/grpc/ob_proxy_grpc_client.cpp index 0aa658bbb..d2fdaf1d6 100644 --- a/src/obproxy/dbconfig/grpc/ob_proxy_grpc_client.cpp +++ b/src/obproxy/dbconfig/grpc/ob_proxy_grpc_client.cpp @@ -156,15 +156,15 @@ int ObGrpcClient::fill_request_node(DiscoveryRequest &request) const char *is_sidecar = getenv("IS_SIDECAR"); if (OB_NOT_NULL(is_sidecar) && OB_UNLIKELY(strncmp(is_sidecar, "false", strlen(is_sidecar)) == 0)) {// app is not in sidecar - char ipstr[OB_IP_STR_BUFF]; - MEMSET(ipstr, 0, OB_IP_STR_BUFF); + char ipstr[MAX_IP_ADDR_LENGTH]; + MEMSET(ipstr, 0, MAX_IP_ADDR_LENGTH); ObSEArray labels; char json[MAX_REQUEST_LABELS_LENGTH]; MEMSET(json, 0, sizeof(json)); - if (OB_FAIL(getip_from_nodeid(ipstr, OB_IP_STR_BUFF))) { + if (OB_FAIL(getip_from_nodeid(ipstr, MAX_IP_ADDR_LENGTH))) { LOG_WARN("can not get ip from node id", K(ret)); } else if (OB_UNLIKELY(strlen(ipstr) == 0)) { ret = OB_ERR_UNEXPECTED; @@ -227,7 +227,7 @@ int ObGrpcClient::getip_from_nodeid(char *ipstr, int64_t length) if (OB_SUCC(ret)) { if (OB_UNLIKELY(length < ip.length())) { ret = OB_SIZE_OVERFLOW; - LOG_WARN("IP string in node id is longer than OB_IP_STR_BUFF", K(length), K(ip.length()), K(ret)); + LOG_WARN("IP string in node id is longer than MAX_IP_ADDR_LENGTH", K(length), K(ip.length()), K(ret)); } else { memcpy(ipstr, ip.ptr(), ip.length()); ipstr[ip.length()] = '\0'; @@ -321,7 +321,17 @@ int ObGrpcClient::to_json(ObIArray& labels, char *json, int bool ObGrpcClient::sync_read(DiscoveryResponse &response) { - return stream_->Read(&response); + bool status = false; + int ret = OB_SUCCESS; + status = stream_->Read(&response); + if (!status) { + LOG_INFO("the stream has been closed, will rebuild the grpc client stream"); + finish_rpc(); + if (OB_FAIL(init_stream())) { + LOG_WARN("fail to init stream", K(ret)); + } + } + return status; } void ObGrpcClient::finish_rpc() diff --git a/src/obproxy/dbconfig/ob_proxy_db_config_info.cpp b/src/obproxy/dbconfig/ob_proxy_db_config_info.cpp index c2e2ac01b..be5030c6e 100644 --- a/src/obproxy/dbconfig/ob_proxy_db_config_info.cpp +++ b/src/obproxy/dbconfig/ob_proxy_db_config_info.cpp @@ -1636,10 +1636,9 @@ int ObShardRule::get_physic_index(const SqlFieldResult &sql_result, const ObProxyShardRuleInfo &rule = rules.at(i); ObProxyExprCtx expr_ctx(physic_size, type, is_elastic_index, &allocator); ObProxyExpr *proxy_expr = rule.expr_; - ObObj result_obj; ObSEArray result_array; int64_t tmp_index = OBPROXY_MAX_DBMESH_ID; - + int64_t tmp_index_for_one_obj = OBPROXY_MAX_DBMESH_ID; LOG_DEBUG("begin to calc rule", K(rule)); ObProxyExprCalcItem calc_item(const_cast(&sql_result)); @@ -1654,16 +1653,23 @@ int ObShardRule::get_physic_index(const SqlFieldResult &sql_result, LOG_WARN("calc proxy expr failed", K(ret)); } } else { - result_obj = result_array.at(0); - ObObj tmp_obj; - if (OB_FAIL(ObProxyFuncExpr::get_int_obj(result_obj, tmp_obj))) { - LOG_WARN("get int obj failed", K(result_obj), K(ret)); - } else if (OB_FAIL(tmp_obj.get_int(tmp_index))) { - LOG_WARN("get int failed", K(ret)); - } else { - if (tmp_index < 0 || tmp_index >= physic_size) { - ret = OB_EXPR_CALC_ERROR; - LOG_WARN("invalid index", K(tmp_index), K(physic_size), K(ret)); + for(int64_t j = 0; OB_SUCC(ret) && j < result_array.count(); j++) { + ObObj& result_obj = result_array.at(j); + ObObj tmp_obj; + if (OB_FAIL(ObProxyFuncExpr::get_int_obj(result_obj, tmp_obj, allocator))) { + LOG_WARN("get int obj failed", K(result_obj), K(ret)); + } else if (OB_FAIL(tmp_obj.get_int(tmp_index_for_one_obj))) { + LOG_WARN("get int failed", K(ret)); + } else if (tmp_index_for_one_obj < 0 || tmp_index_for_one_obj >= physic_size) { + ret = OB_EXPR_CALC_ERROR; + LOG_WARN("invalid index", K(tmp_index_for_one_obj), K(physic_size), K(ret)); + } else if (OBPROXY_MAX_DBMESH_ID == tmp_index) { + tmp_index = tmp_index_for_one_obj; + } else if (tmp_index != tmp_index_for_one_obj) { + ret = OB_ERR_DISTRIBUTED_NOT_SUPPORTED; + LOG_WARN("different physic index for one sharding key is not supported", K(tmp_index), K(last_index), K(ret)); + } else { + //nothing } } } @@ -1749,7 +1755,7 @@ int ObShardRule::get_physic_index_array(const SqlFieldResult &sql_result, for (int64_t i = 0; OB_SUCC(ret) && i < result_obj_array.count(); i++) { ObObj tmp_obj; int64_t tmp_index; - if (OB_FAIL(ObProxyFuncExpr::get_int_obj(result_obj_array.at(i), tmp_obj))) { + if (OB_FAIL(ObProxyFuncExpr::get_int_obj(result_obj_array.at(i), tmp_obj, allocator))) { LOG_WARN("get int obj failed", K(ret), K(result_obj_array.at(i))); } else if (OB_FAIL(tmp_obj.get_int(tmp_index))) { LOG_WARN("get int failed", K(ret)); @@ -2009,6 +2015,91 @@ int ObDbConfigLogicDb::get_shard_router(const ObString &tb_name, ObShardRouter * return ret; } +int ObDbConfigLogicDb::get_first_group_shard_connector(ObShardConnector *&shard_conn, int64_t es_id, + bool is_read_stmt, ObTestLoadType testload_type) +{ + int ret = OB_SUCCESS; + + ObShardTpo *shard_tpo = NULL; + ObGroupCluster *gc_info = NULL; + + if (OB_FAIL(get_shard_tpo(shard_tpo))) { + LOG_WARN("fail to get shard tpo info", K(ret)); + } else if (OB_ISNULL(shard_tpo)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("shard tpo info is null", K(ret)); + } else if (is_single_shard_db_table()) { + ObShardTpo::GCHashMap::iterator it = (const_cast(shard_tpo->gc_map_)).begin(); + gc_info = &(*it); + } else { + ObShardRule *logic_tb_info = NULL; + { + ObDbConfigCache &dbconfig_cache = get_global_dbconfig_cache(); + obsys::CRLockGuard guard(dbconfig_cache.rwlock_); + ObDbConfigChildArrayInfo::CCRHashMap &map = const_cast::CCRHashMap &>(sr_array_.ccr_map_); + for (ObDbConfigChildArrayInfo::CCRHashMap::iterator it = map.begin(); it != map.end(); ++it) { + ObShardRouter::MarkedRuleHashMap &mr_map = it->mr_map_; + for (ObShardRouter::MarkedRuleHashMap::iterator sub_it = mr_map.begin(); + sub_it != mr_map.end(); ++sub_it) { + logic_tb_info = &(*sub_it); + break; + } + } + } + + if (OB_SUCC(ret)) { + char real_database_name[OB_MAX_DATABASE_NAME_LENGTH]; + if (OB_FAIL(logic_tb_info->get_real_name_by_index(logic_tb_info->db_size_, logic_tb_info->db_suffix_len_, 0, + logic_tb_info->db_prefix_.config_string_, + logic_tb_info->db_tail_.config_string_, + real_database_name, OB_MAX_DATABASE_NAME_LENGTH))) { + LOG_WARN("fail to get real group name", KPC(logic_tb_info), K(ret)); + } else if (OB_FAIL(shard_tpo->get_group_cluster(ObString::make_string(real_database_name), gc_info))) { + LOG_DEBUG("group does not exist", "phy_db_name", real_database_name, K(ret)); + } else if (OB_ISNULL(gc_info)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("group cluster info is null", "phy_db_name", real_database_name, K(ret)); + } + } + } + + if (OB_SUCC(ret)) { + // Calculate es_id + int64_t es_size = gc_info->get_es_size(); + ObString shard_name; + if (-1 == es_id || OBPROXY_MAX_DBMESH_ID == es_id) { + if (OB_FAIL(gc_info->get_elastic_id_by_weight(es_id, is_read_stmt))) { + LOG_WARN("fail to get eid by read weight", KPC(gc_info)); + } else { + LOG_DEBUG("succ to get eid by weight", K(es_id)); + } + } else if (OB_UNLIKELY(es_id >= es_size)) { + ret = OB_EXPR_CALC_ERROR; + LOG_WARN("es index is larger than elastic array", K(es_id), K(es_size), K(ret)); + } + } + + if (OB_SUCC(ret)) { + ObString shard_name; + if (FALSE_IT(shard_name = gc_info->get_shard_name_by_eid(es_id))) { + } else if (TESTLOAD_NON != testload_type) { + if (OB_FAIL(get_testload_shard_connector(shard_name, testload_prefix_.config_string_, shard_conn))) { + LOG_WARN("testload shard connector not exist", "testload_type", get_testload_type_str(testload_type), + K(shard_name), "testload_prefix", testload_prefix_, K(ret)); + } + } else if (OB_FAIL(get_shard_connector(shard_name, shard_conn))) { + LOG_WARN("shard connector does not exist", K(shard_name), K(ret)); + } + } + + if (NULL != shard_tpo) { + shard_tpo->dec_ref(); + shard_tpo = NULL; + } + + return ret; +} + int ObDbConfigLogicDb::get_all_shard_table(ObIArray &all_table) { int ret = OB_SUCCESS; @@ -3729,7 +3820,8 @@ int ObDbConfigLogicDb::get_shard_table_info(const ObString &table_name, char *real_table_name, int64_t tb_name_len, int64_t &group_index, int64_t &tb_index, int64_t &es_index, const ObString &hint_table, ObTestLoadType testload_type, - const bool is_read_stmt) + const bool is_read_stmt, + const int64_t last_es_index /*OBPROXY_MAX_DBMESH_ID*/) { int ret = OB_SUCCESS; @@ -3766,7 +3858,12 @@ int ObDbConfigLogicDb::get_shard_table_info(const ObString &table_name, bool is_elastic_index = true; ObString shard_name; if (-1 == es_index || (OBPROXY_MAX_DBMESH_ID == es_index && logic_tb_info->es_rules_.empty())) { - if (OB_FAIL(gc_info->get_elastic_id_by_weight(es_index, is_read_stmt))) { + if (is_read_stmt + && (last_es_index >= 0) + && (last_es_index < es_size)) { + //In multiple statements, the read request can use the effective es id of the previous statement + es_index = last_es_index; + } else if (OB_FAIL(gc_info->get_elastic_id_by_weight(es_index, is_read_stmt))) { LOG_WARN("fail to get eid by read weight", KPC(gc_info)); } else { LOG_DEBUG("succ to get eid by weight", K(es_index)); @@ -3850,7 +3947,7 @@ int ObDbConfigLogicDb::get_single_table_info(const ObString &table_name, char *real_table_name, int64_t tb_name_len, int64_t &group_id, int64_t &table_id, int64_t &es_id, const ObString &hint_table, ObTestLoadType testload_type, - const bool is_read_stmt) + const bool is_read_stmt, const int64_t last_es_id/*OBPROXY_MAX_DBMESH_ID*/) { int ret = OB_SUCCESS; @@ -3871,7 +3968,12 @@ int ObDbConfigLogicDb::get_single_table_info(const ObString &table_name, const ObGroupCluster &gc_info = *it; int64_t es_size = gc_info.get_es_size(); if (es_id < 0 || OBPROXY_MAX_DBMESH_ID == es_id) { - if (OB_FAIL(gc_info.get_elastic_id_by_weight(es_id, is_read_stmt))) { + if (is_read_stmt + && (last_es_id >= 0) + && (last_es_id < es_size)) { + //In multiple statements, the read request can use the effective es id of the previous statement + es_id = last_es_id; + } if (OB_FAIL(gc_info.get_elastic_id_by_weight(es_id, is_read_stmt))) { LOG_WARN("fail to get random eid", K(gc_info)); } } else if (OB_UNLIKELY(es_id >= es_size)) { @@ -4557,8 +4659,8 @@ int ObDbConfigLogicDb::get_table_name_by_index(ObSqlParseResult &parse_result, { int ret = OB_SUCCESS; - ObProxySelectStmt *select_stmt = static_cast(parse_result.get_proxy_stmt()); - ObProxySelectStmt::ExprMap &table_exprs_map = select_stmt->get_table_exprs_map(); + ObProxyDMLStmt *dml_stmt = static_cast(parse_result.get_proxy_stmt()); + ObProxyDMLStmt::ExprMap &table_exprs_map = dml_stmt->get_table_exprs_map(); SqlFieldResult &sql_result = parse_result.get_sql_filed_result(); char real_table_name[OB_MAX_TABLE_NAME_LENGTH]; @@ -4570,8 +4672,8 @@ int ObDbConfigLogicDb::get_table_name_by_index(ObSqlParseResult &parse_result, for (int64_t i = 0; OB_SUCC(ret) && i < table_index_array.count(); i++) { int64_t tb_index = table_index_array.at(i); - ObProxySelectStmt::ExprMap::iterator iter = table_exprs_map.begin(); - ObProxySelectStmt::ExprMap::iterator end = table_exprs_map.end(); + ObProxyDMLStmt::ExprMap::iterator iter = table_exprs_map.begin(); + ObProxyDMLStmt::ExprMap::iterator end = table_exprs_map.end(); table_name_map_wrapper.reuse(); for (; OB_SUCC(ret) && iter != end; iter++) { diff --git a/src/obproxy/dbconfig/ob_proxy_db_config_info.h b/src/obproxy/dbconfig/ob_proxy_db_config_info.h index 7465e7e4a..faf21f07b 100644 --- a/src/obproxy/dbconfig/ob_proxy_db_config_info.h +++ b/src/obproxy/dbconfig/ob_proxy_db_config_info.h @@ -936,7 +936,8 @@ class ObDbConfigLogicDb : public ObDbConfigChild char *real_table_name, int64_t tb_name_len, int64_t &group_id, int64_t &table_id, int64_t &es_id, const common::ObString &hint_table, - ObTestLoadType testload_type, const bool is_read_stmt); + ObTestLoadType testload_type, const bool is_read_stmt, + const int64_t last_es_id = OBPROXY_MAX_DBMESH_ID); int get_shard_table_info(const common::ObString &table_name, obutils::SqlFieldResult &sql_result, ObShardConnector *&shard_conn, @@ -944,7 +945,8 @@ class ObDbConfigLogicDb : public ObDbConfigChild char *real_table_name, int64_t tb_name_len, int64_t &group_index, int64_t &tb_index, int64_t &es_index, const common::ObString &hint_table, - ObTestLoadType testload_type, const bool is_read_stmt); + ObTestLoadType testload_type, const bool is_read_stmt, + const int64_t last_es_index = OBPROXY_MAX_DBMESH_ID); int get_shard_prop(const common::ObString & shard_name, ObShardProp* &shard_prop); int get_real_table_name(const ObString &table_name, obutils::SqlFieldResult &sql_result, @@ -968,6 +970,8 @@ class ObDbConfigLogicDb : public ObDbConfigChild int64_t es_index, common::ObIArray &group_index_array, common::ObIArray &shard_connector_array); + int get_first_group_shard_connector(ObShardConnector *&shard_conn, int64_t es_id, + bool is_read_stmt, ObTestLoadType testload_type); int get_table_name_by_index(obutils::ObSqlParseResult &parse_result, ObTestLoadType testload_type, ObIAllocator &allocator, diff --git a/src/obproxy/driver/c/Makemodule.am b/src/obproxy/driver/c/Makemodule.am new file mode 100644 index 000000000..ffb8c232c --- /dev/null +++ b/src/obproxy/driver/c/Makemodule.am @@ -0,0 +1,3 @@ +obproxy_c_driver_sources:=\ +obproxy/driver/c/ob_proxy_vc_c.h\ +obproxy/driver/c/ob_proxy_vc_c.cpp \ No newline at end of file diff --git a/src/obproxy/driver/c/ob_proxy_vc_c.cpp b/src/obproxy/driver/c/ob_proxy_vc_c.cpp new file mode 100644 index 000000000..b5d8e17f3 --- /dev/null +++ b/src/obproxy/driver/c/ob_proxy_vc_c.cpp @@ -0,0 +1,231 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#include "ob_proxy_vc_c.h" +#include "proxy/client/ob_driver_client.h" +#include "ob_proxy_init.h" +#include "lib/oblog/ob_log.h" +#include "lib/objectpool/ob_concurrency_objpool.h" + +#include + +using namespace oceanbase::common; +using namespace oceanbase::obproxy; +using namespace oceanbase::obproxy::proxy; + +int ob_proxy_vc_c_init(const char *config, void **p_driver_client) +{ + int ret = OB_SUCCESS; + ObDriverClient *driver_client = NULL; + + if (OB_ISNULL(config) || OB_ISNULL(p_driver_client)) { + ret = OB_INVALID_ARGUMENT; + MPRINT("invalid argument config=%p, p_driver_client=%p, ret=%d", config, p_driver_client, ret); + } else if (OB_FAIL(init_obproxy_client(config))) { + MPRINT("init obproxy client failed, ret=%d", ret); + } else if (OB_ISNULL(driver_client = new(std::nothrow) ObDriverClient())) { + ret = OB_ALLOCATE_MEMORY_FAILED; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "driver client is null unexpected", K(ret)); + } else if (OB_FAIL(driver_client->init())) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "driver client init failed", K(ret)); + } else { + *p_driver_client = static_cast(driver_client); + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "create driver_client success", KP(driver_client)); + } + + if(OB_FAIL(ret) && OB_NOT_NULL(driver_client)) { + delete driver_client; + } + + return ret; +} + +int ob_proxy_vc_c_connect(void *driver_client_handle, int64_t conn_timeout, int64_t sock_timeout) +{ + int ret = OB_SUCCESS; + ObDriverClient *driver_client; + + if (OB_ISNULL(driver_client_handle) || conn_timeout < 0 || sock_timeout < 0) { + ret = OB_INVALID_ARGUMENT; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "invalid argument", KP(driver_client_handle), K(conn_timeout), K(sock_timeout), K(ret)); + } else { + driver_client = static_cast(driver_client_handle); + driver_client->set_connect_timeout(conn_timeout); + + if (conn_timeout == 0 && OB_FAIL(driver_client->sync_connect())) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "driver client connect failed", K(ret)); + } else if (conn_timeout > 0 && OB_FAIL(driver_client->sync_connect_with_timeout())) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "driver client connect with timeout failed", K(conn_timeout), K(ret)); + } else { + driver_client->set_send_timeout(sock_timeout); + driver_client->set_recv_timeout(sock_timeout); + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "driver client connect success", K(driver_client)); + } + } + + return ret; +} + +int ob_proxy_vc_c_recv(void *driver_client_handle, char *buffer, int64_t offset, int64_t mlen, int64_t *recv_len, int64_t flag) +{ + int ret = OB_SUCCESS; + int64_t rlen = 0; + ObDriverClient *driver_client; + UNUSED(flag); + + if (OB_ISNULL(driver_client_handle) || OB_ISNULL(buffer) || OB_ISNULL(recv_len)) { + ret = OB_INVALID_ARGUMENT; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "invalid argument", KP(driver_client_handle), K(buffer), K(recv_len), K(ret)); + } else { + driver_client = static_cast(driver_client_handle); + if (OB_FAIL(driver_client->sync_recv_with_timeout(buffer + offset, mlen, rlen))) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "sync recv failed", K(ret)); + } else { + if (rlen < 0) { + switch (errno) { + case ECONNRESET: + case EPIPE: + OBPROXY_DRIVER_CLIENT_LOG(WARN, "Connection reset", "errno", errno); + break; + case EBADF: + OBPROXY_DRIVER_CLIENT_LOG(WARN, "Socket closed", "errno", errno); + break; + case EINTR: + OBPROXY_DRIVER_CLIENT_LOG(WARN, "Operation interrupted", "errno", errno); + break; + default: + OBPROXY_DRIVER_CLIENT_LOG(WARN, "socket read error", "errno", errno); + break; + } + ret = OB_ERR_UNEXPECTED; + } else if (rlen == 0) { + ret = OB_ERR_UNEXPECTED; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "peer close", KP(driver_client), K(ret)); + } else { + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "read success", K(rlen)); + *recv_len = rlen; + } + } + } + + return ret; +} + +int ob_proxy_vc_c_send(void *driver_client_handle, const char *buffer, int64_t offset, int64_t mlen, int64_t *send_len, int64_t flag) +{ + int ret = OB_SUCCESS; + int64_t wlen = 0; + ObDriverClient *driver_client; + UNUSED(flag); + + if (OB_ISNULL(driver_client_handle) || OB_ISNULL(buffer) || OB_ISNULL(send_len)) { + ret = OB_INVALID_ARGUMENT; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "invalid argument", KP(driver_client_handle), K(buffer), K(send_len), K(ret)); + } else { + driver_client = static_cast(driver_client_handle); + + if (OB_FAIL(driver_client->sync_send_with_timeout(buffer + offset, mlen, wlen))) { + ret = OB_ERR_UNEXPECTED; //send error; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "sync_send_with_timeout failed", K(wlen), K(ret)); + } else { + if (wlen > 0) { + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "sync write success", K(wlen)); + *send_len = wlen; + } else { + ret = ob_get_sys_errno(); + if (errno == ECONNRESET) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "wlen is unexpected, connection reset", K(wlen), K(ret)); + } else { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "wlen is unexpected, write failed", K(wlen), K(ret)); + } + } + } + } + + return ret; +} + +int ob_proxy_vc_c_close(void *driver_client_handle) +{ + int ret = OB_SUCCESS; + ObDriverClient *driver_client; + + if (OB_ISNULL(driver_client_handle)) { + ret = OB_INVALID_ARGUMENT; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "invalid argument", KP(driver_client_handle), K(ret)); + } else { + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "free driver client", KP(driver_client_handle)); + driver_client = static_cast(driver_client_handle); + delete driver_client; + driver_client = NULL; + } + + return ret; +} + +int ob_proxy_vc_set_timeout(void *driver_client_handle, int type, int timeout) +{ + int ret = OB_SUCCESS; + ObDriverClient *driver_client; + const int C_DRIVER_CONNECT_TIMEOUT = 0; + const int C_DRIVER_READ_TIMEOUT = 1; + const int C_DRIVER_WRITE_TIMEOUT = 2; + const int C_DRIVER_TIMEOUT_MAX = 3; + + if (OB_ISNULL(driver_client_handle) || type < 0 || C_DRIVER_TIMEOUT_MAX <= type) { + ret = OB_INVALID_ARGUMENT; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "invalid argument", KP(driver_client_handle), K(type), K(ret)); + } else { + driver_client = static_cast(driver_client_handle); + + if (C_DRIVER_CONNECT_TIMEOUT == type) { + driver_client->set_connect_timeout(timeout); + } else if (C_DRIVER_READ_TIMEOUT == type) { + driver_client->set_recv_timeout(timeout); + } else if (C_DRIVER_WRITE_TIMEOUT == type) { + driver_client->set_send_timeout(timeout); + } + + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "driver client set timeout succ", K(type), K(timeout)); + } + + return ret; +} + +int ob_proxy_vc_get_timeout(void *driver_client_handle, int type, int *timeout) +{ + int ret = OB_SUCCESS; + ObDriverClient *driver_client; + const int C_DRIVER_CONNECT_TIMEOUT = 0; + const int C_DRIVER_READ_TIMEOUT = 1; + const int C_DRIVER_WRITE_TIMEOUT = 2; + const int C_DRIVER_TIMEOUT_MAX = 3; + + if (OB_ISNULL(driver_client_handle) || OB_ISNULL(timeout) || type < C_DRIVER_CONNECT_TIMEOUT || C_DRIVER_TIMEOUT_MAX <= type) { + ret = OB_INVALID_ARGUMENT; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "invalid argument", KP(driver_client_handle), KP(timeout), K(type), K(ret)); + } else { + driver_client = static_cast(driver_client_handle); + + if (C_DRIVER_CONNECT_TIMEOUT == type) { + *timeout = static_cast(driver_client->get_connect_timeout()); + } else if (C_DRIVER_READ_TIMEOUT == type) { + *timeout = static_cast(driver_client->get_recv_timeout()); + } else if (C_DRIVER_WRITE_TIMEOUT == type) { + *timeout = static_cast(driver_client->get_send_timeout()); + } + + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "driver client get timeout succ", K(type), "timeout", *timeout); + } + + return ret; +} \ No newline at end of file diff --git a/src/obproxy/driver/c/ob_proxy_vc_c.h b/src/obproxy/driver/c/ob_proxy_vc_c.h new file mode 100644 index 000000000..80f37d8ae --- /dev/null +++ b/src/obproxy/driver/c/ob_proxy_vc_c.h @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#ifndef _OB_OPROXY_VC_C_H +#define _OB_OPROXY_VC_C_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief + * libobclient calls this function to init obproxy and get driver_client handle + * @param config obproxy config string + * @param driver_client point to driver_client handle + * @return int OB_SUCCESS means success and other means failure + */ +int ob_proxy_vc_c_init(const char *config, void **driver_client); + +/** + * @brief + * libobclient calls this function to connect to obproxy + * @param driver_client driver_client handle + * @param conn_timeout connection timeout + * @param sock_timeout socket timeout + * @return int + */ +int ob_proxy_vc_c_connect(void *driver_client, int64_t conn_timeout, int64_t sock_timeout); + +/** + * @brief + * libobclient calls this function to receive data from obproxy + * @param driver_client driver_client handle + * @param buffer receive buffer + * @param offset buffer offset + * @param mlen max receive length + * @param recv_len point to receive length + * @param flag receive flag + * @return int + */ +int ob_proxy_vc_c_recv(void *driver_client, char *buffer, int64_t offset, int64_t mlen, int64_t *recv_len, int64_t flag); + +/** + * @brief + * libobclient calls this function to send data to obproxy + * @param driver_client driver_client handle + * @param buffer send buffer + * @param offset buffer offset + * @param mlen send buffer len + * @param send_len point to send length + * @param flag send flag + * @return int + */ +int ob_proxy_vc_c_send(void *driver_client, const char *buffer, int64_t offset, int64_t mlen, int64_t *send_len, int64_t flag); + +/** + * @brief + * libobclient calls this function to close driver client, but not stop obproxy service + * @param driver_client driver_client handle + * @return int + */ +int ob_proxy_vc_c_close(void *driver_client); + +/** + * @brief + * libobclient calls this function to set timeout + * @param driver_client driver_client handle + * @param type type for timeout + * @param timeout ms + * @return int + */ +int ob_proxy_vc_set_timeout(void *driver_client, int type, int timeout); + +/** + * @brief + * libobclient calls this function to get timeout + * @param driver_client driver_client handle + * @param type type for timeout + * @param timeout ms + * @return int + */ +int ob_proxy_vc_get_timeout(void *driver_client_handle, int type, int *timeout); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /*_OB_OPROXY_VC_JNI_H */ \ No newline at end of file diff --git a/src/obproxy/engine/Makemodule.am b/src/obproxy/engine/Makemodule.am index 75b4e148b..44a328ebc 100644 --- a/src/obproxy/engine/Makemodule.am +++ b/src/obproxy/engine/Makemodule.am @@ -11,4 +11,6 @@ obproxy/engine/ob_proxy_operator_agg.cpp\ obproxy/engine/ob_proxy_operator_table_scan.h\ obproxy/engine/ob_proxy_operator_table_scan.cpp\ obproxy/engine/ob_proxy_operator_async_task.h\ -obproxy/engine/ob_proxy_operator_async_task.cpp +obproxy/engine/ob_proxy_operator_async_task.cpp\ +obproxy/engine/ob_proxy_operator_cont.h\ +obproxy/engine/ob_proxy_operator_cont.cpp diff --git a/src/obproxy/engine/ob_proxy_operator_agg.cpp b/src/obproxy/engine/ob_proxy_operator_agg.cpp index 959d9f4f6..2f3d9f0ff 100644 --- a/src/obproxy/engine/ob_proxy_operator_agg.cpp +++ b/src/obproxy/engine/ob_proxy_operator_agg.cpp @@ -604,7 +604,7 @@ int ObProxyStreamAggOp::handle_response_result(void *data, bool &is_final, ObPro ResultRow *row = NULL; while (OB_SUCC(ret) && OB_SUCC(opres->next(row))) { ObProxyGroupUnit group_unit(allocator_); - if (OB_FAIL(group_unit.init(row, group_exprs))) { + if (OB_FAIL(group_unit.init(row, result_fields_, group_exprs))) { LOG_WARN("fail to init group unit", K(ret)); } else if (NULL == current_group_unit_) { if (OB_FAIL(ObProxyGroupUnit::create_group_unit(allocator_, current_group_unit_, group_unit))) { @@ -732,7 +732,7 @@ int ObProxyMemMergeAggOp::handle_response_result(void *data, bool &is_final, ObP while (OB_SUCC(ret) && OB_SUCC(opres->next(row))) { ObProxyGroupUnit group_unit(allocator_); ObProxyGroupUnit *current_group_unit = NULL; - if (OB_FAIL(group_unit.init(row, group_exprs))) { + if (OB_FAIL(group_unit.init(row, result_fields_, group_exprs))) { LOG_WARN("fail to init group unit", K(ret)); } else if (OB_FAIL(group_unit_map_.get_refactored(group_unit, current_group_unit))) { if (OB_HASH_NOT_EXIST == ret) { @@ -827,7 +827,8 @@ ObProxyGroupUnit::~ObProxyGroupUnit() } } -int ObProxyGroupUnit::init(ResultRow *row, const ObIArray& group_exprs) +int ObProxyGroupUnit::init(ResultRow *row, ResultFields *result_fields, + const ObIArray& group_exprs) { int ret = OB_SUCCESS; @@ -837,11 +838,21 @@ int ObProxyGroupUnit::init(ResultRow *row, const ObIArray& gr for (int64_t i = 0; OB_SUCC(ret) && i < group_exprs.count(); i++) { if (OB_FAIL(group_exprs.at(i)->calc(ctx, calc_item, group_values_))) { LOG_WARN("fail to calc group exprs", K(ret)); + } else { + int64_t index = group_exprs.at(i)->get_expr()->get_index(); + if (-1 != index) { + ObObj &value = group_values_.at(i); + if (OB_FAIL(change_sql_value(value, result_fields->at(index), &allocator_))) { + LOG_WARN("fail to change sql value", K(value), + "filed", result_fields->at(index), K(ret)); + } + } } } if (OB_SUCC(ret)) { row_ = row; + result_fields_ = result_fields; } return ret; @@ -880,6 +891,7 @@ int ObProxyGroupUnit::assign(const ObProxyGroupUnit &group_unit) LOG_WARN("fail to assign group value", K(ret)); } else { row_ = group_unit.get_row(); + result_fields_ = group_unit.get_result_fields(); } return ret; @@ -898,8 +910,19 @@ int ObProxyGroupUnit::do_aggregate(ResultRow *row) agg_values.reuse(); if (OB_FAIL(agg_unit->get_agg_expr()->calc(ctx, calc_item, agg_values))) { LOG_WARN("fail to calc agg expr", K(ret)); - } else if (OB_FAIL(agg_unit->merge(agg_values))) { - LOG_WARN("fail to merge agg value", K(ret)); + } else { + int64_t index = agg_unit->get_agg_expr()->get_index(); + if (-1 != index) { + ObObj &value = agg_values.at(0); + if (OB_FAIL(change_sql_value(value, result_fields_->at(index), &allocator_))) { + LOG_WARN("fail to change sql value", K(value), + "filed", result_fields_->at(index), K(ret)); + } + } + + if (OB_SUCC(ret) && OB_FAIL(agg_unit->merge(agg_values))) { + LOG_WARN("fail to merge agg value", K(ret)); + } } } diff --git a/src/obproxy/engine/ob_proxy_operator_agg.h b/src/obproxy/engine/ob_proxy_operator_agg.h index 223d84968..82792f3f5 100644 --- a/src/obproxy/engine/ob_proxy_operator_agg.h +++ b/src/obproxy/engine/ob_proxy_operator_agg.h @@ -350,12 +350,13 @@ class ObProxyGroupUnit { public: ObProxyGroupUnit(common::ObIAllocator &allocator) - : allocator_(allocator), row_(NULL), + : allocator_(allocator), row_(NULL), result_fields_(NULL), group_values_(ObModIds::OB_SE_ARRAY_ENGINE, ENGINE_ARRAY_NEW_ALLOC_SIZE), agg_units_(ObModIds::OB_SE_ARRAY_ENGINE, ENGINE_ARRAY_NEW_ALLOC_SIZE) {} ~ObProxyGroupUnit(); - int init(ResultRow *row, const common::ObIArray& group_by_exprs); + int init(ResultRow *row, ResultFields *result_fields, + const common::ObIArray& group_by_exprs); uint64_t hash() const; bool operator==(const ObProxyGroupUnit &group_unit) const; @@ -366,6 +367,7 @@ class ObProxyGroupUnit int set_agg_value(); ResultRow *get_row() const { return row_; } + ResultFields *get_result_fields() const { return result_fields_; } const common::ObIArray& get_group_values() const { return group_values_; } const common::ObIArray& get_agg_units() { return agg_units_;; } @@ -385,6 +387,7 @@ class ObProxyGroupUnit private: common::ObIAllocator &allocator_; ResultRow *row_; + ResultFields *result_fields_; common::ObSEArray group_values_; common::ObSEArray agg_units_; }; diff --git a/src/obproxy/engine/ob_proxy_operator_cont.cpp b/src/obproxy/engine/ob_proxy_operator_cont.cpp new file mode 100644 index 000000000..edb490051 --- /dev/null +++ b/src/obproxy/engine/ob_proxy_operator_cont.cpp @@ -0,0 +1,301 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#define USING_LOG_PREFIX PROXY + +#include "ob_proxy_operator_cont.h" +#include "lib/oblog/ob_log_module.h" + +using namespace oceanbase::common; +using namespace oceanbase::obproxy::event; +using namespace oceanbase::obproxy::obutils; + +namespace oceanbase +{ +namespace obproxy +{ +namespace engine +{ + +int ObProxyOperatorCont::init(ObProxyOperator* operator_root, uint8_t seq, const int64_t timeout_ms) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(NULL != buf_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected buf is not null", K(ret)); + } else if (OB_ISNULL(buf_ = new_empty_miobuffer())) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to new_empty_miobuffer for buf", K(ret)); + } else if (OB_ISNULL(buf_reader_ = buf_->alloc_reader())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to allocate buffer reader", K(ret)); + } else { + operator_root_ = operator_root; + timeout_ms_ = timeout_ms; + seq_ = seq; + } + + return ret; +} + +int ObProxyOperatorCont::main_handler(int event, void *data) +{ + int ret = OB_SUCCESS; + + if (NULL == execute_thread_) { + execute_thread_ = &self_ethread(); + } + + switch (event) { + case EVENT_INTERVAL: { + timeout_action_ = NULL; + // If it has been canceled, then the underlying operator has been released, + // and here we need to set pending_action_ to NULL + if (action_.cancelled_) { + pending_action_ = NULL; + } + + if (OB_FAIL(handle_timeout())) { + LOG_WARN("fail to handle timeout"); + } + break; + } + case EVENT_IMMEDIATE: { + pending_action_ = NULL; + if (OB_FAIL(cancel_timeout_action())) { + LOG_WARN("fail to cancel_timeout_action", K(ret)); + } else if (OB_FAIL(handle_event_start())) { + LOG_INFO("fail to handle event start", K(ret)); + } else if (OB_FAIL(schedule_timeout())) { + LOG_WARN("fail to schedule timeout action", K(ret)); + } + break; + } + case VC_EVENT_READ_COMPLETE: { + pending_action_ = NULL; + if (OB_FAIL(cancel_timeout_action())) { + LOG_WARN("fail to cancel_timeout_action", K(ret)); + } else if (OB_FAIL(handle_event_complete(data))) { + LOG_WARN("fail to handle event complete", K(ret)); + } + break; + } + case ASYNC_PROCESS_INFORM_OUT_EVENT: { + pending_action_ = NULL; + if (OB_FAIL(cancel_timeout_action())) { + LOG_WARN("fail to cancel_timeout_action", K(ret)); + } else if (OB_FAIL(handle_event_inform_out())) { + LOG_WARN("fail to handle inform out event", K(ret)); + } + break; + } + case VC_EVENT_ACTIVE_TIMEOUT: + case EVENT_ERROR: + default: { + pending_action_ = NULL; + if (OB_FAIL(cancel_timeout_action())) { + LOG_WARN("fail to cancel_timeout_action", K(ret)); + } else if (action_.cancelled_) { + terminate_ = true; + LOG_INFO("async task has been cancelled, will kill itself", K(ret)); + } else if (NULL != cb_cont_) { + need_callback_ = true; + } else { + terminate_ = true; + } + + if (EVENT_ERROR != event || VC_EVENT_ACTIVE_TIMEOUT != event) { + LOG_WARN("error state, nerver run here", K(event), K(ret)); + } else { + LOG_INFO("error state", K(event)); + } + break; + } + } + + if (!terminate_ && (need_callback_ || OB_FAIL(ret))) { + if (execute_thread_ == &self_ethread()) { + execute_thread_->is_need_thread_pool_event_ = true; + } + if (OB_FAIL(handle_callback())) { + LOG_WARN("fail to handle callback", K(ret)); + } + } + + if (terminate_) { + if (execute_thread_ == &self_ethread()) { + execute_thread_->is_need_thread_pool_event_ = true; + } + destroy(); + } + + return EVENT_DONE; +} + +int ObProxyOperatorCont::init_task() +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(operator_root_->open(this, pending_action_, timeout_ms_))) { + LOG_WARN("fail to open operator", K_(timeout_ms), K(ret)); + } else if (OB_FAIL(operator_root_->get_next_row())) { + LOG_WARN("fail to get next row", K(ret)); + } else if (OB_ISNULL(pending_action_)) { + LOG_WARN("pending action should not be null", K(ret)); + } + + return ret; +} + +int ObProxyOperatorCont::finish_task(void *data) +{ + int ret = OB_SUCCESS; + + ObProxyResultResp *result_resp = reinterpret_cast(data); + if (result_resp->is_resultset_resp()) { + if (OB_FAIL(build_executor_resp(buf_, seq_, result_resp))) { + LOG_WARN("fail to build shard scan resp", K(ret)); + } + } else if (OB_FAIL(ObMysqlPacketUtil::encode_err_packet(*buf_, seq_, result_resp->get_err_code(), result_resp->get_err_msg()))) { + LOG_WARN("fail to encode err pacekt buf", K_(seq), "errmsg", result_resp->get_err_msg(), + "errcode", result_resp->get_err_code(), K(ret)); + } + + return ret; +} + +int ObProxyOperatorCont::schedule_timeout() +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(NULL != timeout_action_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("timeout action must be NULL", K_(timeout_action), K(ret)); + } else if (OB_ISNULL(timeout_action_ = execute_thread_->schedule_in(this, HRTIME_MSECONDS(timeout_ms_)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to schedule timeout", K_(timeout_action), K_(timeout_ms), K(ret)); + } + + return ret; +} + +int ObProxyOperatorCont::build_executor_resp(ObMIOBuffer *write_buf, uint8_t &seq, ObProxyResultResp *result_resp) +{ + int ret = OB_SUCCESS; + int64_t column_count = result_resp->get_column_count(); + ObSEArray *fields = NULL; + ObSEArray ob_fields; + + // header , cols , first eof + if (OB_SUCC(ret)) { + if (OB_FAIL(result_resp->get_fields(fields))) { + LOG_WARN("fail to push field", K(fields), K(ret)); + } else if (OB_ISNULL(fields)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fields should not be null", K(ret)); + } else if (OB_UNLIKELY(fields->count() != column_count)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fields count should equal column_count", K(column_count), "fileds count", fields->count(), K(ret)); + } else if (OB_FAIL(ObMysqlPacketUtil::encode_header(*write_buf, seq, *fields))) { + LOG_WARN("fail to encode header", K(fields), K(seq), K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < column_count; i++) { + obmysql::ObMySQLField &mysql_field = fields->at(i); + ObField ob_field; + if (OB_FAIL(ObSMUtils::to_ob_field(mysql_field, ob_field))) { + LOG_WARN("fail to covert to ob field", K(mysql_field), K(ret)); + } else if (OB_FAIL(ob_fields.push_back(ob_field))) { + LOG_WARN("fail to push ob field", K(ob_field), K(ret)); + } + } + } + } + + // rows + if (OB_SUCC(ret)) { + ObObj *objs = NULL; + int64_t buf_len = sizeof(ObObj) * column_count; + + if (OB_ISNULL(objs = static_cast(op_fixed_mem_alloc(buf_len)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to alloc obj array", K(column_count), K(ret)); + } else { + ObNewRow row; + //ObSEArray *row_array; + ObSEArray *row_array; + while ((OB_SUCC(ret)) && (OB_SUCC(result_resp->next(row_array)))) { + if (OB_ISNULL(row_array)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("row_array should not be null", K(ret)); + } else if (OB_UNLIKELY(row_array->count() != column_count)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("row_array count should equal column_count", K(column_count), "row_array count", row_array->count(), K(ret)); + } + + for (int64_t i = 0; OB_SUCC(ret) && i < column_count; i++) { + objs[i] = *(row_array->at(i)); + } + + if (OB_SUCC(ret)) { + row.cells_ = objs; + row.count_ = column_count; + if (OB_FAIL(ObMysqlPacketUtil::encode_row_packet(*write_buf, seq, row, &ob_fields))) { + LOG_WARN("fail to encode row", K(seq), K(row), K(ret)); + } else { + row.reset(); + row_array = NULL; + } + } + } + + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } + } + + if (OB_NOT_NULL(objs)) { + op_fixed_mem_free(objs, buf_len); + objs = NULL; + } + } + + // second eof + if (OB_SUCC(ret)) { + if (OB_FAIL(ObMysqlPacketUtil::encode_eof_packet(*write_buf, seq))) { + LOG_WARN("fail to encode row", K(seq), K(ret)); + } + } + + return ret; +} + +void ObProxyOperatorCont::destroy() +{ + LOG_DEBUG("ObProxyOperatorCont will be destroyed", KP(this)); + + if (OB_LIKELY(NULL != buf_reader_)) { + buf_reader_->dealloc(); + buf_reader_ = NULL; + } + + if (OB_LIKELY(NULL != buf_)) { + free_miobuffer(buf_); + buf_ = NULL; + } + + ObAsyncCommonTask::destroy(); +} + +} // end of namespace engine +} // end of namespace obproxy +} // end of namespace oceanbase diff --git a/src/obproxy/engine/ob_proxy_operator_cont.h b/src/obproxy/engine/ob_proxy_operator_cont.h new file mode 100644 index 000000000..632fc9196 --- /dev/null +++ b/src/obproxy/engine/ob_proxy_operator_cont.h @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#ifndef OBPROXY_OPERATOR_CONT_H +#define OBPROXY_OPERATOR_CONT_H + +#include "obutils/ob_async_common_task.h" +#include "ob_proxy_operator.h" + +namespace oceanbase +{ +namespace obproxy +{ +namespace engine +{ + +class ObProxyOperatorCont : public obutils::ObAsyncCommonTask +{ +public: + ObProxyOperatorCont(event::ObContinuation *cb_cont, event::ObEThread *submit_thread) + : ObAsyncCommonTask(cb_cont->mutex_, "operator cont", cb_cont, submit_thread), + seq_(0), timeout_ms_(0), operator_root_(NULL), execute_thread_(NULL), data_(NULL), + buf_(NULL), buf_reader_(NULL) + { + SET_HANDLER(&ObProxyOperatorCont::main_handler); + } + + ~ObProxyOperatorCont() {} + + int main_handler(int event, void *data); + int init(ObProxyOperator* operator_root, uint8_t seq, const int64_t timeout_ms = 0); + virtual int init_task(); + virtual int finish_task(void *data); + virtual void *get_callback_data() { return buf_reader_; } + virtual int schedule_timeout(); + virtual void destroy(); + +private: + int build_executor_resp(event::ObMIOBuffer *write_buf, uint8_t &seq, ObProxyResultResp *result_resp); + +private: + uint8_t seq_; + int64_t timeout_ms_; + ObProxyOperator* operator_root_; + event::ObEThread *execute_thread_; + void *data_; + event::ObMIOBuffer *buf_; + event::ObIOBufferReader *buf_reader_; + DISALLOW_COPY_AND_ASSIGN(ObProxyOperatorCont); +}; + +} // end of namespace engine +} // end of namespace obproxy +} // end of namespace oceanbase + +#endif // OBPROXY_OPERATOR_CONT_H diff --git a/src/obproxy/engine/ob_proxy_operator_result.h b/src/obproxy/engine/ob_proxy_operator_result.h index 575d7027b..05793b7dd 100644 --- a/src/obproxy/engine/ob_proxy_operator_result.h +++ b/src/obproxy/engine/ob_proxy_operator_result.h @@ -15,6 +15,7 @@ #include "common/ob_row.h" //#include "common/ob_field.h" #include "common/obsm_utils.h" +#include "common/ob_obj_cast.h" #include "rpc/obmysql/ob_mysql_field.h" #include "proxy/mysqllib/ob_resultset_fetcher.h" #include "lib/container/ob_se_array.h" @@ -123,6 +124,44 @@ int change_sql_field(const ObMysqlField *src_field, obmysql::ObMySQLField *&dst_ return ret; } +int change_sql_value(ObObj &value, obmysql::ObMySQLField &field, ObIAllocator *allocator) +{ + int ret = OB_SUCCESS; + + if (value.is_varchar()) { + ObObjType ob_type; + ObCollationType cs_type = static_cast(field.charsetnr_); + // utf8_general_ci => CS_TYPE_UTF8MB4_GENERAL_CI + if (33 == field.charsetnr_) { + cs_type = CS_TYPE_UTF8MB4_GENERAL_CI; + // utf8_bin => CS_TYPE_UTF8MB4_BIN + } else if (83 == field.charsetnr_) { + cs_type = CS_TYPE_UTF8MB4_BIN; + } + + value.set_collation_type(cs_type); + + if (0 != value.get_string_len()) { + // Convert the column to a specific type, if it cannot be converted, keep varchar + if (OB_FAIL(ObSMUtils::get_ob_type(ob_type, field.type_))) { + COMMON_LOG(INFO, "cast ob type from mysql type failed", K(ob_type), "elem_type", field.type_, K(ret)); + ret = OB_SUCCESS; + } else if (ObTimestampType == ob_type || ObTimeType == ob_type + || ObDateType == ob_type || ObDateTimeType == ob_type) { + //do nothing + } else { + ObCastCtx cast_ctx(allocator, NULL, CM_NULL_ON_WARN, cs_type); + // use src_obj as buf_obj + if (OB_FAIL(ObObjCasterV2::to_type(ob_type, cs_type, cast_ctx, value, value))) { + COMMON_LOG(WARN, "failed to cast obj", "row", value, K(ob_type), K(cs_type), K(ret)); + } + } + } + } + + return ret; +} + class ObProxyResultResp : public executor::ObProxyParallelResp { public: diff --git a/src/obproxy/engine/ob_proxy_operator_sort.cpp b/src/obproxy/engine/ob_proxy_operator_sort.cpp index 8f3122258..3ee286fda 100644 --- a/src/obproxy/engine/ob_proxy_operator_sort.cpp +++ b/src/obproxy/engine/ob_proxy_operator_sort.cpp @@ -405,7 +405,7 @@ int ObProxyMemMergeSortOp::handle_response_result(void *data, bool &is_final, Ob } else if (OB_ISNULL(sort_unit = new (tmp_buf) ObProxyMemMergeSortUnit(allocator_))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to new merge sort unit", K(ret)); - } else if (OB_FAIL(sort_unit->init(row, input->get_order_exprs()))) { + } else if (OB_FAIL(sort_unit->init(row, result_fields_, input->get_order_exprs()))) { LOG_WARN("fail to init sort unit", K(ret)); } else if (OB_FAIL(sort_units_.push_back(sort_unit))) { LOG_WARN("fail to push back sort unit", K(ret)); @@ -460,7 +460,7 @@ int ObProxyMemMergeSortOp::handle_response_result(void *data, bool &is_final, Ob return ret; } -int ObProxyMemMergeSortUnit::init(ResultRow *row, ObIArray &order_exprs) +int ObProxyMemMergeSortUnit::init(ResultRow *row, ResultFields *result_fields, ObIArray &order_exprs) { int ret = OB_SUCCESS; @@ -468,6 +468,7 @@ int ObProxyMemMergeSortUnit::init(ResultRow *row, ObIArray &o LOG_WARN("fail to assign order exprs", K(ret)); } else { row_ = row; + result_fields_ = result_fields; if (OB_FAIL(calc_order_values())) { LOG_WARN("fail to get order value", K(ret)); } @@ -487,6 +488,15 @@ int ObProxyMemMergeSortUnit::calc_order_values() for (int64_t i = 0; OB_SUCC(ret) && i < order_exprs_.count(); i++) { if (OB_FAIL(order_exprs_.at(i)->calc(ctx, calc_item, order_values_))) { LOG_WARN("fail to calc order exprs", K(ret)); + } else { + int64_t index = order_exprs_.at(i)->get_expr()->get_index(); + if (-1 != index) { + ObObj &value = order_values_.at(i); + if (OB_FAIL(change_sql_value(value, result_fields_->at(index), &allocator_))) { + LOG_WARN("fail to change sql value", K(value), + "filed", result_fields_->at(index), K(ret)); + } + } } } @@ -566,7 +576,7 @@ int ObProxyStreamSortOp::handle_response_result(void *data, bool &is_final, ObPr } else if (OB_ISNULL(sort_unit = new (tmp_buf) ObProxyStreamSortUnit(allocator_))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to new merge sort unit", K(ret)); - } else if (OB_FAIL(sort_unit->init(opres, input->get_order_exprs()))) { + } else if (OB_FAIL(sort_unit->init(opres, result_fields_, input->get_order_exprs()))) { LOG_WARN("fail to init sort unit", K(ret)); } else if (OB_FAIL(sort_units_.push_back(sort_unit))) { LOG_WARN("fail to push back sort unit", K(ret)); @@ -638,7 +648,8 @@ int ObProxyStreamSortOp::handle_response_result(void *data, bool &is_final, ObPr return ret; } -int ObProxyStreamSortUnit::init(ObProxyResultResp* result_set, common::ObIArray &order_exprs) +int ObProxyStreamSortUnit::init(ObProxyResultResp* result_set, ResultFields *result_fields, + common::ObIArray &order_exprs) { int ret = OB_SUCCESS; if (OB_FAIL(order_exprs_.assign((order_exprs)))) { @@ -646,6 +657,9 @@ int ObProxyStreamSortUnit::init(ObProxyResultResp* result_set, common::ObIArray< } else if (OB_ISNULL(result_set_ = result_set)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("result set should not NULL", K(ret)); + } else if (OB_ISNULL(result_fields_ = result_fields)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("result fields should not NULL", K(ret)); } else if (OB_FAIL(next())) { // The first time, there must be a result, so it must not be OB_ITER_END LOG_WARN("fail to exec next", K(ret)); diff --git a/src/obproxy/engine/ob_proxy_operator_sort.h b/src/obproxy/engine/ob_proxy_operator_sort.h index 033c73d4e..a59c55c30 100644 --- a/src/obproxy/engine/ob_proxy_operator_sort.h +++ b/src/obproxy/engine/ob_proxy_operator_sort.h @@ -142,12 +142,13 @@ class ObProxyMemMergeSortUnit { public: ObProxyMemMergeSortUnit(common::ObIAllocator &allocator) - : allocator_(allocator), row_(NULL), + : allocator_(allocator), row_(NULL), result_fields_(NULL), order_values_(ObModIds::OB_SE_ARRAY_ENGINE, ENGINE_ARRAY_NEW_ALLOC_SIZE), order_exprs_(ObModIds::OB_SE_ARRAY_ENGINE, ENGINE_ARRAY_NEW_ALLOC_SIZE) {} ~ObProxyMemMergeSortUnit() {} - int init(ResultRow *row, common::ObIArray &order_exprs); + int init(ResultRow *row, ResultFields *result_fields, + common::ObIArray &order_exprs); virtual bool compare(const ObProxyMemMergeSortUnit* sort_unit) const; int calc_order_values(); @@ -159,6 +160,7 @@ class ObProxyMemMergeSortUnit protected: common::ObIAllocator &allocator_; ResultRow *row_; + ResultFields *result_fields_; common::ObSEArray order_values_; common::ObSEArray order_exprs_; }; @@ -188,7 +190,8 @@ class ObProxyStreamSortUnit : public ObProxyMemMergeSortUnit : ObProxyMemMergeSortUnit(allocator), result_set_(NULL) {} ~ObProxyStreamSortUnit() {} - int init(ObProxyResultResp* result_set, common::ObIArray &order_exprs); + int init(ObProxyResultResp* result_set, ResultFields *result_fields, + common::ObIArray &order_exprs); virtual bool compare(const ObProxyStreamSortUnit* sort_unit) const; int next(); diff --git a/src/obproxy/engine/ob_proxy_operator_table_scan.cpp b/src/obproxy/engine/ob_proxy_operator_table_scan.cpp index eb6fd78f0..ddd8de528 100644 --- a/src/obproxy/engine/ob_proxy_operator_table_scan.cpp +++ b/src/obproxy/engine/ob_proxy_operator_table_scan.cpp @@ -20,6 +20,7 @@ #include "executor/ob_proxy_parallel_cont.h" #include "executor/ob_proxy_parallel_execute_cont.h" #include "proxy/shard/obproxy_shard_utils.h" +#include "proxy/mysqllib/ob_proxy_mysql_request.h" using namespace oceanbase::obproxy::executor; using namespace oceanbase::common; @@ -28,6 +29,15 @@ namespace oceanbase { namespace obproxy { namespace engine { +ObProxyTableScanOp::~ObProxyTableScanOp() +{ + for (int64_t i = 0; i < pres_array_.count(); i++) { + executor::ObProxyParallelResp *pres = pres_array_.at(i); + op_free(pres); + pres = NULL; + } +} + int ObProxyTableScanOp::open(event::ObContinuation *cont, event::ObAction *&action, const int64_t timeout_ms) { child_cnt_ = 1; //fake child @@ -77,7 +87,8 @@ int ObProxyTableScanOp::get_next_row() "phy table count", table_name_maps.count(), "shard prop count", shard_props.count(), "dbkey count", db_key_names.count(), K(ret)); - } else if (OB_FAIL(sql_parser.parse_sql_by_obparser(request_sql, NORMAL_PARSE_MODE, parse_result, true))) { + } else if (OB_FAIL(sql_parser.parse_sql_by_obparser(proxy::ObProxyMysqlRequest::get_parse_sql(request_sql), + NORMAL_PARSE_MODE, parse_result, true))) { LOG_WARN("parse_sql_by_obparser failed", K(request_sql), K(ret)); } @@ -88,10 +99,9 @@ int ObProxyTableScanOp::get_next_row() ObSqlString new_sql; char *tmp_buf = NULL; bool is_oracle_mode = db_key_name->server_type_ == common::DB_OB_ORACLE; - if (OB_FAIL(proxy::ObProxyShardUtils::do_rewrite_shard_select_request(request_sql, parse_result, is_oracle_mode, - table_name_map_warraper.get_hash_map(), - db_key_name->database_name_, false, - new_sql))) { + if (OB_FAIL(proxy::ObProxyShardUtils::rewrite_shard_dml_request(request_sql, new_sql, parse_result, + is_oracle_mode, table_name_map_warraper.get_hash_map(), + db_key_name->database_name_, false))) { LOG_WARN("fail to rewrite shard request", K(request_sql), K(is_oracle_mode), K(ret)); } else if (OB_ISNULL(tmp_buf = (char *)allocator_.alloc(new_sql.length()))) { ret = common::OB_ALLOCATE_MEMORY_FAILED; @@ -135,6 +145,8 @@ int ObProxyTableScanOp::handle_result(void *data, bool &is_final, ObProxyResultR } else if (OB_ISNULL(pres = reinterpret_cast(data))) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid input, pres type is not match", K(ret)); + } else if (OB_FAIL(pres_array_.push_back(pres))) { + LOG_WARN("fail to push result resp to array", K(ret)); } else { if (pres->is_ok_resp()) { // it is the OK packet // For the OK package, it is only necessary to construct an OK package in the case of @@ -156,10 +168,6 @@ int ObProxyTableScanOp::handle_result(void *data, bool &is_final, ObProxyResultR } LOG_DEBUG("handle_result success", K(ret), K(pres)); } - if (OB_NOT_NULL(pres)) { - op_free(pres); - pres = NULL; - } return ret; } diff --git a/src/obproxy/engine/ob_proxy_operator_table_scan.h b/src/obproxy/engine/ob_proxy_operator_table_scan.h index 1c14c9267..1571070df 100644 --- a/src/obproxy/engine/ob_proxy_operator_table_scan.h +++ b/src/obproxy/engine/ob_proxy_operator_table_scan.h @@ -32,7 +32,7 @@ class ObProxyTableScanOp : public ObProxyOperator set_op_type(PHY_TABLE_SCAN); } - virtual ~ObProxyTableScanOp() {}; + virtual ~ObProxyTableScanOp(); virtual int open(event::ObContinuation *cont, event::ObAction *&action, const int64_t timeout_ms = 0); virtual int get_next_row(); @@ -53,6 +53,7 @@ class ObProxyTableScanOp : public ObProxyOperator protected: int64_t sub_sql_count_; + common::ObSEArray pres_array_; }; class ObProxyTableScanInput : public ObProxyOpInput diff --git a/src/obproxy/executor/ob_proxy_parallel_execute_cont.cpp b/src/obproxy/executor/ob_proxy_parallel_execute_cont.cpp index 51994759c..92884bfc8 100644 --- a/src/obproxy/executor/ob_proxy_parallel_execute_cont.cpp +++ b/src/obproxy/executor/ob_proxy_parallel_execute_cont.cpp @@ -27,6 +27,16 @@ namespace obproxy namespace executor { +int64_t ObProxyParallelResp::to_string(char *buf, int64_t buf_len) const +{ + int64_t pos = 0; + J_OBJ_START(); + J_KV(K_(column_count), K_(cont_index), + KP_(resp), KP_(rs_fetcher)); + J_OBJ_END(); + return pos; +} + ObProxyParallelResp::~ObProxyParallelResp() { if (OB_NOT_NULL(resp_)) { @@ -66,7 +76,6 @@ int ObProxyParallelResp::next(ObObj *&rows) { int ret = OB_SUCCESS; - ObMysqlField *fields = rs_fetcher_->get_field(); int64_t buf_len = (sizeof(ObObj) * column_count_); char *buf = NULL; @@ -79,50 +88,9 @@ int ObProxyParallelResp::next(ObObj *&rows) LOG_WARN("fail to alloc mem", K(buf_len), K(ret)); } else { rows = new (buf) ObObj[column_count_]; - ObObjType ob_type; for (int64_t i = 0; OB_SUCC(ret) && i < column_count_; i++) { if (OB_FAIL(rs_fetcher_->get_obj(i, rows[i]))) { LOG_WARN("fail to get varchar", K(i), K(ret)); - } else if (rows[i].need_deep_copy()) { - int64_t copy_size = rows[i].get_deep_copy_size(); - int64_t pos = 0; - buf = NULL; - if (OB_ISNULL(buf = static_cast(allocator_->alloc(copy_size)))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("fail to alloc mem", K(copy_size), K(ret)); - } else if (OB_FAIL(rows[i].deep_copy(rows[i], buf, copy_size, pos))) { - LOG_WARN("fail to deep coy", "obj", rows[i], K(copy_size), K(ret)); - } - } - - if (OB_SUCC(ret) && rows[i].is_varchar()) { - ObCollationType cs_type = static_cast(fields[i].charsetnr_); - // utf8_general_ci => CS_TYPE_UTF8MB4_GENERAL_CI - if (33 == fields[i].charsetnr_) { - cs_type = CS_TYPE_UTF8MB4_GENERAL_CI; - // utf8_bin => CS_TYPE_UTF8MB4_BIN - } else if (83 == fields[i].charsetnr_) { - cs_type = CS_TYPE_UTF8MB4_BIN; - } - - rows[i].set_collation_type(cs_type); - - if (0 != rows[i].get_string_len()) { - // if can not convert, stay varchar type - if (OB_FAIL(ObSMUtils::get_ob_type(ob_type, fields[i].type_))) { - LOG_INFO("cast ob type from mysql type failed", K(ob_type), "elem_type", fields[i].type_, K(ret)); - ret = OB_SUCCESS; - } else if (ObTimestampType == ob_type || ObTimeType == ob_type - || ObDateType == ob_type || ObDateTimeType == ob_type) { - //do nothing - } else { - ObCastCtx cast_ctx(allocator_, NULL, CM_NULL_ON_WARN, cs_type); - // use src_obj as buf_obj - if (OB_FAIL(ObObjCasterV2::to_type(ob_type, cs_type, cast_ctx, rows[i], rows[i]))) { - COMMON_LOG(WARN, "failed to cast obj", "idx", i, "row", rows[i], K(ob_type), K(cs_type), K(ret)); - } - } - } } } } @@ -201,6 +169,8 @@ int ObProxyParallelExecuteCont::init_task() int ret = OB_SUCCESS; ObMysqlRequestParam request_param; + request_param.ob_client_flags_.client_flags_.OB_CLIENT_SKIP_AUTOCOMMIT = 1; + request_param.ob_client_flags_.client_flags_.OB_CLIENT_SEND_REQUEST_DIRECT = 1; request_param.sql_ = request_sql_; if (OB_FAIL(mysql_proxy_->async_read(this, request_param, pending_action_))) { LOG_WARN("fail to async read", K_(request_sql), K(ret)); diff --git a/src/obproxy/executor/ob_proxy_parallel_execute_cont.h b/src/obproxy/executor/ob_proxy_parallel_execute_cont.h index 98cb30db9..ac0ff672f 100644 --- a/src/obproxy/executor/ob_proxy_parallel_execute_cont.h +++ b/src/obproxy/executor/ob_proxy_parallel_execute_cont.h @@ -44,6 +44,7 @@ class ObProxyParallelResp ObMysqlField *get_field() const { return rs_fetcher_->get_field(); } int64_t get_column_count() { return column_count_; } int64_t get_cont_index() { return cont_index_; } + int64_t to_string(char *buf, int64_t buf_len) const; private: proxy::ObClientMysqlResp *resp_; diff --git a/src/obproxy/iocore/eventsystem/Makemodule.am b/src/obproxy/iocore/eventsystem/Makemodule.am index be1358679..bc8951c93 100644 --- a/src/obproxy/iocore/eventsystem/Makemodule.am +++ b/src/obproxy/iocore/eventsystem/Makemodule.am @@ -19,6 +19,8 @@ obproxy/iocore/eventsystem/ob_priority_event_queue.h\ obproxy/iocore/eventsystem/ob_processor.h\ obproxy/iocore/eventsystem/ob_protected_queue.h\ obproxy/iocore/eventsystem/ob_protected_queue.cpp\ +obproxy/iocore/eventsystem/ob_protected_queue_thread_pool.cpp\ +obproxy/iocore/eventsystem/ob_protected_queue_thread_pool.h\ obproxy/iocore/eventsystem/ob_thread.h\ obproxy/iocore/eventsystem/ob_thread.cpp\ obproxy/iocore/eventsystem/ob_vconnection.h\ @@ -32,4 +34,6 @@ obproxy/iocore/eventsystem/ob_grpc_task.h\ obproxy/iocore/eventsystem/ob_grpc_task.cpp\ obproxy/iocore/eventsystem/ob_shard_watch_task.h\ obproxy/iocore/eventsystem/ob_shard_watch_task.cpp\ +obproxy/iocore/eventsystem/ob_shard_scan_all_task.h\ +obproxy/iocore/eventsystem/ob_shard_scan_all_task.cpp\ obproxy/iocore/eventsystem/ob_thread_impl.h diff --git a/src/obproxy/iocore/eventsystem/ob_ethread.cpp b/src/obproxy/iocore/eventsystem/ob_ethread.cpp index 24470fefa..6ce48ff4c 100644 --- a/src/obproxy/iocore/eventsystem/ob_ethread.cpp +++ b/src/obproxy/iocore/eventsystem/ob_ethread.cpp @@ -67,6 +67,8 @@ ObEThread::ObEThread() ps_entry_cache_(NULL), text_ps_entry_cache_(NULL), random_seed_(NULL), + is_need_thread_pool_event_(false), + thread_pool_event_queue_(NULL), warn_log_buf_(NULL), warn_log_buf_start_(NULL), tt_(REGULAR), @@ -105,6 +107,8 @@ ObEThread::ObEThread(const ObThreadType att, const int64_t anid) ps_entry_cache_(NULL), text_ps_entry_cache_(NULL), random_seed_(NULL), + is_need_thread_pool_event_(false), + thread_pool_event_queue_(NULL), warn_log_buf_(NULL), warn_log_buf_start_(NULL), tt_(att), @@ -143,6 +147,8 @@ ObEThread::ObEThread(const ObThreadType att, ObEvent *e) ps_entry_cache_(NULL), text_ps_entry_cache_(NULL), random_seed_(NULL), + is_need_thread_pool_event_(false), + thread_pool_event_queue_(NULL), warn_log_buf_(NULL), warn_log_buf_start_(NULL), tt_(att), @@ -275,6 +281,9 @@ inline void ObEThread::process_event(ObEvent *e, const int calling_code) event_queue_external_.enqueue_local(e); } else { if (e->cancelled_) { + if (e->is_thread_pool_event_) { + is_need_thread_pool_event_ = true; + } free_event(*e); } else { const ObContinuation *c_temp = e->continuation_; @@ -444,7 +453,16 @@ void ObEThread::execute() if (ethreads_to_be_signalled_count_ > 0) { flush_signals(this); } - if (OB_UNLIKELY(OB_SUCCESS != event_queue_external_.dequeue_timed(next_time, true))) { + + if (is_need_thread_pool_event_ && NULL != thread_pool_event_queue_) { + if (OB_UNLIKELY(OB_SUCCESS != thread_pool_event_queue_->dequeue_timed(next_time, e))) { + LOG_WARN("fail to dequeue time in event_queue_external_"); + } else if (NULL != e) { + is_need_thread_pool_event_ = false; + e->ethread_ = this; + process_event(e, e->callback_event_); + } + } else if (OB_UNLIKELY(OB_SUCCESS != event_queue_external_.dequeue_timed(next_time, true))) { LOG_WARN("fail to dequeue time in event_queue_external_"); } } diff --git a/src/obproxy/iocore/eventsystem/ob_ethread.h b/src/obproxy/iocore/eventsystem/ob_ethread.h index f7b361012..ae78a1261 100644 --- a/src/obproxy/iocore/eventsystem/ob_ethread.h +++ b/src/obproxy/iocore/eventsystem/ob_ethread.h @@ -34,6 +34,7 @@ #include "iocore/eventsystem/ob_thread.h" #include "iocore/eventsystem/ob_priority_event_queue.h" #include "iocore/eventsystem/ob_protected_queue.h" +#include "iocore/eventsystem/ob_protected_queue_thread_pool.h" #include "lib/container/ob_vector.h" namespace oceanbase @@ -56,7 +57,7 @@ class ObPartitionRefHashMap; class ObRoutineRefHashMap; class ObSqlTableRefHashMap; class ObCacheCleaner; -class ObBasePsEntryCache; +class ObBasePsEntryThreadCache; } namespace net { @@ -324,8 +325,8 @@ class ObEThread : public ObThread proxy::ObSqlTableRefHashMap &get_sql_table_map() { return *sql_table_map_; } proxy::ObPartitionRefHashMap &get_partition_map() { return *partition_map_; } proxy::ObRoutineRefHashMap &get_routine_map() { return *routine_map_; } - proxy::ObBasePsEntryCache &get_ps_entry_cache() { return *ps_entry_cache_; } - proxy::ObBasePsEntryCache &get_text_ps_entry_cache() { return *text_ps_entry_cache_; } + proxy::ObBasePsEntryThreadCache &get_ps_entry_cache() { return *ps_entry_cache_; } + proxy::ObBasePsEntryThreadCache &get_text_ps_entry_cache() { return *text_ps_entry_cache_; } obutils::ObCongestionRefHashMap &get_cgt_map() { return *congestion_map_; } common::ObMysqlRandom &get_random_seed() { return *random_seed_; } @@ -380,10 +381,13 @@ class ObEThread : public ObThread obutils::ObCongestionRefHashMap *congestion_map_; proxy::ObCacheCleaner *cache_cleaner_; proxy::ObSqlTableRefHashMap *sql_table_map_; - proxy::ObBasePsEntryCache *ps_entry_cache_; - proxy::ObBasePsEntryCache *text_ps_entry_cache_; + proxy::ObBasePsEntryThreadCache *ps_entry_cache_; + proxy::ObBasePsEntryThreadCache *text_ps_entry_cache_; common::ObMysqlRandom *random_seed_; + bool is_need_thread_pool_event_; + ObProtectedQueueThreadPool *thread_pool_event_queue_; + char *warn_log_buf_; char *warn_log_buf_start_; diff --git a/src/obproxy/iocore/eventsystem/ob_event.h b/src/obproxy/iocore/eventsystem/ob_event.h index b08d0ddcb..ecfa64ac0 100644 --- a/src/obproxy/iocore/eventsystem/ob_event.h +++ b/src/obproxy/iocore/eventsystem/ob_event.h @@ -208,6 +208,7 @@ class ObEvent : public ObAction uint32_t in_the_prot_queue_:1; uint32_t in_the_priority_queue_:1; uint32_t in_heap_:4; + uint32_t is_thread_pool_event_; int32_t callback_event_; ObHRTime timeout_at_; @@ -235,6 +236,7 @@ inline ObEvent::ObEvent() in_the_prot_queue_(false), in_the_priority_queue_(false), in_heap_(0), + is_thread_pool_event_(false), callback_event_(EVENT_NONE), timeout_at_(0), period_(0), diff --git a/src/obproxy/iocore/eventsystem/ob_event_processor.cpp b/src/obproxy/iocore/eventsystem/ob_event_processor.cpp index 200d38274..c7587f195 100644 --- a/src/obproxy/iocore/eventsystem/ob_event_processor.cpp +++ b/src/obproxy/iocore/eventsystem/ob_event_processor.cpp @@ -34,6 +34,7 @@ #include "iocore/eventsystem/ob_event_system.h" #include #include "utils/ob_cpu_affinity.h" +#include "ob_proxy_init.h" using namespace oceanbase::common; @@ -45,6 +46,18 @@ namespace event { class ObEventProcessor g_event_processor; +int ObEventProcessor::init_thread(ObEThread *&t) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(t->init())) { + LOG_WARN("fail to init event", K(ret)); + delete t; + t = NULL; + } + + return ret; +} + int ObEventProcessor::spawn_event_threads( const int64_t thread_count, const char *et_name, const int64_t stacksize, ObEventThreadType &etype) @@ -76,10 +89,8 @@ int ObEventProcessor::spawn_event_threads( if (OB_ISNULL(t = new(std::nothrow) ObEThread(REGULAR, MAX_THREADS_IN_EACH_TYPE + event_thread_count_ - net_thread_count + i))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_ERROR("fail to allocator memory for REGULAR ObEThread", K(i), K(thread_count), K(ret)); - } else if (OB_FAIL(t->init())) { - LOG_WARN("fail to init event", K(i), K(ret)); - delete t; - t = NULL; + } else if (OB_FAIL(init_thread(t))) { + LOG_WARN("fail to init thread", K(i), K(ret)); } else { all_event_threads_[event_thread_count_ + i] = t; event_thread_[new_thread_group_id][i] = t; @@ -134,10 +145,8 @@ int ObEventProcessor::spawn_net_threads(const int64_t thread_count, if (OB_ISNULL(t = new(std::nothrow) ObEThread(REGULAR, net_thread_count + i))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_ERROR("fail to allocate memory for REGULAR ObEThread", K(i), K(thread_count), K(ret)); - } else if (OB_FAIL(t->init())) { - LOG_WARN("fail to init event", K(i), K(ret)); - delete t; - t = NULL; + } else if (OB_FAIL(init_thread(t))) { + LOG_WARN("fail to init thread", K(i), K(ret)); } else { all_event_threads_[event_thread_count_ + i] = t; event_thread_[ET_CALL][net_thread_count + i] = t; @@ -182,6 +191,7 @@ inline int ObEventProcessor::init_one_event_thread(const int64_t index) delete t; t = NULL; } else { + // It should be noted here that the thread with index 0 in rich client mode will be created if (0 == index) { this_thread() = t; global_mutex = t->mutex_; @@ -235,7 +245,6 @@ int ObEventProcessor::start(const int64_t net_thread_count, const int64_t stacks ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid parameters", K(stacksize), K(ret)); } else { - if (!automatic_match_work_thread || OB_UNLIKELY((cpu_num = get_cpu_count()) <= 0) || cpu_num > net_thread_count) { @@ -297,7 +306,7 @@ int ObEventProcessor::start(const int64_t net_thread_count, const int64_t stacks if (OB_UNLIKELY(length <= 0) || OB_UNLIKELY(length >= static_cast(sizeof(thr_name)))) { ret = OB_SIZE_OVERFLOW; LOG_WARN("fail format thread name", K(length), K(ret)); - } else if ((0 != i) && OB_FAIL(all_event_threads_[i]->start(thr_name, stacksize))) { + } else if ((0 != i || RUN_MODE_CLIENT == g_run_mode) && OB_FAIL(all_event_threads_[i]->start(thr_name, stacksize))) { LOG_WARN("fail to start event thread", K(thr_name), K(ret)); } else { if (bind_cpu) { diff --git a/src/obproxy/iocore/eventsystem/ob_event_processor.h b/src/obproxy/iocore/eventsystem/ob_event_processor.h index df6391d93..cfe8da2a9 100644 --- a/src/obproxy/iocore/eventsystem/ob_event_processor.h +++ b/src/obproxy/iocore/eventsystem/ob_event_processor.h @@ -155,6 +155,8 @@ class ObEventProcessor : public ObProcessor int spawn_net_threads(const int64_t thread_count, const char *et_name, const int64_t stacksize); + virtual int init_thread(ObEThread *&t); + /** * Schedules the continuation on a specific ObEThread to receive an event * at the given timeout. Requests the ObEventProcessor to schedule @@ -303,7 +305,7 @@ class ObEventProcessor : public ObProcessor */ int64_t allocate(const int64_t size); - ObEvent *schedule(ObEvent *e, const ObEventThreadType etype, const bool fast_signal = false); + virtual ObEvent *schedule(ObEvent *e, const ObEventThreadType etype, const bool fast_signal = false); ObEThread *assign_thread(const ObEventThreadType etype); @@ -417,7 +419,7 @@ inline ObEThread *ObEventProcessor::assign_thread(const ObEventThreadType etype) return (event_thread_[etype][next]); } -inline ObEvent *ObEventProcessor::schedule( +ObEvent *ObEventProcessor::schedule( ObEvent *event, const ObEventThreadType etype, const bool fast_signal) { event->ethread_ = assign_thread(etype); diff --git a/src/obproxy/iocore/eventsystem/ob_protected_queue_thread_pool.cpp b/src/obproxy/iocore/eventsystem/ob_protected_queue_thread_pool.cpp new file mode 100644 index 000000000..8a6a64208 --- /dev/null +++ b/src/obproxy/iocore/eventsystem/ob_protected_queue_thread_pool.cpp @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#define USING_LOG_PREFIX PROXY_EVENT + +#include "iocore/eventsystem/ob_event_system.h" +#include "iocore/net/ob_unix_net.h" + +using namespace oceanbase::common; + +namespace oceanbase +{ +namespace obproxy +{ +namespace event +{ + +void ObProtectedQueueThreadPool::enqueue(ObEvent *e) +{ + if (OB_ISNULL(e)) { + LOG_WARN("event NULL, it should not happened"); + } else if (OB_UNLIKELY(e->in_the_prot_queue_) || OB_UNLIKELY(e->in_the_priority_queue_)) { + LOG_WARN("event has already in queue, it should not happened", K(*e)); + } else { + int ret = OB_SUCCESS; + e->in_the_prot_queue_ = 1; + atomic_list_.push(e); + + if (OB_FAIL(signal())) { + LOG_WARN("fail to do signal, it should not happened", K(ret)); + } + } +} + +int ObProtectedQueueThreadPool::dequeue_timed(const ObHRTime timeout, ObEvent *&event) +{ + int ret = OB_SUCCESS; + + if (NULL != (event= (ObEvent *)(atomic_list_.pop()))) { + event->in_the_prot_queue_ = 0; + } else { + if (OB_FAIL(mutex_acquire(&lock_))) { + LOG_ERROR("fail to acquire mutex", K(ret)); + } else { + if (atomic_list_.empty()) { + timespec ts = hrtime_to_timespec(timeout); + cond_timedwait(&might_have_data_, &lock_, &ts); + } + + if (NULL != (event= (ObEvent *)(atomic_list_.pop()))) { + event->in_the_prot_queue_ = 0; + } + + int tmp_ret = OB_SUCCESS; + if (OB_UNLIKELY(OB_SUCCESS != (tmp_ret = mutex_release(&lock_)))) { + LOG_ERROR("fail to release mutex", K(tmp_ret)); + } + } + } + + return ret; +} + +} // end of namespace event +} // end of namespace obproxy +} // end of namespace oceanbase diff --git a/src/obproxy/iocore/eventsystem/ob_protected_queue_thread_pool.h b/src/obproxy/iocore/eventsystem/ob_protected_queue_thread_pool.h new file mode 100644 index 000000000..668caa6e0 --- /dev/null +++ b/src/obproxy/iocore/eventsystem/ob_protected_queue_thread_pool.h @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#ifndef OBPROXY_PROTECTED_QUEUE_THREAD_POOL_H +#define OBPROXY_PROTECTED_QUEUE_THREAD_POOL_H + +#include "iocore/eventsystem/ob_event.h" + +namespace oceanbase +{ +namespace obproxy +{ +namespace event +{ + +class ObProtectedQueueThreadPool +{ +public: + ObProtectedQueueThreadPool() : is_inited_(false) {} + ~ObProtectedQueueThreadPool() { } + + int init(); + void enqueue(ObEvent *e); + int dequeue_timed(const ObHRTime timeout, ObEvent *&event); + int signal(); + +public: + bool is_inited_; + common::ObAtomicList atomic_list_; + ObMutex lock_; + ObProxyThreadCond might_have_data_; + +private: + DISALLOW_COPY_AND_ASSIGN(ObProtectedQueueThreadPool); +}; + +inline int ObProtectedQueueThreadPool::init() +{ + int ret = common::OB_SUCCESS; + ObEvent e; + if (OB_FAIL(common::mutex_init(&lock_))) { + PROXY_EVENT_LOG(WARN, "fail to init mutex", K(ret)); + } else if (OB_FAIL(atomic_list_.init("ObProtectedQueueThreadPool", + reinterpret_cast(&e.link_.next_) - reinterpret_cast(&e)))) { + PROXY_EVENT_LOG(WARN, "fail to init atomic_list_", K(ret)); + } else if (OB_FAIL(cond_init(&might_have_data_))) { + PROXY_EVENT_LOG(WARN, "fail to init ObProxyThreadCond", K(ret)); + } else { + is_inited_ = 0; + } + return ret; +} + +inline int ObProtectedQueueThreadPool::signal() +{ + int ret = common::OB_SUCCESS; + // Need to get the lock before you can signal the thread + if (OB_FAIL(common::mutex_acquire(&lock_))) { + PROXY_EVENT_LOG(ERROR, "fail to acquire lock", K(ret)); + } else { + if (OB_FAIL(cond_signal(&might_have_data_))) { + PROXY_EVENT_LOG(WARN, "fail to call cond_signal", K(ret)); + } + + int tmp_ret = common::OB_SUCCESS; + if (OB_UNLIKELY(common::OB_SUCCESS != ( tmp_ret = common::mutex_release(&lock_)))) { + PROXY_EVENT_LOG(WARN, "fail to release mutex", K(tmp_ret)); + } + } + return ret; +} + +} // end of namespace event +} // end of namespace obproxy +} // end of namespace oceanbase + +#endif // OBPROXY_PROTECTED_QUEUE_THREAD_POOL_H diff --git a/src/obproxy/iocore/eventsystem/ob_shard_scan_all_task.cpp b/src/obproxy/iocore/eventsystem/ob_shard_scan_all_task.cpp new file mode 100644 index 000000000..b1abca64c --- /dev/null +++ b/src/obproxy/iocore/eventsystem/ob_shard_scan_all_task.cpp @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#define USING_LOG_PREFIX PROXY_EVENT + +#include "iocore/eventsystem/ob_shard_scan_all_task.h" +#include "iocore/eventsystem/ob_event_system.h" + +using namespace oceanbase::common; + +namespace oceanbase +{ +namespace obproxy +{ +namespace event +{ +ObEventThreadType ET_SHARD_SCAN_ALL = ET_CALL; +ObShardScanAllTaskProcessor g_shard_scan_all_task_processor; + +// Note that if the number of task_threads is 0, all continuations scheduled for +// ET_SHARD_SCAN_ALL ends up running on ET_CALL (which is the net-threads). +int ObShardScanAllTaskProcessor::start(const int64_t shard_scan_all_threads, const int64_t stacksize) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(thread_pool_event_queue_ = new (std::nothrow) ObProtectedQueueThreadPool())) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to new ObProtectedQueueThreadPool", K(ret)); + } else if (OB_FAIL(thread_pool_event_queue_->init())) { + LOG_WARN("fail to init thread_pool_event_queue", K(ret)); + } else if (OB_FAIL(spawn_event_threads(shard_scan_all_threads, "ET_SHARD_SCAN_ALL", stacksize, ET_SHARD_SCAN_ALL))) { + LOG_WARN("fail to spawn event threads for ET_SHARD_SCAN_ALL", K(ret)); + } + + return ret; +} + +int ObShardScanAllTaskProcessor::init_thread(ObEThread *&t) +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(t->init())) { + LOG_WARN("fail to init event", K(ret)); + delete t; + t = NULL; + } else { + t->thread_pool_event_queue_ = thread_pool_event_queue_; + t->is_need_thread_pool_event_ = true; + } + + return ret; +} + +ObEvent *ObShardScanAllTaskProcessor::schedule(ObEvent *event, const ObEventThreadType etype, const bool fast_signal) +{ + UNUSED(fast_signal); + UNUSED(etype); + + if (NULL != event->continuation_->mutex_) { + event->mutex_ = event->continuation_->mutex_; + } else { + event->continuation_->mutex_ = event->ethread_->mutex_; + event->mutex_ = event->continuation_->mutex_; + } + event->is_thread_pool_event_ = true; + thread_pool_event_queue_->enqueue(event); + return event; +} + +} // end of namespace event +} // end of namespace obproxy +} // end of namespace oceanbase diff --git a/src/obproxy/iocore/eventsystem/ob_shard_scan_all_task.h b/src/obproxy/iocore/eventsystem/ob_shard_scan_all_task.h new file mode 100644 index 000000000..b2ef2590a --- /dev/null +++ b/src/obproxy/iocore/eventsystem/ob_shard_scan_all_task.h @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#ifndef OBPROXY_SHARD_SCAN_ALL_TASK_H +#define OBPROXY_SHARD_SCAN_ALL_TASK_H + +#include "iocore/eventsystem/ob_event_processor.h" +#include "iocore/eventsystem/ob_event.h" +#include "iocore/eventsystem/ob_protected_queue_thread_pool.h" + +namespace oceanbase +{ +namespace obproxy +{ +namespace event +{ +extern ObEventThreadType ET_SHARD_SCAN_ALL; + +class ObShardScanAllTaskProcessor : public ObEventProcessor +{ +public: + ObShardScanAllTaskProcessor() : ObEventProcessor(), thread_pool_event_queue_(NULL) {} + virtual ~ObShardScanAllTaskProcessor() {} + int start(const int64_t shard_scan_all_threads, const int64_t stacksize = DEFAULT_STACKSIZE); + + virtual int init_thread(ObEThread *&t); + virtual ObEvent *schedule(ObEvent *event, const ObEventThreadType etype, const bool fast_signal); + +private: + ObProtectedQueueThreadPool *thread_pool_event_queue_; +}; + +extern ObShardScanAllTaskProcessor g_shard_scan_all_task_processor; +} // end of namespace event +} // end of namespace obproxy +} // end of namespace oceanbase + +#endif // OBPROXY_SHARD_SCAN_ALL_TASK_H diff --git a/src/obproxy/iocore/eventsystem/ob_vconnection.h b/src/obproxy/iocore/eventsystem/ob_vconnection.h index ef3dfe607..d413b7f0b 100644 --- a/src/obproxy/iocore/eventsystem/ob_vconnection.h +++ b/src/obproxy/iocore/eventsystem/ob_vconnection.h @@ -98,6 +98,8 @@ class ObProxyMutex; #define VC_EVENT_ACTIVE_TIMEOUT (VC_EVENT_EVENTS_START+6) #define VC_EVENT_HELLO_PKT_READ_READY (VC_EVENT_EVENTS_START+7) +// OBProxy detect server dead, should close connection +#define VC_EVENT_DETECT_SERVER_DEAD (VC_EVENT_EVENTS_START+8) // ObEvent return codes #define VC_EVENT_DONE CONTINUATION_DONE @@ -184,6 +186,8 @@ class ObVConnection : public ObContinuation * No activity was performed for a certain period. * VC_EVENT_ACTIVE_TIMEOUT * Write operation continued beyond a time limit. + * VC_EVENT_DETECT_SERVER_DEAD + * find Server dead, close connection * VC_EVENT_ERROR * An error occurred during the write * @@ -622,6 +626,10 @@ static inline const char *get_vc_event_name(int32_t event) ret = "VC_EVENT_ACTIVE_TIMEOUT"; break; + case VC_EVENT_DETECT_SERVER_DEAD: + ret = "VC_EVENT_DETECT_SERVER_DEAD"; + break; + default: ret = "unknown event"; break; diff --git a/src/obproxy/iocore/net/ob_connection.cpp b/src/obproxy/iocore/net/ob_connection.cpp index 66dee9a9b..4ee0c9daf 100644 --- a/src/obproxy/iocore/net/ob_connection.cpp +++ b/src/obproxy/iocore/net/ob_connection.cpp @@ -30,6 +30,8 @@ #include "iocore/net/ob_connection.h" #include "utils/ob_proxy_hot_upgrader.h" +#include "utils/ob_layout.h" +#include "ob_proxy_init.h" using namespace oceanbase::common; using namespace oceanbase::obproxy::event; @@ -390,6 +392,50 @@ int ObServerConnection::setup_fd_for_listen( const int32_t send_bufsize) { int ret = OB_SUCCESS; + if (RUN_MODE_PROXY == g_run_mode) { + if (OB_FAIL(setup_fd_for_listen_proxy_mode(non_blocking, recv_bufsize, send_bufsize))) { + PROXY_SOCK_LOG(WARN, "setup_fd_for_listen_proxy_mode failed", K(ret)); + } + } else if (RUN_MODE_CLIENT == g_run_mode) { + if (OB_FAIL(setup_fd_for_listen_client_mode(non_blocking, recv_bufsize, send_bufsize))) { + PROXY_SOCK_LOG(WARN, "setup_fd_for_listen_client_mode failed", K(ret)); + } + } + + return ret; +} + +int ObServerConnection::setup_fd_for_listen_client_mode( + const bool non_blocking, + const int32_t recv_bufsize, + const int32_t send_bufsize) +{ + UNUSED(recv_bufsize); + UNUSED(send_bufsize); + int ret = OB_SUCCESS; + + if (non_blocking && OB_FAIL(ObSocketManager::nonblocking(fd_))) { + PROXY_SOCK_LOG(WARN, "fail to set fd nonblocking", K(fd_), K(ret)); + } + + if (OB_FAIL(ret)) { + // make coverity happy + int tmp_ret = ret; + if (OB_FAIL(close())) { + PROXY_SOCK_LOG(WARN, "fail to close server connection", K(ret)); + } + ret = tmp_ret; + } + return ret; +} + + +int ObServerConnection::setup_fd_for_listen_proxy_mode( + const bool non_blocking, + const int32_t recv_bufsize, + const int32_t send_bufsize) +{ + int ret = OB_SUCCESS; if (OB_FAIL(ObSocketManager::set_sndbuf_and_rcvbuf_size(fd_, send_bufsize, recv_bufsize, SNDBUF_AND_RCVBUF_PREC))) { @@ -458,7 +504,7 @@ int ObServerConnection::setup_fd_for_listen( // make coverity happy int tmp_ret = ret; if (OB_FAIL(close())) { - PROXY_SOCK_LOG(WARN, "fail to close server connection", K(tmp_ret)); + PROXY_SOCK_LOG(WARN, "fail to close server connection", K(ret)); } ret = tmp_ret; } @@ -467,6 +513,55 @@ int ObServerConnection::setup_fd_for_listen( int ObServerConnection::listen(const bool non_blocking, const int32_t recv_bufsize, const int32_t send_bufsize) +{ + int ret = OB_SUCCESS; + if (RUN_MODE_PROXY == g_run_mode) { + if (OB_FAIL(listen_proxy_mode(non_blocking, recv_bufsize, send_bufsize))) { + PROXY_SOCK_LOG(WARN, "listen proxy mode failed", K(ret)); + } + } else if (RUN_MODE_CLIENT == g_run_mode) { + if (OB_FAIL(listen_client_mode(non_blocking, recv_bufsize, send_bufsize))) { + PROXY_SOCK_LOG(WARN, "listen client mode failed", K(ret)); + } + } + + return ret; +} + +int ObServerConnection::listen_client_mode(const bool non_blocking, const int32_t recv_bufsize, + const int32_t send_bufsize) +{ + int ret = OB_SUCCESS; + struct sockaddr_un *addr = (struct sockaddr_un*)&addr_.unix_domain_; + addr->sun_family = AF_UNIX; + memset(addr->sun_path, 0, sizeof(addr->sun_path)); + strncpy(addr->sun_path, get_global_layout().get_unix_domain_path(), sizeof(addr->sun_path) - 1); + if (OB_FAIL(ObSocketManager::socket(AF_UNIX, SOCK_STREAM, 0, fd_))) { + PROXY_SOCK_LOG(WARN, "fail to create socket", K(ret), KERRMSGS); + } else if (OB_FAIL(setup_fd_for_listen_client_mode(non_blocking, recv_bufsize, send_bufsize))) { + PROXY_SOCK_LOG(WARN, "fail to setup_fd_for_listen", K(ret)); + } else if (OB_FAIL(ObSocketManager::bind(fd_, &addr_.sa_, sizeof(*addr)))) { + PROXY_SOCK_LOG(WARN, "fail to bind", K(ret)); + } else if (OB_FAIL(ObSocketManager::listen(fd_, LISTEN_BACKLOG))) { + PROXY_SOCK_LOG(WARN, "fail to listen", KERRMSGS, K(ret)); + } else { + ObHotUpgraderInfo &info = get_global_hot_upgrade_info(); + info.ipv4_fd_ = fd_; + } + + if (OB_FAIL(ret)) { + // make coverity happy + int tmp_ret = ret; + if (OB_FAIL(close())) { + PROXY_SOCK_LOG(WARN, "fail to close server connection", K(ret)); + } + ret = tmp_ret; + } + return ret; +} + +int ObServerConnection::listen_proxy_mode(const bool non_blocking, const int32_t recv_bufsize, + const int32_t send_bufsize) { int ret = OB_SUCCESS; if (!ops_is_ip(accept_addr_)) { @@ -478,21 +573,23 @@ int ObServerConnection::listen(const bool non_blocking, const int32_t recv_bufsi ObHotUpgraderInfo &info = get_global_hot_upgrade_info(); if (OB_FAIL(ObSocketManager::socket(addr_.sa_.sa_family, SOCK_STREAM, IPPROTO_TCP, fd_))) { - PROXY_SOCK_LOG(WARN, "failed to create socket", K(addr_), KERRMSGS, K(ret)); + PROXY_SOCK_LOG(WARN, "fail to create socket", K(addr_), KERRMSGS, K(ret)); } else if (OB_FAIL(setup_fd_for_listen(non_blocking, recv_bufsize, send_bufsize))) { - PROXY_SOCK_LOG(WARN, "failed to setup_fd_for_listen", K(addr_), K(ret)); + PROXY_SOCK_LOG(WARN, "fail to setup_fd_for_listen", K(addr_), K(ret)); } else if (OB_FAIL(ObSocketManager::bind(fd_, &addr_.sa_, static_cast(ops_ip_size(addr_.sa_))))) { - PROXY_SOCK_LOG(WARN, "failed to bind", K(addr_), KERRMSGS, K(ret)); + PROXY_SOCK_LOG(WARN, "fail to bind", K(addr_), KERRMSGS, K(ret)); } else if (OB_FAIL(ObSocketManager::listen(fd_, LISTEN_BACKLOG))) { - PROXY_SOCK_LOG(WARN, "failed to listen", K(addr_), KERRMSGS, K(ret)); + PROXY_SOCK_LOG(WARN, "fail to listen", K(addr_), KERRMSGS, K(ret)); } else { // Original just did this on port == 0. int64_t namelen = sizeof(addr_); if (OB_FAIL(ObSocketManager::getsockname(fd_, &addr_.sa_, &namelen))) { PROXY_SOCK_LOG(WARN, "failed to getsockname", K(addr_), KERRMSGS, K(ret)); - } else { - info.fd_ = fd_; + } else if (addr_.is_ip4()) { + info.ipv4_fd_ = fd_; + } else if (addr_.is_ip6()) { + info.ipv6_fd_ = fd_; } } @@ -500,7 +597,7 @@ int ObServerConnection::listen(const bool non_blocking, const int32_t recv_bufsi // make coverity happy int tmp_ret = ret; if (OB_FAIL(close())) { - PROXY_SOCK_LOG(WARN, "fail to close server connection", K(tmp_ret)); + PROXY_SOCK_LOG(WARN, "fail to close server connection", K(ret)); } ret = tmp_ret; } diff --git a/src/obproxy/iocore/net/ob_connection.h b/src/obproxy/iocore/net/ob_connection.h index 31cf184e7..bc87bc031 100644 --- a/src/obproxy/iocore/net/ob_connection.h +++ b/src/obproxy/iocore/net/ob_connection.h @@ -159,6 +159,22 @@ class ObServerConnection : public ObConnection // Client side (inbound) local IP address. ObIpEndpoint accept_addr_; +private: + int setup_fd_for_listen_proxy_mode( + const bool non_blocking = false, + const int32_t recv_bufsize = 0, + const int32_t send_bufsize = 0); + int setup_fd_for_listen_client_mode( + const bool non_blocking = false, + const int32_t recv_bufsize = 0, + const int32_t send_bufsize = 0); + int listen_proxy_mode(const bool non_blocking = false, + const int32_t recv_bufsize = 0, + const int32_t send_bufsize = 0); + int listen_client_mode(const bool non_blocking = false, + const int32_t recv_bufsize = 0, + const int32_t send_bufsize = 0); + private: static const int32_t LISTEN_BACKLOG; }; diff --git a/src/obproxy/iocore/net/ob_inet.cpp b/src/obproxy/iocore/net/ob_inet.cpp index 3cfe40a17..f37e0e429 100644 --- a/src/obproxy/iocore/net/ob_inet.cpp +++ b/src/obproxy/iocore/net/ob_inet.cpp @@ -41,14 +41,27 @@ namespace obproxy namespace net { +uint64_t ObIpEndpoint::hash(const uint64_t hash) const +{ + char buf[MAX_IP_ADDR_LENGTH]; + int64_t pos = to_string(buf, MAX_IP_ADDR_LENGTH); + return murmurhash(buf, static_cast(pos), hash); +} + int64_t ObIpEndpoint::to_string(char *buf, const int64_t buf_len) const { - char ip_buff[INET6_ADDRSTRLEN]; + char ip_buff[MAX_IP_ADDR_LENGTH]; int64_t pos = 0; J_OBJ_START(); - databuff_printf(buf, buf_len, pos, "%s:%u", - ops_ip_ntop(*this, ip_buff, sizeof(ip_buff)), - ops_ip_port_host_order(*this)); + if (is_ip6()) { + databuff_printf(buf, buf_len, pos, "[%s]:%u", + ops_ip_ntop(*this, ip_buff, sizeof(ip_buff)), + ops_ip_port_host_order(*this)); + } else { + databuff_printf(buf, buf_len, pos, "%s:%u", + ops_ip_ntop(*this, ip_buff, sizeof(ip_buff)), + ops_ip_port_host_order(*this)); + } J_OBJ_END(); return pos; } diff --git a/src/obproxy/iocore/net/ob_inet.h b/src/obproxy/iocore/net/ob_inet.h index 369d8ce39..6321c6e52 100644 --- a/src/obproxy/iocore/net/ob_inet.h +++ b/src/obproxy/iocore/net/ob_inet.h @@ -92,10 +92,15 @@ union ObIpEndpoint memset(this, 0, sizeof(ObIpEndpoint)); assign(addr); } + explicit ObIpEndpoint(const sockaddr_storage &addr) { + memset(this, 0, sizeof(ObIpEndpoint)); + assign(addr); + } ObIpEndpoint (const ObIpEndpoint &point) { MEMCPY(this, &point, sizeof(ObIpEndpoint)); } void operator= (const ObIpEndpoint &point) { MEMCPY(this, &point, sizeof(ObIpEndpoint)); } ObIpEndpoint &assign(const sockaddr &ip); + ObIpEndpoint &assign(const sockaddr_storage &ip); ObIpEndpoint &assign(const ObIpAddr &addr, const in_port_t port = 0); // Test for valid IP address. @@ -107,6 +112,8 @@ union ObIpEndpoint // Test for IPv6. bool is_ip6() const; + bool is_unix_domain() const; + uint16_t family() const; // Set to be any address for family family. // family must be AF_INET or AF_INET6. @@ -129,13 +136,14 @@ union ObIpEndpoint int64_t get_port_host_order() const; uint32_t get_ip4_host_order() const; - uint64_t hash(const uint64_t hash = 0) const { return common::murmurhash(&sa_, sizeof(sockaddr), hash); } + uint64_t hash(const uint64_t hash = 0) const; int64_t to_string(char *buffer, const int64_t size) const; struct sockaddr sa_; // Generic address. struct sockaddr_in sin_; // IPv4 struct sockaddr_in6 sin6_; // IPv6 + struct sockaddr_un unix_domain_; // unix_domain }; // Reset an address to invalid. @@ -485,8 +493,17 @@ inline const uint8_t *ops_ip_addr8_cast(const ObIpEndpoint &ip) // @return true if this is an IP loopback address, false otherwise. inline bool ops_is_ip_loopback(const sockaddr &ip) { - return (AF_INET == ip.sa_family && 0x7F == ops_ip_addr8_cast(ip)[0]) - || (AF_INET6 == ip.sa_family && IN6_IS_ADDR_LOOPBACK(&ops_ip6_addr_cast(ip))); + bool zret = false; + if (ops_is_ip4(ip)) { + in_addr_t a = ops_ip4_addr_cast(ip); + zret = (a == 0x100007F); + } else if (ops_is_ip6(ip)) { + in6_addr a = ops_ip6_addr_cast(ip); + zret = ((a.s6_addr32[0] == 0 && a.s6_addr32[1] == 0 && a.s6_addr32[2] == 0 + && a.s6_addr[12] == 0 && a.s6_addr[13] == 0 && a.s6_addr[14] == 0 + && a.s6_addr[15] == 1)); + } + return zret; } inline bool ops_is_ip_loopback(const ObIpEndpoint &ip) @@ -556,6 +573,8 @@ inline bool ops_ip_copy(sockaddr &dst, const sockaddr &src) case AF_INET6: n = sizeof(sockaddr_in6); break; + case AF_UNIX: + break; } switch (dst.sa_family) { case AF_INET: @@ -1034,6 +1053,12 @@ inline ObIpEndpoint& ObIpEndpoint::assign(const sockaddr &ip) return *this; } +inline ObIpEndpoint& ObIpEndpoint::assign(const sockaddr_storage &ip) +{ + ops_ip_copy(sa_, ops_ip_sa_cast(ip)); + return *this; +} + inline in_port_t& ObIpEndpoint::port() { return ops_ip_port_cast(sa_); @@ -1061,6 +1086,7 @@ inline bool ObIpEndpoint::is_valid() const inline bool ObIpEndpoint::is_ip4() const { return AF_INET == sa_.sa_family; } inline bool ObIpEndpoint::is_ip6() const { return AF_INET6 == sa_.sa_family; } +inline bool ObIpEndpoint::is_unix_domain() const { return AF_UNIX == sa_.sa_family; } inline uint16_t ObIpEndpoint::family() const { return sa_.sa_family; } inline ObIpEndpoint& ObIpEndpoint::set_to_any_addr(const int family) diff --git a/src/obproxy/iocore/net/ob_net_accept.cpp b/src/obproxy/iocore/net/ob_net_accept.cpp index 3827565c0..c43c0ee57 100644 --- a/src/obproxy/iocore/net/ob_net_accept.cpp +++ b/src/obproxy/iocore/net/ob_net_accept.cpp @@ -32,6 +32,7 @@ #include "iocore/net/ob_net_accept.h" #include "iocore/net/ob_net.h" #include "iocore/net/ob_event_io.h" +#include "ob_proxy_init.h" #include "omt/ob_resource_unit_table_processor.h" #include "proxy/mysql/ob_mysql_client_session.h" #include "proxy/route/ob_table_cache.h" @@ -264,7 +265,6 @@ int ObNetAccept::init_accept_per_thread() int ObNetAccept::do_listen(const bool non_blocking) { - int ret = OB_SUCCESS; PROXY_NET_LOG(DEBUG, "ObNetAccept::do_listen", K(server_.fd_), K(non_blocking)); const ObHotUpgraderInfo &info = get_global_hot_upgrade_info(); @@ -323,22 +323,34 @@ int ObNetAccept::do_listen(const bool non_blocking) int ObNetAccept::fetch_vip_tenant(ObUnixNetVConnection* vc, ObVipTenant& vip_tenant, bool& lookup_success) { int ret = OB_SUCCESS; - int32_t ip; - int32_t port; int64_t vid; + bool found = false; + ObConfigItem tenant_item; + ObConfigItem cluster_item; if (OB_ISNULL(vc)) { ret = OB_ERR_UNEXPECTED; PROXY_NET_LOG(WARN, "vc pointer is null", K(ret)); } else { - ip = ntohl(vc->get_virtual_ip()); - port = static_cast(vc->get_virtual_port()); vid = static_cast(vc->get_virtual_vid()); - vip_tenant.vip_addr_.set(ip, port, vid); - if (OB_FAIL(get_global_vip_tenant_processor().get_vip_tenant(vip_tenant))) { - PROXY_NET_LOG(DEBUG, "fail to get vip tenant", K(ret)); - ret = OB_SUCCESS; - } else { - lookup_success = true; + vip_tenant.vip_addr_.set(vc->get_virtual_addr(), vid); + if (OB_FAIL(get_global_config_processor().get_proxy_config_with_level( + vip_tenant.vip_addr_, "", "", "proxy_tenant_name", tenant_item, "LEVEL_VIP", found))) { + PROXY_NET_LOG(WARN, "get proxy tenant name config failed", K(vip_tenant.vip_addr_), K(ret)); + } + + if (OB_SUCC(ret) && found) { + if (OB_FAIL(get_global_config_processor().get_proxy_config_with_level( + vip_tenant.vip_addr_, "", "", "rootservice_cluster_name", cluster_item, "LEVEL_VIP", found))) { + PROXY_NET_LOG(WARN, "get cluster name config failed", K(vip_tenant.vip_addr_), K(ret)); + } + } + + if (OB_SUCC(ret) && found) { + if (OB_FAIL(vip_tenant.set_tenant_cluster(tenant_item.str(), cluster_item.str()))) { + PROXY_CS_LOG(WARN, "set tenant and cluster name failed", K(tenant_item), K(cluster_item), K(ret)); + } else { + lookup_success = true; + } } } return ret; @@ -348,8 +360,8 @@ int ObNetAccept::fetch_tenant_cpu(ObVipTenant& vip_tenant, ObTenantCpu*& tenant_ { int ret = OB_SUCCESS; ObString key_name; - char vip_name[OB_IP_STR_BUFF]; - common::ObFixedLengthString key_string; + char vip_name[MAX_IP_ADDR_LENGTH]; + common::ObFixedLengthString key_string; if (OB_UNLIKELY(!vip_tenant.vip_addr_.addr_.ip_to_string(vip_name, static_cast(sizeof(vip_name))))) { ret = OB_ERR_UNEXPECTED; PROXY_NET_LOG(WARN, "fail to covert ip to string", K(vip_name), K(ret)); diff --git a/src/obproxy/iocore/net/ob_net_vconnection.h b/src/obproxy/iocore/net/ob_net_vconnection.h index 6ab615ea9..6fa432012 100644 --- a/src/obproxy/iocore/net/ob_net_vconnection.h +++ b/src/obproxy/iocore/net/ob_net_vconnection.h @@ -419,35 +419,23 @@ class ObNetVConnection : public event::ObVConnection virtual int get_socket() = 0; public: - // Returns local ip. - // @deprecated get_local_addr() should be used instead for AF_INET6 compatibility. - in_addr_t get_local_ip(); // Returns local port uint16_t get_local_port(); // Returns local sockaddr storage const sockaddr &get_local_addr(); - // Returns remote ip. - // @deprecated get_remote_addr() should be used instead for AF_INET6 compatibility. - in_addr_t get_remote_ip(); // Returns remote port uint16_t get_remote_port(); // Returns remote sockaddr storage const sockaddr &get_remote_addr(); - // Returns virual ip. - // @deprecated get_virtual_addr() should be used instead for AF_INET6 compatibility. - in_addr_t get_virtual_ip(); // Returns virtual port uint16_t get_virtual_port(); // Returns virtual vid(vpc id) uint32_t get_virtual_vid(); // Returns virtual sockaddr storage const sockaddr &get_virtual_addr(); - const sockaddr &get_real_client_addr(); - in_addr_t get_real_client_ip(); - uint16_t get_real_client_port(); // Force an event if a write operation empties the write buffer. // @@ -476,7 +464,7 @@ class ObNetVConnection : public event::ObVConnection ObIpEndpoint local_addr_; // it is local proxy addr ObIpEndpoint remote_addr_; // if from accept, it is client addr, otherwise it is server addr ObIpEndpoint real_client_addr_; - ObIpEndpoint virtual_addr_; + ObIpEndpoint virtual_addr_; // vip addr uint32_t virtual_vid_; bool got_local_addr_; @@ -504,13 +492,6 @@ inline ObNetVConnection::ObNetVConnection() ob_zero(real_client_addr_); } -// local -inline in_addr_t ObNetVConnection::get_local_ip() -{ - const sockaddr addr = get_local_addr(); - return ops_is_ip4(addr) ? ops_ip4_addr_cast(addr) : 0; -} - //@return The local port in host order. inline uint16_t ObNetVConnection::get_local_port() { @@ -530,13 +511,6 @@ inline const sockaddr &ObNetVConnection::get_local_addr() return local_addr_.sa_; } -// remote -inline in_addr_t ObNetVConnection::get_remote_ip() -{ - const sockaddr &addr = get_remote_addr(); - return ops_is_ip4(addr) ? ops_ip4_addr_cast(addr) : 0; -} - // @return The remote port in host order. inline uint16_t ObNetVConnection::get_remote_port() { @@ -561,17 +535,6 @@ inline const sockaddr &ObNetVConnection::get_real_client_addr() return real_client_addr_.sa_; } -inline in_addr_t ObNetVConnection::get_real_client_ip() -{ - const sockaddr addr = get_real_client_addr(); - return ops_is_ip4(addr) ? ops_ip4_addr_cast(addr) : 0; -} - -inline uint16_t ObNetVConnection::get_real_client_port() -{ - return ops_ip_port_host_order(get_real_client_addr()); -} - // virtual inline const sockaddr &ObNetVConnection::get_virtual_addr() { @@ -582,12 +545,6 @@ inline const sockaddr &ObNetVConnection::get_virtual_addr() return virtual_addr_.sa_; } -inline in_addr_t ObNetVConnection::get_virtual_ip() -{ - const sockaddr addr = get_virtual_addr(); - return ops_is_ip4(addr) ? ops_ip4_addr_cast(addr) : 0; -} - inline uint16_t ObNetVConnection::get_virtual_port() { return ops_ip_port_host_order(get_virtual_addr()); @@ -595,6 +552,10 @@ inline uint16_t ObNetVConnection::get_virtual_port() inline uint32_t ObNetVConnection::get_virtual_vid() { + if (!got_virtual_addr_) { + set_virtual_addr(); + got_virtual_addr_ = true; + } return virtual_vid_; } diff --git a/src/obproxy/iocore/net/ob_unix_net.cpp b/src/obproxy/iocore/net/ob_unix_net.cpp index a2410a82f..37d4a2894 100644 --- a/src/obproxy/iocore/net/ob_unix_net.cpp +++ b/src/obproxy/iocore/net/ob_unix_net.cpp @@ -82,6 +82,17 @@ static inline int net_signal_hook_function(ObEThread &thread) return ret; } +void send_signal_when_exit_normally() +{ + if (g_proxy_fatal_errcode == OB_SUCCESS) { + pid_t parent_pid= getppid(); + if (parent_pid != 1) { + PROXY_NET_LOG(INFO, "obproxy child will send SIGUSR2 to parent", K(parent_pid)); + kill(parent_pid, SIGUSR2); + } + } +} + void proxy_exit_once() { // no connection opened, graceful exit flag is true, graceful exit timeout, exit!! @@ -100,7 +111,7 @@ void proxy_exit_once() } ret = OB_SUCCESS;//ignore error } - OB_LOGGER.destory_async_log_thread(); + OB_LOGGER.destroy_async_log_thread(); _exit(1); } @@ -309,6 +320,7 @@ int ObInactivityCop::check_inactivity(int event, ObEvent *e) if (global_connections > 0) { if (info.graceful_exit_end_time_ >= info.graceful_exit_start_time_ && info.graceful_exit_end_time_ <= now) { + send_signal_when_exit_normally(); pthread_once(&g_exit_once, proxy_exit_once); } else { int64_t thread_local_client_connections = 0; @@ -317,6 +329,7 @@ int ObInactivityCop::check_inactivity(int event, ObEvent *e) K(global_connections), K(thread_local_client_connections), K(g_proxy_fatal_errcode)); } } else { + send_signal_when_exit_normally(); pthread_once(&g_exit_once, proxy_exit_once); } } else { @@ -349,7 +362,7 @@ int ObInactivityCop::check_inactivity(int event, ObEvent *e) PROXY_NET_LOG(WARN, "fail to close unix net vconnection", K(vc), K(close_ret)); } } else { - + int32_t event = EVENT_NONE; if (vc->get_is_force_timeout() || (info.graceful_exit_end_time_ >= info.graceful_exit_start_time_ && info.graceful_exit_end_time_ > 0 @@ -358,13 +371,12 @@ int ObInactivityCop::check_inactivity(int event, ObEvent *e) } if (now != vc->next_inactivity_timeout_at_) { - ObIpEndpoint ip; - ip.sa_ = vc->get_remote_addr(); + ObIpEndpoint ip(vc->get_remote_addr()); if (0 < get_global_proxy_config().server_detect_mode && vc->source_type_ == ObUnixNetVConnection::VC_CONNECT && OB_HASH_EXIST == get_global_resource_pool_processor().ip_set_.exist_refactored(ip)) { - PROXY_NET_LOG(WARN, "server dead, close connection", K(ip)); - vc->next_inactivity_timeout_at_ = now; + PROXY_NET_LOG(WARN, "detect server dead, close connection", K(ip)); + event = EVENT_ERROR; } } @@ -391,6 +403,8 @@ int ObInactivityCop::check_inactivity(int event, ObEvent *e) "next_inactivity_timeout_at", hrtime_to_sec(vc->next_inactivity_timeout_at_), "inactivity_timeout_in", hrtime_to_sec(vc->inactivity_timeout_in_)); vc->handle_event(EVENT_IMMEDIATE, e); + } else if (EVENT_NONE != event) { + vc->handle_event(event, e); } } } diff --git a/src/obproxy/iocore/net/ob_unix_net_processor.cpp b/src/obproxy/iocore/net/ob_unix_net_processor.cpp index d6ad29d20..27f409d1d 100644 --- a/src/obproxy/iocore/net/ob_unix_net_processor.cpp +++ b/src/obproxy/iocore/net/ob_unix_net_processor.cpp @@ -459,6 +459,15 @@ class ObCheckConnect : public ObContinuation } break; + case VC_EVENT_DETECT_SERVER_DEAD: + PROXY_NET_LOG(WARN, "detect server addr dead", "addr", vc_->con_.addr_, K(this)); + vc_->do_io_close(); + if (!action_.cancelled_) { + action_.continuation_->handle_event(NET_EVENT_OPEN_FAILED, + reinterpret_cast(-ENET_CONNECT_FAILED)); + } + break; + default: PROXY_NET_LOG(WARN, "unknown connect event"); if (!action_.cancelled_) { diff --git a/src/obproxy/iocore/net/ob_unix_net_vconnection.cpp b/src/obproxy/iocore/net/ob_unix_net_vconnection.cpp index b865ce7d8..764248ebc 100644 --- a/src/obproxy/iocore/net/ob_unix_net_vconnection.cpp +++ b/src/obproxy/iocore/net/ob_unix_net_vconnection.cpp @@ -117,6 +117,7 @@ inline int ObUnixNetVConnection::read_signal_and_update(const int event) case VC_EVENT_ERROR: case VC_EVENT_ACTIVE_TIMEOUT: case VC_EVENT_INACTIVITY_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: PROXY_NET_LOG(DEBUG, "null read.vio cont, closing vc", K(event), K(this)); closed_ = 1; break; @@ -151,6 +152,7 @@ inline int ObUnixNetVConnection::write_signal_and_update(const int event) case VC_EVENT_ERROR: case VC_EVENT_ACTIVE_TIMEOUT: case VC_EVENT_INACTIVITY_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: PROXY_NET_LOG(DEBUG, "null write.vio cont, closing vc", K(event), K(this)); closed_ = 1; break; @@ -1192,6 +1194,32 @@ void ObUnixNetVConnection::remove_from_keep_alive_lru() } } +int ObUnixNetVConnection::set_virtual_addr() +{ + int ret = OB_SUCCESS; + get_remote_addr(); + + if (OB_UNLIKELY(get_global_proxy_config().enable_qa_mode)) { + // Simulate public cloud SLB to assign IP addresses + // Get the real client address first, then modify the virutal address + do_set_virtual_addr(); + if (OB_FAIL(ops_ip_pton(get_global_proxy_config().qa_mode_mock_public_cloud_slb_addr, virtual_addr_))) { + PROXY_CS_LOG(WARN, "fail to ops ip pton", "qa_mode_mock_public_cloud_slb_addr", + get_global_proxy_config().qa_mode_mock_public_cloud_slb_addr, K(ret)); + } else { + virtual_vid_ = static_cast(get_global_proxy_config().qa_mode_mock_public_cloud_vid); + } + } else if (remote_addr_.is_ip4()) { + ret = do_set_virtual_addr(); + } else { + real_client_addr_ = remote_addr_; + virtual_addr_ = remote_addr_; + virtual_addr_.sin6_.sin6_port = htons(2883); + } + + return ret; +} + int ObUnixNetVConnection::do_set_virtual_addr() { int ret = OB_SUCCESS; @@ -1234,27 +1262,6 @@ int ObUnixNetVConnection::do_set_virtual_addr() return ret; } -int ObUnixNetVConnection::set_virtual_addr() -{ - int ret = OB_SUCCESS; - - if (OB_UNLIKELY(get_global_proxy_config().enable_qa_mode)) { - // SLB to simulate public cloud allocation of IP addresses - // First obtain the real client address, and then modify the virutal address - do_set_virtual_addr(); - if (OB_FAIL(ops_ip_pton(get_global_proxy_config().qa_mode_mock_public_cloud_slb_addr, virtual_addr_))) { - PROXY_CS_LOG(WARN, "fail to ops ip pton", "qa_mode_mock_public_cloud_slb_addr", - get_global_proxy_config().qa_mode_mock_public_cloud_slb_addr, K(ret)); - } else { - virtual_vid_ = static_cast(get_global_proxy_config().qa_mode_mock_public_cloud_vid); - } - } else { - ret = do_set_virtual_addr(); - } - - return ret; -} - int ObUnixNetVConnection::apply_options() { int ret = OB_SUCCESS; @@ -1465,7 +1472,7 @@ int ObUnixNetVConnection::main_event(int event, ObEvent *e) if (OB_ISNULL(e)) { ret = OB_ERR_UNEXPECTED; PROXY_NET_LOG(WARN, "occur fatal error", K(event), K(e), K(ret)); - } else if (OB_UNLIKELY(EVENT_IMMEDIATE != event && EVENT_INTERVAL != event)) { + } else if (OB_UNLIKELY(EVENT_IMMEDIATE != event && EVENT_INTERVAL != event && EVENT_ERROR != event)) { ret = OB_ERR_UNEXPECTED; PROXY_NET_LOG(WARN, "occur fatal error", K(event), K(e), K(ret)); } else if (thread_ != this_ethread()) { @@ -1506,6 +1513,8 @@ int ObUnixNetVConnection::main_event(int event, ObEvent *e) signal_event = VC_EVENT_INACTIVITY_TIMEOUT; signal_timeout_at = &next_inactivity_timeout_at_; } + } else if (EVENT_ERROR == event) { + signal_event = VC_EVENT_DETECT_SERVER_DEAD; } else { signal_event = VC_EVENT_ACTIVE_TIMEOUT; signal_timeout = &active_timeout_action_; diff --git a/src/obproxy/ob_proxy.cpp b/src/obproxy/ob_proxy.cpp index b94a9f157..cc8444a7b 100644 --- a/src/obproxy/ob_proxy.cpp +++ b/src/obproxy/ob_proxy.cpp @@ -75,6 +75,7 @@ #include "obutils/ob_session_pool_processor.h" #include "obutils/ob_config_processor.h" #include "iocore/net/ob_ssl_processor.h" +#include "ob_proxy_init.h" using namespace oceanbase::common; using namespace oceanbase::share; @@ -194,9 +195,11 @@ int ObProxy::init(ObProxyOptions &opts, ObAppVersionInfo &proxy_version) } else if (OB_FAIL(app_config_processor.init())) { LOG_ERROR("fail to init app config processor", K(ret)); } else { - // if fail to init prometheus, do not stop the startup of obproxy - if (g_ob_prometheus_processor.init()) { - LOG_WARN("fail to init prometheus processor"); + if (RUN_MODE_PROXY == g_run_mode) { + // if fail to init prometheus, do not stop the startup of obproxy + if (OB_FAIL(g_ob_prometheus_processor.init())) { + LOG_WARN("fail to init prometheus processor", K(ret)); + } } #if OB_HAS_TESTS @@ -247,9 +250,33 @@ void ObProxy::destroy() if (OB_FAIL(ObAsyncCommonTask::destroy_repeat_task(mmp_init_cont_))) { LOG_WARN("fail to destroy meta proxy init task", K(ret)); } + ObThreadId tid = 0; + for (int64_t i = 0; i < g_event_processor.dedicate_thread_count_ && OB_SUCC(ret); ++i) { + tid = g_event_processor.all_dedicate_threads_[i]->tid_; + if (OB_FAIL(thread_cancel(tid))) { + PROXY_NET_LOG(WARN, "fail to do thread_cancel", K(tid), K(ret)); + } else if (OB_FAIL(thread_join(tid))) { + PROXY_NET_LOG(WARN, "fail to do thread_join", K(tid), K(ret)); + } else { + PROXY_NET_LOG(INFO, "graceful exit, dedicated thread exited", K(tid)); + } + ret = OB_SUCCESS;//ignore error + } + + for (int64_t i = 0; i < g_event_processor.event_thread_count_ && OB_SUCC(ret); ++i) { + tid = g_event_processor.all_event_threads_[i]->tid_; + if (OB_FAIL(thread_cancel(tid))) { + PROXY_NET_LOG(WARN, "fail to do thread_cancel", K(tid), K(ret)); + } else if (OB_FAIL(thread_join(tid))) { + PROXY_NET_LOG(WARN, "fail to do thread_join", K(tid), K(ret)); + } else { + PROXY_NET_LOG(INFO, "graceful exit, event thread exited", K(tid)); + } + ret = OB_SUCCESS;//ignore error + } - proxy_opts_ = NULL; - mysql_config_params_ = NULL; + OB_LOGGER.destroy_async_log_thread(); + _exit(0); } } @@ -347,9 +374,11 @@ int ObProxy::start() } else if (OB_FAIL(ObMysqlProxyServerMain::start_mysql_proxy_acceptor())) { LOG_ERROR("fail to start accept server", K(ret)); } else { - // if fail to init prometheus, do not stop the startup of obproxy - if (g_ob_prometheus_processor.start_prometheus()) { - LOG_WARN("fail to start prometheus"); + if (RUN_MODE_PROXY == g_run_mode) { + // if fail to init prometheus, do not stop the startup of obproxy + if (OB_FAIL(g_ob_prometheus_processor.start_prometheus())) { + LOG_WARN("fail to start prometheus", K(ret)); + } } mysql_config_params_ = NULL; @@ -373,7 +402,9 @@ int ObProxy::start() } info.is_parent_ = true; } - this_ethread()->execute(); + if (RUN_MODE_PROXY == g_run_mode) { + this_ethread()->execute(); + } } } return ret; @@ -411,7 +442,7 @@ int ObProxy::init_user_specified_config() { int ret = OB_SUCCESS; //1. set config from cmd -o name=value - if (NULL != proxy_opts_->optstr_ && OB_FAIL(config_->add_extra_config(proxy_opts_->optstr_))) { + if (NULL != proxy_opts_->optstr_ && OB_FAIL(config_->add_extra_config_from_opt(proxy_opts_->optstr_))) { LOG_WARN("fail to add extra config", K(ret)); //2. set config from cmd other opts @@ -958,7 +989,7 @@ int ObProxy::get_meta_table_server(ObIArray &replicas, O if (rs_list.count() <= 0) { ret = OB_ERR_UNEXPECTED; LOG_WARN("rs_list count must > 0", K(ret)); - } else if (OB_FAIL(raw_client.init(user_name, password, database, password1))) { + } else if (OB_FAIL(raw_client.init(user_name, password, database, cluster_name, password1))) { LOG_WARN("fail to init raw mysql client", K(ret)); } else if (OB_FAIL(raw_client.set_server_addr(rs_list))) { LOG_WARN("fail to set server addr", K(ret)); diff --git a/src/obproxy/ob_proxy_init.cpp b/src/obproxy/ob_proxy_init.cpp new file mode 100644 index 000000000..4300cfe69 --- /dev/null +++ b/src/obproxy/ob_proxy_init.cpp @@ -0,0 +1,130 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + * + * ************************************************************* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "ob_proxy_main.h" +#include "lib/oblog/ob_warning_buffer.h" +#include "ob_proxy_init.h" +#include "lib/json/ob_json.h" +#include "obutils/ob_proxy_json_config_info.h" + +using namespace oceanbase::common; +using namespace oceanbase::json; +using namespace oceanbase::obproxy::obutils; + +namespace oceanbase +{ +namespace obproxy +{ + +OBPROXY_RUN_MODE g_run_mode = RUN_MODE_PROXY; +static bool is_obproxy_inited = false; +DRWLock local_init_lock; + +int init_obproxy_client(const ObString &config) +{ + int ret = OB_SUCCESS; + if (!is_obproxy_inited) { + DRWLock::WRLockGuard lock(local_init_lock); + if (!is_obproxy_inited) { + static const int DEFAULT_MMAP_MAX_VAL = 1024 * 1024 * 1024; // 1G + mallopt(M_MMAP_MAX, DEFAULT_MMAP_MAX_VAL); + mallopt(M_ARENA_MAX, 1); // disable malloc multiple arena pool + + setlocale(LC_ALL, ""); + + // turn warn log on so that there's a obproxy.log.wf file which records + // all WARN and ERROR logs in log directory. + ObWarningBuffer::set_warn_log_on(true); + // DISABLE_DIA(); disable di_cache stat + + g_run_mode = RUN_MODE_CLIENT; + int argc = 0; + char argv[10][4096]; + memset(argv, 0, sizeof(argv)); + MEMCPY(argv[0], "./bin/obproxy", strlen("./bin/obproxy")); + argc++; + if (!config.empty()) { + Parser parser; + json::Value *json_value = NULL; + ObArenaAllocator json_allocator(ObModIds::OB_JSON_PARSER); + if (OB_FAIL(parser.init(&json_allocator))) { + MPRINT("json parser init failed, ret =%d", ret); + } else if (OB_FAIL(parser.parse(config.ptr(), config.length(), json_value))) { + MPRINT("json parse failed, ret =%d", ret); + } else if (OB_FAIL(ObProxyJsonUtils::check_config_info_type(json_value, json::JT_OBJECT))) { + MPRINT("check config info type failed, ret=%d", ret); + } else { + DLIST_FOREACH(p, json_value->get_object()) { + if (0 == p->name_.case_compare("proxy_config")) { + if (OB_FAIL(ObProxyJsonUtils::check_config_info_type(p->value_, json::JT_STRING))) { + MPRINT("check config info type failed, ret=%d", ret); + } else { + MEMCPY(argv[argc++], "-o", strlen("-o")); + MEMCPY(argv[argc++], p->value_->get_string().ptr(), p->value_->get_string().length()); + } + } + } + } + } + + if (OB_SUCC(ret)) { + char *tmp_argv[10]; + for (int i = 0; i < argc; i++) { + tmp_argv[i] = argv[i]; + } + ObProxyMain *proxy_main = ObProxyMain::get_instance(); + if (OB_ISNULL(proxy_main)) { + ret = OB_ERR_UNEXPECTED; + MPRINT("fail to get obproxy main instance, ret=%d", ret); + } else if (OB_FAIL(proxy_main->start(argc, tmp_argv))) { + MPRINT("fail to start obproxy, ret=%d", ret); + } else { + is_obproxy_inited = true; + atexit(destroy_obproxy_client); + } + } + } + } + + return ret; +} + +void destroy_obproxy_client() +{ + ObProxyMain *proxy_main = ObProxyMain::get_instance(); + if (OB_NOT_NULL(proxy_main)) { + proxy_main->destroy(); + } +} + +} +} + diff --git a/src/obproxy/ob_proxy_init.h b/src/obproxy/ob_proxy_init.h new file mode 100644 index 000000000..4c76fc2b4 --- /dev/null +++ b/src/obproxy/ob_proxy_init.h @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + * + * ************************************************************* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OBPROXY_INIT_H_ +#define OBPROXY_INIT_H_ + +namespace oceanbase +{ +namespace common +{ +class ObString; +} +namespace obproxy +{ +enum OBPROXY_RUN_MODE { + RUN_MODE_PROXY, + RUN_MODE_CLIENT, + RUN_MODE_INVALID, +}; + +extern OBPROXY_RUN_MODE g_run_mode; + +int init_obproxy_client(const common::ObString& config); + +void destroy_obproxy_client(); + +} // end of obproxy +} // end of oceanbase + + +#endif diff --git a/src/obproxy/ob_proxy_main.cpp b/src/obproxy/ob_proxy_main.cpp index 9a38e14c1..3a5161b37 100644 --- a/src/obproxy/ob_proxy_main.cpp +++ b/src/obproxy/ob_proxy_main.cpp @@ -28,6 +28,7 @@ #include "obutils/ob_async_common_task.h" #include "cmd/ob_show_sqlaudit_handler.h" +#include "ob_proxy_init.h" using namespace oceanbase::common; using namespace oceanbase::lib; @@ -400,6 +401,8 @@ int ObProxyMain::get_log_file_name(const ObLogFDType type, char *file_name, cons ret_len = snprintf(log_file_name, OB_MAX_LOG_FILE_NAME_LEN, "obproxy_pool_stat.log"); } else if (FD_TRACE_FILE == type) { ret_len = snprintf(log_file_name, OB_MAX_LOG_FILE_NAME_LEN, "obproxy_trace.log"); + } else if (FD_DRIVER_CLIENT_FILE == type) { + ret_len = snprintf(log_file_name, OB_MAX_LOG_FILE_NAME_LEN, "obproxy_client.log"); } else { ret_len = snprintf(log_file_name, OB_MAX_LOG_FILE_NAME_LEN, "obproxy.log"); } @@ -436,7 +439,7 @@ int ObProxyMain::start(const int argc, char *const argv[]) ObProxyOptions opts; memset(&opts, 0, sizeof(opts)); - if (OB_FAIL(print_args(argc, argv))) { + if (RUN_MODE_PROXY == g_run_mode && OB_FAIL(print_args(argc, argv))) { MPRINT("fail to print args, ret=%d", ret); } else if (OB_FAIL(parse_cmd_line(argc, argv, opts))) { if (OB_NOT_RUNNING != ret) { @@ -448,7 +451,7 @@ int ObProxyMain::start(const int argc, char *const argv[]) const ObHotUpgraderInfo &info = get_global_hot_upgrade_info(); // if inherited, don not use daemon - if (OB_SUCC(ret)) { + if (RUN_MODE_PROXY == g_run_mode && OB_SUCC(ret)) { if (!opts.nodaemon_ && !info.is_inherited_) { if (OB_FAIL(use_daemon())) { MPRINT("fail to use deamon, ret=%d", ret); @@ -456,16 +459,16 @@ int ObProxyMain::start(const int argc, char *const argv[]) } } - if (OB_SUCC(ret)) { + if (RUN_MODE_PROXY == g_run_mode && OB_SUCC(ret)) { if (info.is_inherited_) { - if (OB_FAIL(close_all_fd(info.fd_))) { + if (OB_FAIL(close_all_fd(info.ipv4_fd_, info.ipv6_fd_))) { MPRINT("fail to close all fd, ret=%d", ret); } } } if (OB_SUCC(ret)) { - if (OB_FAIL(get_global_layout().init(info.argv_[0]))) { + if (OB_FAIL(get_global_layout().init(argv[0]))) { MPRINT("fail to init global layout, ret=%d", ret); } else if (OB_FAIL(init_log())) { MPRINT("fail to init log, ret=%d", ret); @@ -477,7 +480,8 @@ int ObProxyMain::start(const int argc, char *const argv[]) app_info_.setup(PACKAGE_STRING, APP_NAME, RELEASEID); _LOG_INFO("%s-%s", app_info_.full_version_info_str_, build_version()); if (info.is_inherited_) { - LOG_INFO("obproxy will start by hot upgrade", " listen fd", info.fd_, K(info)); + LOG_INFO("obproxy will start by hot upgrade", " listen ipv4 fd", info.ipv4_fd_, + "listen ipv6 fd", info.ipv6_fd_, K(info)); } else { LOG_INFO("has no inherited sockets, start new obproxy", K(info)); } @@ -495,18 +499,28 @@ int ObProxyMain::handle_inherited_sockets(const int argc, char *const argv[]) int ret = OB_SUCCESS; ObHotUpgraderInfo &info = get_global_hot_upgrade_info(); - if (OB_UNLIKELY(argc <= 0) || OB_ISNULL(argv) || OB_ISNULL(argv[0])) { + if (RUN_MODE_CLIENT == g_run_mode) { + // do nothing + } else if (OB_UNLIKELY(argc <= 0) || OB_ISNULL(argv) || OB_ISNULL(argv[0])) { ret = OB_INVALID_ARGUMENT; MPRINT("invalid argument, argc=%d, argv=%p, ret=%d", argc, argv, ret); } else { info.set_main_arg(argc, argv); - char *inherited = NULL; + char *inherited_ipv4 = NULL; + char *inherited_ipv6 = NULL; - if (NULL == (inherited = getenv(OBPROXY_INHERITED_FD))) { + inherited_ipv4 = getenv(OBPROXY_INHERITED_IPV4_FD); + inherited_ipv6 = getenv(OBPROXY_INHERITED_IPV6_FD); + if (NULL == inherited_ipv4 && NULL == inherited_ipv6) { // has no inherited sockets, will start new obproxy, // and set it HU_STATE_WAIT_HU_CMD state info.update_state(HU_STATE_WAIT_HU_CMD); info.is_parent_ = true; + } else if (NULL == inherited_ipv4) { + // Allow IPv6 to be empty + // because it may be a hot upgrade from a lower version to a higher version + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ipv4 should not be NULL", K(ret)); } else if (info.is_inherited_) { ret = OB_ERR_UNEXPECTED; MPRINT("hot upgrade info is_inherited can't be true, ret=%d", ret); @@ -514,11 +528,18 @@ int ObProxyMain::handle_inherited_sockets(const int argc, char *const argv[]) // obproxy will start by hot upgrade // we will set it HU_STATE_WAIT_CR_CMD state and HU_STATUS_NEW_PROXY_CREATED_SUCC status info.is_inherited_ = true; - info.fd_ = atoi(inherited); + info.ipv4_fd_ = atoi(inherited_ipv4); + + if (NULL != inherited_ipv6) { + info.ipv6_fd_ = atoi(inherited_ipv6); + } + info.update_state(HU_STATE_WAIT_HU_CMD); info.is_parent_ = false; - if (OB_FAIL(unsetenv(OBPROXY_INHERITED_FD))) { - MPRINT("fail to unsetenv OBPROXY_INHERITED_FD, ret=%d", ret); + if (OB_FAIL(unsetenv(OBPROXY_INHERITED_IPV4_FD))) { + MPRINT("fail to unsetenv OBPROXY_INHERITED_IPV4_FD, ret=%d", ret); + } else if (OB_FAIL(unsetenv(OBPROXY_INHERITED_IPV6_FD))) { + MPRINT("fail to unsetenv OBPROXY_INHERITED_IPV6_FD, ret=%d", ret); } } } @@ -536,7 +557,13 @@ int ObProxyMain::init_log() LOG_ERROR("fail to get log file name", K(type), K(ret)); } else { if (FD_DEFAULT_FILE == type) { - OB_LOGGER.set_file_name(type, log_file_name, true, true); + if (RUN_MODE_PROXY == g_run_mode) { + OB_LOGGER.set_file_name(type, log_file_name, true, true); + } else if (RUN_MODE_CLIENT == g_run_mode) { + OB_LOGGER.set_file_name(type, log_file_name, false, true); + } else { + MPRINT("invalid g_run_mode, mode=%d", g_run_mode); + } } else { OB_LOGGER.set_file_name(type, log_file_name); } @@ -578,6 +605,8 @@ int ObProxyMain::init_signal() LOG_WARN("fail to add_sig_direct_catched", K(ret)); } else if (OB_FAIL(add_sig_direct_catched(action, SIGUSR1))) { LOG_WARN("fail to add_sig_direct_catched", K(ret)); + } else if (OB_FAIL(add_sig_direct_catched(action, SIGUSR2))) { + LOG_WARN("fail to add_sig_direct_catched", K(ret)); } else if (OB_FAIL(add_sig_direct_catched(action, 43))) { LOG_WARN("fail to add_sig_direct_catched", K(ret)); @@ -738,16 +767,17 @@ int ObProxyMain::do_detect_sig() // -1 : wait for any sub process while((pid = waitpid(-1, &stat, WNOHANG)) > 0) { LOG_INFO("sub process exit", K(info), K(pid), "status", stat, KERRMSGS); - if (info.sub_pid_ == pid) { - info.reset_sub_pid(); - // after sub was exited, we need passing this status - if (OB_LIKELY(common::OB_SUCCESS == lib::mutex_acquire(&info.hot_upgrade_mutex_))) { + if (OB_LIKELY(common::OB_SUCCESS == lib::mutex_acquire(&info.hot_upgrade_mutex_))) { + if (info.sub_pid_ == pid) { + info.reset_sub_pid(); + // after sub was exited, we need passing this status info.update_sub_status(HU_STATUS_EXITED); info.parent_hot_upgrade_flag_ = false; lib::mutex_release(&info.hot_upgrade_mutex_); + } else { + LOG_WARN("sub process exit, but recv it late"); } - } else { - LOG_WARN("sub process exit, but recv it late"); + lib::mutex_release(&info.hot_upgrade_mutex_); } } break; @@ -826,6 +856,17 @@ void ObProxyMain::sig_direct_handler(const int sig) } break; } + case SIGUSR2: { + ObHotUpgraderInfo &info = get_global_hot_upgrade_info(); + if (OB_LIKELY(common::OB_SUCCESS == lib::mutex_acquire(&info.hot_upgrade_mutex_))) { + // If the SIGUSR2 signal is received, + // the child process is considered to exit normally, + // and the child process is ignored + info.reset_sub_pid(); + lib::mutex_release(&info.hot_upgrade_mutex_); + } + break; + } case SIGTERM: case SIGINT: { ObHotUpgraderInfo &info = get_global_hot_upgrade_info(); @@ -945,7 +986,7 @@ int ObProxyMain::do_monitor_mem() } } - if (is_out_of_mem_limit) { + if (is_out_of_mem_limit && RUN_MODE_PROXY == g_run_mode) { LOG_ERROR("obproxy's memroy is out of limit, will be going to commit suicide", K(mem_limited), "OTHER_MEMORY_SIZE", static_cast(OTHER_MEMORY_SIZE), K(is_out_of_mem_limit), K(cur_pos)); @@ -1033,7 +1074,7 @@ int ObProxyMain::do_detect_sqlaudit() return ret; } -int ObProxyMain::close_all_fd(const int32_t listen_fd) +int ObProxyMain::close_all_fd(const int32_t listen_ipv4_fd, const int32_t listen_ipv6_fd) { //this func can't print log, because log isn't initialized int ret = OB_SUCCESS; @@ -1042,7 +1083,7 @@ int ObProxyMain::close_all_fd(const int32_t listen_fd) DIR *fd_dir = NULL; char fd_dir_path [OB_MAX_FILE_NAME_LENGTH]; - if (OB_UNLIKELY(listen_fd < 3)) { + if (OB_UNLIKELY(listen_ipv4_fd < 3 && listen_ipv6_fd < 3)) { ret = OB_INVALID_ARGUMENT; } else { int n = snprintf(fd_dir_path, OB_MAX_FILE_NAME_LENGTH, "/proc/%d/fd", pid); @@ -1062,7 +1103,8 @@ int ObProxyMain::close_all_fd(const int32_t listen_fd) fd = static_cast(strtol(de->d_name, NULL, 10)); if (fd < 0) { continue; - } else if (fd < 3 || fd == dirfd(fd_dir) || fd == listen_fd) { + } else if (fd < 3 || fd == dirfd(fd_dir) || fd == listen_ipv4_fd + || fd == listen_ipv6_fd) { continue; } else { if (OB_UNLIKELY(0 != close(fd))) { diff --git a/src/obproxy/ob_proxy_main.h b/src/obproxy/ob_proxy_main.h index e29857810..35a5d8a44 100644 --- a/src/obproxy/ob_proxy_main.h +++ b/src/obproxy/ob_proxy_main.h @@ -86,7 +86,7 @@ class ObProxyMain int init_log(); int init_signal(); - int close_all_fd(const int32_t listen_fd); + int close_all_fd(const int32_t listen_ipv4_fd, const int32_t listen_ipv6_fd); class ObLogLevel { diff --git a/src/obproxy/obutils/ob_async_common_task.cpp b/src/obproxy/obutils/ob_async_common_task.cpp index 501541f0a..cb05e6f1e 100644 --- a/src/obproxy/obutils/ob_async_common_task.cpp +++ b/src/obproxy/obutils/ob_async_common_task.cpp @@ -117,7 +117,7 @@ int ObAsyncCommonTask::main_handler(int event, void *data) return EVENT_DONE; } -inline int ObAsyncCommonTask::handle_event_start() +int ObAsyncCommonTask::handle_event_start() { int ret = OB_SUCCESS; if (action_.cancelled_) { @@ -134,7 +134,7 @@ inline int ObAsyncCommonTask::handle_event_start() return ret; } -inline int ObAsyncCommonTask::handle_event_complete(void *data) +int ObAsyncCommonTask::handle_event_complete(void *data) { int ret = OB_SUCCESS; if (action_.cancelled_) { diff --git a/src/obproxy/obutils/ob_config_processor.cpp b/src/obproxy/obutils/ob_config_processor.cpp index 08ae8b379..19dd90043 100644 --- a/src/obproxy/obutils/ob_config_processor.cpp +++ b/src/obproxy/obutils/ob_config_processor.cpp @@ -60,7 +60,7 @@ namespace obutils //the table name need to be lower case, or func'handle_dml_stmt' will get error #define MAX_INIT_SQL_LEN 1024 -static const char* sqlite3_db_name = "etc/proxyconfig.db"; +static const char* sqlite3_db_name = "proxyconfig.db"; static const char* all_table_version_table_name = "all_table_version"; static const char* white_list_table_name = "white_list"; static const char* resource_unit_table_name = "resource_unit"; @@ -124,12 +124,28 @@ ObConfigProcessor::~ObConfigProcessor() int ObConfigProcessor::init() { int ret = OB_SUCCESS; + const char *dir = NULL; if (OB_FAIL(table_handler_map_.create(32, ObModIds::OB_HASH_BUCKET))) { LOG_WARN("create hash map failed", K(ret)); - } else if (SQLITE_OK != sqlite3_open_v2( - sqlite3_db_name, &proxy_config_db_, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL)) { + } else if (OB_ISNULL(dir = get_global_layout().get_etc_dir())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("sqlite3 open failed", K(ret), "err_msg", sqlite3_errmsg(proxy_config_db_)); + LOG_WARN("get etc dir failed", K(ret)); + } else { + char *path = NULL; + ObFixedArenaAllocator allocator; + if (OB_FAIL(ObLayout::merge_file_path(dir, sqlite3_db_name, allocator, path))) { + LOG_WARN("fail to merge file path", K(sqlite3_db_name), K(ret)); + } else if (OB_ISNULL(path)) { + ret = OB_ERR_UNEXPECTED; + } else if (SQLITE_OK != sqlite3_open_v2( + path, &proxy_config_db_, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sqlite3 open failed", K(ret), "path", path, "err_msg", sqlite3_errmsg(proxy_config_db_)); + } + } + + if (OB_FAIL(ret)) { + // do nothing } else if (OB_FAIL(check_and_create_table())) { LOG_WARN("check create table failed", K(ret)); } else { @@ -175,14 +191,20 @@ int ObConfigProcessor::init_callback(void *data, int argc, char **argv, char **c if (NULL == argv[i]) { continue; } else { - SqlField sql_field; - sql_field.column_name_.set_string(column_name[i], static_cast(strlen(column_name[i]))); - sql_field.value_type_ = TOKEN_STR_VAL; - sql_field.column_value_.set_value(static_cast(strlen(argv[i])), argv[i]); - if (OB_FAIL(field_result.fields_.push_back(sql_field))) { - LOG_WARN("push back failed", K(ret)); + SqlField *sql_field = NULL; + if (OB_FAIL(SqlField::alloc_sql_field(sql_field))) { + LOG_WARN("fail to alloc sql field", K(ret)); } else { - field_result.field_num_++; + sql_field->column_name_.set_value(static_cast(strlen(column_name[i])), column_name[i]); + sql_field->value_type_ = TOKEN_STR_VAL; + sql_field->column_value_.set_value(static_cast(strlen(argv[i])), argv[i]); + if (OB_FAIL(field_result.fields_.push_back(sql_field))) { + sql_field->reset(); + sql_field = NULL; + LOG_WARN("push back failed", K(ret)); + } else { + field_result.field_num_++; + } } } } @@ -192,11 +214,11 @@ int ObConfigProcessor::init_callback(void *data, int argc, char **argv, char **c const char* cluster_name_str = "cluster_name"; const char* tenant_name_str = "tenant_name"; for (int64_t i = 0; i < field_result.field_num_; i++) { - SqlField &field = field_result.fields_.at(i); - if (field.column_name_.string_ == cluster_name_str) { - params.cluster_name_ = field.column_value_.config_string_; - } else if (field.column_name_.string_ == tenant_name_str) { - params.tenant_name_ = field.column_value_.config_string_; + SqlField* field = field_result.fields_.at(i); + if (field->column_name_.config_string_ == cluster_name_str) { + params.cluster_name_ = field->column_value_.config_string_; + } else if (field->column_name_.config_string_ == tenant_name_str) { + params.tenant_name_ = field->column_value_.config_string_; } } @@ -370,11 +392,11 @@ int ObConfigProcessor::handle_dml_stmt(ObString &sql, ParseResult& parse_result, const char* cluster_name_str = "cluster_name"; const char* tenant_name_str = "tenant_name"; for (int64_t i = 0; i < params.fields_->field_num_; i++) { - SqlField &field = params.fields_->fields_.at(i); - if (field.column_name_.string_ == cluster_name_str) { - params.cluster_name_ = field.column_value_.config_string_; - } else if (field.column_name_.string_ == tenant_name_str) { - params.tenant_name_ = field.column_value_.config_string_; + SqlField* field = params.fields_->fields_.at(i); + if (field->column_name_.config_string_ == cluster_name_str) { + params.cluster_name_ = field->column_value_.config_string_; + } else if (field->column_name_.config_string_ == tenant_name_str) { + params.tenant_name_ = field->column_value_.config_string_; } } //table name is UPPER CASE in stmt, need convert to lower case as origin @@ -404,12 +426,31 @@ int ObConfigProcessor::handle_dml_stmt(ObString &sql, ParseResult& parse_result, } else { memcpy(sql_buf, sql.ptr(), sql.length()); sql_buf[sql.length()] = '\0'; - if (SQLITE_OK != sqlite3_exec(proxy_config_db_, sql_buf, NULL, 0, &err_msg)) { + if (SQLITE_OK != sqlite3_exec(proxy_config_db_, "begin;", NULL, 0, &err_msg)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sqlite3 exec failed", K(sql), "err_msg", err_msg); + sqlite3_free(err_msg); + } + + if (OB_SUCC(ret) && SQLITE_OK != sqlite3_exec(proxy_config_db_, sql_buf, NULL, 0, &err_msg)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("sqlite3 exec failed", K(sql), "err_msg", err_msg); sqlite3_free(err_msg); } ob_free(sql_buf); + + if (OB_SUCC(ret) && NULL != handler.before_commit_func_) { + if (OB_FAIL(handler.before_commit_func_(proxy_config_db_))) { + LOG_WARN("before commit func failed", K_(params.table_name), K(ret)); + } + } + + const char *end_sql = OB_SUCCESS == ret ? "commit;" : "rollback;"; + if (SQLITE_OK != sqlite3_exec(proxy_config_db_, end_sql, NULL, 0, &err_msg)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sqlite3 exec failed", K(sql), "err_msg", err_msg); + sqlite3_free(err_msg); + } } tmp_ret = ret; } @@ -523,6 +564,18 @@ bool ObConfigProcessor::is_table_in_service(const ObString &table_name) return is_in_service; } +int ObConfigProcessor::execute(const char* sql, int (*callback)(void*, int, char**, char**), void* handler) +{ + int ret = OB_SUCCESS; + char *err_msg = NULL; + if (SQLITE_OK != sqlite3_exec(proxy_config_db_, sql, callback, handler, &err_msg)) { + ret = OB_ERR_UNEXPECTED; + WARN_ICMD("exec sql failed", K(ret), "err_msg", err_msg); + sqlite3_free(err_msg); + } + return ret; +} + int ObConfigProcessor::store_global_ssl_config(const ObString &name, const ObString &value) { int ret = OB_SUCCESS; @@ -559,27 +612,42 @@ int ObConfigProcessor::store_global_ssl_config(const ObString &name, const ObStr return ret; } -int ObConfigProcessor::store_global_proxy_config(const ObString &name, const ObString &value) +int ObConfigProcessor::store_proxy_config_with_level(int64_t vid, const ObString &vip, int64_t vport, + const ObString &tenant_name, const ObString &cluster_name, + const ObString &name, const ObString& value, const ObString &level) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(name.empty())) { + if (OB_UNLIKELY(name.empty() || level.empty())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(name), K(value)); + LOG_WARN("invalid argument", K(name), K(level)); } else { - const char *sql = "replace into proxy_config(name, value, config_level) values('%.*s', '%.*s', 'LEVEL_GLOBAL')"; - int64_t buf_len = name.length() + value.length() + strlen(sql); + const char *sql = + "replace into proxy_config(vid, vip, vport, cluster_name, tenant_name, name, value, config_level) " + "values(%ld, '%.*s', %ld, '%.*s', '%.*s', '%.*s', '%.*s', '%.*s')"; + char vid_buf[64]; + char vport_buf[64]; + int32_t vid_len = snprintf(vid_buf, sizeof(vid_buf), "%ld", vid); + int32_t vport_len = snprintf(vport_buf, sizeof(vport_buf), "%ld", vport); + int64_t buf_len = vid_len + vport_len + vip.length() + tenant_name.length() + cluster_name.length() + name.length() + value.length() + level.length() + strlen(sql); char *sql_buf = (char*)ob_malloc(buf_len + 1, ObModIds::OB_PROXY_CONFIG_TABLE); if (OB_ISNULL(sql_buf)) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("allocate memory failed", K(ret), K(buf_len)); } else { ObString sql_string; - int64_t len = 0; + int32_t len = 0; get_global_proxy_config_table_processor().set_need_sync_to_file(false); - len = static_cast(snprintf(sql_buf, buf_len, sql, + len = static_cast(snprintf(sql_buf, buf_len, sql, + vid, + vip.length(), vip.ptr(), + vport, + cluster_name.length(), cluster_name.ptr(), + tenant_name.length(), tenant_name.ptr(), name.length(), name.ptr(), - value.length(), value.ptr())); - sql_string.assign_ptr(sql_buf, static_cast(len)); + value.length(), value.ptr(), + level.length(), level.ptr())); + sql_string.assign_ptr(sql_buf, len); + LOG_DEBUG("execute sql", K(sql_string)); if (OB_UNLIKELY(len <= 0)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to fill sql", K(len), K(ret)); @@ -597,6 +665,15 @@ int ObConfigProcessor::store_global_proxy_config(const ObString &name, const ObS return ret; } +int ObConfigProcessor::store_global_proxy_config(const ObString &name, const ObString &value) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(store_proxy_config_with_level(-1, "", 0, "", "", name, value, "LEVEL_GLOBAL"))) { + LOG_WARN("store_proxy_config_with_level failed", K(ret)); + } + return ret; +} + int ObConfigProcessor::get_proxy_config_with_level(const ObVipAddr &addr, const common::ObString &cluster_name, const common::ObString &tenant_name, const common::ObString& name, common::ObConfigItem &ret_item, const ObString level, bool &found) @@ -612,7 +689,7 @@ int ObConfigProcessor::get_proxy_config_with_level(const ObVipAddr &addr, const } } else if (0 != strcasecmp(proxy_item.config_level_.ptr(), level.ptr())) { ret = OB_SUCCESS; - LOG_DEBUG("vip config level not match", K(proxy_item)); + LOG_TRACE("vip config level not match", K(proxy_item), K(level)); } else { found = true; ret_item = proxy_item.config_item_; @@ -675,6 +752,22 @@ int ObConfigProcessor::get_proxy_config_bool_item(const ObVipAddr &addr, const O return ret; } +int ObConfigProcessor::get_proxy_config_int_item(const ObVipAddr &addr, const ObString &cluster_name, + const ObString &tenant_name, const ObString& name, + ObConfigIntItem &ret_item) +{ + int ret = OB_SUCCESS; + ObConfigItem item; + if (OB_FAIL(get_proxy_config(addr, cluster_name, tenant_name, name, item))) { + LOG_WARN("get proxy config failed", K(addr), K(cluster_name), K(tenant_name), K(name), K(ret)); + } else { + ret_item.set(item.str()); + LOG_DEBUG("get int item succ", K(ret_item)); + } + + return ret; +} + } // end of obutils } // end of obproxy } // end of oceanbase diff --git a/src/obproxy/obutils/ob_config_processor.h b/src/obproxy/obutils/ob_config_processor.h index ef0224e9b..156789a80 100644 --- a/src/obproxy/obutils/ob_config_processor.h +++ b/src/obproxy/obutils/ob_config_processor.h @@ -54,11 +54,14 @@ struct ObVipAddr; typedef int (*config_processor_execute) (void *); typedef int (*config_processor_commit) (void*, bool is_success); +typedef int (*config_processor_before_commit) (void *); struct ObConfigHandler { + ObConfigHandler() : execute_func_(NULL), commit_func_(NULL), before_commit_func_(NULL) {} config_processor_execute execute_func_; config_processor_commit commit_func_; + config_processor_before_commit before_commit_func_; }; typedef common::hash::ObHashMap, ObConfigHandler> ConfigHandlerHashMap; @@ -98,6 +101,11 @@ class ObConfigProcessor bool is_table_in_service(const common::ObString &table_name); int store_global_ssl_config(const common::ObString& name, const common::ObString &value); int store_global_proxy_config(const common::ObString &name, const common::ObString &value); + int store_vip_tenant_cluster_config(int64_t vid, const ObString &vip, int64_t vport, + const ObString &name, const ObString &value); + int store_proxy_config_with_level(int64_t vid, const ObString &vip, int64_t vport, + const ObString &cluster_name, const ObString &tenant_name, + const ObString &name, const ObString &value, const ObString &level); int get_proxy_config(const ObVipAddr &addr, const common::ObString &cluster_name, const common::ObString &tenant_name, const common::ObString& name, @@ -105,15 +113,19 @@ class ObConfigProcessor int get_proxy_config_bool_item(const ObVipAddr &addr, const common::ObString &cluster_name, const common::ObString &tenant_name, const common::ObString& name, common::ObConfigBoolItem &ret_item); + int get_proxy_config_int_item(const ObVipAddr &addr, const common::ObString &cluster_name, + const common::ObString &tenant_name, const common::ObString& name, + common::ObConfigIntItem &ret_item); + int get_proxy_config_with_level(const ObVipAddr &addr, const common::ObString &cluster_name, + const common::ObString &tenant_name, const common::ObString& name, + common::ObConfigItem &ret_item, const ObString level, bool &found); + int execute(const char* sql, int (*callback)(void*, int, char**, char**), void* handler); private: int init_config_from_disk(); int check_and_create_table(); int handle_dml_stmt(common::ObString &sql, ParseResult& parse_result, ObArenaAllocator&allocator); int handle_select_stmt(common::ObString &sql, obproxy::ObConfigV2Handler *v2_handler); - int get_proxy_config_with_level(const ObVipAddr &addr, const common::ObString &cluster_name, - const common::ObString &tenant_name, const common::ObString& name, - common::ObConfigItem &ret_item, const ObString level, bool &found); static int init_callback(void *data, int argc, char **argv, char **column_name); static int sqlite3_callback(void *data, int argc, char **argv, char **column_name); diff --git a/src/obproxy/obutils/ob_congestion_entry.cpp b/src/obproxy/obutils/ob_congestion_entry.cpp index 54859addd..ec3cbf7b6 100644 --- a/src/obproxy/obutils/ob_congestion_entry.cpp +++ b/src/obproxy/obutils/ob_congestion_entry.cpp @@ -91,6 +91,7 @@ ObCongestionEntry::ObCongestionEntry(const ObIpEndpoint &ip) last_dead_congested_(0), dead_congested_(0), last_alive_congested_(0),alive_congested_(0), last_detect_congested_(0), detect_congested_(0), + last_client_feedback_congested_(0), stat_client_feedback_failures_(0), client_feedback_congested_(0), stat_conn_failures_(0), stat_alive_failures_(0), last_revalidate_time_us_(0), cr_version_(-1) { @@ -380,7 +381,7 @@ void ObCongestionEntry::set_alive_failed_at(const ObHRTime t) (void)ATOMIC_FAA(&stat_alive_failures_, 1); if (control_config_->alive_failure_threshold_ >= 0) { int64_t time = hrtime_to_sec(t); - LOG_INFO("alive failed at", K(t)); + LOG_INFO("alive failed at", K(t), KPC(this)); MUTEX_TRY_LOCK(lock, fail_hist_lock_, this_ethread()); if (lock.is_locked()) { alive_fail_history_.regist_event(time); @@ -390,7 +391,32 @@ void ObCongestionEntry::set_alive_failed_at(const ObHRTime t) if (new_congested && !ATOMIC_TAS(&alive_congested_, 1)) { last_alive_congested_ = alive_fail_history_.last_event_; // action congested ? - LOG_INFO("set_alive_congested", KPC(this)); + LOG_INFO("set alive congested", KPC(this)); + } + } + } else { + LOG_DEBUG("failure info lost due to lock contention", + KPC(this), K(time)); + } + } +} + +void ObCongestionEntry::set_client_feedback_failed_at(const ObHRTime t) +{ + (void)ATOMIC_FAA(&stat_client_feedback_failures_, 1); + if (control_config_->alive_failure_threshold_ >= 0) { + int64_t time = hrtime_to_sec(t); + LOG_INFO("client feedback failed at", K(t)); + MUTEX_TRY_LOCK(lock, fail_hist_lock_, this_ethread()); + if (lock.is_locked()) { + client_feedback_fail_history_.regist_event(time); + if (!client_feedback_congested_) { + bool new_congested = check_client_feedback_congested(); + // TODO: This used to signal via SNMP + if (new_congested && !ATOMIC_TAS(&client_feedback_congested_, 1)) { + last_client_feedback_congested_ = client_feedback_fail_history_.last_event_; + // action congested ? + LOG_INFO("set_client_feedback_congested", KPC(this)); } } } else { @@ -435,7 +461,7 @@ void ObCongestionEntry::set_alive_congested() // action congested ? } else { last_alive_congested_ = ObTimeUtility::extract_second(ObTimeUtility::current_time()); - LOG_INFO("set_alive_congested", KPC(this)); + LOG_INFO("set alive congested", KPC(this)); } } @@ -473,7 +499,6 @@ void ObCongestionEntry::set_detect_congested() } else { last_detect_congested_ = ObTimeUtility::extract_second(ObTimeUtility::current_time()); LOG_INFO("set detect congested", KPC(this)); - get_global_resource_pool_processor().ip_set_.set_refactored(server_ip_); } } @@ -483,7 +508,6 @@ void ObCongestionEntry::set_detect_congested_free() // action not congested ? LOG_INFO("set detect congested free", KPC(this)); } - get_global_resource_pool_processor().ip_set_.erase_refactored(server_ip_); } diff --git a/src/obproxy/obutils/ob_congestion_entry.h b/src/obproxy/obutils/ob_congestion_entry.h index d0c4c82e6..0c9f04f1a 100644 --- a/src/obproxy/obutils/ob_congestion_entry.h +++ b/src/obproxy/obutils/ob_congestion_entry.h @@ -290,6 +290,7 @@ struct ObCongestionEntry : public ObCongestionRefCnt void set_detect_congested_free(); void set_dead_failed_at(const ObHRTime t); void set_alive_failed_at(const ObHRTime t); + void set_client_feedback_failed_at(const ObHRTime t); // Connection controls bool alive_need_retry(const ObHRTime t); @@ -300,6 +301,7 @@ struct ObCongestionEntry : public ObCongestionRefCnt void reset_fail_history(); bool check_dead_congested(); bool check_alive_congested(); + bool check_client_feedback_congested(); // ObCongestionEntry and ObCongestionControl config interaction helper functions int validate_config(ObCongestionControlConfig *config); @@ -338,6 +340,11 @@ struct ObCongestionEntry : public ObCongestionRefCnt ObHRTime last_detect_congested_; volatile int64_t detect_congested_; + ObFailHistory client_feedback_fail_history_; + ObHRTime last_client_feedback_congested_; + volatile int64_t stat_client_feedback_failures_; + int64_t client_feedback_congested_; + volatile int64_t stat_conn_failures_; volatile int64_t stat_alive_failures_; int64_t last_revalidate_time_us_; // unit us @@ -437,12 +444,27 @@ inline bool ObCongestionEntry::check_alive_congested() return bret; } +inline bool ObCongestionEntry::check_client_feedback_congested() +{ + bool bret = false; + if (1 == client_feedback_congested_) { + bret = true; + } else if (control_config_->alive_failure_threshold_ < 0) { + bret = false; + } else { + bret = control_config_->alive_failure_threshold_ <= client_feedback_fail_history_.events_; + } + + return bret; +} + inline void ObCongestionEntry::reset_fail_history() { conn_fail_history_.init(control_config_->fail_window_sec_); dead_congested_ = 0; alive_fail_history_.init(control_config_->fail_window_sec_); alive_congested_ = 0; + client_feedback_fail_history_.init(control_config_->fail_window_sec_); } void ObCongestionEntry::free() diff --git a/src/obproxy/obutils/ob_congestion_manager.cpp b/src/obproxy/obutils/ob_congestion_manager.cpp index 3d18b4c21..1be3253b9 100644 --- a/src/obproxy/obutils/ob_congestion_manager.cpp +++ b/src/obproxy/obutils/ob_congestion_manager.cpp @@ -382,6 +382,7 @@ int ObCongestionManager::add_new_server(const net::ObIpEndpoint &ip, break; case ObCongestionEntry::DETECT_ALIVE: entry->set_detect_congested_free(); + entry->set_alive_congested_free(); break; case ObCongestionEntry::DETECT_DEAD: entry->set_detect_congested(); @@ -607,6 +608,7 @@ int ObCongestionManager::process(const int64_t buck_id, ObCongestRequestParam *p break; case ObCongestionEntry::DETECT_ALIVE: entry->set_detect_congested_free(); + entry->set_alive_congested_free(); break; case ObCongestionEntry::DETECT_DEAD: entry->set_detect_congested(); @@ -985,6 +987,7 @@ int ObCongestionManager::revalidate_server(const ObIpEndpoint &ip, break; case ObCongestionEntry::DETECT_ALIVE: entry->set_detect_congested_free(); + entry->set_alive_congested_free(); break; case ObCongestionEntry::DETECT_DEAD: entry->set_detect_congested(); @@ -1014,7 +1017,7 @@ int ObCongestionManager::revalidate_server(const ObIpEndpoint &ip, } } else { LOG_DEBUG("failed to lock_bucket, add to todo_list", "server_state", - ObCongestionEntry::get_server_state_name(server_state), K(*entry)); + ObCongestionEntry::get_server_state_name(server_state)); ObCongestRequestParam *param = op_alloc(ObCongestRequestParam); if (OB_ISNULL(param)) { ret = OB_ALLOCATE_MEMORY_FAILED; diff --git a/src/obproxy/obutils/ob_hot_upgrade_processor.cpp b/src/obproxy/obutils/ob_hot_upgrade_processor.cpp index 5ddfbc27d..bedfce3e1 100644 --- a/src/obproxy/obutils/ob_hot_upgrade_processor.cpp +++ b/src/obproxy/obutils/ob_hot_upgrade_processor.cpp @@ -110,7 +110,7 @@ int ObProxyHotUpgrader::get_envp(char **&envp) { static const int64_t OBPROXY_ENVP_MAX_SIZE = 128; int ret = OB_SUCCESS; - int64_t count = 1; // envp's valid items count + int64_t count = 2; // envp's valid items count bool is_obproxy_root_set = false; char *obproxy_root = NULL; if (NULL != (obproxy_root = getenv("OBPROXY_ROOT"))) { @@ -128,7 +128,8 @@ int ObProxyHotUpgrader::get_envp(char **&envp) memset(var, 0, size); envp = reinterpret_cast(var); envp[0] = reinterpret_cast(malloc(OBPROXY_ENVP_MAX_SIZE)); - if (OB_ISNULL(envp[0])) { + envp[1] = reinterpret_cast(malloc(OBPROXY_ENVP_MAX_SIZE)); + if (OB_ISNULL(envp[0]) || OB_ISNULL(envp[1])) { ret = OB_ALLOCATE_MEMORY_FAILED; free(var); var = NULL; @@ -137,16 +138,23 @@ int ObProxyHotUpgrader::get_envp(char **&envp) } else { const ObHotUpgraderInfo &info = get_global_hot_upgrade_info(); int64_t length = snprintf(envp[0], static_cast(OBPROXY_ENVP_MAX_SIZE), - OBPROXY_INHERITED_FD"=%d", info.fd_); + OBPROXY_INHERITED_IPV4_FD"=%d", info.ipv4_fd_); if (OB_UNLIKELY(length <= 0) || OB_UNLIKELY(length >= OBPROXY_ENVP_MAX_SIZE)) { ret = OB_BUF_NOT_ENOUGH; LOG_WARN("buf not enought", K(length), "envp[0]_length", OBPROXY_ENVP_MAX_SIZE, K(envp[0]), K(ret)); + } else { + int64_t length = snprintf(envp[1], static_cast(OBPROXY_ENVP_MAX_SIZE), + OBPROXY_INHERITED_IPV6_FD"=%d", info.ipv6_fd_); + if (OB_UNLIKELY(length <= 0) || OB_UNLIKELY(length >= OBPROXY_ENVP_MAX_SIZE)) { + ret = OB_BUF_NOT_ENOUGH; + LOG_WARN("buf not enought", K(length), "envp[0]_length", OBPROXY_ENVP_MAX_SIZE, K(envp[1]), K(ret)); + } } } //set OBPROXY_ROOT if (OB_SUCC(ret) && is_obproxy_root_set) { - envp[1] = reinterpret_cast(malloc(OBPROXY_ENVP_MAX_SIZE)); - if (OB_ISNULL(envp[1])) { + envp[2] = reinterpret_cast(malloc(OBPROXY_ENVP_MAX_SIZE)); + if (OB_ISNULL(envp[2])) { ret = OB_ALLOCATE_MEMORY_FAILED; free(envp[0]); free(var); @@ -154,11 +162,11 @@ int ObProxyHotUpgrader::get_envp(char **&envp) envp = NULL; LOG_ERROR("fail to malloc", K(ret)); } else { - int64_t length = snprintf(envp[1], static_cast(OBPROXY_ENVP_MAX_SIZE), + int64_t length = snprintf(envp[2], static_cast(OBPROXY_ENVP_MAX_SIZE), "OBPROXY_ROOT=%s", obproxy_root); if (OB_UNLIKELY(length <= 0) || OB_UNLIKELY(length >= OBPROXY_ENVP_MAX_SIZE)) { ret = OB_BUF_NOT_ENOUGH; - LOG_WARN("buf not enought", K(length), "envp[1]_length", OBPROXY_ENVP_MAX_SIZE, K(envp[1]), K(ret)); + LOG_WARN("buf not enought", K(length), "envp[2]_length", OBPROXY_ENVP_MAX_SIZE, K(envp[2]), K(ret)); } } } @@ -1289,6 +1297,8 @@ int ObHotUpgradeProcessor::init_raw_client(ObRawMysqlClient &raw_client, const O char passwd_staged1_buf[ENC_STRING_BUF_LEN] = {0}; // 1B '*' + 40B octal num ObProxyLoginInfo login_info; int64_t pos = 0; + char cluster_name_buf[OB_PROXY_FULL_USER_NAME_MAX_LEN + 1]; + ObString cluster_name; switch (type) { case USER_TYPE_METADB: { @@ -1311,14 +1321,13 @@ int ObHotUpgradeProcessor::init_raw_client(ObRawMysqlClient &raw_client, const O break; } case USER_TYPE_PROXYRO: { - char cluster_name[OB_PROXY_FULL_USER_NAME_MAX_LEN + 1]; - cluster_name[0] = '\0'; - if (OB_FAIL(get_global_config_server_processor().get_default_cluster_name(cluster_name, OB_PROXY_FULL_USER_NAME_MAX_LEN + 1))) { + cluster_name_buf[0] = '\0'; + if (OB_FAIL(get_global_config_server_processor().get_default_cluster_name(cluster_name_buf, OB_PROXY_FULL_USER_NAME_MAX_LEN + 1))) { LOG_WARN("fail to get default cluster name", K(ret)); } else { - ObString default_cname = '\0' == cluster_name[0] + ObString default_cname = '\0' == cluster_name_buf[0] ? ObString::make_string(OB_PROXY_DEFAULT_CLUSTER_NAME) - : ObString::make_string(cluster_name); + : ObString::make_string(cluster_name_buf); if (OB_FAIL(databuff_printf(full_user_name, OB_PROXY_FULL_USER_NAME_MAX_LEN + 1, pos, "%s#%.*s", ObProxyTableInfo::READ_ONLY_USERNAME, default_cname.length(), default_cname.ptr()))) { LOG_WARN("fail to databuff_printf", "username", ObProxyTableInfo::READ_ONLY_USERNAME, K(default_cname), K(ret)); @@ -1330,6 +1339,7 @@ int ObHotUpgradeProcessor::init_raw_client(ObRawMysqlClient &raw_client, const O static_cast(strlen(get_global_proxy_config().observer_sys_password1.str()))); string_db.assign_ptr(ObProxyTableInfo::READ_ONLY_DATABASE, static_cast(STRLEN(ObProxyTableInfo::READ_ONLY_DATABASE))); + cluster_name.assign_ptr(cluster_name_buf, static_cast(strlen(cluster_name_buf))); } } break; @@ -1357,12 +1367,12 @@ int ObHotUpgradeProcessor::init_raw_client(ObRawMysqlClient &raw_client, const O if (OB_SUCC(ret)) { ObSEArray local_addrs; ObAddr addr; - if (OB_UNLIKELY(!addr.set_ipv4_addr(proxy_ip_, proxy_port_))) { + if (OB_UNLIKELY(!addr.set_ip_addr(proxy_ip_, proxy_port_))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to set addr", K(proxy_ip_), K(proxy_port_), K(ret)); } else if (OB_FAIL(local_addrs.push_back(addr))) { LOG_WARN("fail to push addr to local_addrs", K(addr), K(ret)); - } else if (OB_FAIL(raw_client.init(string_username, string_passwd, string_db, string_passwd1))) { + } else if (OB_FAIL(raw_client.init(string_username, string_passwd, string_db, cluster_name, string_passwd1))) { LOG_WARN("fail to init raw mysql client", K(string_username), K(string_db), K(ret)); } else if (OB_FAIL(raw_client.set_server_addr(local_addrs))) { LOG_WARN("fail to set server addr", K(ret)); diff --git a/src/obproxy/obutils/ob_hot_upgrade_processor.h b/src/obproxy/obutils/ob_hot_upgrade_processor.h index 86798808a..518240016 100644 --- a/src/obproxy/obutils/ob_hot_upgrade_processor.h +++ b/src/obproxy/obutils/ob_hot_upgrade_processor.h @@ -133,7 +133,7 @@ class ObHotUpgradeProcessor ObAsyncCommonTask *hu_cont_; ObAsyncCommonTask *hot_upgrade_cont_; ObHotUpgraderInfo &info_; - char proxy_ip_[common::OB_IP_STR_BUFF]; // ip primary key + char proxy_ip_[common::MAX_IP_ADDR_LENGTH]; // ip primary key char proxy_self_md5_[OB_DEFAULT_PROXY_MD5_LEN + 1]; int32_t proxy_port_; // port primary key int64_t upgrade_failures_; // upgrade failures when handling 'hot_upgrade' cmd diff --git a/src/obproxy/obutils/ob_proxy_config.h b/src/obproxy/obutils/ob_proxy_config.h index 92c7465a4..906eefdb6 100644 --- a/src/obproxy/obutils/ob_proxy_config.h +++ b/src/obproxy/obutils/ob_proxy_config.h @@ -148,6 +148,8 @@ class ObProxyConfig : public common::ObCommonConfig public: // FIXME: DEF_INT can not compare with 0(<, >, >=, <=) mutable obsys::CRWLock rwlock_; + // xa transaction + DEF_BOOL(enable_xa_route, "true", "whether to enable hold XA_START and route to the partition that the next dml will visit",CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); // refresh local config DEF_BOOL(refresh_json_config, "false", "force update json info if refresh_json_config is true", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_MEMORY); DEF_BOOL(refresh_rslist, "false", "when refresh config server, update all rslist if refresh_rslist is true", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_MEMORY); @@ -218,7 +220,7 @@ class ObProxyConfig : public common::ObCommonConfig DEF_INT(server_tcp_keepcnt, "5", "[0,9]", "tcp keepalive probe count, 0 means use default value by kernel", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_INT(server_tcp_user_timeout, "0", "[0,20]", "tcp user timeout, unit is s, 0 means no user timeout", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); - DEF_INT(client_sock_option_flag_out, "2", "[0,]","client sock param, option flag out, bit 1: NO_DELAY, bit 2: KEEP_ALIVE", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); + DEF_INT(client_sock_option_flag_out, "3", "[0,]","client sock param, option flag out, bit 1: NO_DELAY, bit 2: KEEP_ALIVE", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_INT(client_tcp_keepidle, "5", "[0,7200]", "client tcp keepalive idle time, unit is second, 0 means use default value by kernel", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_INT(client_tcp_keepintvl, "5", "[0,75]", "client tcp keepalive interval time, unit is second, 0 means use default value by kernel", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_INT(client_tcp_keepcnt, "5", "[0,9]", "client tcp keepalive probe count, 0 means use default value by kernel", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); @@ -233,6 +235,7 @@ class ObProxyConfig : public common::ObCommonConfig DEF_INT(block_thread_num, "1", "[1,4]", "proxy block thread num, [1, 4]", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_INT(grpc_thread_num, "8", "[8,16]", "proxy grpc thread num, [8, 16]", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_INT(grpc_client_num, "9", "[9,16]", "proxy grpc client num, [9, 16]", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); + DEF_INT(shard_scan_thread_num, "0", "[0,128]", "proxy shard scan thread num, if 0, use (real work thread num/2), [0, 128]", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_BOOL(automatic_match_work_thread, "true", "ignore work_thread_num configuration item, use the count of cpu for current proxy work thread num", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_BOOL(enable_strict_kernel_release, "true", "If is true, proxy only support 5u/6u/7u redhat. Otherwise no care kernel release, and proxy maybe unstable", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); DEF_CAP(max_log_file_size, "256MB", "[1MB,1G]", "max size of log file, [1MB, 1G]", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); @@ -264,6 +267,8 @@ class ObProxyConfig : public common::ObCommonConfig DEF_BOOL(ignore_local_config, "true", "ignore all local cached files, start proxy with remote json", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_IP(local_bound_ip, "0.0.0.0", "local bound ip(any)", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); DEF_INT(listen_port, "6688", "(1024,65536)", "obproxy listen port", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); + DEF_INT(ip_listen_mode, "1", "[1, 3]", "1 means ipv4 listen mode, 2 means ipv6 listen mode, 3 means ipv4 and ipv6 listen mode", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); + DEF_IP(local_bound_ipv6_ip, "::", "local bound ipv6 ip(any)", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); DEF_STR(obproxy_config_server_url, "", "url of config info(rs list and so on)", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); DEF_STR(proxy_service_mode, "client", "proxy deploy and service mode: 1.client(default); 2.server", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); DEF_INT(proxy_id, "0", "[0, 255]", "used to identify each obproxy, it can not be zero if proxy_service_mode is server", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); @@ -284,15 +289,17 @@ class ObProxyConfig : public common::ObCommonConfig DEF_TIME(congestion_retry_interval, "20s", "[1s,1h]", "congestion retry interval, [1s, 1h]", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_TIME(min_congested_connect_timeout, "100ms", "[1ms,1h]", "if client connect timeout after the time, proxy set target server alive congested, [1ms, 1h]", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_BOOL(enable_congestion, "true", "enable congestion feature or not", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); - DEF_INT(server_detect_mode, "0", "[0,1]", "0 means no detect, 1 means target detect", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); + DEF_INT(server_detect_mode, "1", "[0,2]", "0 means no detect, 1 means target server detect, 2 means all server detect", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_INT(server_detect_fail_threshold, "3", "[1,10000]", "server detect try times", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); - DEF_TIME(server_detect_refresh_interval, "10s", "[1ms, 1h]", "the interval to refresh server state for getting zone or server newest state, [10ms, 1h]", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); + DEF_TIME(server_detect_refresh_interval, "1s", "[1ms, 1h]", "the interval to refresh server state for getting zone or server newest state, [10ms, 1h]", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_TIME(detect_server_timeout, "5s", "[1s,1h]", "detect server sql timeout, [1s, 1h]", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_BOOL(enable_bad_route_reject, "false", "if enabled, bad route request will be rejected, e.g. first statement of transaction opened by BEGIN(or START TRANSACTION) without table name", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_BOOL(enable_partition_table_route, "true", "if enabled, partition table will be accurate routing", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_BOOL(enable_compression_protocol, "true", "if enabled, proxy will use compression protocol with server", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_BOOL(enable_ob_protocol_v2, "true", "if enabled, proxy will use oceanbase protocol 2.0 with server", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); + DEF_BOOL(enable_ob_protocol_v2_with_client, "true", "if enabled, proxy will use oceanbase protocol 2.0 with client", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); + DEF_BOOL(enable_transaction_internal_routing, "true", "if enabled, proxy will route the dml statement in a transaction to different servers", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_BOOL(enable_reroute, "false", "if this and protocol_v2 enabled, proxy will reroute when routing error", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_BOOL(enable_pl_route, "true", "if enabled, pl will be accurate routing", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); @@ -306,6 +313,9 @@ class ObProxyConfig : public common::ObCommonConfig DEF_CAP(sqlaudit_mem_limited, "0", "[0,1G]", "sqlaudit memory limited, [0, 1GB]", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_CAP(internal_cmd_mem_limited, "16M", "[0,64MB]", "internal cmd response memory limited, [0, 64MB], 0 means unlimited", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); + // target db servers + DEF_STR(target_db_server, "", "proxy will choose to route target db server addr forcibly, format ip0:port0,ip1:port1,ip2:port2;ip3:port3;ip4:port4", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); + //debug DEF_STR(test_server_addr, "", "proxy will choose this addr(if not empty) as observer addr forcibly, format ip1:sql_port1;ip2:sql_port2", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); DEF_STR(server_routing_mode, "oceanbase", "server routing mode: 1.oceanbase(default mode); 2.random; 3.mock; 4.mysql", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); @@ -449,14 +459,10 @@ class ObProxyConfig : public common::ObCommonConfig // beyond trust sdk DEF_STR(domain_name, "", "app domain name", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); - DEF_BOOL(bt_use_antvip, "true", "if enabled, will use ant vip for bt sdk", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_STR(bt_server_addr, "", "beyond trust server address or hostname", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); - DEF_STR(bt_antvip_server_addr, "", "beyond trust antvip server", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); - DEF_STR(bt_server_antvip, "", "beyond trust server antvip", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); - DEF_BOOL(bt_local_work_mode, "false", "true means LOCAL_CERT_MODE and false means CITADEL_CERT_MODE", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); - DEF_STR(bt_env_mode, "TENANT_MODE", "beyond trust env mode", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); - DEF_STR(bt_instance_id, "", "beyond trust instance id for INSTANCEID env mode", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); DEF_INT(bt_retry_times, "3", "[0,100]", "beyond trust sdk retry times", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); + DEF_STR(bt_mode, "", "beyond trust mode", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); + DEF_STR(citadel_agent_ip, "", "bkmi citadel agent ip", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_USER); // proxyro@sys and root@proxysys passwd DEF_STR(inspector_password, "", "password for inspector user", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); @@ -471,6 +477,18 @@ class ObProxyConfig : public common::ObCommonConfig DEF_BOOL(enable_stat, "true", "if enabled, will collect stat info", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); DEF_INT(digest_sql_length, "1024", "0 means use default print sql len, otherwise is digest_sql_length", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); + + DEF_INT(obproxy_read_only, "1", "[0,1]", "read write type: 0 means ReadOnly, 1 means ReadWrite", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); + DEF_INT(obproxy_read_consistency, "0", "[0,1]", "request target: 0 means leader; 1 means follower", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); + + DEF_BOOL(enable_global_ps_cache, "true", "if enabled, use global ps cache", CFG_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); + + DEF_BOOL(enable_read_write_split, "false", "if enabled, use read write split mode", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); + DEF_BOOL(enable_transaction_split, "false", "if enabled, support transaction split", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); + + // binlog service + DEF_STR(binlog_service_ip, "", "binlog service ip, format ip1:sql_port1", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); + DEF_BOOL(enable_binlog_service, "false", "if enabled, obproxy will send binlog request to OBLogProxy", CFG_NO_NEED_REBOOT, CFG_SECTION_OBPROXY, CFG_VISIBLE_LEVEL_SYS); }; ObProxyConfig &get_global_proxy_config(); diff --git a/src/obproxy/obutils/ob_proxy_config_utils.cpp b/src/obproxy/obutils/ob_proxy_config_utils.cpp index 892594a00..e97774d30 100644 --- a/src/obproxy/obutils/ob_proxy_config_utils.cpp +++ b/src/obproxy/obutils/ob_proxy_config_utils.cpp @@ -18,8 +18,10 @@ #include "utils/ob_layout.h" #include "obutils/ob_proxy_config.h" #include "proxy/client/ob_mysql_proxy.h" +#include "ob_proxy_init.h" using namespace oceanbase::common; +using namespace oceanbase::obproxy; using namespace oceanbase::obproxy::event; using namespace oceanbase::obproxy::proxy; @@ -569,7 +571,9 @@ int ObProxyConfigUtils::load_config_from_file(ObProxyConfig &proxy_config) if (OB_ISNULL(buf = static_cast(ob_malloc(OB_PROXY_CONFIG_BUFFER_SIZE, mem_attr)))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("ob tc malloc memory for buf fail", K(ret)); - } else if (OB_FAIL(ObProxyFileUtils::read(CFG_DUMP_NAME, buf, OB_PROXY_CONFIG_BUFFER_SIZE, read_len))) { + // If it is a rich client mode, the configuration will not be read from the local file + } else if (RUN_MODE_PROXY == g_run_mode + && OB_FAIL(ObProxyFileUtils::read(CFG_DUMP_NAME, buf, OB_PROXY_CONFIG_BUFFER_SIZE, read_len))) { // no need to print warn log, the caller will do it } else { obsys::CWLockGuard guard(proxy_config.rwlock_); diff --git a/src/obproxy/obutils/ob_proxy_json_config_info.cpp b/src/obproxy/obutils/ob_proxy_json_config_info.cpp index 092d05d6b..2aa9b2f65 100644 --- a/src/obproxy/obutils/ob_proxy_json_config_info.cpp +++ b/src/obproxy/obutils/ob_proxy_json_config_info.cpp @@ -2103,7 +2103,7 @@ int ObProxyJsonUtils::rslist_to_json(const LocationList &addr_list, const char * } } if (OB_SUCC(ret)) { - char ip_buf[OB_IP_STR_BUFF]; + char ip_buf[MAX_IP_ADDR_LENGTH]; for (int64_t i = 0; OB_SUCC(ret) && i < addr_list.count(); ++i) { ip_buf[0] = '\0'; if (i > 0) { diff --git a/src/obproxy/obutils/ob_proxy_sql_parser.cpp b/src/obproxy/obutils/ob_proxy_sql_parser.cpp index 7a4fc5d01..d8bd29053 100644 --- a/src/obproxy/obutils/ob_proxy_sql_parser.cpp +++ b/src/obproxy/obutils/ob_proxy_sql_parser.cpp @@ -28,6 +28,7 @@ namespace obproxy { namespace obutils { +#define ISSPACE(c) ((c) == ' ' || (c) == '\n' || (c) == '\r' || (c) == '\t' || (c) == '\f' || (c) == '\v') void ObSqlParseResult::clear_proxy_stmt() { @@ -55,7 +56,7 @@ int ObSqlParseResult::set_real_table_name(const char *table_name, int64_t len) return ret; } -inline int ObSqlParseResult::set_db_name(const ObProxyParseString &database_name, +int ObSqlParseResult::set_db_name(const ObProxyParseString &database_name, const bool use_lower_case_name/*false*/, const bool drop_origin_db_table_name /*false*/) { @@ -200,24 +201,33 @@ inline int ObSqlParseResult::set_call_prarms(const ObProxyCallParseInfo &call_pa } else if (call_parse_info.node_count_ >= 0) { call_info_.is_param_valid_ = true; call_info_.param_count_ = call_parse_info.node_count_; - ObProxyCallParam tmp_param; + ObProxyCallParam* tmp_param = NULL; ObProxyCallParseNode *tmp_node = call_parse_info.head_; - while(tmp_node && OB_SUCC(ret)) { - tmp_param.reset(); - tmp_param.type_ = tmp_node->type_; - if (CALL_TOKEN_INT_VAL == tmp_node->type_) { - tmp_param.str_value_.set_integer(tmp_node->int_value_); - } else if (CALL_TOKEN_PLACE_HOLDER == tmp_node->type_) { - // for place holder, store its pos - tmp_param.str_value_.set_integer(tmp_node->placeholder_idx_); + while(OB_SUCC(ret) && tmp_node) { + tmp_param = NULL; + if (OB_FAIL(ObProxyCallParam::alloc_call_param(tmp_param))) { + LOG_WARN("fail to alloc call param", K(ret)); } else { - const ObString tmp_string(tmp_node->str_value_.str_len_, tmp_node->str_value_.str_); - tmp_param.str_value_.set(tmp_string); - } // end node_type - if (OB_FAIL(call_info_.params_.push_back(tmp_param))) { - LOG_WARN("fail to push back call param", K(tmp_param), K(ret)); + tmp_param->type_ = tmp_node->type_; + if (CALL_TOKEN_INT_VAL == tmp_node->type_) { + tmp_param->str_value_.set_integer(tmp_node->int_value_); + } else if (CALL_TOKEN_PLACE_HOLDER == tmp_node->type_) { + // for place holder, store its pos + tmp_param->str_value_.set_integer(tmp_node->placeholder_idx_); + } else { + tmp_param->str_value_.set_value(tmp_node->str_value_.str_len_, tmp_node->str_value_.str_); + } // end node_type + if (OB_FAIL(call_info_.params_.push_back(tmp_param))) { + LOG_WARN("fail to push back call param", K(tmp_param), K(ret)); + } + + if (OB_FAIL(ret) && NULL != tmp_param) { + tmp_param->reset(); + tmp_param = NULL; + } + + tmp_node = tmp_node->next_; } - tmp_node = tmp_node->next_; } } return ret; @@ -375,26 +385,35 @@ int ObSqlParseResult::set_dbmesh_route_info(const ObProxyParseResult &parse_resu ObShardColumnNode *tmp_node = route_info.head_; fileds_result_.field_num_ = 0; fileds_result_.fields_.reuse(); - SqlField field; + SqlField* field = NULL; while(tmp_node) { - field.reset(); + field = NULL; tmp_str.assign_ptr(tmp_node->tb_name_.str_, tmp_node->tb_name_.str_len_); const ObString table_name = tmp_str.trim(); if (is_dual_request_ || table_name.case_compare(table_name_) == 0) { tmp_str.assign_ptr(tmp_node->col_name_.str_, tmp_node->col_name_.str_len_); - field.column_name_.set(tmp_str); - SqlColumnValue column_value; - if (DBMESH_TOKEN_STR_VAL == tmp_node->type_) { - column_value.value_type_ = TOKEN_STR_VAL; - tmp_str.assign_ptr(tmp_node->col_str_value_.str_, tmp_node->col_str_value_.str_len_); - column_value.column_value_.set(tmp_str); - field.column_values_.push_back(column_value); + if (OB_FAIL(SqlField::alloc_sql_field(field))) { + LOG_WARN("fail to alloc sql field", K(ret)); } else { - LOG_INFO("unknown column value type", "token type", - get_obproxy_dbmesh_token_type(tmp_node->type_)); - } - if (field.is_valid() && OB_SUCCESS == fileds_result_.fields_.push_back(field)) { - ++fileds_result_.field_num_; + field->column_name_.set_value(tmp_str); + SqlColumnValue column_value; + if (DBMESH_TOKEN_STR_VAL == tmp_node->type_) { + column_value.value_type_ = TOKEN_STR_VAL; + tmp_str.assign_ptr(tmp_node->col_str_value_.str_, tmp_node->col_str_value_.str_len_); + column_value.column_value_.set_value(tmp_str); + if (OB_FAIL(field->column_values_.push_back(column_value))) { + LOG_WARN("field push back column values failed", K(column_value), K(ret)); + } + } else { + LOG_INFO("unknown column value type", "token type", + get_obproxy_dbmesh_token_type(tmp_node->type_)); + } + if (OB_SUCC(ret) && field->is_valid() && OB_SUCCESS == fileds_result_.fields_.push_back(field)) { + ++fileds_result_.field_num_; + } else if (NULL != field) { + field->reset(); + field = NULL; + } } } tmp_node = tmp_node->next_; @@ -431,23 +450,38 @@ int ObSqlParseResult::set_dbmesh_route_info(const ObProxyParseResult &parse_resu use_dbp_hint_ = true; dbp_route_info_.scan_all_ = dbp_route_info.scan_all_; } + + if (OB_SUCC(ret) && dbp_route_info.sticky_session_) { + use_dbp_hint_ = true; + dbp_route_info_.sticky_session_ = dbp_route_info.sticky_session_; + } + if (OB_SUCC(ret) && dbp_route_info.has_shard_key_) { use_dbp_hint_ = true; fileds_result_.field_num_ = 0; fileds_result_.fields_.reuse(); dbp_route_info_.has_shard_key_ = dbp_route_info.has_shard_key_; - SqlField field; for (int i = 0; OB_SUCC(ret) && i < dbp_route_info.shard_key_count_;i++) { + SqlField* field = NULL; SqlColumnValue column_value; - field.reset(); - field.column_name_.set_string(dbp_route_info.shard_key_infos_[i].left_str_.str_, - dbp_route_info.shard_key_infos_[i].left_str_.str_len_); - column_value.column_value_.set_string(dbp_route_info.shard_key_infos_[i].right_str_.str_, - dbp_route_info.shard_key_infos_[i].right_str_.str_len_); - column_value.value_type_ = TOKEN_STR_VAL; - field.column_values_.push_back(column_value); - if (field.is_valid() && OB_SUCC(fileds_result_.fields_.push_back(field))) { - ++fileds_result_.field_num_; + if (OB_FAIL(SqlField::alloc_sql_field(field))) { + LOG_WARN("fail to alloc sql field", K(ret)); + } else { + field->column_name_.set_value(dbp_route_info.shard_key_infos_[i].left_str_.str_len_, + dbp_route_info.shard_key_infos_[i].left_str_.str_); + column_value.column_value_.set_value(dbp_route_info.shard_key_infos_[i].right_str_.str_len_, + dbp_route_info.shard_key_infos_[i].right_str_.str_); + column_value.value_type_ = TOKEN_STR_VAL; + if (OB_FAIL(field->column_values_.push_back(column_value))) { + LOG_WARN("fail to push back to column_values", K(ret)); + } else if (field->is_valid() && OB_SUCC(fileds_result_.fields_.push_back(field))) { + ++fileds_result_.field_num_; + } + + if (OB_FAIL(ret) || !field->is_valid()) { + field->reset(); + field = NULL; + } } } } @@ -474,47 +508,52 @@ int ObSqlParseResult::set_var_info(const ObProxyParseResult &parse_result) ObString tmp_str; ObProxySetVarNode *tmp_node = set_parse_info.head_; - SetVarNode var_node; - while(tmp_node) { - var_node.reset(); - - var_node.var_type_ = tmp_node->type_; - - tmp_str.assign_ptr(tmp_node->name_.str_, tmp_node->name_.str_len_); - var_node.var_name_.set(tmp_str); - - var_node.value_type_ = tmp_node->value_type_; - if (SET_VALUE_TYPE_INT == tmp_node->value_type_) { - var_node.int_value_ = tmp_node->int_value_; - // float will be coverted to double - } else if (SET_VALUE_TYPE_NUMBER == tmp_node->value_type_) { - tmp_str.assign_ptr(tmp_node->str_value_.str_, tmp_node->str_value_.str_len_); - var_node.str_value_.set(tmp_str); + SetVarNode* var_node = NULL; + while(OB_SUCC(ret) && tmp_node) { + var_node = NULL; + if (OB_FAIL(SetVarNode::alloc_var_node(var_node))) { + LOG_WARN("fail to alloc var node", K(ret)); } else { - // compatible observer: - // for user var: the var will be returned from observer by OK packet: - // 1. if varchar is digital, observer return value not with ' - // 2. if varchar is string, observer return vaue with ' - // so, varchar type, do not add ' when format SQL - // for sys var: varchar type will add ' on format SQL - if (SET_VAR_USER == tmp_node->type_) { + var_node->var_type_ = tmp_node->type_; + tmp_str.assign_ptr(tmp_node->name_.str_, tmp_node->name_.str_len_); + var_node->var_name_.set_value(tmp_str); + + var_node->value_type_ = tmp_node->value_type_; + if (SET_VALUE_TYPE_INT == tmp_node->value_type_) { + var_node->int_value_ = tmp_node->int_value_; + //Floating point numbers will be converted to double type when saving + } else if (SET_VALUE_TYPE_NUMBER == tmp_node->value_type_) { tmp_str.assign_ptr(tmp_node->str_value_.str_, tmp_node->str_value_.str_len_); - if (OBPROXY_QUOTE_T_SINGLE == tmp_node->str_value_.quote_type_) { - var_node.str_value_.set_with_squote(tmp_str); - } else if (OBPROXY_QUOTE_T_DOUBLE == tmp_node->str_value_.quote_type_) { - var_node.str_value_.set_with_dquote(tmp_str); + var_node->str_value_.set_value(tmp_str); + } else { + // compatible observer: + // for user var: the var will be returned from observer by OK packet: + // 1. if varchar is digital, observer return value not with ' + // 2. if varchar is string, observer return vaue with ' + // so, varchar type, do not add ' when format SQL + // for sys var: varchar type will add ' on format SQL + if (SET_VAR_USER == tmp_node->type_) { + tmp_str.assign_ptr(tmp_node->str_value_.str_, tmp_node->str_value_.str_len_); + if (OBPROXY_QUOTE_T_SINGLE == tmp_node->str_value_.quote_type_) { + var_node->str_value_.set_value_with_quote(tmp_str, '\''); + } else if (OBPROXY_QUOTE_T_DOUBLE == tmp_node->str_value_.quote_type_) { + var_node->str_value_.set_value_with_quote(tmp_str, '"'); + } + } else { + tmp_str.assign_ptr(tmp_node->str_value_.str_, tmp_node->str_value_.str_len_); + var_node->str_value_.set_value(tmp_str); } + } + + if (OB_SUCCESS == set_info_.var_nodes_.push_back(var_node)) { + ++set_info_.node_count_; } else { - tmp_str.assign_ptr(tmp_node->str_value_.str_, tmp_node->str_value_.str_len_); - var_node.str_value_.set(tmp_str); + var_node->reset(); + var_node = NULL; } - } - if (OB_SUCCESS == set_info_.var_nodes_.push_back(var_node)) { - ++set_info_.node_count_; + tmp_node = tmp_node->next_; } - - tmp_node = tmp_node->next_; } } @@ -534,15 +573,20 @@ int ObSqlParseResult::set_text_ps_info(ObProxyTextPsInfo& text_ps_info, } else if (parse_info.node_count_ > 0) { text_ps_info.is_param_valid_ = true; text_ps_info.param_count_ = parse_info.node_count_; - ObProxyTextPsParam tmp_param; + ObProxyTextPsParam* tmp_param = NULL; ObProxyTextPsParseNode *tmp_node = parse_info.head_; while (OB_SUCC(ret) && OB_NOT_NULL(tmp_node)) { - tmp_param.reset(); - const ObString tmp_string(tmp_node->str_value_.str_len_, tmp_node->str_value_.str_); - tmp_param.str_value_.set(tmp_string); - - if (OB_FAIL(text_ps_info.params_.push_back(tmp_param))) { - LOG_WARN("fail to push back text ps execute info", K(tmp_param), K(ret)); + tmp_param = NULL; + if (OB_FAIL(ObProxyTextPsParam::alloc_text_ps_param(tmp_node->str_value_.str_, tmp_node->str_value_.str_len_, tmp_param))) { + LOG_WARN("fail to alloc text ps param", K(ret)); + } else { + const ObString tmp_string(tmp_node->str_value_.str_len_, tmp_node->str_value_.str_); + tmp_param->str_value_.set_value(tmp_string); + if (OB_FAIL(text_ps_info.params_.push_back(tmp_param))) { + tmp_param->reset(); + tmp_param = NULL; + LOG_WARN("fail to push back text ps execute info", KPC(tmp_param), K(ret)); + } } tmp_node = tmp_node->next_; } @@ -597,6 +641,18 @@ int ObSqlParseResult::load_result(const ObProxyParseResult &parse_result, rpc_id_.assign_ptr(rpc_id_buf_, parse_result.rpc_id_.str_len_); } + if (OB_UNLIKELY(NULL != parse_result.target_db_server_.str_ + && 0 < parse_result.target_db_server_.str_len_)) { + if (OB_ISNULL(target_db_server_) && OB_ISNULL(target_db_server_ = op_alloc(ObTargetDbServer))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc memory for target db server", K(ret)); + } else if (OB_FAIL(target_db_server_->init(parse_result.target_db_server_.str_, parse_result.target_db_server_.str_len_))) { + LOG_WARN("fail to init target db server from sql comment", K(ret)); + } else { + LOG_DEBUG("succ to init target db server from sql comment", K(ret)); + } + } + // if is dml stmt, then set db/table name if (OB_LIKELY(is_dml_stmt() || is_call_stmt() || (is_text_ps_stmt() && is_text_ps_inner_dml_stmt()) || is_show_stmt() || is_desc_table_stmt())) { @@ -637,7 +693,7 @@ int ObSqlParseResult::load_result(const ObProxyParseResult &parse_result, if (OB_FAIL(set_var_info(parse_result))) { LOG_WARN("fail to set var info", K(ret)); } - } else if (is_show_topology_stmt()) { + } else if (is_show_elastic_id_stmt()) { ObString tmp_string(parse_result.cmd_info_.string_[0].str_len_, parse_result.cmd_info_.string_[0].str_); if (!tmp_string.empty()) { cmd_info_.string_[0].set(tmp_string); @@ -750,8 +806,7 @@ int64_t ObProxyCallParam::to_string(char *buf, const int64_t buf_len) const { int64_t pos = 0; J_OBJ_START(); - J_KV("type", get_obproxy_call_token_type(type_), - K_(str_value)); + J_KV("type", get_obproxy_call_token_type(type_), K_(str_value), K_(is_alloc)); J_OBJ_END(); return pos; } @@ -765,11 +820,56 @@ int64_t ObProxyCallInfo::to_string(char *buf, const int64_t buf_len) const return pos; } +ObProxyCallInfo::ObProxyCallInfo(const ObProxyCallInfo &other) +{ + int ret = OB_SUCCESS; + is_param_valid_ = other.is_param_valid_; + param_count_ = other.param_count_; + for (int64_t i = 0; OB_SUCC(ret) && i < param_count_; i++) { + ObProxyCallParam *param = other.params_.at(i); + ObProxyCallParam *tmp_param = NULL; + if (OB_FAIL(ObProxyCallParam::alloc_call_param(tmp_param))) { + LOG_WARN("fail to alloc call param", K(ret)); + } else { + *tmp_param = *param; + if (OB_FAIL(params_.push_back(tmp_param))) { + tmp_param->reset(); + tmp_param = NULL; + LOG_ERROR("fail to assign param", K(ret)); + } + } + } +} + +ObProxyCallInfo& ObProxyCallInfo::operator=(const ObProxyCallInfo &other) +{ + int ret = OB_SUCCESS; + if (this != &other) { + is_param_valid_ = other.is_param_valid_; + param_count_ = other.param_count_; + for (int64_t i = 0; OB_SUCC(ret) && i < param_count_; i++) { + ObProxyCallParam *param = other.params_.at(i); + ObProxyCallParam *tmp_param = NULL; + if (OB_FAIL(ObProxyCallParam::alloc_call_param(tmp_param))) { + LOG_WARN("fail to alloc call param", K(ret)); + } else { + *tmp_param = *param; + if (OB_FAIL(params_.push_back(tmp_param))) { + tmp_param->reset(); + tmp_param = NULL; + LOG_ERROR("fail to assign param", K(ret)); + } + } + } + } + return *this; +} + int64_t ObProxyTextPsParam::to_string(char *buf, const int64_t buf_len) const { int64_t pos = 0; J_OBJ_START(); - J_KV(K_(str_value)); + J_KV(K_(str_value), K_(is_alloc)); J_OBJ_END(); return pos; } @@ -783,6 +883,52 @@ int64_t ObProxyTextPsInfo::to_string(char *buf, const int64_t buf_len) const return pos; } +ObProxyTextPsInfo::ObProxyTextPsInfo(const ObProxyTextPsInfo &other) +{ + + int ret = OB_SUCCESS; + is_param_valid_ = other.is_param_valid_; + param_count_ = other.param_count_; + for (int64_t i = 0; OB_SUCC(ret) && i < param_count_; i++) { + ObProxyTextPsParam *param = other.params_.at(i); + ObProxyTextPsParam *tmp_param = NULL; + if (OB_FAIL(ObProxyTextPsParam::alloc_text_ps_param(param->str_value_.ptr(), param->str_value_.length(), tmp_param))) { + LOG_WARN("fai lto alloc text ps param", K(ret)); + } else { + *tmp_param = *param; + if (OB_FAIL(params_.push_back(tmp_param))) { + tmp_param->reset(); + tmp_param = NULL; + LOG_WARN("fail to push back text ps param", K(ret)); + } + } + } +} + +ObProxyTextPsInfo& ObProxyTextPsInfo::operator=(const ObProxyTextPsInfo &other) +{ + int ret = OB_SUCCESS; + if (this != &other) { + is_param_valid_ = other.is_param_valid_; + param_count_ = other.param_count_; + for (int64_t i = 0; OB_SUCC(ret) && i < param_count_; i++) { + ObProxyTextPsParam *param = other.params_.at(i); + ObProxyTextPsParam *tmp_param = NULL; + if (OB_FAIL(ObProxyTextPsParam::alloc_text_ps_param(param->str_value_.ptr(), param->str_value_.length(), tmp_param))) { + LOG_WARN("fai lto alloc text ps param", K(ret)); + } else { + *tmp_param = *param; + if (OB_FAIL(params_.push_back(tmp_param))) { + tmp_param->reset(); + tmp_param = NULL; + LOG_WARN("fail to push back text ps param", K(ret)); + } + } + } + } + return *this; +} + int64_t ObProxySimpleRouteInfo::to_string(char *buf, const int64_t buf_len) const { int64_t pos = 0; @@ -840,7 +986,8 @@ int64_t SetVarNode::to_string(char* buf, const int64_t buf_len) const int64_t pos = 0; J_OBJ_START(); J_KV(K_(var_type), - K_(var_name)); + K_(var_name), + K_(is_alloc)); if (SET_VALUE_TYPE_INT == value_type_) { J_COMMA(); J_KV(K_(int_value)); @@ -920,6 +1067,7 @@ int ObProxySqlParser::parse_sql(const ObString &sql, drop_origin_db_table_name, is_sharding_request))) { LOG_INFO("fail to load result, will go on anyway", K(sql), K(use_lower_case_name), K(tmp_ret)); } else { + sql_parse_result.set_multi_semicolon_in_stmt(ObProxySqlParser::is_multi_semicolon_in_stmt(sql)); LOG_DEBUG("success to do proxy parse", K(sql_parse_result)); } @@ -1360,6 +1508,182 @@ int ObProxySqlParser::parse_sql_by_obparser(const ObString &sql, return ret; } +// A simplified version from observer +int ObProxySqlParser::split_multiple_stmt(const ObString &stmt, + ObIArray &queries) +{ + int ret = OB_SUCCESS; + + int64_t offset = 0; + int64_t remain = stmt.length(); + + trim_multi_stmt(stmt, remain); + + // Special handling for empty statements + if (OB_UNLIKELY(0 >= remain)) { + ObString part; + ret = queries.push_back(part); + } + + while (remain > 0 && OB_SUCC(ret)) { + int64_t str_len = 0; + + //calc the end position of a single sql. + get_single_sql(stmt, offset, remain, str_len); + str_len = str_len == remain ? str_len : str_len + 1; + ObString query(static_cast(str_len), stmt.ptr() + offset); + + remain -= str_len; + offset += str_len; + + if (remain < 0 || offset > stmt.length()) { + LOG_ERROR("split_multiple_stmt data error", + K(remain), K(offset), K(stmt.length()), K(ret)); + } else if(OB_FAIL(queries.push_back(query))){ + LOG_WARN("fail to push back part of multi stmt", K(stmt), K(ret)); + } + } + + return ret; +} + +// avoid separeting sql by semicolons in quotes or comment. +void ObProxySqlParser::get_single_sql(const common::ObString &stmt, int64_t offset, int64_t remain, int64_t &str_len) { + /* following two flags are used to mark wether we are in comment, if in comment, ';' can't be used to split sql*/ + // in -- comment + bool comment_flag = false; + // in /*! comment */ or /* comment */ + bool c_comment_flag = false; + /* follwing three flags are used to mark wether we are in quotes.*/ + // in '', single quotes + bool sq_flag = false; + // in "", double quotes + bool dq_flag = false; + // in ``, backticks. + bool bt_flag = false; + //bool is_escape = false; + + bool in_comment = false; + bool in_string = false; + while (str_len < remain && (in_comment || in_string || (stmt[str_len + offset] != ';'))) { + if (!in_comment && !in_string) { + if (str_len + 1 >= remain) { + } else if ((stmt[str_len + offset] == '-' && stmt[str_len + offset + 1] == '-') || stmt[str_len + offset + 1] == '#') { + comment_flag = true; + } else if (stmt[str_len + offset] == '/' && stmt[str_len + offset + 1] == '*') { + c_comment_flag = true; + } else if (stmt[str_len + offset] == '\'') { + sq_flag = true; + } else if (stmt[str_len + offset] == '"') { + dq_flag = true; + } else if (stmt[str_len + offset] == '`') { + bt_flag = true; + } + } else if (in_comment) { + if (comment_flag) { + if (stmt[str_len + offset] == '\r' || stmt[str_len + offset] == '\n') { + comment_flag = false; + } + } else if (c_comment_flag) { + if (str_len + 1 >= remain) { + + } else if (stmt[str_len + offset] == '*' && (str_len + 1 < remain) && stmt[str_len + offset + 1] == '/') { + c_comment_flag = false; + } + } + } else if (in_string) { + if (str_len + 1 >= remain) { + } else if (!bt_flag && stmt[str_len + offset] == '\\') { + // in mysql mode, handle the escape char in '' and "" + ++ str_len; + } else if (sq_flag) { + if (stmt[str_len + offset] == '\'') { + sq_flag = false; + } + } else if (dq_flag) { + if (stmt[str_len + offset] == '"') { + dq_flag = false; + } + } else if (bt_flag) { + if (stmt[str_len + offset] == '`') { + bt_flag = false; + } + } + } + ++ str_len; + + // update states. + in_comment = comment_flag || c_comment_flag; + in_string = sq_flag || bt_flag || dq_flag; + } +} + +int ObProxySqlParser::preprocess_multi_stmt(ObArenaAllocator &allocator, + char* &multi_sql_buf, + const int64_t origin_sql_length, + ObSEArray &sql_array) +{ + int ret = OB_SUCCESS; + + const int64_t PARSE_EXTRA_CHAR_NUM = 2; + const int64_t total_sql_length = origin_sql_length + + (sql_array.count() * PARSE_EXTRA_CHAR_NUM); + + if (OB_ISNULL(multi_sql_buf = static_cast(allocator.alloc(total_sql_length)))) { + ret = OB_REACH_MEMORY_LIMIT; + LOG_WARN("fail to alloc memory for multi_sql_buf", K(ret), K(total_sql_length)); + } else { + MEMSET(multi_sql_buf, '\0', total_sql_length); + int64_t pos = 0; + for (int64_t i = 0; i < sql_array.count(); ++i) { + ObString& sql = sql_array.at(i); + MEMCPY(multi_sql_buf + pos ,sql.ptr(), sql.length()); + sql.assign_ptr(multi_sql_buf + pos, sql.length()); + pos += sql.length() + PARSE_EXTRA_CHAR_NUM; + } + } + + return ret; +} + +void ObProxySqlParser::trim_multi_stmt(const common::ObString &stmt, int64_t &remain) +{ + // Bypass parser's unfriendly approach to empty query processing: remove the trailing spaces by yourself + while (remain > 0 && ISSPACE(stmt[remain - 1])) { + --remain; + } + //Remove the last '\0' to be compatible with mysql + if (remain > 0 && '\0' == stmt[remain - 1]) { + --remain; + } + //remove trailing spaces + while (remain > 0 && ISSPACE(stmt[remain - 1])) { + --remain; + } +} + +bool ObProxySqlParser::is_multi_semicolon_in_stmt(const common::ObString &stmt) +{ + bool is_multi = false; + int64_t offset = 0; + int64_t remain = stmt.length(); + int64_t str_len = 0; + trim_multi_stmt(stmt, remain); + + // Special handling for empty statements + if (OB_UNLIKELY(0 >= remain)) { + } else { + get_single_sql(stmt, offset, remain, str_len); + remain -= str_len; + // 2: remain space for `;` and `\0` + if (remain > 2) { + is_multi = true; + } + } + return is_multi; +} + + int64_t ObParseNode::to_string(char *buf, const int64_t buf_len) const { int64_t pos = 0; @@ -1380,6 +1704,135 @@ int64_t ObParseNode::to_string(char *buf, const int64_t buf_len) const return pos; } +void ObProxyCallParam::reset() +{ + type_ = CALL_TOKEN_NONE; + str_value_.reset(); + if (is_alloc_) { + is_alloc_ = false; + ob_free(this); + } +} + +int ObProxyCallParam::alloc_call_param(ObProxyCallParam*& param) +{ + int ret = OB_SUCCESS; + char* buf = NULL; + int64_t alloc_size = sizeof(ObProxyCallParam); + ObMemAttr mem_attr; + mem_attr.mod_id_ = common::ObModIds::OB_PROXY_SQL_PARSE; + if (OB_ISNULL(buf = static_cast(ob_malloc(alloc_size, mem_attr)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc mem for call param", K(alloc_size), K(ret)); + } else { + param = new (buf) ObProxyCallParam(); + param->is_alloc_ = true; + } + return ret; +} + +void ObProxyTextPsParam::reset() +{ + str_value_.reset(); + if (is_alloc_) { + is_alloc_ = false; + ob_free(this); + } +} + +int ObProxyTextPsParam::alloc_text_ps_param(const char* str, const int str_len, ObProxyTextPsParam*& param) +{ + int ret = OB_SUCCESS; + char* buf = NULL; + int64_t alloc_size = sizeof(ObProxyTextPsParam); + param = NULL; + ObMemAttr mem_attr; + mem_attr.mod_id_ = ObModIds::OB_PROXY_SQL_PARSE; + if (OB_UNLIKELY(NULL == str || str_len <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(str), K(str_len), K(ret)); + } else if (OB_ISNULL(buf = static_cast(ob_malloc(alloc_size, mem_attr)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc mem for param", K(alloc_size), K(ret)); + } else { + param = new (buf) ObProxyTextPsParam(); + param->is_alloc_ = true; + } + + if (OB_SUCC(ret)) { + param->str_value_.set_value(str_len, str); + } + + if (OB_FAIL(ret) && NULL != param) { + param->reset(); + } + return ret; +} + +void SetVarNode::reset() +{ + value_type_ = SET_VALUE_TYPE_NONE; + var_type_ = SET_VAR_TYPE_NONE; + var_name_.reset(); + int_value_ = 0; + str_value_.reset(); + if (is_alloc_) { + is_alloc_ = false; + ob_free(this); + } +} + +int SetVarNode::alloc_var_node(SetVarNode*& node) +{ + int ret = OB_SUCCESS; + char* buf = NULL; + int64_t alloc_size = sizeof(SetVarNode); + ObMemAttr mem_attr; + mem_attr.mod_id_ = ObModIds::OB_PROXY_SQL_PARSE; + if (OB_ISNULL(buf = static_cast(ob_malloc(alloc_size, mem_attr)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc mem for var node", K(alloc_size), K(ret)); + } else { + node = new (buf) SetVarNode(); + node->is_alloc_ = true; + } + return ret; +} + +int SqlField::alloc_sql_field(SqlField*& field) +{ + int ret = OB_SUCCESS; + char* buf = NULL; + int64_t alloc_size = sizeof(SqlField); + ObMemAttr mem_attr; + mem_attr.mod_id_ = ObModIds::OB_PROXY_SQL_PARSE; + if (OB_ISNULL(buf = static_cast(ob_malloc(alloc_size, mem_attr)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc mem for call param", K(alloc_size), K(ret)); + } else { + field = new (buf) SqlField(); + field->is_alloc_ = true; + } + return ret; +} + +SqlField& SqlField::operator=(const SqlField& other) +{ + int ret = OB_SUCCESS; + if (this != &other) { + column_name_ = other.column_name_; + value_type_ = other.value_type_; + column_int_value_ = other.column_int_value_; + column_value_ = other.column_value_; + for (int i = 0; OB_SUCC(ret) && i < other.column_values_.count(); i++) { + if (OB_FAIL(column_values_.push_back(other.column_values_.at(i)))) { + LOG_WARN("fail to push back column values", K(ret)); + } + } + } + return *this; +} + } // end of namespace obutils } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/obutils/ob_proxy_sql_parser.h b/src/obproxy/obutils/ob_proxy_sql_parser.h index 6fc7274d8..54bf0e879 100644 --- a/src/obproxy/obutils/ob_proxy_sql_parser.h +++ b/src/obproxy/obutils/ob_proxy_sql_parser.h @@ -23,6 +23,8 @@ #include "common/ob_hint.h" #include "lib/utility/ob_print_utils.h" #include "utils/ob_proxy_lib.h" +#include "utils/ob_proxy_utils.h" +#include "utils/ob_target_db_server.h" #include "obutils/ob_proxy_string_utils.h" #include #include @@ -30,8 +32,8 @@ #define OBPROXY_MAX_STRING_VALUE_LENGTH 512 -#define OBPROXY_CALL_NODE_COUNT 20 -#define OBPROXY_TEXT_PS_EXECUTE_NODE_COUNT 20 +#define OBPROXY_CALL_NODE_COUNT 3 +#define OBPROXY_TEXT_PS_EXECUTE_NODE_COUNT 3 using namespace oceanbase::obproxy::opsql; @@ -179,84 +181,72 @@ struct ObProxyCmdInfo struct ObProxyCallParam { - ObProxyCallParam() { reset(); } + ObProxyCallParam() : type_(CALL_TOKEN_NONE), str_value_(), is_alloc_(false) {} ~ObProxyCallParam() { reset(); } DECLARE_TO_STRING; - void reset() - { - type_ = CALL_TOKEN_NONE; - str_value_.reset(); - } - static int32_t get_fix_buf_size() { return OBPROXY_MAX_STRING_VALUE_LENGTH; } + void reset(); + static int alloc_call_param(ObProxyCallParam*& param); ObProxyCallTokenType type_; - ObFixSizeString str_value_; + ObProxyVariantString str_value_; + bool is_alloc_; }; struct ObProxyCallInfo { - ObProxyCallInfo() { reset(); } + ObProxyCallInfo() : params_(), param_count_(0), is_param_valid_(false) {} ~ObProxyCallInfo() { reset(); } + ObProxyCallInfo(const ObProxyCallInfo &other); DECLARE_TO_STRING; - ObProxyCallInfo& operator=(const ObProxyCallInfo &other) - { - if (this != &other) { - is_param_valid_ = other.is_param_valid_; - param_count_ = other.param_count_; - params_.assign(other.params_); - } - return *this; - } + ObProxyCallInfo& operator=(const ObProxyCallInfo &other); void reset() { + for (int64_t i = 0; i < param_count_; i++) { + ObProxyCallParam *param = params_.at(i); + param->reset(); + } param_count_ = 0; is_param_valid_ = false; params_.reset(); } bool is_valid() const { return is_param_valid_ && 0 <= param_count_; } - common::ObSEArray params_; + common::ObSEArray params_; int32_t param_count_; bool is_param_valid_;//whether size is valid }; struct ObProxyTextPsParam { - ObProxyTextPsParam() { reset(); } + ObProxyTextPsParam() : str_value_(), is_alloc_(false) { } ~ObProxyTextPsParam() { reset(); } DECLARE_TO_STRING; - void reset() - { - str_value_.reset(); - } - static int32_t get_fix_buf_size() { return OBPROXY_MAX_STRING_VALUE_LENGTH; } - - ObFixSizeString str_value_; + void reset(); + static int alloc_text_ps_param(const char* str, const int str_len, ObProxyTextPsParam*& param); + ObProxyVariantString str_value_; + bool is_alloc_; }; struct ObProxyTextPsInfo { - ObProxyTextPsInfo() { reset(); } + ObProxyTextPsInfo() : params_(), param_count_(0), is_param_valid_(false) {} ~ObProxyTextPsInfo() { reset(); } + ObProxyTextPsInfo(const ObProxyTextPsInfo &other); DECLARE_TO_STRING; - ObProxyTextPsInfo& operator=(const ObProxyTextPsInfo &other) - { - if (this != &other) { - is_param_valid_ = other.is_param_valid_; - param_count_ = other.param_count_; - params_.assign(other.params_); - } - return *this; - } + ObProxyTextPsInfo& operator=(const ObProxyTextPsInfo &other); void reset() { + for (int64_t i = 0; i < param_count_; i++) { + ObProxyTextPsParam *param = params_.at(i); + param->reset(); + } param_count_ = 0; is_param_valid_ = false; params_.reset(); } bool is_valid() const { return is_param_valid_ && 0 <= param_count_; } - common::ObSEArray params_; + common::ObSEArray params_; int32_t param_count_; bool is_param_valid_;//whether size is valid }; @@ -301,14 +291,16 @@ struct SqlColumnValue column_int_value_ = 0; column_value_.reset(); } - TO_STRING_KV(K_(value_type), K(column_int_value_), K(column_value_)); + TO_STRING_KV(K_(value_type), K_(column_int_value), K_(column_value)); ObProxyTokenType value_type_; int64_t column_int_value_; - ObFixSizeString column_value_; + ObProxyVariantString column_value_; }; struct SqlField { - SqlField() { reset(); } + SqlField() : column_name_(), column_values_(), value_type_(TOKEN_NONE), + column_int_value_(0), column_value_(), is_alloc_(false) {} + ~SqlField() { reset(); } void reset() { @@ -317,31 +309,26 @@ struct SqlField { column_int_value_ = 0; column_value_.reset(); column_values_.reset(); + if (is_alloc_) { + is_alloc_ = false; + ob_free(this); + } } DECLARE_TO_STRING; bool is_valid() const { return column_values_.count() > 0; } - SqlField& operator=(const SqlField& other) - { - if (this != &other) { - column_name_ = other.column_name_; - value_type_ = other.value_type_; - column_int_value_ = other.column_int_value_; - column_value_ = other.column_value_; - for (int i = 0; i < other.column_values_.count(); i++) { - column_values_.push_back(other.column_values_.at(i)); - } - } - return *this; - } + SqlField& operator=(const SqlField& other); + + static int alloc_sql_field(SqlField*& field); + ObProxyVariantString column_name_; - ObFixSizeString column_name_; common::ObSEArray column_values_; // TODO: erase deprecated ObProxyTokenType value_type_; int64_t column_int_value_; - obutils::ObProxyVariantString column_value_; + ObProxyVariantString column_value_; + bool is_alloc_; }; struct SqlFieldResult { @@ -350,13 +337,17 @@ struct SqlFieldResult { void reset() { + for (int64_t i = 0; i < field_num_; i++) { + SqlField* field = fields_.at(i); + field->reset(); + } field_num_ = 0; fields_.reset(); } DECLARE_TO_STRING; int field_num_; - common::ObSEArray fields_; + common::ObSEArray fields_; }; struct DbMeshRouteInfo { @@ -406,40 +397,44 @@ struct DbMeshRouteInfo { }; struct SetVarNode { - SetVarNode() { reset(); } + SetVarNode() : var_name_(), int_value_(0), str_value_(), + value_type_(SET_VALUE_TYPE_NONE), + var_type_(SET_VAR_TYPE_NONE), is_alloc_(false) {} ~SetVarNode() { reset(); } - void reset() { - var_name_.reset(); - str_value_.reset(); - int_value_ = 0; - value_type_ = SET_VALUE_TYPE_ONE; - var_type_ = SET_VAR_TYPE_NONE; - } + void reset(); + static int alloc_var_node(SetVarNode*& node); DECLARE_TO_STRING; - ObFixSizeString var_name_; + ObProxyVariantString var_name_; int64_t int_value_; - ObFixSizeString str_value_; - + obutils::ObProxyVariantString str_value_; ObProxySetValueType value_type_; ObProxySetVarType var_type_; + bool is_alloc_; }; struct ObProxySetInfo { - ObProxySetInfo() { reset(); } + ObProxySetInfo() : node_count_(0), var_nodes_() {} ~ObProxySetInfo() { reset(); } void reset() { + for (int64_t i = 0; i < node_count_; i++) { + SetVarNode *node = var_nodes_.at(i); + node->reset(); + } node_count_ = 0; var_nodes_.reset(); } DECLARE_TO_STRING; int node_count_; - common::ObSEArray var_nodes_; + common::ObSEArray var_nodes_; + +private: + DISALLOW_COPY_AND_ASSIGN(ObProxySetInfo); }; struct DbpRouteInfo { @@ -451,6 +446,7 @@ struct DbpRouteInfo { has_group_info_ = false; group_idx_ = OBPROXY_MAX_DBMESH_ID; scan_all_ = false; + sticky_session_ = false; table_name_.reset(); has_shard_key_ = false; } @@ -463,11 +459,11 @@ struct DbpRouteInfo { bool is_group_info_valid() const { // table_name can be empty - return OBPROXY_MAX_DBMESH_ID != group_idx_ && group_idx_ >= 0 && !scan_all_; + return OBPROXY_MAX_DBMESH_ID != group_idx_ && group_idx_ >= 0 && !scan_all_ && !sticky_session_; } bool is_shard_key_valid() const { - return !scan_all_; + return !scan_all_ && !sticky_session_; } bool is_error_info() const @@ -486,6 +482,7 @@ struct DbpRouteInfo { bool has_group_info_; int64_t group_idx_; bool scan_all_; + bool sticky_session_; common::ObString table_name_; char table_name_str_[common::OB_MAX_TABLE_NAME_LENGTH]; bool has_shard_key_; @@ -519,7 +516,7 @@ typedef struct _ObProxyDualParseResult struct ObSqlParseResult { ObSqlParseResult() : allocator_(common::ObModIds::OB_PROXY_SHARDING_PARSE), - text_ps_buf_(NULL), text_ps_buf_len_(0), ob_parser_result_(NULL), proxy_stmt_(NULL) { reset(); } + text_ps_buf_(NULL), text_ps_buf_len_(0), target_db_server_(NULL), ob_parser_result_(NULL), proxy_stmt_(NULL) { reset(); } ~ObSqlParseResult() { reset(); } void clear_proxy_stmt(); void reset(bool is_reset_origin_db_table = true); @@ -549,7 +546,6 @@ struct ObSqlParseResult bool is_show_session_stmt() const { return OBPROXY_T_ICMD_SHOW_SESSION == stmt_type_; } bool is_select_tx_ro() const { return OBPROXY_T_SELECT_TX_RO == stmt_type_; } bool is_select_proxy_version() const { return OBPROXY_T_SELECT_PROXY_VERSION == stmt_type_; } - bool is_set_autocommit_0() const { return OBPROXY_T_SET_AC_0 == stmt_type_; } bool is_select_route_addr() const { return OBPROXY_T_SELECT_ROUTE_ADDR == stmt_type_; } bool is_set_route_addr() const { return OBPROXY_T_SET_ROUTE_ADDR == stmt_type_; } bool is_set_ob_read_consistency() const { return OBPROXY_T_SET_OB_READ_CONSISTENCY == stmt_type_; } @@ -567,6 +563,7 @@ struct ObSqlParseResult bool is_show_tables_stmt() const { return OBPROXY_T_SHOW == stmt_type_ && OBPROXY_T_SUB_SHOW_TABLES == cmd_sub_type_; } bool is_show_full_tables_stmt() const { return OBPROXY_T_SHOW == stmt_type_ && OBPROXY_T_SUB_SHOW_FULL_TABLES == cmd_sub_type_; } bool is_show_table_status_stmt() const { return OBPROXY_T_SHOW == stmt_type_ && OBPROXY_T_SUB_SHOW_TABLE_STATUS == cmd_sub_type_; } + bool is_show_elastic_id_stmt() const { return OBPROXY_T_SHOW == stmt_type_ && OBPROXY_T_SUB_SHOW_ELASTIC_ID == cmd_sub_type_; } bool is_show_topology_stmt() const { return OBPROXY_T_SHOW == stmt_type_ && OBPROXY_T_SUB_SHOW_TOPOLOGY == cmd_sub_type_; } bool is_show_db_version_stmt() const { return OBPROXY_T_SHOW == stmt_type_ && OBPROXY_T_SUB_SHOW_DB_VERSION == cmd_sub_type_; } bool is_desc_table_stmt() const { return OBPROXY_T_DESC == stmt_type_ && OBPROXY_T_SUB_DESC_TABLE == cmd_sub_type_; } @@ -606,6 +603,16 @@ struct ObSqlParseResult bool is_text_ps_execute_stmt() const { return OBPROXY_T_TEXT_PS_EXECUTE == stmt_type_; } bool is_text_ps_drop_stmt() const { return OBPROXY_T_TEXT_PS_DROP == stmt_type_; } + bool is_binlog_stmt() const + { + return OBPROXY_T_SHOW_MASTER_STATUS == stmt_type_ + || OBPROXY_T_SHOW_BINARY_LOGS == stmt_type_ + || OBPROXY_T_SHOW_BINLOG_EVENTS == stmt_type_ + || OBPROXY_T_PURGE_BINARY_LOGS == stmt_type_ + || OBPROXY_T_RESET_MASTER == stmt_type_ + || OBPROXY_T_SHOW_BINLOG_SERVER_FOR_TENANT == stmt_type_; + } + bool is_internal_select() const { return is_select_tx_ro() || is_select_proxy_version(); } bool is_dual_request() const {return is_dual_request_;} bool is_internal_request() const; @@ -629,6 +636,7 @@ struct ObSqlParseResult bool is_shard_special_cmd() const; + bool is_multi_semicolon_in_stmt() const { return is_multi_semicolon_in_stmt_; } bool has_last_insert_id() const { return has_last_insert_id_; } bool has_found_rows() const { return has_found_rows_; } bool has_row_count() const { return has_row_count_; } @@ -644,6 +652,7 @@ struct ObSqlParseResult bool has_show_warnings() const { return is_show_warnings_stmt(); } bool need_hold_start_trans() const { return is_start_trans_stmt(); } + bool need_hold_xa_start() const { return is_xa_start_stmt_; } // has a function depend on the sql last executed, such as found_rows , row_count, etc. bool has_dependent_func() const; // whether a sql is not supported by PROXY (BUT it is supported by observer) @@ -669,6 +678,9 @@ struct ObSqlParseResult const common::ObString get_trace_id() const { return trace_id_; } const common::ObString get_rpc_id() const { return rpc_id_; } + // route server addrs in sql comment + ObTargetDbServer* get_target_db_server() const { return target_db_server_; } + char *get_table_name_str() { return table_name_.ptr(); } int64_t get_table_name_length() const { return table_name_.length(); } char *get_package_name_str() { return package_name_.ptr(); } @@ -686,6 +698,7 @@ struct ObSqlParseResult void set_stmt_type(const ObProxyBasicStmtType type) { stmt_type_ = type; } void set_err_stmt_type(const ObProxyErrorStmtType type) { cmd_err_type_ = type; } + void set_xa_start_stmt(bool is_xa_start) { is_xa_start_stmt_ = is_xa_start; } int set_db_name(const ObProxyParseString &database_name, const bool use_lower_case_name = false, const bool drop_origin_db_table_name = false); @@ -700,6 +713,7 @@ struct ObSqlParseResult int set_dbmesh_route_info(const ObProxyParseResult &obproxy_parse_result); int set_var_info(const ObProxyParseResult &parse_result); int set_text_ps_info(ObProxyTextPsInfo& text_ps_info, const ObProxyTextPsParseInfo &execute_parse_info); + void set_multi_semicolon_in_stmt(bool is_multi_semicolon_in_stmt) {is_multi_semicolon_in_stmt_ = is_multi_semicolon_in_stmt;} int load_result(const ObProxyParseResult &obproxy_parse_result, const bool use_lower_case_name = false, const bool save_origin_db_table_name = false, @@ -737,6 +751,7 @@ struct ObSqlParseResult has_simple_route_info_ = other.has_simple_route_info_; has_anonymous_block_ = other.has_anonymous_block_; has_for_update_ = other.has_for_update_; + is_xa_start_stmt_ = other.is_xa_start_stmt_; stmt_type_ = other.stmt_type_; hint_query_timeout_ = other.hint_query_timeout_; parsed_length_ = other.parsed_length_; @@ -752,6 +767,7 @@ struct ObSqlParseResult alias_name_quote_ = other.alias_name_quote_; col_name_quote_ = other.col_name_quote_; text_ps_inner_stmt_type_ = other.text_ps_inner_stmt_type_; + is_multi_semicolon_in_stmt_ = other.is_multi_semicolon_in_stmt_; table_name_.assign_ptr(dml_buf_.table_name_buf_, other.table_name_.length()); package_name_.assign_ptr(dml_buf_.package_name_buf_, other.package_name_.length()); database_name_.assign_ptr(dml_buf_.database_name_buf_, other.database_name_.length()); @@ -783,6 +799,18 @@ struct ObSqlParseResult trace_id_.assign_ptr(trace_id_buf_, other.trace_id_.length()); MEMCPY(rpc_id_buf_, other.rpc_id_buf_, other.rpc_id_.length()); rpc_id_.assign_ptr(rpc_id_buf_, other.rpc_id_.length()); + + // copy target db server in sql comment + if (OB_ISNULL(other.target_db_server_)) { + if (OB_NOT_NULL(target_db_server_)) { + op_free(target_db_server_); + target_db_server_ = NULL; + } + } else if (OB_ISNULL(target_db_server_) && OB_ISNULL(target_db_server_ = op_alloc(ObTargetDbServer))) { + PROXY_LOG(WARN, "fail to alloc memory for target db server"); + } else { + *target_db_server_ = *other.target_db_server_; + } } return *this; } @@ -807,6 +835,7 @@ struct ObSqlParseResult database_name_quote_ = other.database_name_quote_; alias_name_quote_ = other.alias_name_quote_; col_name_quote_ = other.col_name_quote_; + is_multi_semicolon_in_stmt_ = other.is_multi_semicolon_in_stmt_; table_name_.assign_ptr(dml_buf_.table_name_buf_, other.table_name_.length()); package_name_.assign_ptr(dml_buf_.package_name_buf_, other.package_name_.length()); database_name_.assign_ptr(dml_buf_.database_name_buf_, other.database_name_.length()); @@ -824,6 +853,18 @@ struct ObSqlParseResult trace_id_.assign_ptr(trace_id_buf_, other.trace_id_.length()); MEMCPY(rpc_id_buf_, other.rpc_id_buf_, other.rpc_id_.length()); rpc_id_.assign_ptr(rpc_id_buf_, other.rpc_id_.length()); + + // copy target db server addr in sql comment + if (OB_ISNULL(other.target_db_server_)) { + if (OB_NOT_NULL(target_db_server_)) { + op_free(target_db_server_); + target_db_server_ = NULL; + } + } else if (OB_ISNULL(target_db_server_) && OB_ISNULL(target_db_server_ = op_alloc(ObTargetDbServer))) { + PROXY_LOG(WARN, "fail to alloc memory target db server"); + } else { + *target_db_server_ = *other.target_db_server_; + } } ObProxyCmdInfo cmd_info_; @@ -841,6 +882,7 @@ struct ObSqlParseResult bool is_dual_request_; bool has_anonymous_block_; bool has_for_update_; + bool is_xa_start_stmt_; ObProxyBasicStmtType stmt_type_; int64_t hint_query_timeout_; int64_t parsed_length_; // next parser can starts with (orig_sql + parsed_length_) @@ -878,6 +920,8 @@ struct ObSqlParseResult common::ObString rpc_id_; char rpc_id_buf_[common::OB_MAX_OBPROXY_TRACE_ID_LENGTH]; + ObTargetDbServer *target_db_server_; + SqlFieldResult fileds_result_; int64_t batch_insert_values_count_; DbMeshRouteInfo dbmesh_route_info_; @@ -886,6 +930,7 @@ struct ObSqlParseResult bool use_dbp_hint_; ObProxyDualParseResult dual_result_; ObDmlBuf origin_dml_buf_; + bool is_multi_semicolon_in_stmt_; // buffer holder union { @@ -931,6 +976,15 @@ class ObProxySqlParser oceanbase::common::ObArenaAllocator &allocator); static int init_ob_parser_node(oceanbase::common::ObArenaAllocator &allocator, ObParseNode *&ob_node); static int get_parse_allocator(common::ObArenaAllocator *&allocator); + static int split_multiple_stmt(const common::ObString &stmt, + common::ObIArray &queries); + static void get_single_sql(const common::ObString &stmt, int64_t offset, int64_t remain, int64_t &str_len); + static int preprocess_multi_stmt(common::ObArenaAllocator &allocator, + char* &multi_sql_buf, + const int64_t origin_sql_length, + common::ObSEArray &sql_array); + static void trim_multi_stmt(const common::ObString &stmt, int64_t &remain); + static bool is_multi_semicolon_in_stmt(const common::ObString &stmt); }; inline void ObSqlParseResult::reset(bool is_reset_origin_db_table /* true */) @@ -944,6 +998,7 @@ inline void ObSqlParseResult::reset(bool is_reset_origin_db_table /* true */) is_dual_request_ = false; has_anonymous_block_ = false; has_for_update_ = false; + is_xa_start_stmt_ = false; stmt_type_ = OBPROXY_T_INVALID; cmd_sub_type_ = OBPROXY_T_SUB_INVALID; cmd_err_type_ = OBPROXY_T_ERR_INVALID; @@ -958,6 +1013,11 @@ inline void ObSqlParseResult::reset(bool is_reset_origin_db_table /* true */) part_name_.reset(); trace_id_.reset(); rpc_id_.reset(); + + if (OB_NOT_NULL(target_db_server_)) { + op_free(target_db_server_); + target_db_server_ = NULL; + } if (is_reset_origin_db_table) { origin_table_name_.reset(); @@ -991,6 +1051,7 @@ inline void ObSqlParseResult::reset(bool is_reset_origin_db_table /* true */) col_name_quote_ = OBPROXY_QUOTE_T_INVALID; dbp_route_info_.reset(); use_dbp_hint_ = false; + is_multi_semicolon_in_stmt_ = false; ob_parser_result_ = NULL; //TODO check delete it } @@ -1084,7 +1145,6 @@ inline bool ObSqlParseResult::is_internal_request() const { return (is_not_supported() || is_internal_select() - || is_set_autocommit_0() || is_set_route_addr() || is_select_route_addr() || is_ping_proxy_cmd()); @@ -1101,6 +1161,7 @@ inline bool ObSqlParseResult::is_shard_special_cmd() const || is_use_db_stmt() || is_show_databases_stmt() || is_show_db_version_stmt() + || is_show_elastic_id_stmt() || is_show_topology_stmt()); } @@ -1123,7 +1184,6 @@ inline bool ObSqlParseResult::is_need_resp_ok_cmd() const { return (is_set_stmt() || is_start_trans_stmt() - || is_set_autocommit_0() || is_commit_stmt() || is_rollback_stmt()); } diff --git a/src/obproxy/obutils/ob_proxy_stmt.cpp b/src/obproxy/obutils/ob_proxy_stmt.cpp index c6e92a20f..b61a71523 100644 --- a/src/obproxy/obutils/ob_proxy_stmt.cpp +++ b/src/obproxy/obutils/ob_proxy_stmt.cpp @@ -23,8 +23,8 @@ namespace obproxy namespace obutils { -ObProxyDMLStmt::ObProxyDMLStmt(common::ObIAllocator& allocator): ObProxyStmt(allocator), limit_offset_(0), limit_size_(-1), limit_token_off_(-1),dml_field_results_(),comments_(), - column_name_array_(), table_name_(), is_inited_(false), has_unsupport_expr_type_(false),table_pos_array_() +ObProxyDMLStmt::ObProxyDMLStmt(common::ObIAllocator& allocator): ObProxyStmt(allocator), limit_offset_(0), limit_size_(-1), limit_token_off_(-1), dml_field_results_(), comments_(), + column_name_array_(), table_name_(), is_inited_(false), has_unsupport_expr_type_(false), table_pos_array_(), has_rollup_(false), has_for_update_(false), from_token_off_(-1), t_case_level_(0) { field_results_ = &dml_field_results_; } @@ -38,6 +38,21 @@ ObProxyDMLStmt::~ObProxyDMLStmt() expr->~ObProxyExpr(); } + for (int64_t i = 0; i < select_exprs_.count(); i++) { + ObProxyExpr *expr = select_exprs_.at(i); + expr->~ObProxyExpr(); + } + + for (int64_t i = 0; i < group_by_exprs_.count(); i++) { + ObProxyGroupItem *group_expr = group_by_exprs_.at(i); + group_expr->~ObProxyGroupItem(); + } + + for (int64_t i = 0; i < order_by_exprs_.count(); i++) { + ObProxyOrderItem *order_expr = order_by_exprs_.at(i); + order_expr->~ObProxyOrderItem(); + } + table_exprs_map_.destroy(); alias_table_map_.destroy(); } @@ -176,7 +191,7 @@ int ObProxyDMLStmt::handle_from_list(ParseNode* node) tmp_node = node->children_[i]; if (NULL == tmp_node) { // do nothing - } else { + } else { switch(tmp_node->type_) { case T_ORG: case T_ALIAS: @@ -217,6 +232,7 @@ int ObProxyDMLStmt::handle_table_node_to_expr(ParseNode* node) int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; ObProxyExprTable* expr_table = NULL; + bool is_sub_query = false; for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { tmp_node = node->children_[i]; if (NULL == tmp_node) { @@ -229,20 +245,28 @@ int ObProxyDMLStmt::handle_table_node_to_expr(ParseNode* node) } break; case T_IDENT: - if (OB_ISNULL(expr_table)) { + if (is_sub_query) { + // skip alias + } else if (OB_ISNULL(expr_table)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to get expr table", K(ret)); - } else if (OB_UNLIKELY(NULL == tmp_node->str_value_ || 0 >= tmp_node->token_len_)) { + } else if (OB_UNLIKELY(NULL == tmp_node->str_value_ || 0 >= tmp_node->str_len_)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("alias token meet some wrong", "token len", tmp_node->token_len_, K(ret)); + LOG_WARN("alias token meet some wrong", "str len", tmp_node->str_len_, K(ret)); } else { - ObString alias_table = ObString::make_string(tmp_node->str_value_); + ObString alias_table(static_cast(tmp_node->str_len_), tmp_node->str_value_); if (OB_FAIL(alias_table_map_.set_refactored(alias_table, expr_table))) { LOG_WARN("fail to add alias table set", K(alias_table), K(ret)); } } break; - case T_SELECT: //sub query in "table node" not support in DML sql except select + case T_SELECT: + if (OB_FAIL(do_handle_parse_result(tmp_node))) { + LOG_WARN("fail to do handle parse result", "node_type", get_type_name(tmp_node->type_), K(ret)); + } else { + is_sub_query = true; + } + break; default: has_unsupport_expr_type_ = true; LOG_WARN("unsupport type", "node_type", get_type_name(node->type_), K(node->str_value_)); @@ -268,19 +292,19 @@ int ObProxyDMLStmt::get_table_and_db_expr(ParseNode* node, ObProxyExprTable* &ex LOG_WARN("T_RELATION_FACTOR children node is not 2", K(node->num_child_), K(ret)); } else if (FALSE_IT(db_node = node->children_[0])) { } else if (NULL != db_node - && OB_UNLIKELY(T_IDENT != db_node->type_ || NULL == db_node->str_value_ || 0 >= db_node->token_len_)) { + && OB_UNLIKELY(T_IDENT != db_node->type_ || NULL == db_node->str_value_ || 0 >= db_node->str_len_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("T_RELATION_FACTOR unexpected table entry", "node type", db_node->type_, - "token len", db_node->token_len_, K(ret)); + "str len", db_node->str_len_, K(ret)); } else if (OB_ISNULL(table_node = node->children_[1])) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected null", K(ret)); - } else if (OB_UNLIKELY(T_IDENT != table_node->type_ || NULL == table_node->str_value_ || 0 >= table_node->token_len_)) { + } else if (OB_UNLIKELY(T_IDENT != table_node->type_ || NULL == table_node->str_value_ || 0 >= table_node->str_len_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("T_RELATION_FACTOR unexpected table entry", "node type", table_node->type_, - "token len", table_node->token_len_, K(ret)); + "str len", table_node->str_len_, K(ret)); } else { - ObString table_name(table_node->token_len_, table_node->str_value_); + ObString table_name(static_cast(table_node->str_len_), table_node->str_value_); string_to_upper_case(table_name.ptr(), table_name.length()); // change all to upper to store if (OB_FAIL(table_exprs_map_.get_refactored(table_name, expr))) { /* same table keep last one. */ if (OB_HASH_NOT_EXIST == ret) { @@ -293,11 +317,11 @@ int ObProxyDMLStmt::get_table_and_db_expr(ParseNode* node, ObProxyExprTable* &ex LOG_WARN("dynamic_cast failed", K(ret)); } else { if (NULL != db_node) { - ObString database_name(db_node->token_len_, db_node->str_value_); + ObString database_name(static_cast(db_node->str_len_), db_node->str_value_); string_to_upper_case(database_name.ptr(), database_name.length()); // change all to upper to store - expr_table->set_database_name(db_node->str_value_, db_node->token_len_); + expr_table->set_database_name(db_node->str_value_, static_cast(db_node->str_len_)); } - expr_table->set_table_name(table_node->str_value_, table_node->token_len_); + expr_table->set_table_name(table_node->str_value_, static_cast(table_node->str_len_)); if (OB_FAIL(table_exprs_map_.set_refactored(table_name, expr_table))) { /* same table keep last one. */ LOG_WARN("fail to add table expr", K(table_name), K(ret)); @@ -311,9 +335,9 @@ int ObProxyDMLStmt::get_table_and_db_expr(ParseNode* node, ObProxyExprTable* &ex ret = OB_ERR_UNEXPECTED; LOG_WARN("dynamic_cast failed", K(ret)); } else if (NULL != db_node && expr_table->get_database_name().empty()) { - ObString database_name(db_node->token_len_, db_node->str_value_); + ObString database_name(static_cast(db_node->str_len_), db_node->str_value_); string_to_upper_case(database_name.ptr(), database_name.length()); // change all to upper to store - expr_table->set_database_name(db_node->str_value_, db_node->token_len_); + expr_table->set_database_name(db_node->str_value_, static_cast(db_node->str_len_)); } } } @@ -342,13 +366,13 @@ int ObProxyDMLStmt::handle_table_and_db_node(ParseNode* node, ObProxyExprTable* ParseNode* table_node = node->children_[1]; if (OB_ISNULL(table_node)) { // do nothing - } else if (OB_UNLIKELY(T_IDENT != table_node->type_ || NULL == table_node->str_value_ || 0 >= table_node->token_len_)) { + } else if (OB_UNLIKELY(T_IDENT != table_node->type_ || NULL == table_node->str_value_ || 0 >= table_node->str_len_)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected table node", "node type", table_node->type_, "token len", table_node->token_len_, K(ret)); + LOG_WARN("unexpected table node", "node type", table_node->type_, "str len", table_node->str_len_, K(ret)); } else if (NULL != db_node - && OB_UNLIKELY(T_IDENT != db_node->type_ || NULL == db_node->str_value_ || 0 >= db_node->token_len_)) { + && OB_UNLIKELY(T_IDENT != db_node->type_ || NULL == db_node->str_value_ || 0 >= db_node->str_len_)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected db node", "node type", db_node->type_, "token len", db_node->token_len_, K(ret)); + LOG_WARN("unexpected db node", "node type", db_node->type_, "str len", db_node->str_len_, K(ret)); } else { ObProxyExpr* expr = NULL; ObString table_name = ObString::make_string(table_node->str_value_); @@ -388,22 +412,23 @@ int ObProxyDMLStmt::handle_table_references(ParseNode *node) for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { ParseNode *tmp_node = node->children_[i]; if (NULL == tmp_node) { - continue; - } - switch (tmp_node->type_) { - case T_ORG: - case T_ALIAS: - if (OB_FAIL(handle_table_node_to_expr(tmp_node))) { - LOG_WARN("fail to handle table node to expr", K(sql_string_), K(ret)); - } - break; - //sql: delete tbl_name1,tbl_name2 ... - //MULTI DELETE STMT is not support now - case T_RELATION_FACTOR: - break; - default: - has_unsupport_expr_type_ = true; - LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); + //do nothing + } else { + switch (tmp_node->type_) { + case T_ORG: + case T_ALIAS: + if (OB_FAIL(handle_table_node_to_expr(tmp_node))) { + LOG_WARN("fail to handle table node to expr", K(sql_string_), K(ret)); + } + break; + //sql: delete tbl_name1,tbl_name2 ... + //MULTI DELETE STMT is not support now + case T_RELATION_FACTOR: + break; + default: + has_unsupport_expr_type_ = true; + LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); + } } } return ret; @@ -440,6 +465,13 @@ int ObProxyDMLStmt::handle_where_clause(ParseNode* node) } break; } + case T_CASE: + t_case_level_++; + if (OB_FAIL(handle_where_clause(tmp_node))) { + LOG_WARN("handle_where_nodes failed", K(sql_string_), K(ret)); + } + t_case_level_--; + break; default: if (OB_FAIL(handle_where_clause(tmp_node))) { LOG_WARN("handle_where_nodes failed", K(sql_string_), K(ret)); @@ -461,6 +493,9 @@ int ObProxyDMLStmt::handle_column_and_value(ParseNode* node) SqlField sql_field; SqlColumnValue column_value; bool is_skip_field = false; + if (t_case_level_ > 0) { + is_skip_field = true; + } if (OB_ISNULL(field_results_)) { LOG_WARN("unexpected null"); ret = OB_ERR_UNEXPECTED; @@ -485,7 +520,7 @@ int ObProxyDMLStmt::handle_column_and_value(ParseNode* node) } else { if (NULL == expr_table || 0 == expr_table->get_table_name().case_compare(table_name_)) { - sql_field.column_name_.set(expr_column->get_column_name()); + sql_field.column_name_.set_value(expr_column->get_column_name()); } else { is_skip_field = true; } @@ -504,8 +539,8 @@ int ObProxyDMLStmt::handle_column_and_value(ParseNode* node) sql_field.column_int_value_ = tmp_node->value_; } column_value.value_type_ = TOKEN_STR_VAL; - column_value.column_value_.set(tmp_node->str_value_); - sql_field.column_values_.push_back(column_value); + column_value.column_value_.set_value(tmp_node->str_value_); + ret = sql_field.column_values_.push_back(column_value); break; case T_VARCHAR: ret = handle_varchar_node_in_column_value(tmp_node, sql_field); @@ -526,7 +561,7 @@ int ObProxyDMLStmt::handle_column_and_value(ParseNode* node) if (OB_SUCC(ret) && !is_skip_field) { int duplicate_column_idx = -1; for (int i = 0; i < field_results_->fields_.count(); i++) { - if (0 == sql_field.column_name_.get_string().case_compare(field_results_->fields_[i].column_name_.get_string())) { + if (0 == sql_field.column_name_.config_string_.case_compare(field_results_->fields_[i]->column_name_.config_string_)) { duplicate_column_idx = i; break; } @@ -534,15 +569,26 @@ int ObProxyDMLStmt::handle_column_and_value(ParseNode* node) if (-1 != duplicate_column_idx) { for (int i = 0; OB_SUCC(ret) && i < sql_field.column_values_.count(); i++) { SqlColumnValue tmp_column_value = sql_field.column_values_[i]; - if (OB_FAIL(field_results_->fields_.at(duplicate_column_idx).column_values_.push_back(tmp_column_value))) { + if (OB_FAIL(field_results_->fields_.at(duplicate_column_idx)->column_values_.push_back(tmp_column_value))) { LOG_WARN("push_back failed", K(ret), K(sql_string_)); } } - } else if (OB_FAIL(field_results_->fields_.push_back(sql_field))) { - LOG_WARN("push_back failed", K(ret), K(sql_string_)); } else { - ++field_results_->field_num_; - LOG_DEBUG("add sql_field", K(sql_field), K(field_results_->field_num_)); + SqlField *tmp_field = NULL; + if (OB_ISNULL(tmp_field = op_alloc(SqlField))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate memory for sqlfield", K(ret)); + } else { + *tmp_field = sql_field; + if (OB_FAIL(field_results_->fields_.push_back(tmp_field))) { + tmp_field->reset(); + tmp_field = NULL; + LOG_WARN("push_back failed", K(ret), K(sql_string_)); + } else { + ++field_results_->field_num_; + LOG_DEBUG("add sql_field", KPC(tmp_field), K(field_results_->field_num_)); + } + } } } } @@ -562,18 +608,16 @@ int ObProxyDMLStmt::handle_varchar_node_in_column_value(ParseNode* node, SqlFiel //there is implicit type conversion: const char* -> ObString sql_field.column_value_.set_value(node->str_value_); column_value.value_type_ = TOKEN_STR_VAL; - column_value.column_value_.set(node->str_value_); - sql_field.column_values_.push_back(column_value); + column_value.column_value_.set_value(node->str_value_); + ret = sql_field.column_values_.push_back(column_value); } else { tmp_varchar_node = NULL; for (i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { - if (node->children_[i] == NULL) { + if ((node->children_[i] == NULL) || (node->children_[i]->type_ != T_VARCHAR)) { //do nothing - } else if (tmp_varchar_node != NULL) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("should null here", K(ret), K(node->str_value_), K(sql_string_)); } else { tmp_varchar_node = node->children_[i]; + break; } } if (tmp_varchar_node == NULL) { @@ -584,8 +628,31 @@ int ObProxyDMLStmt::handle_varchar_node_in_column_value(ParseNode* node, SqlFiel sql_field.column_value_.set_value(tmp_varchar_node->str_value_); sql_field.value_type_ = TOKEN_STR_VAL; column_value.value_type_ = TOKEN_STR_VAL; - column_value.column_value_.set(tmp_varchar_node->str_value_); - sql_field.column_values_.push_back(column_value); + column_value.column_value_.set_value(tmp_varchar_node->str_value_); + if (OB_FAIL(sql_field.column_values_.push_back(column_value))) { + LOG_WARN("fail to push column_value", K(ret)); + } + + bool need_save = false; + ShardingPosType type = SHARDING_POS_NONE; + if (0 == sql_field.column_name_.config_string_.case_compare("SCHEMA_NAME") + || 0 == sql_field.column_name_.config_string_.case_compare("TABLE_SCHEMA")) { + need_save = true; + type = SHARDING_POS_DB; + } else if (0 == sql_field.column_name_.config_string_.case_compare("TABLE_NAME")) { + need_save = true; + type = SHARDING_POS_TABLE; + } + + if (need_save) { + ObProxyDbTablePos db_table_pos; + db_table_pos.set_pos(tmp_varchar_node->token_off_); + db_table_pos.set_name(tmp_varchar_node->str_value_); + db_table_pos.set_type(type); + if (OB_FAIL(db_table_pos_array_.push_back(db_table_pos))) { + LOG_WARN("fail to push expr table pos", K(ret)); + } + } } } return ret; @@ -608,7 +675,7 @@ int ObProxyDMLStmt::handle_expr_list_node_in_column_value(ParseNode* node, SqlFi case T_INT: default: column_value.value_type_ = TOKEN_STR_VAL; - column_value.column_value_.set(tmp_node->str_value_); + column_value.column_value_.set_value(tmp_node->str_value_); if (OB_FAIL(sql_field.column_values_.push_back(column_value))) { LOG_WARN("push_back failed", K(i), K(sql_string_), K(ret)); } @@ -625,18 +692,19 @@ int ObProxyDMLStmt::handle_assign_list(ParseNode *node) for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { ParseNode *tmp_node = node->children_[i]; if (NULL == tmp_node) { - continue; - } - switch (tmp_node->type_) { - case T_ASSIGN_ITEM: - if (OB_FAIL(handle_column_and_value(tmp_node))) { - LOG_WARN("handle op and failed", K(ret)); - } - break; - default: - has_unsupport_expr_type_ = true; - LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); - break; + //do nothing + } else { + switch (tmp_node->type_) { + case T_ASSIGN_ITEM: + if (OB_FAIL(handle_column_and_value(tmp_node))) { + LOG_WARN("handle op and failed", K(ret)); + } + break; + default: + has_unsupport_expr_type_ = true; + LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); + break; + } } } return ret; @@ -686,11 +754,11 @@ int ObProxyDMLStmt::column_ref_to_expr(ParseNode* node, ObProxyExpr* &expr, ObPr if (OB_ISNULL(column_node)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("T_COLUMN_REF unexpected column entry", K(ret)); - } else if (T_IDENT != column_node->type_) { + } else if (T_IDENT != column_node->type_ && T_STAR != column_node->type_) { // now column_ref child should be T_IDENT has_unsupport_expr_type_ = true; LOG_WARN("T_COLUMN_REF unexpected column entry", "node_type", get_type_name(column_node->type_), K(ret)); - } else { + } else if (T_IDENT == column_node->type_) { ObProxyExprColumn* expr_column = NULL; if (OB_FAIL(get_expr_by_type(expr, OB_PROXY_EXPR_TYPE_COLUMN))) { LOG_WARN("get_expr_by_type failed", K(ret), K(sql_string_)); @@ -698,14 +766,26 @@ int ObProxyDMLStmt::column_ref_to_expr(ParseNode* node, ObProxyExpr* &expr, ObPr ret = OB_ERR_UNEXPECTED; LOG_WARN("dynamic_cast failed", K(ret)); } else { - expr_column->set_column_name(column_node->str_value_, column_node->token_len_); + expr_column->set_column_name(column_node->str_value_, static_cast(column_node->str_len_)); if (OB_NOT_NULL(table_node)) { - expr_column->set_table_name(table_node->str_value_, table_node->token_len_); + expr_column->set_table_name(table_node->str_value_, static_cast(table_node->str_len_)); if (NULL != expr_table) { expr_column->set_real_table_name(expr_table->get_table_name()); } } } + } else if (T_STAR == column_node->type_) { + ObProxyExprStar* expr_star = NULL; + if (OB_FAIL(get_expr_by_type(expr, OB_PROXY_EXPR_TYPE_STAR))) { + LOG_WARN("get_expr_by_type failed", K(ret), K(sql_string_)); + } else if (OB_ISNULL(expr_star = dynamic_cast(expr))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dynamic_cast failed", K(ret)); + } else { + if (OB_NOT_NULL(table_node)) { + expr_star->set_table_name(table_node->str_value_, static_cast(table_node->str_len_)); + } + } } } @@ -729,47 +809,8 @@ int ObProxyDMLStmt::limit_to_sql_string(common::ObSqlString& sql_string) } return ret; } -ObProxySelectStmt::ObProxySelectStmt(common::ObIAllocator& allocator) : ObProxyDMLStmt(allocator), - has_rollup_(false), - has_for_update_(false), - from_token_off_(-1) -{ - -} -ObProxySelectStmt::~ObProxySelectStmt() -{ - for (int64_t i = 0; i < select_exprs_.count(); i++) { - ObProxyExpr *expr = select_exprs_.at(i); - expr->~ObProxyExpr(); - } - - for (int64_t i = 0; i < group_by_exprs_.count(); i++) { - ObProxyGroupItem *group_expr = group_by_exprs_.at(i); - group_expr->~ObProxyGroupItem(); - } - - for (int64_t i = 0; i < order_by_exprs_.count(); i++) { - ObProxyOrderItem *order_expr = order_by_exprs_.at(i); - order_expr->~ObProxyOrderItem(); - } -} - -int ObProxySelectStmt::handle_parse_result(const ParseResult &parse_result) -{ - int ret = OB_SUCCESS; - ParseNode* node = parse_result.result_tree_->children_[0]; - - if (OB_FAIL(do_handle_parse_result(node))) { - LOG_WARN("fail to do handle parse result", K(sql_string_), "node_type", get_type_name(node->type_), K(ret)); - } else if (OB_FAIL(handle_comment_list(parse_result))) { - LOG_WARN("handle_comment_list failed", K(ret), K(sql_string_)); - } - - return ret; -} - -int ObProxySelectStmt::do_handle_parse_result(ParseNode* node) +int ObProxyDMLStmt::do_handle_parse_result(ParseNode* node) { int ret = OB_SUCCESS; @@ -843,7 +884,7 @@ int ObProxySelectStmt::do_handle_parse_result(ParseNode* node) return ret; } -int ObProxySelectStmt::handle_comment_list(const ParseResult &parse_result) +int ObProxyDMLStmt::handle_comment_list(const ParseResult &parse_result) { int ret = OB_SUCCESS; for (int i = 0; OB_SUCC(ret) && i < parse_result.comment_cnt_; i++) { @@ -857,7 +898,8 @@ int ObProxySelectStmt::handle_comment_list(const ParseResult &parse_result) } return ret; } -int ObProxySelectStmt::comments_to_sql_string(common::ObSqlString& sql_string) + +int ObProxyDMLStmt::comments_to_sql_string(common::ObSqlString& sql_string) { int ret = OB_SUCCESS; for (int i = 0; OB_SUCC(ret) && i < comments_.count(); i++) { @@ -868,13 +910,13 @@ int ObProxySelectStmt::comments_to_sql_string(common::ObSqlString& sql_string) return ret; } -int ObProxySelectStmt::hint_exprs_to_sql_string(common::ObSqlString& sql_string) +int ObProxyDMLStmt::hint_exprs_to_sql_string(common::ObSqlString& sql_string) { UNUSED(sql_string); int ret = OB_SUCCESS; return ret; } -int ObProxySelectStmt::select_exprs_to_sql_string(common::ObSqlString& sql_string) +int ObProxyDMLStmt::select_exprs_to_sql_string(common::ObSqlString& sql_string) { int ret = OB_SUCCESS; if (select_exprs_.count() < 1) { @@ -894,14 +936,14 @@ int ObProxySelectStmt::select_exprs_to_sql_string(common::ObSqlString& sql_strin return ret; } -int ObProxySelectStmt::table_exprs_to_sql_string(common::ObSqlString& sql_string) +int ObProxyDMLStmt::table_exprs_to_sql_string(common::ObSqlString& sql_string) { UNUSED(sql_string); int ret = OB_SUCCESS; return ret; } -int ObProxySelectStmt::group_by_exprs_to_sql_string(common::ObSqlString& sql_string) +int ObProxyDMLStmt::group_by_exprs_to_sql_string(common::ObSqlString& sql_string) { int ret = OB_SUCCESS; if (group_by_exprs_.count() <= 0) { @@ -927,7 +969,7 @@ int ObProxySelectStmt::group_by_exprs_to_sql_string(common::ObSqlString& sql_str return ret; } -int ObProxySelectStmt::order_by_exprs_to_sql_string(common::ObSqlString& sql_string) +int ObProxyDMLStmt::order_by_exprs_to_sql_string(common::ObSqlString& sql_string) { int ret = OB_SUCCESS; if (order_by_exprs_.count() <= 0) { @@ -949,7 +991,7 @@ int ObProxySelectStmt::order_by_exprs_to_sql_string(common::ObSqlString& sql_str } //REFER:https://dev.mysql.com/doc/refman/8.0/en/select.html -int ObProxySelectStmt::to_sql_string(common::ObSqlString& sql_string) +int ObProxyDMLStmt::to_sql_string(common::ObSqlString& sql_string) { int ret = OB_SUCCESS; if (OB_FAIL(comments_to_sql_string(sql_string))) { @@ -976,7 +1018,7 @@ int ObProxySelectStmt::to_sql_string(common::ObSqlString& sql_string) return ret; } -int ObProxySelectStmt::handle_union_clause(ParseNode* node) +int ObProxyDMLStmt::handle_union_clause(ParseNode* node) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1005,7 +1047,7 @@ int ObProxySelectStmt::handle_union_clause(ParseNode* node) return ret; } -int ObProxySelectStmt::handle_hint_clause(ParseNode* node) +int ObProxyDMLStmt::handle_hint_clause(ParseNode* node) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1031,7 +1073,7 @@ int ObProxySelectStmt::handle_hint_clause(ParseNode* node) return ret; } -int ObProxySelectStmt::handle_limit_clause(ParseNode* node) +int ObProxyDMLStmt::handle_limit_clause(ParseNode* node) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1066,7 +1108,7 @@ int ObProxySelectStmt::handle_limit_clause(ParseNode* node) return ret; } -int ObProxySelectStmt::handle_project_list(ParseNode* node) +int ObProxyDMLStmt::handle_project_list(ParseNode* node) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1098,7 +1140,7 @@ int ObProxySelectStmt::handle_project_list(ParseNode* node) return ret; } -int ObProxySelectStmt::get_const_expr(ParseNode* node, ObProxyExpr* &expr) +int ObProxyDMLStmt::get_const_expr(ParseNode* node, ObProxyExpr* &expr) { int ret = OB_SUCCESS; ObProxyExprConst* expr_const = NULL; @@ -1122,7 +1164,7 @@ int ObProxySelectStmt::get_const_expr(ParseNode* node, ObProxyExpr* &expr) LOG_DEBUG("add int value", K(obj)); } } else { - ObString var(node->token_len_, node->str_value_); + ObString var(static_cast(node->str_len_), node->str_value_); obj.set_varchar(var); expr_const->set_object(obj); LOG_DEBUG("add varchar value", K(obj)); @@ -1131,7 +1173,7 @@ int ObProxySelectStmt::get_const_expr(ParseNode* node, ObProxyExpr* &expr) return ret; } -int ObProxySelectStmt::get_sharding_const_expr(ParseNode* node, ObProxyExpr* &expr) +int ObProxyDMLStmt::get_sharding_const_expr(ParseNode* node, ObProxyExpr* &expr) { int ret = OB_SUCCESS; ObProxyExprShardingConst* expr_const = NULL; @@ -1144,12 +1186,12 @@ int ObProxySelectStmt::get_sharding_const_expr(ParseNode* node, ObProxyExpr* &ex ret = OB_ERR_UNEXPECTED; LOG_WARN("dynamic_cast failed", K(ret)); } else { - expr_const->set_expr_name(node->str_value_, node->token_len_); + expr_const->set_expr_name(node->str_value_, static_cast(node->str_len_)); } return ret; } -int ObProxySelectStmt::handle_table_and_db_in_hint(ParseNode* node) +int ObProxyDMLStmt::handle_table_and_db_in_hint(ParseNode* node) { int ret = OB_SUCCESS; @@ -1165,62 +1207,8 @@ int ObProxySelectStmt::handle_table_and_db_in_hint(ParseNode* node) return ret; } -int ObProxySelectStmt::column_ref_to_expr(ParseNode* node, ObProxyExpr* &expr, ObProxyExprTable* &expr_table) -{ - int ret = OB_SUCCESS; - - if (OB_T_COLUMN_REF_NUM_CHILD /* 3 */ != node->num_child_) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("T_COLUMN_REF children node is not 3", "child num", node->num_child_, K(ret)); - } else if (OB_FAIL(handle_table_and_db_node(node, expr_table))) { - LOG_WARN("fail to handle table and db node", K(ret)); - } - - if (OB_SUCC(ret)) { - ParseNode* table_node = node->children_[1]; - ParseNode* column_node = node->children_[2]; - if (OB_ISNULL(column_node)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("T_COLUMN_REF unexpected column entry", K(ret)); - } else if (T_IDENT != column_node->type_ && T_STAR != column_node->type_) { - // now column_ref child should be T_IDENT - has_unsupport_expr_type_ = true; - LOG_WARN("T_COLUMN_REF unexpected column entry", "node_type", get_type_name(column_node->type_), K(ret)); - } else if (T_IDENT == column_node->type_) { - ObProxyExprColumn* expr_column = NULL; - if (OB_FAIL(get_expr_by_type(expr, OB_PROXY_EXPR_TYPE_COLUMN))) { - LOG_WARN("get_expr_by_type failed", K(ret), K(sql_string_)); - } else if (OB_ISNULL(expr_column = dynamic_cast(expr))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("dynamic_cast failed", K(ret)); - } else { - expr_column->set_column_name(column_node->str_value_, column_node->token_len_); - if (OB_NOT_NULL(table_node)) { - expr_column->set_table_name(table_node->str_value_, table_node->token_len_); - if (NULL != expr_table) { - expr_column->set_real_table_name(expr_table->get_table_name()); - } - } - } - } else if (T_STAR == column_node->type_) { - ObProxyExprStar* expr_star = NULL; - if (OB_FAIL(get_expr_by_type(expr, OB_PROXY_EXPR_TYPE_STAR))) { - LOG_WARN("get_expr_by_type failed", K(ret), K(sql_string_)); - } else if (OB_ISNULL(expr_star = dynamic_cast(expr))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("dynamic_cast failed", K(ret)); - } else { - if (OB_NOT_NULL(table_node)) { - expr_star->set_table_name(table_node->str_value_, table_node->token_len_); - } - } - } - } - - return ret; -} -int ObProxySelectStmt::alias_node_to_expr(ParseNode* node, ObProxyExpr* &expr, ParseNode* string_node) +int ObProxyDMLStmt::alias_node_to_expr(ParseNode* node, ObProxyExpr* &expr, ParseNode* string_node) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1235,11 +1223,11 @@ int ObProxySelectStmt::alias_node_to_expr(ParseNode* node, ObProxyExpr* &expr, P if (OB_ISNULL(expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to get expr table", K(ret)); - } else if (OB_UNLIKELY(NULL == tmp_node->str_value_ || 0 >= tmp_node->token_len_)) { + } else if (OB_UNLIKELY(NULL == tmp_node->str_value_ || 0 >= tmp_node->str_len_)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("alias token meet some wrong", "token len", tmp_node->token_len_, K(ret)); + LOG_WARN("alias token meet some wrong", "str len", tmp_node->str_len_, K(ret)); } else { - expr->set_alias_name(tmp_node->str_value_, tmp_node->token_len_); + expr->set_alias_name(tmp_node->str_value_, static_cast(tmp_node->str_len_)); } break; default: @@ -1252,7 +1240,7 @@ int ObProxySelectStmt::alias_node_to_expr(ParseNode* node, ObProxyExpr* &expr, P return ret; } -int ObProxySelectStmt::func_node_to_expr(ParseNode* node, ObProxyExpr* &expr) +int ObProxyDMLStmt::func_node_to_expr(ParseNode* node, ObProxyExpr* &expr) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1300,12 +1288,12 @@ int ObProxySelectStmt::func_node_to_expr(ParseNode* node, ObProxyExpr* &expr) } if (OB_SUCC(ret)) { - func_expr->set_expr_name(node->str_value_, node->token_len_); + func_expr->set_expr_name(node->str_value_, static_cast(node->str_len_)); } return ret; } -int ObProxySelectStmt::check_node_has_agg(ParseNode* node) +int ObProxyDMLStmt::check_node_has_agg(ParseNode* node) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1338,7 +1326,7 @@ int ObProxySelectStmt::check_node_has_agg(ParseNode* node) return ret; } //we do not cover all sys func. if sys func do not have agg func, pass it to server as string -int ObProxySelectStmt::func_sys_node_to_expr(ParseNode* node, ObProxyExpr* &expr, ParseNode* string_node) +int ObProxyDMLStmt::func_sys_node_to_expr(ParseNode* node, ObProxyExpr* &expr, ParseNode* string_node) { int ret = OB_SUCCESS; if (OB_FAIL(check_node_has_agg(node))) { @@ -1353,7 +1341,7 @@ int ObProxySelectStmt::func_sys_node_to_expr(ParseNode* node, ObProxyExpr* &expr return ret; } -int ObProxySelectStmt::string_node_to_expr(ParseNode* node, ObProxyExpr* &expr, ParseNode* string_node) +int ObProxyDMLStmt::string_node_to_expr(ParseNode* node, ObProxyExpr* &expr, ParseNode* string_node) { int ret = OB_SUCCESS; int i = 0; @@ -1434,7 +1422,7 @@ int ObProxySelectStmt::string_node_to_expr(ParseNode* node, ObProxyExpr* &expr, } return ret; } -int ObProxySelectStmt::project_string_to_expr(ParseNode* node, ObProxyExpr* &expr) +int ObProxyDMLStmt::project_string_to_expr(ParseNode* node, ObProxyExpr* &expr) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1452,56 +1440,8 @@ int ObProxySelectStmt::project_string_to_expr(ParseNode* node, ObProxyExpr* &exp return ret; } -int ObProxySelectStmt::handle_table_node_to_expr(ParseNode* node) -{ - int ret = OB_SUCCESS; - ParseNode* tmp_node = NULL; - ObProxyExprTable* expr_table = NULL; - bool is_sub_query = false; - for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { - tmp_node = node->children_[i]; - if (NULL == tmp_node) { - //do nothing - } else { - switch(tmp_node->type_) { - case T_RELATION_FACTOR: - if (OB_FAIL(get_table_and_db_expr(tmp_node, expr_table))) { - LOG_WARN("fail to get table expr", K(ret)); - } - break; - case T_IDENT: - if (is_sub_query) { - // skip alias - } else if (OB_ISNULL(expr_table)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("fail to get expr table", K(ret)); - } else if (OB_UNLIKELY(NULL == tmp_node->str_value_ || 0 >= tmp_node->token_len_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("alias token meet some wrong", "token len", tmp_node->token_len_, K(ret)); - } else { - ObString alias_table = ObString::make_string(tmp_node->str_value_); - if (OB_FAIL(alias_table_map_.set_refactored(alias_table, expr_table))) { - LOG_WARN("fail to add alias table set", K(alias_table), K(ret)); - } - } - break; - case T_SELECT: - if (OB_FAIL(do_handle_parse_result(tmp_node))) { - LOG_WARN("fail to do handle parse result", "node_type", get_type_name(tmp_node->type_), K(ret)); - } else { - is_sub_query = true; - } - break; - default: - has_unsupport_expr_type_ = true; - LOG_WARN("unsupport type", "node_type", get_type_name(node->type_), K(node->str_value_)); - } - } - } - return ret; -} -int ObProxySelectStmt::handle_sort_key_node(ParseNode* node, ObProxyExpr* &expr, const SortListType& sort_list_type) +int ObProxyDMLStmt::handle_sort_key_node(ParseNode* node, ObProxyExpr* &expr, const SortListType& sort_list_type) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1520,7 +1460,7 @@ int ObProxySelectStmt::handle_sort_key_node(ParseNode* node, ObProxyExpr* &expr, order_direction = NULLS_LAST_DESC; break; default: - if (OB_FAIL(string_node_to_expr(tmp_node, tmp_expr))) { + if (OB_FAIL(string_node_to_expr(tmp_node, tmp_expr, tmp_node))) { LOG_WARN("string_node_to_expr failed", K(ret), K(sql_string_)); } else if (T_INT == tmp_node->type_) { ObProxyExprConst* expr_const = NULL; @@ -1569,7 +1509,7 @@ int ObProxySelectStmt::handle_sort_key_node(ParseNode* node, ObProxyExpr* &expr, } return ret; } -int ObProxySelectStmt::handle_sort_list_node(ParseNode* node, const SortListType& sort_list_type) +int ObProxyDMLStmt::handle_sort_list_node(ParseNode* node, const SortListType& sort_list_type) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1622,7 +1562,7 @@ int ObProxySelectStmt::handle_sort_list_node(ParseNode* node, const SortListType } return ret; } -int ObProxySelectStmt::handle_with_rollup_in_groupby(ParseNode* node) +int ObProxyDMLStmt::handle_with_rollup_in_groupby(ParseNode* node) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1649,7 +1589,7 @@ int ObProxySelectStmt::handle_with_rollup_in_groupby(ParseNode* node) return ret; } -int ObProxySelectStmt::handle_groupby_clause(ParseNode* node) +int ObProxyDMLStmt::handle_groupby_clause(ParseNode* node) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1668,7 +1608,7 @@ int ObProxySelectStmt::handle_groupby_clause(ParseNode* node) return ret; } -int ObProxySelectStmt::handle_orderby_clause(ParseNode* node) +int ObProxyDMLStmt::handle_orderby_clause(ParseNode* node) { int ret = OB_SUCCESS; ParseNode* tmp_node = NULL; @@ -1687,6 +1627,20 @@ int ObProxySelectStmt::handle_orderby_clause(ParseNode* node) return ret; } +int ObProxySelectStmt::handle_parse_result(const ParseResult &parse_result) +{ + int ret = OB_SUCCESS; + ParseNode* node = parse_result.result_tree_->children_[0]; + + if (OB_FAIL(do_handle_parse_result(node))) { + LOG_WARN("fail to do handle parse result", K(sql_string_), "node_type", get_type_name(node->type_), K(ret)); + } else if (OB_FAIL(handle_comment_list(parse_result))) { + LOG_WARN("handle_comment_list failed", K(ret), K(sql_string_)); + } + + return ret; +} + int ObProxyInsertStmt::handle_parse_result(const ParseResult &parse_result) { int ret = OB_SUCCESS; @@ -1698,28 +1652,37 @@ int ObProxyInsertStmt::handle_parse_result(const ParseResult &parse_result) for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { ParseNode* tmp_node = node->children_[i]; if (NULL == tmp_node) { - continue; - } - switch (tmp_node->type_) { - case T_REPLACE: - stmt_type_ = OBPROXY_T_REPLACE; - break; - case T_SINGLE_TABLE_INSERT: - if (OB_FAIL(handle_single_table_insert(tmp_node))) { - LOG_WARN("handle single table insert failed", K(ret)); - } - break; - case T_INSERT: - //nothing - break; - default: - has_unsupport_expr_type_ = true; - LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); - break; + //do nothing + } else { + switch (tmp_node->type_) { + case T_REPLACE: + stmt_type_ = OBPROXY_T_REPLACE; + break; + case T_HINT_OPTION_LIST: + ret = handle_hint_clause(tmp_node); + break; + case T_SINGLE_TABLE_INSERT: + if (OB_FAIL(handle_single_table_insert(tmp_node))) { + LOG_WARN("handle single table insert failed", K(ret)); + } + break; + case T_INSERT: + //nothing + break; + default: + has_unsupport_expr_type_ = true; + LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); + break; + } } } } + if(OB_SUCC(ret)) { + if (OB_FAIL(handle_comment_list(parse_result))) { + LOG_WARN("handle_comment_list failed", K(ret), K(sql_string_)); + } + } return ret; } @@ -1729,27 +1692,33 @@ int ObProxyInsertStmt::handle_single_table_insert(ParseNode *node) for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { ParseNode* tmp_node = node->children_[i]; if (NULL == tmp_node) { - continue; - } - switch (tmp_node->type_) { - case T_INSERT_INTO_CLAUSE: - if (OB_FAIL(handle_insert_into(tmp_node))) { - LOG_WARN("fail to handle insert into", K(ret)); - } - break; - case T_VALUE_LIST: - if (OB_FAIL(handle_value_list(tmp_node))) { - LOG_WARN("fail to handle value list", K(ret)); - } - break; - case T_ASSIGN_LIST: - if (OB_FAIL(handle_assign_list(tmp_node))) { - LOG_WARN("fail to handle assign list", K(ret)); - } - break; - default: - has_unsupport_expr_type_ = true; - LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); + ///do nothing + } else { + switch (tmp_node->type_) { + case T_INSERT_INTO_CLAUSE: + if (OB_FAIL(handle_insert_into(tmp_node))) { + LOG_WARN("fail to handle insert into", K(ret)); + } + break; + case T_VALUE_LIST: + if (OB_FAIL(handle_value_list(tmp_node))) { + LOG_WARN("fail to handle value list", K(ret)); + } + break; + case T_ASSIGN_LIST: + if (OB_FAIL(handle_assign_list(tmp_node))) { + LOG_WARN("fail to handle assign list", K(ret)); + } + break; + case T_SELECT: + if (OB_FAIL(do_handle_parse_result(tmp_node))) { + LOG_WARN("fail to do handle parse result", "node_type", get_type_name(tmp_node->type_), K(ret)); + } + break; + default: + has_unsupport_expr_type_ = true; + LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); + } } } @@ -1762,23 +1731,24 @@ int ObProxyInsertStmt::handle_insert_into(ParseNode *node) for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { ParseNode* tmp_node = node->children_[i]; if (NULL == tmp_node) { - continue; - } - switch (tmp_node->type_) { - case T_ORG: - if (OB_FAIL(handle_table_node_to_expr(tmp_node))) { - LOG_WARN("handle org failed", K(ret)); - } - break; - case T_COLUMN_LIST: - if (OB_FAIL(handle_column_list(tmp_node))) { - LOG_WARN("handle column list failed", K(ret)); - } - break; - default: - has_unsupport_expr_type_ = true; - LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); - break; + //do nothing + } else { + switch (tmp_node->type_) { + case T_ORG: + if (OB_FAIL(handle_table_node_to_expr(tmp_node))) { + LOG_WARN("handle org failed", K(ret)); + } + break; + case T_COLUMN_LIST: + if (OB_FAIL(handle_column_list(tmp_node))) { + LOG_WARN("handle column list failed", K(ret)); + } + break; + default: + has_unsupport_expr_type_ = true; + LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); + break; + } } } @@ -1791,13 +1761,7 @@ int ObProxyInsertStmt::handle_value_list(ParseNode *node) for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { ParseNode *tmp_node = node->children_[i]; if (NULL == tmp_node) { - continue; - } - - // The writing method of insert inserting multiple rows is not supported - if (node->num_child_ > 1) { - ret = OB_ERR_BATCH_INSERT_FOUND; - LOG_WARN("replace more than one row", K(ret)); + //do nothing } else { switch (tmp_node->type_) { case T_VALUE_VECTOR: @@ -1822,17 +1786,18 @@ int ObProxyInsertStmt::handle_column_list(ParseNode *node) for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { ParseNode *tmp_node = node->children_[i]; if (NULL == tmp_node) { - continue; - } - switch (tmp_node->type_) { - case T_COLUMN_REF: - if (OB_FAIL(handle_column_ref_in_list(tmp_node))) { - LOG_WARN("handle column ref failed", K(ret)); - } - break; - default: - has_unsupport_expr_type_ = true; - LOG_WARN("unknown ndoe type", K_(tmp_node->type), K(ret)); + //do nothing + } else { + switch (tmp_node->type_) { + case T_COLUMN_REF: + if (OB_FAIL(handle_column_ref_in_list(tmp_node))) { + LOG_WARN("handle column ref failed", K(ret)); + } + break; + default: + has_unsupport_expr_type_ = true; + LOG_WARN("unknown ndoe type", K_(tmp_node->type), K(ret)); + } } } return ret; @@ -1842,64 +1807,85 @@ int ObProxyInsertStmt::handle_value_vector(ParseNode *node) { int ret = OB_SUCCESS; if (OB_UNLIKELY(column_name_array_.empty())) { - ret = OB_ERR_UNEXPECTED; + ret = OB_EXPR_CALC_ERROR; LOG_WARN("need column name in value vector", K(ret)); } else if (OB_UNLIKELY(node->num_child_ != column_name_array_.count())){ - ret = OB_ERR_PARSE_SQL; + ret = OB_ERR_PARSER_SYNTAX; LOG_WARN("the num of column name do not match value vector", K(ret)); } else { bool is_skip_field = false; SqlColumnValue column_value; for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { - column_value.reset(); - is_skip_field = false; ParseNode *tmp_node = node->children_[i]; + SqlField *sql_field = NULL; if (NULL == tmp_node) { - continue; - } - SqlField sql_field; - sql_field.column_name_.set(column_name_array_.at(i)); - switch (tmp_node->type_) { - case T_INT: - { - sql_field.value_type_ = TOKEN_INT_VAL; - sql_field.column_int_value_ = tmp_node->value_; - column_value.value_type_ = TOKEN_STR_VAL; - column_value.column_value_.set(tmp_node->str_value_); - sql_field.column_values_.push_back(column_value); - break; - } - case T_VARCHAR: - { - ret = handle_varchar_node_in_column_value(tmp_node, sql_field); - break; - } - default: - has_unsupport_expr_type_ = true; - is_skip_field = true; - LOG_WARN("unknown node type", "node type", tmp_node->type_, K(ret)); - break; - } - if (OB_SUCC(ret) && !is_skip_field) { - int duplicate_column_idx = -1; - for (int i = 0; i < field_results_->fields_.count(); i++) { - if (0 == sql_field.column_name_.get_string().case_compare(field_results_->fields_[i].column_name_.get_string())) { - duplicate_column_idx = i; + // do nothing + } else if (OB_ISNULL(sql_field = op_alloc(SqlField))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate memory for sqlfield", K(ret)); + } else { + is_skip_field = false; + column_value.reset(); + sql_field->column_name_.set_value(column_name_array_.at(i)); + switch (tmp_node->type_) { + case T_INT: + { + sql_field->value_type_ = TOKEN_INT_VAL; + sql_field->column_int_value_ = tmp_node->value_; + column_value.value_type_ = TOKEN_STR_VAL; + column_value.column_value_.set_value(tmp_node->str_value_); + ret = sql_field->column_values_.push_back(column_value); + break; + } + case T_VARCHAR: + { + ret = handle_varchar_node_in_column_value(tmp_node, *sql_field); + break; + } + case T_OP_NEG: + { + ParseNode *child_node = tmp_node->children_[0]; + if (child_node->type_ == T_INT) { + sql_field->value_type_ = TOKEN_INT_VAL; + sql_field->column_int_value_ = -1 * (child_node->value_); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unknown node type", K_(child_node->type), K(ret)); + } + break; + } + default: + column_value.value_type_ = TOKEN_NONE; + ret = sql_field->column_values_.push_back(column_value); + has_unsupport_expr_type_ = true; + LOG_WARN("unknown node type", "node type", tmp_node->type_, K(ret)); break; - } } - if (OB_UNLIKELY(-1 != duplicate_column_idx)) { - for (int i = 0; OB_SUCC(ret) && i < sql_field.column_values_.count(); i++) { - SqlColumnValue tmp_column_value = sql_field.column_values_[i]; - if (OB_FAIL(field_results_->fields_.at(duplicate_column_idx).column_values_.push_back(tmp_column_value))) { - LOG_WARN("push_back failed", K(ret), K(sql_string_)); + if (OB_SUCC(ret) && !is_skip_field) { + int duplicate_column_idx = -1; + for (int i = 0; i < field_results_->fields_.count(); i++) { + if (0 == sql_field->column_name_.config_string_.case_compare(field_results_->fields_[i]->column_name_.config_string_)) { + duplicate_column_idx = i; + break; } } - } else if (OB_FAIL(field_results_->fields_.push_back(sql_field))) { - LOG_WARN("push_back failed", K(ret), K(sql_string_)); - } else { - ++field_results_->field_num_; - LOG_DEBUG("add sql_field", K(sql_field), K(field_results_->field_num_)); + if (OB_UNLIKELY(-1 != duplicate_column_idx)) { + for (int i = 0; OB_SUCC(ret) && i < sql_field->column_values_.count(); i++) { + SqlColumnValue tmp_column_value = sql_field->column_values_[i]; + if (OB_FAIL(field_results_->fields_.at(duplicate_column_idx)->column_values_.push_back(tmp_column_value))) { + LOG_WARN("push_back failed", K(ret), K(sql_string_)); + } + } + } else if (OB_FAIL(field_results_->fields_.push_back(sql_field))) { + LOG_WARN("push_back failed", K(ret), K(sql_string_)); + } else { + ++field_results_->field_num_; + LOG_DEBUG("add sql_field", KPC(sql_field), K(field_results_->field_num_)); + } + } + if (OB_FAIL(ret) && NULL != sql_field) { + sql_field->reset(); + sql_field = NULL; } } } @@ -1926,23 +1912,27 @@ int ObProxyDeleteStmt::handle_parse_result(const ParseResult &parse_result) for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { ParseNode* tmp_node = node->children_[i]; if (NULL == tmp_node) { - continue; - } - switch (tmp_node->type_) { - case T_DELETE_TABLE_NODE: - if (OB_FAIL(handle_delete_table_node(tmp_node))) { - LOG_WARN("handle delete table node failed", K(ret)); - } - break; - case T_WHERE_CLAUSE: - if (OB_FAIL(handle_where_clause(tmp_node))) { - LOG_WARN("handle where clause failed", K(ret)); - } - break; - default: - has_unsupport_expr_type_ = true; - LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); - break; + //do nothing + } else { + switch (tmp_node->type_) { + case T_DELETE_TABLE_NODE: + if (OB_FAIL(handle_delete_table_node(tmp_node))) { + LOG_WARN("handle delete table node failed", K(ret)); + } + break; + case T_HINT_OPTION_LIST: + ret = handle_hint_clause(tmp_node); + break; + case T_WHERE_CLAUSE: + if (OB_FAIL(handle_where_clause(tmp_node))) { + LOG_WARN("handle where clause failed", K(ret)); + } + break; + default: + has_unsupport_expr_type_ = true; + LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); + break; + } } } } @@ -1956,17 +1946,18 @@ int ObProxyDeleteStmt::handle_delete_table_node(ParseNode *node) for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { ParseNode *tmp_node = node->children_[i]; if (NULL == tmp_node) { - continue; - } - switch (tmp_node->type_) { - case T_TABLE_REFERENCES: - if (OB_FAIL(handle_table_references(tmp_node))) { - LOG_WARN("handle table references failed", K(ret)); - } - break; - default: - has_unsupport_expr_type_ = true; - LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); + //do nothing + } else { + switch (tmp_node->type_) { + case T_TABLE_REFERENCES: + if (OB_FAIL(handle_table_references(tmp_node))) { + LOG_WARN("handle table references failed", K(ret)); + } + break; + default: + has_unsupport_expr_type_ = true; + LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); + } } } return ret; @@ -1984,28 +1975,32 @@ int ObProxyUpdateStmt::handle_parse_result(const ParseResult &parse_result) for (int i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { ParseNode* tmp_node = node->children_[i]; if (NULL == tmp_node) { - continue; - } - switch (tmp_node->type_) { - case T_TABLE_REFERENCES: - if (OB_FAIL(handle_table_references(tmp_node))) { - LOG_WARN("handle where clause failed", K(ret)); - } - break; - case T_ASSIGN_LIST: - if (OB_FAIL(handle_assign_list(tmp_node))) { - LOG_WARN("handle where clause failed", K(ret)); - } - break; - case T_WHERE_CLAUSE: - if (OB_FAIL(handle_where_clause(tmp_node))) { - LOG_WARN("handle where clause failed", K(ret)); - } - break; - default: - has_unsupport_expr_type_ = true; - LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); - break; + //do nothing + } else { + switch (tmp_node->type_) { + case T_TABLE_REFERENCES: + if (OB_FAIL(handle_table_references(tmp_node))) { + LOG_WARN("handle where clause failed", K(ret)); + } + break; + case T_HINT_OPTION_LIST: + ret = handle_hint_clause(tmp_node); + break; + case T_ASSIGN_LIST: + if (OB_FAIL(handle_assign_list(tmp_node))) { + LOG_WARN("handle where clause failed", K(ret)); + } + break; + case T_WHERE_CLAUSE: + if (OB_FAIL(handle_where_clause(tmp_node))) { + LOG_WARN("handle where clause failed", K(ret)); + } + break; + default: + has_unsupport_expr_type_ = true; + LOG_WARN("unknown node type", K_(tmp_node->type), K(ret)); + break; + } } } } diff --git a/src/obproxy/obutils/ob_proxy_stmt.h b/src/obproxy/obutils/ob_proxy_stmt.h index 7065401fc..39942588c 100644 --- a/src/obproxy/obutils/ob_proxy_stmt.h +++ b/src/obproxy/obutils/ob_proxy_stmt.h @@ -56,6 +56,39 @@ class ObProxyExprTablePos { ObProxyExprTable* table_expr_; }; +enum ShardingPosType { + SHARDING_POS_NONE = 0, + SHARDING_POS_DB, + SHARDING_POS_TABLE, +}; + +class ObProxyDbTablePos { +public: + ObProxyDbTablePos() : pos_(-1), name_(), type_(SHARDING_POS_NONE) {} + virtual ~ObProxyDbTablePos() {} + + void set_pos(const int32_t pos) { pos_ = pos; } + int32_t get_pos() { return pos_; } + + void set_type(const ShardingPosType type) { type_ = type; } + ShardingPosType get_type() { return type_; } + + void set_name(const ObString &name) { name_ = name; } + ObString &get_name() { return name_; } + + bool operator<(ObProxyDbTablePos &db_table_pos) + { + return pos_ < db_table_pos.get_pos(); + } + + TO_STRING_KV(K_(pos), K_(name), K_(type)); + +private: + int32_t pos_; + ObString name_; + ShardingPosType type_; +}; + class ObProxyStmt { public: ObProxyStmt(common::ObIAllocator& allocator) : stmt_type_(OBPROXY_T_INVALID), allocator_(allocator) {} @@ -71,11 +104,19 @@ class ObProxyStmt { common::ObString sql_string_; }; +enum SortListType { + SORT_LIST_NONE = 0, + SORT_LIST_IN_GROUP_BY, + SORT_LSIT_IN_ORDER_BY, + SORT_LIST_TYPE_MAX, +}; + class ObProxyDMLStmt : public ObProxyStmt { public: typedef common::hash::ObHashMap ExprMap; typedef common::ObSEArray TablePosArray; + typedef common::ObSEArray DbTablePosArray; public: ObProxyDMLStmt(common::ObIAllocator& allocator); @@ -96,6 +137,7 @@ class ObProxyDMLStmt : public ObProxyStmt bool has_unsupport_expr_type() const { return has_unsupport_expr_type_; } ExprMap& get_table_exprs_map() { return table_exprs_map_; } TablePosArray& get_table_pos_array() { return table_pos_array_; } + DbTablePosArray& get_db_table_pos_array() { return db_table_pos_array_; } protected: ObProxyExprType get_expr_type_by_node_type(const ObItemType& item_type); @@ -103,7 +145,7 @@ class ObProxyDMLStmt : public ObProxyStmt //for from int handle_from_list(ParseNode* node); - virtual int handle_table_node_to_expr(ParseNode* node); + int handle_table_node_to_expr(ParseNode* node); int get_table_and_db_expr(ParseNode* node, ObProxyExprTable* &expr_table); int handle_table_and_db_node(ParseNode* node, ObProxyExprTable* &expr_table); //for from in delete and update @@ -120,7 +162,7 @@ class ObProxyDMLStmt : public ObProxyStmt int handle_varchar_node_in_column_value(ParseNode* node, SqlField& sql_field); int handle_expr_list_node_in_column_value(ParseNode* node, SqlField& sql_field); int handle_column_ref_in_list(ParseNode *node); - virtual int column_ref_to_expr(ParseNode* node, ObProxyExpr* &expr, ObProxyExprTable* &expr_table); + int column_ref_to_expr(ParseNode* node, ObProxyExpr* &expr, ObProxyExprTable* &expr_table); int condition_exprs_to_sql_string(common::ObSqlString& sql_string); int limit_to_sql_string(common::ObSqlString& sql_string); @@ -146,21 +188,10 @@ class ObProxyDMLStmt : public ObProxyStmt ExprMap table_exprs_map_; ExprMap alias_table_map_; common::ObSEArray table_pos_array_; -}; - -enum SortListType { - SORT_LIST_NONE = 0, - SORT_LIST_IN_GROUP_BY, - SORT_LSIT_IN_ORDER_BY, - SORT_LIST_TYPE_MAX, -}; + common::ObSEArray db_table_pos_array_; -class ObProxySelectStmt : public ObProxyDMLStmt -{ +/*for sub select*/ public: - ObProxySelectStmt(common::ObIAllocator& allocator); - virtual ~ObProxySelectStmt(); - virtual int handle_parse_result(const ParseResult &parse_result); int handle_project_list(ParseNode* node); int handle_project_string(ParseNode* node); int handle_hint_clause(ParseNode* node); @@ -173,7 +204,7 @@ class ObProxySelectStmt : public ObProxyDMLStmt bool has_for_update() const { return has_for_update_; } int64_t get_from_token_off() { return from_token_off_; } -private: +protected: int project_string_to_expr(ParseNode* node, ObProxyExpr* &expr); int string_node_to_expr(ParseNode* node, ObProxyExpr* &expr, ParseNode* string_node = NULL); int alias_node_to_expr(ParseNode* node, ObProxyExpr* &expr, ParseNode* string_node = NULL); @@ -186,11 +217,9 @@ class ObProxySelectStmt : public ObProxyDMLStmt int max_node_to_expr(ParseNode* node, ObProxyExpr* &expr); int min_node_to_expr(ParseNode* node, ObProxyExpr* &expr); - int column_ref_to_expr(ParseNode* node, ObProxyExpr* &expr, ObProxyExprTable* &expr_table); int get_const_expr(ParseNode* node, ObProxyExpr* &expr); int get_sharding_const_expr(ParseNode* node, ObProxyExpr* &expr); - int handle_table_node_to_expr(ParseNode* node); int handle_table_and_db_in_hint(ParseNode* node); //for group by @@ -198,7 +227,7 @@ class ObProxySelectStmt : public ObProxyDMLStmt int handle_sort_list_node(ParseNode* node, const SortListType& sort_list_type); int handle_sort_key_node(ParseNode* node, ObProxyExpr* &expr, const SortListType& sort_list_type); -private: +protected: int do_handle_parse_result(ParseNode* node); int comments_to_sql_string(common::ObSqlString& sql_string); int hint_exprs_to_sql_string(common::ObSqlString& sql_string); @@ -206,16 +235,25 @@ class ObProxySelectStmt : public ObProxyDMLStmt int table_exprs_to_sql_string(common::ObSqlString& sql_string); int group_by_exprs_to_sql_string(common::ObSqlString& sql_string); int order_by_exprs_to_sql_string(common::ObSqlString& sql_string); -private: + int check_node_has_agg(ParseNode* node); public: common::ObSEArray select_exprs_; common::ObSEArray group_by_exprs_; //select groupby expression common::ObSEArray order_by_exprs_; -private: +protected: bool has_rollup_; bool has_for_update_; int64_t from_token_off_; + int64_t t_case_level_; +}; + +class ObProxySelectStmt : public ObProxyDMLStmt +{ +public: + ObProxySelectStmt(common::ObIAllocator& allocator) : ObProxyDMLStmt(allocator) {} + virtual ~ObProxySelectStmt() {} + virtual int handle_parse_result(const ParseResult &parse_result); }; class ObProxyInsertStmt : public ObProxyDMLStmt diff --git a/src/obproxy/obutils/ob_proxy_string_utils.cpp b/src/obproxy/obutils/ob_proxy_string_utils.cpp index 802876b9e..c32caeb5e 100644 --- a/src/obproxy/obutils/ob_proxy_string_utils.cpp +++ b/src/obproxy/obutils/ob_proxy_string_utils.cpp @@ -23,7 +23,7 @@ namespace obproxy { namespace obutils { -ObProxyVariantString::ObProxyVariantString():data_(NULL), data_size_(0) +ObProxyVariantString::ObProxyVariantString(): config_string_(), data_(NULL), data_size_(0) { } @@ -47,7 +47,7 @@ ObProxyVariantString& ObProxyVariantString::operator=(const ObProxyVariantString { if (&vstr != this) { reset(); - set_value(vstr.data_size_, vstr.data_); + set_value(vstr.config_string_.length(), vstr.config_string_.ptr()); } return *this; } @@ -92,6 +92,41 @@ bool ObProxyVariantString::set_value(const int32_t len, const char *value) return true; } +bool ObProxyVariantString::set_value_with_quote(const common::ObString &value, const char quote) +{ + return set_value_with_quote(value.length(), value.ptr(), quote); +} + +bool ObProxyVariantString::set_value_with_quote(const int32_t len, const char *value, const char quote) +{ + reset(); + data_size_ = len + 3; + data_ = (char*)ob_malloc(data_size_); + if (OB_ISNULL(data_)) { + LOG_WARN("ob_malloc failed", K_(data_size)); + return false; + } else { + data_[0] = quote; + MEMCPY(data_ + 1, value, len); + data_[len + 1] = quote; + data_[len + 2] = '\0'; + config_string_.assign_ptr(data_, len + 2); + } + + return true; +} + +void ObProxyVariantString::set_integer(const int64_t other) +{ + char buf[1024]; + const int32_t len = snprintf(buf, 1024, "%ld", other); + if (len <= 0 || len >= 1024) { + LOG_ERROR("snprintf failed", K(other)); + } else { + set_value(len, buf); + } +} + } // end of namespace obutils } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/obutils/ob_proxy_string_utils.h b/src/obproxy/obutils/ob_proxy_string_utils.h index 1e5ce7bd0..8bd004329 100644 --- a/src/obproxy/obutils/ob_proxy_string_utils.h +++ b/src/obproxy/obutils/ob_proxy_string_utils.h @@ -44,7 +44,10 @@ class ObProxyVariantString bool init(common::ObMalloc* allocator, const int64_t mod_id); bool set_value(const common::ObString &value); bool set_value(const int32_t len, const char *value); + bool set_value_with_quote(const common::ObString &value, const char quote); + bool set_value_with_quote(const int32_t len, const char *value, const char quote); uint64_t hash(uint64_t seed = 0) const { return config_string_.hash(seed); } + void set_integer(const int64_t other); common::ObString config_string_; DECLARE_TO_STRING; private: diff --git a/src/obproxy/obutils/ob_proxy_table_processor.h b/src/obproxy/obutils/ob_proxy_table_processor.h index 844245750..f847b0007 100644 --- a/src/obproxy/obutils/ob_proxy_table_processor.h +++ b/src/obproxy/obutils/ob_proxy_table_processor.h @@ -68,7 +68,7 @@ class ObProxyServerInfo DECLARE_TO_STRING; public: - char proxy_ip_[common::OB_IP_STR_BUFF]; // ip primary key + char proxy_ip_[common::MAX_IP_ADDR_LENGTH]; // ip primary key char regist_time_str_[common::OB_MAX_TIME_STR_LENGTH + 1]; // the time when one obproxy register to observer char app_name_[common::OB_MAX_APP_NAME_LENGTH + 1]; // application proxy used for char binary_version_[OB_MAX_PROXY_BINARY_VERSION_LEN + 1]; // man readable version diff --git a/src/obproxy/obutils/ob_proxy_table_processor_utils.cpp b/src/obproxy/obutils/ob_proxy_table_processor_utils.cpp index e1fdc15f8..7e8600dcd 100644 --- a/src/obproxy/obutils/ob_proxy_table_processor_utils.cpp +++ b/src/obproxy/obutils/ob_proxy_table_processor_utils.cpp @@ -453,7 +453,7 @@ int ObProxyTableProcessorUtils::fill_local_vt_cache(ObMysqlResultHandler &result int64_t tmp_real_str_len = 0; int64_t vid = 0; int64_t vport = 0; - char vip[OB_IP_STR_BUFF]; + char vip[MAX_IP_ADDR_LENGTH]; vip[0] = '\0'; ObString tenant_name; ObString cluster_name; @@ -472,7 +472,7 @@ int ObProxyTableProcessorUtils::fill_local_vt_cache(ObMysqlResultHandler &result while (OB_SUCC(ret) && OB_SUCC(result_handler.next())) { PROXY_EXTRACT_INT_FIELD_MYSQL(result_handler, "vid", vid, int64_t); - PROXY_EXTRACT_STRBUF_FIELD_MYSQL(result_handler, "vip", vip, OB_IP_STR_BUFF, tmp_real_str_len); + PROXY_EXTRACT_STRBUF_FIELD_MYSQL(result_handler, "vip", vip, MAX_IP_ADDR_LENGTH, tmp_real_str_len); PROXY_EXTRACT_INT_FIELD_MYSQL(result_handler, "vport", vport, int64_t); PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(result_handler, "tenant_name", tenant_name); PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(result_handler, "cluster_name", cluster_name); @@ -506,8 +506,7 @@ int ObProxyTableProcessorUtils::fill_local_vt_cache(ObMysqlResultHandler &result if (OB_ISNULL(vip_tenant = op_alloc(ObVipTenant))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to alloc memory for ObVipTenant", K(ret)); - } else if (FALSE_IT(vip_tenant->vip_addr_.set(ObAddr::convert_ipv4_addr(vip), - static_cast(vport), vid))) { + } else if (FALSE_IT(vip_tenant->vip_addr_.set(vip, static_cast(vport), vid))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to set vip_addr", K(vip), K(vport), K(vid), K(ret)); } else if (OB_FAIL(vip_tenant->set_tenant_cluster(tenant_name, cluster_name))) { @@ -522,16 +521,47 @@ int ObProxyTableProcessorUtils::fill_local_vt_cache(ObMysqlResultHandler &result } else if (OB_FAIL(cache_map.unique_set(vip_tenant))) { LOG_WARN("fail to insert one vip_tenant into cache_map", K(*vip_tenant), K(ret)); } else { - LOG_DEBUG("succ to insert one vip_tenant into cache_map", K(*vip_tenant)); - vip_tenant = NULL; - vid = 0; - vip[0] = '\0'; - vport = 0; - tenant_name.reset(); - cluster_name.reset(); - info_config = NULL; - request_target_type = -1; - rw_type = -1; + char request_target_buf[32]; + char rw_buf[32]; + ObString request_target_string; + ObString rw_string; + int32_t request_len = snprintf(request_target_buf, sizeof(request_target_buf), "%ld", request_target_type); + int32_t rw_len = snprintf(rw_buf, sizeof(rw_buf), "%ld", rw_type); + request_target_string.assign_ptr(request_target_buf, request_len); + rw_string.assign_ptr(rw_buf, rw_len); + if (OB_FAIL(get_global_config_processor().store_proxy_config_with_level( + vid, vip, vport, "", "", "proxy_tenant_name", tenant_name, "LEVEL_VIP"))) { + LOG_WARN("store proxy_tenant_name failed", K(vid), K(vip), K(vport), K(tenant_name), K(cluster_name), K(ret)); + } else if (OB_FAIL(get_global_config_processor().store_proxy_config_with_level( + vid, vip, vport, "", "", "rootservice_cluster_name", cluster_name, "LEVEL_VIP"))) { + LOG_WARN("store rootservice_cluster_name failed", K(vid), K(vip), K(vport), K(tenant_name), K(cluster_name), K(ret)); + } + if (OB_SUCC(ret) && -1 != rw_type) { + if (OB_FAIL(get_global_config_processor().store_proxy_config_with_level( + vid, vip, vport, tenant_name, cluster_name, "obproxy_read_only", rw_string, "LEVEL_VIP"))) { + LOG_WARN("store obporxy_read_only failed", K(vid), K(vip), K(vport), K(tenant_name), K(cluster_name), K(rw_type), K(ret)); + } + } + if (OB_SUCC(ret) && -1 != request_target_type) { + if (OB_FAIL(get_global_config_processor().store_proxy_config_with_level( + vid, vip, vport, tenant_name, cluster_name, "obproxy_read_consistency", request_target_string, "LEVEL_VIP"))) { + LOG_WARN("store obproxy_read_consistency failed", K(vid), K(vip), K(vport), K(tenant_name), K(cluster_name), K(request_target_type), K(ret)); + } + } + if (OB_SUCC(ret)) { + LOG_DEBUG("succ to insert one vip_tenant into cache_map", K(*vip_tenant)); + vip_tenant = NULL; + vid = 0; + vip[0] = '\0'; + vport = 0; + tenant_name.reset(); + cluster_name.reset(); + info_config = NULL; + request_target_type = -1; + rw_type = -1; + request_target_string.reset(); + rw_string.reset(); + } } }//end if OB_SUCCESS }//end of while @@ -554,23 +584,24 @@ int ObProxyTableProcessorUtils::fill_local_vt_cache(ObMysqlResultHandler &result int ObProxyTableProcessorUtils::get_proxy_local_addr(ObAddr &addr) { int ret = OB_SUCCESS; - char ip_str[OB_IP_STR_BUFF] = {'\0'}; + char ip_str[MAX_IP_ADDR_LENGTH] = {'\0'}; const ObHotUpgraderInfo &info = get_global_hot_upgrade_info(); in_port_t port = 0; ObIpAddr inbound_ip; // get inbound ip and port if (OB_LIKELY(info.is_inherited_)) { - if (OB_UNLIKELY(NO_FD == info.fd_)) { + // Does not support ipv6 yet + if (OB_UNLIKELY(NO_FD == info.ipv4_fd_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("this process is inherited born, but listen fd is invalid", - "is_inherited", info.is_inherited_, "fd", info.fd_, K(ret)); + "is_inherited", info.is_inherited_, "fd", info.ipv4_fd_, K(ret)); } else { struct sockaddr sock_addr; int64_t namelen = sizeof(sock_addr); memset(&sock_addr, 0, namelen); - if (OB_FAIL(ObSocketManager::getsockname(info.fd_, &sock_addr , &namelen))) { - LOG_WARN("fail to get sock name", K(info.fd_), K(ret)); + if (OB_FAIL(ObSocketManager::getsockname(info.ipv4_fd_, &sock_addr , &namelen))) { + LOG_WARN("fail to get sock name", K(info.ipv4_fd_), K(ret)); } else { struct sockaddr_in *ain = (sockaddr_in *)&sock_addr; inbound_ip.assign(sock_addr); @@ -590,7 +621,7 @@ int ObProxyTableProcessorUtils::get_proxy_local_addr(ObAddr &addr) // check valid if (OB_SUCC(ret)) { - inbound_ip.get_ip_str(ip_str, OB_IP_STR_BUFF); + inbound_ip.get_ip_str(ip_str, MAX_IP_ADDR_LENGTH); ObAddr any_addr(ObAddr::IPV4, INADDR_ANY_IP, port); ObAddr local_addr(ObAddr::IPV4, INADDR_LOOPBACK_IP, port); ObAddr inbound_addr(ObAddr::IPV4, ip_str, port); @@ -600,15 +631,15 @@ int ObProxyTableProcessorUtils::get_proxy_local_addr(ObAddr &addr) // if inbound_addr == 0.0.0.0 or 127.0.0.1, we treat it as not user specified ip, // and in this case, we get one local net addr; if (inbound_addr == any_addr || inbound_addr == local_addr) { - memset(ip_str, 0, OB_IP_STR_BUFF); - if (OB_FAIL(get_one_local_addr(ip_str, OB_IP_STR_BUFF))) { + memset(ip_str, 0, MAX_IP_ADDR_LENGTH); + if (OB_FAIL(get_one_local_addr(ip_str, MAX_IP_ADDR_LENGTH))) { LOG_WARN("fail to get one local addr", K(ret)); } } } if (OB_SUCC(ret)) { - addr.set_ipv4_addr(ip_str, port); + addr.set_ip_addr(ip_str, port); if (OB_UNLIKELY(!addr.is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid addr", K(addr), K(ret)); diff --git a/src/obproxy/obutils/ob_resource_pool_processor.cpp b/src/obproxy/obutils/ob_resource_pool_processor.cpp index c83f71b61..7a343bfd8 100644 --- a/src/obproxy/obutils/ob_resource_pool_processor.cpp +++ b/src/obproxy/obutils/ob_resource_pool_processor.cpp @@ -27,6 +27,7 @@ #include "obutils/ob_async_common_task.h" #include "lib/container/ob_array_iterator.h" #include "lib/container/ob_se_array_iterator.h" +#include "lib/encrypt/ob_encrypted_helper.h" using namespace obsys; using namespace oceanbase::common; @@ -511,7 +512,7 @@ int ObServerStateInfoInitCont::finish_task(void *data) const int64_t MAX_DISPLAY_STATUS_LEN = 64; char display_status_str[MAX_DISPLAY_STATUS_LEN]; ObServerStatus::DisplayStatus server_status = ObServerStatus::OB_DISPLAY_MAX; - char ip_str[OB_IP_STR_BUFF]; + char ip_str[MAX_IP_ADDR_LENGTH]; int64_t port = 0; int64_t tmp_real_str_len = 0; int64_t start_service_time = 0; @@ -548,7 +549,7 @@ int ObServerStateInfoInitCont::finish_task(void *data) PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(result_handler, "zone", zone_name); PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(result_handler, "zone_status", zone_status); - PROXY_EXTRACT_STRBUF_FIELD_MYSQL(result_handler, "svr_ip", ip_str, OB_IP_STR_BUFF, tmp_real_str_len); + PROXY_EXTRACT_STRBUF_FIELD_MYSQL(result_handler, "svr_ip", ip_str, MAX_IP_ADDR_LENGTH, tmp_real_str_len); PROXY_EXTRACT_INT_FIELD_MYSQL(result_handler, "svr_port", port, int64_t); PROXY_EXTRACT_INT_FIELD_MYSQL(result_handler, "start_service_time", start_service_time, int64_t); PROXY_EXTRACT_INT_FIELD_MYSQL(result_handler, "stop_time", stop_time, int64_t); @@ -1591,6 +1592,8 @@ int ObClusterResource::init(const common::ObString &cluster_name, int64_t cluste } else if (OB_FAIL(pending_list_.init("cr init pending list", reinterpret_cast(&(reinterpret_cast (0))->link_)))) { LOG_WARN("fail to init pending list", K(ret)); + } else if (OB_FAIL(alive_addr_set_.create(4))) { + LOG_WARN("alive_addr_set create failed", K(ret)); } else { is_inited_ = true; version_ = version; @@ -1619,10 +1622,34 @@ int ObClusterResource::init_local_config(const ObResourcePoolConfig &config) int64_t timeout_ms = usec_to_msec(config.short_async_task_timeout_); const ObString user_name(ObProxyTableInfo::READ_ONLY_USERNAME); const ObString database(ObProxyTableInfo::READ_ONLY_DATABASE); - ObString password(get_global_proxy_config().observer_sys_password.str()); - ObString password1(get_global_proxy_config().observer_sys_password1.str()); + ObString cluster_name = cluster_info_key_.cluster_name_.config_string_; + ObConfigItem item; + char password[ENC_STRING_BUF_LEN]; + char password1[ENC_STRING_BUF_LEN]; + memset(password, 0, sizeof (password)); + memset(password1, 0, sizeof (password1)); + + ObVipAddr addr; + if (OB_FAIL(get_global_config_processor().get_proxy_config( + addr, cluster_name, "", ObProxyTableInfo::OBSERVER_SYS_PASSWORD, item))) { + LOG_WARN("get observer_sys_password config failed", K(cluster_name), K(ret)); + } else { + MEMCPY(password, item.str(), strlen(item.str())); + } - if (OB_FAIL(mysql_proxy_.init(timeout_ms, user_name, password, database, password1))) { + if (OB_SUCC(ret)) { + if (OB_FAIL(get_global_config_processor().get_proxy_config( + addr, cluster_name, "", ObProxyTableInfo::OBSERVER_SYS_PASSWORD1, item))) { + LOG_WARN("get observer_sys_password1 config failed", K(cluster_name), K(ret)); + } else { + MEMCPY(password1, item.str(), strlen(item.str())); + } + } + + + if (OB_FAIL(ret)) { + // do nothing + } else if (OB_FAIL(mysql_proxy_.init(timeout_ms, user_name, password, database, cluster_name, password1))) { LOG_WARN("fail to init mysql proxy", K(ret)); } else if (OB_FAIL(rebuild_mysql_client_pool( get_global_resource_pool_processor().get_default_cluster_resource()))) { @@ -1956,7 +1983,7 @@ int ObClusterResource::update_location_tenant_info(ObSEArray &tenan } } // for } // if in wlock - + return ret; } @@ -2017,7 +2044,7 @@ uint64_t ObClusterResource::get_location_tenant_version(const ObString &tenant_n int ObClusterResource::get_location_tenant_info(const ObString &tenant_name, ObLocationTenantInfo *&info_out) { int ret = OB_SUCCESS; - + if (!tenant_name.empty() && tenant_name != OB_SYS_TENANT_NAME) { ObLocationTenantInfo *info = NULL; DRWLock::RDLockGuard lock(location_tenant_info_lock_); @@ -2057,52 +2084,16 @@ int ObLocationTenantInfo::resolve_location_tenant_info_primary_zone(ObString &pr // resolve to zone priority array // resolve to zone weight priority array - int i = 0; - int j = i; - int total_len = primary_zone_.length(); - const char *ptr = primary_zone_.ptr(); - ObSEArray tmp_pz_prio_array; - int8_t weight = 1; - - while (i < total_len && j < total_len) { - j++; - if (j >= total_len || ptr[j] == ';') { - if (j > i) { - ObString each_zone(j - i, ptr + i); - tmp_pz_prio_array.push_back(each_zone); - } - - if (tmp_pz_prio_array.count() > 0) { - for (int64_t k = 0; k < tmp_pz_prio_array.count(); k++) { - primary_zone_prio_array_.push_back(tmp_pz_prio_array.at(k)); - primary_zone_prio_weight_array_.push_back(weight); - } - tmp_pz_prio_array.reset(); - weight++; - } - i = j + 1; - j = i; - } else if (ptr[j] == ',') { - if (j > i) { - ObString each_zone(j - i, ptr + i); - tmp_pz_prio_array.push_back(each_zone); - } - i = j + 1; - j = i; - } else { - // nothing - } - } // while - - - if (primary_zone_prio_array_.count() != primary_zone_prio_weight_array_.count()) { + if (OB_FAIL(split_weight_group(primary_zone_, primary_zone_prio_array_, primary_zone_prio_weight_array_))) { + LOG_WARN("fail to resolve primary zone", K(ret), K(primary_zone_)); + } else if (primary_zone_prio_array_.count() != primary_zone_prio_weight_array_.count()) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected array count check", K(tenant_name_), K(version_), K(primary_zone_prio_array_.count()), + LOG_WARN("unexpected array count check", K(tenant_name_), K(version_), K(primary_zone_prio_array_.count()), K(primary_zone_prio_weight_array_.count())); } else { LOG_DEBUG("succ to resolve primary zone", KPC(this)); } - } + } return ret; } @@ -2202,11 +2193,12 @@ int ObResourcePoolProcessor::init(ObProxyConfig &config, proxy::ObMysqlProxy &me // impossible } else if (OB_FAIL(default_cr_->init_local_config(config_))) { LOG_WARN("fail to build local default cluster resource", K(ret)); + } else if (OB_FAIL(ip_set_.create(8))) { + LOG_WARN("ip_set create failed", K(ret)); } else { default_cr_->inc_ref(); default_sysvar_set_->inc_ref(); meta_client_proxy_ = &meta_client_proxy; - ip_set_.create(8); is_inited_ = true; } diff --git a/src/obproxy/obutils/ob_resource_pool_processor.h b/src/obproxy/obutils/ob_resource_pool_processor.h index 6777e03f8..b48479570 100644 --- a/src/obproxy/obutils/ob_resource_pool_processor.h +++ b/src/obproxy/obutils/ob_resource_pool_processor.h @@ -228,7 +228,7 @@ class ObClusterResource : public common::ObSharedRefCount cluster_info_key_(), last_access_time_ns_(0), deleting_completed_thread_num_(0), version_(0), fetch_rslist_task_count_(0), fetch_idc_list_task_count_(0), last_idc_list_refresh_time_ns_(0), last_rslist_refresh_time_ns_(0), - pending_list_(), cluster_version_(0), is_inited_(false), cr_state_(CR_BORN), sys_ldg_info_map_(), + pending_list_(), cluster_version_(0), alive_addr_set_(), is_inited_(false), cr_state_(CR_BORN), sys_ldg_info_map_(), sys_ldg_info_lock_(), location_tenant_info_lock_(), location_tenant_info_map_() {} virtual ~ObClusterResource() {} virtual void free(); @@ -358,6 +358,7 @@ class ObClusterResource : public common::ObSharedRefCount int64_t last_rslist_refresh_time_ns_; common::ObAtomicList pending_list_; int64_t cluster_version_; + common::hash::ObHashSet alive_addr_set_; LINK(ObClusterResource, cr_link_); private: diff --git a/src/obproxy/obutils/ob_server_state_processor.cpp b/src/obproxy/obutils/ob_server_state_processor.cpp index d08665b60..346ade5fd 100644 --- a/src/obproxy/obutils/ob_server_state_processor.cpp +++ b/src/obproxy/obutils/ob_server_state_processor.cpp @@ -91,6 +91,8 @@ class ObDetectOneServerStateCont : public obutils::ObAsyncCommonTask private: ObClusterResource *cluster_resource_; ObAddr addr_; + ObMysqlClient *mysql_client_; + ObMysqlProxy mysql_proxy_; private: DISALLOW_COPY_AND_ASSIGN(ObDetectOneServerStateCont); @@ -606,7 +608,7 @@ int ObServerStateRefreshCont::handle_all_tenant(void *data) } } } - + if (ret != OB_ITER_END) { // handle case of fail to access __all_tenant on alipay main site: do not exec error handling process if (ER_TABLEACCESS_DENIED_ERROR == resp->get_err_code()) { @@ -623,7 +625,7 @@ int ObServerStateRefreshCont::handle_all_tenant(void *data) } ret = OB_SUCCESS; } - + if (OB_SUCC(ret) && OB_FAIL(schedule_refresh_server_state())) { LOG_WARN("fail to schedule refresh server state", K(ret)); } @@ -1236,8 +1238,7 @@ int ObServerStateRefreshCont::do_update_server(const ObServerStateInfo &ss_info) } } - ObIpEndpoint ip; - ops_ip_copy(ip.sa_, ss_info.replica_.server_.get_ipv4(), static_cast(ss_info.replica_.server_.get_port())); + ObIpEndpoint ip(ss_info.replica_.server_.get_sockaddr()); if (!need_update && ObCongestionEntry::ACTIVE == ss_info.cgt_server_state_) { if (OB_HASH_EXIST == get_global_resource_pool_processor().ip_set_.exist_refactored(ip)) { need_update = true; @@ -1504,8 +1505,7 @@ int ObServerStateRefreshCont::handle_deleted_server(ObIArray } if (!found) { LOG_INFO("deleted server", "ss_info", last_ss_info); - ops_ip_copy(ip.sa_, last_ss_info.replica_.server_.get_ipv4(), - static_cast(last_ss_info.replica_.server_.get_port())); + ip.assign(last_ss_info.replica_.server_.get_sockaddr()); int64_t cr_version = cluster_resource_->version_; if (OB_FAIL(congestion_manager_->update_server(ip, cr_version, ObCongestionEntry::DELETED, last_ss_info.zone_state_->zone_name_, @@ -1666,7 +1666,7 @@ int ObServerStateRefreshUtils::get_server_state_info( { int ret = OB_SUCCESS; - char ip_str[OB_IP_STR_BUFF]; + char ip_str[MAX_IP_ADDR_LENGTH]; int64_t port = 0; ObServerStateInfo server_state; const int64_t MAX_DISPLAY_STATUS_LEN = 64; @@ -1682,7 +1682,7 @@ int ObServerStateRefreshUtils::get_server_state_info( display_status_str[0] = '\0'; zone_name[0] = '\0'; PROXY_EXTRACT_STRBUF_FIELD_MYSQL(result_handler, "svr_ip", ip_str, - OB_IP_STR_BUFF, tmp_real_str_len); + MAX_IP_ADDR_LENGTH, tmp_real_str_len); PROXY_EXTRACT_INT_FIELD_MYSQL(result_handler, "svr_port", port, int64_t); PROXY_EXTRACT_STRBUF_FIELD_MYSQL(result_handler, "zone", zone_name, MAX_ZONE_LENGTH + 1, zone_name_len); @@ -1921,7 +1921,7 @@ DEF_TO_STRING(ObDetectServerStateCont) int ObDetectServerStateCont::schedule_detect_server_state() { int ret = OB_SUCCESS; - bool enable_server_detect = (0 < get_global_proxy_config().server_detect_mode); + const int64_t server_detect_mode = get_global_proxy_config().server_detect_mode; if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("not init", K_(is_inited), K(ret)); @@ -1931,7 +1931,7 @@ int ObDetectServerStateCont::schedule_detect_server_state() } else if (OB_UNLIKELY(!self_ethread().is_event_thread_type(ET_CALL))) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("server state refresh cont must be scheduled in work thread", K(ret)); - } else if (enable_server_detect) { + } else if (server_detect_mode > 0) { int64_t ss_version = cluster_resource_->server_state_version_; common::DRWLock &server_state_lock = cluster_resource_->get_server_state_lock(ss_version); server_state_lock.rdlock(); @@ -1942,11 +1942,14 @@ int ObDetectServerStateCont::schedule_detect_server_state() for (int i = 0; i < server_state_info.count(); i++) { ObServerStateSimpleInfo &info = server_state_info.at(i); - bool need_check = common::ObTimeUtility::current_time() - info.last_response_time_ >= 5 * 1000 * 1000; - int64_t cnt = info.request_sql_cnt_; + bool check_pass = true; + // Accurate detection method + if (1 == server_detect_mode) { + check_pass = (info.request_sql_cnt_ > 0); + LOG_DEBUG("check detect one server", K(server_detect_mode), K_(info.request_sql_cnt), K(check_pass)); + } - LOG_DEBUG("check need schedule one server", K(info), K(need_check), K(cnt)); - if ((cnt > 0 && need_check) || info.detect_fail_cnt_ > 0) { + if (check_pass || info.detect_fail_cnt_ > 0) { // There is no need to judge whether the push_back is successful here ObDetectOneServerStateCont *cont = NULL; if (OB_ISNULL(cont = op_alloc(ObDetectOneServerStateCont))) { @@ -1960,13 +1963,11 @@ int ObDetectServerStateCont::schedule_detect_server_state() } LOG_DEBUG("schedule detect one server state", K(info), K(ss_version)); } else { - struct sockaddr_in in; - in.sin_family = AF_INET; - in.sin_port = (htons)(static_cast(info.addr_.get_port())); - in.sin_addr.s_addr = htonl(info.addr_.ip_.v4_); - ObIpEndpoint point(*reinterpret_cast(&in)); + ObIpEndpoint point(info.addr_.get_sockaddr()); if (OB_HASH_EXIST == get_global_resource_pool_processor().ip_set_.exist_refactored(point)) { addr_set.set_refactored(info.addr_); + } else if (OB_HASH_EXIST == cluster_resource_->alive_addr_set_.exist_refactored(point)) { + addr_set.set_refactored(info.addr_); } } } @@ -1997,11 +1998,11 @@ int ObDetectServerStateCont::schedule_detect_server_state() HRTIME_USECONDS(server_detect_state_interval_us_), DETECT_SERVER_STATE_EVENT))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to schedule refresh server state", K_(server_detect_state_interval_us), - K(enable_server_detect), KPC_(cluster_resource), K(ret)); + K(server_detect_mode), KPC_(cluster_resource), K(ret)); } LOG_DEBUG("schedule detect server state", K_(server_detect_state_interval_us), - K(enable_server_detect), KPC_(cluster_resource), K(ret)); + K(server_detect_mode), KPC_(cluster_resource), K(ret)); return ret; } @@ -2096,7 +2097,8 @@ int ObDetectServerStateCont::set_detect_server_state_interval(const int64_t refr ObDetectOneServerStateCont::ObDetectOneServerStateCont() : ObAsyncCommonTask(NULL, "detect_server_state_task"), - cluster_resource_(NULL), addr_() + cluster_resource_(NULL), addr_(), mysql_client_(NULL), + mysql_proxy_() { SET_HANDLER(&ObDetectOneServerStateCont::main_handler); } @@ -2104,13 +2106,33 @@ ObDetectOneServerStateCont::ObDetectOneServerStateCont() int ObDetectOneServerStateCont::init(ObClusterResource *cluster_resource, ObAddr addr) { int ret = OB_SUCCESS; + const int64_t timeout_ms = usec_to_msec(get_global_proxy_config().detect_server_timeout); if (OB_UNLIKELY(NULL == cluster_resource || !addr.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("init obdetectserverstate cont failed", K(cluster_resource), K(ret)); + // The detection only depends on whether OBServer returns OB_MYSQL_COM_HANDSHAKE, + // and will not log in. The following parameters will not be actually used, + // only for the initialization of class objects + // user_name : detect_username + // password : detect_password + // database : detect_database + } else if (OB_FAIL(mysql_proxy_.init(timeout_ms, ObProxyTableInfo::DETECT_USERNAME_USER, "detect_password", "detect_database"))) { + LOG_WARN("fail to init mysql proxy", K(ret)); } else { cluster_resource->inc_ref(); cluster_resource_ = cluster_resource; addr_ = addr; + if (OB_ISNULL(mysql_client_ = op_alloc(ObMysqlClient))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate ObMysqlClient", K(ret)); + } else if (OB_FAIL(mysql_client_->init_detect_client(cluster_resource_))) { + LOG_WARN("fail to init detect client", K(ret)); + } + + if (OB_FAIL(ret) && (NULL != mysql_client_)) { + mysql_client_->kill_this(); + mysql_client_ = NULL; + } } return ret; @@ -2124,6 +2146,10 @@ void ObDetectOneServerStateCont::kill_this() cluster_resource_->dec_ref(); cluster_resource_ = NULL; } + if (OB_LIKELY(NULL != mysql_client_)) { + mysql_client_->kill_this(); + mysql_client_ = NULL; + } if (OB_FAIL(cancel_timeout_action())) { LOG_WARN("fail to cancel timeout action", K(ret)); } @@ -2174,14 +2200,15 @@ int ObDetectOneServerStateCont::main_handler(int event, void *data) int ObDetectOneServerStateCont::detect_server_state_by_sql() { int ret = OB_SUCCESS; - ObMysqlProxy *mysql_proxy = &cluster_resource_->mysql_proxy_; - char sql[] = "select 'detect server alive' from dual"; + char sql[] = "select 'detect server' from dual"; LOG_DEBUG("begin to detect server", K_(addr)); ObMysqlRequestParam request_param(sql); request_param.set_target_addr(addr_); + request_param.set_mysql_client(mysql_client_); + request_param.set_is_detect_client(true); const int64_t timeout_ms = usec_to_msec(get_global_proxy_config().detect_server_timeout); - if (OB_FAIL(mysql_proxy->async_read(this, request_param, pending_action_, timeout_ms))) { - LOG_WARN("fail to nonblock read", K(sql), K(ret)); + if (OB_FAIL(mysql_proxy_.async_read(this, request_param, pending_action_, timeout_ms))) { + LOG_WARN("fail to async read", K(ret)); } return ret; @@ -2199,24 +2226,26 @@ int ObDetectOneServerStateCont::handle_client_resp(void *data) bool found = false; for (int i = 0; !found && i < server_state_info.count(); i++) { ObServerStateSimpleInfo &info = server_state_info.at(i); - ObIpEndpoint ip; + ObIpEndpoint ip(info.addr_.get_sockaddr()); ObCongestionEntry::ObServerState state = ObCongestionEntry::ObServerState::ACTIVE; - ops_ip_copy(ip.sa_, info.addr_.get_ipv4(), static_cast(info.addr_.get_port())); if (addr_ == info.addr_) { if (NULL != data) { (void)ATOMIC_SET(&info.detect_fail_cnt_, 0); state = ObCongestionEntry::ObServerState::DETECT_ALIVE; - LOG_DEBUG("succe to get resp from server", K(info)); + cluster_resource_->alive_addr_set_.erase_refactored(ip); + get_global_resource_pool_processor().ip_set_.erase_refactored(ip); + LOG_DEBUG("detect server alive", K(info)); } else { int64_t fail_cnt = ATOMIC_AAF(&info.detect_fail_cnt_, 1); - LOG_WARN("detect server alive failed", K(info)); + LOG_WARN("detect server dead", K(info)); if (fail_cnt >= get_global_proxy_config().server_detect_fail_threshold) { // If the detection failure exceeds the number of retries, the server needs to be added to the blacklist (void)ATOMIC_SET(&info.detect_fail_cnt_, 0); state = ObCongestionEntry::ObServerState::DETECT_DEAD; + get_global_resource_pool_processor().ip_set_.set_refactored(ip); } } - + if (ObCongestionEntry::ObServerState::DETECT_DEAD == state || ObCongestionEntry::ObServerState::DETECT_ALIVE == state) { ObCongestionManager &congestion_manager = cluster_resource_->congestion_manager_; @@ -2232,9 +2261,9 @@ int ObDetectOneServerStateCont::handle_client_resp(void *data) } if (!found) { - ObIpEndpoint ip; - ops_ip_copy(ip.sa_, addr_.get_ipv4(), static_cast(addr_.get_port())); + ObIpEndpoint ip(addr_.get_sockaddr()); get_global_resource_pool_processor().ip_set_.erase_refactored(ip); + cluster_resource_->alive_addr_set_.erase_refactored(ip); LOG_WARN("server not in cluster", K(ip), KPC_(cluster_resource)); } server_state_lock2.rdunlock(); diff --git a/src/obproxy/obutils/ob_state_info.h b/src/obproxy/obutils/ob_state_info.h index f6d450e8f..f039bd8dc 100644 --- a/src/obproxy/obutils/ob_state_info.h +++ b/src/obproxy/obutils/ob_state_info.h @@ -286,7 +286,7 @@ inline int ObServerStateInfo::add_addr(const char *ip, const int64_t port) inline ObServerStateSimpleInfo &ObServerStateSimpleInfo::operator=(const ObServerStateSimpleInfo &other) { if (this != &other) { - addr_.set_ipv4_addr(other.addr_.get_ipv4(), other.addr_.get_port()); + addr_ = other.addr_; is_merging_ = other.is_merging_; is_force_congested_ = other.is_force_congested_; zone_type_ = other.zone_type_; @@ -329,8 +329,8 @@ inline int ObServerStateSimpleInfo::set_addr(const common::ObAddr &addr) if (OB_UNLIKELY(!addr.is_valid())) { ret = common::OB_INVALID_ARGUMENT; PROXY_LOG(WARN, "invalid argument", K(addr), K(ret)); - } else if (OB_UNLIKELY(!addr_.set_ipv4_addr(addr.get_ipv4(), addr.get_port()))) { - ret = common::OB_INVALID_ARGUMENT; + } else { + addr_ = addr; } return ret; } @@ -338,7 +338,7 @@ inline int ObServerStateSimpleInfo::set_addr(const common::ObAddr &addr) inline int ObServerStateSimpleInfo::set_addr(const char *ip, const int64_t port) { int ret = common::OB_SUCCESS; - if (OB_UNLIKELY(!addr_.set_ipv4_addr(ip, static_cast(port)))) { + if (OB_UNLIKELY(!addr_.set_ip_addr(ip, static_cast(port)))) { ret = common::OB_INVALID_ARGUMENT; } return ret; diff --git a/src/obproxy/obutils/ob_vip_tenant_cache.cpp b/src/obproxy/obutils/ob_vip_tenant_cache.cpp index 0d3a41d50..51b27f90b 100644 --- a/src/obproxy/obutils/ob_vip_tenant_cache.cpp +++ b/src/obproxy/obutils/ob_vip_tenant_cache.cpp @@ -23,7 +23,19 @@ namespace obproxy namespace obutils { -void ObVipAddr::set(const int32_t ip, const int32_t port, const int64_t vid) +void ObVipAddr::set(const char* ip, const int32_t port, const int64_t vid) +{ + if (NULL == ip || 0 == strcasecmp(ip, "") || port <= 0) { + addr_.reset(); + } else if (OB_UNLIKELY(!addr_.set_ip_addr(ip, port))) { + LOG_WARN("fail to set_ip_addr", K(ip), K(port), K(addr_)); + addr_.reset(); + } else { + vid_ = vid; + } +} + +void ObVipAddr::set_ipv4(int32_t ip, const int32_t port, const int64_t vid) { if (OB_UNLIKELY(!addr_.set_ipv4_addr(ip, port))) { LOG_WARN("fail to set_ipv4_addr", K(ip), K(port), K(addr_)); @@ -33,6 +45,12 @@ void ObVipAddr::set(const int32_t ip, const int32_t port, const int64_t vid) } } +void ObVipAddr::set(const struct sockaddr &addr, const int64_t vid) +{ + addr_.set_sockaddr(addr); + vid_ = vid; +} + int ObVipTenant::set_tenant_cluster(const ObString &tenant_name, const ObString &cluster_name) { int ret = OB_SUCCESS; diff --git a/src/obproxy/obutils/ob_vip_tenant_cache.h b/src/obproxy/obutils/ob_vip_tenant_cache.h index 487c6b0a5..95c2aefac 100644 --- a/src/obproxy/obutils/ob_vip_tenant_cache.h +++ b/src/obproxy/obutils/ob_vip_tenant_cache.h @@ -24,6 +24,19 @@ namespace obproxy namespace obutils { +enum ObVipTenantRequestType +{ + InvalidRequestType = -1, + RequestLeader, + RequestFollower, +}; +enum ObVipTenantRWType +{ + InvalidRWType = -1, + ReadOnly, + ReadWrite, +}; + struct ObVipAddr { public: @@ -33,7 +46,9 @@ struct ObVipAddr bool is_valid() const { return (addr_.is_valid() && vid_ >= 0); } void reset() { vid_ = -1; addr_.reset(); } bool operator==(const ObVipAddr &vip_addr) const { return (vip_addr.vid_ == vid_ && vip_addr.addr_ == addr_); } - void set(const int32_t ip, const int32_t port, const int64_t vid); + void set(const char* ip, const int32_t port, const int64_t vid); + void set_ipv4(int32_t ip, const int32_t port, const int64_t vid); + void set(const struct sockaddr &addr, const int64_t vid); TO_STRING_KV(K_(addr), K_(vid)); public: @@ -43,20 +58,6 @@ struct ObVipAddr struct ObVipTenant { -private: - enum ObVipTenantRequestType - { - InvalidRequestType = -1, - RequestLeader, - RequestFollower, - }; - enum ObVipTenantRWType - { - InvalidRWType = -1, - ReadOnly, - ReadWrite, - }; - public: ObVipTenant() : vip_addr_(), tenant_name_(), cluster_name_(), request_target_type_(InvalidRequestType), rw_type_(InvalidRWType) diff --git a/src/obproxy/omt/ob_conn_table_processor.cpp b/src/obproxy/omt/ob_conn_table_processor.cpp index bf49a3254..73bb19ee6 100644 --- a/src/obproxy/omt/ob_conn_table_processor.cpp +++ b/src/obproxy/omt/ob_conn_table_processor.cpp @@ -49,7 +49,7 @@ using namespace oceanbase::obproxy::obutils; using namespace oceanbase::json; extern int build_tenant_cluster_vip_name(const ObString &tenant_name, const ObString &cluster_name, const ObString &vip_name, - ObFixedLengthString &key_string); + ObFixedLengthString &key_string); int ObConnTableProcessor::commit(bool is_success) { @@ -111,7 +111,7 @@ int ObConnTableProcessor::inc_conn(ObString& cluster_name, ObString& tenant_name int ret = OB_SUCCESS; ObString key_name; ObUsedConn* used_conn = NULL; - common::ObFixedLengthString key_string; + common::ObFixedLengthString key_string; if (OB_FAIL(build_tenant_cluster_vip_name(tenant_name, cluster_name, ip_name, key_string))) { LOG_WARN("build tenant cluser vip name failed", K(tenant_name), K(cluster_name), K(ip_name), K(ret)); } else { @@ -131,7 +131,7 @@ void ObConnTableProcessor::dec_conn( int ret = OB_SUCCESS; ObUsedConn* used_conn = NULL; int64_t cur_used_connections = 0; - common::ObFixedLengthString key_string; + common::ObFixedLengthString key_string; if (OB_FAIL(build_tenant_cluster_vip_name(tenant_name, cluster_name, ip_name, key_string))) { LOG_WARN("build tenant cluster vip name failed", K(ret), K(tenant_name), K(cluster_name), K(ip_name)); @@ -161,7 +161,7 @@ int ObConnTableProcessor::get_vt_conn_object( { int ret = OB_SUCCESS; - common::ObFixedLengthString key_string; + common::ObFixedLengthString key_string; if (OB_FAIL(build_tenant_cluster_vip_name(tenant_name, cluster_name, vip_name, key_string))) { LOG_WARN("build tenant cluser vip name failed", K(ret), K(tenant_name), K(cluster_name), K(vip_name)); } else { @@ -193,7 +193,7 @@ int ObConnTableProcessor::alloc_and_init_vt_conn( } else if (OB_ISNULL(tmp_vt_conn = op_alloc(ObVipTenantConn))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to alloc memory for ObVipTenantConn", K(ret)); - } else if (OB_FAIL(tmp_vt_conn->set(cluster_name, tenant_name, vip_name, max_connections))) { + } else if (OB_FAIL(tmp_vt_conn->set(cluster_name, tenant_name, vip_name, max_connections))) { LOG_WARN("fail to set vip tenant connect info", K(ret)); } else { vt_conn = tmp_vt_conn; @@ -211,11 +211,11 @@ int ObConnTableProcessor::alloc_and_init_vt_conn( // local vip json format: //[ // { -// "vip" : "127.0.0.1", +// "vip" : "127.0.0.1", // "value" : "1000" // }, // { -// "vip" : "0.0.0.1", +// "vip" : "0.0.0.1", // "value" : "2000" // } //] @@ -328,7 +328,7 @@ int ObConnTableProcessor::conn_handle_replace_config( return ret; } -int ObConnTableProcessor::conn_handle_delete_config(ObString& cluster_name, ObString& tenant_name) +int ObConnTableProcessor::conn_handle_delete_config(ObString& cluster_name, ObString& tenant_name) { int ret = OB_SUCCESS; diff --git a/src/obproxy/omt/ob_cpu_table_processor.cpp b/src/obproxy/omt/ob_cpu_table_processor.cpp index 2e018203e..dc9638e0d 100644 --- a/src/obproxy/omt/ob_cpu_table_processor.cpp +++ b/src/obproxy/omt/ob_cpu_table_processor.cpp @@ -51,7 +51,7 @@ using namespace oceanbase::obproxy::obutils; using namespace oceanbase::json; extern int build_tenant_cluster_vip_name(const ObString &tenant_name, const ObString &cluster_name, const ObString &vip_name, - ObFixedLengthString &key_string); + ObFixedLengthString &key_string); void ObCpuTableProcessor::commit(bool is_success) { @@ -214,7 +214,7 @@ int ObCpuTableProcessor::handle_cpu_config( int ret = OB_SUCCESS; ObString key_name; ObTenantCpu* tenant_cpu = NULL; - common::ObFixedLengthString key_string; + common::ObFixedLengthString key_string; if (max_cpu_usage <= 0) { ret = OB_ERR_UNEXPECTED; LOG_WARN("max cpu usage error", K(max_cpu_usage), K(ret)); diff --git a/src/obproxy/omt/ob_proxy_config_table_processor.cpp b/src/obproxy/omt/ob_proxy_config_table_processor.cpp index f07e9b83a..f3a1966ac 100644 --- a/src/obproxy/omt/ob_proxy_config_table_processor.cpp +++ b/src/obproxy/omt/ob_proxy_config_table_processor.cpp @@ -38,7 +38,17 @@ #include "cmd/ob_internal_cmd_processor.h" static const char *config_name_array[] = {"proxy_route_policy", "proxy_idc_name", "enable_cloud_full_username", - "enable_client_ssl", "enable_server_ssl"}; + "enable_client_ssl", "enable_server_ssl", + "obproxy_read_consistency", "obproxy_read_only", + "proxy_tenant_name", "rootservice_cluster_name", + "enable_read_write_split", "enable_transaction_split", + "target_db_server", "observer_sys_password", + "observer_sys_password1"}; + +static const char *EXECUTE_SQL = + "replace into proxy_config(vip, vid, vport, cluster_name, tenant_name, name, value, config_level) values(" + "'%.*s', %ld, %ld, '%.*s', '%.*s', '%s', '%s', '%.*s')"; + using namespace oceanbase::common; using namespace oceanbase::obproxy::obutils; namespace oceanbase @@ -143,12 +153,19 @@ int ObProxyConfigTableProcessor::commit(void *arg, bool is_success) LOG_WARN("proxy config commit failed", K(is_success)); } + get_global_proxy_config_table_processor().clear_execute_sql(); get_global_proxy_config_table_processor().clean_hashmap( get_global_proxy_config_table_processor().get_backup_hashmap()); return OB_SUCCESS; } +int ObProxyConfigTableProcessor::before_commit(void *arg) +{ + sqlite3 *db = (sqlite3*)arg; + return get_global_proxy_config_table_processor().commit_execute_sql(db); +} + void ObProxyConfigTableProcessor::inc_index() { DRWLock::WRLockGuard guard(proxy_config_lock_); @@ -167,6 +184,7 @@ int ObProxyConfigTableProcessor::init() ObConfigHandler handler; handler.execute_func_ = &ObProxyConfigTableProcessor::execute; handler.commit_func_ = &ObProxyConfigTableProcessor::commit; + handler.before_commit_func_ = &ObProxyConfigTableProcessor::before_commit; if (OB_FAIL(get_global_config_processor().register_callback("proxy_config", handler))) { LOG_WARN("register proxy config table callback failed", K(ret)); } @@ -237,15 +255,15 @@ int ObProxyConfigTableProcessor::set_proxy_config(void *arg) ObString name; SqlFieldResult *sql_fields = static_cast(arg); for (int i = 0; OB_SUCC(ret) && i < sql_fields->field_num_; i++) { - SqlField &sql_field = sql_fields->fields_.at(i); - if (0 == sql_field.column_name_.string_.case_compare("vip")) { + SqlField &sql_field = *(sql_fields->fields_.at(i)); + if (0 == sql_field.column_name_.config_string_.case_compare("vip")) { if (TOKEN_STR_VAL != sql_field.value_type_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); } else { vip = sql_field.column_value_.config_string_; } - } else if (0 == sql_field.column_name_.string_.case_compare("vport")) { + } else if (0 == sql_field.column_name_.config_string_.case_compare("vport")) { if (TOKEN_STR_VAL == sql_field.value_type_) { vport = atoi(sql_field.column_value_.config_string_.ptr()); } else if (TOKEN_INT_VAL == sql_field.value_type_) { @@ -254,7 +272,7 @@ int ObProxyConfigTableProcessor::set_proxy_config(void *arg) ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid value type", K(sql_field.value_type_), K(ret)); } - } else if (0 == sql_field.column_name_.string_.case_compare("vid")) { + } else if (0 == sql_field.column_name_.config_string_.case_compare("vid")) { if (TOKEN_STR_VAL == sql_field.value_type_) { vid = atoi(sql_field.column_value_.config_string_.ptr()); } else if (TOKEN_INT_VAL == sql_field.value_type_) { @@ -263,28 +281,28 @@ int ObProxyConfigTableProcessor::set_proxy_config(void *arg) ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid value type", K(sql_field.value_type_), K(ret)); } - } else if (0 == sql_field.column_name_.string_.case_compare("config_level")) { + } else if (0 == sql_field.column_name_.config_string_.case_compare("config_level")) { if (TOKEN_STR_VAL != sql_field.value_type_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); } else { item->config_level_.assign(sql_field.column_value_.config_string_.ptr()); } - } else if (0 == sql_field.column_name_.string_.case_compare("tenant_name")) { + } else if (0 == sql_field.column_name_.config_string_.case_compare("tenant_name")) { if (TOKEN_STR_VAL != sql_field.value_type_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); } else { item->tenant_name_.assign(sql_field.column_value_.config_string_.ptr()); } - } else if (0 == sql_field.column_name_.string_.case_compare("cluster_name")) { + } else if (0 == sql_field.column_name_.config_string_.case_compare("cluster_name")) { if (TOKEN_STR_VAL != sql_field.value_type_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); } else { item->cluster_name_.assign(sql_field.column_value_.config_string_.ptr()); } - } else if (0 == sql_field.column_name_.string_.case_compare("name")) { + } else if (0 == sql_field.column_name_.config_string_.case_compare("name")) { if (TOKEN_STR_VAL != sql_field.value_type_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); @@ -292,7 +310,7 @@ int ObProxyConfigTableProcessor::set_proxy_config(void *arg) ObString &name = sql_field.column_value_.config_string_; item->config_item_.set_name(name.ptr()); } - } else if (0 == sql_field.column_name_.string_.case_compare("value")) { + } else if (0 == sql_field.column_name_.config_string_.case_compare("value")) { if (TOKEN_STR_VAL != sql_field.value_type_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); @@ -301,12 +319,12 @@ int ObProxyConfigTableProcessor::set_proxy_config(void *arg) } } else { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected column name", K(sql_field.column_name_.string_)); + LOG_WARN("unexpected column name", K(sql_field.column_name_.config_string_)); } } if (OB_SUCC(ret)) { - item->vip_addr_.set(ObAddr::convert_ipv4_addr(vip.ptr()), static_cast(vport), vid); + item->vip_addr_.set(vip.ptr(), static_cast(vport), vid); if (0 != strcasecmp("LEVEL_GLOBAL", item->config_level_.ptr()) && !is_config_in_service(item->config_item_.name())) { ret = OB_NOT_SUPPORTED; @@ -321,7 +339,45 @@ int ObProxyConfigTableProcessor::set_proxy_config(void *arg) tmp_item = NULL; } - if (need_sync_to_file_ && 0 == strcasecmp("LEVEL_GLOBAL", item->config_level_.ptr()) && + // need_sync_to_file_ indicates that it is not a command set by alter proxyconfig, + // but a configuration item set by proxy_config + if (need_sync_to_file_) { + if ((0 == strcasecmp("obproxy_sys_password", item->config_item_.name()) + || 0 == strcasecmp("observer_sys_password", item->config_item_.name()) + || 0 == strcasecmp("observer_sys_password1", item->config_item_.name())) + && (NULL != item->config_item_.str() && '\0' != *item->config_item_.str())) { + char value_str[common::OB_MAX_CONFIG_VALUE_LEN + 1]; + char passwd_staged1_buf[ENC_STRING_BUF_LEN]; + ObString tmp_value_string; + ObString passwd_string(ENC_STRING_BUF_LEN, passwd_staged1_buf); + if (OB_FAIL(ObEncryptedHelper::encrypt_passwd_to_stage1(item->config_item_.str(), passwd_string))) { + LOG_WARN("encrypt_passwd_to_stage1 failed", K(ret)); + } else { + MEMCPY(value_str, passwd_staged1_buf + 1, 40); + value_str[40] = '\0'; + tmp_value_string.assign(value_str, 40); + item->config_item_.set_value(tmp_value_string); + char sql[1024]; + int64_t len = static_cast(snprintf(sql, 1024, EXECUTE_SQL, vip.length(), vip.ptr(), vid, vport, + item->cluster_name_.size(), item->cluster_name_.ptr(), + item->tenant_name_.size(), item->tenant_name_.ptr(), + item->config_item_.name(), item->config_item_.str(), + item->config_level_.size(), item->config_level_.ptr())); + if (OB_UNLIKELY(len <= 0 || len >= 1024)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get execute sql failed", K(len), K(ret)); + } else { + ObProxyVariantString buf_string; + buf_string.set_value(sql); + if (OB_FAIL(execute_sql_array_.push_back(buf_string))) { + LOG_WARN("execute_sql_array push back failed", K(ret)); + } + } + } + } + } + + if (OB_SUCC(ret) && need_sync_to_file_ && 0 == strcasecmp("LEVEL_GLOBAL", item->config_level_.ptr()) && OB_FAIL(alter_proxy_config(item->config_item_.name(), item->config_item_.str()))) { LOG_WARN("alter proxyconfig failed", K(ret)); } else if (OB_FAIL(backup_map.unique_set(item))) { @@ -359,22 +415,22 @@ int ObProxyConfigTableProcessor::delete_proxy_config(void *arg) bool need_delete = true; ++it; for (int i = 0; OB_SUCC(ret) && need_delete && i < fields->field_num_; i++) { - SqlField &sql_field = fields->fields_.at(i); - if (0 == sql_field.column_name_.string_.case_compare("vip")) { + SqlField* sql_field = fields->fields_.at(i); + if (0 == sql_field->column_name_.config_string_.case_compare("vip")) { char ip_buf[256]; item.vip_addr_.addr_.ip_to_string(ip_buf, 256); - if (TOKEN_STR_VAL != sql_field.value_type_) { + if (TOKEN_STR_VAL != sql_field->value_type_) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); - } else if (0 != strcasecmp(ip_buf, sql_field.column_value_.config_string_.ptr())) { + LOG_WARN("unexpeted type", K(sql_field->value_type_), K(ret)); + } else if (0 != strcasecmp(ip_buf, sql_field->column_value_.config_string_.ptr())) { need_delete = false; } - } else if (0 == sql_field.column_name_.string_.case_compare("vport")) { + } else if (0 == sql_field->column_name_.config_string_.case_compare("vport")) { int64_t vport = 0; - if (TOKEN_STR_VAL == sql_field.value_type_) { - vport = atoi(sql_field.column_value_.config_string_.ptr()); - } else if (TOKEN_INT_VAL == sql_field.value_type_) { - vport = sql_field.column_int_value_; + if (TOKEN_STR_VAL == sql_field->value_type_) { + vport = atoi(sql_field->column_value_.config_string_.ptr()); + } else if (TOKEN_INT_VAL == sql_field->value_type_) { + vport = sql_field->column_int_value_; } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid value type", K(ret)); @@ -384,12 +440,12 @@ int ObProxyConfigTableProcessor::delete_proxy_config(void *arg) need_delete = false; } } - } else if (0 == sql_field.column_name_.string_.case_compare("vid")) { + } else if (0 == sql_field->column_name_.config_string_.case_compare("vid")) { int64_t vid = 0; - if (TOKEN_STR_VAL == sql_field.value_type_) { - vid = atoi(sql_field.column_value_.config_string_.ptr()); - } else if (TOKEN_INT_VAL == sql_field.value_type_) { - vid = sql_field.column_int_value_; + if (TOKEN_STR_VAL == sql_field->value_type_) { + vid = atoi(sql_field->column_value_.config_string_.ptr()); + } else if (TOKEN_INT_VAL == sql_field->value_type_) { + vid = sql_field->column_int_value_; } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid value type", K(ret)); @@ -399,44 +455,44 @@ int ObProxyConfigTableProcessor::delete_proxy_config(void *arg) need_delete = false; } } - } else if (0 == sql_field.column_name_.string_.case_compare("config_level")) { - if (TOKEN_STR_VAL != sql_field.value_type_) { + } else if (0 == sql_field->column_name_.config_string_.case_compare("config_level")) { + if (TOKEN_STR_VAL != sql_field->value_type_) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); - } else if (0 != strcasecmp(item.config_level_.ptr(), sql_field.column_value_.config_string_.ptr())) { + LOG_WARN("unexpeted type", K(sql_field->value_type_), K(ret)); + } else if (0 != strcasecmp(item.config_level_.ptr(), sql_field->column_value_.config_string_.ptr())) { need_delete = false; } - } else if (0 == sql_field.column_name_.string_.case_compare("tenant_name")) { - if (TOKEN_STR_VAL != sql_field.value_type_) { + } else if (0 == sql_field->column_name_.config_string_.case_compare("tenant_name")) { + if (TOKEN_STR_VAL != sql_field->value_type_) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); - } else if (0 != strcasecmp(item.tenant_name_.ptr(), sql_field.column_value_.config_string_.ptr())) { + LOG_WARN("unexpeted type", K(sql_field->value_type_), K(ret)); + } else if (0 != strcasecmp(item.tenant_name_.ptr(), sql_field->column_value_.config_string_.ptr())) { need_delete = false; } - } else if (0 == sql_field.column_name_.string_.case_compare("cluster_name")) { - if (TOKEN_STR_VAL != sql_field.value_type_) { + } else if (0 == sql_field->column_name_.config_string_.case_compare("cluster_name")) { + if (TOKEN_STR_VAL != sql_field->value_type_) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); - } else if (0 != strcasecmp(item.cluster_name_.ptr(), sql_field.column_value_.config_string_.ptr())) { + LOG_WARN("unexpeted type", K(sql_field->value_type_), K(ret)); + } else if (0 != strcasecmp(item.cluster_name_.ptr(), sql_field->column_value_.config_string_.ptr())) { need_delete = false; } - } else if (0 == sql_field.column_name_.string_.case_compare("name")) { - if (TOKEN_STR_VAL != sql_field.value_type_) { + } else if (0 == sql_field->column_name_.config_string_.case_compare("name")) { + if (TOKEN_STR_VAL != sql_field->value_type_) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); - } else if (0 != strcasecmp(item.config_item_.name(), sql_field.column_value_.config_string_.ptr())) { + LOG_WARN("unexpeted type", K(sql_field->value_type_), K(ret)); + } else if (0 != strcasecmp(item.config_item_.name(), sql_field->column_value_.config_string_.ptr())) { need_delete = false; } - } else if (0 == sql_field.column_name_.string_.case_compare("value")) { - if (TOKEN_STR_VAL != sql_field.value_type_) { + } else if (0 == sql_field->column_name_.config_string_.case_compare("value")) { + if (TOKEN_STR_VAL != sql_field->value_type_) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpeted type", K(sql_field.value_type_), K(ret)); - } else if (0 != strcasecmp(item.config_item_.str(), sql_field.column_value_.config_string_.ptr())) { + LOG_WARN("unexpeted type", K(sql_field->value_type_), K(ret)); + } else if (0 != strcasecmp(item.config_item_.str(), sql_field->column_value_.config_string_.ptr())) { need_delete = false; } } else { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected column name", K(sql_field.column_name_.string_)); + LOG_WARN("unexpected column name", K(sql_field->column_name_)); } } @@ -482,7 +538,7 @@ int ObProxyConfigTableProcessor::get_config_item(const obutils::ObVipAddr &addr, LOG_WARN("proxy config item is null unexpected", K(ret)); } else { item = *proxy_config_item; - LOG_DEBUG("get config item succ", K(addr), K(cluster_name), K(tenant_name), K(item)); + LOG_TRACE("get config item succ", K(addr), K(cluster_name), K(tenant_name), K(item)); } return ret; @@ -501,22 +557,6 @@ int ObProxyConfigTableProcessor::alter_proxy_config(const common::ObString &key_ ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(key_string), K(value_string), K(ret)); } else { - char value_str[common::OB_MAX_CONFIG_VALUE_LEN + 1]; - if ((0 == key_string.case_compare("observer_sys_password") - || 0 == key_string.case_compare("obproxy_sys_password") - || 0 == key_string.case_compare("observer_sys_password1")) - && !value_string.empty()) { - char passwd_staged1_buf[ENC_STRING_BUF_LEN]; - ObString passwd_string(ENC_STRING_BUF_LEN, passwd_staged1_buf); - if (OB_FAIL(ObEncryptedHelper::encrypt_passwd_to_stage1(value_string, passwd_string))) { - LOG_WARN("encrypt_passwd_to_stage1 failed", K(ret)); - } else { - MEMCPY(value_str, passwd_staged1_buf + 1, 40); - value_str[40] = '\0'; - tmp_value_string.assign(value_str, 40); - LOG_DEBUG("alter password", K(key_string), K(value_string)); - } - } if (OB_ISNULL(reload_config = get_global_internal_cmd_processor().get_reload_config())) { ret = OB_ERR_NULL_VALUE; LOG_WARN("fail to get reload config", K(ret)); @@ -586,6 +626,36 @@ bool ObProxyConfigTableProcessor::is_config_in_service(const ObString &config_na return is_in_service; } +int ObProxyConfigTableProcessor::commit_execute_sql(sqlite3 *db) +{ + int ret = OB_SUCCESS; + if (execute_sql_array_.count() > 0) { + if (OB_UNLIKELY(NULL == db)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sqlite db is null unexpected", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < execute_sql_array_.count(); i++) { + char *err_msg = NULL; + ObString sql = execute_sql_array_.at(i).config_string_; + if (SQLITE_OK != sqlite3_exec(db, sql.ptr(), NULL, 0, &err_msg)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("exec failed", K(ret), "err_msg", err_msg); + } + + if (NULL != err_msg) { + sqlite3_free(err_msg); + } + } + } + + return ret; +} + +void ObProxyConfigTableProcessor::clear_execute_sql() +{ + execute_sql_array_.reset(); +} + } // end of omt } // end of obprxy } // end of oceanbase diff --git a/src/obproxy/omt/ob_proxy_config_table_processor.h b/src/obproxy/omt/ob_proxy_config_table_processor.h index eae6ade52..ef1728258 100644 --- a/src/obproxy/omt/ob_proxy_config_table_processor.h +++ b/src/obproxy/omt/ob_proxy_config_table_processor.h @@ -31,10 +31,13 @@ #ifndef OB_PROXY_CONFIG_TABLE_PROCESSOR_H_ #define OB_PROXY_CONFIG_TABLE_PROCESSOR_H_ +#include + #include "lib/lock/ob_drw_lock.h" #include "obutils/ob_vip_tenant_cache.h" #include "lib/string/ob_fixed_length_string.h" #include "share/config/ob_config.h" +#include "obutils/ob_proxy_string_utils.h" namespace oceanbase { @@ -98,7 +101,8 @@ class ObProxyConfigTableProcessor public: ObProxyConfigTableProcessor() : index_(0), proxy_config_lock_(obsys::WRITE_PRIORITY), - config_version_(0), need_sync_to_file_(false) {} + config_version_(0), need_sync_to_file_(false), + execute_sql_array_() {} ~ObProxyConfigTableProcessor() {} int init(); @@ -113,6 +117,8 @@ class ObProxyConfigTableProcessor void inc_config_version() { config_version_++; } void set_need_sync_to_file(const bool bvalue) { need_sync_to_file_ = bvalue; } ProxyConfigHashMap& get_backup_hashmap() { return proxy_config_map_array_[(index_ + 1) % 2]; } + int commit_execute_sql(sqlite3 *db); + void clear_execute_sql(); private: void clean_hashmap_with_lock(ProxyConfigHashMap &map); int backup_hashmap_with_lock(); @@ -120,6 +126,7 @@ class ObProxyConfigTableProcessor bool is_config_in_service(const common::ObString &config_name); static int execute(void *arg); static int commit(void* arg, bool is_success); + static int before_commit(void * arg); private: ProxyConfigHashMap proxy_config_map_array_[2]; @@ -127,6 +134,7 @@ class ObProxyConfigTableProcessor common::DRWLock proxy_config_lock_; uint64_t config_version_; bool need_sync_to_file_; + common::ObSEArray execute_sql_array_; private: DISALLOW_COPY_AND_ASSIGN(ObProxyConfigTableProcessor); }; diff --git a/src/obproxy/omt/ob_resource_unit_table_processor.cpp b/src/obproxy/omt/ob_resource_unit_table_processor.cpp index c216670ef..6311e3b76 100644 --- a/src/obproxy/omt/ob_resource_unit_table_processor.cpp +++ b/src/obproxy/omt/ob_resource_unit_table_processor.cpp @@ -69,11 +69,11 @@ int ObResourceUnitTableProcessor::get_config_params(void* args, } else { // The storage format is:[cluster|tenant|name|value] for (int64_t i = 0; i < fields->field_num_; i++) { - SqlField& sql_field = fields->fields_.at(i); - if (0 == sql_field.column_name_.string_.case_compare("name")) { - name_str = sql_field.column_value_.config_string_; - } else if (0 == sql_field.column_name_.string_.case_compare("value")) { - value_str = sql_field.column_value_.config_string_; + SqlField* sql_field = fields->fields_.at(i); + if (0 == sql_field->column_name_.config_string_.case_compare("name")) { + name_str = sql_field->column_value_.config_string_; + } else if (0 == sql_field->column_name_.config_string_.case_compare("value")) { + value_str = sql_field->column_value_.config_string_; } } } @@ -216,16 +216,16 @@ int ObResourceUnitTableProcessor::handle_delete_config( } int build_tenant_cluster_vip_name(const ObString &tenant_name, const ObString &cluster_name, - const ObString &vip_name, ObFixedLengthString &key_string) + const ObString &vip_name, ObFixedLengthString &key_string) { int ret = OB_SUCCESS; - char buf[OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + OB_IP_STR_BUFF]; + char buf[OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + MAX_IP_ADDR_LENGTH]; int64_t len = 0; - len = static_cast(snprintf(buf, OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + OB_IP_STR_BUFF, "%.*s#%.*s|%.*s", + len = static_cast(snprintf(buf, OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + MAX_IP_ADDR_LENGTH, "%.*s#%.*s|%.*s", tenant_name.length(), tenant_name.ptr(), cluster_name.length(), cluster_name.ptr(), vip_name.length(), vip_name.ptr())); - if (OB_UNLIKELY(len <= 0) || OB_UNLIKELY(len >= OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + OB_IP_STR_BUFF)) { + if (OB_UNLIKELY(len <= 0) || OB_UNLIKELY(len >= OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + MAX_IP_ADDR_LENGTH)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to fill buf", K(ret), K(tenant_name), K(cluster_name), K(vip_name)); } else if (OB_FAIL(key_string.assign(buf))) { diff --git a/src/obproxy/omt/ob_resource_unit_table_processor.h b/src/obproxy/omt/ob_resource_unit_table_processor.h index cc5967b20..f8f90838e 100644 --- a/src/obproxy/omt/ob_resource_unit_table_processor.h +++ b/src/obproxy/omt/ob_resource_unit_table_processor.h @@ -62,7 +62,7 @@ class ObResourceUnitTableProcessor ObResourceUnitTableProcessor &get_global_resource_unit_table_processor(); int build_tenant_cluster_vip_name(const common::ObString &tenant_name, const common::ObString &cluster_name, const common::ObString &vip_name, - common::ObFixedLengthString& key_string); + common::ObFixedLengthString& key_string); } // end of namespace omt } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/omt/ob_ssl_config_table_processor.cpp b/src/obproxy/omt/ob_ssl_config_table_processor.cpp index e7a42d3e3..7f05b7404 100644 --- a/src/obproxy/omt/ob_ssl_config_table_processor.cpp +++ b/src/obproxy/omt/ob_ssl_config_table_processor.cpp @@ -72,11 +72,11 @@ int ObSSLConfigTableProcessor::execute(void *arg) LOG_WARN("execute failed, tenant_name or cluster_name is null", K(ret), K(cluster_name), K(tenant_name)); } else { for (int64_t i = 0; i < params->fields_->field_num_; i++) { - SqlField &sql_field = params->fields_->fields_.at(i); - if (sql_field.column_name_.string_ == "value") { - value = sql_field.column_value_.config_string_; - } else if (sql_field.column_name_.string_ == "name") { - name = sql_field.column_value_.config_string_; + SqlField *sql_field = params->fields_->fields_.at(i); + if (0 == sql_field->column_name_.config_string_.case_compare("value")) { + value = sql_field->column_value_.config_string_; + } else if (0 == sql_field->column_name_.config_string_.case_compare("name")) { + name = sql_field->column_value_.config_string_; } } diff --git a/src/obproxy/omt/ob_vip_tenant_conn.cpp b/src/obproxy/omt/ob_vip_tenant_conn.cpp index 6286c285c..86f3480bf 100644 --- a/src/obproxy/omt/ob_vip_tenant_conn.cpp +++ b/src/obproxy/omt/ob_vip_tenant_conn.cpp @@ -45,7 +45,7 @@ using namespace obsys; using namespace oceanbase::common; extern int build_tenant_cluster_vip_name(const ObString &tenant_name, const ObString &cluster_name, const ObString &vip_name, - ObFixedLengthString &key_string); + ObFixedLengthString &key_string); int ObVipTenantConn::set_tenant_cluster(const ObString &tenant_name, const ObString &cluster_name) { @@ -66,7 +66,7 @@ int ObVipTenantConn::set_tenant_cluster(const ObString &tenant_name, const ObStr int ObVipTenantConn::set_addr(const common::ObString addr) { int ret = OB_SUCCESS; - if (addr.empty() || addr.length() > OB_IP_STR_BUFF) { + if (addr.empty() || addr.length() > MAX_IP_ADDR_LENGTH) { ret = OB_INVALID_ARGUMENT; LOG_WARN("name invalid", K(addr), K(ret)); } else { @@ -80,7 +80,7 @@ int ObVipTenantConn::set_full_name() { int ret = OB_SUCCESS; - ObFixedLengthString full_name; + ObFixedLengthString full_name; if (OB_FAIL(build_tenant_cluster_vip_name(tenant_name_, cluster_name_, vip_name_, full_name))) { LOG_WARN("build tenant cluser and vip name failed", K(ret), K_(tenant_name), K_(cluster_name), K_(vip_name)); } else { @@ -149,7 +149,7 @@ int ObVipTenantConnCache::get(ObString& key_name, ObVipTenantConn*& vt_conn) int ret = OB_SUCCESS; ObVipTenantConn *tmp_vt_conn = NULL; - if (key_name.empty() || key_name.length() > OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + OB_IP_STR_BUFF) { + if (key_name.empty() || key_name.length() > OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + MAX_IP_ADDR_LENGTH) { ret = OB_INVALID_ARGUMENT; LOG_WARN("name invalid", K(key_name), K(ret)); } else { @@ -231,19 +231,19 @@ int ObVipTenantConnCache::backup() //CWLockGuard guard(rwlock_); // Initialization state: - // vt_conn_map_ = vt_conn_map_array[0]; + // vt_conn_map_ = vt_conn_map_array[0]; // replica_vt_conn_map = vt_conn_map_array[1]; VTHashMap& replica_vt_conn_map = get_conn_map_replica(); clear_conn_map(replica_vt_conn_map); // Even if an error occurs in the backup process and an error is returned to the cloud platform, vt_conn_map_ is still the previous configuration information VTHashMap::iterator last = vt_conn_map_->end(); for (VTHashMap::iterator it = vt_conn_map_->begin(); it != last; ++it) { - ObVipTenantConn* tmp_vt_conn = NULL; + ObVipTenantConn* tmp_vt_conn = NULL; if (OB_ISNULL(tmp_vt_conn = op_alloc(ObVipTenantConn))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to alloc memory for ObVipTenantConn", K(ret)); } else if (OB_FAIL(tmp_vt_conn->set( - it->cluster_name_, it->tenant_name_, it->vip_name_, it->max_connections_))) { + it->cluster_name_, it->tenant_name_, it->vip_name_, it->max_connections_))) { LOG_WARN("fail to set vip tenant connect info", K(ret)); } else if (OB_FAIL(replica_vt_conn_map.unique_set(tmp_vt_conn))) { LOG_WARN("insert vip tenant connection failed", K(ret)); @@ -302,7 +302,7 @@ void ObVipTenantConnCache::dump_conn_map(VTHashMap &cache_map) int ObUsedConnCache::get(ObString& key_name, ObUsedConn*& used_conn) { int ret = OB_SUCCESS; - if (key_name.empty() || key_name.length() > OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + OB_IP_STR_BUFF) { + if (key_name.empty() || key_name.length() > OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + MAX_IP_ADDR_LENGTH) { ret = OB_INVALID_ARGUMENT; LOG_WARN("name invalid", K(key_name), K(ret)); } else if (OB_FAIL(used_conn_map_.get_refactored(key_name, used_conn))) { @@ -326,7 +326,7 @@ int ObUsedConnCache::set(ObUsedConn* used_conn) int ObUsedConnCache::erase(ObString& key_name) { int ret = OB_SUCCESS; - if (key_name.empty() || key_name.length() > OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + OB_IP_STR_BUFF) { + if (key_name.empty() || key_name.length() > OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + MAX_IP_ADDR_LENGTH) { ret = OB_INVALID_ARGUMENT; LOG_WARN("name invalid", K(key_name), K(ret)); } else if (OB_FAIL(used_conn_map_.erase_refactored(key_name))) { diff --git a/src/obproxy/omt/ob_vip_tenant_conn.h b/src/obproxy/omt/ob_vip_tenant_conn.h index b767c0eaf..ea3de354b 100644 --- a/src/obproxy/omt/ob_vip_tenant_conn.h +++ b/src/obproxy/omt/ob_vip_tenant_conn.h @@ -78,10 +78,10 @@ class ObVipTenantConn { LINK(ObVipTenantConn, vt_link_); private: - char tenant_name_str_[common::OB_MAX_TENANT_NAME_LENGTH]; + char tenant_name_str_[common::OB_MAX_TENANT_NAME_LENGTH]; char cluster_name_str_[OB_PROXY_MAX_CLUSTER_NAME_LENGTH]; - char vip_name_str_[common::OB_IP_STR_BUFF]; - char full_name_str_[OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + common::OB_IP_STR_BUFF]; + char vip_name_str_[common::MAX_IP_ADDR_LENGTH]; + char full_name_str_[OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + common::MAX_IP_ADDR_LENGTH]; DISALLOW_COPY_AND_ASSIGN(ObVipTenantConn); }; @@ -109,7 +109,7 @@ class ObVipTenantConnCache typedef common::hash::ObBuildInHashMap VTHashMap; public: - + int set(ObVipTenantConn* vt); int get(common::ObString& key_name, ObVipTenantConn*& vt_conn); int erase(common::ObString& cluster_name, common::ObString& tenant_name); @@ -132,7 +132,7 @@ class ObVipTenantConnCache class ObUsedConn : public common::ObSharedRefCount { public: ObUsedConn(common::ObString& full_name) : max_used_connections_(0), is_in_map_(false) { - if (full_name.length() < OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + common::OB_IP_STR_BUFF) { + if (full_name.length() < OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + common::MAX_IP_ADDR_LENGTH) { MEMCPY(full_name_str_, full_name.ptr(), full_name.length()); full_name_.assign_ptr(full_name_str_, (int32_t)full_name.length()); } @@ -158,7 +158,7 @@ class ObUsedConn : public common::ObSharedRefCount { bool is_in_map_; private: - char full_name_str_[OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + common::OB_IP_STR_BUFF]; + char full_name_str_[OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + common::MAX_IP_ADDR_LENGTH]; DISALLOW_COPY_AND_ASSIGN(ObUsedConn); }; diff --git a/src/obproxy/omt/ob_vip_tenant_cpu.cpp b/src/obproxy/omt/ob_vip_tenant_cpu.cpp index 55c18bc2b..5260ec22d 100644 --- a/src/obproxy/omt/ob_vip_tenant_cpu.cpp +++ b/src/obproxy/omt/ob_vip_tenant_cpu.cpp @@ -57,11 +57,11 @@ ObTenantCpu::ObTenantCpu(ObString& cluster_name, ObString& tenant_name, MEMCPY(tenant_name_str_, tenant_name.ptr(), tenant_name.length()); tenant_name_.assign_ptr(tenant_name_str_, tenant_name.length()); } - if (vip_name.length() < OB_IP_STR_BUFF) { + if (vip_name.length() < MAX_IP_ADDR_LENGTH) { MEMCPY(vip_name_str_, vip_name.ptr(), vip_name.length()); vip_name_.assign_ptr(vip_name_str_, vip_name.length()); } - if (full_name.length() < OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + OB_IP_STR_BUFF) { + if (full_name.length() < OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + MAX_IP_ADDR_LENGTH) { MEMCPY(full_name_str_, full_name.ptr(), full_name.length()); full_name_.assign_ptr(full_name_str_, full_name.length()); } @@ -176,7 +176,7 @@ int64_t ObTenantCpuCache::get_cpu_map_count() int ObTenantCpuCache::get(ObString& key_name, ObTenantCpu*& tenant_cpu) { int ret = OB_SUCCESS; - if (key_name.empty() || key_name.length() > OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + OB_IP_STR_BUFF) { + if (key_name.empty() || key_name.length() > OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + MAX_IP_ADDR_LENGTH) { ret = OB_INVALID_ARGUMENT; LOG_WARN("name invalid", K(key_name), K(ret)); } else if (OB_FAIL(vt_cpu_map_.get_refactored(key_name, tenant_cpu))) { diff --git a/src/obproxy/omt/ob_vip_tenant_cpu.h b/src/obproxy/omt/ob_vip_tenant_cpu.h index 8b598ae43..d0ee29ae4 100644 --- a/src/obproxy/omt/ob_vip_tenant_cpu.h +++ b/src/obproxy/omt/ob_vip_tenant_cpu.h @@ -73,7 +73,7 @@ class ObTenantCpu : public common::ObSharedRefCount { int set_unit_max_cpu(double cpu); int acquire_more_worker(const int64_t tid); - + TO_STRING_KV(K_(tenant_name), K_(cluster_name), K_(vip_name), K_(full_name), K_(max_thread_num), K_(backup_max_thread_num), K_(max_cpu_usage), K_(backup_max_cpu_usage), K_(index), K_(is_inited), K_(instance_status)); @@ -92,14 +92,14 @@ class ObTenantCpu : public common::ObSharedRefCount { bool is_inited_; ObTenantCpuStatus instance_status_; common::ObSEArray thread_array_; - + LINK(ObTenantCpu, cpu_link_); private: - char tenant_name_str_[common::OB_MAX_TENANT_NAME_LENGTH]; + char tenant_name_str_[common::OB_MAX_TENANT_NAME_LENGTH]; char cluster_name_str_[OB_PROXY_MAX_CLUSTER_NAME_LENGTH]; - char vip_name_str_[common::OB_IP_STR_BUFF]; - char full_name_str_[OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + common::OB_IP_STR_BUFF]; + char vip_name_str_[common::MAX_IP_ADDR_LENGTH]; + char full_name_str_[OB_PROXY_MAX_TENANT_CLUSTER_NAME_LENGTH + common::MAX_IP_ADDR_LENGTH]; DISALLOW_COPY_AND_ASSIGN(ObTenantCpu); }; @@ -148,4 +148,4 @@ class ObTenantCpuCache } // namespace obproxy } // namespace oceanbase -#endif // OB_VIP_TENANT_CPU_H \ No newline at end of file +#endif // OB_VIP_TENANT_CPU_H diff --git a/src/obproxy/omt/ob_white_list_table_processor.cpp b/src/obproxy/omt/ob_white_list_table_processor.cpp index 384c8ff7e..b332c216e 100644 --- a/src/obproxy/omt/ob_white_list_table_processor.cpp +++ b/src/obproxy/omt/ob_white_list_table_processor.cpp @@ -63,9 +63,9 @@ int ObWhiteListTableProcessor::execute(void *arg) LOG_WARN("execute failed, tenant_name or cluster_name is null", K(ret), K(cluster_name), K(tenant_name)); } else { for (int64_t i = 0; i < params->fields_->field_num_; i++) { - SqlField &sql_field = params->fields_->fields_.at(i); - if (sql_field.column_name_.string_ == "value") { - ip_list = sql_field.column_value_.config_string_; + SqlField *sql_field = params->fields_->fields_.at(i); + if (0 == sql_field->column_name_.config_string_.case_compare("value")) { + ip_list = sql_field->column_value_.config_string_; } } @@ -154,6 +154,7 @@ int ObWhiteListTableProcessor::set_ip_list(ObString &cluster_name, ObString &ten int pos = 0; AddrStruct ip_addr; memset(&ip_addr, 0, sizeof(AddrStruct)); + bool set_ip = false; while (OB_SUCC(ret) && pos < ip_list.length()) { if (ip_list[pos] == ',' || pos == ip_list.length() - 1 || ip_list[pos] == '/') { char buf[64]; @@ -164,10 +165,16 @@ int ObWhiteListTableProcessor::set_ip_list(ObString &cluster_name, ObString &ten } memcpy(buf, start, len); buf[len] = '\0'; - if (ip_addr.ip_ == 0) { - if (OB_FAIL(ip_to_int(buf, ip_addr.ip_))) { - LOG_WARN("ip to int failed", K(ret)); + if (!set_ip) { + if (false == ip_addr.addr_.set_ip_addr(buf, 0)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("set ip addr failed", K(buf), K(ret)); break; + } else { + if (ObAddr::VER::IPV4 == ip_addr.addr_.version_) { + ip_addr.v4_ = to_little_endian(htonl(ip_addr.addr_.ip_.v4_)); + } + set_ip = true; } } else { ip_addr.net_ = atoi(buf); @@ -183,6 +190,7 @@ int ObWhiteListTableProcessor::set_ip_list(ObString &cluster_name, ObString &ten LOG_WARN("ip addr push back failed", K(ret)); } else { memset(&ip_addr, 0, sizeof(AddrStruct)); + set_ip = false; } } pos++; @@ -234,26 +242,26 @@ int ObWhiteListTableProcessor::delete_ip_list(ObString &cluster_name, ObString & return ret; } -bool ObWhiteListTableProcessor::can_ip_pass(ObString &cluster_name, ObString &tenant_name, ObString &user_name, char* ip) +bool ObWhiteListTableProcessor::can_ip_pass(ObString &cluster_name, ObString &tenant_name, + ObString &user_name, const struct sockaddr& addr) { - uint32_t ip_value = 0; - int ret = OB_SUCCESS; bool can_pass = false; - if (OB_FAIL(ip_to_int(ip, ip_value))) { - LOG_WARN("ip to in failed", K(ret)); - } else { - can_pass = can_ip_pass(cluster_name, tenant_name, user_name, ip_value, false); + if (net::ops_is_ip4(addr)) { + can_pass = can_ipv4_pass(cluster_name, tenant_name, user_name, addr); + } else if (net::ops_is_ip6(addr)) { + can_pass = can_ipv6_pass(cluster_name, tenant_name, user_name, addr); } return can_pass; } -bool ObWhiteListTableProcessor::can_ip_pass(ObString &cluster_name, ObString &tenant_name, - ObString &user_name, uint32_t src_ip, bool is_big_endian) +bool ObWhiteListTableProcessor::can_ipv4_pass(ObString &cluster_name, ObString &tenant_name, + ObString &user_name, const struct sockaddr& in_addr) { int ret = OB_SUCCESS; bool can_pass = false; - uint32_t ip = is_big_endian ? to_little_endian(src_ip) : src_ip; - LOG_DEBUG("check can ip pass", K(cluster_name), K(tenant_name), K(ip)); + ObIpEndpoint endpoint(in_addr); + uint32_t ip = to_little_endian(endpoint.sin_.sin_addr.s_addr); + LOG_DEBUG("check can ip pass", K(cluster_name), K(tenant_name), K(endpoint)); if (!cluster_name.empty() && !tenant_name.empty()) { ObFixedLengthString key_string; if (OB_FAIL(paste_tenant_and_cluster_name(tenant_name, cluster_name, key_string))) { @@ -265,22 +273,71 @@ bool ObWhiteListTableProcessor::can_ip_pass(ObString &cluster_name, ObString &te if (OB_SUCC(current_map.get_refactored(key_string, ip_array))) { for (int64_t i = 0; !can_pass && i < ip_array.count(); i++) { AddrStruct addr = ip_array.at(i); - if (0 == addr.ip_) { + if (0 == addr.v4_) { can_pass = true; } else if (0 == addr.net_) { - can_pass = (addr.ip_ == ip); + can_pass = (addr.v4_ == ip); } else { uint32_t mask = 0xffffffff; - can_pass = (addr.ip_ == (ip & (mask << (32 - addr.net_)))); + can_pass = (addr.v4_ == (ip & (mask << (32 - addr.net_)))); } - if (OB_UNLIKELY(IS_DEBUG_ENABLED())) { - ObIpEndpoint client_info; - ObIpEndpoint white_list_info; - client_info.sin_.sin_addr.s_addr = __bswap_32(ip); - client_info.sin_.sin_family = AF_INET; - white_list_info.sin_.sin_addr.s_addr = __bswap_32(addr.ip_); - white_list_info.sin_.sin_family = AF_INET; - LOG_DEBUG("ip check can pass", K(client_info), K(white_list_info), "mask", addr.net_, K(can_pass)); + } + } else if (OB_HASH_NOT_EXIST == ret) { + can_pass = true; + } else { + LOG_WARN("unexpected error", K(ret)); + } + } + } else { + LOG_WARN("cluster_name or tenant_name is empty", K(cluster_name), K(tenant_name), K(endpoint)); + } + + if (!can_pass) { + LOG_WARN("can not pass white_list", K(cluster_name), K(tenant_name), K(user_name), K(endpoint)); + } + + return can_pass; +} + +bool ObWhiteListTableProcessor::can_ipv6_pass(ObString &cluster_name, ObString &tenant_name, + ObString &user_name, const struct sockaddr& in6_addr) +{ + int ret = OB_SUCCESS; + bool can_pass =false; + ObIpEndpoint endpoint(in6_addr); + LOG_DEBUG("check can ip pass", K(cluster_name), K(tenant_name), K(endpoint)); + if (!cluster_name.empty() && !tenant_name.empty()) { + ObFixedLengthString key_string; + if (OB_FAIL(paste_tenant_and_cluster_name(tenant_name, cluster_name, key_string))) { + LOG_WARN("paste tenant and cluster name failed", K(ret), K(tenant_name), K(cluster_name)); + } else { + ObSEArray ip_array; + DRWLock::RDLockGuard guard(white_list_lock_); + WhiteListHashMap ¤t_map = addr_hash_map_array_[index_]; + if (OB_SUCC(current_map.get_refactored(key_string, ip_array))) { + for (int64_t i = 0; !can_pass && i < ip_array.count(); i++) { + AddrStruct addr = ip_array.at(i); + if (addr.addr_.ip_.v6_[0] == 0 && addr.addr_.ip_.v6_[1] == 0 + && addr.addr_.ip_.v6_[2] == 0 && addr.addr_.ip_.v6_[3] == 0) { + can_pass = true; + } else { + int64_t net = addr.net_; + int64_t index = 0; + can_pass = true; + sockaddr_storage ss = addr.addr_.get_sockaddr(); + sockaddr_in6 &in6 = *(sockaddr_in6*)(&ss); + while ((net - 8) >= 0 && can_pass) { + if (in6.sin6_addr.s6_addr[index] != endpoint.sin6_.sin6_addr.s6_addr[index]) { + can_pass = false; + } + index++; + net -= 8; + } + + if (net && can_pass) { + can_pass = in6.sin6_addr.s6_addr[index] == + (endpoint.sin6_.sin6_addr.s6_addr[index] & (0xff << (8 - net))); + } } } } else if (OB_HASH_NOT_EXIST == ret) { @@ -290,13 +347,11 @@ bool ObWhiteListTableProcessor::can_ip_pass(ObString &cluster_name, ObString &te } } } else { - LOG_WARN("cluster_name or tenant_name is empty", K(cluster_name), K(tenant_name), K(ip)); + LOG_WARN("cluster_name or tenant_name is empty", K(cluster_name), K(tenant_name), K(endpoint)); } if (!can_pass) { - struct sockaddr_in address; - address.sin_addr.s_addr = __bswap_32(ip); - LOG_WARN("can not pass white_list", K(cluster_name), K(tenant_name), K(user_name), "client_ip", inet_ntoa(address.sin_addr)); + LOG_WARN("can not pass white_list", K(cluster_name), K(tenant_name), K(user_name), K(endpoint)); } return can_pass; @@ -305,10 +360,8 @@ bool ObWhiteListTableProcessor::can_ip_pass(ObString &cluster_name, ObString &te int64_t AddrStruct::to_string(char *buf, const int64_t buf_len) const { int64_t pos = 0; - in_addr addr; - addr.s_addr = static_cast(ip_); J_OBJ_START(); - J_KV("ip", inet_ntoa(addr), K_(net)); + J_KV(K_(addr), K_(net)); J_OBJ_END(); return pos; } @@ -353,9 +406,7 @@ void ObWhiteListTableProcessor::print_config() LOG_DEBUG("white list map info", K(iter->first)); for (int64_t i = 0; i < iter->second.count(); i++) { AddrStruct addr_info = iter->second.at(i); - struct sockaddr_in address; - address.sin_addr.s_addr = __bswap_32(addr_info.ip_); - LOG_DEBUG("ip/net info", "ip", inet_ntoa(address.sin_addr), "mask", addr_info.net_); + LOG_DEBUG("ip/net info", K(addr_info)); } } } diff --git a/src/obproxy/omt/ob_white_list_table_processor.h b/src/obproxy/omt/ob_white_list_table_processor.h index 8c9a5ca20..cbfc2d6fb 100644 --- a/src/obproxy/omt/ob_white_list_table_processor.h +++ b/src/obproxy/omt/ob_white_list_table_processor.h @@ -35,6 +35,7 @@ #include "lib/container/ob_se_array.h" #include "lib/lock/ob_drw_lock.h" #include "utils/ob_proxy_lib.h" +#include "lib/net/ob_addr.h" namespace oceanbase { @@ -45,7 +46,8 @@ namespace omt struct AddrStruct { - uint32_t ip_; + common::ObAddr addr_; + uint32_t v4_; uint32_t net_; int64_t to_string(char *buf, const int64_t buf_len) const; @@ -60,8 +62,7 @@ typedef common::hash::ObHashMapexpr_result_; - expr_result.target_mask_ = FIRST_PART_MASK; // set for init success if (OB_FAIL(ObProxySqlParser::get_parse_allocator(allocator_))) { } else if (OB_ISNULL(allocator_)) { ret = OB_ERR_UNEXPECTED; diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parse_result.h b/src/obproxy/opsql/expr_parser/ob_expr_parse_result.h index c27ea471d..4dfee39df 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parse_result.h +++ b/src/obproxy/opsql/expr_parser/ob_expr_parse_result.h @@ -124,9 +124,18 @@ typedef struct _ObProxyTokenList ObProxyTokenNode *tail_; } ObProxyTokenList; +/** + * @brief If level_ == PART_KEY_LEVEL_ONE, first_part_column_idx_ will be set. + * If level_ == PART_KEY_LEVEL_TWO, second_part_column_idx_ will be set. + * If level_ == PART_KEY_LEVEL_BOTH, both of them will be set. + * first_part_column_idx_: the column's idx in partition expression + * second_part_column_idx_: the column's idx in subpartition expression + */ typedef struct _ObProxyRelationExpr { int64_t column_idx_; + int64_t first_part_column_idx_; + int64_t second_part_column_idx_; ObProxyTokenList *left_value_; ObProxyTokenList *right_value_; ObProxyFunctionType type_; @@ -150,17 +159,21 @@ typedef struct _ObProxyPartKeyAccuracy { typedef struct _ObProxyPartKey { ObProxyParseString name_; + ObProxyParseString default_value_; // serialized value ObProxyPartKeyLevel level_; - int64_t idx_; // column position + int64_t idx_; // pos in schema columns int64_t obj_type_; // ObObjType int64_t cs_type_; // ObCollationType + bool is_exist_in_sql_; // is part key exist in sql bool is_generated_; int64_t generated_col_idx_; int64_t param_num_; ObProxyExprType func_type_; ObProxyParamNode *params_[OBPROXY_MAX_PARAM_NUM]; // used to store generated func param - int64_t idx_in_rowid_; + int64_t real_source_idx_; // the real source idx of generated key, have no params_ + int64_t idx_in_rowid_; // pos in rowid + int64_t idx_in_part_columns_; // pos in part expr columns ObProxyPartKeyAccuracy accuracy_; } ObProxyPartKey; @@ -185,7 +198,6 @@ typedef struct _ObExprParseResult ObExprParseMode parse_mode_; ObProxyTableInfo table_info_; ObProxyPartKeyInfo part_key_info_; - int64_t target_mask_; // scanner buffer void *yyscan_info_; // yy_scan_t @@ -195,7 +207,6 @@ typedef struct _ObExprParseResult jmp_buf jmp_buf_; // handle fatal error const char *start_pos_; const char *end_pos_; - int64_t cur_mask_; // if cur_flag_ == target_flag_ means we will finish parse int64_t column_idx_; int64_t values_list_idx_; int64_t multi_param_values_; @@ -208,7 +219,6 @@ typedef struct _ObExprParseResult // hash rowid or not bool has_rowid_; - } ObExprParseResult; static const char *g_ROWID = "ROWID"; diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parser.h b/src/obproxy/opsql/expr_parser/ob_expr_parser.h index 0e21e2ca8..e39db2228 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parser.h +++ b/src/obproxy/opsql/expr_parser/ob_expr_parser.h @@ -76,7 +76,6 @@ inline int ObExprParser::init_result(ObExprParseResult &parse_result, const char parse_result.tmp_buf_ = NULL; parse_result.tmp_len_ = 0; parse_result.end_pos_ = NULL; - parse_result.cur_mask_ = 0; parse_result.column_idx_ = 0; parse_result.values_list_idx_ = 0; parse_result.multi_param_values_ = 0; @@ -87,12 +86,13 @@ inline int ObExprParser::init_result(ObExprParseResult &parse_result, const char parse_result.relation_info_.relation_num_ = 0; parse_result.all_relation_info_.relation_num_ = 0; parse_result.all_relation_info_.right_value_num_ = 0; + for (int64_t i = 0; i < parse_result.part_key_info_.key_num_; ++i) { + parse_result.part_key_info_.part_keys_[i].is_exist_in_sql_ = false; + } - if (0 == parse_result.target_mask_ - || INVALID_PARSE_MODE == parse_result.parse_mode_) { + if (INVALID_PARSE_MODE == parse_result.parse_mode_) { ret = common::OB_INVALID_ARGUMENT; PROXY_LOG(DEBUG, "failed to initialized parser, maybe parse sql for shard user", - K(parse_result.target_mask_), K(parse_result.parse_mode_), K(ret)); } diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parser.l b/src/obproxy/opsql/expr_parser/ob_expr_parser.l index fca7116bb..ff498367b 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parser.l +++ b/src/obproxy/opsql/expr_parser/ob_expr_parser.l @@ -45,6 +45,10 @@ do {\ #define RETURN_ROW_ID() \ { store_expr_str(yytext, yyleng, yytext + yyleng, yyscanner); return ROW_ID; } + +#define RETURN_REVERSED_EXPR_FUNC() \ + { store_expr_str(yytext, yyleng, yytext + yyleng, yyscanner); return REVERSED_EXPR_FUNC; } + %} %x in_c_comment @@ -59,8 +63,10 @@ multi_byte_left_parenthesis [\uff08] multi_byte_right_parenthesis [\uff09] space [ \t\n\r\f] identifer ([A-Za-z0-9$_]*) -int_num [\-\+]?[0-9]+ -number ([\-]?[0-9]+E[-+]?[0-9]+)|([\-]?[0-9]+"."[0-9]*E[-+]?[0-9]+)|([\-]?"."[0-9]+E[-+]?[0-9]+)|([\-]?[0-9]+"."[0-9]*)|([\-]?"."[0-9]+) + +/* limit the length of int_num from 1 to 17 in case of int64_t out of bound, 17 -> [ ( length of 2^64 ) - 2 ]*/ +int_num [\-\+]?[0-9]{1,17} +number ([\-]?[0-9]+E[-+]?[0-9]+)|([\-]?[0-9]+"."[0-9]*E[-+]?[0-9]+)|([\-]?"."[0-9]+E[-+]?[0-9]+)|([\-]?[0-9]+"."[0-9]*)|([\-]?"."[0-9]+)|([\-\+]?[0-9]{18,}) non_newline [^\n\r] sql_comment ("--"{space}+{non_newline}*)|(#{non_newline}*) @@ -113,6 +119,9 @@ AND { return AND_OP; } OR { return OR_OP; } "||" { return OR_OP; } IN { return IN; } +IS { return IS; } +NULL { return TOKEN_NULL; } +NOT { return NOT; } "=" { return COMP_EQ; } "<=>" { return COMP_NSEQ; } ">=" { return COMP_GE; } @@ -122,6 +131,7 @@ IN { return IN; } "!="|"<>" { return COMP_NE; } "?" { return PLACE_HOLDER; } ":"{int_num} { store_pos_place_holder(yytext + 1, yyscanner); return POS_PLACE_HOLDER; } +"SYSDATE" { RETURN_REVERSED_EXPR_FUNC();} {int_num} { RETURN_INT_VAL(); } {number} { RETURN_NUMBER_VAL(); } diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parser.y b/src/obproxy/opsql/expr_parser/ob_expr_parser.y index 06489e71f..e190314c8 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parser.y +++ b/src/obproxy/opsql/expr_parser/ob_expr_parser.y @@ -55,8 +55,8 @@ static inline void add_token_list(ObProxyTokenList *list, ObProxyTokenList *next if (OB_ISNULL(list) || OB_ISNULL(next_list)) { } else if (NULL != list->tail_ && NULL != next_list->head_ - && (TOKEN_INT_VAL == list->tail_->type_ || TOKEN_STR_VAL == list->tail_->type_) - && (TOKEN_INT_VAL == next_list->head_->type_ || TOKEN_STR_VAL == next_list->head_->type_)) { + && (TOKEN_INT_VAL == list->tail_->type_ || TOKEN_STR_VAL == list->tail_->type_ || TOKEN_FUNC == list->tail_->type_) + && (TOKEN_INT_VAL == next_list->head_->type_ || TOKEN_STR_VAL == next_list->head_->type_ || TOKEN_FUNC == next_list->head_->type_)) { list->tail_->next_ = next_list->head_; list->tail_ = next_list->head_; list->tail_->next_ = NULL; @@ -128,11 +128,18 @@ static inline void set_part_key_column_idx(ObExprParseResult *result, ObProxyPar for (i = 0; i < result->part_key_info_.key_num_; ++i) { if (is_equal(column_name, &result->part_key_info_.part_keys_[i].name_)) { result->part_key_info_.part_keys_[i].idx_ = result->column_idx_; - break; + result->part_key_info_.part_keys_[i].is_exist_in_sql_ = true; } } } +static inline void init_part_key_all_match(ObExprParseResult *result) +{ + for (int64_t i = 0; i < result->part_key_info_.key_num_; ++i) { + result->part_key_info_.part_keys_[i].is_exist_in_sql_ = true; + } +} + #define malloc_node(node, result, type) \ do { \ if (OB_ISNULL(node = ((ObProxyTokenNode *)obproxy_parse_malloc(sizeof(ObProxyTokenNode), \ @@ -167,21 +174,13 @@ static inline void set_part_key_column_idx(ObExprParseResult *result, ObProxyPar do { \ if (NULL == relation) { \ } else { \ - int64_t new_mask = get_mask(relation->type_, relation->level_); \ - bool has_rowid = result->has_rowid_; \ - if (((result->cur_mask_ | new_mask) != result->cur_mask_) \ - || (has_rowid \ - && is_equal_to_rowid(&relation->left_value_->column_node_->column_name_))) { \ + if (relation->level_ != PART_KEY_LEVEL_ZERO) { \ if (result->relation_info_.relation_num_ < OBPROXY_MAX_RELATION_NUM) { \ result->relation_info_.relations_[result->relation_info_.relation_num_++] = relation; \ - result->cur_mask_ = (result->cur_mask_ | new_mask); \ } else { \ /* YYACCEPT; */ \ } \ } \ - if ((result->cur_mask_ & result->target_mask_) == result->target_mask_) { \ - /* YYACCEPT; */ \ - } \ } \ } while(0) \ @@ -251,6 +250,92 @@ static inline void add_relation(ObExprParseResult *result, } } +static inline void set_relation_part_with_column_idx(int64_t idx_in_schema_columns, + ObExprParseResult *result, + ObProxyPartKeyLevel *level, + int64_t *first_part_column_idx, + int64_t *second_part_column_idx) +{ + if (OB_ISNULL(level) && OB_ISNULL(first_part_column_idx) && + OB_ISNULL(second_part_column_idx) && OB_ISNULL(result)) { + // do nothing + } else { + *level = PART_KEY_LEVEL_ZERO; + *first_part_column_idx = 0; + *second_part_column_idx = 0; + bool is_level_one = false; + bool is_level_two = false; + for (int i = 0; i < result->part_key_info_.key_num_; i++) { + // make sure the part_key exist in sql to avoid the uninitialized idx_ + if (idx_in_schema_columns == result->part_key_info_.part_keys_[i].idx_ && result->part_key_info_.part_keys_[i].is_exist_in_sql_) { + if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_ONE) { + is_level_one = true; + *first_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } else if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_TWO) { + is_level_two = true; + *second_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } + } + } + if (is_level_one) { + *level = PART_KEY_LEVEL_ONE; + } + if (is_level_two) { + *level = PART_KEY_LEVEL_TWO; + } + if (is_level_one && is_level_two) { + *level = PART_KEY_LEVEL_BOTH; + } + } +} + +static inline void set_relation_part_with_column_name(ObProxyParseString *column, + ObExprParseResult *result, + ObProxyPartKeyLevel *level, + int64_t *first_part_column_idx, + int64_t *second_part_column_idx) +{ + if (OB_ISNULL(column) + || OB_ISNULL(result) + || OB_ISNULL(level) + || OB_ISNULL(first_part_column_idx) + || OB_ISNULL(second_part_column_idx)) { + // do nothing + } else if (result->has_rowid_ + && is_equal_to_rowid(column)) { + // handle rowid + *level = PART_KEY_LEVEL_ONE; + *first_part_column_idx = 0; + *second_part_column_idx = 0; + } else { + *level = PART_KEY_LEVEL_ZERO; + *first_part_column_idx = 0; + *second_part_column_idx = 0; + bool is_level_one = false; + bool is_level_two = false; + for (int i = 0; i < result->part_key_info_.key_num_; i++) { + if (is_equal(&result->part_key_info_.part_keys_[i].name_, column)) { + if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_ONE) { + is_level_one = true; + *first_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } else if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_TWO) { + is_level_two = true; + *second_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } + } + } + if (is_level_one) { + *level = PART_KEY_LEVEL_ONE; + } + if (is_level_two) { + *level = PART_KEY_LEVEL_TWO; + } + if (is_level_one && is_level_two) { + *level = PART_KEY_LEVEL_BOTH; + } + } +} + static inline ObProxyRelationExpr *get_relation(ObExprParseResult *result, ObProxyTokenList *left_value, @@ -261,25 +346,25 @@ static inline ObProxyRelationExpr *get_relation(ObExprParseResult *result, ObProxyTokenList *tmp_left = NULL; ObProxyTokenList *tmp_right = NULL; ObProxyFunctionType tmp_type = F_NONE; - ObProxyPartKeyLevel tmp_level = PART_KEY_LEVEL_ZERO; int64_t tmp_column_idx_ = -1; + ObProxyParseString *tmp_column = NULL; if (NULL != left_value->column_node_ && TOKEN_COLUMN == left_value->column_node_->type_ && left_value->column_node_->part_key_idx_ >= 0) { tmp_left = left_value; - tmp_level = result->part_key_info_.part_keys_[left_value->column_node_->part_key_idx_].level_; tmp_right = right_value; tmp_type = type; tmp_column_idx_ = left_value->column_node_->part_key_idx_; + tmp_column = &left_value->column_node_->column_name_; } else if (NULL != right_value->column_node_ && TOKEN_COLUMN == right_value->column_node_->type_ && right_value->column_node_->part_key_idx_ >= 0) { tmp_left = right_value; - tmp_level = result->part_key_info_.part_keys_[right_value->column_node_->part_key_idx_].level_; tmp_right = left_value; tmp_type = get_reverse_func(type); tmp_column_idx_ = right_value->column_node_->part_key_idx_; + tmp_column = &right_value->column_node_->column_name_; } if (NULL == tmp_left || NULL == tmp_right || F_COMP_NE == tmp_type) { @@ -292,7 +377,11 @@ static inline ObProxyRelationExpr *get_relation(ObExprParseResult *result, relation->left_value_ = tmp_left; relation->type_ = tmp_type; relation->right_value_ = tmp_right; - relation->level_ = tmp_level; + set_relation_part_with_column_name(tmp_column, + result, + &relation->level_, + &relation->first_part_column_idx_, + &relation->second_part_column_idx_); } return relation; } @@ -306,14 +395,20 @@ static inline ObProxyRelationExpr *get_values_relation(ObExprParseResult *result } else { int64_t i = 0; for (i = 0; i < result->part_key_info_.key_num_; ++i) { - if (result->values_list_idx_ == result->part_key_info_.part_keys_[i].idx_) { + // make sure the part_key exist in sql to avoid the uninitialized idx_ + if (result->values_list_idx_ == result->part_key_info_.part_keys_[i].idx_ && result->part_key_info_.part_keys_[i].is_exist_in_sql_) { if (OB_ISNULL(relation = ((ObProxyRelationExpr *)obproxy_parse_malloc( sizeof(ObProxyRelationExpr), result->malloc_pool_)))) { } else { relation->column_idx_ = i; relation->type_ = F_COMP_EQ; relation->right_value_ = right_value; - relation->level_ = result->part_key_info_.part_keys_[i].level_; + relation->left_value_ = NULL; + set_relation_part_with_column_idx(result->values_list_idx_, + result, + &relation->level_, + &relation->first_part_column_idx_, + &relation->second_part_column_idx_); } break; } @@ -363,12 +458,12 @@ static inline void add_right_relation_value(ObExprParseResult *result, %token DUMMY_SELECT_CLAUSE DUMMY_INSERT_CLAUSE /* reserved keyword */ %token WHERE AS VALUES SET END_WHERE JOIN -%token AND_OP OR_OP IN ON BETWEEN +%token AND_OP OR_OP IN ON BETWEEN IS TOKEN_NULL NOT %token COMP_EQ COMP_NSEQ COMP_GE COMP_GT COMP_LE COMP_LT COMP_NE %token PLACE_HOLDER %token END_P ERROR IGNORED_WORD /* type token */ -%token NAME_OB STR_VAL ROW_ID +%token NAME_OB STR_VAL ROW_ID REVERSED_EXPR_FUNC %token INT_VAL POS_PLACE_HOLDER %type comp %type token opt_column @@ -422,6 +517,8 @@ bool_pri: expr comp expr { add_relation(result, $1, $2,$3); $$ = get_relation(re add_relation(result, $1, F_COMP_LE, $5); $$ = NULL; } + | expr IS TOKEN_NULL { $$ = NULL; } + | expr IS NOT TOKEN_NULL { $$ = NULL; } comp: COMP_EQ { $$ = F_COMP_EQ; } | COMP_NSEQ { $$ = F_COMP_NSEQ; } @@ -469,6 +566,11 @@ token: $$->part_key_idx_ = get_part_key_idx(&$1, &$3, &$5, result); $$->column_name_ = $5; } + | REVERSED_EXPR_FUNC + { + malloc_node($$, result, TOKEN_FUNC); + $$->str_value_ = $1; + } | NAME_OB '(' token_list ')' { malloc_node($$, result, TOKEN_FUNC); @@ -518,7 +620,7 @@ values_expr_lists: '(' values_expr_list ')' result->multi_param_values_++; } -opt_column_list: /* empty */ +opt_column_list: /* empty */ { init_part_key_all_match(result);} | '(' column_list ')' /* column_list: NAME_OB { result->column_idx_ = 0; set_part_key_column_idx(result, &$1); } diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_lex.c b/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_lex.c index e5532cd5b..4be993430 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_lex.c +++ b/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_lex.c @@ -348,8 +348,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); yyg->yy_hold_char = *yy_cp; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 57 -#define YY_END_OF_BUFFER 58 +#define YY_NUM_RULES 61 +#define YY_END_OF_BUFFER 62 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -357,28 +357,37 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[187] = +static yyconst flex_int16_t yy_accept[269] = { 0, - 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, - 58, 56, 31, 31, 35, 46, 31, 30, 35, 35, - 40, 33, 34, 35, 32, 35, 35, 35, 28, 35, - 24, 19, 22, 26, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 52, 35, 56, - 56, 39, 38, 39, 41, 42, 57, 47, 48, 57, - 54, 55, 31, 0, 25, 31, 30, 15, 28, 0, - 0, 28, 29, 36, 29, 28, 30, 0, 27, 23, - 21, 30, 2, 30, 30, 30, 30, 18, 30, 30, - 12, 16, 30, 30, 30, 30, 17, 33, 34, 32, - - 0, 37, 41, 0, 0, 43, 0, 0, 44, 47, - 0, 49, 0, 0, 0, 50, 54, 53, 31, 0, - 0, 0, 29, 0, 0, 29, 20, 14, 30, 6, - 30, 30, 30, 30, 30, 5, 30, 30, 45, 0, - 45, 0, 51, 0, 51, 0, 31, 31, 31, 29, - 0, 29, 0, 29, 30, 30, 30, 11, 30, 30, - 30, 30, 0, 0, 0, 0, 30, 8, 30, 7, - 10, 4, 1, 0, 0, 45, 0, 0, 0, 51, - 0, 30, 9, 3, 13, 0 + 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, + 62, 60, 35, 35, 39, 50, 35, 34, 39, 39, + 44, 37, 38, 39, 36, 39, 39, 39, 32, 39, + 27, 22, 25, 29, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 56, 39, + 60, 60, 43, 42, 43, 45, 46, 61, 51, 52, + 61, 58, 59, 35, 0, 28, 35, 34, 15, 32, + 0, 0, 32, 33, 40, 33, 32, 34, 0, 30, + 26, 24, 34, 2, 34, 34, 34, 34, 18, 19, + 34, 34, 34, 34, 12, 16, 34, 34, 34, 34, + + 34, 17, 37, 38, 36, 0, 41, 45, 0, 0, + 47, 0, 0, 48, 51, 0, 53, 0, 0, 0, + 54, 58, 57, 32, 35, 0, 32, 0, 0, 33, + 0, 32, 0, 33, 30, 23, 14, 34, 6, 34, + 34, 34, 34, 21, 34, 34, 5, 34, 34, 34, + 49, 0, 49, 0, 55, 0, 55, 0, 32, 35, + 35, 35, 32, 33, 0, 33, 0, 33, 32, 30, + 34, 34, 34, 11, 34, 20, 34, 34, 34, 34, + 0, 0, 0, 0, 32, 32, 32, 30, 34, 8, + 34, 7, 10, 34, 4, 1, 0, 0, 49, 0, + + 0, 0, 55, 0, 32, 32, 32, 30, 34, 9, + 34, 3, 32, 32, 32, 30, 13, 31, 32, 32, + 32, 30, 32, 32, 32, 30, 32, 32, 32, 30, + 32, 32, 32, 30, 32, 32, 32, 30, 32, 32, + 32, 30, 32, 32, 32, 30, 32, 32, 32, 30, + 32, 32, 32, 30, 32, 32, 32, 30, 32, 32, + 33, 30, 33, 33, 33, 33, 33, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -391,17 +400,17 @@ static yyconst flex_int32_t yy_ec[256] = 20, 20, 20, 20, 20, 20, 20, 21, 9, 22, 23, 24, 25, 9, 26, 27, 8, 28, 29, 30, 31, 32, 33, 34, 8, 35, 36, 37, 38, 39, - 8, 40, 41, 42, 43, 44, 45, 8, 8, 8, - 1, 46, 1, 9, 8, 47, 48, 49, 8, 50, + 8, 40, 41, 42, 43, 44, 45, 8, 46, 8, + 1, 47, 1, 9, 8, 48, 49, 50, 8, 51, - 51, 52, 53, 54, 55, 56, 8, 57, 58, 59, - 60, 61, 8, 62, 63, 64, 65, 66, 67, 8, - 8, 8, 1, 68, 1, 9, 1, 1, 1, 1, + 52, 53, 54, 55, 56, 57, 8, 58, 59, 60, + 61, 62, 8, 63, 64, 65, 66, 67, 68, 8, + 69, 8, 1, 70, 1, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 69, 1, 70, 1, 1, 1, 1, 71, 72, 1, - 1, 73, 1, 1, 1, 1, 1, 1, 1, 1, + 71, 1, 72, 1, 1, 1, 1, 73, 74, 1, + 1, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -413,140 +422,174 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[74] = +static yyconst flex_int32_t yy_meta[76] = { 0, 1, 1, 2, 2, 1, 3, 1, 4, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 6, 7, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, - 1, 1, 1 + 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, + 1, 1, 1, 1, 1 } ; -static yyconst flex_int16_t yy_base[203] = +static yyconst flex_int16_t yy_base[285] = { 0, - 0, 0, 71, 72, 65, 66, 72, 73, 312, 311, - 357, 500, 78, 85, 333, 500, 0, 0, 500, 345, - 500, 500, 500, 334, 500, 73, 333, 338, 74, 80, - 60, 500, 328, 500, 61, 70, 63, 64, 79, 69, - 69, 75, 73, 71, 85, 89, 84, 500, 282, 280, - 68, 500, 500, 103, 0, 141, 0, 0, 153, 0, - 0, 301, 147, 278, 500, 0, 0, 500, 326, 159, - 325, 146, 145, 500, 147, 151, 162, 324, 323, 317, - 500, 118, 0, 130, 133, 140, 137, 0, 150, 148, - 0, 0, 140, 144, 152, 160, 500, 500, 500, 500, - - 174, 500, 0, 188, 329, 500, 321, 268, 500, 0, - 211, 500, 330, 318, 265, 500, 0, 500, 216, 264, - 206, 210, 204, 214, 307, 303, 500, 0, 187, 0, - 193, 204, 201, 206, 207, 0, 198, 202, 500, 296, - 292, 241, 500, 290, 280, 244, 130, 247, 249, 264, - 215, 192, 184, 181, 227, 226, 229, 0, 225, 240, - 240, 241, 270, 84, 273, 73, 242, 0, 251, 0, - 0, 242, 0, 291, 295, 297, 308, 311, 318, 322, - 326, 272, 0, 0, 0, 500, 395, 402, 409, 416, - 423, 92, 430, 437, 444, 451, 458, 464, 471, 478, - - 485, 492 + 0, 0, 73, 74, 67, 68, 74, 75, 611, 610, + 631, 660, 80, 87, 601, 660, 0, 0, 660, 598, + 660, 660, 660, 585, 660, 75, 574, 579, 76, 82, + 62, 660, 560, 660, 63, 72, 65, 66, 81, 71, + 71, 77, 73, 80, 75, 96, 92, 105, 660, 482, + 480, 71, 660, 660, 133, 0, 152, 0, 0, 164, + 0, 0, 501, 170, 477, 660, 0, 0, 660, 527, + 173, 526, 160, 133, 660, 159, 164, 175, 524, 523, + 518, 660, 110, 0, 122, 143, 148, 147, 0, 0, + 161, 160, 155, 163, 0, 0, 154, 159, 161, 168, + + 175, 660, 660, 660, 660, 186, 660, 0, 226, 530, + 660, 522, 467, 660, 0, 230, 660, 531, 519, 464, + 660, 0, 660, 514, 236, 462, 225, 193, 231, 227, + 235, 239, 512, 511, 509, 660, 0, 197, 0, 206, + 220, 221, 227, 0, 226, 229, 0, 235, 221, 226, + 660, 515, 513, 267, 660, 517, 508, 271, 490, 146, + 290, 292, 270, 489, 484, 483, 481, 478, 280, 470, + 251, 243, 265, 0, 262, 0, 278, 282, 281, 282, + 310, 414, 313, 400, 450, 306, 310, 440, 289, 0, + 289, 0, 0, 281, 295, 0, 341, 345, 361, 363, + + 347, 367, 351, 372, 438, 359, 362, 437, 300, 0, + 354, 0, 434, 367, 372, 421, 0, 0, 416, 375, + 379, 413, 405, 380, 392, 403, 402, 397, 400, 393, + 387, 410, 417, 385, 383, 422, 427, 382, 374, 430, + 435, 369, 366, 443, 447, 348, 320, 448, 455, 258, + 247, 460, 463, 211, 198, 468, 473, 195, 187, 476, + 488, 660, 137, 493, 498, 99, 501, 660, 553, 560, + 567, 574, 581, 94, 588, 595, 602, 609, 616, 622, + 629, 636, 643, 650 } ; -static yyconst flex_int16_t yy_def[203] = +static yyconst flex_int16_t yy_def[285] = { 0, - 186, 1, 187, 187, 188, 188, 189, 189, 190, 190, - 186, 186, 186, 186, 186, 186, 191, 192, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 192, 186, - 186, 186, 186, 186, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 186, 186, 186, - 186, 186, 186, 186, 193, 186, 194, 195, 186, 196, - 197, 186, 186, 186, 186, 191, 192, 186, 186, 186, - 186, 186, 186, 186, 186, 192, 192, 186, 186, 186, - 186, 192, 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 186, 186, 186, 186, - - 186, 186, 193, 186, 198, 186, 186, 186, 186, 195, - 186, 186, 199, 186, 186, 186, 197, 186, 200, 186, - 186, 186, 186, 186, 186, 192, 186, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 186, 198, - 198, 186, 186, 199, 199, 186, 200, 200, 200, 186, - 186, 186, 186, 186, 192, 192, 192, 192, 192, 192, - 192, 192, 201, 186, 202, 186, 192, 192, 192, 192, - 192, 192, 192, 201, 201, 201, 201, 202, 202, 202, - 202, 192, 192, 192, 192, 0, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - - 186, 186 + 268, 1, 269, 269, 270, 270, 271, 271, 272, 272, + 268, 268, 268, 268, 268, 268, 273, 274, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 274, 268, + 268, 268, 268, 268, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 274, 274, 274, 274, 274, 268, 268, + 268, 268, 268, 268, 268, 275, 268, 276, 277, 268, + 278, 279, 268, 268, 268, 268, 273, 274, 268, 268, + 268, 268, 268, 268, 268, 268, 274, 274, 268, 268, + 268, 268, 274, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, + + 274, 268, 268, 268, 268, 268, 268, 275, 268, 280, + 268, 268, 268, 268, 277, 268, 268, 281, 268, 268, + 268, 279, 268, 268, 282, 268, 268, 268, 268, 268, + 268, 274, 268, 274, 268, 268, 274, 274, 274, 274, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, + 268, 280, 280, 268, 268, 281, 281, 268, 268, 282, + 282, 282, 268, 268, 268, 268, 268, 268, 274, 268, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, + 283, 268, 284, 268, 268, 268, 274, 268, 274, 274, + 274, 274, 274, 274, 274, 274, 283, 283, 283, 283, + + 284, 284, 284, 284, 268, 268, 274, 268, 274, 274, + 274, 274, 268, 268, 274, 268, 274, 274, 268, 268, + 274, 268, 268, 268, 274, 268, 268, 268, 274, 268, + 268, 268, 274, 268, 268, 268, 274, 268, 268, 268, + 274, 268, 268, 268, 274, 268, 268, 268, 274, 268, + 268, 268, 274, 268, 268, 268, 274, 268, 268, 268, + 274, 268, 268, 268, 274, 268, 268, 0, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268 } ; -static yyconst flex_int16_t yy_nxt[574] = +static yyconst flex_int16_t yy_nxt[736] = { 0, 12, 13, 14, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 19, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 18, 18, 37, - 38, 39, 40, 41, 42, 18, 18, 43, 18, 44, - 45, 18, 18, 46, 47, 12, 48, 35, 36, 18, - 18, 37, 38, 39, 40, 41, 42, 18, 18, 43, - 18, 44, 45, 18, 18, 46, 47, 49, 50, 51, - 12, 12, 12, 53, 53, 56, 56, 59, 59, 63, - 63, 63, 80, 65, 54, 54, 63, 63, 63, 70, - 71, 75, 72, 76, 78, 67, 78, 82, 84, 79, - - 85, 83, 77, 86, 87, 88, 89, 90, 93, 91, - 57, 57, 92, 94, 95, 96, 101, 60, 60, 82, - 84, 102, 85, 83, 77, 86, 87, 88, 89, 90, - 93, 91, 186, 186, 92, 94, 95, 96, 98, 99, - 100, 165, 104, 104, 104, 128, 64, 105, 63, 63, - 63, 106, 163, 64, 111, 111, 111, 107, 112, 113, - 119, 119, 119, 75, 73, 72, 123, 128, 75, 114, - 76, 129, 130, 122, 121, 124, 125, 131, 125, 77, - 132, 126, 133, 134, 135, 136, 137, 101, 138, 104, - 104, 104, 102, 129, 130, 122, 121, 124, 139, 131, - - 154, 77, 132, 154, 133, 134, 135, 136, 137, 108, - 138, 152, 111, 111, 111, 64, 143, 148, 119, 119, - 125, 115, 125, 123, 151, 150, 151, 120, 153, 152, - 153, 155, 124, 154, 152, 156, 157, 158, 159, 160, - 161, 162, 163, 163, 163, 165, 165, 165, 148, 119, - 119, 186, 186, 155, 124, 167, 108, 156, 157, 158, - 159, 160, 161, 162, 168, 169, 170, 171, 172, 173, - 182, 175, 163, 163, 179, 165, 165, 167, 180, 115, - 176, 183, 184, 150, 149, 145, 168, 169, 170, 171, - 172, 173, 182, 186, 186, 145, 175, 163, 163, 186, - - 186, 176, 141, 183, 184, 176, 141, 176, 185, 164, - 186, 186, 166, 186, 186, 149, 180, 148, 176, 179, - 165, 165, 126, 180, 186, 186, 150, 180, 186, 186, - 185, 180, 119, 111, 146, 145, 104, 142, 177, 141, - 127, 181, 79, 79, 73, 69, 63, 118, 63, 97, - 81, 74, 73, 69, 68, 65, 186, 62, 62, 186, - 186, 186, 186, 177, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 175, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 181, 186, 186, 186, - 186, 186, 186, 186, 179, 52, 52, 52, 52, 52, - - 52, 52, 55, 55, 55, 55, 55, 55, 55, 58, - 58, 58, 58, 58, 58, 58, 61, 61, 61, 61, - 61, 61, 61, 66, 186, 66, 66, 66, 66, 66, - 103, 103, 103, 103, 186, 186, 103, 109, 109, 109, - 109, 109, 109, 109, 110, 110, 186, 110, 110, 186, - 110, 116, 116, 116, 116, 116, 116, 116, 117, 117, - 117, 117, 117, 117, 140, 186, 140, 140, 140, 140, - 140, 144, 186, 144, 144, 144, 144, 144, 147, 147, - 147, 147, 147, 147, 147, 174, 174, 174, 174, 174, - 174, 174, 178, 178, 178, 178, 178, 178, 178, 11, - - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186 + 38, 39, 40, 41, 42, 18, 43, 44, 18, 45, + 46, 18, 18, 47, 48, 18, 12, 49, 35, 36, + 18, 18, 37, 38, 39, 40, 41, 42, 18, 43, + 44, 18, 45, 46, 18, 18, 47, 48, 18, 50, + 51, 52, 12, 12, 12, 54, 54, 57, 57, 60, + 60, 64, 64, 64, 81, 66, 55, 55, 64, 64, + 64, 71, 72, 76, 73, 77, 79, 68, 79, 83, + + 85, 80, 86, 84, 78, 87, 88, 89, 91, 92, + 93, 90, 97, 58, 58, 94, 95, 100, 266, 96, + 61, 61, 83, 85, 98, 86, 84, 78, 87, 88, + 89, 91, 92, 93, 90, 97, 101, 137, 94, 95, + 100, 99, 96, 103, 104, 105, 106, 98, 268, 268, + 65, 107, 74, 109, 109, 109, 266, 65, 110, 101, + 137, 129, 111, 138, 99, 116, 116, 116, 112, 117, + 118, 64, 64, 64, 125, 125, 125, 76, 130, 127, + 119, 76, 139, 132, 129, 140, 138, 131, 128, 133, + 141, 133, 78, 142, 134, 143, 144, 145, 146, 106, + + 147, 148, 149, 150, 107, 139, 263, 133, 140, 133, + 131, 128, 164, 141, 262, 78, 142, 259, 143, 144, + 145, 146, 113, 147, 148, 149, 150, 109, 109, 109, + 258, 116, 116, 116, 120, 155, 151, 161, 125, 125, + 65, 171, 76, 126, 163, 165, 130, 165, 172, 167, + 166, 167, 173, 128, 168, 131, 76, 174, 169, 175, + 176, 177, 178, 179, 171, 180, 255, 78, 181, 181, + 181, 172, 183, 183, 183, 173, 128, 254, 131, 189, + 174, 190, 175, 176, 177, 178, 179, 76, 180, 186, + 78, 161, 125, 125, 268, 268, 113, 76, 128, 187, + + 120, 191, 189, 192, 190, 193, 162, 194, 78, 195, + 196, 198, 181, 181, 202, 183, 183, 209, 203, 210, + 199, 128, 211, 76, 191, 206, 192, 76, 193, 207, + 194, 78, 195, 196, 128, 212, 217, 182, 78, 251, + 209, 184, 210, 268, 268, 211, 198, 181, 181, 268, + 268, 199, 203, 268, 268, 199, 203, 128, 212, 217, + 162, 78, 161, 268, 268, 268, 268, 250, 202, 183, + 183, 199, 203, 199, 268, 268, 76, 203, 214, 76, + 200, 215, 218, 204, 76, 247, 220, 128, 246, 76, + 78, 221, 76, 243, 224, 128, 76, 76, 225, 228, + + 78, 242, 239, 128, 238, 218, 235, 78, 128, 76, + 128, 229, 234, 78, 76, 200, 232, 76, 128, 233, + 78, 231, 230, 78, 227, 128, 128, 76, 78, 236, + 78, 128, 226, 198, 76, 223, 237, 204, 128, 76, + 222, 240, 202, 78, 76, 78, 241, 76, 128, 244, + 128, 78, 76, 219, 245, 78, 216, 213, 128, 208, + 76, 128, 248, 78, 76, 76, 249, 252, 78, 205, + 183, 128, 76, 128, 253, 78, 128, 76, 78, 256, + 76, 128, 257, 78, 181, 76, 78, 260, 128, 188, + 76, 78, 261, 76, 128, 264, 128, 168, 78, 128, + + 168, 78, 166, 166, 128, 76, 78, 265, 164, 185, + 76, 128, 267, 157, 78, 76, 78, 265, 76, 128, + 267, 128, 157, 153, 78, 153, 78, 128, 170, 128, + 134, 164, 125, 159, 116, 158, 157, 109, 154, 78, + 153, 136, 135, 80, 128, 74, 124, 64, 123, 78, + 64, 102, 128, 53, 53, 53, 53, 53, 53, 53, + 56, 56, 56, 56, 56, 56, 56, 59, 59, 59, + 59, 59, 59, 59, 62, 62, 62, 62, 62, 62, + 62, 67, 82, 67, 67, 67, 67, 67, 108, 108, + 108, 108, 75, 74, 108, 114, 114, 114, 114, 114, + + 114, 114, 115, 115, 70, 115, 115, 69, 115, 121, + 121, 121, 121, 121, 121, 121, 122, 122, 122, 122, + 122, 122, 152, 66, 152, 152, 152, 152, 152, 156, + 268, 156, 156, 156, 156, 156, 160, 160, 160, 160, + 160, 160, 160, 197, 197, 197, 197, 197, 197, 197, + 201, 201, 201, 201, 201, 201, 201, 63, 63, 11, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268 } ; -static yyconst flex_int16_t yy_chk[574] = +static yyconst flex_int16_t yy_chk[736] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -555,62 +598,80 @@ static yyconst flex_int16_t yy_chk[574] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 4, 5, 6, 7, 8, 13, - 13, 13, 31, 31, 3, 4, 14, 14, 14, 26, - 26, 29, 26, 29, 30, 192, 30, 35, 36, 30, - - 37, 35, 29, 38, 39, 40, 41, 42, 44, 43, - 5, 6, 43, 45, 46, 47, 54, 7, 8, 35, - 36, 54, 37, 35, 29, 38, 39, 40, 41, 42, - 44, 43, 147, 147, 43, 45, 46, 47, 51, 51, - 51, 166, 56, 56, 56, 82, 13, 56, 63, 63, - 63, 56, 164, 14, 59, 59, 59, 56, 59, 59, - 70, 70, 70, 72, 73, 72, 75, 82, 76, 59, - 76, 84, 85, 73, 72, 75, 77, 86, 77, 76, - 87, 77, 89, 90, 93, 94, 95, 101, 96, 104, - 104, 104, 101, 84, 85, 73, 72, 75, 104, 86, - - 154, 76, 87, 153, 89, 90, 93, 94, 95, 56, - 96, 152, 111, 111, 111, 63, 111, 119, 119, 119, - 121, 59, 121, 123, 122, 121, 122, 70, 124, 122, - 124, 129, 123, 124, 151, 131, 132, 133, 134, 135, - 137, 138, 142, 142, 142, 146, 146, 146, 148, 148, - 148, 149, 149, 129, 123, 155, 104, 131, 132, 133, - 134, 135, 137, 138, 156, 157, 159, 160, 161, 162, - 167, 163, 163, 163, 165, 165, 165, 155, 165, 111, - 163, 169, 172, 150, 119, 145, 156, 157, 159, 160, - 161, 162, 167, 174, 174, 144, 175, 175, 175, 176, - - 176, 174, 141, 169, 172, 175, 140, 176, 182, 142, - 177, 177, 146, 178, 178, 148, 178, 149, 177, 179, - 179, 179, 126, 179, 180, 180, 125, 180, 181, 181, - 182, 181, 120, 115, 114, 113, 108, 107, 163, 105, - 80, 165, 79, 78, 71, 69, 64, 62, 50, 49, - 33, 28, 27, 24, 20, 15, 11, 10, 9, 0, - 0, 0, 0, 175, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 177, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, - 0, 0, 0, 0, 181, 187, 187, 187, 187, 187, - - 187, 187, 188, 188, 188, 188, 188, 188, 188, 189, - 189, 189, 189, 189, 189, 189, 190, 190, 190, 190, - 190, 190, 190, 191, 0, 191, 191, 191, 191, 191, - 193, 193, 193, 193, 0, 0, 193, 194, 194, 194, - 194, 194, 194, 194, 195, 195, 0, 195, 195, 0, - 195, 196, 196, 196, 196, 196, 196, 196, 197, 197, - 197, 197, 197, 197, 198, 0, 198, 198, 198, 198, - 198, 199, 0, 199, 199, 199, 199, 199, 200, 200, - 200, 200, 200, 200, 200, 201, 201, 201, 201, 201, - 201, 201, 202, 202, 202, 202, 202, 202, 202, 186, - - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186 + 1, 1, 1, 1, 1, 3, 4, 5, 6, 7, + 8, 13, 13, 13, 31, 31, 3, 4, 14, 14, + 14, 26, 26, 29, 26, 29, 30, 274, 30, 35, + + 36, 30, 37, 35, 29, 38, 39, 40, 41, 42, + 43, 40, 45, 5, 6, 43, 44, 47, 266, 44, + 7, 8, 35, 36, 46, 37, 35, 29, 38, 39, + 40, 41, 42, 43, 40, 45, 48, 83, 43, 44, + 47, 46, 44, 52, 52, 52, 55, 46, 160, 160, + 13, 55, 74, 57, 57, 57, 263, 14, 57, 48, + 83, 74, 57, 85, 46, 60, 60, 60, 57, 60, + 60, 64, 64, 64, 71, 71, 71, 73, 76, 73, + 60, 77, 86, 77, 74, 87, 85, 76, 73, 78, + 88, 78, 77, 91, 78, 92, 93, 94, 97, 106, + + 98, 99, 100, 101, 106, 86, 259, 128, 87, 128, + 76, 73, 128, 88, 258, 77, 91, 255, 92, 93, + 94, 97, 57, 98, 99, 100, 101, 109, 109, 109, + 254, 116, 116, 116, 60, 116, 109, 125, 125, 125, + 64, 138, 127, 71, 127, 129, 130, 129, 140, 131, + 129, 131, 141, 127, 131, 130, 132, 142, 132, 143, + 145, 146, 148, 149, 138, 150, 251, 132, 154, 154, + 154, 140, 158, 158, 158, 141, 127, 250, 130, 171, + 142, 172, 143, 145, 146, 148, 149, 163, 150, 163, + 132, 161, 161, 161, 162, 162, 109, 169, 163, 169, + + 116, 173, 171, 175, 172, 177, 125, 178, 169, 179, + 180, 181, 181, 181, 183, 183, 183, 189, 183, 191, + 181, 163, 194, 186, 173, 186, 175, 187, 177, 187, + 178, 169, 179, 180, 186, 195, 209, 154, 187, 247, + 189, 158, 191, 197, 197, 194, 198, 198, 198, 201, + 201, 197, 201, 203, 203, 198, 203, 186, 195, 209, + 161, 187, 162, 199, 199, 200, 200, 246, 202, 202, + 202, 199, 202, 200, 204, 204, 206, 204, 206, 207, + 181, 207, 211, 183, 214, 243, 214, 206, 242, 215, + 207, 215, 220, 239, 220, 214, 221, 224, 221, 224, + + 215, 238, 235, 220, 234, 211, 231, 221, 224, 225, + 206, 225, 230, 207, 228, 198, 228, 229, 214, 229, + 225, 227, 226, 215, 223, 228, 220, 232, 229, 232, + 221, 224, 222, 200, 233, 219, 233, 202, 232, 236, + 216, 236, 204, 225, 237, 233, 237, 240, 228, 240, + 236, 229, 241, 213, 241, 237, 208, 205, 240, 188, + 244, 232, 244, 241, 245, 248, 245, 248, 233, 185, + 184, 244, 249, 236, 249, 245, 248, 252, 237, 252, + 253, 240, 253, 249, 182, 256, 241, 256, 252, 170, + 257, 253, 257, 260, 244, 260, 256, 168, 245, 248, + + 167, 257, 166, 165, 260, 261, 249, 261, 164, 159, + 264, 252, 264, 157, 253, 265, 261, 265, 267, 256, + 267, 264, 156, 153, 257, 152, 265, 260, 135, 267, + 134, 133, 126, 124, 120, 119, 118, 113, 112, 261, + 110, 81, 80, 79, 264, 72, 70, 65, 63, 265, + 51, 50, 267, 269, 269, 269, 269, 269, 269, 269, + 270, 270, 270, 270, 270, 270, 270, 271, 271, 271, + 271, 271, 271, 271, 272, 272, 272, 272, 272, 272, + 272, 273, 33, 273, 273, 273, 273, 273, 275, 275, + 275, 275, 28, 27, 275, 276, 276, 276, 276, 276, + + 276, 276, 277, 277, 24, 277, 277, 20, 277, 278, + 278, 278, 278, 278, 278, 278, 279, 279, 279, 279, + 279, 279, 280, 15, 280, 280, 280, 280, 280, 281, + 11, 281, 281, 281, 281, 281, 282, 282, 282, 282, + 282, 282, 282, 283, 283, 283, 283, 283, 283, 283, + 284, 284, 284, 284, 284, 284, 284, 10, 9, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268 } ; /* The intent behind this definition is that it'll catch @@ -665,11 +726,16 @@ do {\ #define RETURN_ROW_ID() \ { store_expr_str(yytext, yyleng, yytext + yyleng, yyscanner); return ROW_ID; } +#define RETURN_REVERSED_EXPR_FUNC() \ + { store_expr_str(yytext, yyleng, yytext + yyleng, yyscanner); return REVERSED_EXPR_FUNC; } + + /*following character status will be rewrite by gen_parse.sh according to connection character*/ -#line 674 "ob_expr_parser_gbk_lex.c" +/* limit the length of int_num from 1 to 17 in case of int64_t out of bound, 17 -> [ ( length of 2^64 ) - 2 ]*/ +#line 740 "ob_expr_parser_gbk_lex.c" #define INITIAL 0 #define in_c_comment 1 @@ -917,9 +983,9 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 96 "ob_expr_parser_gbk.l" +#line 102 "ob_expr_parser_gbk.l" -#line 925 "ob_expr_parser_gbk_lex.c" +#line 991 "ob_expr_parser_gbk_lex.c" yylval = yylval_param; @@ -976,13 +1042,13 @@ YY_DECL while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 187 ) + if ( yy_current_state >= 269 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 500 ); + while ( yy_base[yy_current_state] != 660 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -1008,206 +1074,226 @@ YY_DECL case 1: YY_RULE_SETUP -#line 97 "ob_expr_parser_gbk.l" +#line 103 "ob_expr_parser_gbk.l" { return WHERE; } YY_BREAK case 2: YY_RULE_SETUP -#line 98 "ob_expr_parser_gbk.l" +#line 104 "ob_expr_parser_gbk.l" { return AS; } YY_BREAK case 3: YY_RULE_SETUP -#line 99 "ob_expr_parser_gbk.l" +#line 105 "ob_expr_parser_gbk.l" { return VALUES; } YY_BREAK case 4: YY_RULE_SETUP -#line 100 "ob_expr_parser_gbk.l" +#line 106 "ob_expr_parser_gbk.l" { return VALUES; } YY_BREAK case 5: YY_RULE_SETUP -#line 101 "ob_expr_parser_gbk.l" +#line 107 "ob_expr_parser_gbk.l" { return SET; } YY_BREAK case 6: YY_RULE_SETUP -#line 102 "ob_expr_parser_gbk.l" +#line 108 "ob_expr_parser_gbk.l" { return END_WHERE; } YY_BREAK case 7: YY_RULE_SETUP -#line 103 "ob_expr_parser_gbk.l" +#line 109 "ob_expr_parser_gbk.l" { return END_WHERE; } YY_BREAK case 8: YY_RULE_SETUP -#line 104 "ob_expr_parser_gbk.l" +#line 110 "ob_expr_parser_gbk.l" { return END_WHERE; } YY_BREAK case 9: YY_RULE_SETUP -#line 105 "ob_expr_parser_gbk.l" +#line 111 "ob_expr_parser_gbk.l" { return END_WHERE; } YY_BREAK case 10: YY_RULE_SETUP -#line 106 "ob_expr_parser_gbk.l" +#line 112 "ob_expr_parser_gbk.l" { RETURN_ROW_ID(); } YY_BREAK case 11: YY_RULE_SETUP -#line 108 "ob_expr_parser_gbk.l" +#line 114 "ob_expr_parser_gbk.l" { return JOIN; } YY_BREAK case 12: YY_RULE_SETUP -#line 109 "ob_expr_parser_gbk.l" +#line 115 "ob_expr_parser_gbk.l" { return ON; } YY_BREAK case 13: YY_RULE_SETUP -#line 110 "ob_expr_parser_gbk.l" +#line 116 "ob_expr_parser_gbk.l" { return BETWEEN; } YY_BREAK case 14: YY_RULE_SETUP -#line 111 "ob_expr_parser_gbk.l" +#line 117 "ob_expr_parser_gbk.l" { return AND_OP; } YY_BREAK case 15: YY_RULE_SETUP -#line 112 "ob_expr_parser_gbk.l" +#line 118 "ob_expr_parser_gbk.l" { return AND_OP; } YY_BREAK case 16: YY_RULE_SETUP -#line 113 "ob_expr_parser_gbk.l" +#line 119 "ob_expr_parser_gbk.l" { return OR_OP; } YY_BREAK case 17: YY_RULE_SETUP -#line 114 "ob_expr_parser_gbk.l" +#line 120 "ob_expr_parser_gbk.l" { return OR_OP; } YY_BREAK case 18: YY_RULE_SETUP -#line 115 "ob_expr_parser_gbk.l" +#line 121 "ob_expr_parser_gbk.l" { return IN; } YY_BREAK case 19: YY_RULE_SETUP -#line 116 "ob_expr_parser_gbk.l" -{ return COMP_EQ; } +#line 122 "ob_expr_parser_gbk.l" +{ return IS; } YY_BREAK case 20: YY_RULE_SETUP -#line 117 "ob_expr_parser_gbk.l" -{ return COMP_NSEQ; } +#line 123 "ob_expr_parser_gbk.l" +{ return TOKEN_NULL; } YY_BREAK case 21: YY_RULE_SETUP -#line 118 "ob_expr_parser_gbk.l" -{ return COMP_GE; } +#line 124 "ob_expr_parser_gbk.l" +{ return NOT; } YY_BREAK case 22: YY_RULE_SETUP -#line 119 "ob_expr_parser_gbk.l" -{ return COMP_GT; } +#line 125 "ob_expr_parser_gbk.l" +{ return COMP_EQ; } YY_BREAK case 23: YY_RULE_SETUP -#line 120 "ob_expr_parser_gbk.l" -{ return COMP_LE; } +#line 126 "ob_expr_parser_gbk.l" +{ return COMP_NSEQ; } YY_BREAK case 24: YY_RULE_SETUP -#line 121 "ob_expr_parser_gbk.l" -{ return COMP_LT; } +#line 127 "ob_expr_parser_gbk.l" +{ return COMP_GE; } YY_BREAK case 25: YY_RULE_SETUP -#line 122 "ob_expr_parser_gbk.l" -{ return COMP_NE; } +#line 128 "ob_expr_parser_gbk.l" +{ return COMP_GT; } YY_BREAK case 26: YY_RULE_SETUP -#line 123 "ob_expr_parser_gbk.l" -{ return PLACE_HOLDER; } +#line 129 "ob_expr_parser_gbk.l" +{ return COMP_LE; } YY_BREAK case 27: YY_RULE_SETUP -#line 124 "ob_expr_parser_gbk.l" -{ store_pos_place_holder(yytext + 1, yyscanner); return POS_PLACE_HOLDER; } +#line 130 "ob_expr_parser_gbk.l" +{ return COMP_LT; } YY_BREAK case 28: YY_RULE_SETUP -#line 126 "ob_expr_parser_gbk.l" -{ RETURN_INT_VAL(); } +#line 131 "ob_expr_parser_gbk.l" +{ return COMP_NE; } YY_BREAK case 29: YY_RULE_SETUP -#line 127 "ob_expr_parser_gbk.l" -{ RETURN_NUMBER_VAL(); } +#line 132 "ob_expr_parser_gbk.l" +{ return PLACE_HOLDER; } YY_BREAK case 30: YY_RULE_SETUP -#line 128 "ob_expr_parser_gbk.l" -{ RETURN_NAME_OB(); } +#line 133 "ob_expr_parser_gbk.l" +{ store_pos_place_holder(yytext + 1, yyscanner); return POS_PLACE_HOLDER; } YY_BREAK case 31: -/* rule 31 can match eol */ YY_RULE_SETUP -#line 129 "ob_expr_parser_gbk.l" -{ } +#line 134 "ob_expr_parser_gbk.l" +{ RETURN_REVERSED_EXPR_FUNC();} YY_BREAK case 32: YY_RULE_SETUP -#line 130 "ob_expr_parser_gbk.l" -{ return ','; } +#line 136 "ob_expr_parser_gbk.l" +{ RETURN_INT_VAL(); } YY_BREAK case 33: YY_RULE_SETUP -#line 131 "ob_expr_parser_gbk.l" -{ return '('; } +#line 137 "ob_expr_parser_gbk.l" +{ RETURN_NUMBER_VAL(); } YY_BREAK case 34: YY_RULE_SETUP -#line 132 "ob_expr_parser_gbk.l" -{ return ')'; } +#line 138 "ob_expr_parser_gbk.l" +{ RETURN_NAME_OB(); } YY_BREAK case 35: +/* rule 35 can match eol */ YY_RULE_SETUP -#line 133 "ob_expr_parser_gbk.l" +#line 139 "ob_expr_parser_gbk.l" +{ } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 140 "ob_expr_parser_gbk.l" +{ return ','; } + YY_BREAK +case 37: +YY_RULE_SETUP +#line 141 "ob_expr_parser_gbk.l" +{ return '('; } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 142 "ob_expr_parser_gbk.l" +{ return ')'; } + YY_BREAK +case 39: +YY_RULE_SETUP +#line 143 "ob_expr_parser_gbk.l" { return yytext[0]; } YY_BREAK /* comment */ -case 36: +case 40: YY_RULE_SETUP -#line 136 "ob_expr_parser_gbk.l" +#line 146 "ob_expr_parser_gbk.l" { PUSH_STATE(in_c_comment); } YY_BREAK -case 37: +case 41: YY_RULE_SETUP -#line 137 "ob_expr_parser_gbk.l" +#line 147 "ob_expr_parser_gbk.l" { POP_STATE(); } YY_BREAK -case 38: -/* rule 38 can match eol */ +case 42: +/* rule 42 can match eol */ YY_RULE_SETUP -#line 138 "ob_expr_parser_gbk.l" +#line 148 "ob_expr_parser_gbk.l" {} YY_BREAK -case 39: +case 43: YY_RULE_SETUP -#line 139 "ob_expr_parser_gbk.l" +#line 149 "ob_expr_parser_gbk.l" {} YY_BREAK /* quote */ -case 40: +case 44: YY_RULE_SETUP -#line 142 "ob_expr_parser_gbk.l" +#line 152 "ob_expr_parser_gbk.l" { PUSH_STATE(sq); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1218,10 +1304,10 @@ YY_RULE_SETUP } } YY_BREAK -case 41: -/* rule 41 can match eol */ +case 45: +/* rule 45 can match eol */ YY_RULE_SETUP -#line 152 "ob_expr_parser_gbk.l" +#line 162 "ob_expr_parser_gbk.l" { ObExprParseResult *p = (ObExprParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -1229,9 +1315,9 @@ YY_RULE_SETUP } } YY_BREAK -case 42: +case 46: YY_RULE_SETUP -#line 159 "ob_expr_parser_gbk.l" +#line 169 "ob_expr_parser_gbk.l" { POP_STATE(); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1241,15 +1327,15 @@ YY_RULE_SETUP return STR_VAL; } YY_BREAK -case 43: +case 47: YY_RULE_SETUP -#line 168 "ob_expr_parser_gbk.l" +#line 178 "ob_expr_parser_gbk.l" {} YY_BREAK -case 44: -/* rule 44 can match eol */ +case 48: +/* rule 48 can match eol */ YY_RULE_SETUP -#line 169 "ob_expr_parser_gbk.l" +#line 179 "ob_expr_parser_gbk.l" { ObExprParseResult *p = (ObExprParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -1257,20 +1343,20 @@ YY_RULE_SETUP } } YY_BREAK -case 45: -/* rule 45 can match eol */ +case 49: +/* rule 49 can match eol */ YY_RULE_SETUP -#line 175 "ob_expr_parser_gbk.l" +#line 185 "ob_expr_parser_gbk.l" {} YY_BREAK case YY_STATE_EOF(sq): -#line 176 "ob_expr_parser_gbk.l" +#line 186 "ob_expr_parser_gbk.l" { return ERROR; } YY_BREAK /* dquote */ -case 46: +case 50: YY_RULE_SETUP -#line 180 "ob_expr_parser_gbk.l" +#line 190 "ob_expr_parser_gbk.l" { PUSH_STATE(dq); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1281,10 +1367,10 @@ YY_RULE_SETUP } } YY_BREAK -case 47: -/* rule 47 can match eol */ +case 51: +/* rule 51 can match eol */ YY_RULE_SETUP -#line 190 "ob_expr_parser_gbk.l" +#line 200 "ob_expr_parser_gbk.l" { ObExprParseResult *p = (ObExprParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -1292,9 +1378,9 @@ YY_RULE_SETUP } } YY_BREAK -case 48: +case 52: YY_RULE_SETUP -#line 197 "ob_expr_parser_gbk.l" +#line 207 "ob_expr_parser_gbk.l" { POP_STATE(); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1307,31 +1393,31 @@ YY_RULE_SETUP return STR_VAL; } YY_BREAK -case 49: +case 53: YY_RULE_SETUP -#line 209 "ob_expr_parser_gbk.l" +#line 219 "ob_expr_parser_gbk.l" {} YY_BREAK -case 50: -/* rule 50 can match eol */ +case 54: +/* rule 54 can match eol */ YY_RULE_SETUP -#line 210 "ob_expr_parser_gbk.l" +#line 220 "ob_expr_parser_gbk.l" {} YY_BREAK -case 51: -/* rule 51 can match eol */ +case 55: +/* rule 55 can match eol */ YY_RULE_SETUP -#line 211 "ob_expr_parser_gbk.l" +#line 221 "ob_expr_parser_gbk.l" {} YY_BREAK case YY_STATE_EOF(dq): -#line 212 "ob_expr_parser_gbk.l" +#line 222 "ob_expr_parser_gbk.l" { return ERROR; } YY_BREAK /* backtick */ -case 52: +case 56: YY_RULE_SETUP -#line 216 "ob_expr_parser_gbk.l" +#line 226 "ob_expr_parser_gbk.l" { PUSH_STATE(bt); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1342,9 +1428,9 @@ YY_RULE_SETUP } } YY_BREAK -case 53: +case 57: YY_RULE_SETUP -#line 226 "ob_expr_parser_gbk.l" +#line 236 "ob_expr_parser_gbk.l" { ObExprParseResult *p = (ObExprParseResult *)yyextra; if (NULL != p && NULL != p->tmp_buf_ && p->tmp_len_ + 1 < OBPROXY_MAX_NAME_LENGTH) { @@ -1352,10 +1438,10 @@ YY_RULE_SETUP } } YY_BREAK -case 54: -/* rule 54 can match eol */ +case 58: +/* rule 58 can match eol */ YY_RULE_SETUP -#line 233 "ob_expr_parser_gbk.l" +#line 243 "ob_expr_parser_gbk.l" { ObExprParseResult *p = (ObExprParseResult *)yyextra; if (NULL != p && NULL != p->tmp_buf_ && p->tmp_len_ + yyleng < OBPROXY_MAX_NAME_LENGTH) { @@ -1364,9 +1450,9 @@ YY_RULE_SETUP } } YY_BREAK -case 55: +case 59: YY_RULE_SETUP -#line 241 "ob_expr_parser_gbk.l" +#line 251 "ob_expr_parser_gbk.l" { POP_STATE(); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1379,27 +1465,27 @@ YY_RULE_SETUP } YY_BREAK case YY_STATE_EOF(bt): -#line 252 "ob_expr_parser_gbk.l" +#line 262 "ob_expr_parser_gbk.l" { return ERROR; } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(in_c_comment): -#line 256 "ob_expr_parser_gbk.l" +#line 266 "ob_expr_parser_gbk.l" { return END_P; } YY_BREAK -case 56: +case 60: YY_RULE_SETUP -#line 257 "ob_expr_parser_gbk.l" +#line 267 "ob_expr_parser_gbk.l" { return IGNORED_WORD; } YY_BREAK -case 57: +case 61: YY_RULE_SETUP -#line 258 "ob_expr_parser_gbk.l" +#line 268 "ob_expr_parser_gbk.l" ECHO; YY_BREAK -#line 1405 "ob_expr_parser_gbk_lex.c" +#line 1491 "ob_expr_parser_gbk_lex.c" case YY_END_OF_BUFFER: { @@ -1691,7 +1777,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 187 ) + if ( yy_current_state >= 269 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1720,11 +1806,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 187 ) + if ( yy_current_state >= 269 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 186); + yy_is_jam = (yy_current_state == 268); return yy_is_jam ? 0 : yy_current_state; } @@ -2549,7 +2635,7 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 258 "ob_expr_parser_gbk.l" +#line 268 "ob_expr_parser_gbk.l" @@ -2680,22 +2766,26 @@ extern int ob_expr_parser_gbk_yydebug; IN = 268, ON = 269, BETWEEN = 270, - COMP_EQ = 271, - COMP_NSEQ = 272, - COMP_GE = 273, - COMP_GT = 274, - COMP_LE = 275, - COMP_LT = 276, - COMP_NE = 277, - PLACE_HOLDER = 278, - END_P = 279, - ERROR = 280, - IGNORED_WORD = 281, - NAME_OB = 282, - STR_VAL = 283, - ROW_ID = 284, - INT_VAL = 285, - POS_PLACE_HOLDER = 286 + IS = 271, + TOKEN_NULL = 272, + NOT = 273, + COMP_EQ = 274, + COMP_NSEQ = 275, + COMP_GE = 276, + COMP_GT = 277, + COMP_LE = 278, + COMP_LT = 279, + COMP_NE = 280, + PLACE_HOLDER = 281, + END_P = 282, + ERROR = 283, + IGNORED_WORD = 284, + NAME_OB = 285, + STR_VAL = 286, + ROW_ID = 287, + REVERSED_EXPR_FUNC = 288, + INT_VAL = 289, + POS_PLACE_HOLDER = 290 }; #endif diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_lex.h b/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_lex.h index c3edcf276..6f76d34d3 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_lex.h +++ b/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_lex.h @@ -341,7 +341,7 @@ extern int ob_expr_parser_gbk_yylex \ #undef YY_DECL #endif -#line 258 "ob_expr_parser_gbk.l" +#line 268 "ob_expr_parser_gbk.l" #line 348 "ob_expr_parser_gbk_lex.h" diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_tab.c b/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_tab.c index 46a18aa72..41f0d84ca 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_tab.c +++ b/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_tab.c @@ -139,22 +139,26 @@ extern int ob_expr_parser_gbk_yydebug; IN = 268, ON = 269, BETWEEN = 270, - COMP_EQ = 271, - COMP_NSEQ = 272, - COMP_GE = 273, - COMP_GT = 274, - COMP_LE = 275, - COMP_LT = 276, - COMP_NE = 277, - PLACE_HOLDER = 278, - END_P = 279, - ERROR = 280, - IGNORED_WORD = 281, - NAME_OB = 282, - STR_VAL = 283, - ROW_ID = 284, - INT_VAL = 285, - POS_PLACE_HOLDER = 286 + IS = 271, + TOKEN_NULL = 272, + NOT = 273, + COMP_EQ = 274, + COMP_NSEQ = 275, + COMP_GE = 276, + COMP_GT = 277, + COMP_LE = 278, + COMP_LT = 279, + COMP_NE = 280, + PLACE_HOLDER = 281, + END_P = 282, + ERROR = 283, + IGNORED_WORD = 284, + NAME_OB = 285, + STR_VAL = 286, + ROW_ID = 287, + REVERSED_EXPR_FUNC = 288, + INT_VAL = 289, + POS_PLACE_HOLDER = 290 }; #endif @@ -232,8 +236,8 @@ static inline void add_token_list(ObProxyTokenList *list, ObProxyTokenList *next if (OB_ISNULL(list) || OB_ISNULL(next_list)) { } else if (NULL != list->tail_ && NULL != next_list->head_ - && (TOKEN_INT_VAL == list->tail_->type_ || TOKEN_STR_VAL == list->tail_->type_) - && (TOKEN_INT_VAL == next_list->head_->type_ || TOKEN_STR_VAL == next_list->head_->type_)) { + && (TOKEN_INT_VAL == list->tail_->type_ || TOKEN_STR_VAL == list->tail_->type_ || TOKEN_FUNC == list->tail_->type_) + && (TOKEN_INT_VAL == next_list->head_->type_ || TOKEN_STR_VAL == next_list->head_->type_ || TOKEN_FUNC == next_list->head_->type_)) { list->tail_->next_ = next_list->head_; list->tail_ = next_list->head_; list->tail_->next_ = NULL; @@ -305,11 +309,18 @@ static inline void set_part_key_column_idx(ObExprParseResult *result, ObProxyPar for (i = 0; i < result->part_key_info_.key_num_; ++i) { if (is_equal(column_name, &result->part_key_info_.part_keys_[i].name_)) { result->part_key_info_.part_keys_[i].idx_ = result->column_idx_; - break; + result->part_key_info_.part_keys_[i].is_exist_in_sql_ = true; } } } +static inline void init_part_key_all_match(ObExprParseResult *result) +{ + for (int64_t i = 0; i < result->part_key_info_.key_num_; ++i) { + result->part_key_info_.part_keys_[i].is_exist_in_sql_ = true; + } +} + #define malloc_node(node, result, type) \ do { \ if (OB_ISNULL(node = ((ObProxyTokenNode *)obproxy_parse_malloc(sizeof(ObProxyTokenNode), \ @@ -344,21 +355,13 @@ static inline void set_part_key_column_idx(ObExprParseResult *result, ObProxyPar do { \ if (NULL == relation) { \ } else { \ - int64_t new_mask = get_mask(relation->type_, relation->level_); \ - bool has_rowid = result->has_rowid_; \ - if (((result->cur_mask_ | new_mask) != result->cur_mask_) \ - || (has_rowid \ - && is_equal_to_rowid(&relation->left_value_->column_node_->column_name_))) { \ + if (relation->level_ != PART_KEY_LEVEL_ZERO) { \ if (result->relation_info_.relation_num_ < OBPROXY_MAX_RELATION_NUM) { \ result->relation_info_.relations_[result->relation_info_.relation_num_++] = relation; \ - result->cur_mask_ = (result->cur_mask_ | new_mask); \ } else { \ /* YYACCEPT; */ \ } \ } \ - if ((result->cur_mask_ & result->target_mask_) == result->target_mask_) { \ - /* YYACCEPT; */ \ - } \ } \ } while(0) \ @@ -428,6 +431,92 @@ static inline void add_relation(ObExprParseResult *result, } } +static inline void set_relation_part_with_column_idx(int64_t idx_in_schema_columns, + ObExprParseResult *result, + ObProxyPartKeyLevel *level, + int64_t *first_part_column_idx, + int64_t *second_part_column_idx) +{ + if (OB_ISNULL(level) && OB_ISNULL(first_part_column_idx) && + OB_ISNULL(second_part_column_idx) && OB_ISNULL(result)) { + // do nothing + } else { + *level = PART_KEY_LEVEL_ZERO; + *first_part_column_idx = 0; + *second_part_column_idx = 0; + bool is_level_one = false; + bool is_level_two = false; + for (int i = 0; i < result->part_key_info_.key_num_; i++) { + // make sure the part_key exist in sql to avoid the uninitialized idx_ + if (idx_in_schema_columns == result->part_key_info_.part_keys_[i].idx_ && result->part_key_info_.part_keys_[i].is_exist_in_sql_) { + if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_ONE) { + is_level_one = true; + *first_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } else if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_TWO) { + is_level_two = true; + *second_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } + } + } + if (is_level_one) { + *level = PART_KEY_LEVEL_ONE; + } + if (is_level_two) { + *level = PART_KEY_LEVEL_TWO; + } + if (is_level_one && is_level_two) { + *level = PART_KEY_LEVEL_BOTH; + } + } +} + +static inline void set_relation_part_with_column_name(ObProxyParseString *column, + ObExprParseResult *result, + ObProxyPartKeyLevel *level, + int64_t *first_part_column_idx, + int64_t *second_part_column_idx) +{ + if (OB_ISNULL(column) + || OB_ISNULL(result) + || OB_ISNULL(level) + || OB_ISNULL(first_part_column_idx) + || OB_ISNULL(second_part_column_idx)) { + // do nothing + } else if (result->has_rowid_ + && is_equal_to_rowid(column)) { + // handle rowid + *level = PART_KEY_LEVEL_ONE; + *first_part_column_idx = 0; + *second_part_column_idx = 0; + } else { + *level = PART_KEY_LEVEL_ZERO; + *first_part_column_idx = 0; + *second_part_column_idx = 0; + bool is_level_one = false; + bool is_level_two = false; + for (int i = 0; i < result->part_key_info_.key_num_; i++) { + if (is_equal(&result->part_key_info_.part_keys_[i].name_, column)) { + if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_ONE) { + is_level_one = true; + *first_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } else if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_TWO) { + is_level_two = true; + *second_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } + } + } + if (is_level_one) { + *level = PART_KEY_LEVEL_ONE; + } + if (is_level_two) { + *level = PART_KEY_LEVEL_TWO; + } + if (is_level_one && is_level_two) { + *level = PART_KEY_LEVEL_BOTH; + } + } +} + static inline ObProxyRelationExpr *get_relation(ObExprParseResult *result, ObProxyTokenList *left_value, @@ -438,25 +527,25 @@ static inline ObProxyRelationExpr *get_relation(ObExprParseResult *result, ObProxyTokenList *tmp_left = NULL; ObProxyTokenList *tmp_right = NULL; ObProxyFunctionType tmp_type = F_NONE; - ObProxyPartKeyLevel tmp_level = PART_KEY_LEVEL_ZERO; int64_t tmp_column_idx_ = -1; + ObProxyParseString *tmp_column = NULL; if (NULL != left_value->column_node_ && TOKEN_COLUMN == left_value->column_node_->type_ && left_value->column_node_->part_key_idx_ >= 0) { tmp_left = left_value; - tmp_level = result->part_key_info_.part_keys_[left_value->column_node_->part_key_idx_].level_; tmp_right = right_value; tmp_type = type; tmp_column_idx_ = left_value->column_node_->part_key_idx_; + tmp_column = &left_value->column_node_->column_name_; } else if (NULL != right_value->column_node_ && TOKEN_COLUMN == right_value->column_node_->type_ && right_value->column_node_->part_key_idx_ >= 0) { tmp_left = right_value; - tmp_level = result->part_key_info_.part_keys_[right_value->column_node_->part_key_idx_].level_; tmp_right = left_value; tmp_type = get_reverse_func(type); tmp_column_idx_ = right_value->column_node_->part_key_idx_; + tmp_column = &right_value->column_node_->column_name_; } if (NULL == tmp_left || NULL == tmp_right || F_COMP_NE == tmp_type) { @@ -469,7 +558,11 @@ static inline ObProxyRelationExpr *get_relation(ObExprParseResult *result, relation->left_value_ = tmp_left; relation->type_ = tmp_type; relation->right_value_ = tmp_right; - relation->level_ = tmp_level; + set_relation_part_with_column_name(tmp_column, + result, + &relation->level_, + &relation->first_part_column_idx_, + &relation->second_part_column_idx_); } return relation; } @@ -483,14 +576,20 @@ static inline ObProxyRelationExpr *get_values_relation(ObExprParseResult *result } else { int64_t i = 0; for (i = 0; i < result->part_key_info_.key_num_; ++i) { - if (result->values_list_idx_ == result->part_key_info_.part_keys_[i].idx_) { + // make sure the part_key exist in sql to avoid the uninitialized idx_ + if (result->values_list_idx_ == result->part_key_info_.part_keys_[i].idx_ && result->part_key_info_.part_keys_[i].is_exist_in_sql_) { if (OB_ISNULL(relation = ((ObProxyRelationExpr *)obproxy_parse_malloc( sizeof(ObProxyRelationExpr), result->malloc_pool_)))) { } else { relation->column_idx_ = i; relation->type_ = F_COMP_EQ; relation->right_value_ = right_value; - relation->level_ = result->part_key_info_.part_keys_[i].level_; + relation->left_value_ = NULL; + set_relation_part_with_column_idx(result->values_list_idx_, + result, + &relation->level_, + &relation->first_part_column_idx_, + &relation->second_part_column_idx_); } break; } @@ -752,20 +851,20 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 17 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 231 +#define YYLAST 242 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 44 +#define YYNTOKENS 48 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 24 /* YYNRULES -- Number of rules. */ -#define YYNRULES 80 +#define YYNRULES 83 /* YYNRULES -- Number of states. */ -#define YYNSTATES 144 +#define YYNSTATES 149 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 286 +#define YYMAXUTOK 290 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -776,9 +875,9 @@ static const yytype_uint8 yytranslate[] = 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 43, 2, 2, 2, 41, 42, 2, - 35, 32, 39, 37, 36, 38, 34, 40, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, + 2, 2, 2, 47, 2, 2, 2, 45, 46, 2, + 39, 36, 43, 41, 40, 42, 38, 44, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 37, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -801,7 +900,8 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31 + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35 }; #if YYDEBUG @@ -812,57 +912,58 @@ static const yytype_uint16 yyprhs[] = 0, 0, 3, 6, 9, 13, 16, 21, 23, 25, 27, 29, 31, 33, 36, 40, 43, 48, 52, 57, 63, 70, 72, 76, 82, 86, 92, 96, 102, 108, - 114, 120, 122, 124, 126, 128, 130, 132, 134, 136, - 140, 142, 144, 147, 148, 152, 156, 158, 160, 164, - 170, 175, 180, 182, 184, 186, 188, 190, 192, 194, - 196, 198, 200, 202, 204, 209, 214, 218, 220, 224, - 230, 231, 235, 237, 241, 243, 245, 249, 251, 255, - 256 + 114, 120, 124, 129, 131, 133, 135, 137, 139, 141, + 143, 145, 149, 151, 153, 156, 157, 161, 165, 167, + 169, 173, 179, 181, 186, 191, 193, 195, 197, 199, + 201, 203, 205, 207, 209, 211, 213, 215, 220, 225, + 229, 231, 235, 241, 242, 246, 248, 252, 254, 256, + 260, 262, 266, 267 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 45, 0, -1, 3, 46, -1, 4, 60, -1, 5, - 51, 47, -1, 48, 47, -1, 48, 5, 51, 47, - -1, 1, -1, 9, -1, 32, -1, 33, -1, 24, - -1, 49, -1, 48, 49, -1, 50, 14, 51, -1, - 10, 27, -1, 10, 27, 34, 27, -1, 10, 27, - 27, -1, 10, 27, 6, 27, -1, 10, 27, 34, - 27, 27, -1, 10, 27, 34, 27, 6, 27, -1, - 52, -1, 51, 11, 52, -1, 35, 51, 11, 52, - 32, -1, 51, 12, 52, -1, 35, 51, 12, 52, - 32, -1, 55, 53, 55, -1, 55, 53, 35, 55, - 32, -1, 35, 55, 53, 55, 32, -1, 55, 13, - 35, 54, 32, -1, 55, 15, 55, 11, 55, -1, - 16, -1, 17, -1, 18, -1, 19, -1, 20, -1, - 21, -1, 22, -1, 55, -1, 54, 36, 55, -1, - 56, -1, 58, -1, 56, 58, -1, -1, 56, 36, - 56, -1, 57, 36, 56, -1, 29, -1, 27, -1, - 27, 34, 27, -1, 27, 34, 27, 34, 27, -1, - 27, 35, 56, 32, -1, 27, 35, 57, 32, -1, - 30, -1, 28, -1, 59, -1, 23, -1, 31, -1, - 37, -1, 38, -1, 39, -1, 40, -1, 41, -1, - 42, -1, 43, -1, 62, 7, 61, 47, -1, 8, - 66, 67, 47, -1, 14, 51, 47, -1, 46, -1, - 35, 65, 32, -1, 61, 36, 35, 65, 32, -1, - -1, 35, 63, 32, -1, 64, -1, 63, 36, 64, - -1, 27, -1, 55, -1, 65, 36, 55, -1, 52, - -1, 66, 36, 52, -1, -1, 5, 51, -1 + 49, 0, -1, 3, 50, -1, 4, 64, -1, 5, + 55, 51, -1, 52, 51, -1, 52, 5, 55, 51, + -1, 1, -1, 9, -1, 36, -1, 37, -1, 27, + -1, 53, -1, 52, 53, -1, 54, 14, 55, -1, + 10, 30, -1, 10, 30, 38, 30, -1, 10, 30, + 30, -1, 10, 30, 6, 30, -1, 10, 30, 38, + 30, 30, -1, 10, 30, 38, 30, 6, 30, -1, + 56, -1, 55, 11, 56, -1, 39, 55, 11, 56, + 36, -1, 55, 12, 56, -1, 39, 55, 12, 56, + 36, -1, 59, 57, 59, -1, 59, 57, 39, 59, + 36, -1, 39, 59, 57, 59, 36, -1, 59, 13, + 39, 58, 36, -1, 59, 15, 59, 11, 59, -1, + 59, 16, 17, -1, 59, 16, 18, 17, -1, 19, + -1, 20, -1, 21, -1, 22, -1, 23, -1, 24, + -1, 25, -1, 59, -1, 58, 40, 59, -1, 60, + -1, 62, -1, 60, 62, -1, -1, 60, 40, 60, + -1, 61, 40, 60, -1, 32, -1, 30, -1, 30, + 38, 30, -1, 30, 38, 30, 38, 30, -1, 33, + -1, 30, 39, 60, 36, -1, 30, 39, 61, 36, + -1, 34, -1, 31, -1, 63, -1, 26, -1, 35, + -1, 41, -1, 42, -1, 43, -1, 44, -1, 45, + -1, 46, -1, 47, -1, 66, 7, 65, 51, -1, + 8, 70, 71, 51, -1, 14, 55, 51, -1, 50, + -1, 39, 69, 36, -1, 65, 40, 39, 69, 36, + -1, -1, 39, 67, 36, -1, 68, -1, 67, 40, + 68, -1, 30, -1, 59, -1, 69, 40, 59, -1, + 56, -1, 70, 40, 56, -1, -1, 5, 55, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 380, 380, 381, 383, 384, 385, 386, 388, 389, - 390, 391, 393, 394, 396, 398, 399, 400, 401, 402, - 403, 405, 406, 407, 408, 409, 411, 412, 413, 414, - 415, 426, 427, 428, 429, 430, 431, 432, 434, 435, - 437, 439, 440, 442, 443, 444, 447, 454, 460, 466, - 472, 478, 484, 485, 486, 487, 493, 499, 500, 501, - 502, 503, 504, 505, 507, 508, 509, 510, 512, 516, - 521, 522, 527, 531, 536, 542, 552, 562, 563, 565, - 566 + 0, 475, 475, 476, 478, 479, 480, 481, 483, 484, + 485, 486, 488, 489, 491, 493, 494, 495, 496, 497, + 498, 500, 501, 502, 503, 504, 506, 507, 508, 509, + 510, 520, 521, 523, 524, 525, 526, 527, 528, 529, + 531, 532, 534, 536, 537, 539, 540, 541, 544, 551, + 557, 563, 569, 574, 580, 586, 587, 588, 589, 595, + 601, 602, 603, 604, 605, 606, 607, 609, 610, 611, + 612, 614, 618, 623, 624, 629, 633, 638, 644, 654, + 664, 665, 667, 668 }; #endif @@ -873,13 +974,14 @@ static const char *const yytname[] = { "$end", "error", "$undefined", "DUMMY_SELECT_CLAUSE", "DUMMY_INSERT_CLAUSE", "WHERE", "AS", "VALUES", "SET", "END_WHERE", - "JOIN", "AND_OP", "OR_OP", "IN", "ON", "BETWEEN", "COMP_EQ", "COMP_NSEQ", - "COMP_GE", "COMP_GT", "COMP_LE", "COMP_LT", "COMP_NE", "PLACE_HOLDER", - "END_P", "ERROR", "IGNORED_WORD", "NAME_OB", "STR_VAL", "ROW_ID", - "INT_VAL", "POS_PLACE_HOLDER", "')'", "';'", "'.'", "'('", "','", "'+'", - "'-'", "'*'", "'/'", "'%'", "'&'", "'!'", "$accept", "start", - "select_root", "end_flag", "join_expr_list", "join_on_expr", "join_expr", - "cond_expr", "bool_pri", "comp", "in_expr_list", "expr", "token_list", + "JOIN", "AND_OP", "OR_OP", "IN", "ON", "BETWEEN", "IS", "TOKEN_NULL", + "NOT", "COMP_EQ", "COMP_NSEQ", "COMP_GE", "COMP_GT", "COMP_LE", + "COMP_LT", "COMP_NE", "PLACE_HOLDER", "END_P", "ERROR", "IGNORED_WORD", + "NAME_OB", "STR_VAL", "ROW_ID", "REVERSED_EXPR_FUNC", "INT_VAL", + "POS_PLACE_HOLDER", "')'", "';'", "'.'", "'('", "','", "'+'", "'-'", + "'*'", "'/'", "'%'", "'&'", "'!'", "$accept", "start", "select_root", + "end_flag", "join_expr_list", "join_on_expr", "join_expr", "cond_expr", + "bool_pri", "comp", "in_expr_list", "expr", "token_list", "func_param_list", "token", "operator", "insert_root", "values_expr_lists", "opt_column_list", "column_list", "opt_column", "values_expr_list", "set_expr", "opt_where_clause", 0 @@ -894,23 +996,23 @@ static const yytype_uint16 yytoknum[] = 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 41, 59, 46, 40, 44, 43, 45, 42, - 47, 37, 38, 33 + 285, 286, 287, 288, 289, 290, 41, 59, 46, 40, + 44, 43, 45, 42, 47, 37, 38, 33 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 44, 45, 45, 46, 46, 46, 46, 47, 47, - 47, 47, 48, 48, 49, 50, 50, 50, 50, 50, - 50, 51, 51, 51, 51, 51, 52, 52, 52, 52, - 52, 53, 53, 53, 53, 53, 53, 53, 54, 54, - 55, 56, 56, 57, 57, 57, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 59, 59, 59, - 59, 59, 59, 59, 60, 60, 60, 60, 61, 61, - 62, 62, 63, 63, 64, 65, 65, 66, 66, 67, - 67 + 0, 48, 49, 49, 50, 50, 50, 50, 51, 51, + 51, 51, 52, 52, 53, 54, 54, 54, 54, 54, + 54, 55, 55, 55, 55, 55, 56, 56, 56, 56, + 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, + 58, 58, 59, 60, 60, 61, 61, 61, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 63, 63, 63, 63, 63, 63, 63, 64, 64, 64, + 64, 65, 65, 66, 66, 67, 67, 68, 69, 69, + 70, 70, 71, 71 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -919,12 +1021,12 @@ static const yytype_uint8 yyr2[] = 0, 2, 2, 2, 3, 2, 4, 1, 1, 1, 1, 1, 1, 2, 3, 2, 4, 3, 4, 5, 6, 1, 3, 5, 3, 5, 3, 5, 5, 5, - 5, 1, 1, 1, 1, 1, 1, 1, 1, 3, - 1, 1, 2, 0, 3, 3, 1, 1, 3, 5, - 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 4, 4, 3, 1, 3, 5, - 0, 3, 1, 3, 1, 1, 3, 1, 3, 0, - 2 + 5, 3, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 1, 1, 2, 0, 3, 3, 1, 1, + 3, 5, 1, 4, 4, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 4, 4, 3, + 1, 3, 5, 0, 3, 1, 3, 1, 1, 3, + 1, 3, 0, 2 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -933,140 +1035,142 @@ static const yytype_uint8 yyr2[] = static const yytype_uint8 yydefact[] = { 0, 0, 0, 0, 7, 0, 0, 2, 0, 12, - 0, 0, 0, 0, 67, 3, 0, 1, 55, 47, - 53, 46, 52, 56, 0, 57, 58, 59, 60, 61, - 62, 63, 0, 21, 0, 40, 41, 54, 15, 0, - 8, 11, 9, 10, 5, 13, 0, 0, 77, 79, - 0, 74, 0, 72, 0, 0, 43, 0, 0, 0, - 0, 4, 0, 0, 31, 32, 33, 34, 35, 36, - 37, 0, 42, 0, 17, 0, 0, 14, 0, 0, - 0, 0, 66, 71, 0, 0, 0, 48, 0, 0, - 0, 0, 0, 22, 24, 0, 0, 0, 26, 18, - 16, 6, 0, 80, 78, 65, 73, 75, 0, 0, - 64, 0, 50, 0, 51, 0, 22, 24, 26, 0, - 38, 0, 0, 0, 19, 0, 68, 0, 0, 49, - 44, 45, 23, 25, 28, 29, 0, 30, 27, 20, - 76, 0, 39, 69 + 0, 0, 0, 0, 70, 3, 0, 1, 58, 49, + 56, 48, 52, 55, 59, 0, 60, 61, 62, 63, + 64, 65, 66, 0, 21, 0, 42, 43, 57, 15, + 0, 8, 11, 9, 10, 5, 13, 0, 0, 80, + 82, 0, 77, 0, 75, 0, 0, 45, 0, 0, + 0, 0, 4, 0, 0, 0, 33, 34, 35, 36, + 37, 38, 39, 0, 44, 0, 17, 0, 0, 14, + 0, 0, 0, 0, 69, 74, 0, 0, 0, 50, + 0, 0, 0, 0, 0, 22, 24, 0, 0, 31, + 0, 0, 26, 18, 16, 6, 0, 83, 81, 68, + 76, 78, 0, 0, 67, 0, 53, 0, 54, 0, + 22, 24, 26, 0, 40, 0, 32, 0, 0, 19, + 0, 71, 0, 0, 51, 46, 47, 23, 25, 28, + 29, 0, 30, 27, 20, 79, 0, 41, 72 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 3, 7, 44, 8, 9, 10, 32, 33, 71, - 119, 34, 35, 89, 36, 37, 15, 86, 16, 52, - 53, 108, 49, 81 + -1, 3, 7, 45, 8, 9, 10, 33, 34, 73, + 123, 35, 36, 91, 37, 38, 15, 88, 16, 53, + 54, 112, 50, 83 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -52 +#define YYPACT_NINF -54 static const yytype_int16 yypact[] = { - 41, 16, 1, 13, -52, 108, -9, -52, 22, -52, - 14, 129, 108, 6, -52, -52, 33, -52, -52, 31, - -52, -52, -52, -52, 108, -52, -52, -52, -52, -52, - -52, -52, 76, -52, 202, 171, -52, -52, 8, 108, - -52, -52, -52, -52, -52, -52, 108, 171, -52, 7, - 76, -52, -12, -52, 3, 24, 171, 84, 202, 129, - 129, -52, 25, 171, -52, -52, -52, -52, -52, -52, - -52, 150, -52, 30, -52, 45, 76, 90, 209, 108, - 129, 60, -52, -52, 6, 171, 43, 49, 87, -7, - 129, 129, 150, -52, -52, 171, 66, 171, -52, -52, - 10, -52, 171, 90, -52, -52, -52, -52, 27, 54, - -52, 64, -52, 171, -52, 171, 73, 74, 75, 50, - -52, 171, 79, 86, -52, 75, -52, 171, 171, -52, - 171, 171, -52, -52, -52, -52, 171, -52, -52, -52, - -52, 58, -52, -52 + 16, 77, 8, 7, -54, 109, -5, -54, 22, -54, + 24, 131, 109, 38, -54, -54, 44, -54, -54, 6, + -54, -54, -54, -54, -54, 109, -54, -54, -54, -54, + -54, -54, -54, 68, -54, 210, 175, -54, -54, 5, + 109, -54, -54, -54, -54, -54, -54, 109, 175, -54, + 0, 68, -54, -28, -54, 15, 43, 175, 79, 210, + 131, 131, -54, 36, 175, 75, -54, -54, -54, -54, + -54, -54, -54, 153, -54, 53, -54, 56, 68, 85, + 217, 109, 131, 62, -54, -54, 38, 175, -3, 50, + 87, -10, 131, 131, 153, -54, -54, 175, 83, -54, + 86, 175, -54, -54, 11, -54, 175, 85, -54, -54, + -54, -54, 10, 67, -54, 80, -54, 175, -54, 175, + 73, 76, 78, 21, -54, 175, -54, 88, 81, -54, + 78, -54, 175, 175, -54, 175, 175, -54, -54, -54, + -54, 175, -54, -54, -54, -54, 27, -54, -54 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -52, -52, 118, -28, -52, 113, -52, -5, -10, -48, - -52, -24, -51, -52, -32, -52, -52, -52, -52, -52, - 38, 4, -52, -52 + -54, -54, 113, -23, -54, 117, -54, -11, -8, -38, + -54, -25, -53, -54, -34, -54, -54, -54, -54, -54, + 40, 3, -54, -54 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -71 +#define YYTABLE_NINF -74 static const yytype_int16 yytable[] = { - 58, 48, 4, 72, 61, 88, 5, 50, -70, 11, - 92, 6, 79, 17, 73, 12, 123, 4, 38, 57, - 83, 5, 82, 78, 84, 114, 6, 39, 46, 115, - 102, 40, 6, 51, 76, 74, 13, 124, 85, 96, - 54, 77, 75, 80, 1, 2, 41, 98, 101, 93, - 94, 87, 40, 105, 42, 43, 72, 99, 110, 126, - 95, 107, 130, 127, 131, 55, 56, 41, 118, 40, - 104, 120, 100, 122, 103, 42, 43, 121, 125, 109, - 116, 117, 135, 111, 41, 40, 136, 59, 60, 128, - 143, 129, 42, 43, 127, 90, 91, 137, 72, 72, - 41, 59, 60, 140, 107, 132, 133, 134, 42, 43, - 18, 138, 142, 139, 19, 20, 21, 22, 23, 112, - 14, 45, 106, 113, 25, 26, 27, 28, 29, 30, - 31, 18, 141, 0, 0, 19, 20, 21, 22, 23, - 0, 0, 0, 24, 0, 25, 26, 27, 28, 29, - 30, 31, 18, 0, 0, 0, 19, 20, 21, 22, - 23, 0, 0, 0, 47, 0, 25, 26, 27, 28, - 29, 30, 31, 18, 0, 0, 0, 19, 20, 21, - 22, 23, 0, 0, 0, 97, 0, 25, 26, 27, - 28, 29, 30, 31, 18, 0, 0, 0, 19, 20, - 21, 22, 23, 0, 0, 0, 0, 0, 25, 26, - 27, 28, 29, 30, 31, 62, 0, 63, 64, 65, - 66, 67, 68, 69, 70, 64, 65, 66, 67, 68, - 69, 70 + 59, 51, 74, 49, 90, 81, 41, 17, 85, 4, + 62, 75, 86, 5, 58, -73, 11, 128, 6, 1, + 2, 94, 12, 80, 42, 39, 118, 40, 84, 78, + 119, 41, 6, 43, 44, 76, 79, 113, 47, 98, + 82, 129, 106, 77, 56, 57, 131, 13, 102, 42, + 132, 55, 95, 96, 87, 105, 74, 140, 43, 44, + 109, 141, 111, 148, 135, 114, 136, 132, 52, 122, + 107, 41, 124, 89, 108, 97, 127, 41, 4, 60, + 61, 130, 5, 103, 120, 121, 104, 6, 115, 42, + 92, 93, 99, 100, 125, 42, 60, 61, 43, 44, + 142, 74, 74, 126, 43, 44, 133, 145, 111, 137, + 134, 144, 138, 18, 139, 14, 147, 19, 20, 21, + 22, 23, 24, 116, 143, 46, 110, 117, 26, 27, + 28, 29, 30, 31, 32, 18, 146, 0, 0, 19, + 20, 21, 22, 23, 24, 0, 0, 0, 25, 0, + 26, 27, 28, 29, 30, 31, 32, 18, 0, 0, + 0, 19, 20, 21, 22, 23, 24, 0, 0, 0, + 48, 0, 26, 27, 28, 29, 30, 31, 32, 18, + 0, 0, 0, 19, 20, 21, 22, 23, 24, 0, + 0, 0, 101, 0, 26, 27, 28, 29, 30, 31, + 32, 18, 0, 0, 0, 19, 20, 21, 22, 23, + 24, 0, 0, 0, 0, 0, 26, 27, 28, 29, + 30, 31, 32, 63, 0, 64, 65, 0, 0, 66, + 67, 68, 69, 70, 71, 72, 66, 67, 68, 69, + 70, 71, 72 }; static const yytype_int16 yycheck[] = { - 24, 11, 1, 35, 32, 56, 5, 12, 7, 8, - 58, 10, 5, 0, 6, 14, 6, 1, 27, 24, - 32, 5, 50, 47, 36, 32, 10, 5, 14, 36, - 78, 9, 10, 27, 39, 27, 35, 27, 35, 63, - 7, 46, 34, 36, 3, 4, 24, 71, 76, 59, - 60, 27, 9, 81, 32, 33, 88, 27, 86, 32, - 35, 85, 113, 36, 115, 34, 35, 24, 92, 9, - 80, 95, 27, 97, 79, 32, 33, 11, 102, 36, - 90, 91, 32, 34, 24, 9, 36, 11, 12, 35, - 32, 27, 32, 33, 36, 11, 12, 121, 130, 131, - 24, 11, 12, 127, 128, 32, 32, 32, 32, 33, - 23, 32, 136, 27, 27, 28, 29, 30, 31, 32, - 2, 8, 84, 36, 37, 38, 39, 40, 41, 42, - 43, 23, 128, -1, -1, 27, 28, 29, 30, 31, - -1, -1, -1, 35, -1, 37, 38, 39, 40, 41, - 42, 43, 23, -1, -1, -1, 27, 28, 29, 30, - 31, -1, -1, -1, 35, -1, 37, 38, 39, 40, - 41, 42, 43, 23, -1, -1, -1, 27, 28, 29, - 30, 31, -1, -1, -1, 35, -1, 37, 38, 39, - 40, 41, 42, 43, 23, -1, -1, -1, 27, 28, - 29, 30, 31, -1, -1, -1, -1, -1, 37, 38, - 39, 40, 41, 42, 43, 13, -1, 15, 16, 17, - 18, 19, 20, 21, 22, 16, 17, 18, 19, 20, - 21, 22 + 25, 12, 36, 11, 57, 5, 9, 0, 36, 1, + 33, 6, 40, 5, 25, 7, 8, 6, 10, 3, + 4, 59, 14, 48, 27, 30, 36, 5, 51, 40, + 40, 9, 10, 36, 37, 30, 47, 40, 14, 64, + 40, 30, 80, 38, 38, 39, 36, 39, 73, 27, + 40, 7, 60, 61, 39, 78, 90, 36, 36, 37, + 83, 40, 87, 36, 117, 88, 119, 40, 30, 94, + 81, 9, 97, 30, 82, 39, 101, 9, 1, 11, + 12, 106, 5, 30, 92, 93, 30, 10, 38, 27, + 11, 12, 17, 18, 11, 27, 11, 12, 36, 37, + 125, 135, 136, 17, 36, 37, 39, 132, 133, 36, + 30, 30, 36, 26, 36, 2, 141, 30, 31, 32, + 33, 34, 35, 36, 36, 8, 86, 40, 41, 42, + 43, 44, 45, 46, 47, 26, 133, -1, -1, 30, + 31, 32, 33, 34, 35, -1, -1, -1, 39, -1, + 41, 42, 43, 44, 45, 46, 47, 26, -1, -1, + -1, 30, 31, 32, 33, 34, 35, -1, -1, -1, + 39, -1, 41, 42, 43, 44, 45, 46, 47, 26, + -1, -1, -1, 30, 31, 32, 33, 34, 35, -1, + -1, -1, 39, -1, 41, 42, 43, 44, 45, 46, + 47, 26, -1, -1, -1, 30, 31, 32, 33, 34, + 35, -1, -1, -1, -1, -1, 41, 42, 43, 44, + 45, 46, 47, 13, -1, 15, 16, -1, -1, 19, + 20, 21, 22, 23, 24, 25, 19, 20, 21, 22, + 23, 24, 25 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 3, 4, 45, 1, 5, 10, 46, 48, 49, - 50, 8, 14, 35, 46, 60, 62, 0, 23, 27, - 28, 29, 30, 31, 35, 37, 38, 39, 40, 41, - 42, 43, 51, 52, 55, 56, 58, 59, 27, 5, - 9, 24, 32, 33, 47, 49, 14, 35, 52, 66, - 51, 27, 63, 64, 7, 34, 35, 51, 55, 11, - 12, 47, 13, 15, 16, 17, 18, 19, 20, 21, - 22, 53, 58, 6, 27, 34, 51, 51, 55, 5, - 36, 67, 47, 32, 36, 35, 61, 27, 56, 57, - 11, 12, 53, 52, 52, 35, 55, 35, 55, 27, - 27, 47, 53, 51, 52, 47, 64, 55, 65, 36, - 47, 34, 32, 36, 32, 36, 52, 52, 55, 54, - 55, 11, 55, 6, 27, 55, 32, 36, 35, 27, - 56, 56, 32, 32, 32, 32, 36, 55, 32, 27, - 55, 65, 55, 32 + 0, 3, 4, 49, 1, 5, 10, 50, 52, 53, + 54, 8, 14, 39, 50, 64, 66, 0, 26, 30, + 31, 32, 33, 34, 35, 39, 41, 42, 43, 44, + 45, 46, 47, 55, 56, 59, 60, 62, 63, 30, + 5, 9, 27, 36, 37, 51, 53, 14, 39, 56, + 70, 55, 30, 67, 68, 7, 38, 39, 55, 59, + 11, 12, 51, 13, 15, 16, 19, 20, 21, 22, + 23, 24, 25, 57, 62, 6, 30, 38, 55, 55, + 59, 5, 40, 71, 51, 36, 40, 39, 65, 30, + 60, 61, 11, 12, 57, 56, 56, 39, 59, 17, + 18, 39, 59, 30, 30, 51, 57, 55, 56, 51, + 68, 59, 69, 40, 51, 38, 36, 40, 36, 40, + 56, 56, 59, 58, 59, 11, 17, 59, 6, 30, + 59, 36, 40, 39, 30, 60, 60, 36, 36, 36, + 36, 40, 59, 36, 30, 59, 69, 59, 36 }; #define yyerrok (yyerrstatus = 0) @@ -2003,47 +2107,47 @@ YYLTYPE yylloc; case 31: - { (yyval.func) = F_COMP_EQ; ;} + { (yyval.relation) = NULL; ;} break; case 32: - { (yyval.func) = F_COMP_NSEQ; ;} + { (yyval.relation) = NULL; ;} break; case 33: - { (yyval.func) = F_COMP_GE; ;} + { (yyval.func) = F_COMP_EQ; ;} break; case 34: - { (yyval.func) = F_COMP_GT; ;} + { (yyval.func) = F_COMP_NSEQ; ;} break; case 35: - { (yyval.func) = F_COMP_LE; ;} + { (yyval.func) = F_COMP_GE; ;} break; case 36: - { (yyval.func) = F_COMP_LT; ;} + { (yyval.func) = F_COMP_GT; ;} break; case 37: - { (yyval.func) = F_COMP_NE; ;} + { (yyval.func) = F_COMP_LE; ;} break; case 38: - { (yyval.list) = (yyvsp[(1) - (1)].list); ;} + { (yyval.func) = F_COMP_LT; ;} break; case 39: - { (yyval.list) = (yyvsp[(1) - (3)].list); add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); ;} + { (yyval.func) = F_COMP_NE; ;} break; case 40: @@ -2053,31 +2157,41 @@ YYLTYPE yylloc; case 41: - { malloc_list((yyval.list), result, (yyvsp[(1) - (1)].node)); ;} + { (yyval.list) = (yyvsp[(1) - (3)].list); add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); ;} break; case 42: - { add_token((yyvsp[(1) - (2)].list), result, (yyvsp[(2) - (2)].node)); (yyval.list) = (yyvsp[(1) - (2)].list); ;} + { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; case 43: - { (yyval.list) = NULL; ;} + { malloc_list((yyval.list), result, (yyvsp[(1) - (1)].node)); ;} break; case 44: - { add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); (yyval.list) = (yyvsp[(1) - (3)].list); ;} + { add_token((yyvsp[(1) - (2)].list), result, (yyvsp[(2) - (2)].node)); (yyval.list) = (yyvsp[(1) - (2)].list); ;} break; case 45: - { add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); (yyval.list) = (yyvsp[(1) - (3)].list); ;} + { (yyval.list) = NULL; ;} break; case 46: + { add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); (yyval.list) = (yyvsp[(1) - (3)].list); ;} + break; + + case 47: + + { add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); (yyval.list) = (yyvsp[(1) - (3)].list); ;} + break; + + case 48: + { malloc_node((yyval.node), result, TOKEN_COLUMN); (yyval.node)->part_key_idx_ = 0; @@ -2086,7 +2200,7 @@ YYLTYPE yylloc; ;} break; - case 47: + case 49: { malloc_node((yyval.node), result, TOKEN_COLUMN); @@ -2095,7 +2209,7 @@ YYLTYPE yylloc; ;} break; - case 48: + case 50: { malloc_node((yyval.node), result, TOKEN_COLUMN); @@ -2104,7 +2218,7 @@ YYLTYPE yylloc; ;} break; - case 49: + case 51: { malloc_node((yyval.node), result, TOKEN_COLUMN); @@ -2113,7 +2227,15 @@ YYLTYPE yylloc; ;} break; - case 50: + case 52: + + { + malloc_node((yyval.node), result, TOKEN_FUNC); + (yyval.node)->str_value_ = (yyvsp[(1) - (1)].str); + ;} + break; + + case 53: { malloc_node((yyval.node), result, TOKEN_FUNC); @@ -2122,7 +2244,7 @@ YYLTYPE yylloc; ;} break; - case 51: + case 54: { malloc_node((yyval.node), result, TOKEN_FUNC); @@ -2131,22 +2253,22 @@ YYLTYPE yylloc; ;} break; - case 52: + case 55: { malloc_node((yyval.node), result, TOKEN_INT_VAL); (yyval.node)->int_value_ = (yyvsp[(1) - (1)].num); ;} break; - case 53: + case 56: { malloc_node((yyval.node), result, TOKEN_STR_VAL); (yyval.node)->str_value_ = (yyvsp[(1) - (1)].str); ;} break; - case 54: + case 57: { malloc_node((yyval.node), result, TOKEN_OPERATOR); (yyval.node)->operator_ = (yyvsp[(1) - (1)].operator); ;} break; - case 55: + case 58: { result->placeholder_list_idx_++; @@ -2155,7 +2277,7 @@ YYLTYPE yylloc; ;} break; - case 56: + case 59: { malloc_node((yyval.node), result, TOKEN_PLACE_HOLDER); @@ -2163,71 +2285,76 @@ YYLTYPE yylloc; ;} break; - case 57: + case 60: { (yyval.operator) = OPT_ADD; ;} break; - case 58: + case 61: { (yyval.operator) = OPT_MINUS; ;} break; - case 59: + case 62: { (yyval.operator) = OPT_MUL; ;} break; - case 60: + case 63: { (yyval.operator) = OPT_DIV; ;} break; - case 61: + case 64: { (yyval.operator) = OPT_MOD; ;} break; - case 62: + case 65: { (yyval.operator) = OPT_AND; ;} break; - case 63: + case 66: { (yyval.operator) = OPT_NOT; ;} break; - case 64: + case 67: { YYACCEPT; ;} break; - case 65: + case 68: { YYACCEPT; ;} break; - case 66: + case 69: { YYACCEPT; ;} break; - case 68: + case 71: { result->multi_param_values_++; ;} break; - case 69: + case 72: { result->multi_param_values_++; ;} break; - case 72: + case 73: + + { init_part_key_all_match(result);;} + break; + + case 75: { malloc_list((yyval.list), result, (yyvsp[(1) - (1)].node)); @@ -2235,7 +2362,7 @@ YYLTYPE yylloc; ;} break; - case 73: + case 76: { malloc_list((yyval.list), result, (yyvsp[(3) - (3)].node)); @@ -2243,7 +2370,7 @@ YYLTYPE yylloc; ;} break; - case 74: + case 77: { set_part_key_column_idx(result, &(yyvsp[(1) - (1)].str)); @@ -2253,7 +2380,7 @@ YYLTYPE yylloc; ;} break; - case 75: + case 78: { if (result->multi_param_values_ < 1) { @@ -2266,7 +2393,7 @@ YYLTYPE yylloc; ;} break; - case 76: + case 79: { if (result->multi_param_values_ < 1) { @@ -2278,17 +2405,17 @@ YYLTYPE yylloc; ;} break; - case 77: + case 80: { check_and_add_relation(result, (yyvsp[(1) - (1)].relation)); ;} break; - case 78: + case 81: { check_and_add_relation(result, (yyvsp[(3) - (3)].relation)); ;} break; - case 80: + case 83: {;} break; diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_tab.h b/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_tab.h index 8c63ec12f..9c8c5a669 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_tab.h +++ b/src/obproxy/opsql/expr_parser/ob_expr_parser_gbk_tab.h @@ -69,22 +69,26 @@ extern int ob_expr_parser_gbk_yydebug; IN = 268, ON = 269, BETWEEN = 270, - COMP_EQ = 271, - COMP_NSEQ = 272, - COMP_GE = 273, - COMP_GT = 274, - COMP_LE = 275, - COMP_LT = 276, - COMP_NE = 277, - PLACE_HOLDER = 278, - END_P = 279, - ERROR = 280, - IGNORED_WORD = 281, - NAME_OB = 282, - STR_VAL = 283, - ROW_ID = 284, - INT_VAL = 285, - POS_PLACE_HOLDER = 286 + IS = 271, + TOKEN_NULL = 272, + NOT = 273, + COMP_EQ = 274, + COMP_NSEQ = 275, + COMP_GE = 276, + COMP_GT = 277, + COMP_LE = 278, + COMP_LT = 279, + COMP_NE = 280, + PLACE_HOLDER = 281, + END_P = 282, + ERROR = 283, + IGNORED_WORD = 284, + NAME_OB = 285, + STR_VAL = 286, + ROW_ID = 287, + REVERSED_EXPR_FUNC = 288, + INT_VAL = 289, + POS_PLACE_HOLDER = 290 }; #endif diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_lex.c b/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_lex.c index 59356d32a..c9ed9c7ba 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_lex.c +++ b/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_lex.c @@ -348,8 +348,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); yyg->yy_hold_char = *yy_cp; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 57 -#define YY_END_OF_BUFFER 58 +#define YY_NUM_RULES 61 +#define YY_END_OF_BUFFER 62 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -357,30 +357,38 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[197] = +static yyconst flex_int16_t yy_accept[279] = { 0, - 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, - 58, 56, 31, 31, 35, 46, 31, 30, 35, 35, - 40, 33, 34, 35, 32, 35, 35, 35, 28, 35, - 24, 19, 22, 26, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 52, 35, 56, - 56, 39, 38, 39, 41, 42, 57, 47, 48, 57, - 54, 55, 31, 0, 25, 31, 30, 15, 28, 0, - 0, 28, 29, 36, 29, 28, 30, 0, 27, 23, - 21, 30, 2, 30, 30, 30, 30, 18, 30, 30, - 12, 16, 30, 30, 30, 30, 17, 0, 0, 0, - - 37, 41, 0, 0, 43, 0, 0, 44, 47, 0, - 49, 0, 0, 0, 50, 54, 53, 31, 0, 0, - 0, 29, 0, 0, 29, 20, 14, 30, 6, 30, - 30, 30, 30, 30, 5, 30, 30, 33, 34, 32, - 45, 0, 45, 0, 0, 51, 0, 51, 0, 0, - 31, 31, 31, 0, 29, 0, 29, 0, 29, 30, - 30, 30, 11, 30, 30, 30, 30, 0, 0, 0, - 0, 31, 30, 8, 30, 7, 10, 4, 1, 0, - 0, 45, 0, 0, 0, 0, 51, 0, 0, 30, - 9, 3, 0, 0, 13, 0 - + 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, + 62, 60, 35, 35, 39, 50, 35, 34, 39, 39, + 44, 37, 38, 39, 36, 39, 39, 39, 32, 39, + 27, 22, 25, 29, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 56, 39, + 60, 60, 43, 42, 43, 45, 46, 61, 51, 52, + 61, 58, 59, 35, 0, 28, 35, 34, 15, 32, + 0, 0, 32, 33, 40, 33, 32, 34, 0, 30, + 26, 24, 34, 2, 34, 34, 34, 34, 18, 19, + 34, 34, 34, 34, 12, 16, 34, 34, 34, 34, + + 34, 17, 0, 0, 0, 41, 45, 0, 0, 47, + 0, 0, 48, 51, 0, 53, 0, 0, 0, 54, + 58, 57, 32, 35, 0, 32, 0, 0, 33, 0, + 32, 0, 33, 30, 23, 14, 34, 6, 34, 34, + 34, 34, 21, 34, 34, 5, 34, 34, 34, 37, + 38, 36, 49, 0, 49, 0, 0, 55, 0, 55, + 0, 0, 32, 35, 35, 35, 0, 32, 33, 0, + 33, 0, 33, 32, 30, 34, 34, 34, 11, 34, + 20, 34, 34, 34, 34, 0, 0, 0, 0, 32, + 35, 32, 32, 30, 34, 8, 34, 7, 10, 34, + + 4, 1, 0, 0, 49, 0, 0, 0, 0, 55, + 0, 0, 32, 32, 32, 30, 34, 9, 34, 3, + 0, 0, 32, 32, 32, 30, 13, 31, 32, 32, + 32, 30, 32, 32, 32, 30, 32, 32, 32, 30, + 32, 32, 32, 30, 32, 32, 32, 30, 32, 32, + 32, 30, 32, 32, 32, 30, 32, 32, 32, 30, + 32, 32, 32, 30, 32, 32, 32, 30, 32, 32, + 33, 30, 33, 33, 33, 33, 33, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -393,167 +401,204 @@ static yyconst flex_int32_t yy_ec[256] = 20, 20, 20, 20, 20, 20, 20, 21, 9, 22, 23, 24, 25, 9, 26, 27, 8, 28, 29, 30, 31, 32, 33, 34, 8, 35, 36, 37, 38, 39, - 8, 40, 41, 42, 43, 44, 45, 8, 8, 8, - 1, 46, 1, 9, 8, 47, 48, 49, 8, 50, + 8, 40, 41, 42, 43, 44, 45, 8, 46, 8, + 1, 47, 1, 9, 8, 48, 49, 50, 8, 51, - 51, 52, 53, 54, 55, 56, 8, 57, 58, 59, - 60, 61, 8, 62, 63, 64, 65, 66, 67, 8, - 8, 8, 1, 68, 1, 9, 1, 69, 1, 1, - 1, 1, 1, 1, 1, 70, 71, 1, 1, 72, + 52, 53, 54, 55, 56, 57, 8, 58, 59, 60, + 61, 62, 8, 63, 64, 65, 66, 67, 68, 8, + 69, 8, 1, 70, 1, 9, 1, 71, 1, 1, + 1, 1, 1, 1, 1, 72, 73, 1, 1, 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 73, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 74, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 75, 1, + 1, 1, 1, 1, 1, 1, 76, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 77, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[76] = +static yyconst flex_int32_t yy_meta[78] = { 0, 1, 1, 2, 2, 1, 3, 1, 4, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 6, 7, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, - 1, 1, 1, 1, 1 + 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, + 1, 1, 1, 1, 1, 1, 1 } ; -static yyconst flex_int16_t yy_base[213] = +static yyconst flex_int16_t yy_base[295] = { 0, - 0, 0, 73, 74, 67, 68, 74, 75, 330, 329, - 375, 517, 80, 87, 351, 517, 0, 0, 517, 363, - 517, 517, 517, 352, 517, 75, 351, 356, 76, 82, - 62, 517, 346, 517, 63, 72, 65, 66, 81, 71, - 71, 77, 75, 73, 87, 91, 86, 517, 300, 297, - 292, 517, 517, 105, 0, 139, 0, 0, 145, 0, - 0, 317, 155, 294, 517, 0, 0, 517, 342, 161, - 341, 148, 116, 517, 124, 151, 159, 340, 339, 334, - 517, 132, 0, 128, 132, 135, 134, 0, 148, 147, - 0, 0, 139, 143, 151, 158, 517, 288, 118, 177, - - 517, 0, 212, 345, 517, 338, 285, 517, 0, 218, - 517, 347, 334, 281, 517, 0, 517, 208, 273, 210, - 211, 212, 219, 318, 311, 517, 0, 173, 0, 190, - 204, 201, 209, 210, 0, 201, 205, 517, 517, 517, - 517, 312, 306, 244, 247, 517, 296, 294, 247, 229, - 194, 250, 253, 220, 268, 255, 250, 197, 184, 229, - 222, 225, 0, 226, 241, 242, 243, 274, 132, 293, - 124, 270, 250, 0, 250, 0, 0, 246, 0, 301, - 304, 316, 322, 86, 307, 326, 331, 337, 66, 277, - 0, 0, 341, 343, 0, 517, 412, 419, 426, 433, - - 440, 94, 447, 454, 461, 468, 475, 481, 488, 495, - 502, 509 + 0, 0, 75, 76, 69, 70, 76, 77, 533, 532, + 579, 696, 82, 89, 555, 696, 0, 0, 696, 566, + 696, 696, 696, 555, 696, 77, 552, 557, 78, 84, + 64, 696, 547, 696, 65, 74, 67, 68, 83, 73, + 73, 79, 75, 82, 77, 98, 94, 107, 696, 499, + 496, 491, 696, 696, 132, 0, 152, 0, 0, 168, + 0, 0, 517, 145, 493, 696, 0, 0, 696, 543, + 174, 542, 161, 132, 696, 137, 162, 177, 541, 540, + 532, 696, 132, 0, 122, 133, 148, 144, 0, 0, + 160, 159, 157, 165, 0, 0, 156, 160, 162, 169, + + 177, 696, 482, 158, 191, 696, 0, 231, 538, 696, + 530, 475, 696, 0, 234, 696, 538, 520, 465, 696, + 0, 696, 511, 243, 457, 223, 200, 234, 219, 238, + 239, 507, 502, 499, 696, 0, 211, 0, 217, 228, + 225, 230, 0, 229, 232, 0, 238, 224, 229, 696, + 696, 696, 696, 497, 492, 270, 424, 696, 485, 482, + 274, 416, 464, 204, 278, 290, 396, 277, 442, 437, + 435, 434, 433, 280, 430, 270, 262, 265, 0, 261, + 0, 276, 279, 279, 282, 310, 375, 314, 372, 422, + 332, 319, 320, 419, 301, 0, 302, 0, 0, 299, + + 301, 0, 340, 355, 359, 364, 366, 370, 375, 379, + 385, 362, 406, 375, 376, 403, 332, 0, 355, 0, + 395, 405, 402, 392, 395, 399, 0, 0, 397, 396, + 400, 382, 381, 412, 416, 380, 377, 420, 440, 367, + 360, 441, 445, 340, 335, 453, 457, 332, 327, 460, + 461, 325, 303, 465, 478, 295, 276, 481, 482, 250, + 199, 486, 496, 192, 178, 500, 503, 148, 133, 506, + 521, 696, 120, 522, 525, 101, 539, 696, 591, 598, + 605, 612, 619, 96, 626, 633, 640, 647, 654, 660, + 667, 674, 681, 688 + } ; -static yyconst flex_int16_t yy_def[213] = +static yyconst flex_int16_t yy_def[295] = { 0, - 196, 1, 197, 197, 198, 198, 199, 199, 200, 200, - 196, 196, 196, 196, 196, 196, 201, 202, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 202, 196, - 196, 196, 196, 196, 202, 202, 202, 202, 202, 202, - 202, 202, 202, 202, 202, 202, 202, 196, 196, 196, - 196, 196, 196, 196, 203, 196, 204, 205, 196, 206, - 207, 196, 196, 196, 196, 201, 202, 196, 196, 196, - 196, 196, 196, 196, 196, 202, 202, 196, 196, 196, - 196, 202, 202, 202, 202, 202, 202, 202, 202, 202, - 202, 202, 202, 202, 202, 202, 196, 196, 196, 196, - - 196, 203, 196, 208, 196, 196, 196, 196, 205, 196, - 196, 209, 196, 196, 196, 207, 196, 210, 196, 196, - 196, 196, 196, 196, 202, 196, 202, 202, 202, 202, - 202, 202, 202, 202, 202, 202, 202, 196, 196, 196, - 196, 208, 208, 196, 196, 196, 209, 209, 196, 196, - 210, 210, 210, 196, 196, 196, 196, 196, 196, 202, - 202, 202, 202, 202, 202, 202, 202, 211, 196, 212, - 196, 210, 202, 202, 202, 202, 202, 202, 202, 211, - 211, 211, 211, 196, 212, 212, 212, 212, 196, 202, - 202, 202, 211, 212, 202, 0, 196, 196, 196, 196, - - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196 + 278, 1, 279, 279, 280, 280, 281, 281, 282, 282, + 278, 278, 278, 278, 278, 278, 283, 284, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 284, 278, + 278, 278, 278, 278, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, 278, 278, + 278, 278, 278, 278, 278, 285, 278, 286, 287, 278, + 288, 289, 278, 278, 278, 278, 283, 284, 278, 278, + 278, 278, 278, 278, 278, 278, 284, 284, 278, 278, + 278, 278, 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + + 284, 278, 278, 278, 278, 278, 285, 278, 290, 278, + 278, 278, 278, 287, 278, 278, 291, 278, 278, 278, + 289, 278, 278, 292, 278, 278, 278, 278, 278, 278, + 284, 278, 284, 278, 278, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, 284, 278, + 278, 278, 278, 290, 290, 278, 278, 278, 291, 291, + 278, 278, 278, 292, 292, 292, 278, 278, 278, 278, + 278, 278, 278, 284, 278, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 293, 278, 294, 278, 278, + 292, 278, 284, 278, 284, 284, 284, 284, 284, 284, + + 284, 284, 293, 293, 293, 293, 278, 294, 294, 294, + 294, 278, 278, 278, 284, 278, 284, 284, 284, 284, + 293, 294, 278, 278, 284, 278, 284, 284, 278, 278, + 284, 278, 278, 278, 284, 278, 278, 278, 284, 278, + 278, 278, 284, 278, 278, 278, 284, 278, 278, 278, + 284, 278, 278, 278, 284, 278, 278, 278, 284, 278, + 278, 278, 284, 278, 278, 278, 284, 278, 278, 278, + 284, 278, 278, 278, 284, 278, 278, 0, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278 + } ; -static yyconst flex_int16_t yy_nxt[593] = +static yyconst flex_int16_t yy_nxt[774] = { 0, 12, 13, 14, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 19, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 18, 18, 37, - 38, 39, 40, 41, 42, 18, 18, 43, 18, 44, - 45, 18, 18, 46, 47, 12, 48, 35, 36, 18, - 18, 37, 38, 39, 40, 41, 42, 18, 18, 43, - 18, 44, 45, 18, 18, 46, 47, 49, 12, 12, - 12, 12, 12, 50, 51, 53, 53, 56, 56, 59, - 59, 63, 63, 63, 80, 65, 54, 54, 63, 63, - 63, 70, 71, 75, 72, 76, 78, 67, 78, 82, - - 84, 79, 85, 83, 77, 86, 87, 88, 89, 90, - 93, 91, 57, 57, 92, 94, 95, 96, 100, 60, - 60, 82, 84, 101, 85, 83, 77, 86, 87, 88, - 89, 90, 93, 91, 170, 73, 92, 94, 95, 96, - 103, 103, 103, 122, 121, 104, 110, 110, 110, 105, - 111, 112, 123, 64, 168, 106, 63, 63, 63, 127, - 64, 113, 118, 118, 118, 75, 121, 72, 75, 128, - 76, 129, 130, 124, 123, 124, 120, 131, 125, 77, - 132, 127, 133, 134, 135, 136, 137, 138, 139, 140, - 100, 128, 189, 129, 130, 101, 196, 196, 120, 131, - - 184, 77, 132, 159, 133, 134, 135, 136, 137, 152, - 118, 118, 107, 103, 103, 103, 159, 160, 114, 110, - 110, 110, 141, 146, 124, 156, 124, 156, 64, 155, - 157, 122, 161, 158, 119, 158, 162, 163, 159, 160, - 123, 164, 165, 166, 167, 168, 168, 168, 170, 170, - 170, 152, 118, 118, 161, 196, 196, 173, 162, 163, - 174, 175, 123, 164, 165, 166, 167, 176, 177, 157, - 178, 179, 196, 196, 157, 181, 168, 168, 190, 173, - 191, 153, 174, 175, 182, 107, 192, 155, 118, 176, - 177, 114, 178, 179, 186, 170, 170, 110, 187, 148, - - 190, 148, 191, 196, 196, 181, 168, 168, 192, 196, - 196, 182, 187, 195, 182, 103, 143, 169, 196, 196, - 171, 172, 143, 153, 196, 196, 182, 186, 170, 170, - 125, 187, 182, 196, 196, 195, 187, 155, 152, 196, - 196, 154, 187, 196, 196, 196, 196, 183, 187, 150, - 149, 182, 148, 145, 144, 143, 63, 126, 79, 79, - 73, 69, 98, 117, 99, 98, 188, 97, 81, 74, - 73, 69, 68, 65, 196, 62, 62, 183, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 193, 196, 196, 196, 196, 196, 196, 196, 196, 188, - - 196, 196, 196, 196, 196, 194, 196, 196, 196, 181, - 196, 186, 52, 52, 52, 52, 52, 52, 52, 55, - 55, 55, 55, 55, 55, 55, 58, 58, 58, 58, - 58, 58, 58, 61, 61, 61, 61, 61, 61, 61, - 66, 196, 66, 66, 66, 66, 66, 102, 102, 102, - 102, 196, 196, 102, 108, 108, 108, 108, 108, 108, - 108, 109, 109, 196, 109, 109, 196, 109, 115, 115, - 115, 115, 115, 115, 115, 116, 116, 116, 116, 116, - 116, 142, 196, 142, 142, 142, 142, 142, 147, 196, - 147, 147, 147, 147, 147, 151, 151, 151, 151, 151, - - 151, 151, 180, 180, 180, 180, 180, 180, 180, 185, - 185, 185, 185, 185, 185, 185, 11, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196 - + 38, 39, 40, 41, 42, 18, 43, 44, 18, 45, + 46, 18, 18, 47, 48, 18, 12, 49, 35, 36, + 18, 18, 37, 38, 39, 40, 41, 42, 18, 43, + 44, 18, 45, 46, 18, 18, 47, 48, 18, 50, + 12, 12, 12, 12, 12, 51, 52, 54, 54, 57, + 57, 60, 60, 64, 64, 64, 81, 66, 55, 55, + 64, 64, 64, 71, 72, 76, 73, 77, 79, 68, + + 79, 83, 85, 80, 86, 84, 78, 87, 88, 89, + 91, 92, 93, 90, 97, 58, 58, 94, 95, 100, + 276, 96, 61, 61, 83, 85, 98, 86, 84, 78, + 87, 88, 89, 91, 92, 93, 90, 97, 101, 276, + 94, 95, 100, 99, 96, 105, 64, 64, 64, 98, + 106, 74, 273, 108, 108, 108, 129, 65, 109, 136, + 128, 101, 110, 137, 65, 130, 99, 272, 111, 115, + 115, 115, 138, 116, 117, 124, 124, 124, 76, 76, + 126, 131, 136, 128, 118, 139, 137, 140, 130, 127, + 78, 132, 141, 132, 142, 138, 133, 269, 143, 144, + + 145, 146, 147, 148, 105, 149, 278, 278, 139, 106, + 140, 268, 127, 78, 132, 141, 132, 142, 265, 169, + 65, 143, 144, 145, 146, 147, 148, 112, 149, 150, + 151, 152, 108, 108, 108, 115, 115, 115, 129, 158, + 76, 153, 168, 119, 165, 124, 124, 130, 170, 125, + 170, 127, 172, 171, 172, 176, 76, 173, 174, 177, + 178, 179, 180, 181, 182, 183, 184, 78, 185, 264, + 130, 186, 186, 186, 127, 188, 188, 188, 176, 165, + 124, 124, 177, 178, 179, 180, 181, 182, 183, 184, + 78, 185, 278, 278, 76, 261, 192, 76, 195, 193, + + 196, 197, 198, 199, 200, 127, 112, 201, 78, 119, + 202, 204, 186, 186, 260, 209, 188, 188, 166, 210, + 205, 195, 257, 196, 197, 198, 199, 200, 127, 217, + 201, 78, 218, 202, 278, 278, 76, 76, 214, 215, + 219, 220, 278, 278, 256, 187, 253, 127, 78, 189, + 205, 252, 217, 166, 249, 218, 204, 186, 186, 248, + 191, 278, 278, 219, 220, 205, 278, 278, 227, 205, + 127, 78, 278, 278, 205, 210, 209, 188, 188, 245, + 210, 278, 278, 228, 210, 206, 244, 278, 278, 211, + 210, 227, 76, 76, 224, 225, 241, 278, 278, 240, + + 237, 236, 165, 127, 78, 205, 228, 278, 278, 76, + 210, 230, 76, 76, 231, 234, 233, 76, 232, 235, + 127, 229, 226, 78, 127, 223, 127, 78, 78, 76, + 206, 238, 188, 76, 221, 239, 186, 76, 216, 242, + 127, 213, 212, 127, 78, 207, 78, 127, 127, 194, + 211, 78, 173, 173, 171, 222, 171, 76, 76, 243, + 246, 169, 76, 127, 247, 204, 124, 78, 78, 127, + 76, 127, 250, 78, 76, 209, 251, 76, 76, 254, + 255, 127, 76, 190, 258, 78, 115, 160, 127, 78, + 160, 78, 127, 127, 108, 76, 78, 259, 76, 76, + + 262, 263, 155, 76, 127, 266, 78, 155, 78, 127, + 78, 127, 78, 76, 127, 267, 127, 76, 175, 270, + 76, 133, 271, 76, 78, 274, 169, 167, 127, 78, + 163, 78, 127, 78, 127, 162, 161, 127, 76, 76, + 275, 277, 76, 160, 275, 157, 156, 78, 155, 78, + 127, 127, 64, 78, 78, 135, 76, 127, 277, 134, + 80, 74, 123, 103, 122, 104, 103, 127, 102, 82, + 75, 74, 78, 127, 70, 69, 78, 66, 278, 63, + 63, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 127, 53, 53, 53, 53, 53, 53, 53, 56, 56, + + 56, 56, 56, 56, 56, 59, 59, 59, 59, 59, + 59, 59, 62, 62, 62, 62, 62, 62, 62, 67, + 278, 67, 67, 67, 67, 67, 107, 107, 107, 107, + 278, 278, 107, 113, 113, 113, 113, 113, 113, 113, + 114, 114, 278, 114, 114, 278, 114, 120, 120, 120, + 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, + 154, 278, 154, 154, 154, 154, 154, 159, 278, 159, + 159, 159, 159, 159, 164, 164, 164, 164, 164, 164, + 164, 203, 203, 203, 203, 203, 203, 203, 208, 208, + 208, 208, 208, 208, 208, 11, 278, 278, 278, 278, + + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278 } ; -static yyconst flex_int16_t yy_chk[593] = +static yyconst flex_int16_t yy_chk[774] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -562,65 +607,84 @@ static yyconst flex_int16_t yy_chk[593] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 3, 4, 5, 6, 7, - 8, 13, 13, 13, 31, 31, 3, 4, 14, 14, - 14, 26, 26, 29, 26, 29, 30, 202, 30, 35, - - 36, 30, 37, 35, 29, 38, 39, 40, 41, 42, - 44, 43, 5, 6, 43, 45, 46, 47, 54, 7, - 8, 35, 36, 54, 37, 35, 29, 38, 39, 40, - 41, 42, 44, 43, 189, 73, 43, 45, 46, 47, - 56, 56, 56, 75, 73, 56, 59, 59, 59, 56, - 59, 59, 75, 13, 184, 56, 63, 63, 63, 82, - 14, 59, 70, 70, 70, 72, 73, 72, 76, 84, - 76, 85, 86, 77, 75, 77, 72, 87, 77, 76, - 89, 82, 90, 93, 94, 95, 96, 99, 99, 99, - 100, 84, 171, 85, 86, 100, 151, 151, 72, 87, - - 169, 76, 89, 159, 90, 93, 94, 95, 96, 118, - 118, 118, 56, 103, 103, 103, 158, 128, 59, 110, - 110, 110, 103, 110, 120, 121, 120, 121, 63, 120, - 121, 122, 130, 123, 70, 123, 131, 132, 123, 128, - 122, 133, 134, 136, 137, 144, 144, 144, 149, 149, - 149, 152, 152, 152, 130, 153, 153, 160, 131, 132, - 161, 162, 122, 133, 134, 136, 137, 164, 165, 157, - 166, 167, 172, 172, 156, 168, 168, 168, 173, 160, - 175, 118, 161, 162, 168, 103, 178, 155, 154, 164, - 165, 110, 166, 167, 170, 170, 170, 150, 170, 148, - - 173, 147, 175, 180, 180, 181, 181, 181, 178, 185, - 185, 180, 185, 190, 181, 145, 143, 144, 182, 182, - 149, 153, 142, 152, 183, 183, 182, 186, 186, 186, - 125, 186, 183, 187, 187, 190, 187, 124, 172, 188, - 188, 119, 188, 193, 193, 194, 194, 168, 194, 114, - 113, 193, 112, 107, 106, 104, 98, 80, 79, 78, - 71, 69, 64, 62, 51, 50, 170, 49, 33, 28, - 27, 24, 20, 15, 11, 10, 9, 181, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 183, 0, 0, 0, 0, 0, 0, 0, 0, 186, - - 0, 0, 0, 0, 0, 188, 0, 0, 0, 193, - 0, 194, 197, 197, 197, 197, 197, 197, 197, 198, - 198, 198, 198, 198, 198, 198, 199, 199, 199, 199, - 199, 199, 199, 200, 200, 200, 200, 200, 200, 200, - 201, 0, 201, 201, 201, 201, 201, 203, 203, 203, - 203, 0, 0, 203, 204, 204, 204, 204, 204, 204, - 204, 205, 205, 0, 205, 205, 0, 205, 206, 206, - 206, 206, 206, 206, 206, 207, 207, 207, 207, 207, - 207, 208, 0, 208, 208, 208, 208, 208, 209, 0, - 209, 209, 209, 209, 209, 210, 210, 210, 210, 210, - - 210, 210, 211, 211, 211, 211, 211, 211, 211, 212, - 212, 212, 212, 212, 212, 212, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196 - + 1, 1, 1, 1, 1, 1, 1, 3, 4, 5, + 6, 7, 8, 13, 13, 13, 31, 31, 3, 4, + 14, 14, 14, 26, 26, 29, 26, 29, 30, 284, + + 30, 35, 36, 30, 37, 35, 29, 38, 39, 40, + 41, 42, 43, 40, 45, 5, 6, 43, 44, 47, + 276, 44, 7, 8, 35, 36, 46, 37, 35, 29, + 38, 39, 40, 41, 42, 43, 40, 45, 48, 273, + 43, 44, 47, 46, 44, 55, 64, 64, 64, 46, + 55, 74, 269, 57, 57, 57, 76, 13, 57, 83, + 74, 48, 57, 85, 14, 76, 46, 268, 57, 60, + 60, 60, 86, 60, 60, 71, 71, 71, 73, 77, + 73, 77, 83, 74, 60, 87, 85, 88, 76, 73, + 77, 78, 91, 78, 92, 86, 78, 265, 93, 94, + + 97, 98, 99, 100, 105, 101, 164, 164, 87, 105, + 88, 264, 73, 77, 127, 91, 127, 92, 261, 127, + 64, 93, 94, 97, 98, 99, 100, 57, 101, 104, + 104, 104, 108, 108, 108, 115, 115, 115, 129, 115, + 126, 108, 126, 60, 124, 124, 124, 129, 128, 71, + 128, 126, 130, 128, 130, 137, 131, 130, 131, 139, + 140, 141, 142, 144, 145, 147, 148, 131, 149, 260, + 129, 156, 156, 156, 126, 161, 161, 161, 137, 165, + 165, 165, 139, 140, 141, 142, 144, 145, 147, 148, + 131, 149, 166, 166, 168, 257, 168, 174, 176, 174, + + 177, 178, 180, 182, 183, 168, 108, 184, 174, 115, + 185, 186, 186, 186, 256, 188, 188, 188, 124, 188, + 186, 176, 253, 177, 178, 180, 182, 183, 168, 195, + 184, 174, 197, 185, 191, 191, 192, 193, 192, 193, + 200, 201, 203, 203, 252, 156, 249, 192, 193, 161, + 203, 248, 195, 165, 245, 197, 204, 204, 204, 244, + 166, 205, 205, 200, 201, 204, 206, 206, 217, 205, + 192, 193, 208, 208, 206, 208, 209, 209, 209, 241, + 209, 210, 210, 219, 210, 186, 240, 211, 211, 188, + 211, 217, 214, 215, 214, 215, 237, 221, 221, 236, + + 233, 232, 191, 214, 215, 221, 219, 222, 222, 224, + 222, 224, 225, 230, 225, 230, 229, 231, 226, 231, + 224, 223, 216, 225, 230, 213, 214, 215, 231, 234, + 204, 234, 212, 235, 206, 235, 207, 238, 194, 238, + 234, 190, 189, 224, 235, 187, 225, 230, 238, 175, + 209, 231, 173, 172, 171, 211, 170, 239, 242, 239, + 242, 169, 243, 234, 243, 221, 167, 235, 239, 242, + 246, 238, 246, 243, 247, 222, 247, 250, 251, 250, + 251, 246, 254, 163, 254, 247, 162, 160, 250, 251, + 159, 239, 242, 254, 157, 255, 243, 255, 258, 259, + + 258, 259, 155, 262, 246, 262, 255, 154, 247, 258, + 259, 250, 251, 263, 262, 263, 254, 266, 134, 266, + 267, 133, 267, 270, 263, 270, 132, 125, 266, 255, + 123, 267, 258, 259, 270, 119, 118, 262, 271, 274, + 271, 274, 275, 117, 275, 112, 111, 263, 109, 271, + 274, 266, 103, 275, 267, 81, 277, 270, 277, 80, + 79, 72, 70, 65, 63, 52, 51, 277, 50, 33, + 28, 27, 271, 274, 24, 20, 275, 15, 11, 10, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 277, 279, 279, 279, 279, 279, 279, 279, 280, 280, + + 280, 280, 280, 280, 280, 281, 281, 281, 281, 281, + 281, 281, 282, 282, 282, 282, 282, 282, 282, 283, + 0, 283, 283, 283, 283, 283, 285, 285, 285, 285, + 0, 0, 285, 286, 286, 286, 286, 286, 286, 286, + 287, 287, 0, 287, 287, 0, 287, 288, 288, 288, + 288, 288, 288, 288, 289, 289, 289, 289, 289, 289, + 290, 0, 290, 290, 290, 290, 290, 291, 0, 291, + 291, 291, 291, 291, 292, 292, 292, 292, 292, 292, + 292, 293, 293, 293, 293, 293, 293, 293, 294, 294, + 294, 294, 294, 294, 294, 278, 278, 278, 278, 278, + + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278 } ; /* The intent behind this definition is that it'll catch @@ -675,11 +739,16 @@ do {\ #define RETURN_ROW_ID() \ { store_expr_str(yytext, yyleng, yytext + yyleng, yyscanner); return ROW_ID; } +#define RETURN_REVERSED_EXPR_FUNC() \ + { store_expr_str(yytext, yyleng, yytext + yyleng, yyscanner); return REVERSED_EXPR_FUNC; } + + /*following character status will be rewrite by gen_parse.sh according to connection character*/ -#line 684 "ob_expr_parser_utf8_lex.c" +/* limit the length of int_num from 1 to 17 in case of int64_t out of bound, 17 -> [ ( length of 2^64 ) - 2 ]*/ +#line 753 "ob_expr_parser_utf8_lex.c" #define INITIAL 0 #define in_c_comment 1 @@ -927,9 +996,9 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 96 "ob_expr_parser_utf8.l" +#line 102 "ob_expr_parser_utf8.l" -#line 935 "ob_expr_parser_utf8_lex.c" +#line 1004 "ob_expr_parser_utf8_lex.c" yylval = yylval_param; @@ -986,13 +1055,13 @@ YY_DECL while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 197 ) + if ( yy_current_state >= 279 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 517 ); + while ( yy_base[yy_current_state] != 696 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -1018,206 +1087,226 @@ YY_DECL case 1: YY_RULE_SETUP -#line 97 "ob_expr_parser_utf8.l" +#line 103 "ob_expr_parser_utf8.l" { return WHERE; } YY_BREAK case 2: YY_RULE_SETUP -#line 98 "ob_expr_parser_utf8.l" +#line 104 "ob_expr_parser_utf8.l" { return AS; } YY_BREAK case 3: YY_RULE_SETUP -#line 99 "ob_expr_parser_utf8.l" +#line 105 "ob_expr_parser_utf8.l" { return VALUES; } YY_BREAK case 4: YY_RULE_SETUP -#line 100 "ob_expr_parser_utf8.l" +#line 106 "ob_expr_parser_utf8.l" { return VALUES; } YY_BREAK case 5: YY_RULE_SETUP -#line 101 "ob_expr_parser_utf8.l" +#line 107 "ob_expr_parser_utf8.l" { return SET; } YY_BREAK case 6: YY_RULE_SETUP -#line 102 "ob_expr_parser_utf8.l" +#line 108 "ob_expr_parser_utf8.l" { return END_WHERE; } YY_BREAK case 7: YY_RULE_SETUP -#line 103 "ob_expr_parser_utf8.l" +#line 109 "ob_expr_parser_utf8.l" { return END_WHERE; } YY_BREAK case 8: YY_RULE_SETUP -#line 104 "ob_expr_parser_utf8.l" +#line 110 "ob_expr_parser_utf8.l" { return END_WHERE; } YY_BREAK case 9: YY_RULE_SETUP -#line 105 "ob_expr_parser_utf8.l" +#line 111 "ob_expr_parser_utf8.l" { return END_WHERE; } YY_BREAK case 10: YY_RULE_SETUP -#line 106 "ob_expr_parser_utf8.l" +#line 112 "ob_expr_parser_utf8.l" { RETURN_ROW_ID(); } YY_BREAK case 11: YY_RULE_SETUP -#line 108 "ob_expr_parser_utf8.l" +#line 114 "ob_expr_parser_utf8.l" { return JOIN; } YY_BREAK case 12: YY_RULE_SETUP -#line 109 "ob_expr_parser_utf8.l" +#line 115 "ob_expr_parser_utf8.l" { return ON; } YY_BREAK case 13: YY_RULE_SETUP -#line 110 "ob_expr_parser_utf8.l" +#line 116 "ob_expr_parser_utf8.l" { return BETWEEN; } YY_BREAK case 14: YY_RULE_SETUP -#line 111 "ob_expr_parser_utf8.l" +#line 117 "ob_expr_parser_utf8.l" { return AND_OP; } YY_BREAK case 15: YY_RULE_SETUP -#line 112 "ob_expr_parser_utf8.l" +#line 118 "ob_expr_parser_utf8.l" { return AND_OP; } YY_BREAK case 16: YY_RULE_SETUP -#line 113 "ob_expr_parser_utf8.l" +#line 119 "ob_expr_parser_utf8.l" { return OR_OP; } YY_BREAK case 17: YY_RULE_SETUP -#line 114 "ob_expr_parser_utf8.l" +#line 120 "ob_expr_parser_utf8.l" { return OR_OP; } YY_BREAK case 18: YY_RULE_SETUP -#line 115 "ob_expr_parser_utf8.l" +#line 121 "ob_expr_parser_utf8.l" { return IN; } YY_BREAK case 19: YY_RULE_SETUP -#line 116 "ob_expr_parser_utf8.l" -{ return COMP_EQ; } +#line 122 "ob_expr_parser_utf8.l" +{ return IS; } YY_BREAK case 20: YY_RULE_SETUP -#line 117 "ob_expr_parser_utf8.l" -{ return COMP_NSEQ; } +#line 123 "ob_expr_parser_utf8.l" +{ return TOKEN_NULL; } YY_BREAK case 21: YY_RULE_SETUP -#line 118 "ob_expr_parser_utf8.l" -{ return COMP_GE; } +#line 124 "ob_expr_parser_utf8.l" +{ return NOT; } YY_BREAK case 22: YY_RULE_SETUP -#line 119 "ob_expr_parser_utf8.l" -{ return COMP_GT; } +#line 125 "ob_expr_parser_utf8.l" +{ return COMP_EQ; } YY_BREAK case 23: YY_RULE_SETUP -#line 120 "ob_expr_parser_utf8.l" -{ return COMP_LE; } +#line 126 "ob_expr_parser_utf8.l" +{ return COMP_NSEQ; } YY_BREAK case 24: YY_RULE_SETUP -#line 121 "ob_expr_parser_utf8.l" -{ return COMP_LT; } +#line 127 "ob_expr_parser_utf8.l" +{ return COMP_GE; } YY_BREAK case 25: YY_RULE_SETUP -#line 122 "ob_expr_parser_utf8.l" -{ return COMP_NE; } +#line 128 "ob_expr_parser_utf8.l" +{ return COMP_GT; } YY_BREAK case 26: YY_RULE_SETUP -#line 123 "ob_expr_parser_utf8.l" -{ return PLACE_HOLDER; } +#line 129 "ob_expr_parser_utf8.l" +{ return COMP_LE; } YY_BREAK case 27: YY_RULE_SETUP -#line 124 "ob_expr_parser_utf8.l" -{ store_pos_place_holder(yytext + 1, yyscanner); return POS_PLACE_HOLDER; } +#line 130 "ob_expr_parser_utf8.l" +{ return COMP_LT; } YY_BREAK case 28: YY_RULE_SETUP -#line 126 "ob_expr_parser_utf8.l" -{ RETURN_INT_VAL(); } +#line 131 "ob_expr_parser_utf8.l" +{ return COMP_NE; } YY_BREAK case 29: YY_RULE_SETUP -#line 127 "ob_expr_parser_utf8.l" -{ RETURN_NUMBER_VAL(); } +#line 132 "ob_expr_parser_utf8.l" +{ return PLACE_HOLDER; } YY_BREAK case 30: YY_RULE_SETUP -#line 128 "ob_expr_parser_utf8.l" -{ RETURN_NAME_OB(); } +#line 133 "ob_expr_parser_utf8.l" +{ store_pos_place_holder(yytext + 1, yyscanner); return POS_PLACE_HOLDER; } YY_BREAK case 31: -/* rule 31 can match eol */ YY_RULE_SETUP -#line 129 "ob_expr_parser_utf8.l" -{ } +#line 134 "ob_expr_parser_utf8.l" +{ RETURN_REVERSED_EXPR_FUNC();} YY_BREAK case 32: YY_RULE_SETUP -#line 130 "ob_expr_parser_utf8.l" -{ return ','; } +#line 136 "ob_expr_parser_utf8.l" +{ RETURN_INT_VAL(); } YY_BREAK case 33: YY_RULE_SETUP -#line 131 "ob_expr_parser_utf8.l" -{ return '('; } +#line 137 "ob_expr_parser_utf8.l" +{ RETURN_NUMBER_VAL(); } YY_BREAK case 34: YY_RULE_SETUP -#line 132 "ob_expr_parser_utf8.l" -{ return ')'; } +#line 138 "ob_expr_parser_utf8.l" +{ RETURN_NAME_OB(); } YY_BREAK case 35: +/* rule 35 can match eol */ YY_RULE_SETUP -#line 133 "ob_expr_parser_utf8.l" +#line 139 "ob_expr_parser_utf8.l" +{ } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 140 "ob_expr_parser_utf8.l" +{ return ','; } + YY_BREAK +case 37: +YY_RULE_SETUP +#line 141 "ob_expr_parser_utf8.l" +{ return '('; } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 142 "ob_expr_parser_utf8.l" +{ return ')'; } + YY_BREAK +case 39: +YY_RULE_SETUP +#line 143 "ob_expr_parser_utf8.l" { return yytext[0]; } YY_BREAK /* comment */ -case 36: +case 40: YY_RULE_SETUP -#line 136 "ob_expr_parser_utf8.l" +#line 146 "ob_expr_parser_utf8.l" { PUSH_STATE(in_c_comment); } YY_BREAK -case 37: +case 41: YY_RULE_SETUP -#line 137 "ob_expr_parser_utf8.l" +#line 147 "ob_expr_parser_utf8.l" { POP_STATE(); } YY_BREAK -case 38: -/* rule 38 can match eol */ +case 42: +/* rule 42 can match eol */ YY_RULE_SETUP -#line 138 "ob_expr_parser_utf8.l" +#line 148 "ob_expr_parser_utf8.l" {} YY_BREAK -case 39: +case 43: YY_RULE_SETUP -#line 139 "ob_expr_parser_utf8.l" +#line 149 "ob_expr_parser_utf8.l" {} YY_BREAK /* quote */ -case 40: +case 44: YY_RULE_SETUP -#line 142 "ob_expr_parser_utf8.l" +#line 152 "ob_expr_parser_utf8.l" { PUSH_STATE(sq); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1228,10 +1317,10 @@ YY_RULE_SETUP } } YY_BREAK -case 41: -/* rule 41 can match eol */ +case 45: +/* rule 45 can match eol */ YY_RULE_SETUP -#line 152 "ob_expr_parser_utf8.l" +#line 162 "ob_expr_parser_utf8.l" { ObExprParseResult *p = (ObExprParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -1239,9 +1328,9 @@ YY_RULE_SETUP } } YY_BREAK -case 42: +case 46: YY_RULE_SETUP -#line 159 "ob_expr_parser_utf8.l" +#line 169 "ob_expr_parser_utf8.l" { POP_STATE(); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1251,15 +1340,15 @@ YY_RULE_SETUP return STR_VAL; } YY_BREAK -case 43: +case 47: YY_RULE_SETUP -#line 168 "ob_expr_parser_utf8.l" +#line 178 "ob_expr_parser_utf8.l" {} YY_BREAK -case 44: -/* rule 44 can match eol */ +case 48: +/* rule 48 can match eol */ YY_RULE_SETUP -#line 169 "ob_expr_parser_utf8.l" +#line 179 "ob_expr_parser_utf8.l" { ObExprParseResult *p = (ObExprParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -1267,20 +1356,20 @@ YY_RULE_SETUP } } YY_BREAK -case 45: -/* rule 45 can match eol */ +case 49: +/* rule 49 can match eol */ YY_RULE_SETUP -#line 175 "ob_expr_parser_utf8.l" +#line 185 "ob_expr_parser_utf8.l" {} YY_BREAK case YY_STATE_EOF(sq): -#line 176 "ob_expr_parser_utf8.l" +#line 186 "ob_expr_parser_utf8.l" { return ERROR; } YY_BREAK /* dquote */ -case 46: +case 50: YY_RULE_SETUP -#line 180 "ob_expr_parser_utf8.l" +#line 190 "ob_expr_parser_utf8.l" { PUSH_STATE(dq); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1291,10 +1380,10 @@ YY_RULE_SETUP } } YY_BREAK -case 47: -/* rule 47 can match eol */ +case 51: +/* rule 51 can match eol */ YY_RULE_SETUP -#line 190 "ob_expr_parser_utf8.l" +#line 200 "ob_expr_parser_utf8.l" { ObExprParseResult *p = (ObExprParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -1302,9 +1391,9 @@ YY_RULE_SETUP } } YY_BREAK -case 48: +case 52: YY_RULE_SETUP -#line 197 "ob_expr_parser_utf8.l" +#line 207 "ob_expr_parser_utf8.l" { POP_STATE(); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1317,31 +1406,31 @@ YY_RULE_SETUP return STR_VAL; } YY_BREAK -case 49: +case 53: YY_RULE_SETUP -#line 209 "ob_expr_parser_utf8.l" +#line 219 "ob_expr_parser_utf8.l" {} YY_BREAK -case 50: -/* rule 50 can match eol */ +case 54: +/* rule 54 can match eol */ YY_RULE_SETUP -#line 210 "ob_expr_parser_utf8.l" +#line 220 "ob_expr_parser_utf8.l" {} YY_BREAK -case 51: -/* rule 51 can match eol */ +case 55: +/* rule 55 can match eol */ YY_RULE_SETUP -#line 211 "ob_expr_parser_utf8.l" +#line 221 "ob_expr_parser_utf8.l" {} YY_BREAK case YY_STATE_EOF(dq): -#line 212 "ob_expr_parser_utf8.l" +#line 222 "ob_expr_parser_utf8.l" { return ERROR; } YY_BREAK /* backtick */ -case 52: +case 56: YY_RULE_SETUP -#line 216 "ob_expr_parser_utf8.l" +#line 226 "ob_expr_parser_utf8.l" { PUSH_STATE(bt); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1352,9 +1441,9 @@ YY_RULE_SETUP } } YY_BREAK -case 53: +case 57: YY_RULE_SETUP -#line 226 "ob_expr_parser_utf8.l" +#line 236 "ob_expr_parser_utf8.l" { ObExprParseResult *p = (ObExprParseResult *)yyextra; if (NULL != p && NULL != p->tmp_buf_ && p->tmp_len_ + 1 < OBPROXY_MAX_NAME_LENGTH) { @@ -1362,10 +1451,10 @@ YY_RULE_SETUP } } YY_BREAK -case 54: -/* rule 54 can match eol */ +case 58: +/* rule 58 can match eol */ YY_RULE_SETUP -#line 233 "ob_expr_parser_utf8.l" +#line 243 "ob_expr_parser_utf8.l" { ObExprParseResult *p = (ObExprParseResult *)yyextra; if (NULL != p && NULL != p->tmp_buf_ && p->tmp_len_ + yyleng < OBPROXY_MAX_NAME_LENGTH) { @@ -1374,9 +1463,9 @@ YY_RULE_SETUP } } YY_BREAK -case 55: +case 59: YY_RULE_SETUP -#line 241 "ob_expr_parser_utf8.l" +#line 251 "ob_expr_parser_utf8.l" { POP_STATE(); ObExprParseResult *p = (ObExprParseResult *)yyextra; @@ -1389,27 +1478,27 @@ YY_RULE_SETUP } YY_BREAK case YY_STATE_EOF(bt): -#line 252 "ob_expr_parser_utf8.l" +#line 262 "ob_expr_parser_utf8.l" { return ERROR; } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(in_c_comment): -#line 256 "ob_expr_parser_utf8.l" +#line 266 "ob_expr_parser_utf8.l" { return END_P; } YY_BREAK -case 56: +case 60: YY_RULE_SETUP -#line 257 "ob_expr_parser_utf8.l" +#line 267 "ob_expr_parser_utf8.l" { return IGNORED_WORD; } YY_BREAK -case 57: +case 61: YY_RULE_SETUP -#line 258 "ob_expr_parser_utf8.l" +#line 268 "ob_expr_parser_utf8.l" ECHO; YY_BREAK -#line 1415 "ob_expr_parser_utf8_lex.c" +#line 1504 "ob_expr_parser_utf8_lex.c" case YY_END_OF_BUFFER: { @@ -1701,7 +1790,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 197 ) + if ( yy_current_state >= 279 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1730,11 +1819,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 197 ) + if ( yy_current_state >= 279 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 196); + yy_is_jam = (yy_current_state == 278); return yy_is_jam ? 0 : yy_current_state; } @@ -2559,7 +2648,7 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 258 "ob_expr_parser_utf8.l" +#line 268 "ob_expr_parser_utf8.l" @@ -2690,22 +2779,26 @@ extern int ob_expr_parser_utf8_yydebug; IN = 268, ON = 269, BETWEEN = 270, - COMP_EQ = 271, - COMP_NSEQ = 272, - COMP_GE = 273, - COMP_GT = 274, - COMP_LE = 275, - COMP_LT = 276, - COMP_NE = 277, - PLACE_HOLDER = 278, - END_P = 279, - ERROR = 280, - IGNORED_WORD = 281, - NAME_OB = 282, - STR_VAL = 283, - ROW_ID = 284, - INT_VAL = 285, - POS_PLACE_HOLDER = 286 + IS = 271, + TOKEN_NULL = 272, + NOT = 273, + COMP_EQ = 274, + COMP_NSEQ = 275, + COMP_GE = 276, + COMP_GT = 277, + COMP_LE = 278, + COMP_LT = 279, + COMP_NE = 280, + PLACE_HOLDER = 281, + END_P = 282, + ERROR = 283, + IGNORED_WORD = 284, + NAME_OB = 285, + STR_VAL = 286, + ROW_ID = 287, + REVERSED_EXPR_FUNC = 288, + INT_VAL = 289, + POS_PLACE_HOLDER = 290 }; #endif diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_lex.h b/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_lex.h index 4d9bbc925..330e2a731 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_lex.h +++ b/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_lex.h @@ -341,7 +341,7 @@ extern int ob_expr_parser_utf8_yylex \ #undef YY_DECL #endif -#line 258 "ob_expr_parser_utf8.l" +#line 268 "ob_expr_parser_utf8.l" #line 348 "ob_expr_parser_utf8_lex.h" diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_tab.c b/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_tab.c index 2bcad007d..437bec45c 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_tab.c +++ b/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_tab.c @@ -139,22 +139,26 @@ extern int ob_expr_parser_utf8_yydebug; IN = 268, ON = 269, BETWEEN = 270, - COMP_EQ = 271, - COMP_NSEQ = 272, - COMP_GE = 273, - COMP_GT = 274, - COMP_LE = 275, - COMP_LT = 276, - COMP_NE = 277, - PLACE_HOLDER = 278, - END_P = 279, - ERROR = 280, - IGNORED_WORD = 281, - NAME_OB = 282, - STR_VAL = 283, - ROW_ID = 284, - INT_VAL = 285, - POS_PLACE_HOLDER = 286 + IS = 271, + TOKEN_NULL = 272, + NOT = 273, + COMP_EQ = 274, + COMP_NSEQ = 275, + COMP_GE = 276, + COMP_GT = 277, + COMP_LE = 278, + COMP_LT = 279, + COMP_NE = 280, + PLACE_HOLDER = 281, + END_P = 282, + ERROR = 283, + IGNORED_WORD = 284, + NAME_OB = 285, + STR_VAL = 286, + ROW_ID = 287, + REVERSED_EXPR_FUNC = 288, + INT_VAL = 289, + POS_PLACE_HOLDER = 290 }; #endif @@ -232,8 +236,8 @@ static inline void add_token_list(ObProxyTokenList *list, ObProxyTokenList *next if (OB_ISNULL(list) || OB_ISNULL(next_list)) { } else if (NULL != list->tail_ && NULL != next_list->head_ - && (TOKEN_INT_VAL == list->tail_->type_ || TOKEN_STR_VAL == list->tail_->type_) - && (TOKEN_INT_VAL == next_list->head_->type_ || TOKEN_STR_VAL == next_list->head_->type_)) { + && (TOKEN_INT_VAL == list->tail_->type_ || TOKEN_STR_VAL == list->tail_->type_ || TOKEN_FUNC == list->tail_->type_) + && (TOKEN_INT_VAL == next_list->head_->type_ || TOKEN_STR_VAL == next_list->head_->type_ || TOKEN_FUNC == next_list->head_->type_)) { list->tail_->next_ = next_list->head_; list->tail_ = next_list->head_; list->tail_->next_ = NULL; @@ -305,11 +309,18 @@ static inline void set_part_key_column_idx(ObExprParseResult *result, ObProxyPar for (i = 0; i < result->part_key_info_.key_num_; ++i) { if (is_equal(column_name, &result->part_key_info_.part_keys_[i].name_)) { result->part_key_info_.part_keys_[i].idx_ = result->column_idx_; - break; + result->part_key_info_.part_keys_[i].is_exist_in_sql_ = true; } } } +static inline void init_part_key_all_match(ObExprParseResult *result) +{ + for (int64_t i = 0; i < result->part_key_info_.key_num_; ++i) { + result->part_key_info_.part_keys_[i].is_exist_in_sql_ = true; + } +} + #define malloc_node(node, result, type) \ do { \ if (OB_ISNULL(node = ((ObProxyTokenNode *)obproxy_parse_malloc(sizeof(ObProxyTokenNode), \ @@ -344,21 +355,13 @@ static inline void set_part_key_column_idx(ObExprParseResult *result, ObProxyPar do { \ if (NULL == relation) { \ } else { \ - int64_t new_mask = get_mask(relation->type_, relation->level_); \ - bool has_rowid = result->has_rowid_; \ - if (((result->cur_mask_ | new_mask) != result->cur_mask_) \ - || (has_rowid \ - && is_equal_to_rowid(&relation->left_value_->column_node_->column_name_))) { \ + if (relation->level_ != PART_KEY_LEVEL_ZERO) { \ if (result->relation_info_.relation_num_ < OBPROXY_MAX_RELATION_NUM) { \ result->relation_info_.relations_[result->relation_info_.relation_num_++] = relation; \ - result->cur_mask_ = (result->cur_mask_ | new_mask); \ } else { \ /* YYACCEPT; */ \ } \ } \ - if ((result->cur_mask_ & result->target_mask_) == result->target_mask_) { \ - /* YYACCEPT; */ \ - } \ } \ } while(0) \ @@ -428,6 +431,92 @@ static inline void add_relation(ObExprParseResult *result, } } +static inline void set_relation_part_with_column_idx(int64_t idx_in_schema_columns, + ObExprParseResult *result, + ObProxyPartKeyLevel *level, + int64_t *first_part_column_idx, + int64_t *second_part_column_idx) +{ + if (OB_ISNULL(level) && OB_ISNULL(first_part_column_idx) && + OB_ISNULL(second_part_column_idx) && OB_ISNULL(result)) { + // do nothing + } else { + *level = PART_KEY_LEVEL_ZERO; + *first_part_column_idx = 0; + *second_part_column_idx = 0; + bool is_level_one = false; + bool is_level_two = false; + for (int i = 0; i < result->part_key_info_.key_num_; i++) { + // make sure the part_key exist in sql to avoid the uninitialized idx_ + if (idx_in_schema_columns == result->part_key_info_.part_keys_[i].idx_ && result->part_key_info_.part_keys_[i].is_exist_in_sql_) { + if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_ONE) { + is_level_one = true; + *first_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } else if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_TWO) { + is_level_two = true; + *second_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } + } + } + if (is_level_one) { + *level = PART_KEY_LEVEL_ONE; + } + if (is_level_two) { + *level = PART_KEY_LEVEL_TWO; + } + if (is_level_one && is_level_two) { + *level = PART_KEY_LEVEL_BOTH; + } + } +} + +static inline void set_relation_part_with_column_name(ObProxyParseString *column, + ObExprParseResult *result, + ObProxyPartKeyLevel *level, + int64_t *first_part_column_idx, + int64_t *second_part_column_idx) +{ + if (OB_ISNULL(column) + || OB_ISNULL(result) + || OB_ISNULL(level) + || OB_ISNULL(first_part_column_idx) + || OB_ISNULL(second_part_column_idx)) { + // do nothing + } else if (result->has_rowid_ + && is_equal_to_rowid(column)) { + // handle rowid + *level = PART_KEY_LEVEL_ONE; + *first_part_column_idx = 0; + *second_part_column_idx = 0; + } else { + *level = PART_KEY_LEVEL_ZERO; + *first_part_column_idx = 0; + *second_part_column_idx = 0; + bool is_level_one = false; + bool is_level_two = false; + for (int i = 0; i < result->part_key_info_.key_num_; i++) { + if (is_equal(&result->part_key_info_.part_keys_[i].name_, column)) { + if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_ONE) { + is_level_one = true; + *first_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } else if (result->part_key_info_.part_keys_[i].level_ == PART_KEY_LEVEL_TWO) { + is_level_two = true; + *second_part_column_idx = result->part_key_info_.part_keys_[i].idx_in_part_columns_; + } + } + } + if (is_level_one) { + *level = PART_KEY_LEVEL_ONE; + } + if (is_level_two) { + *level = PART_KEY_LEVEL_TWO; + } + if (is_level_one && is_level_two) { + *level = PART_KEY_LEVEL_BOTH; + } + } +} + static inline ObProxyRelationExpr *get_relation(ObExprParseResult *result, ObProxyTokenList *left_value, @@ -438,25 +527,25 @@ static inline ObProxyRelationExpr *get_relation(ObExprParseResult *result, ObProxyTokenList *tmp_left = NULL; ObProxyTokenList *tmp_right = NULL; ObProxyFunctionType tmp_type = F_NONE; - ObProxyPartKeyLevel tmp_level = PART_KEY_LEVEL_ZERO; int64_t tmp_column_idx_ = -1; + ObProxyParseString *tmp_column = NULL; if (NULL != left_value->column_node_ && TOKEN_COLUMN == left_value->column_node_->type_ && left_value->column_node_->part_key_idx_ >= 0) { tmp_left = left_value; - tmp_level = result->part_key_info_.part_keys_[left_value->column_node_->part_key_idx_].level_; tmp_right = right_value; tmp_type = type; tmp_column_idx_ = left_value->column_node_->part_key_idx_; + tmp_column = &left_value->column_node_->column_name_; } else if (NULL != right_value->column_node_ && TOKEN_COLUMN == right_value->column_node_->type_ && right_value->column_node_->part_key_idx_ >= 0) { tmp_left = right_value; - tmp_level = result->part_key_info_.part_keys_[right_value->column_node_->part_key_idx_].level_; tmp_right = left_value; tmp_type = get_reverse_func(type); tmp_column_idx_ = right_value->column_node_->part_key_idx_; + tmp_column = &right_value->column_node_->column_name_; } if (NULL == tmp_left || NULL == tmp_right || F_COMP_NE == tmp_type) { @@ -469,7 +558,11 @@ static inline ObProxyRelationExpr *get_relation(ObExprParseResult *result, relation->left_value_ = tmp_left; relation->type_ = tmp_type; relation->right_value_ = tmp_right; - relation->level_ = tmp_level; + set_relation_part_with_column_name(tmp_column, + result, + &relation->level_, + &relation->first_part_column_idx_, + &relation->second_part_column_idx_); } return relation; } @@ -483,14 +576,20 @@ static inline ObProxyRelationExpr *get_values_relation(ObExprParseResult *result } else { int64_t i = 0; for (i = 0; i < result->part_key_info_.key_num_; ++i) { - if (result->values_list_idx_ == result->part_key_info_.part_keys_[i].idx_) { + // make sure the part_key exist in sql to avoid the uninitialized idx_ + if (result->values_list_idx_ == result->part_key_info_.part_keys_[i].idx_ && result->part_key_info_.part_keys_[i].is_exist_in_sql_) { if (OB_ISNULL(relation = ((ObProxyRelationExpr *)obproxy_parse_malloc( sizeof(ObProxyRelationExpr), result->malloc_pool_)))) { } else { relation->column_idx_ = i; relation->type_ = F_COMP_EQ; relation->right_value_ = right_value; - relation->level_ = result->part_key_info_.part_keys_[i].level_; + relation->left_value_ = NULL; + set_relation_part_with_column_idx(result->values_list_idx_, + result, + &relation->level_, + &relation->first_part_column_idx_, + &relation->second_part_column_idx_); } break; } @@ -752,20 +851,20 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 17 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 231 +#define YYLAST 242 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 44 +#define YYNTOKENS 48 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 24 /* YYNRULES -- Number of rules. */ -#define YYNRULES 80 +#define YYNRULES 83 /* YYNRULES -- Number of states. */ -#define YYNSTATES 144 +#define YYNSTATES 149 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 286 +#define YYMAXUTOK 290 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -776,9 +875,9 @@ static const yytype_uint8 yytranslate[] = 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 43, 2, 2, 2, 41, 42, 2, - 35, 32, 39, 37, 36, 38, 34, 40, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, + 2, 2, 2, 47, 2, 2, 2, 45, 46, 2, + 39, 36, 43, 41, 40, 42, 38, 44, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 37, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -801,7 +900,8 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31 + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35 }; #if YYDEBUG @@ -812,57 +912,58 @@ static const yytype_uint16 yyprhs[] = 0, 0, 3, 6, 9, 13, 16, 21, 23, 25, 27, 29, 31, 33, 36, 40, 43, 48, 52, 57, 63, 70, 72, 76, 82, 86, 92, 96, 102, 108, - 114, 120, 122, 124, 126, 128, 130, 132, 134, 136, - 140, 142, 144, 147, 148, 152, 156, 158, 160, 164, - 170, 175, 180, 182, 184, 186, 188, 190, 192, 194, - 196, 198, 200, 202, 204, 209, 214, 218, 220, 224, - 230, 231, 235, 237, 241, 243, 245, 249, 251, 255, - 256 + 114, 120, 124, 129, 131, 133, 135, 137, 139, 141, + 143, 145, 149, 151, 153, 156, 157, 161, 165, 167, + 169, 173, 179, 181, 186, 191, 193, 195, 197, 199, + 201, 203, 205, 207, 209, 211, 213, 215, 220, 225, + 229, 231, 235, 241, 242, 246, 248, 252, 254, 256, + 260, 262, 266, 267 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 45, 0, -1, 3, 46, -1, 4, 60, -1, 5, - 51, 47, -1, 48, 47, -1, 48, 5, 51, 47, - -1, 1, -1, 9, -1, 32, -1, 33, -1, 24, - -1, 49, -1, 48, 49, -1, 50, 14, 51, -1, - 10, 27, -1, 10, 27, 34, 27, -1, 10, 27, - 27, -1, 10, 27, 6, 27, -1, 10, 27, 34, - 27, 27, -1, 10, 27, 34, 27, 6, 27, -1, - 52, -1, 51, 11, 52, -1, 35, 51, 11, 52, - 32, -1, 51, 12, 52, -1, 35, 51, 12, 52, - 32, -1, 55, 53, 55, -1, 55, 53, 35, 55, - 32, -1, 35, 55, 53, 55, 32, -1, 55, 13, - 35, 54, 32, -1, 55, 15, 55, 11, 55, -1, - 16, -1, 17, -1, 18, -1, 19, -1, 20, -1, - 21, -1, 22, -1, 55, -1, 54, 36, 55, -1, - 56, -1, 58, -1, 56, 58, -1, -1, 56, 36, - 56, -1, 57, 36, 56, -1, 29, -1, 27, -1, - 27, 34, 27, -1, 27, 34, 27, 34, 27, -1, - 27, 35, 56, 32, -1, 27, 35, 57, 32, -1, - 30, -1, 28, -1, 59, -1, 23, -1, 31, -1, - 37, -1, 38, -1, 39, -1, 40, -1, 41, -1, - 42, -1, 43, -1, 62, 7, 61, 47, -1, 8, - 66, 67, 47, -1, 14, 51, 47, -1, 46, -1, - 35, 65, 32, -1, 61, 36, 35, 65, 32, -1, - -1, 35, 63, 32, -1, 64, -1, 63, 36, 64, - -1, 27, -1, 55, -1, 65, 36, 55, -1, 52, - -1, 66, 36, 52, -1, -1, 5, 51, -1 + 49, 0, -1, 3, 50, -1, 4, 64, -1, 5, + 55, 51, -1, 52, 51, -1, 52, 5, 55, 51, + -1, 1, -1, 9, -1, 36, -1, 37, -1, 27, + -1, 53, -1, 52, 53, -1, 54, 14, 55, -1, + 10, 30, -1, 10, 30, 38, 30, -1, 10, 30, + 30, -1, 10, 30, 6, 30, -1, 10, 30, 38, + 30, 30, -1, 10, 30, 38, 30, 6, 30, -1, + 56, -1, 55, 11, 56, -1, 39, 55, 11, 56, + 36, -1, 55, 12, 56, -1, 39, 55, 12, 56, + 36, -1, 59, 57, 59, -1, 59, 57, 39, 59, + 36, -1, 39, 59, 57, 59, 36, -1, 59, 13, + 39, 58, 36, -1, 59, 15, 59, 11, 59, -1, + 59, 16, 17, -1, 59, 16, 18, 17, -1, 19, + -1, 20, -1, 21, -1, 22, -1, 23, -1, 24, + -1, 25, -1, 59, -1, 58, 40, 59, -1, 60, + -1, 62, -1, 60, 62, -1, -1, 60, 40, 60, + -1, 61, 40, 60, -1, 32, -1, 30, -1, 30, + 38, 30, -1, 30, 38, 30, 38, 30, -1, 33, + -1, 30, 39, 60, 36, -1, 30, 39, 61, 36, + -1, 34, -1, 31, -1, 63, -1, 26, -1, 35, + -1, 41, -1, 42, -1, 43, -1, 44, -1, 45, + -1, 46, -1, 47, -1, 66, 7, 65, 51, -1, + 8, 70, 71, 51, -1, 14, 55, 51, -1, 50, + -1, 39, 69, 36, -1, 65, 40, 39, 69, 36, + -1, -1, 39, 67, 36, -1, 68, -1, 67, 40, + 68, -1, 30, -1, 59, -1, 69, 40, 59, -1, + 56, -1, 70, 40, 56, -1, -1, 5, 55, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 380, 380, 381, 383, 384, 385, 386, 388, 389, - 390, 391, 393, 394, 396, 398, 399, 400, 401, 402, - 403, 405, 406, 407, 408, 409, 411, 412, 413, 414, - 415, 426, 427, 428, 429, 430, 431, 432, 434, 435, - 437, 439, 440, 442, 443, 444, 447, 454, 460, 466, - 472, 478, 484, 485, 486, 487, 493, 499, 500, 501, - 502, 503, 504, 505, 507, 508, 509, 510, 512, 516, - 521, 522, 527, 531, 536, 542, 552, 562, 563, 565, - 566 + 0, 475, 475, 476, 478, 479, 480, 481, 483, 484, + 485, 486, 488, 489, 491, 493, 494, 495, 496, 497, + 498, 500, 501, 502, 503, 504, 506, 507, 508, 509, + 510, 520, 521, 523, 524, 525, 526, 527, 528, 529, + 531, 532, 534, 536, 537, 539, 540, 541, 544, 551, + 557, 563, 569, 574, 580, 586, 587, 588, 589, 595, + 601, 602, 603, 604, 605, 606, 607, 609, 610, 611, + 612, 614, 618, 623, 624, 629, 633, 638, 644, 654, + 664, 665, 667, 668 }; #endif @@ -873,13 +974,14 @@ static const char *const yytname[] = { "$end", "error", "$undefined", "DUMMY_SELECT_CLAUSE", "DUMMY_INSERT_CLAUSE", "WHERE", "AS", "VALUES", "SET", "END_WHERE", - "JOIN", "AND_OP", "OR_OP", "IN", "ON", "BETWEEN", "COMP_EQ", "COMP_NSEQ", - "COMP_GE", "COMP_GT", "COMP_LE", "COMP_LT", "COMP_NE", "PLACE_HOLDER", - "END_P", "ERROR", "IGNORED_WORD", "NAME_OB", "STR_VAL", "ROW_ID", - "INT_VAL", "POS_PLACE_HOLDER", "')'", "';'", "'.'", "'('", "','", "'+'", - "'-'", "'*'", "'/'", "'%'", "'&'", "'!'", "$accept", "start", - "select_root", "end_flag", "join_expr_list", "join_on_expr", "join_expr", - "cond_expr", "bool_pri", "comp", "in_expr_list", "expr", "token_list", + "JOIN", "AND_OP", "OR_OP", "IN", "ON", "BETWEEN", "IS", "TOKEN_NULL", + "NOT", "COMP_EQ", "COMP_NSEQ", "COMP_GE", "COMP_GT", "COMP_LE", + "COMP_LT", "COMP_NE", "PLACE_HOLDER", "END_P", "ERROR", "IGNORED_WORD", + "NAME_OB", "STR_VAL", "ROW_ID", "REVERSED_EXPR_FUNC", "INT_VAL", + "POS_PLACE_HOLDER", "')'", "';'", "'.'", "'('", "','", "'+'", "'-'", + "'*'", "'/'", "'%'", "'&'", "'!'", "$accept", "start", "select_root", + "end_flag", "join_expr_list", "join_on_expr", "join_expr", "cond_expr", + "bool_pri", "comp", "in_expr_list", "expr", "token_list", "func_param_list", "token", "operator", "insert_root", "values_expr_lists", "opt_column_list", "column_list", "opt_column", "values_expr_list", "set_expr", "opt_where_clause", 0 @@ -894,23 +996,23 @@ static const yytype_uint16 yytoknum[] = 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 41, 59, 46, 40, 44, 43, 45, 42, - 47, 37, 38, 33 + 285, 286, 287, 288, 289, 290, 41, 59, 46, 40, + 44, 43, 45, 42, 47, 37, 38, 33 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 44, 45, 45, 46, 46, 46, 46, 47, 47, - 47, 47, 48, 48, 49, 50, 50, 50, 50, 50, - 50, 51, 51, 51, 51, 51, 52, 52, 52, 52, - 52, 53, 53, 53, 53, 53, 53, 53, 54, 54, - 55, 56, 56, 57, 57, 57, 58, 58, 58, 58, - 58, 58, 58, 58, 58, 58, 58, 59, 59, 59, - 59, 59, 59, 59, 60, 60, 60, 60, 61, 61, - 62, 62, 63, 63, 64, 65, 65, 66, 66, 67, - 67 + 0, 48, 49, 49, 50, 50, 50, 50, 51, 51, + 51, 51, 52, 52, 53, 54, 54, 54, 54, 54, + 54, 55, 55, 55, 55, 55, 56, 56, 56, 56, + 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, + 58, 58, 59, 60, 60, 61, 61, 61, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 63, 63, 63, 63, 63, 63, 63, 64, 64, 64, + 64, 65, 65, 66, 66, 67, 67, 68, 69, 69, + 70, 70, 71, 71 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -919,12 +1021,12 @@ static const yytype_uint8 yyr2[] = 0, 2, 2, 2, 3, 2, 4, 1, 1, 1, 1, 1, 1, 2, 3, 2, 4, 3, 4, 5, 6, 1, 3, 5, 3, 5, 3, 5, 5, 5, - 5, 1, 1, 1, 1, 1, 1, 1, 1, 3, - 1, 1, 2, 0, 3, 3, 1, 1, 3, 5, - 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 4, 4, 3, 1, 3, 5, - 0, 3, 1, 3, 1, 1, 3, 1, 3, 0, - 2 + 5, 3, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 1, 1, 2, 0, 3, 3, 1, 1, + 3, 5, 1, 4, 4, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 4, 4, 3, + 1, 3, 5, 0, 3, 1, 3, 1, 1, 3, + 1, 3, 0, 2 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -933,140 +1035,142 @@ static const yytype_uint8 yyr2[] = static const yytype_uint8 yydefact[] = { 0, 0, 0, 0, 7, 0, 0, 2, 0, 12, - 0, 0, 0, 0, 67, 3, 0, 1, 55, 47, - 53, 46, 52, 56, 0, 57, 58, 59, 60, 61, - 62, 63, 0, 21, 0, 40, 41, 54, 15, 0, - 8, 11, 9, 10, 5, 13, 0, 0, 77, 79, - 0, 74, 0, 72, 0, 0, 43, 0, 0, 0, - 0, 4, 0, 0, 31, 32, 33, 34, 35, 36, - 37, 0, 42, 0, 17, 0, 0, 14, 0, 0, - 0, 0, 66, 71, 0, 0, 0, 48, 0, 0, - 0, 0, 0, 22, 24, 0, 0, 0, 26, 18, - 16, 6, 0, 80, 78, 65, 73, 75, 0, 0, - 64, 0, 50, 0, 51, 0, 22, 24, 26, 0, - 38, 0, 0, 0, 19, 0, 68, 0, 0, 49, - 44, 45, 23, 25, 28, 29, 0, 30, 27, 20, - 76, 0, 39, 69 + 0, 0, 0, 0, 70, 3, 0, 1, 58, 49, + 56, 48, 52, 55, 59, 0, 60, 61, 62, 63, + 64, 65, 66, 0, 21, 0, 42, 43, 57, 15, + 0, 8, 11, 9, 10, 5, 13, 0, 0, 80, + 82, 0, 77, 0, 75, 0, 0, 45, 0, 0, + 0, 0, 4, 0, 0, 0, 33, 34, 35, 36, + 37, 38, 39, 0, 44, 0, 17, 0, 0, 14, + 0, 0, 0, 0, 69, 74, 0, 0, 0, 50, + 0, 0, 0, 0, 0, 22, 24, 0, 0, 31, + 0, 0, 26, 18, 16, 6, 0, 83, 81, 68, + 76, 78, 0, 0, 67, 0, 53, 0, 54, 0, + 22, 24, 26, 0, 40, 0, 32, 0, 0, 19, + 0, 71, 0, 0, 51, 46, 47, 23, 25, 28, + 29, 0, 30, 27, 20, 79, 0, 41, 72 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 3, 7, 44, 8, 9, 10, 32, 33, 71, - 119, 34, 35, 89, 36, 37, 15, 86, 16, 52, - 53, 108, 49, 81 + -1, 3, 7, 45, 8, 9, 10, 33, 34, 73, + 123, 35, 36, 91, 37, 38, 15, 88, 16, 53, + 54, 112, 50, 83 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -52 +#define YYPACT_NINF -54 static const yytype_int16 yypact[] = { - 41, 16, 1, 13, -52, 108, -9, -52, 22, -52, - 14, 129, 108, 6, -52, -52, 33, -52, -52, 31, - -52, -52, -52, -52, 108, -52, -52, -52, -52, -52, - -52, -52, 76, -52, 202, 171, -52, -52, 8, 108, - -52, -52, -52, -52, -52, -52, 108, 171, -52, 7, - 76, -52, -12, -52, 3, 24, 171, 84, 202, 129, - 129, -52, 25, 171, -52, -52, -52, -52, -52, -52, - -52, 150, -52, 30, -52, 45, 76, 90, 209, 108, - 129, 60, -52, -52, 6, 171, 43, 49, 87, -7, - 129, 129, 150, -52, -52, 171, 66, 171, -52, -52, - 10, -52, 171, 90, -52, -52, -52, -52, 27, 54, - -52, 64, -52, 171, -52, 171, 73, 74, 75, 50, - -52, 171, 79, 86, -52, 75, -52, 171, 171, -52, - 171, 171, -52, -52, -52, -52, 171, -52, -52, -52, - -52, 58, -52, -52 + 16, 77, 8, 7, -54, 109, -5, -54, 22, -54, + 24, 131, 109, 38, -54, -54, 44, -54, -54, 6, + -54, -54, -54, -54, -54, 109, -54, -54, -54, -54, + -54, -54, -54, 68, -54, 210, 175, -54, -54, 5, + 109, -54, -54, -54, -54, -54, -54, 109, 175, -54, + 0, 68, -54, -28, -54, 15, 43, 175, 79, 210, + 131, 131, -54, 36, 175, 75, -54, -54, -54, -54, + -54, -54, -54, 153, -54, 53, -54, 56, 68, 85, + 217, 109, 131, 62, -54, -54, 38, 175, -3, 50, + 87, -10, 131, 131, 153, -54, -54, 175, 83, -54, + 86, 175, -54, -54, 11, -54, 175, 85, -54, -54, + -54, -54, 10, 67, -54, 80, -54, 175, -54, 175, + 73, 76, 78, 21, -54, 175, -54, 88, 81, -54, + 78, -54, 175, 175, -54, 175, 175, -54, -54, -54, + -54, 175, -54, -54, -54, -54, 27, -54, -54 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -52, -52, 118, -28, -52, 113, -52, -5, -10, -48, - -52, -24, -51, -52, -32, -52, -52, -52, -52, -52, - 38, 4, -52, -52 + -54, -54, 113, -23, -54, 117, -54, -11, -8, -38, + -54, -25, -53, -54, -34, -54, -54, -54, -54, -54, + 40, 3, -54, -54 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -71 +#define YYTABLE_NINF -74 static const yytype_int16 yytable[] = { - 58, 48, 4, 72, 61, 88, 5, 50, -70, 11, - 92, 6, 79, 17, 73, 12, 123, 4, 38, 57, - 83, 5, 82, 78, 84, 114, 6, 39, 46, 115, - 102, 40, 6, 51, 76, 74, 13, 124, 85, 96, - 54, 77, 75, 80, 1, 2, 41, 98, 101, 93, - 94, 87, 40, 105, 42, 43, 72, 99, 110, 126, - 95, 107, 130, 127, 131, 55, 56, 41, 118, 40, - 104, 120, 100, 122, 103, 42, 43, 121, 125, 109, - 116, 117, 135, 111, 41, 40, 136, 59, 60, 128, - 143, 129, 42, 43, 127, 90, 91, 137, 72, 72, - 41, 59, 60, 140, 107, 132, 133, 134, 42, 43, - 18, 138, 142, 139, 19, 20, 21, 22, 23, 112, - 14, 45, 106, 113, 25, 26, 27, 28, 29, 30, - 31, 18, 141, 0, 0, 19, 20, 21, 22, 23, - 0, 0, 0, 24, 0, 25, 26, 27, 28, 29, - 30, 31, 18, 0, 0, 0, 19, 20, 21, 22, - 23, 0, 0, 0, 47, 0, 25, 26, 27, 28, - 29, 30, 31, 18, 0, 0, 0, 19, 20, 21, - 22, 23, 0, 0, 0, 97, 0, 25, 26, 27, - 28, 29, 30, 31, 18, 0, 0, 0, 19, 20, - 21, 22, 23, 0, 0, 0, 0, 0, 25, 26, - 27, 28, 29, 30, 31, 62, 0, 63, 64, 65, - 66, 67, 68, 69, 70, 64, 65, 66, 67, 68, - 69, 70 + 59, 51, 74, 49, 90, 81, 41, 17, 85, 4, + 62, 75, 86, 5, 58, -73, 11, 128, 6, 1, + 2, 94, 12, 80, 42, 39, 118, 40, 84, 78, + 119, 41, 6, 43, 44, 76, 79, 113, 47, 98, + 82, 129, 106, 77, 56, 57, 131, 13, 102, 42, + 132, 55, 95, 96, 87, 105, 74, 140, 43, 44, + 109, 141, 111, 148, 135, 114, 136, 132, 52, 122, + 107, 41, 124, 89, 108, 97, 127, 41, 4, 60, + 61, 130, 5, 103, 120, 121, 104, 6, 115, 42, + 92, 93, 99, 100, 125, 42, 60, 61, 43, 44, + 142, 74, 74, 126, 43, 44, 133, 145, 111, 137, + 134, 144, 138, 18, 139, 14, 147, 19, 20, 21, + 22, 23, 24, 116, 143, 46, 110, 117, 26, 27, + 28, 29, 30, 31, 32, 18, 146, 0, 0, 19, + 20, 21, 22, 23, 24, 0, 0, 0, 25, 0, + 26, 27, 28, 29, 30, 31, 32, 18, 0, 0, + 0, 19, 20, 21, 22, 23, 24, 0, 0, 0, + 48, 0, 26, 27, 28, 29, 30, 31, 32, 18, + 0, 0, 0, 19, 20, 21, 22, 23, 24, 0, + 0, 0, 101, 0, 26, 27, 28, 29, 30, 31, + 32, 18, 0, 0, 0, 19, 20, 21, 22, 23, + 24, 0, 0, 0, 0, 0, 26, 27, 28, 29, + 30, 31, 32, 63, 0, 64, 65, 0, 0, 66, + 67, 68, 69, 70, 71, 72, 66, 67, 68, 69, + 70, 71, 72 }; static const yytype_int16 yycheck[] = { - 24, 11, 1, 35, 32, 56, 5, 12, 7, 8, - 58, 10, 5, 0, 6, 14, 6, 1, 27, 24, - 32, 5, 50, 47, 36, 32, 10, 5, 14, 36, - 78, 9, 10, 27, 39, 27, 35, 27, 35, 63, - 7, 46, 34, 36, 3, 4, 24, 71, 76, 59, - 60, 27, 9, 81, 32, 33, 88, 27, 86, 32, - 35, 85, 113, 36, 115, 34, 35, 24, 92, 9, - 80, 95, 27, 97, 79, 32, 33, 11, 102, 36, - 90, 91, 32, 34, 24, 9, 36, 11, 12, 35, - 32, 27, 32, 33, 36, 11, 12, 121, 130, 131, - 24, 11, 12, 127, 128, 32, 32, 32, 32, 33, - 23, 32, 136, 27, 27, 28, 29, 30, 31, 32, - 2, 8, 84, 36, 37, 38, 39, 40, 41, 42, - 43, 23, 128, -1, -1, 27, 28, 29, 30, 31, - -1, -1, -1, 35, -1, 37, 38, 39, 40, 41, - 42, 43, 23, -1, -1, -1, 27, 28, 29, 30, - 31, -1, -1, -1, 35, -1, 37, 38, 39, 40, - 41, 42, 43, 23, -1, -1, -1, 27, 28, 29, - 30, 31, -1, -1, -1, 35, -1, 37, 38, 39, - 40, 41, 42, 43, 23, -1, -1, -1, 27, 28, - 29, 30, 31, -1, -1, -1, -1, -1, 37, 38, - 39, 40, 41, 42, 43, 13, -1, 15, 16, 17, - 18, 19, 20, 21, 22, 16, 17, 18, 19, 20, - 21, 22 + 25, 12, 36, 11, 57, 5, 9, 0, 36, 1, + 33, 6, 40, 5, 25, 7, 8, 6, 10, 3, + 4, 59, 14, 48, 27, 30, 36, 5, 51, 40, + 40, 9, 10, 36, 37, 30, 47, 40, 14, 64, + 40, 30, 80, 38, 38, 39, 36, 39, 73, 27, + 40, 7, 60, 61, 39, 78, 90, 36, 36, 37, + 83, 40, 87, 36, 117, 88, 119, 40, 30, 94, + 81, 9, 97, 30, 82, 39, 101, 9, 1, 11, + 12, 106, 5, 30, 92, 93, 30, 10, 38, 27, + 11, 12, 17, 18, 11, 27, 11, 12, 36, 37, + 125, 135, 136, 17, 36, 37, 39, 132, 133, 36, + 30, 30, 36, 26, 36, 2, 141, 30, 31, 32, + 33, 34, 35, 36, 36, 8, 86, 40, 41, 42, + 43, 44, 45, 46, 47, 26, 133, -1, -1, 30, + 31, 32, 33, 34, 35, -1, -1, -1, 39, -1, + 41, 42, 43, 44, 45, 46, 47, 26, -1, -1, + -1, 30, 31, 32, 33, 34, 35, -1, -1, -1, + 39, -1, 41, 42, 43, 44, 45, 46, 47, 26, + -1, -1, -1, 30, 31, 32, 33, 34, 35, -1, + -1, -1, 39, -1, 41, 42, 43, 44, 45, 46, + 47, 26, -1, -1, -1, 30, 31, 32, 33, 34, + 35, -1, -1, -1, -1, -1, 41, 42, 43, 44, + 45, 46, 47, 13, -1, 15, 16, -1, -1, 19, + 20, 21, 22, 23, 24, 25, 19, 20, 21, 22, + 23, 24, 25 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 3, 4, 45, 1, 5, 10, 46, 48, 49, - 50, 8, 14, 35, 46, 60, 62, 0, 23, 27, - 28, 29, 30, 31, 35, 37, 38, 39, 40, 41, - 42, 43, 51, 52, 55, 56, 58, 59, 27, 5, - 9, 24, 32, 33, 47, 49, 14, 35, 52, 66, - 51, 27, 63, 64, 7, 34, 35, 51, 55, 11, - 12, 47, 13, 15, 16, 17, 18, 19, 20, 21, - 22, 53, 58, 6, 27, 34, 51, 51, 55, 5, - 36, 67, 47, 32, 36, 35, 61, 27, 56, 57, - 11, 12, 53, 52, 52, 35, 55, 35, 55, 27, - 27, 47, 53, 51, 52, 47, 64, 55, 65, 36, - 47, 34, 32, 36, 32, 36, 52, 52, 55, 54, - 55, 11, 55, 6, 27, 55, 32, 36, 35, 27, - 56, 56, 32, 32, 32, 32, 36, 55, 32, 27, - 55, 65, 55, 32 + 0, 3, 4, 49, 1, 5, 10, 50, 52, 53, + 54, 8, 14, 39, 50, 64, 66, 0, 26, 30, + 31, 32, 33, 34, 35, 39, 41, 42, 43, 44, + 45, 46, 47, 55, 56, 59, 60, 62, 63, 30, + 5, 9, 27, 36, 37, 51, 53, 14, 39, 56, + 70, 55, 30, 67, 68, 7, 38, 39, 55, 59, + 11, 12, 51, 13, 15, 16, 19, 20, 21, 22, + 23, 24, 25, 57, 62, 6, 30, 38, 55, 55, + 59, 5, 40, 71, 51, 36, 40, 39, 65, 30, + 60, 61, 11, 12, 57, 56, 56, 39, 59, 17, + 18, 39, 59, 30, 30, 51, 57, 55, 56, 51, + 68, 59, 69, 40, 51, 38, 36, 40, 36, 40, + 56, 56, 59, 58, 59, 11, 17, 59, 6, 30, + 59, 36, 40, 39, 30, 60, 60, 36, 36, 36, + 36, 40, 59, 36, 30, 59, 69, 59, 36 }; #define yyerrok (yyerrstatus = 0) @@ -2003,47 +2107,47 @@ YYLTYPE yylloc; case 31: - { (yyval.func) = F_COMP_EQ; ;} + { (yyval.relation) = NULL; ;} break; case 32: - { (yyval.func) = F_COMP_NSEQ; ;} + { (yyval.relation) = NULL; ;} break; case 33: - { (yyval.func) = F_COMP_GE; ;} + { (yyval.func) = F_COMP_EQ; ;} break; case 34: - { (yyval.func) = F_COMP_GT; ;} + { (yyval.func) = F_COMP_NSEQ; ;} break; case 35: - { (yyval.func) = F_COMP_LE; ;} + { (yyval.func) = F_COMP_GE; ;} break; case 36: - { (yyval.func) = F_COMP_LT; ;} + { (yyval.func) = F_COMP_GT; ;} break; case 37: - { (yyval.func) = F_COMP_NE; ;} + { (yyval.func) = F_COMP_LE; ;} break; case 38: - { (yyval.list) = (yyvsp[(1) - (1)].list); ;} + { (yyval.func) = F_COMP_LT; ;} break; case 39: - { (yyval.list) = (yyvsp[(1) - (3)].list); add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); ;} + { (yyval.func) = F_COMP_NE; ;} break; case 40: @@ -2053,31 +2157,41 @@ YYLTYPE yylloc; case 41: - { malloc_list((yyval.list), result, (yyvsp[(1) - (1)].node)); ;} + { (yyval.list) = (yyvsp[(1) - (3)].list); add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); ;} break; case 42: - { add_token((yyvsp[(1) - (2)].list), result, (yyvsp[(2) - (2)].node)); (yyval.list) = (yyvsp[(1) - (2)].list); ;} + { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; case 43: - { (yyval.list) = NULL; ;} + { malloc_list((yyval.list), result, (yyvsp[(1) - (1)].node)); ;} break; case 44: - { add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); (yyval.list) = (yyvsp[(1) - (3)].list); ;} + { add_token((yyvsp[(1) - (2)].list), result, (yyvsp[(2) - (2)].node)); (yyval.list) = (yyvsp[(1) - (2)].list); ;} break; case 45: - { add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); (yyval.list) = (yyvsp[(1) - (3)].list); ;} + { (yyval.list) = NULL; ;} break; case 46: + { add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); (yyval.list) = (yyvsp[(1) - (3)].list); ;} + break; + + case 47: + + { add_token_list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); (yyval.list) = (yyvsp[(1) - (3)].list); ;} + break; + + case 48: + { malloc_node((yyval.node), result, TOKEN_COLUMN); (yyval.node)->part_key_idx_ = 0; @@ -2086,7 +2200,7 @@ YYLTYPE yylloc; ;} break; - case 47: + case 49: { malloc_node((yyval.node), result, TOKEN_COLUMN); @@ -2095,7 +2209,7 @@ YYLTYPE yylloc; ;} break; - case 48: + case 50: { malloc_node((yyval.node), result, TOKEN_COLUMN); @@ -2104,7 +2218,7 @@ YYLTYPE yylloc; ;} break; - case 49: + case 51: { malloc_node((yyval.node), result, TOKEN_COLUMN); @@ -2113,7 +2227,15 @@ YYLTYPE yylloc; ;} break; - case 50: + case 52: + + { + malloc_node((yyval.node), result, TOKEN_FUNC); + (yyval.node)->str_value_ = (yyvsp[(1) - (1)].str); + ;} + break; + + case 53: { malloc_node((yyval.node), result, TOKEN_FUNC); @@ -2122,7 +2244,7 @@ YYLTYPE yylloc; ;} break; - case 51: + case 54: { malloc_node((yyval.node), result, TOKEN_FUNC); @@ -2131,22 +2253,22 @@ YYLTYPE yylloc; ;} break; - case 52: + case 55: { malloc_node((yyval.node), result, TOKEN_INT_VAL); (yyval.node)->int_value_ = (yyvsp[(1) - (1)].num); ;} break; - case 53: + case 56: { malloc_node((yyval.node), result, TOKEN_STR_VAL); (yyval.node)->str_value_ = (yyvsp[(1) - (1)].str); ;} break; - case 54: + case 57: { malloc_node((yyval.node), result, TOKEN_OPERATOR); (yyval.node)->operator_ = (yyvsp[(1) - (1)].operator); ;} break; - case 55: + case 58: { result->placeholder_list_idx_++; @@ -2155,7 +2277,7 @@ YYLTYPE yylloc; ;} break; - case 56: + case 59: { malloc_node((yyval.node), result, TOKEN_PLACE_HOLDER); @@ -2163,71 +2285,76 @@ YYLTYPE yylloc; ;} break; - case 57: + case 60: { (yyval.operator) = OPT_ADD; ;} break; - case 58: + case 61: { (yyval.operator) = OPT_MINUS; ;} break; - case 59: + case 62: { (yyval.operator) = OPT_MUL; ;} break; - case 60: + case 63: { (yyval.operator) = OPT_DIV; ;} break; - case 61: + case 64: { (yyval.operator) = OPT_MOD; ;} break; - case 62: + case 65: { (yyval.operator) = OPT_AND; ;} break; - case 63: + case 66: { (yyval.operator) = OPT_NOT; ;} break; - case 64: + case 67: { YYACCEPT; ;} break; - case 65: + case 68: { YYACCEPT; ;} break; - case 66: + case 69: { YYACCEPT; ;} break; - case 68: + case 71: { result->multi_param_values_++; ;} break; - case 69: + case 72: { result->multi_param_values_++; ;} break; - case 72: + case 73: + + { init_part_key_all_match(result);;} + break; + + case 75: { malloc_list((yyval.list), result, (yyvsp[(1) - (1)].node)); @@ -2235,7 +2362,7 @@ YYLTYPE yylloc; ;} break; - case 73: + case 76: { malloc_list((yyval.list), result, (yyvsp[(3) - (3)].node)); @@ -2243,7 +2370,7 @@ YYLTYPE yylloc; ;} break; - case 74: + case 77: { set_part_key_column_idx(result, &(yyvsp[(1) - (1)].str)); @@ -2253,7 +2380,7 @@ YYLTYPE yylloc; ;} break; - case 75: + case 78: { if (result->multi_param_values_ < 1) { @@ -2266,7 +2393,7 @@ YYLTYPE yylloc; ;} break; - case 76: + case 79: { if (result->multi_param_values_ < 1) { @@ -2278,17 +2405,17 @@ YYLTYPE yylloc; ;} break; - case 77: + case 80: { check_and_add_relation(result, (yyvsp[(1) - (1)].relation)); ;} break; - case 78: + case 81: { check_and_add_relation(result, (yyvsp[(3) - (3)].relation)); ;} break; - case 80: + case 83: {;} break; diff --git a/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_tab.h b/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_tab.h index 8c2fb9737..9fee13472 100644 --- a/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_tab.h +++ b/src/obproxy/opsql/expr_parser/ob_expr_parser_utf8_tab.h @@ -69,22 +69,26 @@ extern int ob_expr_parser_utf8_yydebug; IN = 268, ON = 269, BETWEEN = 270, - COMP_EQ = 271, - COMP_NSEQ = 272, - COMP_GE = 273, - COMP_GT = 274, - COMP_LE = 275, - COMP_LT = 276, - COMP_NE = 277, - PLACE_HOLDER = 278, - END_P = 279, - ERROR = 280, - IGNORED_WORD = 281, - NAME_OB = 282, - STR_VAL = 283, - ROW_ID = 284, - INT_VAL = 285, - POS_PLACE_HOLDER = 286 + IS = 271, + TOKEN_NULL = 272, + NOT = 273, + COMP_EQ = 274, + COMP_NSEQ = 275, + COMP_GE = 276, + COMP_GT = 277, + COMP_LE = 278, + COMP_LT = 279, + COMP_NE = 280, + PLACE_HOLDER = 281, + END_P = 282, + ERROR = 283, + IGNORED_WORD = 284, + NAME_OB = 285, + STR_VAL = 286, + ROW_ID = 287, + REVERSED_EXPR_FUNC = 288, + INT_VAL = 289, + POS_PLACE_HOLDER = 290 }; #endif diff --git a/src/obproxy/opsql/expr_resolver/ob_expr_resolver.cpp b/src/obproxy/opsql/expr_resolver/ob_expr_resolver.cpp index e09643039..6a656e7e6 100644 --- a/src/obproxy/opsql/expr_resolver/ob_expr_resolver.cpp +++ b/src/obproxy/opsql/expr_resolver/ob_expr_resolver.cpp @@ -11,6 +11,10 @@ */ #define USING_LOG_PREFIX PROXY +#include "opsql/func_expr_resolver/ob_func_expr_resolver.h" +#include "opsql/func_expr_parser/ob_func_expr_parser.h" +#include "opsql/func_expr_resolver/proxy_expr/ob_proxy_expr_factory.h" +#include "opsql/func_expr_resolver/proxy_expr/ob_proxy_expr.h" #include "opsql/expr_resolver/ob_expr_resolver.h" #include "proxy/route/obproxy_part_info.h" #include "proxy/route/obproxy_expr_calculator.h" @@ -20,11 +24,14 @@ #include "proxy/mysql/ob_prepare_statement_struct.h" #include "obutils/ob_proxy_sql_parser.h" #include "utils/ob_proxy_utils.h" +#include "dbconfig/ob_proxy_db_config_info.h" +#include "common/ob_obj_compare.h" using namespace oceanbase::common; using namespace oceanbase::obproxy::proxy; using namespace oceanbase::obproxy::obutils; using namespace oceanbase::obmysql; +using namespace oceanbase::obproxy::dbconfig; namespace oceanbase { @@ -60,6 +67,51 @@ int64_t ObExprResolverResult::to_string(char *buf, const int64_t buf_len) const return pos; } +/** + * @brief The range's border flag is decided by the last valid column. + * If use range directly, the range will cover partition which + * doesn't contain the data. + * + * @param range + * @param border_flags all columns' border flag + * @return int + */ +int ObExprResolver::preprocess_range(ObNewRange &range, ObIArray &border_flags) { + int ret = OB_SUCCESS; + ObObj *obj_start = const_cast(range.start_key_.get_obj_ptr()); + ObObj *obj_end = const_cast(range.end_key_.get_obj_ptr()); + int64_t invalid_idx = range.start_key_.get_obj_cnt(); + for (int64_t i = 0; i < range.start_key_.get_obj_cnt(); i++) { + // find the last valid col, + // use the last valid col's border flag as range's border flag + range.border_flag_.set_data(border_flags.at(i).get_data()); + if (OB_ISNULL(obj_start) || OB_ISNULL(obj_end)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null pointer"); + } else { + ObCompareCtx cmp_ctx(ObMaxType, CS_TYPE_INVALID, true, INVALID_TZ_OFF); + bool need_cast = false; + ObObj cmp_result(false); + if (OB_FAIL(ObObjCmpFuncs::compare(cmp_result, *obj_start, *obj_end, cmp_ctx, ObCmpOp::CO_EQ, need_cast))) { + LOG_WARN("fail to compare", K(ret)); + invalid_idx = i + 1; + ret = OB_SUCCESS; + break; + } else if (!cmp_result.get_bool()) { + invalid_idx = i + 1; + break; + } + } + } + // set the cols after invalid_idx(included) to (max : min) + for (int64_t i = invalid_idx; i < range.start_key_.get_obj_cnt(); i++) { + (obj_start + i)->set_max_value(); + (obj_end + i)->set_min_value(); + } + LOG_DEBUG("succ to simplify range", K(range)); + return ret; +} + int ObExprResolver::resolve(ObExprResolverContext &ctx, ObExprResolverResult &result) { int ret = OB_SUCCESS; @@ -67,27 +119,156 @@ int ObExprResolver::resolve(ObExprResolverContext &ctx, ObExprResolverResult &re ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid ctx", K(ctx.relation_info_), K(ret)); } else { - // ignore ret in for loop - for (int64_t i = 0; i < ctx.relation_info_->relation_num_; ++i) { - if (OB_ISNULL(ctx.relation_info_->relations_[i])) { - LOG_INFO("relations is not valid here, ignore it", - K(ctx.relation_info_->relations_[i]), K(i)); - } else if (OB_UNLIKELY(ctx.relation_info_->relations_[i]->level_ == PART_KEY_LEVEL_ZERO)) { - LOG_INFO("level is zero, ignore it"); + proxy::ObProxyPartInfo *part_info = ctx.part_info_; + + // to store partition column's border flag as order above like + // "where c2 > 1 and c1 < 33" => ordered_part_col_border [(exclusive_start, exclusive_end] + ObSEArray part_columns_border; + ObSEArray sub_part_columns_border; + + // init range and border + if (part_info->get_part_level() >= share::schema::PARTITION_LEVEL_ONE) { + if (OB_FAIL(result.ranges_[0].build_row_key(part_info->get_part_columns().count(), allocator_))) { + LOG_WARN("fail to init range", K(ret)); } else { - int64_t part_idx = (ctx.relation_info_->relations_[i]->level_ >= PART_KEY_LEVEL_BOTH) ? 0 - : static_cast(ctx.relation_info_->relations_[i]->level_ - 1); - if (OB_FAIL(resolve_token_list(ctx.relation_info_->relations_[i], - ctx.part_info_, - ctx.client_request_, - ctx.client_info_, - ctx.ps_id_entry_, - ctx.text_ps_entry_, - result.ranges_[part_idx]))) { - LOG_INFO("fail to resolve token list, ignore it", K(ret)); + for (int i = 0; OB_SUCC(ret) && i < part_info->get_part_columns().count(); i++) { + if (OB_FAIL(part_columns_border.push_back(ObBorderFlag()))) { + LOG_WARN("fail to push border flag", K(i), K(ret)); + } + } + } + } + if (part_info->get_part_level() == share::schema::PARTITION_LEVEL_TWO) { + if (OB_FAIL(result.ranges_[1].build_row_key(part_info->get_sub_part_columns().count(), allocator_))) { + LOG_WARN("fail to init range", K(ret)); + } else { + for (int i = 0; OB_SUCC(ret) && i < part_info->get_sub_part_columns().count(); i++) { + if (OB_FAIL(sub_part_columns_border.push_back(ObBorderFlag()))) { + LOG_WARN("fail to push border flag", K(i), K(ret)); + } } } } + + if (OB_SUCC(ret)) { + ObObj *target_obj = NULL; + void *tmp_buf = NULL; + + // ignore ret in for loop + // resolve every relation + for (int64_t i = 0; i < ctx.relation_info_->relation_num_; ++i) { + if (OB_ISNULL(ctx.relation_info_->relations_[i])) { + LOG_INFO("relations is not valid here, ignore it", + K(ctx.relation_info_->relations_[i]), K(i)); + } else if (OB_UNLIKELY(ctx.relation_info_->relations_[i]->level_ == PART_KEY_LEVEL_ZERO)) { + LOG_INFO("level is zero, ignore it"); + } else { + if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObObj)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc new obj", K(ret)); + } else if (OB_ISNULL(target_obj = new (tmp_buf) ObObj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to do placement new", K(ret)); + } else if (OB_FAIL(resolve_token_list(ctx.relation_info_->relations_[i], ctx.part_info_, ctx.client_request_, + ctx.client_info_, ctx.ps_id_entry_, ctx.text_ps_entry_, target_obj, + ctx.sql_field_result_))) { + LOG_INFO("fail to resolve token list, ignore it", K(ret)); + } else if ((PART_KEY_LEVEL_ONE == ctx.relation_info_->relations_[i]->level_ || + PART_KEY_LEVEL_BOTH == ctx.relation_info_->relations_[i]->level_) && + OB_FAIL(place_obj_to_range(ctx.relation_info_->relations_[i]->type_, + ctx.relation_info_->relations_[i]->first_part_column_idx_, + target_obj, &result.ranges_[0], part_columns_border))) { + LOG_WARN("fail to place obj to range of part level one", K(ret)); + } else if ((PART_KEY_LEVEL_TWO == ctx.relation_info_->relations_[i]->level_ || + PART_KEY_LEVEL_BOTH == ctx.relation_info_->relations_[i]->level_) && + OB_FAIL(place_obj_to_range(ctx.relation_info_->relations_[i]->type_, + ctx.relation_info_->relations_[i]->second_part_column_idx_, + target_obj, &result.ranges_[1], sub_part_columns_border))) { + LOG_WARN("fail to place obj to range of part level two", K(ret)); + } else {} + if (OB_NOT_NULL(target_obj)) { + allocator_.free(target_obj); + } + } + } + + if (OB_SUCC(ret) && ctx.is_insert_stm_) { + if(OB_FAIL(handle_default_value(ctx.parse_result_->part_key_info_, + ctx.client_info_, result.ranges_, + ctx.sql_field_result_,part_columns_border, + sub_part_columns_border, part_info->is_oracle_mode()))){ + LOG_WARN("fail to handle default value of part keys", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(preprocess_range(result.ranges_[0], part_columns_border))) { + LOG_WARN("fail to preprocess range, part key level 0", K(ret)); + } else if (OB_FAIL(preprocess_range(result.ranges_[1], sub_part_columns_border))) { + LOG_WARN("fail to preprocess range, part key level 1", K(ret)); + } else {} + } + } + } + return ret; +} + +/** + * @brief 1. Place the resolved partition obj to range.start_key_/range.end_key_[idx]. + * The idx is the obj's according column's idx in partition expression. + * 2. Set the border flag of the partition obj. Use the border flag later in ObExprResolver::preprocess_range. + * + * @param relation + * @param part_info + * @param target_obj + * @param range out + * @param border_flags out + * @param part_columns + * @return int + */ +int ObExprResolver::place_obj_to_range(ObProxyFunctionType type, + int64_t idx_in_part_columns, + ObObj *target_obj, + ObNewRange *range, + ObIArray &border_flags) +{ + int ret = OB_SUCCESS; + ObObj *start_obj = const_cast(range->start_key_.get_obj_ptr()) + idx_in_part_columns; + ObObj *end_obj = const_cast(range->end_key_.get_obj_ptr()) + idx_in_part_columns; + if (OB_ISNULL(start_obj) || OB_ISNULL(end_obj) || OB_ISNULL(target_obj)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null pointer"); + } + + // 1. deep copy the resolved obj to right position in result.ranges_[x] + // 2. set the resolved obj's border flag + if (OB_SUCC(ret)) { + switch (type) { + case F_COMP_EQ: + *start_obj = *target_obj; + *end_obj = *target_obj; + border_flags.at(idx_in_part_columns).set_inclusive_start(); + border_flags.at(idx_in_part_columns).set_inclusive_end(); + break; + case F_COMP_GE: + *start_obj = *target_obj; + border_flags.at(idx_in_part_columns).set_inclusive_start(); + break; + case F_COMP_GT: + *start_obj = *target_obj; + break; + case F_COMP_LE: + *end_obj = *target_obj; + border_flags.at(idx_in_part_columns).set_inclusive_end(); + break; + case F_COMP_LT: + *end_obj = *target_obj; + break; + default: + LOG_INFO("this func is not useful for range", "func_type", + get_obproxy_function_type(type)); + break; + } // end of switch } return ret; } @@ -108,179 +289,365 @@ int ObExprResolver::resolve_token_list(ObProxyRelationExpr *relation, ObClientSessionInfo *client_info, ObPsIdEntry *ps_id_entry, ObTextPsEntry *text_ps_entry, - ObNewRange &range, + ObObj *target_obj, + SqlFieldResult *sql_field_result, const bool has_rowid) { int ret = OB_SUCCESS; UNUSED(text_ps_entry); - if (OB_ISNULL(relation) || OB_ISNULL(part_info)) { + if (OB_ISNULL(target_obj)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("target_obj is null"); + } else if (OB_ISNULL(relation) || OB_ISNULL(part_info)) { ret = OB_INVALID_ARGUMENT; LOG_INFO("relation or part info is null", K(relation), K(part_info), K(ret)); } else if (OB_ISNULL(relation->right_value_) || OB_ISNULL(relation->right_value_->head_)) { ret = OB_INVALID_ARGUMENT; LOG_INFO("token list or head is null", K(relation->right_value_), K(ret)); } else { - ObObj *target_obj = NULL; - void *tmp_buf = NULL; + ObProxyTokenNode *token = relation->right_value_->head_; + int64_t col_idx = relation->column_idx_; + if (TOKEN_STR_VAL == token->type_) { + target_obj->set_varchar(token->str_value_.str_, token->str_value_.str_len_); + target_obj->set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + } else if (TOKEN_INT_VAL == token->type_) { + target_obj->set_int(token->int_value_); + } else if (TOKEN_PLACE_HOLDER == token->type_) { + int64_t param_index = token->placeholder_idx_; + if (OB_FAIL(get_obj_with_param(*target_obj, client_request, client_info, + part_info, ps_id_entry, param_index))) { + LOG_DEBUG("fail to get target obj with param", K(ret)); + } + } else if (TOKEN_FUNC == token->type_) { + if (OB_FAIL(calc_token_func_obj(token, client_info, *target_obj, sql_field_result, part_info->is_oracle_mode()))) { + LOG_WARN("fail to calc token func obj", K(ret)); + } + } else { + ret = OB_INVALID_ARGUMENT; + } + + if (OB_SUCC(ret) + && !has_rowid + && part_info->has_generated_key()) { + int64_t target_idx = -1; + ObProxyPartKeyInfo &part_key_info = part_info->get_part_key_info(); + if (col_idx >= part_key_info.key_num_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("relation column index is invalid", K(col_idx), K(part_key_info.key_num_), K(ret)); + } else if (part_key_info.part_keys_[col_idx].is_generated_) { + // do nothing, user sql explicitly contains value for generated key, no need to calculate + } else if (FALSE_IT(target_idx = part_key_info.part_keys_[col_idx].generated_col_idx_)) { + // will not come here + } else if (OB_UNLIKELY(0 > target_idx)) { + LOG_DEBUG("this relation's part key is not used to generate column"); + } else if (OB_UNLIKELY(target_idx >= part_key_info.key_num_) + || OB_UNLIKELY(!part_key_info.part_keys_[target_idx].is_generated_) + || OB_UNLIKELY(part_key_info.part_keys_[target_idx].level_ != relation->level_)) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("fail to get generated key value, source key is not offered", + K(col_idx), K(part_key_info.key_num_), K(target_idx), K(ret)); + } else if (OB_FAIL(calc_generated_key_value(*target_obj, part_key_info.part_keys_[col_idx], + part_info->is_oracle_mode()))) { + LOG_WARN("fail to get generated key value", K(target_obj), K(ret)); + } else { + LOG_DEBUG("succ to calculate generated key value", K(target_obj), K(ret)); + } + } + + if (OB_SUCC(ret) && ObStringTC == target_obj->get_type_class()) { + // The character set of the string parsed from the parser uses the value of the variable collation_connection + target_obj->set_collation_type(static_cast(client_info->get_collation_connection())); + } + } // end of else + return ret; +} + +/* + * calculate func token, convert token node to param node to reuse func resolver + */ +int ObExprResolver::calc_token_func_obj(ObProxyTokenNode *token, + ObClientSessionInfo *client_session_info, + ObObj &target_obj, + SqlFieldResult *sql_field_result, + const bool is_oracle_mode) +{ + int ret = OB_SUCCESS; + ObProxyParamNode *param_node = NULL; + ObProxyExprFactory factory(allocator_); + ObFuncExprResolverContext ctx(&allocator_, &factory); + ObFuncExprResolver resolver(ctx); + ObProxyExpr *expr; + + if (OB_FAIL(convert_token_node_to_param_node(token, param_node))) { + LOG_WARN("fail to convert func token to param node", K(ret)); + } else if (OB_ISNULL(param_node)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to convert func token to param node", K(ret)); + } else if (OB_FAIL(resolver.resolve(param_node, expr))) { + LOG_WARN("proxy expr resolve failed", K(ret)); + } else { + ObSEArray result_array; + ObProxyExprCalcItem calc_item(const_cast(sql_field_result)); + ObProxyExprCtx expr_ctx(0, TESTLOAD_NON, false, &allocator_, client_session_info); + expr_ctx.is_oracle_mode = is_oracle_mode; + if (OB_FAIL(expr->calc(expr_ctx, calc_item, result_array))) { + LOG_WARN("calc expr result failed", K(ret)); + } else if (OB_FAIL(result_array.at(0, target_obj))) { + LOG_WARN("get expr calc result fail", K(ret)); + } + } + + return ret; +} + +int ObExprResolver::handle_default_value(ObProxyPartKeyInfo &part_key_info, + proxy::ObClientSessionInfo *client_info, + common::ObNewRange ranges[], + obutils::SqlFieldResult *sql_field_result, + ObIArray &part_border_flags, + ObIArray &sub_part_border_flags, + bool is_oracle_mode) +{ + int ret = OB_SUCCESS; + ObObj *target_obj = NULL; + void *tmp_buf = NULL; + for (int i = 0; OB_SUCC(ret) && i < part_key_info.key_num_; i++) { + ObProxyPartKeyLevel level = part_key_info.part_keys_[i].level_; + int64_t column_idx = part_key_info.part_keys_[i].idx_in_part_columns_; + bool is_need_default_val = false; + if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObObj)))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to alloc new obj", K(ret)); - } else { - target_obj = new (tmp_buf) ObObj(); - - ObProxyFunctionType &func_type = relation->type_; - ObProxyTokenNode *token = relation->right_value_->head_; - int64_t col_idx = relation->column_idx_; - if (TOKEN_STR_VAL == token->type_) { - target_obj->set_varchar(token->str_value_.str_, token->str_value_.str_len_); - target_obj->set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); - } else if (TOKEN_INT_VAL == token->type_) { - target_obj->set_int(token->int_value_); - } else if (TOKEN_PLACE_HOLDER == token->type_) { - int64_t param_index = token->placeholder_idx_; - if (OB_FAIL(get_obj_with_param(*target_obj, client_request, client_info, - part_info, ps_id_entry, param_index))) { - LOG_DEBUG("fail to get target obj with param", K(ret)); + } else if (OB_ISNULL(target_obj = new (tmp_buf) ObObj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to do placement new ObObj", K(ret)); + } + + if(OB_SUCC(ret)){ + if (part_key_info.part_keys_[i].is_generated_ && !part_key_info.part_keys_[i].is_exist_in_sql_) { + int source_idx = -1; + ObProxyParseString *var_str = NULL; + for (int j = 0; j < part_key_info.key_num_; j++) { + if (part_key_info.part_keys_[j].generated_col_idx_ == i + && !part_key_info.part_keys_[j].is_exist_in_sql_) { + source_idx = j; + break; + } } - } else if (TOKEN_FUNC == token->type_) { - if (OB_FAIL(calc_token_func_obj(token, client_info, *target_obj))) { - LOG_WARN("fail to calc token func obj", K(ret)); + if (source_idx >= 0) { + int64_t real_source_idx = part_key_info.part_keys_[source_idx].real_source_idx_; + if (real_source_idx < 0 || real_source_idx > OBPROXY_MAX_PART_KEY_NUM){ + // invalid real source idx + } else if (FALSE_IT(var_str = &part_key_info.part_keys_[real_source_idx].default_value_) || var_str->str_len_ < 0 ){ + } else if (OB_FAIL(parse_and_resolve_default_value(*var_str, client_info, sql_field_result, target_obj, is_oracle_mode))){ + LOG_WARN("parse and resolve default value of partition key failed", K(ret)); + } else if (OB_FAIL(calc_generated_key_value(*target_obj, part_key_info.part_keys_[source_idx], is_oracle_mode))) { + LOG_WARN("fail to get generated key value", K(target_obj), K(ret)); + } else { + is_need_default_val = true; + } + } + } else if (!part_key_info.part_keys_[i].is_exist_in_sql_) { + ObProxyParseString &var_str = part_key_info.part_keys_[i].default_value_; + if (var_str.str_len_ > 0) { + if (OB_FAIL(parse_and_resolve_default_value(var_str, client_info, sql_field_result, target_obj, is_oracle_mode))) { + LOG_WARN("parse and resolve default value of partition key failed", K(ret)); + } else { + is_need_default_val = true; + } } - } else { - ret = OB_INVALID_ARGUMENT; } + } + + if (OB_SUCC(ret) && is_need_default_val) { + if ((PART_KEY_LEVEL_ONE == level || PART_KEY_LEVEL_BOTH == level) && + OB_FAIL(place_obj_to_range(F_COMP_EQ, column_idx, target_obj, &ranges[0], part_border_flags))) { + LOG_WARN("fail to place obj to range of part level one", K(ret)); + } else if ((PART_KEY_LEVEL_TWO == level || PART_KEY_LEVEL_BOTH == level) && + OB_FAIL(place_obj_to_range(F_COMP_EQ, column_idx, target_obj, &ranges[1], sub_part_border_flags))) { + LOG_WARN("fail to place obj to range of part level two", K(ret)); + } else {} + } + if (OB_NOT_NULL(target_obj)) { + allocator_.free(target_obj); + } + } + return ret; +} - if (!has_rowid - && part_info->has_generated_key()) { - int64_t target_idx = -1; - ObProxyPartKeyInfo &part_key_info = part_info->get_part_key_info(); - if (col_idx >= part_key_info.key_num_) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("relation column index is invalid", K(col_idx), K(part_key_info.key_num_), K(ret)); - } else if (part_key_info.part_keys_[col_idx].is_generated_) { - // do nothing, user sql explicitly contains value for generated key, no need to calculate - } else if (FALSE_IT(target_idx = part_key_info.part_keys_[col_idx].generated_col_idx_)) { - // will not come here - } else if (OB_UNLIKELY(target_idx >= part_key_info.key_num_) - || OB_UNLIKELY(target_idx < 0) - || OB_UNLIKELY(!part_key_info.part_keys_[target_idx].is_generated_) - || OB_UNLIKELY(part_key_info.part_keys_[target_idx].level_ != relation->level_)) { - ret = OB_ENTRY_NOT_EXIST; - LOG_WARN("fail to get generated key value, source key is not offered", - K(col_idx), K(part_key_info.key_num_), K(target_idx), K(ret)); - } else if (OB_FAIL(calc_generated_key_value(*target_obj, part_key_info.part_keys_[col_idx], - part_info->is_oracle_mode()))) { - LOG_WARN("fail to get generated key value", K(target_obj), K(ret)); +int ObExprResolver::parse_and_resolve_default_value(ObProxyParseString &default_value, + ObClientSessionInfo *client_session_info, + SqlFieldResult *sql_field_result, + ObObj *target_obj, + bool is_oracle_mode) +{ + int ret = OB_SUCCESS; + number::ObNumber nb; + if (default_value.str_len_ > 0 ){ + int64_t tmp_pos = 0; + if (OB_FAIL(target_obj->deserialize(default_value.str_ , default_value.str_len_, tmp_pos))) { + LOG_WARN("fail to deserialize default value of part key"); + } else if (FALSE_IT(LOG_DEBUG("default value deserialize succ" , K(*target_obj)))) { + } else if (target_obj->is_varchar() && is_oracle_mode) { + // oracle mode return the default as a unresolved varchar type obj + ObString default_value_expr = target_obj->get_varchar(); + if (default_value_expr.empty()) { + target_obj->set_varchar(ObString()); + } else if ('\'' == default_value_expr[0]) { + // match string type + ObString dst; + if (2 >= default_value_expr.length()) { + dst = ObString(); + // remove single quotes + } else if (OB_FAIL(ob_sub_str(allocator_, default_value_expr, 1, default_value_expr.length() - 2, dst))) { + LOG_WARN("get sub stirng of default value failed", K(ret)); + } + if (OB_SUCC(ret)) { + target_obj->set_varchar(dst); + } + } else if ( OB_SUCCESS == nb.from(default_value_expr.ptr(), default_value_expr.length(), allocator_)) { + // match positive number + } else if ('-' == default_value_expr[0] && 4 <= default_value_expr.length()) { + // match megative number + // server return negative with brackets, -1 -> -(1) + ObString number_part; + char *buf = NULL; + if(OB_FAIL(ob_sub_str(allocator_, default_value_expr, 2, default_value_expr.length() - 2, number_part))) { + LOG_WARN("get default value number part fail", K(ret)); + } else if (OB_ISNULL(buf = static_cast(allocator_.alloc(number_part.length() + 1)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("alloc memory failed", K(ret)); } else { - LOG_DEBUG("succ to calculate generated key value", K(target_obj), K(ret)); + MEMCPY(buf, "-", 1); + MEMCPY(buf + 1, number_part.ptr(), number_part.length()); + target_obj->set_varchar(ObString(number_part.length()+1, buf)); } - } + } else { + // match expr + ObFuncExprParser parser(allocator_, SHARDING_EXPR_FUNC_PARSE_MODE); + ObFuncExprParseResult result; - if (OB_SUCC(ret) && ObStringTC == target_obj->get_type_class()) { - // The character set of the string parsed from the parser uses the value of the variable collation_connection - target_obj->set_collation_type(static_cast(client_info->get_collation_connection())); - } + ObProxyExprFactory factory(allocator_); + ObFuncExprResolverContext ctx(&allocator_, &factory); + ObFuncExprResolver resolver(ctx); + ObProxyExpr *expr; - if (OB_SUCC(ret)) { - switch (func_type) { - case F_COMP_EQ: - range.start_key_.assign(target_obj, 1); - range.end_key_.assign(target_obj, 1); - range.border_flag_.set_inclusive_start(); - range.border_flag_.set_inclusive_end(); - break; - case F_COMP_GE: - range.start_key_.assign(target_obj, 1); - range.border_flag_.set_inclusive_start(); - break; - case F_COMP_GT: - range.start_key_.assign(target_obj, 1); - break; - case F_COMP_LE: - range.end_key_.assign(target_obj, 1); - range.border_flag_.set_inclusive_end(); - break; - case F_COMP_LT: - range.end_key_.assign(target_obj, 1); - break; - default: - LOG_INFO("this func is not useful for range", "func_type", - get_obproxy_function_type(func_type)); - break; - } // end of switch - } // end of if - } // end of else - } // end of else + if (OB_FAIL(parser.parse(default_value_expr, result))) { + LOG_INFO("parse default value expr failed", K(ret)); + } else if (OB_FAIL(resolver.resolve(result.param_node_, expr))) { + LOG_INFO("proxy expr resolve failed", K(ret)); + } else { + ObSEArray result_array; + ObProxyExprCalcItem calc_item(const_cast(sql_field_result)); + ObProxyExprCtx expr_ctx(0, TESTLOAD_NON, false, &allocator_, client_session_info); + expr_ctx.is_oracle_mode = is_oracle_mode; + if (OB_FAIL(expr->calc(expr_ctx, calc_item, result_array))) { + LOG_WARN("calc expr result failed", K(ret)); + } else if (OB_FAIL(result_array.at(0, *target_obj))) { + LOG_WARN("get expr calc result fail", K(ret)); + } + } + } + } else { + // mysql mode return the default value with resolved obj in column's type + // do nothing + } + } + if (OB_SUCC(ret) && ObStringTC == target_obj->get_type_class()) { + LOG_DEBUG("parse and resolve default value succ", K(*target_obj), K(ret)); + target_obj->set_collation_type(static_cast(client_session_info->get_collation_connection())); + } return ret; } -/* - * currently only support to_date/to_timestamp function - * currently support at least one param, at most two params now - */ -int ObExprResolver::calc_token_func_obj(ObProxyTokenNode *token, - ObClientSessionInfo *client_session_info, - ObObj &target_obj) +int ObExprResolver::convert_token_node_to_param_node(ObProxyTokenNode *token, + ObProxyParamNode *¶m) { int ret = OB_SUCCESS; - ObObjType target_type = ObMaxType; - ObString func_name(token->str_value_.str_len_ ,token->str_value_.str_); - - if (func_name.case_compare("to_date") == 0) { - target_type = ObDateTimeType; - } else if (func_name.case_compare("to_timestamp") == 0) { - target_type = ObTimestampNanoType; + if (OB_ISNULL(token)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret)); } else { - /* more function could be supported */ + void *tmp_buf = NULL; + if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObProxyParamNode)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc new param node", K(ret)); + } else { + param = new(tmp_buf) ObProxyParamNode(); + param->next_ = NULL; + if (TOKEN_INT_VAL == token->type_) { + param->int_value_ = token->int_value_; + param->type_ = PARAM_INT_VAL; + } else if (TOKEN_STR_VAL == token->type_) { + param->str_value_ = token->str_value_; + param->type_ = PARAM_STR_VAL; + } else if (TOKEN_FUNC == token->type_) { + if (OB_FAIL(recursive_convert_func_token(token, param))) { + LOG_WARN("convert func token node to param node failed", K(ret)); + } + } else { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("unexpected token node type, please check", K(ret), K(param->type_)); + } + } } + return ret; +} - if (target_type == ObMaxType) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("fail to parse token func, unsupported function name", K(ret), K(func_name)); - } else if (OB_ISNULL(token->child_) - || OB_ISNULL(token->child_->head_)){ +int ObExprResolver::recursive_convert_func_token(ObProxyTokenNode *token, + ObProxyParamNode *param) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(token) || OB_ISNULL(param) || token->type_ != TOKEN_FUNC) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("fail to parse token func, param list null", K(ret), K(token->str_value_.str_)); - } else { - ObCollationType collation = ObCharset::get_default_collation(ObCharset::get_default_charset()); - target_obj.set_collation_type(collation); - - ObProxyTokenNode *param_node = token->child_->head_; - if (param_node->type_ == TOKEN_STR_VAL) { - target_obj.set_varchar(param_node->str_value_.str_, param_node->str_value_.str_len_); - } else if (param_node->type_ == TOKEN_INT_VAL) { - target_obj.set_int(param_node->int_value_); + LOG_WARN("invalid argument", K(ret)); + } + + ObString func_name(token->str_value_.str_len_, token->str_value_.str_); + ObProxyExprType func_type = get_expr_token_func_type(&func_name); + if (OB_SUCC(ret) && func_type == OB_PROXY_EXPR_TYPE_NONE) { + ret = OB_ERR_FUNCTION_UNKNOWN; + LOG_WARN("unsupported func type", K(ret), K(func_name), K(func_type)); + } + + if (OB_SUCC(ret)) { + void *tmp_buf = NULL; + param->type_ = PARAM_FUNC; + if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObFuncExprNode)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc new func expr node", K(ret)); } else { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("unexpected token node type, please check", K(ret), K(param_node->type_)); - } - - if (OB_SUCC(ret)) { - ObString nls_format; - if (param_node->next_ != NULL) { - nls_format.assign_ptr(param_node->next_->str_value_.str_, param_node->next_->str_value_.str_len_); - } - - ObTimeZoneInfo tz_info; - ObDataTypeCastParams dtc_params; + param->func_expr_node_ = new(tmp_buf) ObFuncExprNode(); + param->func_expr_node_->func_type_ = func_type; + param->func_expr_node_->child_ = NULL; - if (!nls_format.empty()) { - dtc_params.tz_info_ = &tz_info; - dtc_params.set_nls_format_by_type(target_type, nls_format); + if (OB_ISNULL(token->child_)) { + // do nothing + } else if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObProxyParamNodeList)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc new token list", K(ret)); } else { - dtc_params.tz_info_ = &tz_info; - if (OB_FAIL(ObExprCalcTool::build_dtc_params(client_session_info, target_type, dtc_params))) { - LOG_WARN("fail to build dtc params", K(ret), K(target_type)); + param->func_expr_node_->child_ = new(tmp_buf) ObProxyParamNodeList(); + ObProxyParamNode head; + ObProxyParamNode *param_cur = &head; + ObProxyTokenNode *token_child = token->child_->head_; + int64_t child_num = 0; + for (; OB_SUCC(ret) && token_child != NULL; token_child = token_child->next_, param_cur = param_cur->next_) { + if (OB_FAIL(convert_token_node_to_param_node(token_child, param_cur->next_))) { + LOG_WARN("recursive convert func token failed", K(ret)); + } else { + child_num++; + } + } + if (OB_SUCC(ret)) { + param->func_expr_node_->child_->tail_ = param_cur; + param->func_expr_node_->child_->head_ = head.next_; + param->func_expr_node_->child_->child_num_ = child_num; } - } - - ObCastCtx cast_ctx(&allocator_, &dtc_params, CM_NULL_ON_WARN, collation); - if (OB_SUCC(ret) && OB_FAIL(ObObjCasterV2::to_type(target_type, collation, cast_ctx, target_obj, target_obj))) { - LOG_WARN("fail to cast obj", K(ret), K(target_obj), K(target_type), K(collation)); } } } - return ret; } @@ -346,21 +713,21 @@ int ObExprResolver::get_obj_with_param(ObObj &target_obj, ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid placeholder idx", K(param_index), K(call_info), K(ret)); } else { - const ObProxyCallParam &call_param = call_info.params_.at(param_index); - if (CALL_TOKEN_INT_VAL == call_param.type_) { + const ObProxyCallParam* call_param = call_info.params_.at(param_index); + if (CALL_TOKEN_INT_VAL == call_param->type_) { int64_t int_val = 0; - if (OB_FAIL(get_int_value(call_param.str_value_.string_, int_val))) { - LOG_WARN("fail to get int value", K(call_param.str_value_.string_), K(ret)); + if (OB_FAIL(get_int_value(call_param->str_value_.config_string_, int_val))) { + LOG_WARN("fail to get int value", K(call_param->str_value_.config_string_), K(ret)); } else { target_obj.set_int(int_val); } - } else if (CALL_TOKEN_STR_VAL == call_param.type_) { - target_obj.set_varchar(call_param.str_value_.string_); + } else if (CALL_TOKEN_STR_VAL == call_param->type_) { + target_obj.set_varchar(call_param->str_value_.config_string_); target_obj.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); - } else if (CALL_TOKEN_PLACE_HOLDER == call_param.type_) { + } else if (CALL_TOKEN_PLACE_HOLDER == call_param->type_) { need_use_execute_param = true; - if (OB_FAIL(get_int_value(call_param.str_value_.string_, execute_param_index))) { - LOG_WARN("fail to get int value", K(call_param.str_value_.string_), K(ret)); + if (OB_FAIL(get_int_value(call_param->str_value_.config_string_, execute_param_index))) { + LOG_WARN("fail to get int value", K(call_param->str_value_.config_string_), K(ret)); } } } @@ -400,8 +767,8 @@ int ObExprResolver::get_obj_with_param(ObObj &target_obj, LOG_WARN("param index is large than param count", K(execute_param_index), K(execute_info.param_count_), K(ret)); } else { - ObProxyTextPsParam ¶m = execute_info.params_.at(execute_param_index); - ObString user_variable_name = param.str_value_.string_; + ObProxyTextPsParam* param = execute_info.params_.at(execute_param_index); + ObString user_variable_name = param->str_value_.config_string_; if (OB_FAIL(static_cast(*client_info).get_user_variable_value(user_variable_name, target_obj))) { LOG_WARN("get user variable failed", K(ret), K(user_variable_name)); } else { @@ -449,6 +816,63 @@ int ObExprResolver::get_obj_with_param(ObObj &target_obj, return ret; } +ObProxyExprType ObExprResolver::get_expr_token_func_type(ObString *func) +{ + ObProxyExprType type = OB_PROXY_EXPR_TYPE_NONE; + if (func == NULL) { + type = OB_PROXY_EXPR_TYPE_NONE; + } else if (0 == func->case_compare("HASH")) { + type = OB_PROXY_EXPR_TYPE_FUNC_HASH; + } else if (0 == func->case_compare("SUBSTR")) { + type = OB_PROXY_EXPR_TYPE_FUNC_SUBSTR; + } else if (0 == func->case_compare("CONCAT")) { + type = OB_PROXY_EXPR_TYPE_FUNC_CONCAT; + } else if (0 == func->case_compare("TOINT")) { + type = OB_PROXY_EXPR_TYPE_FUNC_TOINT; + } else if (0 == func->case_compare("DIV")) { + type = OB_PROXY_EXPR_TYPE_FUNC_DIV; + } else if (0 == func->case_compare("ADD")) { + type = OB_PROXY_EXPR_TYPE_FUNC_ADD; + } else if (0 == func->case_compare("SUB")) { + type = OB_PROXY_EXPR_TYPE_FUNC_SUB; + } else if (0 == func->case_compare("MUL")) { + type = OB_PROXY_EXPR_TYPE_FUNC_MUL; + } else if (0 == func->case_compare("SUM")) { + type = OB_PROXY_EXPR_TYPE_FUNC_SUM; + } else if (0 == func->case_compare("CONUT")) { + type = OB_PROXY_EXPR_TYPE_FUNC_COUNT; + } else if (0 == func->case_compare("MAX")) { + type = OB_PROXY_EXPR_TYPE_FUNC_MAX; + } else if (0 == func->case_compare("MIN")) { + type = OB_PROXY_EXPR_TYPE_FUNC_MIN; + } else if (0 == func->case_compare("AVG")) { + type = OB_PROXY_EXPR_TYPE_FUNC_AVG; + } else if (0 == func->case_compare("GROUP")) { + type = OB_PROXY_EXPR_TYPE_FUNC_GROUP; + } else if (0 == func->case_compare("ORDER")) { + type = OB_PROXY_EXPR_TYPE_FUNC_ORDER; + } else if (0 == func->case_compare("TESTLOAD")) { + type = OB_PROXY_EXPR_TYPE_FUNC_TESTLOAD; + } else if (0 == func->case_compare("SPLIT")) { + type = OB_PROXY_EXPR_TYPE_FUNC_SPLIT; + } else if (0 == func->case_compare("TO_DATE")) { + type = OB_PROXY_EXPR_TYPE_FUNC_TO_DATE; + } else if (0 == func->case_compare("TO_TIMESTAMP")) { + type = OB_PROXY_EXPR_TYPE_FUNC_TO_TIMESTAMP; + } else if (0 == func->case_compare("NVL")) { + type = OB_PROXY_EXPR_TYPE_FUNC_NVL; + } else if (0 == func->case_compare("TO_CHAR")) { + type = OB_PROXY_EXPR_TYPE_FUNC_TO_CHAR; + } else if (0 == func->case_compare("SYSDATE")) { + type = OB_PROXY_EXPR_TYPE_FUNC_SYSDATE; + } else if (0 == func->case_compare("MOD")) { + type = OB_PROXY_EXPR_TYPE_FUNC_MOD; + } else { + type = OB_PROXY_EXPR_TYPE_NONE; + } + return type; +} + } // end of opsql } // end of obproxy } // end of oceanbase diff --git a/src/obproxy/opsql/expr_resolver/ob_expr_resolver.h b/src/obproxy/opsql/expr_resolver/ob_expr_resolver.h index 4f7f1c38f..082b2eec2 100644 --- a/src/obproxy/opsql/expr_resolver/ob_expr_resolver.h +++ b/src/obproxy/opsql/expr_resolver/ob_expr_resolver.h @@ -25,6 +25,12 @@ class ObNewRange; } namespace obproxy { + +namespace obutils +{ +struct SqlFieldResult; +} + namespace proxy { class ObProxyPartInfo; @@ -38,7 +44,8 @@ namespace opsql struct ObExprResolverContext { ObExprResolverContext() : relation_info_(NULL), part_info_(NULL), client_request_(NULL), - ps_id_entry_(NULL), text_ps_entry_(NULL), client_info_(NULL) {} + ps_id_entry_(NULL), text_ps_entry_(NULL), client_info_(NULL), + sql_field_result_(NULL) {} // parse result ObProxyRelationInfo *relation_info_; proxy::ObProxyPartInfo *part_info_; @@ -47,6 +54,9 @@ struct ObExprResolverContext proxy::ObPsIdEntry *ps_id_entry_; proxy::ObTextPsEntry *text_ps_entry_; proxy::ObClientSessionInfo *client_info_; + obutils::SqlFieldResult *sql_field_result_; + ObExprParseResult *parse_result_; + bool is_insert_stm_; }; class ObExprResolverResult @@ -73,12 +83,21 @@ class ObExprResolver proxy::ObClientSessionInfo *client_info, proxy::ObPsIdEntry *ps_entry, proxy::ObTextPsEntry *text_ps_entry, - common::ObNewRange &range, + common::ObObj *target_obj, + obutils::SqlFieldResult *sql_field_result, const bool has_rowid = false); private: + int preprocess_range(common::ObNewRange &range, common::ObIArray &border_flags); + int place_obj_to_range(ObProxyFunctionType type, + int64_t idx_in_part_columns, + common::ObObj *target_obj, + common::ObNewRange *range, + common::ObIArray &border_flags); int calc_token_func_obj(ObProxyTokenNode *token, proxy::ObClientSessionInfo *client_session_info, - common::ObObj &target_obj); + common::ObObj &target_obj, + obutils::SqlFieldResult *sql_field_result, + const bool is_oracle_mode); int calc_generated_key_value(common::ObObj &obj, const ObProxyPartKey &part_key, const bool is_oracle_mode); int get_obj_with_param(common::ObObj &target_obj, proxy::ObProxyMysqlRequest *client_request, @@ -86,6 +105,24 @@ class ObExprResolver proxy::ObProxyPartInfo *part_info, proxy::ObPsIdEntry *ps_entry, const int64_t param_index); + int convert_token_node_to_param_node(ObProxyTokenNode *token, + ObProxyParamNode *¶m); + int recursive_convert_func_token(ObProxyTokenNode *token, + ObProxyParamNode *param); + int handle_default_value(ObProxyPartKeyInfo &part_info, + proxy::ObClientSessionInfo *client_info, + common::ObNewRange range[], + obutils::SqlFieldResult *sql_field_result, + common::ObIArray &part_border_flags, + common::ObIArray &sub_part_border_flags, + bool is_oracle_mode); + int parse_and_resolve_default_value(ObProxyParseString &default_value_expr, + proxy::ObClientSessionInfo *client_session_info, + obutils::SqlFieldResult *sql_field_result, + common::ObObj *target_obj, + bool is_oracle_mode); + + ObProxyExprType get_expr_token_func_type(common::ObString *func); common::ObIAllocator &allocator_; DISALLOW_COPY_AND_ASSIGN(ObExprResolver); diff --git a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser.l b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser.l index 06aef3ab9..420b291eb 100644 --- a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser.l +++ b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser.l @@ -63,8 +63,11 @@ do {\ space [ \t\n\r\f] identifer ([A-Za-z0-9$_]*) -int_num [\-\+]?[0-9]+ -number ([0-9]+E[-+]?[0-9]+)|([0-9]+"."[0-9]*E[-+]?[0-9]+)|("."[0-9]+E[-+]?[0-9]+)|([0-9]+"."[0-9]*)|("."[0-9]+) + +/* limit the length of int_num from 1 to 17 in case of int64_t out of bound, 17 -> [ ( length of 2^64 ) - 2 ]*/ +int_num [\-\+]?[0-9]{1,17} +number ([\-]?[0-9]+E[-+]?[0-9]+)|([\-]?[0-9]+"."[0-9]*E[-+]?[0-9]+)|([\-]?"."[0-9]+E[-+]?[0-9]+)|([\-]?[0-9]+"."[0-9]*)|([\-]?"."[0-9]+)|([\-\+]?[0-9]{18,}) + whitespace ({space}+) c_cmt_begin \/\* @@ -97,16 +100,22 @@ rightbracket \) endtoken \# %% -substr { return FUNC_SUBSTR; } -substring { return FUNC_SUBSTR; } -concat { return FUNC_CONCAT; } -hash { return FUNC_HASH; } -toint { return FUNC_TOINT; } -div { return FUNC_DIV; } -add { return FUNC_ADD; } -sub { return FUNC_SUB; } -mul { return FUNC_MUL; } -testload { return FUNC_TESTLOAD; } +substr { return FUNC_SUBSTR; } +substring { return FUNC_SUBSTR; } +concat { return FUNC_CONCAT; } +hash { return FUNC_HASH; } +toint { return FUNC_TOINT; } +div { return FUNC_DIV; } +add { return FUNC_ADD; } +sub { return FUNC_SUB; } +mul { return FUNC_MUL; } +testload { return FUNC_TESTLOAD; } +to_date { return FUNC_TO_DATE; } +to_timestamp { return FUNC_TO_TIMESTAMP; } +nvl { return FUNC_NVL; } +to_char { return FUNC_TO_CHAR; } +mod { return FUNC_MOD; } +sysdate { return FUNC_SYSDATE; } {endtoken} { return TOKEN_SPECIAL; } diff --git a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser.y b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser.y index db953fa1a..5e32e90e3 100644 --- a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser.y +++ b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser.y @@ -83,11 +83,12 @@ static inline void add_param_node(ObProxyParamNodeList *list, ObFuncExprParseRes %token DUMMY_FUNCTION_CLAUSE /* reserved keyword */ %token TOKEN_SPECIAL FUNC_SUBSTR FUNC_CONCAT FUNC_HASH FUNC_TOINT FUNC_DIV FUNC_ADD FUNC_SUB FUNC_MUL FUNC_TESTLOAD +%token FUNC_TO_DATE FUNC_TO_TIMESTAMP FUNC_NVL FUNC_TO_CHAR FUNC_MOD FUNC_SYSDATE %token END_P ERROR IGNORED_WORD /* type token */ %token NAME_OB STR_VAL NUMBER_VAL %token INT_VAL -%type func_name +%type func_name reserved_func %type param_list %type func_expr %type param @@ -113,6 +114,11 @@ func_expr: func_name '(' param_list ')' malloc_func_expr_node($$, result, $1); $$->child_ = NULL; } + | reserved_func + { + malloc_func_expr_node($$, result, $1); + $$->child_ = NULL; + } func_name: FUNC_SUBSTR { $$ = OB_PROXY_EXPR_TYPE_FUNC_SUBSTR; } | FUNC_CONCAT { $$ = OB_PROXY_EXPR_TYPE_FUNC_CONCAT; } @@ -123,6 +129,13 @@ func_name: FUNC_SUBSTR { $$ = OB_PROXY_EXPR_TYPE_FUNC_SUBSTR; } | FUNC_SUB { $$ = OB_PROXY_EXPR_TYPE_FUNC_SUB; } | FUNC_MUL { $$ = OB_PROXY_EXPR_TYPE_FUNC_MUL; } | FUNC_TESTLOAD { $$ = OB_PROXY_EXPR_TYPE_FUNC_TESTLOAD; } + | FUNC_TO_DATE { $$ = OB_PROXY_EXPR_TYPE_FUNC_TO_DATE; } + | FUNC_TO_TIMESTAMP { $$ = OB_PROXY_EXPR_TYPE_FUNC_TO_TIMESTAMP; } + | FUNC_NVL { $$ = OB_PROXY_EXPR_TYPE_FUNC_NVL; } + | FUNC_TO_CHAR { $$ = OB_PROXY_EXPR_TYPE_FUNC_TO_CHAR; } + | FUNC_MOD { $$ = OB_PROXY_EXPR_TYPE_FUNC_MOD; } + +reserved_func: FUNC_SYSDATE { $$ = OB_PROXY_EXPR_TYPE_FUNC_SYSDATE; } param_list: param { diff --git a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_lex.c b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_lex.c index 0a5152330..3580edb3c 100644 --- a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_lex.c +++ b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_lex.c @@ -348,8 +348,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); yyg->yy_hold_char = *yy_cp; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 41 -#define YY_END_OF_BUFFER 42 +#define YY_NUM_RULES 47 +#define YY_END_OF_BUFFER 48 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -357,21 +357,30 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[115] = +static yyconst flex_int16_t yy_accept[201] = { 0, - 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, - 42, 40, 18, 18, 19, 30, 11, 14, 24, 19, - 19, 19, 12, 14, 14, 14, 14, 14, 14, 14, - 36, 23, 22, 23, 25, 26, 41, 31, 32, 41, - 38, 39, 18, 16, 0, 14, 0, 15, 12, 13, - 20, 13, 12, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 0, 17, 0, 21, 25, 0, 27, 28, - 31, 0, 33, 34, 38, 37, 0, 13, 0, 0, - 13, 7, 14, 6, 14, 9, 8, 14, 14, 29, - 35, 0, 13, 0, 13, 13, 14, 4, 14, 14, - - 14, 14, 14, 14, 5, 3, 1, 14, 14, 14, - 14, 10, 2, 0 + 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 46, 24, 24, 25, 36, 17, 20, 30, 25, + 25, 25, 25, 18, 20, 20, 20, 20, 20, 20, + 20, 20, 42, 29, 28, 29, 31, 32, 47, 37, + 38, 47, 44, 45, 24, 22, 0, 20, 0, 21, + 18, 0, 18, 19, 26, 19, 18, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, + 23, 0, 27, 31, 0, 33, 34, 37, 0, 39, + 40, 44, 43, 18, 18, 0, 0, 19, 0, 18, + 0, 19, 7, 20, 6, 20, 15, 9, 13, 8, + + 20, 20, 20, 20, 35, 41, 18, 18, 19, 0, + 19, 0, 19, 18, 20, 4, 20, 20, 20, 20, + 20, 20, 20, 18, 18, 18, 20, 20, 20, 20, + 5, 20, 20, 20, 18, 18, 18, 3, 1, 20, + 20, 20, 20, 20, 18, 18, 18, 20, 16, 20, + 14, 11, 20, 18, 18, 18, 20, 10, 20, 18, + 18, 18, 2, 20, 18, 18, 18, 20, 18, 18, + 18, 20, 18, 18, 18, 12, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 19, 19, 19, 19, 19, 19, 0 + } ; static yyconst flex_int32_t yy_ec[256] = @@ -380,16 +389,16 @@ static yyconst flex_int32_t yy_ec[256] = 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 5, 6, 7, 4, 4, 8, 4, - 4, 9, 10, 4, 10, 11, 12, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 4, 4, 1, - 4, 1, 4, 4, 14, 15, 16, 17, 18, 7, - 19, 20, 21, 7, 7, 22, 23, 24, 25, 7, - 7, 26, 27, 28, 29, 30, 7, 7, 7, 7, - 1, 31, 1, 4, 7, 32, 33, 34, 35, 36, - - 37, 7, 38, 39, 40, 7, 7, 41, 42, 43, - 44, 7, 7, 45, 46, 47, 48, 49, 7, 7, - 7, 7, 1, 4, 1, 4, 1, 1, 1, 1, + 4, 9, 10, 4, 11, 12, 13, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 4, 4, 1, + 4, 1, 4, 4, 15, 16, 17, 18, 19, 7, + 20, 21, 22, 7, 7, 23, 24, 25, 26, 27, + 7, 28, 29, 30, 31, 32, 7, 7, 33, 7, + 1, 34, 1, 4, 35, 36, 37, 38, 39, 40, + + 41, 7, 42, 43, 44, 7, 7, 45, 46, 47, + 48, 49, 7, 50, 51, 52, 53, 54, 7, 7, + 55, 7, 1, 4, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -406,123 +415,202 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[50] = +static yyconst flex_int32_t yy_meta[56] = { 0, 1, 1, 1, 1, 2, 1, 3, 4, 1, 1, - 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, + 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 5, 3, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 5, 6, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3 + 3, 3, 3, 3, 3 } ; -static yyconst flex_int16_t yy_base[128] = +static yyconst flex_int16_t yy_base[214] = { 0, - 0, 0, 47, 48, 44, 45, 49, 50, 217, 216, - 247, 250, 56, 58, 250, 241, 250, 0, 237, 231, - 230, 233, 51, 46, 40, 45, 53, 39, 41, 53, - 209, 250, 250, 65, 0, 90, 0, 0, 97, 0, - 0, 208, 70, 250, 234, 0, 230, 250, 212, 78, - 250, 88, 92, 94, 77, 71, 78, 82, 89, 97, - 89, 96, 190, 250, 109, 250, 0, 130, 250, 250, - 0, 117, 250, 250, 0, 250, 113, 121, 127, 200, - 199, 0, 108, 0, 121, 0, 115, 116, 121, 250, - 250, 194, 193, 149, 146, 70, 132, 0, 119, 126, - - 121, 122, 125, 127, 0, 0, 132, 140, 131, 139, - 138, 0, 0, 250, 176, 182, 188, 194, 199, 76, - 200, 202, 208, 214, 220, 226, 232 + 0, 0, 53, 54, 50, 51, 55, 56, 384, 382, + 415, 508, 62, 64, 508, 403, 508, 0, 398, 389, + 56, 388, 390, 57, 54, 47, 52, 60, 51, 46, + 48, 61, 361, 508, 508, 79, 0, 103, 0, 0, + 105, 0, 0, 342, 110, 508, 369, 0, 365, 508, + 358, 351, 102, 101, 508, 103, 111, 117, 100, 94, + 92, 97, 111, 109, 110, 118, 106, 107, 115, 328, + 508, 136, 508, 0, 158, 508, 508, 0, 160, 508, + 508, 0, 508, 345, 155, 161, 166, 154, 168, 169, + 341, 340, 0, 147, 0, 149, 0, 0, 0, 155, + + 167, 157, 164, 173, 508, 508, 335, 185, 331, 328, + 326, 319, 317, 186, 178, 0, 164, 186, 179, 178, + 193, 202, 196, 316, 219, 223, 189, 193, 192, 202, + 0, 214, 202, 210, 314, 233, 234, 0, 227, 236, + 242, 230, 240, 242, 308, 251, 254, 237, 0, 249, + 0, 0, 240, 307, 274, 282, 256, 0, 248, 288, + 285, 291, 0, 270, 273, 294, 297, 266, 268, 305, + 306, 287, 258, 315, 325, 0, 206, 329, 338, 139, + 339, 348, 133, 349, 357, 125, 363, 369, 124, 372, + 373, 79, 381, 382, 77, 393, 397, 72, 405, 508, + + 446, 452, 458, 464, 469, 80, 470, 472, 478, 484, + 490, 496, 502 } ; -static yyconst flex_int16_t yy_def[128] = +static yyconst flex_int16_t yy_def[214] = { 0, - 114, 1, 115, 115, 116, 116, 117, 117, 118, 118, - 114, 114, 114, 114, 114, 119, 114, 120, 121, 114, - 114, 114, 120, 120, 120, 120, 120, 120, 120, 120, - 122, 114, 114, 114, 123, 114, 124, 125, 114, 126, - 127, 114, 114, 114, 119, 120, 121, 114, 114, 114, - 114, 114, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 122, 114, 114, 114, 123, 114, 114, 114, - 125, 114, 114, 114, 127, 114, 114, 114, 114, 114, - 120, 120, 120, 120, 120, 120, 120, 120, 120, 114, - 114, 114, 114, 114, 114, 114, 120, 120, 120, 120, - - 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 0, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114 + 200, 1, 201, 201, 202, 202, 203, 203, 204, 204, + 200, 200, 200, 200, 200, 205, 200, 206, 207, 200, + 200, 200, 200, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 208, 200, 200, 200, 209, 200, 210, 211, + 200, 212, 213, 200, 200, 200, 205, 206, 207, 200, + 200, 200, 200, 200, 200, 200, 206, 206, 206, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 208, + 200, 200, 200, 209, 200, 200, 200, 211, 200, 200, + 200, 213, 200, 200, 200, 200, 200, 200, 200, 206, + 200, 206, 206, 206, 206, 206, 206, 206, 206, 206, + + 206, 206, 206, 206, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, 200, 200, 206, 206, 206, 206, 206, + 206, 206, 206, 206, 200, 200, 206, 206, 206, 206, + 206, 206, 206, 206, 200, 200, 206, 206, 206, 206, + 206, 206, 206, 200, 200, 206, 206, 206, 206, 200, + 200, 206, 206, 206, 200, 200, 206, 206, 200, 200, + 206, 206, 200, 200, 206, 206, 200, 200, 206, 200, + 200, 206, 200, 200, 206, 200, 200, 206, 200, 200, + 206, 200, 200, 206, 200, 200, 206, 200, 200, 0, + + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200 } ; -static yyconst flex_int16_t yy_nxt[300] = +static yyconst flex_int16_t yy_nxt[564] = { 0, 12, 13, 14, 15, 16, 17, 18, 19, 15, 20, - 21, 22, 23, 24, 18, 25, 26, 18, 18, 27, - 18, 18, 28, 18, 18, 18, 29, 30, 18, 18, - 12, 31, 24, 18, 25, 26, 18, 18, 27, 18, - 18, 28, 18, 18, 18, 29, 30, 18, 18, 33, - 33, 36, 36, 39, 39, 34, 34, 43, 43, 43, - 43, 52, 55, 53, 56, 57, 58, 59, 54, 60, - 61, 43, 43, 65, 37, 37, 66, 62, 46, 40, - 40, 55, 96, 56, 57, 58, 59, 54, 60, 61, - 50, 68, 68, 82, 83, 77, 62, 69, 72, 72, - - 78, 73, 52, 80, 53, 79, 81, 84, 85, 54, - 86, 87, 82, 83, 77, 88, 89, 65, 72, 72, - 66, 91, 92, 97, 79, 93, 84, 85, 54, 86, - 87, 68, 68, 78, 88, 89, 94, 90, 79, 95, - 98, 99, 97, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 79, 95, 98, - 99, 95, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 32, 32, 32, 32, - 32, 32, 35, 35, 35, 35, 35, 35, 38, 38, - 38, 38, 38, 38, 41, 41, 41, 41, 41, 41, - - 45, 45, 47, 47, 63, 93, 93, 63, 67, 67, - 67, 81, 96, 67, 70, 70, 70, 70, 70, 70, - 71, 64, 71, 71, 49, 71, 74, 74, 74, 74, - 74, 74, 75, 75, 75, 75, 75, 48, 44, 76, - 64, 51, 50, 49, 48, 44, 114, 42, 42, 11, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114 - + 21, 22, 23, 24, 25, 18, 26, 27, 18, 18, + 28, 18, 18, 29, 30, 18, 18, 18, 31, 32, + 18, 18, 18, 12, 18, 33, 25, 18, 26, 27, + 18, 18, 28, 18, 18, 29, 30, 18, 18, 18, + 31, 32, 18, 18, 18, 35, 35, 38, 38, 41, + 41, 36, 36, 45, 45, 45, 45, 52, 56, 53, + 57, 59, 60, 61, 62, 58, 63, 65, 66, 68, + 67, 64, 48, 39, 39, 198, 69, 72, 42, 42, + 198, 73, 195, 59, 60, 61, 62, 58, 63, 65, + + 66, 68, 67, 64, 75, 75, 79, 79, 69, 80, + 76, 45, 45, 56, 54, 85, 88, 93, 94, 87, + 86, 89, 56, 95, 90, 96, 91, 91, 97, 58, + 92, 98, 99, 100, 101, 102, 103, 192, 189, 93, + 94, 87, 86, 89, 72, 95, 186, 96, 73, 104, + 97, 58, 183, 98, 99, 100, 101, 102, 103, 75, + 75, 79, 79, 115, 106, 105, 56, 88, 108, 116, + 91, 91, 89, 86, 109, 110, 110, 112, 112, 111, + 56, 113, 114, 117, 118, 115, 119, 58, 120, 121, + 122, 116, 127, 128, 89, 86, 56, 56, 125, 126, + + 129, 130, 123, 86, 58, 117, 118, 131, 119, 58, + 120, 121, 122, 132, 127, 128, 133, 134, 138, 180, + 139, 140, 129, 130, 123, 86, 58, 141, 142, 131, + 56, 143, 136, 144, 56, 132, 137, 86, 133, 134, + 138, 58, 139, 140, 56, 56, 146, 147, 148, 141, + 142, 86, 58, 143, 149, 144, 150, 151, 152, 86, + 153, 157, 56, 58, 155, 56, 158, 156, 159, 86, + 148, 177, 58, 86, 58, 163, 149, 164, 150, 151, + 152, 173, 153, 157, 168, 56, 169, 161, 158, 172, + 159, 86, 86, 56, 58, 162, 56, 163, 166, 164, + + 58, 165, 56, 86, 167, 56, 168, 170, 56, 58, + 171, 172, 86, 176, 86, 58, 56, 56, 174, 175, + 160, 154, 58, 86, 58, 86, 56, 145, 178, 135, + 113, 58, 113, 86, 86, 176, 56, 58, 179, 111, + 56, 111, 181, 58, 109, 86, 58, 86, 124, 56, + 56, 182, 184, 92, 109, 86, 58, 86, 107, 56, + 56, 185, 187, 71, 54, 58, 58, 86, 56, 86, + 188, 84, 50, 46, 56, 58, 190, 83, 58, 86, + 56, 86, 191, 56, 56, 193, 194, 58, 58, 86, + 86, 58, 56, 56, 196, 197, 71, 58, 55, 86, + + 58, 54, 51, 86, 56, 50, 199, 46, 56, 58, + 197, 86, 86, 58, 200, 58, 56, 44, 199, 44, + 200, 86, 58, 86, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 86, 200, 200, 200, 58, 200, 200, + 200, 200, 200, 200, 200, 86, 34, 34, 34, 34, + 34, 34, 37, 37, 37, 37, 37, 37, 40, 40, + 40, 40, 40, 40, 43, 43, 43, 43, 43, 43, + 47, 47, 49, 49, 70, 200, 200, 70, 74, 74, + 74, 200, 200, 74, 77, 77, 77, 77, 77, 77, + 78, 200, 78, 78, 200, 78, 81, 81, 81, 81, + + 81, 81, 82, 82, 82, 82, 82, 11, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200 } ; -static yyconst flex_int16_t yy_chk[300] = +static yyconst flex_int16_t yy_chk[564] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, - 4, 5, 6, 7, 8, 3, 4, 13, 13, 14, - 14, 23, 24, 23, 25, 26, 27, 28, 23, 29, - 30, 43, 43, 34, 5, 6, 34, 30, 120, 7, - 8, 24, 96, 25, 26, 27, 28, 23, 29, 30, - 50, 36, 36, 55, 56, 50, 30, 36, 39, 39, - - 52, 39, 53, 54, 53, 52, 54, 57, 58, 53, - 59, 60, 55, 56, 50, 61, 62, 65, 72, 72, - 65, 72, 77, 83, 52, 77, 57, 58, 53, 59, - 60, 68, 68, 78, 61, 62, 79, 68, 78, 79, - 85, 87, 83, 88, 89, 97, 99, 100, 101, 102, - 103, 104, 107, 108, 109, 110, 111, 78, 95, 85, - 87, 94, 88, 89, 97, 99, 100, 101, 102, 103, - 104, 107, 108, 109, 110, 111, 115, 115, 115, 115, - 115, 115, 116, 116, 116, 116, 116, 116, 117, 117, - 117, 117, 117, 117, 118, 118, 118, 118, 118, 118, - - 119, 119, 121, 121, 122, 93, 92, 122, 123, 123, - 123, 81, 80, 123, 124, 124, 124, 124, 124, 124, - 125, 63, 125, 125, 49, 125, 126, 126, 126, 126, - 126, 126, 127, 127, 127, 127, 127, 47, 45, 42, - 31, 22, 21, 20, 19, 16, 11, 10, 9, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114 - + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 3, 4, 5, 6, 7, + 8, 3, 4, 13, 13, 14, 14, 21, 24, 21, + 24, 25, 26, 27, 28, 24, 29, 30, 31, 32, + 31, 29, 206, 5, 6, 198, 32, 36, 7, 8, + 195, 36, 192, 25, 26, 27, 28, 24, 29, 30, + + 31, 32, 31, 29, 38, 38, 41, 41, 32, 41, + 38, 45, 45, 53, 54, 53, 56, 59, 60, 54, + 53, 56, 57, 61, 57, 62, 58, 58, 63, 57, + 58, 64, 65, 66, 67, 68, 69, 189, 186, 59, + 60, 54, 53, 56, 72, 61, 183, 62, 72, 69, + 63, 57, 180, 64, 65, 66, 67, 68, 69, 75, + 75, 79, 79, 94, 79, 75, 85, 88, 85, 96, + 86, 86, 88, 85, 86, 87, 87, 89, 89, 87, + 90, 89, 90, 100, 101, 94, 102, 90, 103, 104, + 104, 96, 115, 117, 88, 85, 108, 114, 108, 114, + + 118, 119, 104, 108, 114, 100, 101, 120, 102, 90, + 103, 104, 104, 121, 115, 117, 122, 123, 127, 177, + 128, 129, 118, 119, 104, 108, 114, 130, 132, 120, + 125, 133, 125, 134, 126, 121, 126, 125, 122, 123, + 127, 126, 128, 129, 136, 137, 136, 137, 139, 130, + 132, 136, 137, 133, 140, 134, 141, 142, 143, 125, + 144, 148, 146, 126, 146, 147, 150, 147, 153, 146, + 139, 173, 147, 136, 137, 157, 140, 159, 141, 142, + 143, 169, 144, 148, 164, 155, 165, 155, 150, 168, + 153, 146, 155, 156, 147, 156, 161, 157, 161, 159, + + 156, 160, 162, 161, 162, 166, 164, 166, 167, 162, + 167, 168, 166, 172, 155, 167, 170, 171, 170, 171, + 154, 145, 156, 170, 171, 161, 174, 135, 174, 124, + 113, 162, 112, 174, 166, 172, 175, 167, 175, 111, + 178, 110, 178, 175, 109, 170, 171, 178, 107, 179, + 181, 179, 181, 92, 91, 174, 179, 181, 84, 182, + 184, 182, 184, 70, 52, 175, 182, 184, 185, 178, + 185, 51, 49, 47, 187, 185, 187, 44, 179, 181, + 188, 187, 188, 190, 191, 190, 191, 188, 182, 184, + 190, 191, 193, 194, 193, 194, 33, 185, 23, 193, + + 194, 22, 20, 187, 196, 19, 196, 16, 197, 188, + 197, 196, 190, 191, 11, 197, 199, 10, 199, 9, + 0, 193, 194, 199, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 196, 0, 0, 0, 197, 0, 0, + 0, 0, 0, 0, 0, 199, 201, 201, 201, 201, + 201, 201, 202, 202, 202, 202, 202, 202, 203, 203, + 203, 203, 203, 203, 204, 204, 204, 204, 204, 204, + 205, 205, 207, 207, 208, 0, 0, 208, 209, 209, + 209, 0, 0, 209, 210, 210, 210, 210, 210, 210, + 211, 0, 211, 211, 0, 211, 212, 212, 212, 212, + + 212, 212, 213, 213, 213, 213, 213, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200 } ; /* The intent behind this definition is that it'll catch @@ -590,7 +678,8 @@ do {\ -#line 595 "ob_func_expr_parser_lex.c" +/* limit the length of int_num from 1 to 17 in case of int64_t out of bound, 17 -> [ ( length of 2^64 ) - 2 ]*/ +#line 684 "ob_func_expr_parser_lex.c" #define INITIAL 0 #define in_c_comment 1 @@ -838,9 +927,9 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 99 "ob_func_expr_parser.l" +#line 102 "ob_func_expr_parser.l" -#line 846 "ob_func_expr_parser_lex.c" +#line 935 "ob_func_expr_parser_lex.c" yylval = yylval_param; @@ -897,13 +986,13 @@ YY_DECL while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 115 ) + if ( yy_current_state >= 201 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 250 ); + while ( yy_base[yy_current_state] != 508 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -929,126 +1018,156 @@ YY_DECL case 1: YY_RULE_SETUP -#line 100 "ob_func_expr_parser.l" +#line 103 "ob_func_expr_parser.l" { return FUNC_SUBSTR; } YY_BREAK case 2: YY_RULE_SETUP -#line 101 "ob_func_expr_parser.l" +#line 104 "ob_func_expr_parser.l" { return FUNC_SUBSTR; } YY_BREAK case 3: YY_RULE_SETUP -#line 102 "ob_func_expr_parser.l" +#line 105 "ob_func_expr_parser.l" { return FUNC_CONCAT; } YY_BREAK case 4: YY_RULE_SETUP -#line 103 "ob_func_expr_parser.l" +#line 106 "ob_func_expr_parser.l" { return FUNC_HASH; } YY_BREAK case 5: YY_RULE_SETUP -#line 104 "ob_func_expr_parser.l" +#line 107 "ob_func_expr_parser.l" { return FUNC_TOINT; } YY_BREAK case 6: YY_RULE_SETUP -#line 105 "ob_func_expr_parser.l" +#line 108 "ob_func_expr_parser.l" { return FUNC_DIV; } YY_BREAK case 7: YY_RULE_SETUP -#line 106 "ob_func_expr_parser.l" +#line 109 "ob_func_expr_parser.l" { return FUNC_ADD; } YY_BREAK case 8: YY_RULE_SETUP -#line 107 "ob_func_expr_parser.l" +#line 110 "ob_func_expr_parser.l" { return FUNC_SUB; } YY_BREAK case 9: YY_RULE_SETUP -#line 108 "ob_func_expr_parser.l" +#line 111 "ob_func_expr_parser.l" { return FUNC_MUL; } YY_BREAK case 10: YY_RULE_SETUP -#line 109 "ob_func_expr_parser.l" +#line 112 "ob_func_expr_parser.l" { return FUNC_TESTLOAD; } YY_BREAK case 11: YY_RULE_SETUP -#line 111 "ob_func_expr_parser.l" -{ return TOKEN_SPECIAL; } +#line 113 "ob_func_expr_parser.l" +{ return FUNC_TO_DATE; } YY_BREAK case 12: YY_RULE_SETUP -#line 113 "ob_func_expr_parser.l" -{ RETURN_INT_VAL(); } +#line 114 "ob_func_expr_parser.l" +{ return FUNC_TO_TIMESTAMP; } YY_BREAK case 13: YY_RULE_SETUP -#line 114 "ob_func_expr_parser.l" -{ RETURN_NUMBER_VAL(); } +#line 115 "ob_func_expr_parser.l" +{ return FUNC_NVL; } YY_BREAK case 14: YY_RULE_SETUP -#line 115 "ob_func_expr_parser.l" -{ RETURN_NAME_OB(); } +#line 116 "ob_func_expr_parser.l" +{ return FUNC_TO_CHAR; } YY_BREAK case 15: YY_RULE_SETUP -#line 116 "ob_func_expr_parser.l" -{ RETURN_NAME_OB_WITH_QUOTE(OBPROXY_QUOTE_T_SINGLE); } +#line 117 "ob_func_expr_parser.l" +{ return FUNC_MOD; } YY_BREAK case 16: YY_RULE_SETUP -#line 117 "ob_func_expr_parser.l" -{ RETURN_NAME_OB_WITH_QUOTE(OBPROXY_QUOTE_T_DOUBLE); } +#line 118 "ob_func_expr_parser.l" +{ return FUNC_SYSDATE; } YY_BREAK case 17: YY_RULE_SETUP -#line 118 "ob_func_expr_parser.l" -{ RETURN_NAME_OB_WITH_QUOTE(OBPROXY_QUOTE_T_BACK); } +#line 120 "ob_func_expr_parser.l" +{ return TOKEN_SPECIAL; } YY_BREAK case 18: -/* rule 18 can match eol */ YY_RULE_SETUP -#line 119 "ob_func_expr_parser.l" -{ } +#line 122 "ob_func_expr_parser.l" +{ RETURN_INT_VAL(); } YY_BREAK case 19: YY_RULE_SETUP -#line 120 "ob_func_expr_parser.l" +#line 123 "ob_func_expr_parser.l" +{ RETURN_NUMBER_VAL(); } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 124 "ob_func_expr_parser.l" +{ RETURN_NAME_OB(); } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 125 "ob_func_expr_parser.l" +{ RETURN_NAME_OB_WITH_QUOTE(OBPROXY_QUOTE_T_SINGLE); } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 126 "ob_func_expr_parser.l" +{ RETURN_NAME_OB_WITH_QUOTE(OBPROXY_QUOTE_T_DOUBLE); } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 127 "ob_func_expr_parser.l" +{ RETURN_NAME_OB_WITH_QUOTE(OBPROXY_QUOTE_T_BACK); } + YY_BREAK +case 24: +/* rule 24 can match eol */ +YY_RULE_SETUP +#line 128 "ob_func_expr_parser.l" +{ } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 129 "ob_func_expr_parser.l" { return yytext[0]; } YY_BREAK /* comment */ -case 20: +case 26: YY_RULE_SETUP -#line 123 "ob_func_expr_parser.l" +#line 132 "ob_func_expr_parser.l" { PUSH_STATE(in_c_comment); } YY_BREAK -case 21: +case 27: YY_RULE_SETUP -#line 124 "ob_func_expr_parser.l" +#line 133 "ob_func_expr_parser.l" { POP_STATE(); } YY_BREAK -case 22: -/* rule 22 can match eol */ +case 28: +/* rule 28 can match eol */ YY_RULE_SETUP -#line 125 "ob_func_expr_parser.l" +#line 134 "ob_func_expr_parser.l" {} YY_BREAK -case 23: +case 29: YY_RULE_SETUP -#line 126 "ob_func_expr_parser.l" +#line 135 "ob_func_expr_parser.l" {} YY_BREAK /* quote */ -case 24: +case 30: YY_RULE_SETUP -#line 129 "ob_func_expr_parser.l" +#line 138 "ob_func_expr_parser.l" { PUSH_STATE(sq); ObFuncExprParseResult *p = (ObFuncExprParseResult *)yyextra; @@ -1059,10 +1178,10 @@ YY_RULE_SETUP } } YY_BREAK -case 25: -/* rule 25 can match eol */ +case 31: +/* rule 31 can match eol */ YY_RULE_SETUP -#line 139 "ob_func_expr_parser.l" +#line 148 "ob_func_expr_parser.l" { ObFuncExprParseResult *p = (ObFuncExprParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -1070,9 +1189,9 @@ YY_RULE_SETUP } } YY_BREAK -case 26: +case 32: YY_RULE_SETUP -#line 146 "ob_func_expr_parser.l" +#line 155 "ob_func_expr_parser.l" { POP_STATE(); ObFuncExprParseResult *p = (ObFuncExprParseResult *)yyextra; @@ -1082,31 +1201,31 @@ YY_RULE_SETUP return STR_VAL; } YY_BREAK -case 27: +case 33: YY_RULE_SETUP -#line 155 "ob_func_expr_parser.l" +#line 164 "ob_func_expr_parser.l" {} YY_BREAK -case 28: -/* rule 28 can match eol */ +case 34: +/* rule 34 can match eol */ YY_RULE_SETUP -#line 156 "ob_func_expr_parser.l" +#line 165 "ob_func_expr_parser.l" {} YY_BREAK -case 29: -/* rule 29 can match eol */ +case 35: +/* rule 35 can match eol */ YY_RULE_SETUP -#line 157 "ob_func_expr_parser.l" +#line 166 "ob_func_expr_parser.l" {} YY_BREAK case YY_STATE_EOF(sq): -#line 158 "ob_func_expr_parser.l" +#line 167 "ob_func_expr_parser.l" { return ERROR; } YY_BREAK /* dquote */ -case 30: +case 36: YY_RULE_SETUP -#line 162 "ob_func_expr_parser.l" +#line 171 "ob_func_expr_parser.l" { PUSH_STATE(dq); ObFuncExprParseResult *p = (ObFuncExprParseResult *)yyextra; @@ -1117,10 +1236,10 @@ YY_RULE_SETUP } } YY_BREAK -case 31: -/* rule 31 can match eol */ +case 37: +/* rule 37 can match eol */ YY_RULE_SETUP -#line 172 "ob_func_expr_parser.l" +#line 181 "ob_func_expr_parser.l" { ObFuncExprParseResult *p = (ObFuncExprParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -1128,9 +1247,9 @@ YY_RULE_SETUP } } YY_BREAK -case 32: +case 38: YY_RULE_SETUP -#line 179 "ob_func_expr_parser.l" +#line 188 "ob_func_expr_parser.l" { POP_STATE(); ObFuncExprParseResult *p = (ObFuncExprParseResult *)yyextra; @@ -1140,31 +1259,31 @@ YY_RULE_SETUP return STR_VAL; } YY_BREAK -case 33: +case 39: YY_RULE_SETUP -#line 188 "ob_func_expr_parser.l" +#line 197 "ob_func_expr_parser.l" {} YY_BREAK -case 34: -/* rule 34 can match eol */ +case 40: +/* rule 40 can match eol */ YY_RULE_SETUP -#line 189 "ob_func_expr_parser.l" +#line 198 "ob_func_expr_parser.l" {} YY_BREAK -case 35: -/* rule 35 can match eol */ +case 41: +/* rule 41 can match eol */ YY_RULE_SETUP -#line 190 "ob_func_expr_parser.l" +#line 199 "ob_func_expr_parser.l" {} YY_BREAK case YY_STATE_EOF(dq): -#line 191 "ob_func_expr_parser.l" +#line 200 "ob_func_expr_parser.l" { return ERROR; } YY_BREAK /* backtick */ -case 36: +case 42: YY_RULE_SETUP -#line 195 "ob_func_expr_parser.l" +#line 204 "ob_func_expr_parser.l" { PUSH_STATE(bt); ObFuncExprParseResult *p = (ObFuncExprParseResult *)yyextra; @@ -1175,9 +1294,9 @@ YY_RULE_SETUP } } YY_BREAK -case 37: +case 43: YY_RULE_SETUP -#line 205 "ob_func_expr_parser.l" +#line 214 "ob_func_expr_parser.l" { ObFuncExprParseResult *p = (ObFuncExprParseResult *)yyextra; if (NULL != p && NULL != p->tmp_buf_ && p->tmp_len_ + 1 < OBPROXY_MAX_NAME_LENGTH) { @@ -1185,10 +1304,10 @@ YY_RULE_SETUP } } YY_BREAK -case 38: -/* rule 38 can match eol */ +case 44: +/* rule 44 can match eol */ YY_RULE_SETUP -#line 212 "ob_func_expr_parser.l" +#line 221 "ob_func_expr_parser.l" { ObFuncExprParseResult *p = (ObFuncExprParseResult *)yyextra; if (NULL != p && NULL != p->tmp_buf_ && p->tmp_len_ + yyleng < OBPROXY_MAX_NAME_LENGTH) { @@ -1197,9 +1316,9 @@ YY_RULE_SETUP } } YY_BREAK -case 39: +case 45: YY_RULE_SETUP -#line 220 "ob_func_expr_parser.l" +#line 229 "ob_func_expr_parser.l" { POP_STATE(); ObFuncExprParseResult *p = (ObFuncExprParseResult *)yyextra; @@ -1212,27 +1331,27 @@ YY_RULE_SETUP } YY_BREAK case YY_STATE_EOF(bt): -#line 231 "ob_func_expr_parser.l" +#line 240 "ob_func_expr_parser.l" { return ERROR; } YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(in_c_comment): -#line 235 "ob_func_expr_parser.l" +#line 244 "ob_func_expr_parser.l" { return END_P; } YY_BREAK -case 40: +case 46: YY_RULE_SETUP -#line 236 "ob_func_expr_parser.l" +#line 245 "ob_func_expr_parser.l" { return IGNORED_WORD; } YY_BREAK -case 41: +case 47: YY_RULE_SETUP -#line 237 "ob_func_expr_parser.l" +#line 246 "ob_func_expr_parser.l" ECHO; YY_BREAK -#line 1238 "ob_func_expr_parser_lex.c" +#line 1357 "ob_func_expr_parser_lex.c" case YY_END_OF_BUFFER: { @@ -1524,7 +1643,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 115 ) + if ( yy_current_state >= 201 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1553,11 +1672,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 115 ) + if ( yy_current_state >= 201 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 114); + yy_is_jam = (yy_current_state == 200); return yy_is_jam ? 0 : yy_current_state; } @@ -2382,7 +2501,7 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 237 "ob_func_expr_parser.l" +#line 246 "ob_func_expr_parser.l" @@ -2511,13 +2630,19 @@ extern int obfuncexprdebug; FUNC_SUB = 266, FUNC_MUL = 267, FUNC_TESTLOAD = 268, - END_P = 269, - ERROR = 270, - IGNORED_WORD = 271, - NAME_OB = 272, - STR_VAL = 273, - NUMBER_VAL = 274, - INT_VAL = 275 + FUNC_TO_DATE = 269, + FUNC_TO_TIMESTAMP = 270, + FUNC_NVL = 271, + FUNC_TO_CHAR = 272, + FUNC_MOD = 273, + FUNC_SYSDATE = 274, + END_P = 275, + ERROR = 276, + IGNORED_WORD = 277, + NAME_OB = 278, + STR_VAL = 279, + NUMBER_VAL = 280, + INT_VAL = 281 }; #endif diff --git a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_lex.h b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_lex.h index 14f5fb507..3d8a11e85 100644 --- a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_lex.h +++ b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_lex.h @@ -341,7 +341,7 @@ extern int obfuncexprlex \ #undef YY_DECL #endif -#line 237 "ob_func_expr_parser.l" +#line 246 "ob_func_expr_parser.l" #line 348 "ob_func_expr_parser_lex.h" diff --git a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_tab.c b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_tab.c index 49ab72020..abb236463 100644 --- a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_tab.c +++ b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_tab.c @@ -138,13 +138,19 @@ extern int obfuncexprdebug; FUNC_SUB = 266, FUNC_MUL = 267, FUNC_TESTLOAD = 268, - END_P = 269, - ERROR = 270, - IGNORED_WORD = 271, - NAME_OB = 272, - STR_VAL = 273, - NUMBER_VAL = 274, - INT_VAL = 275 + FUNC_TO_DATE = 269, + FUNC_TO_TIMESTAMP = 270, + FUNC_NVL = 271, + FUNC_TO_CHAR = 272, + FUNC_MOD = 273, + FUNC_SYSDATE = 274, + END_P = 275, + ERROR = 276, + IGNORED_WORD = 277, + NAME_OB = 278, + STR_VAL = 279, + NUMBER_VAL = 280, + INT_VAL = 281 }; #endif @@ -460,22 +466,22 @@ union yyalloc #endif /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 15 +#define YYFINAL 22 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 46 +#define YYLAST 64 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 24 +#define YYNTOKENS 30 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 7 +#define YYNNTS 8 /* YYNRULES -- Number of rules. */ -#define YYNRULES 22 +#define YYNRULES 29 /* YYNRULES -- Number of states. */ -#define YYNSTATES 30 +#define YYNSTATES 37 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 275 +#define YYMAXUTOK 281 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -487,7 +493,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 21, 22, 2, 2, 23, 2, 2, 2, 2, 2, + 27, 28, 2, 2, 29, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -510,7 +516,8 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20 + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26 }; #if YYDEBUG @@ -519,27 +526,28 @@ static const yytype_uint8 yytranslate[] = static const yytype_uint8 yyprhs[] = { 0, 0, 3, 5, 7, 9, 14, 18, 20, 22, - 24, 26, 28, 30, 32, 34, 36, 38, 42, 46, - 48, 50, 52 + 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, + 44, 46, 48, 50, 52, 56, 60, 62, 64, 66 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 25, 0, -1, 26, -1, 27, -1, 1, -1, 28, - 21, 29, 22, -1, 28, 21, 22, -1, 5, -1, - 6, -1, 7, -1, 8, -1, 9, -1, 10, -1, - 11, -1, 12, -1, 13, -1, 30, -1, 29, 23, - 30, -1, 4, 17, 4, -1, 17, -1, 20, -1, - 18, -1, 27, -1 + 31, 0, -1, 32, -1, 33, -1, 1, -1, 34, + 27, 36, 28, -1, 34, 27, 28, -1, 35, -1, + 5, -1, 6, -1, 7, -1, 8, -1, 9, -1, + 10, -1, 11, -1, 12, -1, 13, -1, 14, -1, + 15, -1, 16, -1, 17, -1, 18, -1, 19, -1, + 37, -1, 36, 29, 37, -1, 4, 23, 4, -1, + 23, -1, 26, -1, 24, -1, 33, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 96, 96, 98, 104, 106, 111, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 127, 131, 137, 138, - 139, 140, 141 + 0, 97, 97, 99, 105, 107, 112, 117, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 138, 140, 144, 150, 151, 152, 153, 154 }; #endif @@ -550,10 +558,12 @@ static const char *const yytname[] = { "$end", "error", "$undefined", "DUMMY_FUNCTION_CLAUSE", "TOKEN_SPECIAL", "FUNC_SUBSTR", "FUNC_CONCAT", "FUNC_HASH", "FUNC_TOINT", "FUNC_DIV", - "FUNC_ADD", "FUNC_SUB", "FUNC_MUL", "FUNC_TESTLOAD", "END_P", "ERROR", - "IGNORED_WORD", "NAME_OB", "STR_VAL", "NUMBER_VAL", "INT_VAL", "'('", - "')'", "','", "$accept", "start", "func_root", "func_expr", "func_name", - "param_list", "param", 0 + "FUNC_ADD", "FUNC_SUB", "FUNC_MUL", "FUNC_TESTLOAD", "FUNC_TO_DATE", + "FUNC_TO_TIMESTAMP", "FUNC_NVL", "FUNC_TO_CHAR", "FUNC_MOD", + "FUNC_SYSDATE", "END_P", "ERROR", "IGNORED_WORD", "NAME_OB", "STR_VAL", + "NUMBER_VAL", "INT_VAL", "'('", "')'", "','", "$accept", "start", + "func_root", "func_expr", "func_name", "reserved_func", "param_list", + "param", 0 }; #endif @@ -564,24 +574,24 @@ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 40, 41, 44 + 275, 276, 277, 278, 279, 280, 281, 40, 41, 44 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 24, 25, 26, 26, 27, 27, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 29, 29, 30, 30, - 30, 30, 30 + 0, 30, 31, 32, 32, 33, 33, 33, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 35, 36, 36, 37, 37, 37, 37, 37 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 1, 1, 1, 4, 3, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, - 1, 1, 1 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 3, 1, 1, 1, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -589,15 +599,16 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 0, 4, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 0, 2, 3, 0, 1, 0, 0, 19, 21, - 20, 6, 22, 0, 16, 0, 5, 0, 18, 17 + 0, 4, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 0, 2, 3, + 0, 7, 1, 0, 0, 26, 28, 27, 6, 29, + 0, 23, 0, 5, 0, 25, 24 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 11, 12, 22, 14, 23, 24 + -1, 17, 18, 29, 20, 21, 30, 31 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing @@ -605,15 +616,16 @@ static const yytype_int8 yydefgoto[] = #define YYPACT_NINF -13 static const yytype_int8 yypact[] = { - 33, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, 12, -13, -13, -6, -13, -4, 0, -13, -13, - -13, -13, -13, -12, -13, 25, -13, 15, -13, -13 + 45, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -13, -13, -13, -13, -13, -13, 18, -13, -13, + -6, -13, -13, -4, 0, -13, -13, -13, -13, -13, + -12, -13, 37, -13, 21, -13, -13 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -13, -13, -13, 30, -13, -13, 4 + -13, -13, -13, 42, -13, -13, -13, 9 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -623,20 +635,24 @@ static const yytype_int8 yypgoto[] = #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { - 17, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 26, 27, 15, 18, 19, 16, 20, 25, 21, 17, - 2, 3, 4, 5, 6, 7, 8, 9, 10, 28, - 13, 29, 18, 19, 1, 20, 0, 0, 2, 3, - 4, 5, 6, 7, 8, 9, 10 + 24, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 33, 34, 22, 25, + 26, 23, 27, 32, 28, 24, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 35, 19, 36, 25, 26, 1, 27, 0, 0, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16 }; static const yytype_int8 yycheck[] = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 22, 23, 0, 17, 18, 21, 20, 17, 22, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 4, - 0, 27, 17, 18, 1, 20, -1, -1, 5, 6, - 7, 8, 9, 10, 11, 12, 13 + 14, 15, 16, 17, 18, 19, 28, 29, 0, 23, + 24, 27, 26, 23, 28, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 4, 0, 34, 23, 24, 1, 26, -1, -1, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -644,8 +660,9 @@ static const yytype_int8 yycheck[] = static const yytype_uint8 yystos[] = { 0, 1, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 25, 26, 27, 28, 0, 21, 4, 17, 18, - 20, 22, 27, 29, 30, 17, 22, 23, 4, 30 + 13, 14, 15, 16, 17, 18, 19, 31, 32, 33, + 34, 35, 0, 27, 4, 23, 24, 26, 28, 33, + 36, 37, 23, 28, 29, 4, 37 }; #define yyerrok (yyerrstatus = 0) @@ -1528,57 +1545,95 @@ YYLTYPE yylloc; case 7: - { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_SUBSTR; ;} + { + malloc_func_expr_node((yyval.func_node), result, (yyvsp[(1) - (1)].function_type)); + (yyval.func_node)->child_ = NULL; + ;} break; case 8: - { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_CONCAT; ;} + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_SUBSTR; ;} break; case 9: - { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_HASH; ;} + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_CONCAT; ;} break; case 10: - { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_TOINT; ;} + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_HASH; ;} break; case 11: - { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_DIV; ;} + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_TOINT; ;} break; case 12: - { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_ADD; ;} + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_DIV; ;} break; case 13: - { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_SUB; ;} + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_ADD; ;} break; case 14: - { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_MUL; ;} + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_SUB; ;} break; case 15: - { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_TESTLOAD; ;} + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_MUL; ;} break; case 16: + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_TESTLOAD; ;} + break; + + case 17: + + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_TO_DATE; ;} + break; + + case 18: + + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_TO_TIMESTAMP; ;} + break; + + case 19: + + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_NVL; ;} + break; + + case 20: + + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_TO_CHAR; ;} + break; + + case 21: + + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_MOD; ;} + break; + + case 22: + + { (yyval.function_type) = OB_PROXY_EXPR_TYPE_FUNC_SYSDATE; ;} + break; + + case 23: + { malloc_list((yyval.list), result, (yyvsp[(1) - (1)].param_node)); ;} break; - case 17: + case 24: { add_param_node((yyvsp[(1) - (3)].list), result, (yyvsp[(3) - (3)].param_node)); @@ -1586,27 +1641,27 @@ YYLTYPE yylloc; ;} break; - case 18: + case 25: { malloc_param_node((yyval.param_node), result, PARAM_COLUMN); (yyval.param_node)->col_name_ = (yyvsp[(2) - (3)].str); ;} break; - case 19: + case 26: { malloc_param_node((yyval.param_node), result, PARAM_COLUMN); (yyval.param_node)->col_name_ = (yyvsp[(1) - (1)].str); ;} break; - case 20: + case 27: { malloc_param_node((yyval.param_node), result, PARAM_INT_VAL); (yyval.param_node)->int_value_ = (yyvsp[(1) - (1)].num); ;} break; - case 21: + case 28: { malloc_param_node((yyval.param_node), result, PARAM_STR_VAL); (yyval.param_node)->str_value_ = (yyvsp[(1) - (1)].str); ;} break; - case 22: + case 29: { malloc_param_node((yyval.param_node), result, PARAM_FUNC); (yyval.param_node)->func_expr_node_ = (yyvsp[(1) - (1)].func_node); ;} break; diff --git a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_tab.h b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_tab.h index 1eb7984ee..4f199b4b4 100644 --- a/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_tab.h +++ b/src/obproxy/opsql/func_expr_parser/ob_func_expr_parser_tab.h @@ -67,13 +67,19 @@ extern int obfuncexprdebug; FUNC_SUB = 266, FUNC_MUL = 267, FUNC_TESTLOAD = 268, - END_P = 269, - ERROR = 270, - IGNORED_WORD = 271, - NAME_OB = 272, - STR_VAL = 273, - NUMBER_VAL = 274, - INT_VAL = 275 + FUNC_TO_DATE = 269, + FUNC_TO_TIMESTAMP = 270, + FUNC_NVL = 271, + FUNC_TO_CHAR = 272, + FUNC_MOD = 273, + FUNC_SYSDATE = 274, + END_P = 275, + ERROR = 276, + IGNORED_WORD = 277, + NAME_OB = 278, + STR_VAL = 279, + NUMBER_VAL = 280, + INT_VAL = 281 }; #endif diff --git a/src/obproxy/opsql/func_expr_resolver/ob_func_expr_resolver.cpp b/src/obproxy/opsql/func_expr_resolver/ob_func_expr_resolver.cpp index f586ef93f..c8b4dffb4 100644 --- a/src/obproxy/opsql/func_expr_resolver/ob_func_expr_resolver.cpp +++ b/src/obproxy/opsql/func_expr_resolver/ob_func_expr_resolver.cpp @@ -50,6 +50,11 @@ int ObFuncExprResolver::recursive_resolve_proxy_expr(const ObProxyParamNode *nod ObProxyExprConst *str_expr = NULL; if(OB_FAIL(ctx_.expr_factory_->create_proxy_expr(OB_PROXY_EXPR_TYPE_CONST, str_expr))) { LOG_WARN("create proxy expr failed", K(ret)); + } else if (0 == node->str_value_.str_len_) { + ObObj &obj = str_expr->get_object(); + obj.set_varchar(NULL, 0); + obj.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI); + expr = str_expr; } else { ObIAllocator &allocator = *ctx_.allocator_; char *buf = NULL; @@ -103,6 +108,8 @@ int ObFuncExprResolver::recursive_resolve_proxy_expr(const ObProxyParamNode *nod ObProxyFuncExpr *func_expr = NULL; if (OB_FAIL(create_func_expr_by_type(func_expr_node, func_expr))) { LOG_WARN("create func expr by type failed", K(ret)); + } else if (OB_ISNULL(func_expr_node->child_)) { + // do nothing } else { ObProxyParamNodeList *child = func_expr_node->child_; ObProxyParamNode* tmp_param_node = child->head_; @@ -242,6 +249,68 @@ int ObFuncExprResolver::create_func_expr_by_type(const ObFuncExprNode *func_expr } } break; + case OB_PROXY_EXPR_TYPE_FUNC_TO_DATE: + { + ObProxyExprToTimeHandler *todate_expr = NULL; + if (OB_FAIL(ctx_.expr_factory_->create_proxy_expr(OB_PROXY_EXPR_TYPE_FUNC_TO_DATE, todate_expr))) { + LOG_WARN("create proxy to_date failed", K(ret)); + } else { + todate_expr->set_target_type(ObDateTimeType); + func_expr = todate_expr; + } + } + break; + case OB_PROXY_EXPR_TYPE_FUNC_TO_TIMESTAMP: + { + ObProxyExprToTimeHandler *totimestamp_expr = NULL; + if (OB_FAIL(ctx_.expr_factory_->create_proxy_expr(OB_PROXY_EXPR_TYPE_FUNC_TO_TIMESTAMP, totimestamp_expr))) { + LOG_WARN("create proxy to_timestamp failed", K(ret)); + } else { + totimestamp_expr->set_target_type(ObTimestampNanoType); + func_expr = totimestamp_expr; + } + } + break; + case OB_PROXY_EXPR_TYPE_FUNC_NVL: + { + ObProxyExprNvl *nvl_expr = NULL; + if (OB_FAIL(ctx_.expr_factory_->create_proxy_expr(OB_PROXY_EXPR_TYPE_FUNC_NVL, nvl_expr))) { + LOG_WARN("create proxy nvl failed", K(ret)); + } else { + func_expr = nvl_expr; + } + } + break; + case OB_PROXY_EXPR_TYPE_FUNC_TO_CHAR: + { + ObProxyExprToChar *tochar_expr = NULL; + if (OB_FAIL(ctx_.expr_factory_->create_proxy_expr(OB_PROXY_EXPR_TYPE_FUNC_TO_CHAR, tochar_expr))) { + LOG_WARN("create proxy to_char failed", K(ret)); + } else { + func_expr = tochar_expr; + } + } + break; + case OB_PROXY_EXPR_TYPE_FUNC_SYSDATE: + { + ObProxyExprSysdate *sysdate_expr = NULL; + if (OB_FAIL(ctx_.expr_factory_->create_proxy_expr(OB_PROXY_EXPR_TYPE_FUNC_SYSDATE, sysdate_expr))) { + LOG_WARN("create proxy sysdate failed", K(ret)); + } else { + func_expr = sysdate_expr; + } + } + break; + case OB_PROXY_EXPR_TYPE_FUNC_MOD: + { + ObProxyExprMod *mod_expr = NULL; + if (OB_FAIL(ctx_.expr_factory_->create_proxy_expr(OB_PROXY_EXPR_TYPE_FUNC_MOD, mod_expr))) { + LOG_WARN("create proxy mod failed", K(ret)); + } else { + func_expr = mod_expr; + } + } + break; default: ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected type", K(func_expr_node->func_type_), K(ret)); diff --git a/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr.cpp b/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr.cpp index 9c3bb18f0..323a9a142 100644 --- a/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr.cpp +++ b/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr.cpp @@ -12,10 +12,16 @@ #define USING_LOG_PREFIX PROXY -#include "common/ob_obj_cast.h" #include "opsql/func_expr_resolver/proxy_expr/ob_proxy_expr.h" -#include "utils/ob_proxy_utils.h" +#include "common/ob_obj_cast.h" +#include "common/ob_obj_type.h" #include "dbconfig/ob_proxy_db_config_info.h" +#include "lib/time/ob_time_utility.h" +#include "proxy/route/obproxy_expr_calculator.h" +#include "utils/ob_proxy_utils.h" +#include "common/expression/ob_expr_regexp_context.h" +#include "lib/utility/utility.h" +#include namespace oceanbase { @@ -226,10 +232,10 @@ int ObProxyExprColumn::calc(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem } else if (result_obj_array.count() == len && ObProxyExprCalcItem::FROM_SQL_FIELD == calc_item.source_) { bool found = false; for (int64_t i = 0; OB_SUCC(ret) && i < calc_item.sql_result_->field_num_; i++) { - SqlField &field = calc_item.sql_result_->fields_.at(i); - if (0 == field.column_name_.string_.case_compare(column_name_)) { + SqlField* field = calc_item.sql_result_->fields_.at(i); + if (0 == field->column_name_.config_string_.case_compare(column_name_)) { found = true; - common::ObSEArray &column_values = field.column_values_; + common::ObSEArray &column_values = field->column_values_; for (int64_t j = 0; OB_SUCC(ret) && j < column_values.count(); j++) { ObObj result_obj; SqlColumnValue &sql_column_value = column_values.at(j); @@ -240,7 +246,7 @@ int ObProxyExprColumn::calc(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem LOG_WARN("push back obj failed", K(ret), K(result_obj)); } } else if (TOKEN_STR_VAL == sql_column_value.value_type_) { - ObString value = sql_column_value.column_value_.string_; + ObString value = sql_column_value.column_value_.config_string_; result_obj.set_varchar(value); result_obj.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI); if (OB_FAIL(result_obj_array.push_back(result_obj))) { @@ -362,26 +368,19 @@ int ObProxyFuncExpr::calc_param_expr(const ObProxyExprCtx &ctx, return ret; } -int ObProxyFuncExpr::get_int_obj(const ObObj &src, ObObj &dst) +int ObProxyFuncExpr::get_int_obj(const ObObj &src, ObObj &dst, common::ObIAllocator &allocator) { int ret = OB_SUCCESS; - if (src.is_varchar()) { - ObString str; - int64_t val; - if (OB_FAIL(src.get_varchar(str))) { - LOG_WARN("get varchar failed", K(ret)); - } else if (OB_FAIL(get_int_value(str, val))) { - LOG_WARN("get int value failed", K(ret), K(src)); - } else { - dst.set_int(val); + if (!src.is_int()) { + ObCollationType collation = ObCharset::get_default_collation(ObCharset::get_default_charset()); + ObCastCtx cast_ctx(&allocator, NULL, CM_NULL_ON_WARN, collation); + if (OB_FAIL(ObObjCasterV2::to_type(ObIntType, collation, cast_ctx, src, dst))) { + LOG_WARN("cast obj to varchar obj fail", K(ret)); } - } else if (src.is_int()) { - dst = src; } else { - ret = OB_EXPR_CALC_ERROR; - LOG_WARN("invalid type to int", K(ret)); - } + dst = src; + } return ret; } @@ -389,22 +388,14 @@ int ObProxyFuncExpr::get_int_obj(const ObObj &src, ObObj &dst) int ObProxyFuncExpr::get_varchar_obj(const common::ObObj &src, common::ObObj &dst, common::ObIAllocator &allocator) { int ret = OB_SUCCESS; - if (src.is_int()) { - char *buf = NULL; - const int64_t buf_len = 256; - if (OB_ISNULL(buf = static_cast(allocator.alloc(buf_len)))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("alloc buf failed", K(ret), K(buf_len)); - } else { - snprintf(buf, buf_len, "%ld", src.get_int()); - dst.set_varchar(buf, static_cast(strlen(buf))); - dst.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI); + if (!src.is_varchar()) { + ObCollationType collation = ObCharset::get_default_collation(ObCharset::get_default_charset()); + ObCastCtx cast_ctx(&allocator, NULL, CM_NULL_ON_WARN, collation); + if (OB_FAIL(ObObjCasterV2::to_type(ObVarcharType, collation, cast_ctx, src, dst))) { + LOG_WARN("cast obj to varchar obj fail", K(ret)); } } else if (src.is_varchar()) { dst = src; - } else { - ret = OB_EXPR_CALC_ERROR; - LOG_INFO("get varchar obj failed", K(src), K(ret)); } return ret; @@ -456,7 +447,7 @@ int ObProxyExprHash::calc(const ObProxyExprCtx &ctx, tmp_obj = param_result_array.at(j).at(i); } if (OB_FAIL(param_result.push_back(tmp_obj))) { - LOG_WARN("push back obj faile", K(ret), K(i), K(j)); + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); } } @@ -475,7 +466,7 @@ int ObProxyExprHash::calc(const ObProxyExprCtx &ctx, LOG_DEBUG("test load type", K(test_load_obj)); } - if (OB_FAIL(get_int_obj(test_load_obj, obj1))) { + if (OB_FAIL(get_int_obj(test_load_obj, obj1, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret), K(test_load_obj)); } else if (OB_FAIL(obj1.get_int(index))) { LOG_WARN("get int failed", K(ret), K(obj1)); @@ -483,7 +474,7 @@ int ObProxyExprHash::calc(const ObProxyExprCtx &ctx, if (OB_SUCC(ret) && param_array_.count() == 2) { ObObj obj2; - if (OB_FAIL(get_int_obj(param_result.at(1), obj2))) { + if (OB_FAIL(get_int_obj(param_result.at(1), obj2, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); } else if (OB_FAIL(obj2.get_int(num))) { LOG_WARN("get int failed", K(ret)); @@ -507,7 +498,7 @@ int ObProxyExprHash::calc(const ObProxyExprCtx &ctx, } } } - } while (++i < cnt); + } while (OB_SUCC(ret) && ++i < cnt); } } ObProxyExpr::print_proxy_expr(this); @@ -544,7 +535,7 @@ int ObProxyExprSubStr::calc(const ObProxyExprCtx &ctx, tmp_obj = param_result_array.at(j).at(i); } if (OB_FAIL(param_result.push_back(tmp_obj))) { - LOG_WARN("push back obj faile", K(ret), K(i), K(j)); + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); } } @@ -556,6 +547,9 @@ int ObProxyExprSubStr::calc(const ObProxyExprCtx &ctx, int64_t substr_len = -1; ObObj first_obj; + // substr retrun NULL on out of bounds params + bool is_invalid_params = false; + if (OB_FAIL(get_varchar_obj(param_result.at(0), first_obj, *ctx.allocator_))) { LOG_WARN("get varchar obj failed", K(ret)); } else if (OB_FAIL(first_obj.get_varchar(value))) { @@ -567,26 +561,33 @@ int ObProxyExprSubStr::calc(const ObProxyExprCtx &ctx, if (OB_SUCC(ret)) { ObObj obj; - if (OB_FAIL(get_int_obj(param_result.at(1), obj))) { + if (OB_FAIL(get_int_obj(param_result.at(1), obj, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); } else if (OB_FAIL(obj.get_int(start_pos))) { LOG_WARN("get int failed", K(ret)); } } - + if (start_pos == 0) { + if (ctx.is_oracle_mode) { + // 1 and 0 treated as thr first character in oracle + start_pos = 1; + } else { + is_invalid_params = true; + } + } if (OB_SUCC(ret) && 3 == param_result.count()) { ObObj obj; - if (OB_FAIL(get_int_obj(param_result.at(2), obj))) { + if (OB_FAIL(get_int_obj(param_result.at(2), obj, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); } else if (OB_FAIL(obj.get_int(substr_len))) { LOG_WARN("get int failed", K(ret)); } else if (substr_len <= 0) { - ret = OB_INVALID_ARGUMENT_FOR_SUBSTR; - LOG_WARN("substr function param 3 is less than 1", K(ret)); + is_invalid_params = true; + LOG_DEBUG("substr function param 3 is less than 1", K(ret)); } } - if (OB_SUCC(ret)) { + if (OB_SUCC(ret) && !is_invalid_params) { value_length = value.length(); if (start_pos < 0) { start_pos = value_length + start_pos + 1; @@ -597,26 +598,37 @@ int ObProxyExprSubStr::calc(const ObProxyExprCtx &ctx, } if (start_pos <= 0 || start_pos > value_length || substr_len <= 0 || substr_len > value_length || start_pos + substr_len - 1 > value_length) { - ret = OB_INVALID_ARGUMENT_FOR_SUBSTR; - LOG_WARN("column value length does not match", K(start_pos), - K(substr_len), K(value_length), K(value), K(ret)); + is_invalid_params = true; + LOG_DEBUG("invalid substr params", K(start_pos), K(substr_len), K(value_length), K(value), K(ret)); } + } - if (OB_SUCC(ret)) { + if (OB_SUCC(ret)) { + if(is_invalid_params) { + if (ctx.is_oracle_mode) { + result_obj.set_null(); + } else { + result_obj.set_varchar(ObString()); + } + } else { ObString result_str; result_str.assign_ptr(value.ptr() + start_pos - 1, static_cast(substr_len)); result_obj.set_varchar(result_str); result_obj.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI); - if (OB_FAIL(check_varchar_empty(result_obj))) { LOG_WARN("check varchar emtpy failed", K(ret)); - } else if (OB_FAIL(result_obj_array.push_back(result_obj))) { - LOG_WARN("result obj array push back failed", K(ret)); - } + } } } + + if (OB_SUCC(ret)) { + if (OB_FAIL(result_obj_array.push_back(result_obj))) { + LOG_WARN("result obj array push back failed", K(ret)); + } + } + } - } while (++i < cnt); + } while (OB_SUCC(ret) && ++i < cnt); } } ObProxyExpr::print_proxy_expr(this); @@ -653,7 +665,7 @@ int ObProxyExprConcat::calc(const ObProxyExprCtx &ctx, tmp_obj = param_result_array.at(j).at(i); } if (OB_FAIL(param_result.push_back(tmp_obj))) { - LOG_WARN("push back obj faile", K(ret), K(i), K(j)); + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); } } @@ -709,7 +721,7 @@ int ObProxyExprConcat::calc(const ObProxyExprCtx &ctx, } } } - } while (++i < cnt); + } while (OB_SUCC(ret) && ++i < cnt); } } ObProxyExpr::print_proxy_expr(this); @@ -746,19 +758,19 @@ int ObProxyExprToInt::calc(const ObProxyExprCtx &ctx, tmp_obj = param_result_array.at(j).at(i); } if (OB_FAIL(param_result.push_back(tmp_obj))) { - LOG_WARN("push back obj faile", K(ret), K(i), K(j)); + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); } } if (OB_SUCC(ret)) { ObObj result_obj; ObObj &obj = param_result.at(0); - if (OB_FAIL(get_int_obj(obj, result_obj))) { + if (OB_FAIL(get_int_obj(obj, result_obj, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); } else if (OB_FAIL(result_obj_array.push_back(result_obj))) { LOG_WARN("result obj array push back failed", K(ret)); } } - } while (++i < cnt); + } while (OB_SUCC(ret) && ++i < cnt); } } ObProxyExpr::print_proxy_expr(this); @@ -774,7 +786,7 @@ int ObProxyExprDiv::calc(const ObProxyExprCtx &ctx, common::ObSEArray, 4> param_result_array; int cnt = 0; int64_t len = result_obj_array.count(); - + if (-1 != index_ && ObProxyExprCalcItem::FROM_OBJ_ARRAY == calc_item.source_ && !has_agg_) { if (OB_FAIL(ObProxyExpr::calc(ctx, calc_item, result_obj_array))) { LOG_WARN("calc expr failed", K(ret)); @@ -799,7 +811,7 @@ int ObProxyExprDiv::calc(const ObProxyExprCtx &ctx, tmp_obj = param_result_array.at(j).at(i); } if (OB_FAIL(param_result.push_back(tmp_obj))) { - LOG_WARN("push back obj faile", K(ret), K(i), K(j)); + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); } } @@ -810,7 +822,7 @@ int ObProxyExprDiv::calc(const ObProxyExprCtx &ctx, if (ObDoubleTC == obj1.get_type_class() || ObDoubleTC == obj2.get_type_class()) { if (OB_FAIL((get_obj_for_calc(ctx.allocator_, obj1, obj2)))) { LOG_WARN("get double obj failed", K(obj1), K(obj2), K(ret)); - } else if (fabs(obj2.get_double()) == 0.0) { + } else if (fabs(obj2.get_double()) < DBL_EPSILON) { result_obj.set_null(); } else { double obj1_d = obj1.get_double(); @@ -820,6 +832,8 @@ int ObProxyExprDiv::calc(const ObProxyExprCtx &ctx, } else if (ObFloatTC == obj1.get_type_class() || ObFloatTC == obj2.get_type_class()) { if (OB_FAIL((get_obj_for_calc(ctx.allocator_, obj1, obj2)))) { LOG_WARN("get float obj failed", K(obj1), K(obj2), K(ret)); + } else if (fabs(obj2.get_float()) < FLT_EPSILON) { + result_obj.set_null(); } else { float obj1_f = obj1.get_float(); float obj2_f = obj2.get_float(); @@ -846,9 +860,9 @@ int ObProxyExprDiv::calc(const ObProxyExprCtx &ctx, } } } else { - if (OB_FAIL(get_int_obj(param_result.at(0), obj1))) { + if (OB_FAIL(get_int_obj(param_result.at(0), obj1, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); - } else if (OB_FAIL(get_int_obj(param_result.at(1), obj2))) { + } else if (OB_FAIL(get_int_obj(param_result.at(1), obj2, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); } else { int64_t num1 = obj1.get_int(); @@ -866,7 +880,7 @@ int ObProxyExprDiv::calc(const ObProxyExprCtx &ctx, LOG_WARN("result obj array push back failed", K(ret)); } } - } while (++i < cnt); + } while (OB_SUCC(ret) && ++i < cnt); } } ObProxyExpr::print_proxy_expr(this); @@ -907,7 +921,7 @@ int ObProxyExprAdd::calc(const ObProxyExprCtx &ctx, tmp_obj = param_result_array.at(j).at(i); } if (OB_FAIL(param_result.push_back(tmp_obj))) { - LOG_WARN("push back obj faile", K(ret), K(i), K(j)); + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); } } @@ -950,9 +964,9 @@ int ObProxyExprAdd::calc(const ObProxyExprCtx &ctx, } } } else { - if (OB_FAIL(get_int_obj(param_result.at(0), obj1))) { + if (OB_FAIL(get_int_obj(param_result.at(0), obj1, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); - } else if (OB_FAIL(get_int_obj(param_result.at(1), obj2))) { + } else if (OB_FAIL(get_int_obj(param_result.at(1), obj2, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); } else { int64_t num1 = obj1.get_int(); @@ -970,7 +984,7 @@ int ObProxyExprAdd::calc(const ObProxyExprCtx &ctx, LOG_WARN("result obj array push back failed", K(ret)); } } - } while (++i < cnt); + } while (OB_SUCC(ret) && ++i < cnt); } } ObProxyExpr::print_proxy_expr(this); @@ -1011,7 +1025,7 @@ int ObProxyExprSub::calc(const ObProxyExprCtx &ctx, tmp_obj = param_result_array.at(j).at(i); } if (OB_FAIL(param_result.push_back(tmp_obj))) { - LOG_WARN("push back obj faile", K(ret), K(i), K(j)); + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); } } @@ -1054,9 +1068,9 @@ int ObProxyExprSub::calc(const ObProxyExprCtx &ctx, } } } else { - if (OB_FAIL(get_int_obj(param_result.at(0), obj1))) { + if (OB_FAIL(get_int_obj(param_result.at(0), obj1, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); - } else if (OB_FAIL(get_int_obj(param_result.at(1), obj2))) { + } else if (OB_FAIL(get_int_obj(param_result.at(1), obj2, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); } else { int64_t num1 = obj1.get_int(); @@ -1074,7 +1088,7 @@ int ObProxyExprSub::calc(const ObProxyExprCtx &ctx, LOG_WARN("result obj array push back failed", K(ret)); } } - } while (++i < cnt); + } while (OB_SUCC(ret) && ++i < cnt); } } ObProxyExpr::print_proxy_expr(this); @@ -1115,7 +1129,7 @@ int ObProxyExprMul::calc(const ObProxyExprCtx &ctx, tmp_obj = param_result_array.at(j).at(i); } if (OB_FAIL(param_result.push_back(tmp_obj))) { - LOG_WARN("push back obj faile", K(ret), K(i), K(j)); + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); } } @@ -1158,9 +1172,9 @@ int ObProxyExprMul::calc(const ObProxyExprCtx &ctx, } } } else { - if (OB_FAIL(get_int_obj(param_result.at(0), obj1))) { + if (OB_FAIL(get_int_obj(param_result.at(0), obj1, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); - } else if (OB_FAIL(get_int_obj(param_result.at(1), obj2))) { + } else if (OB_FAIL(get_int_obj(param_result.at(1), obj2, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); } else { int64_t num1 = obj1.get_int(); @@ -1178,7 +1192,7 @@ int ObProxyExprMul::calc(const ObProxyExprCtx &ctx, LOG_WARN("result obj array push back failed", K(ret)); } } - } while (++i < cnt); + } while (OB_SUCC(ret) && ++i < cnt); } } ObProxyExpr::print_proxy_expr(this); @@ -1215,7 +1229,7 @@ int ObProxyExprTestLoad::calc(const ObProxyExprCtx &ctx, tmp_obj = param_result_array.at(j).at(i); } if (OB_FAIL(param_result.push_back(tmp_obj))) { - LOG_WARN("push back obj faile", K(ret), K(i), K(j)); + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); } } @@ -1236,7 +1250,7 @@ int ObProxyExprTestLoad::calc(const ObProxyExprCtx &ctx, } } } - } while (++i < cnt); + } while (OB_SUCC(ret) && ++i < cnt); } } ObProxyExpr::print_proxy_expr(this); @@ -1273,7 +1287,7 @@ int ObProxyExprSplit::calc(const ObProxyExprCtx &ctx, tmp_obj = param_result_array.at(j).at(i); } if (OB_FAIL(param_result.push_back(tmp_obj))) { - LOG_WARN("push back obj faile", K(ret), K(i), K(j)); + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); } } @@ -1303,7 +1317,7 @@ int ObProxyExprSplit::calc(const ObProxyExprCtx &ctx, if (OB_SUCC(ret)) { ObObj obj; - if (OB_FAIL(get_int_obj(param_result.at(2), obj))) { + if (OB_FAIL(get_int_obj(param_result.at(2), obj, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); } else if (OB_FAIL(obj.get_int(index))) { LOG_WARN("get int failed", K(ret)); @@ -1374,7 +1388,7 @@ int ObProxyExprSplit::calc(const ObProxyExprCtx &ctx, } } } - } while (++i < cnt); + } while (OB_SUCC(ret) && ++i < cnt); } } ObProxyExpr::print_proxy_expr(this); @@ -1404,7 +1418,7 @@ int ObProxyExprAvg::calc(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem &c if (ObDoubleTC == obj1.get_type_class() || ObDoubleTC == obj2.get_type_class()) { if (OB_FAIL((get_obj_for_calc(ctx.allocator_, obj1, obj2)))) { LOG_WARN("get double obj failed", K(obj1), K(obj2), K(ret)); - } else if (fabs(obj2.get_double()) == 0.0) { + } else if (fabs(obj2.get_double()) < DBL_EPSILON) { result_obj.set_null(); } else { double obj1_d = obj1.get_double(); @@ -1414,6 +1428,8 @@ int ObProxyExprAvg::calc(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem &c } else if (ObFloatTC == obj1.get_type_class() || ObFloatTC == obj2.get_type_class()) { if (OB_FAIL((get_obj_for_calc(ctx.allocator_, obj1, obj2)))) { LOG_WARN("get float obj failed", K(obj1), K(obj2), K(ret)); + } else if (fabs(obj2.get_float() < FLT_EPSILON)) { + result_obj.set_null(); } else { float obj1_f = obj1.get_float(); float obj2_f = obj2.get_float(); @@ -1440,9 +1456,9 @@ int ObProxyExprAvg::calc(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem &c } } } else { - if (OB_FAIL(get_int_obj(param_result.at(0), obj1))) { + if (OB_FAIL(get_int_obj(param_result.at(0), obj1, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); - } else if (OB_FAIL(get_int_obj(param_result.at(1), obj2))) { + } else if (OB_FAIL(get_int_obj(param_result.at(1), obj2, *ctx.allocator_))) { LOG_WARN("get int obj failed", K(ret)); } else { int64_t num1 = obj1.get_int(); @@ -1471,6 +1487,383 @@ int ObProxyExprAvg::calc(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem &c return ret; } +/* + * for to_date and to_timestamp, only support at least one param, at most two params + */ +int ObProxyExprToTimeHandler::calc(const ObProxyExprCtx &ctx, + const ObProxyExprCalcItem &calc_item, + common::ObIArray &result_obj_array) +{ + int ret = OB_SUCCESS; + common::ObSEArray, 4> param_result_array; + int cnt = 0; + int64_t len = result_obj_array.count(); + + if (OB_FAIL(ObProxyExpr::calc(ctx, calc_item, result_obj_array))) { + LOG_WARN("calc expr failed", K(ret), K(param_array_.count())); + } else if (len == result_obj_array.count()) { + if (OB_UNLIKELY(param_array_.count() < 1)) { + ret = OB_EXPR_CALC_ERROR; + LOG_WARN("to_date should have at least one param", K(ret)); + } else if (OB_FAIL(calc_param_expr(ctx, calc_item, param_result_array, cnt))) { + LOG_WARN("calc param expr failed", K(ret)); + } else { + int i = 0; + do { + common::ObSEArray param_result; + for (int64_t j = 0; OB_SUCC(ret) && j < param_result_array.count(); j++) { + ObObj tmp_obj; + if (param_result_array.at(j).count() == 1) { + tmp_obj = param_result_array.at(j).at(0); + } else { + tmp_obj = param_result_array.at(j).at(i); + } + if (OB_FAIL(param_result.push_back(tmp_obj))) { + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); + } + } + + ObObjTypeClass type = param_result.at(0).get_type_class(); + if (OB_SUCC(ret) && type != ObStringTC && type != ObIntTC && type != ObNumberTC) { + ret = OB_EXPR_CALC_ERROR; + LOG_WARN("unexpected the first param type of to_date", K(type)); + } + + ObTimeZoneInfo tz_info; + ObDataTypeCastParams dtc_params; + if (OB_SUCC(ret)) { + ObObj second_obj; + ObString nls_format; + + if (2 == param_result.count()) { + if(OB_FAIL(get_varchar_obj(param_result.at(1), second_obj, *ctx.allocator_))){ + LOG_WARN("get varchar obj failed", K(ret)); + } else if (OB_FAIL(second_obj.get_varchar(nls_format))) { + LOG_WARN("get varchar failded", K(ret)); + } else { + if (!nls_format.empty()) { + dtc_params.tz_info_ = &tz_info; + dtc_params.set_nls_format_by_type(target_type_, nls_format); + } else { + dtc_params.tz_info_ = &tz_info; + if (OB_FAIL(proxy::ObExprCalcTool::build_dtc_params( + ctx.client_session_info_, target_type_, dtc_params))) { + LOG_WARN("fail to build dtc params", K(ret), K(target_type_)); + } + } + } + } + } + + ObCollationType collation = ObCharset::get_default_collation(ObCharset::get_default_charset()); + ObCastCtx cast_ctx(ctx.allocator_, &dtc_params, CM_NULL_ON_WARN, collation); + param_result.at(0).set_collation_type(collation); + if (OB_SUCC(ret) && OB_FAIL(ObObjCasterV2::to_type(target_type_, collation, cast_ctx, + param_result.at(0), param_result.at(0)))) { + LOG_WARN("fail to cast obj", K(ret), K(target_type_), K(collation)); + } + if (OB_SUCC(ret) && OB_FAIL(result_obj_array.push_back(param_result.at(0)))) { + LOG_WARN("result obj array push back failed", K(ret)); + } + } while (OB_SUCC(ret) && ++i < cnt); + } + } + ObProxyExpr::print_proxy_expr(this); + return ret; +} + +int ObProxyExprNvl::calc(const ObProxyExprCtx &ctx, + const ObProxyExprCalcItem &calc_item, + common::ObIArray &result_obj_array) +{ + int ret = OB_SUCCESS; + common::ObSEArray, 4> param_result_array; + int cnt = 0; + int64_t len = result_obj_array.count(); + + if (OB_FAIL(ObProxyExpr::calc(ctx, calc_item, result_obj_array))) { + LOG_WARN("calc expr failed", K(ret), K(param_array_.count())); + } else if (len == result_obj_array.count()) { + if (OB_UNLIKELY(param_array_.count() != 2)) { + ret = OB_EXPR_CALC_ERROR; + LOG_WARN("nvl should have two param", K(ret)); + } else if (OB_FAIL(calc_param_expr(ctx, calc_item, param_result_array, cnt))) { + LOG_WARN("calc param expr failed", K(ret)); + } else { + int i = 0; + do { + common::ObSEArray param_result; + for (int64_t j = 0; OB_SUCC(ret) && j < param_result_array.count(); j++) { + ObObj tmp_obj; + if (param_result_array.at(j).count() == 1) { + tmp_obj = param_result_array.at(j).at(0); + } else { + tmp_obj = param_result_array.at(j).at(i); + } + if (OB_FAIL(param_result.push_back(tmp_obj))) { + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); + } + } + + ObObj result_obj = param_result.at(0); + ObObj second_obj = param_result.at(1); + if (OB_SUCC(ret)) { + // null expr or empty varchar treated as null + if (result_obj.is_null()) { + result_obj = second_obj; + } else if (result_obj.is_string_type()) { + ObString str; + if (OB_FAIL(result_obj.get_string(str))) { + LOG_WARN("get varchar of param failed", K(ret)); + } else if (str.empty()) { + result_obj = second_obj; + } + } + } + + if (OB_SUCC(ret) && OB_FAIL(result_obj_array.push_back(result_obj))) { + LOG_WARN("result obj array push back failed", K(ret)); + } + } while (OB_SUCC(ret) && ++i < cnt); + } + } + ObProxyExpr::print_proxy_expr(this); + return ret; +} + +/* + * only support datetime format. + */ +int ObProxyExprToChar::calc(const ObProxyExprCtx &ctx, + const ObProxyExprCalcItem &calc_item, + common::ObIArray &result_obj_array) +{ + int ret = OB_SUCCESS; + common::ObSEArray, 4> param_result_array; + int cnt = 0; + int64_t len = result_obj_array.count(); + + if (OB_FAIL(ObProxyExpr::calc(ctx, calc_item, result_obj_array))) { + LOG_WARN("calc expr failed", K(ret), K(param_array_.count())); + } else if (len == result_obj_array.count()) { + if (OB_UNLIKELY(param_array_.count() < 1) || OB_UNLIKELY(param_array_.count() > 2)) { + ret = OB_EXPR_CALC_ERROR; + LOG_WARN("to_char should have one or two param", K(ret), K(param_array_.count())); + } else if (OB_FAIL(calc_param_expr(ctx, calc_item, param_result_array, cnt))) { + LOG_WARN("calc param expr failed", K(ret)); + } else { + int i = 0; + do { + common::ObSEArray param_result; + for (int64_t j = 0; OB_SUCC(ret) && j < param_result_array.count(); j++) { + ObObj tmp_obj; + if (param_result_array.at(j).count() == 1) { + tmp_obj = param_result_array.at(j).at(0); + } else { + tmp_obj = param_result_array.at(j).at(i); + } + if (OB_FAIL(param_result.push_back(tmp_obj))) { + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); + } + } + if (OB_SUCC(ret)) { + ObObjType target_type = ObVarcharType; + ObObj result_obj = param_result.at(0); + ObObj second_obj; + ObString nls_format; + ObTimeZoneInfo tz_info; + ObDataTypeCastParams dtc_params = ObDataTypeCastParams(); + + // to_char(datetime) return NULL when nls_format parmas is '' + bool is_empty_format = false; + + ObCollationType collation = ObCharset::get_default_collation(ObCharset::get_default_charset()); + dtc_params.tz_info_ = &tz_info; + + if (ObDateTimeTC != param_result.at(0).get_type_class() && ObOTimestampTC != param_result.at(0).get_type_class()) { + ret = OB_EXPR_CALC_ERROR; + LOG_WARN("unsupported first param type of to_char", K(param_result.at(0).get_type_class())); + } else if (2 == param_result.count()) { + if (OB_FAIL(get_varchar_obj(param_result.at(1), second_obj, *ctx.allocator_))) { + LOG_WARN("get varchar obj failed", K(ret)); + } else if (OB_FAIL(second_obj.get_varchar(nls_format))) { + LOG_WARN("get varchar failed", K(ret)); + } else { + if (!nls_format.empty()) { + // ObObjCasterV2 only support ObOTimestampTC to format by nls_format, here convert ObDateTimeTC to ObTimestampTZType + dtc_params.set_nls_format_by_type(ObTimestampTZType, nls_format); + ObCastCtx cast_ctx_otimestamp(ctx.allocator_, &dtc_params, CM_NULL_ON_WARN, collation); + if (OB_FAIL(ObObjCasterV2::to_type(ObTimestampTZType, collation, cast_ctx_otimestamp, + result_obj, result_obj))) { + LOG_WARN("cast DateTime to ObTimestampTZTType failed", K(ret)); + } + } else { + is_empty_format = true; + } + } + } + + if (OB_SUCC(ret)) { + ObCastCtx cast_ctx(ctx.allocator_, &dtc_params, CM_NULL_ON_WARN, collation); + if (param_array_.count() == 1) { + // do nothing + } else if (is_empty_format) { + result_obj.set_null(); + } else if (OB_FAIL(ObObjCasterV2::to_type(target_type, collation, cast_ctx, result_obj, result_obj))) { + LOG_WARN("fail to cast obj to timestamp", K(ret), K(result_obj), K(target_type), K(collation)); + } + } + + if (OB_SUCC(ret) && OB_FAIL(result_obj_array.push_back(result_obj))) { + LOG_WARN("result obj array push back failed", K(ret)); + } + } + } while (OB_SUCC(ret) && ++i < cnt); + } + } + ObProxyExpr::print_proxy_expr(this); + return ret; +} + +int ObProxyExprSysdate::calc(const ObProxyExprCtx &ctx, + const ObProxyExprCalcItem &calc_item, + common::ObIArray &result_obj_array) +{ + int ret = OB_SUCCESS; + int cnt = 0; + int64_t len = result_obj_array.count(); + + if (OB_FAIL(ObProxyExpr::calc(ctx, calc_item, result_obj_array))) { + LOG_WARN("calc expr failed", K(ret)); + } else if (len == result_obj_array.count()) { + if (OB_UNLIKELY(param_array_.count() > 0)) { + ret = OB_EXPR_CALC_ERROR; + LOG_WARN("sysdate should have no param", K(ret)); + } else { + int i = 0; + do { + common::ObSEArray param_result; + if (OB_SUCC(ret)) { + ObObjType target_type = ObDateTimeType; + + int64 now = common::ObTimeUtility::current_time(); + // calc timezone offset to correct the time zone info + int64 gm_time_buf = (int64)((time_t)now - mktime(gmtime((time_t *)&now))) * 1000000; + + ObObj result_obj; + result_obj.set_timestamp(now + gm_time_buf); + ObTimeZoneInfo tz_info; + ObCollationType collation = ObCharset::get_default_collation(ObCharset::get_default_charset()); + if (OB_SUCC(ret)) { + ObCastCtx cast_ctx(ctx.allocator_, NULL, CM_NULL_ON_WARN, collation); + if (OB_FAIL(ObObjCasterV2::to_type(target_type, collation, cast_ctx, result_obj, result_obj))) { + LOG_WARN("fail to cast obj to timestamp", K(ret), K(result_obj), K(target_type), K(collation)); + } else if (OB_FAIL(result_obj_array.push_back(result_obj))) { + LOG_WARN("result obj array push back failed", K(ret)); + } + } + } + } while (OB_SUCC(ret) && ++i < cnt); + } + } + ObProxyExpr::print_proxy_expr(this); + return ret; +} + +/* + * refer to the implementation of oracle + * mod calculate: MOD(n1, n2) = n1 - n2 * FLOOR(n1/n2) + * when ( n2 = 0 ), return n1 + */ +int ObProxyExprMod::calc(const ObProxyExprCtx &ctx, + const ObProxyExprCalcItem &calc_item, + common::ObIArray &result_obj_array) +{ + int ret = OB_SUCCESS; + common::ObSEArray, 4> param_result_array; + int cnt = 0; + int64_t len = result_obj_array.count(); + + if (-1 != index_ && + ObProxyExprCalcItem::FROM_OBJ_ARRAY == calc_item.source_ && !has_agg_) { + if (OB_FAIL(ObProxyExpr::calc(ctx, calc_item, result_obj_array))) { + LOG_WARN("calc expr failed", K(ret)); + } + } + + if (OB_SUCC(ret) && len == result_obj_array.count()) { + if (2 != param_array_.count()) { + ret = OB_EXPR_CALC_ERROR; + LOG_WARN("mod should have two param", K(ret), K(param_array_.count())); + } else if (OB_FAIL( + calc_param_expr(ctx, calc_item, param_result_array, cnt))) { + LOG_WARN("calc param result failed", K(ret)); + } else { + int i = 0; + do { + common::ObSEArray param_result; + for (int64_t j = 0; OB_SUCC(ret) && j < param_result_array.count(); j++) { + ObObj tmp_obj; + if (param_result_array.at(j).count() == 1) { + tmp_obj = param_result_array.at(j).at(0); + } else { + tmp_obj = param_result_array.at(j).at(i); + } + if (OB_FAIL(param_result.push_back(tmp_obj))) { + LOG_WARN("push back obj failed", K(ret), K(i), K(j)); + } + } + + if (OB_SUCC(ret)) { + ObObj obj1 = param_result.at(0); + ObObj obj2 = param_result.at(1); + ObObj result_obj; + + if (ObDoubleTC == obj1.get_type_class() || + ObDoubleTC == obj2.get_type_class()) { + if (OB_FAIL((get_obj_for_calc(ctx.allocator_, obj1, obj2)))) { + LOG_WARN("get double obj failed", K(obj1), K(obj2), K(ret)); + } else if (fabs(obj2.get_double()) < DBL_EPSILON) { + result_obj.set_double(obj1.get_double()); + } else { + double obj1_d = obj1.get_double(); + double obj2_d = obj2.get_double(); + result_obj.set_double(obj1_d - obj2_d * floor(obj1_d / obj1_d)); + } + } else if (ObFloatTC == obj1.get_type_class() || ObFloatTC == obj2.get_type_class()) { + if (OB_FAIL((get_obj_for_calc(ctx.allocator_, obj1, obj2)))) { + LOG_WARN("get float obj failed", K(obj1), K(obj2), K(ret)); + } else if (fabs(obj2.get_float()) < FLT_EPSILON) { + result_obj.set_float(obj1.get_float()); + } else { + float obj1_f = obj1.get_float(); + float obj2_f = obj2.get_float(); + result_obj.set_float(obj1_f - obj2_f * floor(obj1_f / obj1_f)); + } + } else { + number::ObNumber res_nmb; + if (OB_FAIL((get_obj_for_calc(ctx.allocator_, obj1, obj2)))) { + LOG_WARN("get number obj failed", K(ret), K(obj1), K(obj2)); + } else if (obj2.get_number().is_zero()) { + result_obj.set_number(obj1.get_number()); + } else if (OB_FAIL(obj1.get_number().rem(obj2.get_number(), res_nmb, *ctx.allocator_))) { + LOG_WARN("failed to mod numbers", K(ret), K(obj1), K(obj2)); + } else if (OB_SUCC(ret)) { + result_obj.set_number(res_nmb); + } + } + + if (OB_SUCC(ret) && OB_FAIL(result_obj_array.push_back(result_obj))) { + LOG_WARN("result obj array push back failed", K(ret)); + } + } + } while (OB_SUCC(ret) && ++i < cnt); + } + } + ObProxyExpr::print_proxy_expr(this); + return ret; +} + } // end opsql } // end obproxy } // end oceanbase diff --git a/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr.h b/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr.h index cda8fca6a..e7ff08008 100644 --- a/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr.h +++ b/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr.h @@ -13,10 +13,11 @@ #ifndef OB_FUNC_EXPR_PROXY_EXPR_H #define OB_FUNC_EXPR_PROXY_EXPR_H -#include "opsql/func_expr_resolver/proxy_expr/ob_proxy_expr_type.h" #include "dbconfig/ob_proxy_db_config_info.h" #include "lib/allocator/ob_mod_define.h" #include "lib/ob_define.h" +#include "opsql/func_expr_resolver/proxy_expr/ob_proxy_expr_type.h" +#include "proxy/mysqllib/ob_proxy_session_info.h" namespace oceanbase { @@ -30,15 +31,26 @@ class ObProxyExprCtx { public: explicit ObProxyExprCtx(const int64_t physical_size, dbconfig::ObTestLoadType type, - bool is_elastic_index, common::ObIAllocator* allocator) + bool is_elastic_index, common::ObIAllocator *allocator) : sharding_physical_size_(physical_size), test_load_type_(type), is_elastic_index_(is_elastic_index), - allocator_(allocator), scale_(-1) {} + allocator_(allocator), scale_(-1), is_oracle_mode(false) {} + explicit ObProxyExprCtx(const int64_t physical_size, + dbconfig::ObTestLoadType type, bool is_elastic_index, + common::ObIAllocator *allocator, + proxy::ObClientSessionInfo *client_session_info) + : sharding_physical_size_(physical_size), test_load_type_(type), + is_elastic_index_(is_elastic_index), allocator_(allocator), scale_(-1), + client_session_info_(client_session_info), is_oracle_mode(false) {} ~ObProxyExprCtx() {} void set_sharding_physical_size(const int64_t physical_size) { sharding_physical_size_ = physical_size; } void set_test_load_type(const dbconfig::ObTestLoadType type) { test_load_type_ = type; } void set_is_elastic_index(const bool is_elastic_index) { is_elastic_index_ = is_elastic_index; } void set_scale(const int64_t scale) { scale_ = scale; }; + void set_client_session_info(proxy::ObClientSessionInfo *client_session_info) + { + client_session_info_ = client_session_info; + } public: int64_t sharding_physical_size_; @@ -46,6 +58,8 @@ class ObProxyExprCtx bool is_elastic_index_; common::ObIAllocator *allocator_; int64_t scale_; + proxy::ObClientSessionInfo *client_session_info_; + bool is_oracle_mode; }; struct ObProxyExprCalcItem { @@ -255,6 +269,8 @@ class ObProxyFuncExpr : public ObProxyExpr virtual ~ObProxyFuncExpr(); int add_param_expr(ObProxyExpr* expr) { return param_array_.push_back(expr); } + int64_t get_param_conut() { return param_array_.count(); } + int calc_param_expr(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem &calc_item, common::ObSEArray, 4> ¶m_result, int &cnt); @@ -263,7 +279,7 @@ class ObProxyFuncExpr : public ObProxyExpr void set_param_array(common::ObSEArray& param_array) { param_array_ = param_array; } public: - static int get_int_obj(const common::ObObj &src, common::ObObj &dst); + static int get_int_obj(const common::ObObj &src, common::ObObj &dst, common::ObIAllocator &allocator); static int get_varchar_obj(const common::ObObj &src, common::ObObj &dst, common::ObIAllocator &allocator); int check_varchar_empty(const common::ObObj& result); @@ -415,6 +431,56 @@ class ObProxyExprSplit : public ObProxyFuncExpr common::ObIArray &result_obj_array); }; +// include to_date and to_timestamp +class ObProxyExprToTimeHandler : public ObProxyFuncExpr +{ +public: + explicit ObProxyExprToTimeHandler() {} + explicit ObProxyExprToTimeHandler(ObObjType &target_type) : target_type_(target_type) {} + ~ObProxyExprToTimeHandler() {} + int calc(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem &calc_item, + common::ObIArray &result_obj_array); + void set_target_type(ObObjType target_type) { target_type_ = target_type; } +private: + ObObjType target_type_; +}; + +class ObProxyExprNvl : public ObProxyFuncExpr +{ +public: + explicit ObProxyExprNvl() {} + ~ObProxyExprNvl() {} + int calc(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem &calc_item, + common::ObIArray &result_obj_array); +}; + +class ObProxyExprToChar : public ObProxyFuncExpr +{ +public: + explicit ObProxyExprToChar() {} + ~ObProxyExprToChar() {} + int calc(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem &calc_item, + common::ObIArray &result_obj_array); +}; + +class ObProxyExprSysdate : public ObProxyFuncExpr +{ +public: + explicit ObProxyExprSysdate() {} + ~ObProxyExprSysdate() {} + int calc(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem &calc_item, + common::ObIArray &result_obj_array); +}; + +class ObProxyExprMod : public ObProxyFuncExpr +{ +public: + explicit ObProxyExprMod() {} + ~ObProxyExprMod() {} + int calc(const ObProxyExprCtx &ctx, const ObProxyExprCalcItem &calc_item, + common::ObIArray &result_obj_array); +}; + } // end opsql } // end obproxy } // end oceanbase diff --git a/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr_type.h b/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr_type.h index 6554cb504..115929f36 100644 --- a/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr_type.h +++ b/src/obproxy/opsql/func_expr_resolver/proxy_expr/ob_proxy_expr_type.h @@ -38,6 +38,12 @@ typedef enum ObProxyExprType OB_PROXY_EXPR_TYPE_FUNC_ORDER, OB_PROXY_EXPR_TYPE_FUNC_TESTLOAD, OB_PROXY_EXPR_TYPE_FUNC_SPLIT, + OB_PROXY_EXPR_TYPE_FUNC_TO_DATE, + OB_PROXY_EXPR_TYPE_FUNC_TO_TIMESTAMP, + OB_PROXY_EXPR_TYPE_FUNC_NVL, + OB_PROXY_EXPR_TYPE_FUNC_TO_CHAR, + OB_PROXY_EXPR_TYPE_FUNC_SYSDATE, + OB_PROXY_EXPR_TYPE_FUNC_MOD, OB_PROXY_EXPR_TYPE_MAX, }ObProxyExprType; @@ -112,6 +118,24 @@ const char* get_expr_type_name(int expr_type) case OB_PROXY_EXPR_TYPE_FUNC_TESTLOAD: type_name = "OB_PROXY_EXPR_TYPE_FUNC_TESTLOAD"; break; + case OB_PROXY_EXPR_TYPE_FUNC_TO_DATE: + type_name = "OB_PROXY_EXPR_TYPE_FUNC_TO_DATE"; + break; + case OB_PROXY_EXPR_TYPE_FUNC_TO_TIMESTAMP: + type_name = "OB_PROXY_EXPR_TYPE_FUNC_TO_TIMESTAMP"; + break; + case OB_PROXY_EXPR_TYPE_FUNC_NVL: + type_name = "OB_PROXY_EXPR_TYPE_FUNC_NVL"; + break; + case OB_PROXY_EXPR_TYPE_FUNC_TO_CHAR: + type_name = "OB_PROXY_EXPR_TYPE_FUNC_TO_CHAR"; + break; + case OB_PROXY_EXPR_TYPE_FUNC_SYSDATE: + type_name = "OB_PROXY_EXPR_TYPE_FUNC_SYSDATE"; + break; + case OB_PROXY_EXPR_TYPE_FUNC_MOD: + type_name = "OB_PROXY_EXPR_TYPE_FUNC_MOD"; + break; case OB_PROXY_EXPR_TYPE_MAX: type_name = "OB_PROXY_EXPR_TYPE_MAX"; break; diff --git a/src/obproxy/opsql/parser/ob_proxy_parse_result.cpp b/src/obproxy/opsql/parser/ob_proxy_parse_result.cpp index 7c375f3a4..97046f70d 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parse_result.cpp +++ b/src/obproxy/opsql/parser/ob_proxy_parse_result.cpp @@ -116,9 +116,6 @@ const char* get_print_stmt_name(const ObProxyBasicStmtType type) case OBPROXY_T_SELECT_TX_RO: str_ret = "SELECT_TX_RO"; break; - case OBPROXY_T_SET_AC_0: - str_ret = "SET"; - break; case OBPROXY_T_PING_PROXY: str_ret = "PING"; break; @@ -191,6 +188,25 @@ const char* get_print_stmt_name(const ObProxyBasicStmtType type) str_ret = "DESC"; break; + case OBPROXY_T_SHOW_MASTER_STATUS: + str_ret = "SHOW_MASTER_STATUS"; + break; + case OBPROXY_T_SHOW_BINLOG_EVENTS: + str_ret = "SHOW_BINLOG_EVENTS"; + break; + case OBPROXY_T_PURGE_BINARY_LOGS: + str_ret = "PURGE_BINARY_LOGS"; + break; + case OBPROXY_T_RESET_MASTER: + str_ret = "RESET_MASTER"; + break; + case OBPROXY_T_SHOW_BINLOG_SERVER_FOR_TENANT: + str_ret = "SHOW_BINLOG_SERVER_FOR_TENANT"; + break; + case OBPROXY_T_SHOW_BINARY_LOGS: + str_ret = "SHOW_BINARY_LOGS"; + break; + case OBPROXY_T_INVALID: case OBPROXY_T_MAX: case OBPROXY_T_OTHERS: @@ -348,9 +364,6 @@ const char* get_obproxy_stmt_name(const ObProxyBasicStmtType type) case OBPROXY_T_SELECT_PROXY_VERSION: str_ret = "OBPROXY_T_SELECT_PROXY_VERSION"; break; - case OBPROXY_T_SET_AC_0: - str_ret = "OBPROXY_T_SET_AC_0"; - break; case OBPROXY_T_SHOW_WARNINGS: str_ret = "OBPROXY_T_SHOW_WARNINGS"; break; @@ -411,6 +424,12 @@ const char* get_obproxy_stmt_name(const ObProxyBasicStmtType type) case OBPROXY_T_TEXT_PS_DROP: str_ret = "OBPROXY_T_TEXT_PS_DROP"; break; + case OBPROXY_T_LOGIN: + str_ret = "OBPROXY_T_LOGIN"; + break; + case OBPROXY_T_DESC: + str_ret = "OBPROXY_T_DESC"; + break; case OBPROXY_T_MAX: str_ret = "OBPROXY_T_MAX"; break; @@ -506,6 +525,9 @@ const char* get_obproxy_sub_stmt_name(const ObProxyBasicStmtSubType type) case OBPROXY_T_SUB_ROUTE_ROUTINE: str_ret = "OBPROXY_T_SUB_ROUTE_ROUTINE"; break; + case OBPROXY_T_SUB_SHOW_ELASTIC_ID: + str_ret = "OBPROXY_T_SUB_SHOW_ELASTIC_ID"; + break; case OBPROXY_T_SUB_SHOW_TOPOLOGY: str_ret = "OBPROXY_T_SUB_SHOW_TOPOLOGY"; break; diff --git a/src/obproxy/opsql/parser/ob_proxy_parse_result.h b/src/obproxy/opsql/parser/ob_proxy_parse_result.h index 145532c2d..04574905a 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parse_result.h +++ b/src/obproxy/opsql/parser/ob_proxy_parse_result.h @@ -87,7 +87,6 @@ typedef enum ObProxyBasicStmtType // internal request OBPROXY_T_BEGIN, OBPROXY_T_SELECT_TX_RO, - OBPROXY_T_SET_AC_0, OBPROXY_T_PING_PROXY, OBPROXY_T_SELECT_ROUTE_ADDR, OBPROXY_T_SET_ROUTE_ADDR, @@ -126,6 +125,14 @@ typedef enum ObProxyBasicStmtType // only for print obproxy_stat log OBPROXY_T_LOGIN, + // binglog related + OBPROXY_T_SHOW_MASTER_STATUS, + OBPROXY_T_SHOW_BINARY_LOGS, + OBPROXY_T_SHOW_BINLOG_EVENTS, + OBPROXY_T_PURGE_BINARY_LOGS, + OBPROXY_T_RESET_MASTER, + OBPROXY_T_SHOW_BINLOG_SERVER_FOR_TENANT, + OBPROXY_T_MAX } ObProxyBasicStmtType; @@ -196,6 +203,7 @@ typedef enum ObProxyBasicStmtSubType OBPROXY_T_SUB_SHOW_FULL_TABLES, OBPROXY_T_SUB_SHOW_TABLE_STATUS, OBPROXY_T_SUB_SHOW_CREATE_TABLE, + OBPROXY_T_SUB_SHOW_ELASTIC_ID, OBPROXY_T_SUB_SHOW_TOPOLOGY, OBPROXY_T_SUB_SHOW_DB_VERSION, OBPROXY_T_SUB_SHOW_COLUMNS, @@ -332,7 +340,7 @@ typedef struct _ObDbMeshRouteInfo typedef enum _ObProxySetValueType { - SET_VALUE_TYPE_ONE = 0, + SET_VALUE_TYPE_NONE = 0, SET_VALUE_TYPE_STR, SET_VALUE_TYPE_INT, SET_VALUE_TYPE_NUMBER, @@ -379,6 +387,7 @@ typedef struct _ObDbpRouteInfo ObProxyParseString table_name_; ObProxyParseString group_idx_str_; bool scan_all_; + bool sticky_session_; bool has_shard_key_; ObDbpShardKeyInfo shard_key_infos_[OBPROXY_MAX_DBP_SHARD_KEY_NUM]; int shard_key_count_; @@ -426,6 +435,9 @@ typedef struct _ObProxyParseResult ObProxyParseString col_name_; ObProxyParseString trace_id_; ObProxyParseString rpc_id_; + + // store the route server address in sql comment + ObProxyParseString target_db_server_; // read_consistency ObProxyReadConsistencyType read_consistency_type_; // db/table name diff --git a/src/obproxy/opsql/parser/ob_proxy_parser.h b/src/obproxy/opsql/parser/ob_proxy_parser.h index ab2436a27..27167a992 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parser.h +++ b/src/obproxy/opsql/parser/ob_proxy_parser.h @@ -152,6 +152,7 @@ inline int ObProxyParser::obparse(const common::ObString &sql_string, common::ObString parse_sql_string = sql_string; //set ; ob parse need end with ; bool add_semicolon = false; + char origin_byte = parse_sql_string.ptr()[sql_string.length() - 2]; if (parse_sql_string.ptr()[sql_string.length() - 3] != ';') { parse_sql_string.ptr()[sql_string.length() - 2] = ';'; add_semicolon = true; @@ -169,7 +170,7 @@ inline int ObProxyParser::obparse(const common::ObString &sql_string, } } if (add_semicolon) { - parse_sql_string.ptr()[sql_string.length() - 2] = '\0'; + parse_sql_string.ptr()[sql_string.length() - 2] = origin_byte; } } return ret; diff --git a/src/obproxy/opsql/parser/ob_proxy_parser.l b/src/obproxy/opsql/parser/ob_proxy_parser.l index e01bb1396..ef1c29f7b 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parser.l +++ b/src/obproxy/opsql/parser/ob_proxy_parser.l @@ -269,6 +269,7 @@ do {\ %x prepare %x insert_all_expr %x set_expr +%x show_elastic_id %x show_topology %x show_tables %x proxy_icmd_state @@ -281,8 +282,10 @@ multi_byte_right_parenthesis [\uff09] multi_byte_connect_char /*According to connection character to set by gen_parse.sh*/ space [ \t\n\r\f] identifer (([A-Za-z0-9$_#]|{multi_byte_connect_char})*) -int_num [\-\+]?[0-9]+ -number ([0-9]+E[-+]?[0-9]+)|([0-9]+"."[0-9]*E[-+]?[0-9]+)|("."[0-9]+E[-+]?[0-9]+)|([0-9]+"."[0-9]*)|("."[0-9]+) + +/* limit the length of int_num from 1 to 17 in case of int64_t out of bound, 17 -> [ ( length of 2^64 ) - 2 ]*/ +int_num [\-\+]?[0-9]{1,17} +number ([\-]?[0-9]+E[-+]?[0-9]+)|([\-]?[0-9]+"."[0-9]*E[-+]?[0-9]+)|([\-]?"."[0-9]+E[-+]?[0-9]+)|([\-]?[0-9]+"."[0-9]*)|([\-]?"."[0-9]+)|([\-\+]?[0-9]{18,}) comment_identifer [\-\+]?{identifer} odp_comment_identifer ([\-\+]?[A-Za-z0-9$_\-]*) @@ -301,7 +304,6 @@ c_cmt_end \*+\/ tx_read_only (@@session{space}*\.{space}*tx_read_only|@@tx_read_only) autocommit (@@session{space}*\.{space}*autocommit|@@autocommit|autocommit) -autocommit_0 ({autocommit}{space}*={space}*0) set_names (set{space}+names{space}+) set_charset (set{space}+charset{space}+|set{space}+character{space}+set{space}+) set_password (set{space}+password{space}+) @@ -357,7 +359,8 @@ show_full_tables (show{space}+full{space}+tables) show_create_table (show{space}+create{space}+table) show_columns (show{space}+(full{space}+)?(columns|fields)) show_index (show{space}+(index|indexes|keys)) -show_topology (show{space}+elastic_id) +show_elastic_id (show{space}+elastic_id) +show_topology (show{space}+topology) show_db_version (show{space}+database_version) select_database (select{space}+database({leftbracket}|{multi_byte_left_parenthesis})({rightbracket}|{multi_byte_right_parenthesis})) alter_proxyconfig (alter{space}+proxyconfig) @@ -369,6 +372,15 @@ select_proxy_version (select{space}+proxy_version{space}*({leftbracket}|{m select_obproxy_route_addr (select{space}+@obproxy_route_addr) set_obproxy_route_addr (set{space}+@obproxy_route_addr) + +/* binlog relate SQL */ +show_master_status (show{space}+master{space}+status) +show_binary_logs (show{space}+binary{space}+logs) +show_binlog_events (show{space}+binlog{space}+events) +purge_binary_logs (purge{space}+binary{space}+logs) +reset_master (reset{space}+master) +show_binlog_server_for_tenant (show{space}+binlog{space}+server{space}+for{space}+tenant) + %% /* basic dml stmt: */ @@ -390,7 +402,7 @@ CALL { SET_BASIC_STMT(OBPROXY_T_CALL); return CALL; } DECLARE { SET_HAS_ANONYMOUS_BLOCK(); PUSH_STATE(in_anonymous_block); } WHEN { ObProxyParseResult *p = yyget_extra(yyscanner); if (OB_NOTNULL(p)) { - if (OBPROXY_T_INSERT == p->cur_stmt_type_) + if (OBPROXY_T_INSERT == p->cur_stmt_type_) PUSH_STATE(insert_all_expr); } return WHEN; } @@ -411,7 +423,7 @@ UNIQUE { return UNIQUE; } USING { return USING; } PREPARE { PUSH_STATE(prepare); return PREPARE; } EXECUTE { return EXECUTE; } -DEALLOCATE { return DEALLOCATE; } +DEALLOCATE { return DEALLOCATE; } /* oracle ddl stmt */ @@ -445,7 +457,7 @@ ALL { return ALL; } LIKE { return LIKE; } PARTITION { return PARTITION; } BINARY { return BINARY; } -GROUP_NAME { return GROUP_NAME; } +GROUP_NAME { RETURN_NON_RESERVED_KEYWORD(GROUP_NAME); } /* to make bison easy, do not return these reserved keyword in non strict mode */ IGNORE { RETURN_IGNORED_WORD(); } @@ -549,13 +561,15 @@ REFRESH { RETURN_NON_RESERVED_KEYWORD(REFRESH); } UPGRADE { RETURN_NON_RESERVED_KEYWORD(UPGRADE); } IDC { RETURN_NON_RESERVED_KEYWORD(IDC); } -{show_topology} { SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_topology); return SHOW_TOPOLOGY; } -"FROM" { POP_STATE(); PUSH_STATE(INITIAL); return FROM; } -"WHERE" { POP_STATE(); PUSH_STATE(INITIAL); return WHERE; } -<> { return END_P; } -{whitespace} { } -; { POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } -. { return ERROR; } +{show_elastic_id} { SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_elastic_id ); return SHOW_ELASTIC_ID; } +"FROM" { POP_STATE(); PUSH_STATE(INITIAL); return FROM; } +"WHERE" { POP_STATE(); PUSH_STATE(INITIAL); return WHERE; } +<> { return END_P; } +{whitespace} { } +; { POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } +. { return ERROR; } + +{show_topology} { SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_TOPOLOGY; } {show_db_version} { SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_DB_VERSION; } {show_databases} { SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_DATABASES; } @@ -647,7 +661,13 @@ LAST_INSERT_ID { SET_LAST_INSERT_ID(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } return MERGE_HINT_BEGIN; } -{autocommit_0} { return AUTOCOMMIT_0; } +{show_master_status} { SET_BASIC_STMT(OBPROXY_T_SHOW_MASTER_STATUS); return SHOW_MASTER_STATUS; } +{show_binary_logs} { SET_BASIC_STMT(OBPROXY_T_SHOW_BINARY_LOGS); return SHOW_BINARY_LOGS; } +{show_binlog_events} { SET_BASIC_STMT(OBPROXY_T_SHOW_BINLOG_EVENTS); return SHOW_BINLOG_EVENTS; } +{purge_binary_logs} { SET_BASIC_STMT(OBPROXY_T_PURGE_BINARY_LOGS); return PURGE_BINARY_LOGS; } +{reset_master} { SET_BASIC_STMT(OBPROXY_T_RESET_MASTER); return RESET_MASTER; } +{show_binlog_server_for_tenant} { SET_BASIC_STMT(OBPROXY_T_SHOW_BINLOG_SERVER_FOR_TENANT); return SHOW_BINLOG_SERVER_FOR_TENANT; } + "global" { return GLOBAL; } "session" { return SESSION; } {int_num} { RETURN_INT_NUM(); } @@ -802,6 +822,7 @@ LAST_INSERT_ID { SET_LAST_INSERT_ID(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } {space}*"trace_id" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(TRACE_ID); } {space}*{comment_identifer}"." { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT_NAME_OB_DOT(NAME_OB_DOT); } {space}*"rpc_id" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(RPC_ID); } +{space}*"target_db_server" { PUSH_STATE(in_odp_comment_expr); return TARGET_DB_SERVER; } "group_id" { return GROUP_ID; } "table_id" { return TABLE_ID; } @@ -812,6 +833,7 @@ LAST_INSERT_ID { SET_LAST_INSERT_ID(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } "tnt_id" { return TNT_ID; } "trace_id" { return TRACE_ID; } "rpc_id" { return RPC_ID; } +"target_db_server" { return TARGET_DB_SERVER; } {sqbegin} { ENTER_QUOTE_STATE(comment_sq); } {comma}|{multi_byte_comma} { return ','; } {odp_comment_identifer} { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } @@ -882,6 +904,7 @@ LAST_INSERT_ID { SET_LAST_INSERT_ID(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } "$ROUTE" { return ROUTE_TAG; } "$SYS" { return SYS_TAG; } "SCAN_ALL" { return SCAN_ALL; } +"STICKY_SESSION" { return STICKY_SESSION; } "SHARDING_KEY" { return SHARD_KEY; } "table_name" { return TABLE_NAME;} "parallelism" { return PARALL; } @@ -1135,7 +1158,6 @@ LAST_INSERT_ID { SET_LAST_INSERT_ID(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } "last_insert_id" { SET_LAST_INSERT_ID(); RETURN_IGNORED_WORD(); } "global" { SET_GLOBAL_SET_STMT(); RETURN_IGNORED_WORD(); } {tx_read_only} { RETURN_COL_NAME(TX_READ_ONLY); } -{autocommit_0} { return AUTOCOMMIT_0; } {identifer} { RETURN_IGNORED_WORD(); } <> { return END_P; } {whitespace} { } @@ -1169,7 +1191,7 @@ LAST_INSERT_ID { SET_LAST_INSERT_ID(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } {dquote} { POP_STATE(); } {quote} { POP_STATE(); } -"BEGIN" { POP_STATE(); return BEGI;} +"BEGIN" { POP_STATE(); RETURN_NON_RESERVED_KEYWORD(BEGI);} . {} <> { return END_P; } diff --git a/src/obproxy/opsql/parser/ob_proxy_parser.y b/src/obproxy/opsql/parser/ob_proxy_parser.y index 5e930f58a..dbd0eda37 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parser.y +++ b/src/obproxy/opsql/parser/ob_proxy_parser.y @@ -39,9 +39,6 @@ static inline void handle_stmt_end(ObProxyParseResult* result) case OBPROXY_T_SELECT_TX_RO: result->stmt_type_ = OBPROXY_T_SELECT; break; - case OBPROXY_T_SET_AC_0: - result->stmt_type_ = OBPROXY_T_OTHERS; - break; case OBPROXY_T_BEGIN: result->stmt_type_ = OBPROXY_T_OTHERS; break; @@ -60,7 +57,7 @@ static inline void handle_stmt_end(ObProxyParseResult* result) } } else { result->stmt_type_ = result->cur_stmt_type_; - } + } if (OBPROXY_T_TEXT_PS_PREPARE == result->text_ps_inner_stmt_type_) { ObProxyBasicStmtType tmp_type = result->cur_stmt_type_; @@ -289,19 +286,19 @@ extern void *obproxy_parse_malloc(const size_t nbyte, void *malloc_pool); %token FROM DUAL %token PREPARE EXECUTE USING DEALLOCATE %token SELECT_HINT_BEGIN UPDATE_HINT_BEGIN DELETE_HINT_BEGIN INSERT_HINT_BEGIN REPLACE_HINT_BEGIN MERGE_HINT_BEGIN HINT_END COMMENT_BEGIN COMMENT_END ROUTE_TABLE ROUTE_PART_KEY QUERY_TIMEOUT READ_CONSISTENCY WEAK STRONG FROZEN PLACE_HOLDER -%token END_P ERROR +%token END_P ERROR %token WHEN /* non-reserved keyword */ %token FLASHBACK AUDIT NOAUDIT %token BEGI START TRANSACTION READ ONLY WITH CONSISTENT SNAPSHOT INDEX XA %token WARNINGS ERRORS TRACE %token QUICK COUNT AS WHERE VALUES ORDER GROUP HAVING INTO UNION FOR -%token TX_READ_ONLY AUTOCOMMIT_0 SELECT_OBPROXY_ROUTE_ADDR SET_OBPROXY_ROUTE_ADDR +%token TX_READ_ONLY SELECT_OBPROXY_ROUTE_ADDR SET_OBPROXY_ROUTE_ADDR %token NAME_OB_DOT NAME_OB EXPLAIN DESC DESCRIBE NAME_STR %token USE HELP SET_NAMES SET_CHARSET SET_PASSWORD SET_DEFAULT SET_OB_READ_CONSISTENCY SET_TX_READ_ONLY GLOBAL SESSION %token NUMBER_VAL -%token GROUP_ID TABLE_ID ELASTIC_ID TESTLOAD ODP_COMMENT TNT_ID DISASTER_STATUS TRACE_ID RPC_ID -%token DBP_COMMENT ROUTE_TAG SYS_TAG TABLE_NAME SCAN_ALL PARALL SHARD_KEY +%token GROUP_ID TABLE_ID ELASTIC_ID TESTLOAD ODP_COMMENT TNT_ID DISASTER_STATUS TRACE_ID RPC_ID TARGET_DB_SERVER +%token DBP_COMMENT ROUTE_TAG SYS_TAG TABLE_NAME SCAN_ALL STICKY_SESSION PARALL SHARD_KEY %token INT_NUM %type right_string_val tracer_right_string_val name_right_string_val %type call_expr @@ -323,12 +320,13 @@ extern void *obproxy_parse_malloc(const size_t nbyte, void *malloc_pool); %token SHOW_PROXYSTAT REFRESH %token SHOW_PROXYTRACE %token SHOW_PROXYINFO BINARY UPGRADE IDC -%token SHOW_TOPOLOGY GROUP_NAME SHOW_DB_VERSION +%token SHOW_ELASTIC_ID SHOW_TOPOLOGY GROUP_NAME SHOW_DB_VERSION %token SHOW_DATABASES SHOW_TABLES SHOW_FULL_TABLES SELECT_DATABASE SHOW_CREATE_TABLE SELECT_PROXY_VERSION SHOW_COLUMNS SHOW_INDEX %token ALTER_PROXYCONFIG %token ALTER_PROXYRESOURCE %token PING_PROXY %token KILL_PROXYSESSION KILL_GLOBALSESSION KILL QUERY +%token SHOW_MASTER_STATUS SHOW_BINARY_LOGS SHOW_BINLOG_EVENTS PURGE_BINARY_LOGS RESET_MASTER SHOW_BINLOG_SERVER_FOR_TENANT %type table_factor non_reserved_keyword var_name %start root @@ -372,6 +370,7 @@ stmt: select_stmt {} | ddl_stmt {} | text_ps_stmt {} | merge_stmt {} + | binlog_stmt {} | other_stmt { result->cur_stmt_type_ = OBPROXY_T_OTHERS; } select_stmt: select_with_opt_hint select_expr_list opt_from @@ -433,7 +432,7 @@ text_ps_prepare_args_stmt : text_ps_prepare_var_list | text_ps_from_stmt -text_ps_prepare_stmt: PREPARE var_name FROM +text_ps_prepare_stmt: PREPARE var_name FROM { result->text_ps_inner_stmt_type_ = OBPROXY_T_TEXT_PS_PREPARE; result->text_ps_name_ = $2; @@ -496,17 +495,14 @@ select_tx_read_only_stmt: SELECT TX_READ_ONLY { result->cur_stmt_type_ = OBPROXY select_proxy_version_stmt: SELECT_PROXY_VERSION | SELECT_PROXY_VERSION AS var_name { result->col_name_ = $3; } -set_autocommit_0_stmt: SET AUTOCOMMIT_0 { result->cur_stmt_type_ = OBPROXY_T_SET_AC_0; } - | SET AUTOCOMMIT_0 expr_list - hooked_stmt: select_tx_read_only_stmt {} | select_proxy_version_stmt {} - | set_autocommit_0_stmt {} | select_obproxy_route_addr_stmt {} | set_obproxy_route_addr_stmt {} | shard_special_stmt {} shard_special_stmt: show_es_id_stmt {} + | show_topology_stmt {} | show_db_version_stmt {} | SELECT_DATABASE { result->sub_stmt_type_ = OBPROXY_T_SUB_SELECT_DATABASE; } | SHOW_DATABASES { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_DATABASES; } @@ -515,8 +511,9 @@ shard_special_stmt: show_es_id_stmt {} | show_columns_stmt {} | show_index_stmt {} | SHOW_CREATE_TABLE routine_name_stmt { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_CREATE_TABLE; } - | explain_or_desc routine_name_stmt + | explain_or_desc var_name { + result->table_info_.table_name_ = $2; result->cur_stmt_type_ = OBPROXY_T_DESC; result->sub_stmt_type_ = OBPROXY_T_SUB_DESC_TABLE; } @@ -567,21 +564,28 @@ show_table_status_stmt: SHOW TABLE STATUS opt_show_from opt_show_like show_db_version_stmt: SHOW_DB_VERSION { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_DB_VERSION; } -show_es_id_stmt: SHOW_TOPOLOGY { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; } - | SHOW_TOPOLOGY FROM NAME_OB +show_es_id_stmt: SHOW_ELASTIC_ID { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; } + | SHOW_ELASTIC_ID FROM NAME_OB { SET_ICMD_ONE_STRING($3); - result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; + result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; } - | SHOW_TOPOLOGY WHERE GROUP_NAME '=' NAME_OB + | SHOW_ELASTIC_ID WHERE GROUP_NAME '=' NAME_OB { SET_ICMD_SECOND_STRING($5); - result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; + result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; } - | SHOW_TOPOLOGY FROM NAME_OB WHERE GROUP_NAME '=' NAME_OB + | SHOW_ELASTIC_ID FROM NAME_OB WHERE GROUP_NAME '=' NAME_OB { SET_ICMD_ONE_STRING($3); SET_ICMD_SECOND_STRING($7); + result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; + } + +show_topology_stmt: SHOW_TOPOLOGY { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; } + | SHOW_TOPOLOGY FROM NAME_OB + { + result->table_info_.table_name_ = $3; result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; } @@ -771,7 +775,7 @@ comment_expr: COMMENT_BEGIN comment_list COMMENT_END {} | COMMENT_BEGIN DISASTER_STATUS '=' right_string_val odp_comment_list COMMENT_END { result->dbmesh_route_info_.disaster_status_str_ = $4; } | COMMENT_BEGIN DBP_COMMENT ROUTE_TAG '=' '{' dbp_comment_list '}' COMMENT_END {} | COMMENT_BEGIN DBP_COMMENT SYS_TAG '=' '{' dbp_sys_comment '}' COMMENT_END {} - + | COMMENT_BEGIN TARGET_DB_SERVER '=' right_string_val odp_comment_list COMMENT_END { result->target_db_server_ = $4; } comment_list: /* empty */ {} | comment_list comment @@ -794,6 +798,7 @@ dbp_comment: GROUP_ID '(' right_string_val ')' } | SCAN_ALL '(' ')' { result->dbp_route_info_.scan_all_ = true; } | SCAN_ALL '(' PARALL '=' right_string_val ')' { result->dbp_route_info_.scan_all_ = true; } + | STICKY_SESSION '(' ')' { result->dbp_route_info_.sticky_session_ = true; } | SHARD_KEY '(' dbp_kv_comment_list ')' {result->dbp_route_info_.has_shard_key_ = true;} dbp_sys_comment: TRACE '(' tracer_right_string_val')' { result->trace_id_ = $3; } @@ -822,6 +827,7 @@ odp_comment: GROUP_ID '=' right_string_val { result->dbmesh_route_info_.group_ | RPC_ID '=' tracer_right_string_val { result->rpc_id_ = $3; } | TNT_ID '=' right_string_val { result->dbmesh_route_info_.tnt_id_str_ = $3; } | DISASTER_STATUS '=' right_string_val { result->dbmesh_route_info_.disaster_status_str_ = $3; } + | TARGET_DB_SERVER '=' right_string_val { result->target_db_server_ = $3; } | NAME_OB '.' NAME_OB '=' name_right_string_val { malloc_shard_column_node($$, $1, $3, DBMESH_TOKEN_STR_VAL); @@ -848,10 +854,10 @@ delete_with_opt_hint: DELETE insert_with_opt_hint: INSERT insert_all_when | INSERT_HINT_BEGIN hint_list_with_end insert_all_when -insert_all_when: +insert_all_when: | ALL | ALL WHEN - + replace_with_opt_hint: REPLACE | REPLACE_HINT_BEGIN hint_list_with_end merge_with_opt_hint: MERGE @@ -911,6 +917,13 @@ icmd_stmt: show_proxynet | kill_globalsession | kill_mysql +binlog_stmt: SHOW_MASTER_STATUS {} + | SHOW_BINARY_LOGS {} + | SHOW_BINLOG_EVENTS {} + | PURGE_BINARY_LOGS {} + | RESET_MASTER {} + | SHOW_BINLOG_SERVER_FOR_TENANT {} + /* limit param stmt*/ opt_limit: /*empty*/ @@ -1172,24 +1185,7 @@ non_reserved_keyword: START | UPGRADE | IDC | QUERY - | GROUP_ID - | TABLE_ID - | ELASTIC_ID - | TESTLOAD | GROUP_NAME - | ODP_COMMENT - | TNT_ID - | DISASTER_STATUS - | TRACE_ID - | RPC_ID - | DBP_COMMENT - | ROUTE_TAG - | SYS_TAG - | TABLE_NAME - | PARALL - | SCAN_ALL - | SHARD_KEY - | INDEX | FLASHBACK | AUDIT | NOAUDIT diff --git a/src/obproxy/opsql/parser/ob_proxy_parser_gbk_lex.c b/src/obproxy/opsql/parser/ob_proxy_parser_gbk_lex.c index 1deffdefe..6e7ce96ca 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parser_gbk_lex.c +++ b/src/obproxy/opsql/parser/ob_proxy_parser_gbk_lex.c @@ -348,8 +348,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); yyg->yy_hold_char = *yy_cp; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 336 -#define YY_END_OF_BUFFER 337 +#define YY_NUM_RULES 344 +#define YY_END_OF_BUFFER 345 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -357,264 +357,285 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[2327] = +static yyconst flex_int16_t yy_accept[2515] = { 0, - 146, 146, 189, 189, 0, 0, 0, 0, 202, 202, - 230, 230, 0, 0, 0, 0, 0, 0, 258, 258, + 147, 147, 195, 195, 0, 0, 0, 0, 208, 208, + 238, 238, 0, 0, 0, 0, 0, 0, 267, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 307, 307, 0, 0, - 0, 0, 325, 325, 330, 330, 0, 0, 168, 168, - 0, 0, 0, 0, 0, 0, 337, 335, 156, 156, - 152, 282, 146, 146, 271, 153, 152, 144, 335, 152, - 152, 145, 151, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 288, 335, 335, 335, - - 335, 335, 335, 191, 336, 189, 188, 191, 191, 182, - 189, 189, 189, 189, 189, 189, 191, 191, 191, 191, - 191, 191, 195, 194, 195, 197, 197, 336, 197, 197, - 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, - 197, 197, 197, 197, 197, 197, 207, 207, 202, 207, - 207, 202, 202, 207, 207, 207, 207, 207, 207, 207, - 234, 233, 233, 230, 228, 234, 230, 229, 230, 232, - 231, 230, 230, 230, 230, 230, 234, 234, 240, 239, - 239, 236, 240, 237, 240, 240, 242, 241, 241, 241, - 242, 242, 242, 260, 257, 257, 258, 252, 253, 260, - - 258, 256, 258, 258, 258, 258, 258, 258, 260, 260, - 262, 261, 336, 336, 268, 267, 267, 265, 263, 264, - 268, 268, 268, 270, 269, 269, 269, 270, 270, 270, - 277, 278, 336, 272, 273, 336, 283, 284, 336, 290, - 291, 293, 294, 310, 308, 308, 298, 307, 307, 299, - 297, 310, 309, 310, 307, 307, 307, 307, 307, 300, - 310, 310, 310, 310, 310, 310, 334, 334, 317, 316, - 316, 314, 316, 315, 312, 313, 317, 317, 317, 317, - 327, 326, 326, 320, 325, 325, 321, 318, 319, 327, - 325, 325, 325, 327, 327, 327, 327, 327, 327, 331, - - 330, 332, 329, 330, 336, 336, 336, 336, 336, 336, - 178, 178, 176, 170, 170, 174, 168, 168, 173, 176, - 167, 176, 176, 166, 172, 171, 171, 168, 168, 168, - 175, 176, 176, 176, 176, 176, 176, 117, 115, 115, - 115, 117, 116, 117, 117, 117, 126, 124, 124, 124, - 126, 125, 126, 126, 126, 336, 336, 336, 156, 0, - 148, 0, 0, 0, 0, 0, 0, 0, 156, 146, - 156, 156, 156, 156, 156, 156, 146, 0, 0, 0, - 0, 0, 0, 0, 147, 0, 0, 0, 0, 0, - 0, 145, 0, 150, 192, 150, 145, 146, 146, 146, - - 44, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 8, 0, 149, 0, 0, 0, 0, - 0, 0, 0, 146, 154, 155, 144, 189, 0, 0, - 0, 0, 0, 0, 0, 190, 182, 182, 189, 189, - 189, 189, 189, 189, 0, 189, 179, 180, 0, 193, - 0, 0, 0, 217, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 196, 0, + 0, 0, 0, 0, 0, 0, 315, 315, 0, 0, + 0, 0, 333, 333, 338, 338, 0, 0, 174, 174, + 0, 0, 0, 0, 0, 0, 0, 0, 345, 343, + 157, 157, 153, 291, 147, 147, 280, 154, 153, 145, + 343, 153, 153, 146, 152, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 297, 343, + + 343, 343, 343, 343, 343, 197, 344, 195, 194, 197, + 197, 188, 195, 195, 195, 195, 195, 195, 197, 197, + 197, 197, 197, 197, 201, 200, 201, 203, 203, 344, + 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, 213, 213, + 208, 213, 213, 208, 208, 213, 213, 213, 213, 213, + 213, 213, 242, 241, 241, 238, 236, 242, 238, 237, + 238, 240, 239, 238, 238, 238, 238, 238, 242, 242, + 248, 247, 247, 244, 248, 245, 248, 248, 250, 249, + 249, 249, 250, 250, 250, 269, 266, 266, 267, 261, + + 262, 269, 267, 265, 267, 267, 267, 267, 267, 267, + 269, 269, 271, 270, 344, 344, 277, 276, 276, 274, + 272, 273, 277, 277, 277, 279, 278, 278, 278, 279, + 279, 279, 286, 287, 344, 281, 282, 344, 292, 293, + 344, 299, 300, 302, 303, 318, 316, 316, 307, 315, + 315, 308, 306, 318, 317, 318, 315, 315, 315, 315, + 309, 318, 318, 318, 318, 318, 318, 342, 342, 325, + 324, 324, 322, 324, 323, 320, 321, 325, 325, 325, + 325, 335, 334, 334, 328, 333, 333, 329, 326, 327, + 335, 333, 333, 333, 335, 335, 335, 335, 335, 335, + + 339, 338, 340, 337, 338, 344, 344, 344, 344, 344, + 344, 184, 184, 182, 176, 176, 180, 174, 174, 179, + 182, 173, 182, 182, 172, 178, 177, 174, 174, 181, + 182, 182, 182, 182, 182, 182, 117, 115, 115, 115, + 117, 116, 117, 117, 117, 127, 125, 125, 125, 127, + 126, 127, 127, 127, 344, 344, 344, 157, 0, 149, + 0, 0, 0, 0, 0, 0, 0, 157, 147, 157, + 157, 157, 157, 157, 157, 147, 0, 0, 0, 0, + 0, 0, 0, 148, 0, 0, 0, 0, 0, 0, + 146, 0, 0, 146, 151, 198, 151, 146, 147, 147, + + 147, 44, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 8, 0, 150, 0, 0, 0, + 0, 0, 0, 0, 147, 155, 156, 145, 195, 0, + 0, 0, 0, 0, 0, 0, 196, 188, 188, 195, + 195, 195, 195, 195, 195, 0, 195, 185, 186, 0, + 199, 0, 0, 0, 223, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, - 202, 0, 0, 0, 0, 0, 0, 0, 203, 0, - 0, 0, 0, 0, 0, 0, 206, 202, 202, 0, - 205, 0, 0, 0, 0, 0, 0, 0, 202, 230, - 0, 235, 230, 230, 230, 230, 230, 230, 230, 230, - 233, 229, 0, 238, 239, 237, 0, 241, 241, 258, - 258, 258, 0, 259, 258, 258, 258, 258, 258, 258, - 257, 254, 255, 256, 262, 261, 0, 266, 267, 264, - - 0, 269, 269, 277, 0, 0, 279, 0, 0, 280, - 272, 0, 0, 274, 0, 0, 275, 0, 285, 0, - 0, 0, 286, 290, 289, 293, 292, 308, 0, 308, - 307, 308, 308, 308, 308, 308, 308, 307, 0, 0, - 0, 0, 0, 0, 0, 0, 307, 307, 307, 307, - 307, 307, 0, 307, 297, 0, 316, 0, 316, 0, - 0, 312, 313, 326, 0, 326, 325, 326, 326, 326, - 326, 326, 326, 325, 0, 0, 0, 0, 0, 0, - 0, 325, 325, 325, 0, 325, 318, 319, 330, 0, - 0, 0, 0, 0, 0, 330, 0, 330, 0, 170, - - 0, 170, 168, 170, 170, 170, 170, 170, 170, 168, - 0, 0, 0, 0, 0, 0, 166, 0, 169, 169, - 166, 168, 0, 168, 168, 168, 0, 168, 167, 115, - 0, 115, 0, 0, 0, 124, 0, 124, 0, 0, - 0, 0, 0, 0, 0, 0, 156, 146, 0, 0, - 156, 0, 0, 150, 0, 0, 146, 55, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 42, 146, - 146, 146, 146, 146, 146, 146, 111, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 13, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 53, 146, - 146, 146, 146, 146, 146, 0, 0, 0, 189, 189, - 189, 189, 189, 189, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 210, 0, 0, 0, 0, 0, 0, + 0, 208, 0, 0, 0, 0, 0, 0, 0, 209, + 0, 0, 0, 0, 0, 0, 0, 212, 208, 208, + 0, 211, 0, 0, 0, 0, 0, 0, 0, 208, + 238, 0, 243, 238, 238, 238, 238, 238, 238, 238, + 238, 241, 237, 0, 246, 247, 245, 0, 249, 249, + 267, 267, 267, 0, 268, 267, 267, 267, 267, 267, + 267, 267, 266, 263, 264, 265, 271, 270, 0, 275, + + 276, 273, 0, 278, 278, 286, 0, 0, 288, 0, + 0, 289, 281, 0, 0, 283, 0, 0, 284, 0, + 294, 0, 0, 0, 295, 299, 298, 302, 301, 316, + 0, 316, 315, 316, 316, 316, 316, 316, 316, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 315, 315, + 315, 315, 315, 0, 315, 306, 0, 324, 0, 324, + 0, 0, 320, 321, 334, 0, 334, 333, 334, 334, + 334, 334, 334, 334, 333, 0, 0, 0, 0, 0, + 0, 0, 333, 333, 333, 0, 333, 326, 327, 338, + 0, 0, 0, 0, 0, 0, 338, 0, 338, 0, + + 176, 0, 176, 174, 176, 176, 176, 176, 176, 176, + 174, 0, 0, 0, 0, 0, 0, 172, 0, 0, + 172, 175, 175, 172, 174, 174, 174, 0, 174, 173, + 115, 0, 115, 0, 0, 0, 125, 0, 125, 0, + 0, 0, 0, 0, 0, 0, 0, 157, 147, 0, + 0, 146, 157, 0, 146, 0, 0, 151, 0, 146, + 0, 147, 55, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 42, 147, 147, 147, 147, 147, 147, + 147, 111, 147, 147, 147, 147, 147, 147, 147, 147, + + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 13, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 53, 147, 147, 147, 147, 147, + 147, 0, 0, 0, 188, 188, 195, 195, 195, 195, + 195, 195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 202, 202, 0, 0, 0, 230, 230, 230, 230, - 230, 230, 230, 230, 258, 258, 258, 258, 258, 258, - 258, 258, 281, 0, 281, 0, 276, 0, 276, 0, - 287, 0, 287, 0, 308, 307, 308, 0, 0, 0, - - 0, 307, 307, 307, 307, 307, 307, 0, 0, 316, - 0, 0, 326, 325, 326, 0, 325, 325, 325, 0, - 330, 0, 0, 170, 168, 170, 0, 0, 169, 0, - 0, 168, 0, 0, 168, 168, 168, 0, 115, 0, - 0, 0, 124, 0, 0, 0, 0, 0, 0, 0, - 156, 0, 156, 156, 156, 0, 150, 0, 150, 150, - 146, 146, 146, 146, 146, 146, 14, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 49, 18, 146, 146, - 146, 146, 146, 25, 146, 146, 146, 74, 146, 146, - 146, 146, 61, 137, 146, 56, 146, 146, 146, 146, - - 146, 146, 71, 146, 146, 146, 146, 146, 146, 146, - 51, 146, 146, 146, 146, 146, 146, 146, 146, 0, - 0, 7, 146, 146, 90, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 16, 146, - 52, 0, 189, 189, 189, 189, 189, 184, 0, 0, - 0, 0, 208, 0, 0, 0, 0, 0, 0, 0, - 0, 202, 202, 0, 230, 230, 230, 230, 230, 230, - 230, 230, 258, 245, 258, 258, 258, 258, 258, 258, - 0, 0, 0, 0, 0, 0, 308, 308, 308, 308, - 0, 0, 0, 307, 307, 296, 307, 307, 307, 0, - - 316, 316, 316, 0, 326, 326, 326, 326, 325, 325, - 325, 328, 177, 170, 170, 170, 170, 0, 169, 0, - 169, 169, 0, 0, 168, 168, 168, 115, 115, 115, - 113, 0, 124, 124, 124, 122, 123, 92, 94, 93, - 19, 146, 146, 37, 9, 146, 146, 146, 146, 146, - 66, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 31, 39, 146, 146, 146, 22, 146, 0, - 0, 146, 54, 146, 6, 146, 146, 146, 41, 146, - 0, 0, 146, 34, 138, 65, 146, 146, 146, 146, - 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 146, 10, 146, 23, 146, 69, - 146, 146, 43, 146, 146, 146, 27, 47, 146, 146, - 45, 189, 187, 189, 189, 189, 243, 0, 0, 0, - 0, 0, 198, 0, 0, 0, 202, 200, 230, 230, - 230, 230, 230, 230, 230, 230, 258, 258, 258, 258, - 258, 258, 251, 0, 0, 281, 0, 0, 0, 276, - 0, 0, 0, 287, 0, 0, 0, 0, 307, 307, - 0, 307, 0, 0, 307, 307, 307, 333, 0, 325, - 325, 325, 0, 0, 168, 168, 168, 114, 0, 0, - 146, 146, 58, 146, 11, 146, 146, 17, 146, 146, - - 146, 2, 146, 68, 146, 146, 146, 146, 146, 40, - 146, 60, 3, 0, 0, 0, 146, 146, 0, 0, - 0, 146, 146, 84, 146, 0, 0, 146, 146, 21, - 146, 32, 146, 146, 146, 1, 0, 0, 0, 0, + 208, 208, 0, 0, 0, 238, 238, 238, 238, 238, + 238, 238, 238, 238, 267, 267, 267, 267, 267, 267, + 267, 267, 267, 290, 0, 290, 0, 285, 0, 285, + + 0, 296, 0, 296, 0, 316, 315, 316, 0, 0, + 0, 315, 315, 315, 315, 315, 0, 0, 324, 0, + 0, 334, 333, 334, 0, 333, 333, 333, 0, 338, + 0, 0, 176, 174, 172, 176, 0, 172, 0, 0, + 175, 0, 172, 0, 174, 174, 174, 0, 115, 0, + 0, 0, 125, 0, 0, 0, 0, 0, 0, 0, + 157, 0, 146, 157, 157, 157, 146, 151, 0, 151, + 0, 151, 146, 147, 147, 147, 147, 147, 147, 14, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 49, + 18, 147, 147, 147, 147, 147, 25, 147, 147, 147, + + 74, 147, 147, 147, 147, 61, 138, 147, 56, 147, + 147, 147, 147, 147, 147, 71, 147, 147, 147, 147, + 147, 147, 147, 51, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 0, 0, 7, 147, 147, 90, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 16, 147, 52, 0, 188, 188, 195, 195, + 195, 195, 195, 190, 0, 0, 0, 0, 214, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 208, 208, + 0, 238, 238, 238, 238, 238, 238, 238, 238, 238, + 267, 253, 267, 267, 267, 267, 267, 267, 267, 0, + + 0, 0, 0, 0, 0, 316, 316, 316, 316, 0, + 0, 315, 305, 315, 315, 315, 0, 324, 324, 324, + 0, 334, 334, 334, 334, 333, 333, 333, 336, 183, + 176, 172, 176, 176, 176, 172, 175, 0, 175, 0, + 175, 172, 174, 174, 115, 115, 115, 113, 0, 125, + 125, 125, 123, 124, 92, 94, 93, 146, 146, 146, + 19, 147, 147, 37, 9, 147, 147, 147, 147, 147, + 66, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 31, 39, 147, 147, 147, 22, 147, 0, + 0, 147, 54, 147, 6, 147, 147, 147, 41, 147, + + 0, 0, 147, 34, 139, 65, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 147, 10, 147, 23, 147, + 69, 147, 147, 43, 147, 147, 147, 27, 47, 147, + 147, 45, 188, 188, 195, 193, 195, 195, 195, 251, + 0, 0, 0, 0, 0, 204, 0, 0, 0, 0, + 208, 206, 238, 238, 238, 238, 238, 238, 238, 238, + 238, 267, 267, 267, 267, 267, 267, 267, 260, 0, + 0, 290, 0, 0, 0, 285, 0, 0, 0, 296, + 0, 0, 0, 315, 0, 315, 0, 0, 315, 315, + + 315, 341, 0, 333, 333, 333, 172, 172, 172, 174, + 174, 114, 146, 146, 146, 0, 0, 147, 147, 58, + 147, 11, 147, 147, 17, 147, 147, 147, 2, 147, + 68, 147, 147, 147, 147, 147, 40, 147, 60, 3, + 0, 0, 0, 147, 147, 0, 0, 0, 147, 147, + 84, 147, 0, 0, 147, 0, 0, 147, 21, 147, + 0, 0, 32, 147, 147, 147, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 146, 24, 82, 146, - 146, 26, 4, 146, 46, 146, 146, 186, 189, 189, - 185, 0, 0, 0, 0, 218, 0, 0, 215, 0, - 202, 230, 230, 230, 227, 230, 230, 225, 230, 244, - 258, 258, 258, 258, 258, 0, 0, 0, 307, 307, - - 0, 0, 0, 0, 0, 307, 307, 0, 307, 0, - 0, 0, 0, 0, 0, 0, 304, 307, 307, 311, - 325, 325, 325, 0, 0, 168, 164, 168, 0, 0, - 33, 146, 35, 146, 146, 146, 15, 63, 0, 0, - 0, 146, 29, 48, 146, 146, 146, 146, 0, 0, - 0, 0, 0, 146, 146, 0, 0, 38, 103, 146, - 0, 28, 107, 5, 146, 100, 146, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 147, + 24, 82, 147, 147, 26, 4, 147, 46, 147, 147, + + 188, 188, 192, 195, 195, 191, 0, 0, 0, 0, + 224, 0, 0, 0, 221, 0, 208, 238, 238, 238, + 234, 238, 238, 238, 232, 238, 252, 267, 267, 267, + 267, 267, 267, 0, 0, 315, 0, 0, 0, 0, + 0, 315, 315, 0, 315, 0, 0, 0, 0, 0, + 0, 0, 313, 315, 315, 319, 333, 333, 333, 172, + 172, 172, 170, 174, 146, 146, 146, 0, 0, 33, + 147, 35, 147, 147, 147, 15, 63, 0, 0, 0, + 147, 29, 48, 147, 147, 147, 147, 0, 0, 0, + 0, 0, 147, 147, 0, 0, 38, 103, 147, 0, + + 28, 0, 0, 107, 5, 0, 0, 147, 100, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 146, 146, 146, 0, 0, 0, 110, - - 146, 146, 189, 189, 0, 0, 0, 0, 0, 0, - 0, 0, 202, 230, 230, 230, 230, 230, 230, 230, - 258, 258, 258, 258, 258, 0, 0, 0, 307, 307, - 0, 0, 0, 0, 0, 307, 0, 307, 0, 307, - 307, 307, 0, 0, 307, 307, 325, 325, 325, 0, - 0, 168, 165, 0, 146, 146, 146, 146, 0, 0, - 50, 146, 146, 146, 146, 0, 0, 0, 0, 146, - 146, 0, 0, 162, 146, 0, 0, 0, 0, 12, - 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 147, + 147, 147, 0, 0, 0, 110, 147, 147, 188, 188, + 195, 195, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 208, 238, 238, 238, 238, 238, 238, 238, 238, + 267, 267, 267, 267, 267, 267, 0, 0, 315, 0, + 0, 0, 0, 0, 315, 0, 315, 0, 315, 315, + 315, 0, 0, 315, 315, 333, 333, 333, 172, 172, + + 172, 171, 146, 146, 146, 0, 147, 147, 147, 147, + 0, 0, 50, 147, 147, 147, 147, 0, 0, 0, + 0, 147, 147, 0, 0, 163, 147, 0, 0, 0, + 0, 0, 0, 12, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, - 146, 20, 0, 0, 146, 67, 189, 189, 0, 0, - 209, 199, 210, 0, 213, 216, 201, 230, 230, 219, - 220, 230, 223, 226, 250, 258, 246, 258, 258, 0, - 0, 0, 307, 307, 0, 0, 0, 0, 0, 307, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 307, - 307, 325, 325, 325, 0, 0, 168, 0, 88, 146, - 146, 146, 0, 0, 159, 36, 146, 146, 146, 0, - 0, 160, 0, 0, 146, 146, 0, 0, 0, 0, - 57, 0, 0, 0, 142, 0, 0, 0, 0, 0, - - 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 128, 0, 0, 0, 0, 0, 146, 0, 0, 158, - 89, 189, 189, 0, 0, 0, 230, 230, 230, 258, - 258, 258, 0, 0, 0, 307, 307, 0, 295, 0, - 0, 0, 0, 0, 0, 0, 295, 0, 0, 0, - 0, 0, 0, 0, 307, 302, 325, 325, 323, 0, - 0, 168, 0, 83, 72, 30, 0, 0, 0, 0, - 141, 59, 146, 0, 0, 0, 0, 0, 0, 146, - 146, 0, 0, 0, 134, 0, 0, 161, 0, 0, - + 0, 0, 0, 0, 0, 0, 73, 147, 20, 0, + 0, 147, 67, 188, 188, 195, 195, 0, 0, 215, + 205, 216, 0, 0, 219, 222, 207, 238, 238, 226, + 227, 238, 238, 230, 233, 259, 267, 254, 267, 267, + + 267, 0, 0, 315, 0, 0, 0, 0, 0, 315, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 315, + 315, 333, 333, 333, 172, 172, 172, 146, 146, 146, + 0, 88, 147, 147, 147, 0, 0, 160, 36, 147, + 147, 147, 0, 0, 161, 0, 0, 147, 147, 0, + 0, 0, 0, 57, 0, 0, 0, 0, 0, 143, + 0, 0, 0, 0, 0, 158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, - 0, 146, 0, 0, 0, 0, 189, 189, 0, 212, - 211, 230, 222, 221, 258, 258, 248, 0, 0, 0, - 0, 0, 307, 301, 295, 0, 0, 0, 0, 0, - 0, 0, 0, 307, 322, 325, 0, 0, 0, 0, - 168, 0, 0, 0, 0, 146, 0, 0, 0, 0, - 0, 146, 146, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 129, 0, 0, + 0, 0, 0, 0, 0, 147, 0, 0, 159, 89, + + 188, 188, 195, 195, 0, 0, 0, 0, 238, 238, + 238, 238, 267, 267, 267, 267, 0, 0, 315, 0, + 304, 0, 0, 0, 0, 0, 0, 0, 304, 0, + 0, 0, 0, 0, 0, 0, 315, 311, 333, 333, + 331, 172, 172, 172, 146, 146, 146, 0, 83, 72, + 30, 0, 0, 0, 0, 142, 59, 147, 0, 0, + 0, 0, 0, 0, 147, 147, 0, 0, 0, 135, + 0, 0, 0, 162, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, + 0, 0, 0, 0, 129, 0, 0, 0, 0, 0, + 0, 0, 147, 0, 0, 0, 0, 188, 188, 195, + 195, 0, 218, 217, 0, 238, 229, 228, 238, 267, + 267, 267, 257, 0, 0, 0, 0, 310, 304, 0, + 0, 0, 0, 0, 0, 0, 0, 315, 330, 333, + 172, 172, 172, 146, 146, 146, 0, 0, 0, 0, + 147, 0, 0, 0, 0, 0, 147, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 120, 0, 70, 0, 0, 0, - 189, 189, 0, 230, 249, 258, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 295, 307, 325, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, - 0, 0, 0, 146, 62, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, - 78, 0, 0, 0, 0, 127, 0, 0, 0, 0, - 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 95, 0, 0, 0, 0, 105, 0, 189, - 189, 0, 230, 247, 0, 0, 0, 0, 0, 0, - 306, 0, 295, 307, 325, 0, 0, 0, 0, 163, - 0, 0, 0, 0, 64, 0, 0, 0, 146, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, - 0, 101, 104, 0, 181, 189, 0, 230, 0, 0, - 0, 307, 325, 0, 0, 0, 159, 0, 160, 0, - 0, 0, 143, 0, 0, 0, 0, 157, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 119, 0, 0, 0, 0, 0, 0, 0, 0, 109, - 0, 0, 0, 0, 106, 0, 158, 0, 189, 0, - 230, 0, 0, 305, 303, 324, 0, 0, 0, 0, - 0, 161, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 112, 0, - 0, 0, 0, 0, 0, 0, 0, 99, 0, 108, - 189, 214, 224, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 121, 0, 0, 70, 0, 0, + 0, 188, 188, 195, 195, 0, 0, 238, 238, 258, + 267, 267, 0, 0, 0, 0, 0, 304, 315, 333, + 172, 172, 172, 146, 146, 146, 0, 0, 0, 147, + 0, 0, 0, 147, 62, 0, 0, 0, 0, 0, + 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 76, 0, 78, 0, 0, 0, 0, 0, 0, 0, + 0, 128, 0, 0, 0, 0, 0, 0, 129, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 95, 0, 0, 0, 0, 0, 105, 0, 188, 188, + 195, 195, 0, 0, 238, 238, 256, 267, 0, 0, + 304, 315, 333, 172, 172, 172, 146, 146, 146, 0, + 0, 0, 64, 0, 0, 0, 147, 163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 80, 0, 0, 121, 0, 87, 0, 91, 0, - - 102, 0, 0, 183, 0, 0, 0, 132, 0, 0, - 135, 0, 130, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 80, 0, 129, 0, 0, 96, 0, 0, - 86, 0, 0, 0, 0, 136, 0, 0, 0, 0, - 0, 80, 0, 76, 0, 0, 0, 85, 0, 97, - 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, + 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, + 0, 0, 0, 0, 0, 101, 104, 118, 0, 188, + 188, 187, 195, 0, 0, 238, 238, 267, 0, 0, + 315, 333, 172, 172, 172, 146, 146, 146, 0, 0, + + 160, 0, 161, 0, 0, 0, 144, 0, 0, 0, + 0, 0, 158, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 120, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, + 0, 0, 0, 106, 0, 159, 0, 188, 188, 195, + 0, 0, 238, 238, 255, 0, 314, 312, 332, 172, + 172, 172, 146, 146, 146, 0, 0, 0, 0, 0, + 162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 98, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 118, 0, - 0, 131, 0, 0, 0, 0, 0, 0, 305, 0, + 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 140, 79, 0, 0, 0, 0, 79, - 0, 0, 79, 0, 0, 139, 0, 80, 0, 0, - 0, 0, 0, 0, 79, 0 + 99, 0, 108, 188, 188, 195, 220, 0, 231, 238, + 0, 172, 172, 172, 146, 146, 146, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 80, 165, 0, 0, 0, 0, 122, + 0, 0, 87, 0, 91, 0, 102, 0, 0, 188, + 188, 189, 225, 235, 0, 172, 172, 172, 146, 146, + 146, 133, 0, 0, 136, 167, 0, 131, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, + 0, 130, 0, 0, 0, 96, 0, 0, 86, 188, + 188, 0, 172, 172, 172, 146, 146, 147, 0, 137, + + 0, 0, 0, 0, 0, 80, 0, 76, 0, 0, + 166, 0, 0, 85, 164, 0, 97, 188, 0, 172, + 172, 174, 151, 151, 147, 134, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 175, 175, + 174, 151, 151, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 98, 0, 175, 175, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 119, 0, 0, + 132, 0, 0, 0, 0, 0, 0, 0, 314, 0, + 0, 0, 0, 141, 79, 0, 0, 0, 0, 0, + 0, 79, 0, 0, 0, 79, 0, 0, 0, 140, + + 0, 80, 0, 0, 0, 0, 0, 0, 169, 0, + 0, 0, 79, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -623,2339 +644,2383 @@ static yyconst flex_int32_t yy_ec[256] = 1, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 5, 6, 7, 8, 5, 5, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 20, 21, 1, - 22, 1, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 51, 53, 54, 55, 56, 57, 58, 59, - - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 53, 82, 53, 51, 51, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 84, 85, 86, 87, 87, 87, 87, 88, 89, 90, - 90, 91, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 93, 93, 1 + 11, 12, 13, 14, 15, 16, 17, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 19, 20, 1, + 21, 1, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 50, 52, 53, 54, 55, 56, 57, 58, + + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 52, 81, 52, 50, 50, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, + 83, 84, 85, 86, 86, 86, 86, 87, 88, 89, + 89, 90, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 1 } ; -static yyconst flex_int32_t yy_meta[94] = +static yyconst flex_int32_t yy_meta[93] = { 0, 1, 2, 3, 3, 1, 4, 5, 6, 7, 1, - 1, 1, 8, 1, 9, 10, 1, 11, 11, 12, - 1, 1, 1, 13, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 13, 14, 13, 11, 15, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 13, 16, 16, 16, 16, 16, 17, 18, 16, - 19, 16, 16 + 1, 1, 2, 1, 8, 9, 1, 10, 11, 1, + 1, 1, 12, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 12, + 13, 12, 10, 14, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 12, 15, 15, 15, 15, 15, 16, 17, 15, 18, + 15, 15 } ; -static yyconst flex_int16_t yy_base[2511] = +static yyconst flex_int16_t yy_base[2700] = { 0, - 0, 0, 93, 0, 184, 185, 197, 0, 290, 0, - 383, 0, 475, 479, 492, 496, 0, 0, 582, 0, - 674, 677, 686, 697, 708, 719, 471, 476, 477, 481, - 486, 491, 3544, 3533, 3529, 3518, 805, 0, 499, 500, - 897, 911, 997, 0, 1090, 0, 504, 506, 1183, 0, - 1275, 1282, 1304, 1311, 486, 491, 3564,15602, 907, 1289, - 15602, 1314, 1407, 649, 1349,15602, 171,15602, 176, 174, - 3549, 1485,15602, 1563, 733, 909, 727, 913, 917, 1319, - 1449, 1492, 1351, 1524, 667, 1571, 1567, 1600, 1457, 1628, - 1633, 1650, 1671, 1326, 1700, 1427, 1682, 1728, 1769, 1777, - - 905, 1784, 493,15602,15602, 1757,15602, 501, 497, 1786, - 1810, 1822, 1840, 1857, 1876, 1892, 1979, 1986, 1993, 1305, - 2000, 502,15602,15602, 518,15602, 2081, 2173, 2265, 529, - 489, 0,15602, 491, 504, 500, 516, 657, 654, 1998, - 2357, 3466, 0, 533, 0, 673,15602, 2015, 2043, 2107, - 537, 2199, 2214, 2238, 2370, 2377, 2395, 684, 2419, 729, - 15602,15602,15602, 0,15602, 552, 0,15602, 0,15602, - 15602, 691, 708, 711, 714, 2018, 3448, 3436,15602,15602, - 15602,15602, 560,15602, 3434, 3422,15602,15602,15602,15602, - 562, 3426, 3402,15602,15602,15602, 722,15602,15602, 756, - - 0,15602, 0, 0, 715, 734, 912, 916, 3394, 688, - 15602,15602, 3372, 3356,15602,15602,15602,15602,15602,15602, - 774, 3349, 3342,15602,15602,15602,15602, 787, 3340, 713, - 0, 2135, 0, 0, 2144, 0,15602, 1747, 0, 0, - 3353, 0, 3349,15602, 1297, 1360,15602, 2501, 2225,15602, - 15602, 3382,15602, 3351, 2397, 2556, 1489, 2181, 877,15602, - 2519, 2526, 2599, 1262, 2606, 944,15602, 738,15602, 1373, - 1387,15602, 0,15602,15602,15602, 3337, 908, 3252, 878, - 15602, 1445, 1451,15602, 2688, 2249,15602,15602,15602, 3301, - 2583, 2474, 2643, 2737, 2744, 2786, 1546, 2793, 1269,15602, - - 2631,15602,15602, 2767, 2854, 2862, 2869, 1276, 2876, 1291, - 15602, 905,15602, 1600, 1610,15602, 2958, 2900,15602, 1298, - 15602, 1312, 1338, 3036,15602,15602, 3287, 1662, 1797, 1973, - 15602, 3007, 3015, 3056, 1445, 3094, 1407,15602, 1796, 1852, - 0, 3294,15602, 903, 917, 3216,15602, 1886, 1951, 0, - 3283,15602, 915, 1269, 3178, 1288, 1321, 1340, 2011, 3175, - 15602, 2912, 3133, 3147, 3154, 1432, 3173, 1451, 0, 3255, - 3348, 3164, 0, 3371, 0, 1461, 3154, 3388, 3395, 3402, - 1466, 3456, 1488, 3199,15602, 3464, 3478, 3516, 1497, 3534, - 1500, 1508, 2061, 2095,15602, 2189, 3601, 2438, 3547, 2475, - - 2193, 3114, 2804, 2211, 2873, 2364, 3563, 2731, 3608, 3234, - 3075, 3636, 3198, 3416, 3586, 3644, 3679, 3382, 3687, 3409, - 3683, 3701, 3717, 3485, 3722, 3708, 3751, 3773, 3778, 3785, - 3790, 3802, 3818, 3835, 2916, 3823, 3851, 3900, 3881, 3918, - 3863, 3926, 3947, 3965, 3971, 3979, 3983, 3999, 4033, 4038, - 4052, 3001, 4057, 4066, 3238,15602, 4084, 4120, 4123, 1519, - 4138, 1528, 4094, 4091,15602,15602,15602, 4123, 4141, 4210, - 4217, 1548, 4224, 1602, 1449,15602, 1635, 4226, 4250, 4167, - 4238, 4276, 4302, 4320, 4263, 4331,15602,15602, 1460,15602, - 4423, 4515, 0,15602, 1448, 1488, 1518, 1570, 1577, 3834, - - 4607, 3146, 0, 1640, 0, 1667, 3138, 1522,15602, 1617, - 1627, 1647, 1656, 1657, 1657, 1685, 1691, 1681, 1683, 1734, - 4357, 0,15602, 4449, 4469, 4537, 4621, 1686, 4628, 1702, - 4479, 4646, 4687, 4700, 1788, 4707, 1793, 4490,15602, 4725, - 4766, 4779, 1799, 4786, 1843, 1638,15602, 4786, 4797, 4808, - 15602, 4895, 4898, 4902, 1849, 4916, 1863, 4873, 4902, 0, - 1722,15602, 1735, 1769, 1788, 1807, 1861, 1861, 1913, 1970, - 15602,15602, 1802,15602,15602,15602, 1922,15602,15602, 0, - 1989, 1993, 2008,15602, 2010, 2008, 2032, 2037, 2060, 2064, - 15602,15602,15602,15602,15602,15602, 2060,15602,15602,15602, - - 2145,15602,15602, 0, 2365, 3210,15602, 3197, 3099,15602, - 0, 2395, 3168,15602, 3155, 3072,15602, 2462,15602, 3144, - 3127, 3050,15602, 0,15602, 0,15602, 2413, 3026, 0, - 4998, 5091, 3014, 0, 5114, 0, 1919, 4940, 4920, 5131, - 5138, 1953, 5145, 1955, 2537, 2791, 4972, 5147, 5171, 5182, - 5202, 5230, 4951, 4983,15602, 2087, 2600, 3008, 0, 2675, - 2143,15602,15602, 2683, 2989, 0, 5323, 5416, 2948, 0, - 5439, 0, 2142, 5087, 5456, 5463, 5470, 2162, 5524, 2164, - 2783, 5265, 5299, 5472, 5213, 5276,15602,15602, 5310, 5562, - 5575, 5583, 2166, 5601, 2207, 5585, 5412, 5601, 2159, 2937, - - 2940, 0, 5694, 5787, 2934, 0, 5810, 0, 2256, 5636, - 5827, 5834, 5841, 2258, 5895, 2276, 2301, 2945, 2415, 2677, - 5962, 4443, 2362, 4783, 4632, 5125, 5647, 4531,15602, 2951, - 2932, 0, 3004, 2166, 2185, 3075, 2928, 0, 3079, 2177, - 2186, 2211, 2410, 2449, 5667, 5784, 5678, 6055, 5841, 5852, - 3083, 2910, 2618, 2789, 2812, 2325, 5872, 5883, 5922, 5949, - 5910, 5998, 6010, 6067, 6082, 6043, 6138, 2887, 3501, 3605, - 4228, 4653, 4426, 3971, 3936, 4782, 4786, 3062, 3144, 3736, - 3884, 3797, 4003, 5179, 4081, 4428, 3991, 4359, 6172, 6173, - 4647, 5549, 4594, 6175, 6145, 4692, 6205, 5173, 4773, 3995, - - 4575, 6216, 5497, 6219, 5949, 6220, 6196, 6228, 6240, 6218, - 4698, 6237, 6257, 6265, 6269, 6267, 6286, 6314, 6290, 6282, - 6327, 6311, 6334, 6292, 6336, 6343, 6366, 6376, 6352, 6354, - 6382, 6373, 6386, 6396, 6398, 6106, 6391, 2327, 6404, 6439, - 6460, 6475, 6499, 6535, 2344, 6613, 6691, 2526, 3119, 2555, - 3028, 2543, 3165, 3276, 2609, 2757, 2372, 6421, 6548, 6488, - 6584, 6571, 6642, 6519, 6653, 2388, 2480, 2499, 2551, 2923, - 2624, 2663, 2908, 2756, 2753, 2800, 2834, 2860, 2874, 2877, - 2890, 3011,15602, 2943, 2914, 3112,15602, 2899, 2892, 3231, - 15602, 2884, 2876, 3315, 6602, 6784, 3331, 2787, 3061, 3191, - - 3201, 6678, 6734, 6765, 6802, 6821, 6666, 2422, 3241, 3496, - 2758, 3252, 6832, 6925, 3545, 2752, 6905, 6955, 6874, 2444, - 6936, 2477, 3335, 6966, 7059, 3552, 2740, 3284, 3476, 3559, - 2501, 7013, 3392, 3452, 7038, 7081, 7110, 2510, 3593, 2737, - 3453, 3449, 3760, 2722, 3469, 3491, 3560, 3574, 3567, 2529, - 2597, 2601, 0, 3883, 2685, 2637, 2735, 2739, 2746, 2784, - 7133, 7155, 7002, 7183, 7194, 7215, 7226, 7291, 3721, 3860, - 7292, 7293, 6780, 7298, 5600, 7356, 7299, 3879, 7300, 7357, - 7305, 4441, 6782, 3959, 7359, 7358, 7366, 4054, 4494, 7364, - 6921, 7372, 4941, 7409, 7125, 5957, 7410, 7411, 6329, 6923, - - 7417, 6584, 6650, 7419, 6869, 7455, 7435, 6942, 7127, 7126, - 7148, 7149, 7443, 7461, 7467, 7472, 7200, 7201, 7477, 7540, - 7538, 7548, 7495, 7532, 7537, 7306, 7592, 7489, 7542, 7600, - 7585, 7597, 7602, 7611, 7608, 7605, 7618, 7626, 7647, 7650, - 7652, 2878, 7634, 7649, 7664, 7675, 7705, 7692, 7753, 7831, - 3606, 4127,15602, 3604, 3784, 5450, 4790, 4090, 5477, 2880, - 2885, 7716, 7792, 2919, 3568, 3584, 3671, 3701, 3796, 3838, - 3842, 3872, 3905, 0, 3992, 4086, 2712, 4140, 4140, 4159, - 4761, 2664, 7130, 2662, 4591, 2658, 2947, 0, 4397, 2641, - 4203, 4206, 2638, 7803, 7842, 7934, 7944, 7813, 7950, 4235, - - 0, 4582, 2599, 4247, 3009, 0, 5075, 2580, 7952, 7901, - 7971, 7982,15602, 3018, 0, 5465, 2578, 3038, 3150, 3175, - 3185, 3192, 4393, 4483, 8019, 8057, 8068, 0, 5659, 2554, - 15602, 4583, 0, 5770, 2551,15602,15602,15602,15602,15602, - 8160, 8252, 5169, 4606, 4607, 4786, 5562, 5523, 7130, 4902, - 4687, 5524, 7439, 7776, 7914, 7916, 5617, 5807, 7034, 6566, - 7918, 4861, 4698, 5228, 6781, 7523, 7921, 4700, 7775, 8134, - 8344, 6920, 4733, 7781, 8116, 6922, 7783, 7785, 4765, 7928, - 8010, 8427, 7782, 4862, 4967, 5067, 7473, 8138, 8141, 8142, - 8145, 8045, 8046, 7929, 5571, 5162, 5251, 5256, 5416, 5461, - - 5465, 2548, 8510, 8593, 5616, 5561, 7784, 5601, 8144, 5663, - 8154, 8156, 5763, 8157, 8161, 8180, 5814, 8041, 8159, 8048, - 5816, 8189, 8200, 8295, 8236, 8327,15602, 8662, 8740, 5851, - 6398, 7840, 6399, 8060, 8064, 7198, 8370, 8220, 5878, 5955, - 2574, 5999, 2558, 5989, 6045, 2555, 6148, 2522, 6150, 6181, - 6220, 2501, 0, 2540, 7287, 2523, 696, 2499, 7341, 2483, - 698, 2463, 6513, 2452, 1404, 6303, 6302, 6572, 8382, 8410, - 8503, 8833, 2420, 8508, 8537, 8549, 8577,15602, 6605, 8596, - 8610, 8634, 6611, 6608, 8674, 8702, 8729,15602, 8230, 8925, - 8341, 8139, 6710, 8317, 6764, 8325, 8327, 6779, 8494, 8343, - - 8496, 8655, 8499, 6780, 8344, 8439, 8309, 8186, 8454, 6782, - 8728, 6851, 8726, 6969, 7163, 2336, 8498, 8898, 8933, 2399, - 9016, 8727, 7360, 7416, 8901, 7530, 2308, 8909, 8907, 7524, - 8911, 7538, 8914, 8913, 8219, 8964, 8957, 7627, 7674, 7670, - 7678, 2332, 7826, 2325, 7869, 7846, 7836, 8952, 7873, 7932, - 7987, 8006, 8008, 8065, 8075, 2263, 8143, 8133, 8179, 8925, - 8730, 8181, 9008, 8924, 8215, 8497, 8971, 8989, 9018, 9044, - 9032, 8927, 9026, 8233, 8997, 8235, 8453, 9030, 8343, 8376, - 9066, 8421, 8461, 8501, 0, 8975, 8533, 0, 8550, 0, - 8585, 8647, 8673, 8672, 8673, 8745, 8742, 8926, 9101, 9122, - - 9168, 8913, 2212, 9214, 9221, 0, 0, 9228, 8953, 9306, - 2195, 0, 9399, 0, 9243, 5836, 9248, 9259, 9284,15602, - 9381, 9408, 9430, 8988, 9021, 9441, 9345, 9466, 9014, 2166, - 9010, 9098, 9015, 9170, 9116, 9118, 9016, 9063, 9236, 2219, - 9558, 9117, 9097, 9152, 9210, 9205, 9229, 9226, 9279, 2175, - 9641, 9187, 9202, 9220, 9238, 2094, 3283, 9214, 9219, 9497, - 9239, 9234, 9242, 9566, 9513, 9272, 9534, 9595, 2110, 9724, - 9328, 9326, 9308, 9384, 9383, 9401, 9416, 9406, 9406, 9408, - 9415, 9424, 9463, 9483, 9481, 9475, 9473, 9512, 9495, 9525, - 9537, 9548, 9544, 9543, 9546, 9572, 9634, 2107, 9807, 9539, - - 9596, 9583, 9597, 9666, 9634, 9575, 9641, 9642, 9675, 9645, - 9682, 9705, 9698, 9558, 2061, 9613, 9640, 9646, 9685, 9686, - 9701, 9694, 9700, 9706, 9715, 9723, 9724, 9740, 9755, 9780, - 9872, 9878, 9892, 9741, 9901, 9745, 9984, 2027, 9910, 0, - 9727, 2008, 9937, 2006, 9918, 9944,10008, 9971,10041, 9734, - 9735,10052,10063, 9759, 9770, 9851, 9877, 9774, 1995, 3301, - 9752, 9876, 9872, 9898, 9897, 1992, 3404, 9795, 9774, 9828, - 10038, 3410, 2146,10020,10119, 9813,10105, 2057,10199, 9847, - 9874, 9863, 9918, 9917, 1982, 3417, 1975, 9921, 1968, 9942, - 10134, 9944, 9974, 9989, 9972,10022,10008,10056,10060,10043, - - 10051,10054,10134,10132,10119,10136,10139,10129,10128,10117, - 10135,10123, 1932, 3439,10131,10128,10142,10179,10191,10147, - 10149,10150,10209,10210,10211,10213,10201, 1955,10215, 0, - 0,10212, 0, 0, 0,10243, 0, 1952,10245,10258, - 10258,10269,10265,10252,10357,10264,10318,10363,10372,10265, - 10386,10392, 1915,10421,10431,10450,10459,10479,10489,10491, - 10510,10539,10558,10577,10266,10278,10607,10333,10334,10348, - 10398,10377, 3453, 2226,10465,10358,10421,10448,10464, 3581, - 2354,10508,10384,10370,10471,10466,10529,10651,10411, 1912, - 10422,10439, 1906, 3600,10472,10499,10482,10488, 3658, 2443, - - 10654,10493,10493,10497,10502,10532,10531,10552, 7702,10564, - 10565,10580,10569,10563,10582,10628,10645, 8003,10649,10627, - 15602,10647,10628,10633,10650,10644,10662, 3697, 3059,10716, - 10632,10673,10703,10704,10711,10712,10641,10657,10692,10679, - 10688,10695,10703, 8526, 1904,10729,10754,10846,15602,10852, - 10861,10868,10884,10914,10891,10951, 0,10967,10974,10981, - 10990,10997,11004,11013,11017,11028,11048,11081,11059,10709, - 10308,11109,10700,10700,10701,10724,10725,10959,10765, 1872, - 10749,10751,10851,11044,11092,10769, 1838,10767,10783,10829, - 10853,11075, 1835,10789,15602, 3710, 3078,11154,10791,10810, - - 10821,11158,11176,10844, 1808,10849,10859,10873,10859,10881, - 10882,10897, 8173, 1800,10921,10961,10985,10976,10992,10998, - 10991,10988,11179, 1779,11000,11008,10995,11237,11011,10999, - 11014,11153,11208,11224,11065, 1754,11232,11253,11171,11066, - 11152,11143, 0, 0,11151,11160, 0,11157,11229,11326, - 1739,11166,11409, 8649,11345,11359,11365,11374,11381,11423, - 11432,11452,11459,11331,11437,11462,11180,11274,11247, 1713, - 11554,11226,11564, 1705,11186,11223,11567, 1702,11192,11214, - 11229,11212,11342,11225,11570,11481,11293, 1698,11313,11338, - 11348,11575, 1677,11376,11392,11380,11412,11392,11413, 8353, - - 8712, 1703,11416, 1690,11403, 9376,11435,11452,15602,11442, - 11453,11478,11461,11465,11488,11524,11495,11530,11546,11554, - 11551,11540,11552,11553,15602,11558,11546,11595, 1657,11562, - 11577,11605,11648,11576, 0,11553,11559,11674,11559,11557, - 1631,11583,10234,11653,11695,11724,11738,11703,11726,11640, - 11718,11640, 1599,11759,11706,11777,11647,11672,11679,11684, - 11692,11709,11701,11718,11705, 9379,11790, 1579,11734,11734, - 11764, 1607,11756,11777,11768,11793, 1568,11781,10685, 1531, - 11123, 1527,11797,11823,11794,15602,11836, 1514,11805, 1504, - 11809,11812,15602,11806,11799,11807,11816,11810,11804,11807, - - 11806,11810,15602,11831,11832,11818,11816,15602,11818,11839, - 11856,11917,11819, 0,11893,11823, 1496,11832, 1464,11899, - 15602, 1460,11906,11933,11918,11950,11825, 1457,11955,15602, - 1448,11895,11895,11902,11906,11972,11917,11919,11935,11976, - 1438,11923,11920,11941,11942,12010, 1342,12019, 1333,11947, - 12022,11957,12026, 1290,11962,11993,11989,12000,12000,11994, - 12005,11997,12011,12005,12006,15602,12007,12003,12005,12006, - 12024,15602,15602,12050,12000,12028,12062,12020,12031,12032, - 12049,12120,12071,12061,12072,12065,12055, 1284,12141, 1265, - 12066,12103,12087,12147,12092,12117,12118,12167, 1262,12125, - - 12171,12178, 1255,12114,12126,12186, 1244,12128,12140,12159, - 15602,12146,12165,12166,12156,12158,12158,12170,12176,15602, - 12164,12163,12180,12177,15602,12182,12210, 1220,12188,12185, - 12176,12194,12198,15602,12241,12199,12208,12205,12219,12232, - 12228,12297, 1214, 1229, 892,12251,12258,12300,12279,12258, - 880,12269,12264,12281,12268,12263,12278,12286,15602,12273, - 12284,12274,12290,12289,12278,12273,12281,15602,12287,15602, - 12306,12294, 0,12290,12305,12292,12301,12291,12295,12297, - 12314, 703, 872,12326,12333, 898, 876,12336,12329,12330, - 12343,12375,12351,12340,15602,12344,15602,12343,15602,12344, - - 15602,12374,12368,12337,12371,12381,12373,15602,12385,12377, - 15602,12378,15602, 816,12385,12388,12391,12392,12386,12407, - 12448,12395,12451, 694,15602,12399,12406,15602,12412,12418, - 15602,12419, 720,12420,12429,15602,12415,12422,12430,12439, - 12441,12477, 717,12480, 666,12427,12439,15602,12435,15602, - 12444,12446,12453,15602,12446,12455,12452,12471,12472,12473, - 12471,12467,12469,12465,12472,12467,12483,12542,12474,12491, - 12492,12494,12485,12487,15602,12511,12498,12555, 662,12564, - 2594, 497, 478,12510, 506, 493,12519,12521,15602,12506, - 12535,15602, 445,12524,12536,12530,12529,12523,15602,12545, - - 12548,12537,12542,15602,12579,12556,12536,12549,12552,12594, - 448,12547,12606,12547,12543,15602,12566,12610,12558,12561, - 12593,12586,12598,12578,12631,15602,12715,12734,12753,12772, - 12791,12810,12829,12848,12867,12886,12905,12924,12943,12962, - 12981,13000,13016,13035,13050,13065,13080,13089,13104,13113, - 13130,13139,13152,13167,13182,13197,13206,13217,13223,13234, - 13253,13272,13291,13310,13329,13348,13367,13382,13391,13408, - 13427,13442,13451,13465,13474,13490,13505,13514,13533,13552, - 13568,13577,13593,13612,13631,13646,13655,13667,13676,13688, - 13697,13709,13718,13733,13742,13755,13764,13776,13785,13797, - - 13806,13818,13827,13838,13844,13855,13874,13893,13912,13931, - 13950,13969,13988,14007,14026,14041,14050,14066,14085,14104, - 14123,14138,14147,14159,14168,14184,14203,14222,14237,14246, - 14262,14281,14297,14316,14335,14350,14369,14384,14399,14414, - 14429,14445,14460,14475,14490,14504,14510,14521,14540,14559, - 14578,14597,14616,14631,14650,14669,14688,14707,14722,14737, - 14756,14775,14794,14809,14828,14847,14866,14885,14900,14915, - 14930,14945,14959,14965,14976,14995,15014,15033,15052,15067, - 15086,15105,15124,15139,15154,15173,15192,15207,15226,15245, - 15263,15278,15293,15308,15322,15328,15339,15358,15377,15392, - - 15411,15430,15449,15468,15487,15506,15525,15544,15563,15582 + 0, 0, 92, 0, 182, 183, 195, 0, 287, 0, + 379, 0, 470, 474, 487, 491, 0, 0, 576, 0, + 667, 670, 679, 690, 701, 712, 466, 471, 472, 476, + 481, 486, 4126, 4121, 4118, 4099, 797, 0, 494, 495, + 888, 902, 987, 0, 1079, 0, 499, 501, 1171, 0, + 1262, 1269, 0, 0, 1290, 1297, 481, 486, 4152,15625, + 898, 1276,15625, 1300, 1392, 643, 1334,15625, 4133,15625, + 172, 4121, 4126, 1469,15625, 1546, 508, 898, 720, 905, + 1295, 1429, 913, 1432, 726, 1478, 721, 1504, 1550, 1583, + 1554, 1508, 1616, 1621, 1632, 1412, 1679, 1413, 1631, 1681, + + 1721, 1729, 669, 1738, 4092,15625,15625, 1738,15625, 494, + 4091, 1749, 1770, 1781, 1799, 1816, 1835, 1851, 1937, 1943, + 1949, 658, 1955, 4077,15625,15625, 495,15625, 2035, 2126, + 2217, 497, 483, 0,15625, 483, 483, 488, 507, 511, + 499, 910, 2308, 4011, 0, 4075, 0, 4074,15625, 1998, + 2088, 2152, 531, 2167, 2205, 2191, 1961, 2050, 2320, 4071, + 2326, 4069,15625,15625,15625, 0,15625, 546, 0,15625, + 0,15625,15625, 510, 640, 637, 650, 1279, 4003, 3995, + 15625,15625,15625,15625, 667,15625, 4001, 3992,15625,15625, + 15625,15625, 683, 3998, 3915,15625,15625,15625, 699,15625, + + 15625, 748, 0,15625, 0, 0, 702, 723, 1734, 894, + 3856, 679,15625,15625, 3852, 3846,15625,15625,15625,15625, + 15625,15625, 751, 3844, 3837,15625,15625,15625,15625, 764, + 3840, 104, 0, 1510, 0, 0, 2025, 0,15625, 2142, + 0, 0, 3868, 0, 3860,15625, 1283, 1366,15625, 2407, + 2179,15625,15625, 3898,15625, 3889, 2462, 1420, 1303, 855, + 15625, 2333, 2387, 2424, 700, 2459, 3892,15625, 723,15625, + 1461, 1501,15625, 0,15625,15625,15625, 3862, 891, 3787, + 703,15625, 1722, 1797,15625, 2554, 2432,15625,15625,15625, + 3852, 2503, 2572, 2583, 2669, 2675, 2681, 892, 2687, 3848, + + 15625, 2527,15625,15625, 2687, 2737, 2774, 2786, 3844, 2792, + 3841,15625, 888,15625, 1810, 1813,15625, 2873, 2815,15625, + 3812,15625, 778, 3809, 2950,15625,15625, 2302, 1337,15625, + 2799, 2858, 2922, 680, 2929, 3808,15625, 1909, 1927, 0, + 3803,15625, 887, 901, 3734,15625, 1950, 1972, 0, 3800, + 15625, 902, 923, 3731, 1251, 1258, 1267, 1978, 3729,15625, + 2905, 2993, 2999, 3006, 3789, 3055, 3783, 0, 3136, 3228, + 3710, 0, 3250, 0, 3774, 3006, 3063, 3111, 3117, 3739, + 3266, 3736, 3090,15625, 3272, 3278, 3291, 3732, 3326, 3730, + 3726, 2067, 3694, 1576, 1480,15625, 1481, 3392, 1735, 3330, + + 2036, 1649, 2428, 2165, 1748, 2007, 2768, 2329, 1931, 3367, + 2684, 2910, 3084, 2805, 3346, 3385, 3401, 3260, 3427, 2724, + 2427, 2916, 3430, 3431, 3297, 3478, 2690, 3482, 3339, 3483, + 2374, 3489, 3173, 3497, 3502, 3049, 3503, 3518, 3566, 3558, + 3571, 3550, 3594, 3622, 3636, 3639, 3642, 3647, 3655, 3656, + 3702, 3705, 3353, 3706, 3710, 3699,15625, 3744, 3748, 3752, + 3684, 3798, 3678, 3120, 3713,15625,15625,15625, 3752, 3801, + 3838, 3850, 3673, 3857, 3671, 771,15625, 3630, 3858, 3882, + 3870, 3904, 3951, 3935, 3973, 3962, 3984,15625,15625, 903, + 15625, 4075, 4166, 0,15625, 1286, 1296, 1307, 1411, 1468, + + 2127, 4257, 3560, 0, 3623, 0, 3611, 3532, 1258,15625, + 1493, 1492, 1521, 1531, 1532, 1544, 1560, 1600, 1553, 1554, + 1599, 4037, 0,15625, 4101, 4090, 4188, 4270, 3589, 4276, + 3561, 4130, 4282, 4294, 4332, 3555, 4346, 3554, 4141,15625, + 4353, 4371, 4408, 3547, 4421, 3533, 1325,15625, 4394, 4408, + 4433,15625, 4519, 4522, 4525, 3517, 4528, 3511, 4421, 4470, + 0, 1359,15625, 1588, 1609, 1613, 1637, 1671, 1628, 1666, + 1730,15625,15625, 1383,15625,15625,15625, 1415,15625,15625, + 0, 1717, 1797, 1421,15625, 1808, 1856, 1891, 1941, 1939, + 1952, 1959,15625,15625,15625,15625,15625,15625, 1422,15625, + + 15625,15625, 1439,15625,15625, 0, 2460, 3500,15625, 3493, + 3409,15625, 0, 2524, 3482,15625, 3472, 3402,15625, 2201, + 15625, 3462, 3438, 3369,15625, 0,15625, 0,15625, 2111, + 3367, 0, 4609, 4701, 3358, 0, 4723, 0, 3417, 4499, + 4589, 4739, 4745, 3409, 4751, 3398, 2396, 1943, 4589, 4566, + 4754, 4774, 4802, 4693, 4785,15625, 1992, 2446, 3331, 0, + 2595, 2006,15625,15625, 2598, 3309, 0, 4894, 4986, 3305, + 0, 5008, 0, 3368, 4836, 4801, 5024, 5030, 3361, 5036, + 3357, 2620, 4868, 5037, 5053, 4847, 4879,15625,15625, 4978, + 5139, 5145, 5151, 3348, 5157, 3342, 5160, 5171, 5182, 2003, + + 2626, 3271, 0, 5274, 5366, 3267, 0, 5388, 0, 3313, + 5216, 5404, 5410, 5416, 3309, 5429, 3294, 3293, 2630, 3292, + 3795, 2088, 2304, 5495, 3856, 3865, 4390, 5227, 3804,15625, + 2647, 3224, 0, 2682, 2029, 2051, 2712, 3221, 0, 2859, + 2065, 2078, 2103, 2101, 2130, 5247, 5442, 5258, 5587, 5416, + 5454, 3285, 2866, 3219, 3878, 1769, 1780, 2689, 2213, 5664, + 3279, 5474, 5531, 5741, 2320, 2773, 2476, 2887, 2943, 2993, + 2780, 3369, 3512, 3406, 3044, 3436, 3408, 2426, 3494, 3631, + 3138, 3532, 2308, 2131, 3564, 2987, 3619, 3057, 3500, 3557, + 3569, 2258, 3666, 2270, 2347, 3704, 3585, 3955, 2453, 3677, + + 2479, 3155, 3340, 3859, 3634, 3699, 2478, 3956, 3247, 4073, + 3949, 3819, 3952, 3499, 3858, 3957, 4071, 2502, 3857, 4175, + 4072, 2752, 2620, 4264, 3751, 4259, 5030, 4307, 2652, 4383, + 4331, 5145, 4149, 4076, 2813, 4382, 4297, 4146, 5151, 5622, + 4536, 5542, 5613, 3276, 3275, 5624, 5642, 5707, 5695, 5761, + 5772, 5800, 3274, 5877, 5954, 3958, 4413, 3684, 4369, 2867, + 4732, 4255, 5157, 3160, 4412, 3273, 5784, 5812, 5823, 5908, + 5897, 5937, 5836, 5976, 3265, 2893, 2935, 3095, 3229, 3286, + 3321, 3357, 3201, 3412, 3508, 3626, 3701, 3881, 3964, 4039, + 4150, 4208, 4280,15625, 3244, 3190, 4000,15625, 3187, 3184, + + 4152,15625, 3154, 3127, 4198, 5847, 6068, 4643, 3048, 4315, + 4323, 5965, 6050, 6087, 6118, 6018, 3112, 4382, 4665, 3045, + 4442, 5866, 6210, 4681, 3044, 6160, 6191, 6231, 3108, 6267, + 3104, 4496, 6098, 6359, 3103, 4747, 3037, 5018, 2565, 2566, + 4776, 2748, 6436, 3093, 6253, 6513, 5058, 3086, 5089, 3001, + 4527, 4527, 5130, 3000, 4577, 4606, 4726, 4772, 4777, 3058, + 3057, 3051, 3050, 0, 5147, 2983, 5166, 3046, 3037, 3030, + 3013, 3012, 6590, 6667, 5372, 5621, 5279, 5378, 4809, 4900, + 6355, 5044, 6345, 5280, 5397, 5120, 5402, 5564, 5443, 4901, + 5115, 5165, 5477, 5611, 6353, 6072, 5373, 5479, 5615, 5700, + + 5400, 5424, 5401, 5698, 5447, 5614, 6387, 5763, 5616, 5699, + 5766, 6213, 6358, 5768, 6360, 5617, 5702, 6361, 6419, 6073, + 6425, 6357, 6366, 5703, 6427, 6057, 6215, 5901, 6422, 6090, + 6363, 6431, 6432, 6758, 6493, 6474, 5904, 6051, 5767, 6433, + 6438, 6489, 6054, 6441, 6126, 5960, 6194, 6508, 6501, 6509, + 6510, 6547, 5902, 6511, 6075, 3009, 3008, 6538, 6550, 6568, + 6613, 6631, 6761, 6642, 6721, 6838, 6122, 6216,15625, 6511, + 6433, 6512, 6513, 6700, 6704, 6589, 3007, 3002, 6777, 6811, + 3001, 6126, 6193, 6218, 6227, 6303, 6304, 6331, 6371, 6378, + 6438, 0, 6444, 6500, 2965, 6509, 6524, 6531, 6532, 5565, + + 2921, 6661, 2903, 6610, 2902, 2952, 0, 5568, 2860, 6665, + 2882, 6849, 6940, 6950, 6772, 6956, 6673, 0, 6664, 2850, + 6686, 2913, 0, 6685, 2838, 6958, 6908, 6977, 6799,15625, + 2900, 2898, 0, 6788, 2831, 6890, 2895, 2859, 2853, 2841, + 2840, 7054, 7131, 6739, 0, 6831, 2773,15625, 6741, 0, + 6834, 2771,15625,15625,15625,15625,15625, 2834, 6948, 7208, + 7299, 7006, 7049, 6975, 7015, 7033, 7081, 7074, 7093, 7088, + 7097, 7100, 7118, 7121, 7106, 7149, 7164, 7170, 7188, 7196, + 7231, 7235, 7203, 7266, 7246, 7238, 7261, 7242, 7279, 7309, + 7324, 7331, 7271, 7354, 7334, 7364, 7395, 7357, 7369, 7399, + + 7406, 7405, 7446, 7416, 7432, 7458, 7463, 7466, 7477, 7481, + 7488, 7493, 7498, 7504, 7508, 6755, 6752, 6758, 6764, 6764, + 6818, 6827, 2765, 7590, 7547, 7528, 7517, 7554, 7520, 7582, + 7524, 7666, 7672, 7575, 7675, 7678, 7639, 7602, 7610, 7684, + 7696, 7708, 2817, 7686, 7698, 7710, 7750, 7786, 7797,15625, + 7874, 7951, 6948, 6941, 6957, 6949, 7400, 7505, 7048, 7122, + 7886, 7731, 6835, 6847, 2778, 6888, 2777, 6876, 6918, 6956, + 2767, 7028, 2766, 7022, 7103, 7097, 7115, 2760, 0, 2803, + 7721, 2793, 1369, 2789, 7741, 2781, 1444, 2758, 7842, 2751, + 901, 7136, 7138, 7809, 7926, 8043, 2736, 8129, 7914, 8106, + + 8117,15625, 7186, 7933, 8150, 8176, 2729, 7643, 7887, 7660, + 7286,15625, 2728, 7673, 8253, 8146, 8266, 8216, 7862, 7826, + 8141, 7848, 8245, 8248, 7851, 8275, 8283, 8294, 7910, 8290, + 7857, 8301, 8304, 8321, 8351, 8331, 8138, 8359, 8160, 8170, + 7195, 7213, 2651, 8376, 8335, 8379, 2712, 8387, 8386, 8367, + 8163, 8404, 7237, 2618, 8417, 8422, 8456, 8449, 8413, 8453, + 8480, 8506, 8486, 8489, 8495, 8499, 8516, 7471, 7321, 7356, + 7364, 7379, 2644, 7380, 2643, 7409, 7667, 7420, 7503, 7684, + 7517, 7571, 7595, 7601, 7590, 7667, 7693, 7696, 2608, 8523, + 8538, 8546, 8562, 8573, 8549, 8577, 8581, 8593, 8599, 8608, + + 2672, 8610, 8621, 8640, 8651, 8662, 7876, 8365, 7697, 7891, + 7793, 7884, 7794, 8377, 7875, 7892, 8727, 7951, 7955, 7950, + 0, 8398, 2600, 7971, 0, 8107, 0, 8114, 8195, 8248, + 8258, 2594, 8272, 8281, 8315, 8715, 8762, 8368, 2548, 8768, + 8820, 0, 0, 8826, 8383, 8903, 2543, 0, 8995, 0, + 8854, 8633, 8803, 8859, 8881,15625, 8977, 9004, 9026, 2607, + 8589, 8602, 8422, 8449, 2602, 8615, 8846, 8413, 2520, 8675, + 8834, 8684, 8776, 8840, 9021, 8757, 8788, 8898, 2570, 9112, + 9077, 8936, 8956, 9095, 9120, 9129, 9071, 9054, 2550, 9163, + 8490, 8493, 9123, 9136, 2475, 1255, 8972, 9024, 9139, 8517, + + 9142, 8535, 2474, 9145, 9165, 8549, 2459, 9153, 9188, 9195, + 9235, 2524, 9233, 8566, 8565, 8561, 8574, 8574, 8599, 8599, + 8600, 8600, 8608, 8613, 8618, 8631, 8714, 8738, 8735, 8786, + 8794, 8807, 8818, 8825, 8835, 8840, 8851, 8843, 8842, 9207, + 9227, 9263, 9251, 2513, 9281, 9257, 9292, 9305, 2483, 9307, + 9318, 9343, 9144, 8899, 9248, 9194, 9285, 9289, 9296, 9297, + 9309, 9364, 8889, 2427, 8993, 8994, 9022, 9146, 9175, 9218, + 9242, 9237, 9291, 9297, 9288, 9313, 9300, 9315, 9375, 9466, + 9472, 9481, 9318, 9487, 9321, 9569, 2390, 9502, 0, 9309, + 2389, 9508, 2377, 9515, 9526, 9551, 9589, 9626, 2433, 9479, + + 9503, 9332, 2422, 9485, 9565, 9345, 9642, 9662, 9665, 9549, + 2353, 1283, 9415, 9685, 9680, 9688, 9701, 2352, 1517, 9360, + 9393, 9693, 9725, 1674, 1531, 9733, 9738, 9394, 9488, 9756, + 2413, 9773, 9486, 9435, 9775, 9496, 9519, 9505, 2332, 1745, + 2358, 9506, 2340, 9549, 9696, 9551, 9577, 9671, 9676, 9695, + 9732, 9690, 9719, 9737, 9720, 9737, 9747, 9758, 9758, 9746, + 9756, 9775, 9776, 9767, 9766, 9768, 9807, 9838, 9841, 2299, + 1756, 9844, 9848, 2351, 9789, 9821, 9850, 9802, 9796, 9797, + 9805, 9806, 9830, 9859, 9831, 9832, 9861, 2311, 9835, 0, + 0, 9847, 9860, 0, 0, 0, 9855, 0, 2301, 9861, + + 9863, 9888, 9899, 9882, 9973, 9894, 9979, 9988,10005, 9919, + 10015,10032, 2270,10050,10065,10072,10079,10098,10107,10110, + 10129,10145,10179,10165, 2334, 9986,10108, 2324,10100,10256, + 9911,10021,10141,10202,10093, 1835, 1591,10275,10238,10278, + 10284,10287, 1838, 1619,10291, 9938, 9931,10294,10297,10300, + 10307, 9964, 2256,10321, 9950, 9989, 2252, 1882,10015,10328, + 10035,10076,10082, 2007, 1656,10344,10086,10087,10094,10101, + 10114,10118,10114,10338,10129,10116,10133,10138,10206,10247, + 10262,10288,10275,10292,10352,10302,10286,15625,10306,10317, + 10314,10319,10340,10336,10337,10382, 2124, 2080,10385,10393, + + 2307,10395,10370,10406,10349,10373,10382,10377,10350,10374, + 10380, 2260,10373,10383,10376,10391,10497, 2232,10432,10523, + 15625,10529,10538,10544,10559,10588,10607,10616, 0,10622, + 10637,10651,10666,10681,10699,10714,10701,10716,10736,10769, + 10747, 2230,10539,10632, 2229,10554,10846,10385,10469,10500, + 10505,10728,10574,10412, 2163,10673,10733,10810,10757,10841, + 10474, 2144,10477,10487,10863,10866,10763, 2123,10517,15625, + 10527, 2189, 2302,10873,10541,10534,10573,10560,10877,10880, + 10584, 2114,10602,10619,10639,10632,10651,10654,10664,10883, + 2105,10685,10672,10688,10671,10692,10690,10712,10724,10731, + + 10805,10887, 2079,10836,10860,10851,10853,10945,10869,10855, + 10862,10863,10948,10951,10970,10875, 2077, 2134,10957,10982, + 11008,10902,10876,10878,10916,10869, 0, 0,10891,10900, + 10934,10927, 0,10993,11034, 2057,10942,11036,11127,11133, + 11142,11148,11169,11175,11205,11211,11232,11213,11234,11263, + 2120,10976,11088, 2093,11140,11201,10957,11058, 2016,10947, + 11289,11084, 1976,10954,10957,10995,11111,11279,10981,10977, + 11184,11076,10994, 1973,10986,10987,11027,11054,11247, 1966, + 11102,11137,11124,11156,11174,11195,11276,11305, 1994,11197, + 1992,11308,11331,11188,11336,11195,11214,15625,11203,11210, + + 11219,11202,11203,11339,11271,11326,11292,11308,11328,11337, + 11338,11327,11337,11338,15625,11341,11343,11374,11381, 1960, + 11342, 2013,11362,11342,11392,11358,11379,11365,11380, 0, + 11361,11404,11456,11390, 1938,11404,11483,11489,11468,11491, + 1980,11479,11487, 1952,11484,11582,11425,11442,11445,11520, + 11446,11478,11467,11529,11523,11532,11560,11585, 1881,11477, + 15625,11479,11541, 1905,11527,11563,11554,11566, 1895,11553, + 11605, 1849,11614, 1833,11569,11625,11566,11628, 1831,11634, + 1809,15625,11642, 1723,11583, 1750,11594,11592,15625,11645, + 1714,11588,11589,11602,11611,11616,11610,11613,11614,11617, + + 15625,11636,11637,11628,11626,11624,15625,11630, 1756,11648, + 11667,11684,11745,11746,11631,11634, 0,11640, 1717,11647, + 11777,11754,11765, 1741,11767,11775, 1731,11804,11862,11658, + 11654,11677,11717,11742,11721,11723,11865,11803, 1647,11868, + 1623,11739,11743,11756,11757,11808, 1645,11871, 1639,11786, + 11812,11793,11879, 1598,11839,11839,11834,11856,11861,11846, + 11857,11858,11852,11853,11865,11856,11871,11864,11866,15625, + 11867,11863,11867,11868,11886,15625,15625,15625,11953, 1661, + 11895,11881,11907,11886,11956,11878,11929,11939,11959,11954, + 11976,11987, 1648,11988,11993, 1639,11992,12021,11983,11975, + + 12024, 1560,12038, 1557,11973,11990,12052,12012,12080,12009, + 12057,12058,12087, 1513,12061,12090,12093, 1497,12060,12061, + 12098, 1467,12066,12073,12080,12083,12071,12088,15625,12069, + 12088,12091,12078,12098,12081,12081,12093,12098,15625,12086, + 12084,12105,12105,15625,12110,12145, 1452, 1513,12114,12126, + 12187,12161,12118,12133, 0,12162,15625,12148,12179, 1505, + 12166,12225, 1503,12226,12270,12163,12183,12213,12208,12217, + 12176, 1432, 1458, 1292,12207,12213,12253,12227,12228, 1412, + 12244,12243,12261,12248,12244,12251,12257,12250,12262,12271, + 15625,12258,12269,12259,12260,12276,12277,12266,12261,12269, + + 15625,12273,15625, 1436,12287,12301,12281,12362, 0,12273, + 12291, 1392,12336,12380, 1381,12340,12398,12286,12276,12281, + 12314,12324,12340, 2261, 1294,12363,12369, 1321, 1307,12372, + 12366,12367,12379,12415,15625,12370,12387,12392,12380,15625, + 12384,12379,15625,12383,15625,12384,15625,12402,12392, 1317, + 12425,12379,12413, 0,12420, 1310,12459,12464, 1306,12467, + 12518,15625,12422,12435,15625,15625,12435,15625, 1200,12442, + 12451,12453,12455,12449,12471,12487,12458,12535, 1198,12459, + 12461,15625,12487,12498,12498,15625,12509,12514,15625, 1256, + 12465, 909, 942,12546,12551, 940,12560,12579,12530,15625, + + 12515,12523,12531,12537,12540,12541, 901,12582, 865,12537, + 15625,12600,12559,15625,15625,12560,15625,15625,12562, 924, + 12597,12612, 922,12598,12630,15625,12565,12575,12578,12597, + 12599,12611,12609,12657, 694,12603,12605,12607, 699,12660, + 12663, 689,12664,12625,12691,12626,12647,12650,12658,12653, + 12658,12660,15625,12663, 678,12686, 632,12722, 2380, 492, + 481,12671, 501, 492,12676,12680,12666,15625,12662,12687, + 15625, 440,12675,12689,12682,12690,12685,12745,15625,12708, + 12710,12701,12707,15625,12750,12753, 110,12723,12710,12722, + 12725,12769, 106,12733,12722,12775,12726,12721,12743,15625, + + 12750,12781,12762,12745,12751,12750,12752,12770,15625,12764, + 12777,12756,12806,15625,12889,12907,12925,12943,12961,12979, + 12997,13015,13033,13051,13069,13087,13105,13123,13141,13159, + 13174,13192,13206,13220,13234,13243,13257,13266,13282,13291, + 13303,13317,13331,13345,13354,13364,13369,13379,13397,13415, + 13433,13451,13469,13487,13505,13519,13528,13544,13562,13576, + 13585,13598,13607,13622,13636,13645,13663,13681,13696,13705, + 13720,13738,13756,13770,13779,13790,13799,13810,13819,13830, + 13839,13853,13862,13874,13883,13894,13903,13914,13923,13934, + 13943,13953,13958,13968,13986,14004,14022,14040,14058,14076, + + 14094,14112,14130,14144,14153,14168,14186,14204,14222,14236, + 14245,14256,14265,14280,14298,14316,14330,14339,14354,14372, + 14387,14405,14423,14437,14455,14469,14483,14497,14511,14526, + 14540,14554,14568,14581,14586,14596,14614,14632,14650,14668, + 14686,14700,14718,14736,14754,14772,14786,14800,14818,14836, + 14854,14868,14886,14904,14922,14940,14954,14968,14982,14996, + 15009,15014,15024,15042,15060,15078,15096,15110,15128,15146, + 15164,15178,15192,15210,15228,15242,15260,15278,15292,15306, + 15320,15334,15347,15352,15362,15380,15398,15412,15426,15444, + 15462,15480,15498,15516,15534,15552,15570,15588,15606 + } ; -static yyconst flex_int16_t yy_def[2511] = +static yyconst flex_int16_t yy_def[2700] = { 0, - 2326, 1, 2326, 3, 2327, 2327, 2326, 7, 2326, 9, - 2326, 11, 2328, 2328, 2329, 2329, 2330, 2330, 2326, 19, - 2330, 2330, 2331, 2331, 2332, 2332, 2333, 2333, 2334, 2334, - 2335, 2335, 2336, 2336, 2337, 2337, 2326, 37, 2338, 2338, - 2339, 2339, 2326, 43, 2326, 45, 2340, 2340, 2326, 49, - 2341, 2341, 2342, 2342, 2330, 2330, 2326, 2326, 2326, 2326, - 2326, 2343, 2344, 2345, 2346, 2326, 2326, 2326, 2326, 2326, - 2326, 2345, 2326, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 2347, 2345, 2345, 2345, - - 2348, 2345, 2326, 2326, 2326, 2349, 2326, 2326, 2326, 2349, - 2349, 2349, 2349, 2349, 2349, 2349, 2349, 2349, 2349, 2350, - 2349, 2326, 2326, 2326, 2326, 2326, 2351, 2351, 2351, 2326, - 129, 129, 2326, 129, 129, 129, 129, 129, 129, 129, - 2351, 141, 141, 2352, 141, 2326, 2326, 2353, 2354, 2355, - 2326, 2354, 2354, 2356, 2354, 2354, 2354, 2357, 2354, 2326, - 2326, 2326, 2326, 2358, 2326, 2326, 2358, 2326, 2358, 2326, - 2326, 2358, 2358, 2358, 2358, 2358, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2359, 2326, 2326, 2326, - - 2359, 2326, 2359, 2359, 2359, 2359, 2359, 2359, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2360, 2326, 2361, 2362, 2326, 2363, 2326, 2326, 2364, 2365, - 2326, 2366, 2326, 2326, 2326, 2326, 2326, 2367, 2368, 2326, - 2326, 2326, 2326, 2326, 2368, 2368, 256, 256, 256, 2326, - 2368, 2368, 2368, 2369, 2368, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2370, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2371, 2372, 2326, 2326, 2326, 2326, - 2372, 2372, 2372, 2372, 2372, 2372, 2373, 2372, 2326, 2326, - - 2374, 2326, 2326, 2374, 2374, 2374, 2374, 2375, 2374, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2376, 2377, 2326, 2326, - 2326, 2326, 2326, 2377, 2326, 2326, 2326, 324, 324, 324, - 2326, 2377, 2377, 2377, 2378, 2377, 2326, 2326, 2326, 2326, - 2379, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2380, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2381, 2381, 2381, 2381, 2382, 2381, 2326, 2383, 2384, - 2384, 371, 371, 2385, 371, 2383, 2386, 2386, 2386, 2386, - 2387, 2386, 2326, 2388, 2326, 2388, 2388, 2388, 2389, 2388, - 2326, 2326, 2326, 2326, 2326, 2326, 2386, 397, 397, 397, - - 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, - 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, - 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, - 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, - 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, - 397, 397, 397, 397, 2390, 2326, 2390, 2390, 2390, 2391, - 2390, 2326, 2326, 397, 2326, 2326, 2326, 2392, 2392, 2392, - 2392, 2393, 2392, 2326, 2326, 2326, 2326, 2392, 2392, 2392, - 2392, 2392, 2392, 2392, 2326, 2392, 2326, 2326, 2326, 2326, - 2394, 2394, 492, 2326, 492, 492, 492, 492, 492, 492, - - 2394, 501, 501, 2395, 501, 2326, 501, 2326, 2326, 492, - 492, 492, 492, 492, 492, 492, 492, 492, 492, 492, - 2326, 492, 2326, 2396, 2396, 2396, 2396, 2397, 2396, 2326, - 2398, 2398, 2398, 2398, 2399, 2398, 2326, 2400, 2326, 2400, - 2400, 2400, 2401, 2400, 2326, 2326, 2326, 2398, 2398, 2402, - 2326, 2402, 2402, 2402, 2403, 2402, 2326, 2326, 2398, 2404, - 2326, 2326, 2404, 2404, 2404, 2404, 2404, 2404, 2404, 2404, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2405, - 2405, 2405, 2326, 2326, 2405, 2405, 2405, 2405, 2405, 2405, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 2406, 2326, 2407, 2326, 2326, 2326, 2326, - 2408, 2326, 2409, 2326, 2326, 2326, 2326, 2326, 2326, 2410, - 2326, 2326, 2326, 2411, 2326, 2412, 2326, 2326, 2326, 2413, - 2414, 2414, 632, 632, 2415, 632, 2413, 2416, 2416, 2416, - 2416, 2417, 2416, 2326, 2326, 2326, 2416, 2416, 2416, 2416, - 2416, 2416, 2326, 2416, 2326, 2326, 2326, 2326, 2418, 2326, - 2326, 2326, 2326, 2326, 2326, 2419, 2420, 2420, 668, 668, - 2421, 668, 2419, 2422, 2422, 2422, 2422, 2423, 2422, 2326, - 2326, 2422, 2422, 2422, 2326, 2422, 2326, 2326, 2424, 2424, - 2424, 2424, 2425, 2424, 2326, 2424, 2326, 2424, 2326, 2326, - - 2326, 2426, 2427, 2427, 704, 704, 2428, 704, 2426, 2429, - 2429, 2429, 2429, 2430, 2429, 2326, 2326, 2326, 2326, 2326, - 2429, 721, 2326, 721, 721, 721, 2326, 721, 2326, 2326, - 2326, 2431, 2326, 2326, 2326, 2326, 2326, 2432, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2433, 2434, 2435, 2326, 2436, - 2437, 2326, 2326, 2326, 2326, 2326, 2438, 2438, 2438, 2438, - 2438, 2438, 2438, 2438, 2438, 2438, 2438, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, - - 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, - 767, 767, 767, 767, 767, 2326, 2439, 2326, 2440, 2440, - 2440, 2440, 2440, 2440, 2326, 2441, 2441, 847, 847, 847, - 847, 847, 847, 847, 847, 847, 2326, 2326, 2442, 2326, - 2443, 2444, 2444, 2326, 2445, 2326, 2446, 2446, 2446, 2446, - 2446, 2446, 2446, 2446, 2447, 2447, 2447, 2447, 2447, 2447, - 2447, 2447, 2326, 2448, 2448, 2326, 2326, 2449, 2449, 2326, - 2326, 2450, 2450, 2326, 2451, 2452, 2453, 2326, 2326, 2326, - - 2326, 2454, 2454, 2454, 2454, 2454, 2454, 2326, 2326, 2455, - 2326, 2326, 2456, 2457, 2458, 2326, 2459, 2459, 2459, 2326, - 2460, 2326, 2326, 2461, 2462, 2463, 2326, 2326, 2326, 2326, - 2326, 2464, 2326, 2326, 2464, 2464, 2464, 2326, 2465, 2326, - 2326, 2326, 2466, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2467, 2326, 2468, 2468, 2468, 2326, 2326, 2326, 2326, 2326, - 2469, 2469, 2469, 2469, 2469, 2469, 2469, 2469, 968, 968, - 968, 968, 968, 968, 968, 968, 968, 968, 968, 968, - 968, 968, 968, 968, 968, 968, 968, 968, 968, 968, - 968, 968, 968, 968, 968, 968, 968, 968, 968, 968, - - 968, 968, 968, 968, 968, 968, 968, 968, 968, 968, - 968, 968, 968, 968, 968, 968, 968, 968, 968, 2326, - 2469, 968, 968, 968, 968, 968, 968, 968, 968, 968, - 968, 968, 968, 968, 968, 968, 968, 968, 968, 968, - 968, 2326, 2470, 2470, 2470, 2470, 2470, 2470, 2471, 2471, - 1050, 1050, 2326, 1050, 1050, 1050, 1050, 1050, 1050, 2326, - 2326, 2472, 2472, 2326, 2473, 2473, 2473, 2473, 2473, 2473, - 2473, 2473, 2474, 2474, 2474, 2474, 2474, 2474, 2474, 2474, - 2475, 2326, 2476, 2326, 2477, 2326, 2478, 2479, 2479, 2479, - 2326, 2326, 2326, 2480, 2480, 2480, 1096, 1096, 1096, 2326, - - 2481, 2481, 2481, 2326, 2482, 2483, 2483, 2483, 2484, 2484, - 2484, 2485, 2326, 2486, 2487, 2487, 2487, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2488, 2488, 2488, 2489, 2489, 2489, - 2326, 2326, 2490, 2490, 2490, 2326, 2326, 2326, 2326, 2326, - 2491, 2491, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, - 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, - 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 2326, - 2491, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, - 2326, 2491, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, - 1142, 1142, 1142, 1142, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 2491, 1142, 1142, 1142, 1142, 1142, 1142, - 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, - 1142, 2492, 2492, 2492, 2492, 2492, 2326, 2493, 2493, 1229, - 1229, 1229, 1229, 1229, 1229, 1229, 2494, 2494, 2495, 2495, - 2495, 2495, 2495, 2495, 2495, 2495, 2496, 2496, 2496, 2496, - 2496, 2496, 2496, 2497, 2497, 2497, 2497, 2498, 2498, 2498, - 2498, 2499, 2499, 2499, 2499, 2326, 2326, 2326, 2500, 2500, - 2326, 2326, 2326, 2500, 2500, 2500, 2500, 2326, 2326, 2484, - 2484, 2484, 2326, 2326, 2488, 2488, 2488, 2326, 2326, 2491, - 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, - - 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, - 1142, 1142, 1142, 2326, 2326, 2326, 1142, 1142, 2326, 2326, - 2491, 1142, 1142, 1142, 1142, 2326, 2326, 1142, 1142, 1142, - 1142, 1142, 1142, 1142, 1142, 1142, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 1142, 1142, 1142, 1142, - 1142, 1142, 1142, 1142, 1142, 1142, 1142, 2492, 2492, 2492, - 2492, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, - 2494, 2495, 2495, 2495, 2495, 2495, 2495, 2495, 2495, 2496, - 2496, 2496, 2496, 2496, 2496, 2326, 2326, 2326, 2500, 2500, - - 2501, 2326, 2326, 2501, 2501, 1272, 1272, 2501, 1272, 1272, - 1410, 1410, 2502, 1410, 2501, 2326, 2500, 2500, 2500, 2326, - 2484, 2484, 2484, 2326, 2326, 2488, 2488, 2488, 2326, 2326, - 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 2326, 2326, - 2491, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 2326, 2326, - 2491, 2326, 2326, 1142, 1142, 2326, 2503, 1142, 1142, 1142, - 2326, 1142, 1142, 1142, 1142, 1142, 1142, 2326, 2326, 2491, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 1142, 1142, 1142, 2326, 2326, 2491, 1142, - - 1142, 1142, 2492, 2492, 1229, 1229, 1229, 1229, 1229, 1229, - 1229, 1229, 2494, 2495, 2495, 2495, 2495, 2495, 2495, 2495, - 2496, 2496, 2496, 2496, 2496, 2326, 2326, 2326, 2500, 2500, - 2501, 2501, 2501, 2326, 2501, 1272, 2501, 1272, 2501, 1272, - 1272, 1272, 2504, 2326, 2500, 2500, 2484, 2484, 2484, 2326, - 2326, 2488, 2488, 2326, 1142, 1142, 1142, 1142, 2326, 2505, - 1142, 1142, 1142, 1142, 1142, 2326, 2506, 2326, 2326, 1142, - 1142, 2503, 2503, 2326, 1142, 2326, 2326, 2326, 2491, 1142, - 1142, 2326, 2326, 2326, 2326, 2507, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 1142, - 1142, 1142, 2326, 2508, 1142, 1142, 2492, 2492, 1229, 1229, - 1229, 1229, 1229, 1229, 1229, 1229, 2494, 2495, 2495, 2495, - 2495, 2495, 2495, 2495, 2496, 2496, 2496, 2496, 2496, 2326, - 2326, 2326, 2500, 2500, 2501, 2326, 2509, 2504, 2501, 1272, - 2501, 2501, 1410, 2504, 2504, 2509, 2504, 2504, 2504, 2500, - 2500, 2484, 2484, 2484, 2326, 2326, 2488, 2326, 1142, 1142, - 1142, 1142, 2505, 2505, 2326, 1142, 1142, 1142, 1142, 2506, - 2506, 2326, 2326, 2326, 1142, 1142, 2326, 2326, 2326, 2326, - 1142, 2326, 2326, 2510, 1142, 2326, 2326, 2326, 2507, 2507, - - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 1142, 2508, 2508, 2326, - 1142, 2492, 2492, 1229, 1229, 1229, 2495, 2495, 2495, 2496, - 2496, 2496, 2326, 2326, 2326, 2500, 2500, 2501, 2326, 2509, - 2509, 2509, 2509, 2509, 2509, 2509, 1272, 2504, 2504, 2509, - 2509, 2504, 2504, 2504, 2500, 2500, 2484, 2484, 2484, 2326, - 2326, 2488, 2326, 1142, 1142, 1142, 2326, 2326, 2326, 2326, - 1142, 1142, 1142, 2326, 2326, 2326, 2326, 2326, 2326, 1142, - 1142, 2326, 2326, 2326, 2326, 2510, 2510, 2326, 2326, 2326, - - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 1142, 2326, 2326, 2326, 2326, 2492, 2492, 1229, 1229, - 1229, 2495, 2495, 2495, 2496, 2496, 2496, 2326, 2326, 2326, - 2326, 2326, 2500, 1853, 2501, 2509, 2509, 2509, 2509, 2504, - 2509, 2504, 2504, 1853, 2484, 2484, 2326, 2326, 2326, 2326, - 2488, 2326, 2326, 2326, 2326, 1142, 2326, 2326, 2326, 2326, - 2326, 1142, 1142, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 1142, 2326, 2326, 2326, - 2492, 2492, 1229, 2495, 2496, 2496, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2500, 2509, 2504, 1853, 2484, 2326, - 2326, 2326, 2326, 2326, 2326, 2488, 2326, 2326, 2326, 1142, - 2326, 2326, 2326, 1142, 1142, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2492, - 2492, 1229, 2495, 2496, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2509, 1853, 2484, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 1142, 2326, 2326, 2326, 1142, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2492, 2492, 1229, 2495, 2326, 2326, - 2326, 1853, 2484, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 1142, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2492, 1229, - 2495, 2326, 2326, 2326, 1853, 2484, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2492, 1229, 2495, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 2492, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 0, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326 + 2514, 1, 2514, 3, 2515, 2515, 2514, 7, 2514, 9, + 2514, 11, 2516, 2516, 2517, 2517, 2518, 2518, 2514, 19, + 2518, 2518, 2519, 2519, 2520, 2520, 2521, 2521, 2522, 2522, + 2523, 2523, 2524, 2524, 2525, 2525, 2514, 37, 2526, 2526, + 2527, 2527, 2514, 43, 2514, 45, 2528, 2528, 2514, 49, + 2529, 2529, 2518, 2518, 2530, 2530, 2518, 2518, 2514, 2514, + 2514, 2514, 2514, 2531, 2532, 2533, 2534, 2514, 2514, 2514, + 2514, 2514, 2514, 2533, 2514, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 2535, 2533, + + 2533, 2533, 2536, 2533, 2514, 2514, 2514, 2537, 2514, 2514, + 2514, 2537, 2537, 2537, 2537, 2537, 2537, 2537, 2537, 2537, + 2537, 2538, 2537, 2514, 2514, 2514, 2514, 2514, 2539, 2539, + 2539, 2514, 131, 131, 2514, 131, 131, 131, 131, 131, + 131, 131, 2539, 143, 143, 2540, 143, 2514, 2514, 2541, + 2542, 2543, 2514, 2542, 2542, 2544, 2542, 2542, 2542, 2545, + 2542, 2514, 2514, 2514, 2514, 2546, 2514, 2514, 2546, 2514, + 2546, 2514, 2514, 2546, 2546, 2546, 2546, 2546, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2547, 2514, + + 2514, 2514, 2547, 2514, 2547, 2547, 2547, 2547, 2547, 2547, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2548, 2514, 2549, 2550, 2514, 2551, 2514, 2514, + 2552, 2553, 2514, 2554, 2514, 2514, 2514, 2514, 2514, 2555, + 2556, 2514, 2514, 2514, 2514, 2514, 2556, 257, 257, 257, + 2514, 2556, 2556, 2556, 2557, 2556, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2558, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2559, 2560, 2514, 2514, 2514, + 2514, 2560, 2560, 2560, 2560, 2560, 2560, 2561, 2560, 2514, + + 2514, 2562, 2514, 2514, 2562, 2562, 2562, 2562, 2563, 2562, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2564, 2565, 2514, + 2514, 2514, 2514, 2514, 2565, 2514, 2514, 325, 325, 2514, + 2565, 2565, 2565, 2566, 2565, 2514, 2514, 2514, 2514, 2567, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2568, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2569, 2569, 2569, 2569, 2570, 2569, 2514, 2571, 2572, 2572, + 370, 370, 2573, 370, 2571, 2574, 2574, 2574, 2574, 2575, + 2574, 2514, 2576, 2514, 2576, 2576, 2576, 2577, 2576, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2574, 398, 398, + + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 2578, 2514, 2578, 2578, 2578, + 2579, 2578, 2514, 2514, 398, 2514, 2514, 2514, 2580, 2580, + 2580, 2580, 2581, 2580, 2514, 2514, 2514, 2514, 2580, 2580, + 2580, 2580, 2580, 2580, 2580, 2514, 2580, 2514, 2514, 2514, + 2514, 2582, 2582, 493, 2514, 493, 493, 493, 493, 493, + + 493, 2582, 502, 502, 2583, 502, 2514, 502, 2514, 2514, + 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, + 493, 2514, 493, 2514, 2584, 2584, 2584, 2584, 2585, 2584, + 2514, 2586, 2586, 2586, 2586, 2587, 2586, 2514, 2588, 2514, + 2588, 2588, 2588, 2589, 2588, 2514, 2514, 2514, 2586, 2586, + 2590, 2514, 2590, 2590, 2590, 2591, 2590, 2514, 2514, 2586, + 2592, 2514, 2514, 2592, 2592, 2592, 2592, 2592, 2592, 2592, + 2592, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2593, 2593, 2593, 2514, 2514, 2593, 2593, 2593, 2593, 2593, + 2593, 2593, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + + 2514, 2514, 2514, 2514, 2514, 2594, 2514, 2595, 2514, 2514, + 2514, 2514, 2596, 2514, 2597, 2514, 2514, 2514, 2514, 2514, + 2514, 2598, 2514, 2514, 2514, 2599, 2514, 2600, 2514, 2514, + 2514, 2601, 2602, 2602, 634, 634, 2603, 634, 2601, 2604, + 2604, 2604, 2604, 2605, 2604, 2514, 2514, 2514, 2604, 2604, + 2604, 2604, 2604, 2514, 2604, 2514, 2514, 2514, 2514, 2606, + 2514, 2514, 2514, 2514, 2514, 2514, 2607, 2608, 2608, 669, + 669, 2609, 669, 2607, 2610, 2610, 2610, 2610, 2611, 2610, + 2514, 2514, 2610, 2610, 2610, 2514, 2610, 2514, 2514, 2612, + 2612, 2612, 2612, 2613, 2612, 2514, 2612, 2514, 2612, 2514, + + 2514, 2514, 2614, 2615, 2615, 705, 705, 2616, 705, 2614, + 2617, 2617, 2617, 2617, 2618, 2617, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2617, 724, 724, 724, 2514, 724, 2514, + 2514, 2514, 2619, 2514, 2514, 2514, 2514, 2514, 2620, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2621, 2622, 2623, 2514, + 2624, 2514, 2625, 2514, 2514, 2514, 2514, 2514, 2514, 2626, + 2514, 2626, 2626, 2626, 764, 764, 764, 764, 764, 764, + 764, 764, 764, 764, 764, 764, 764, 764, 764, 764, + 764, 764, 764, 764, 764, 764, 764, 764, 764, 764, + 764, 764, 764, 764, 764, 764, 764, 764, 764, 764, + + 764, 764, 764, 764, 764, 764, 764, 764, 764, 764, + 764, 764, 764, 764, 764, 764, 764, 764, 764, 764, + 764, 764, 764, 764, 764, 764, 764, 764, 764, 764, + 764, 764, 764, 764, 764, 764, 764, 764, 764, 764, + 764, 2514, 2627, 2514, 2514, 2628, 2628, 2628, 2628, 2628, + 2628, 2628, 2514, 2629, 2629, 855, 855, 855, 855, 855, + 855, 855, 855, 855, 855, 2514, 2514, 2630, 2514, 2631, + 2632, 2632, 2514, 2633, 2514, 2634, 2634, 2634, 2634, 2634, + 2634, 2634, 2634, 2634, 2635, 2635, 2635, 2635, 2635, 2635, + 2635, 2635, 2635, 2514, 2636, 2636, 2514, 2514, 2637, 2637, + + 2514, 2514, 2638, 2638, 2514, 2639, 2640, 2641, 2514, 2514, + 2514, 2642, 2642, 2642, 2642, 2642, 2514, 2514, 2643, 2514, + 2514, 2644, 2645, 2646, 2514, 2647, 2647, 2647, 2514, 2648, + 2514, 2514, 2649, 2650, 2514, 2651, 2514, 2514, 2514, 2514, + 2514, 2514, 2652, 2514, 2652, 2652, 946, 2514, 2653, 2514, + 2514, 2514, 2654, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2655, 2514, 2514, 2656, 2656, 2656, 2514, 2514, 2514, 2514, + 2514, 2514, 2657, 2657, 974, 974, 974, 974, 974, 974, + 974, 974, 974, 974, 974, 974, 974, 974, 974, 974, + 974, 974, 974, 974, 974, 974, 974, 974, 974, 974, + + 974, 974, 974, 974, 974, 974, 974, 974, 974, 974, + 974, 974, 974, 974, 974, 974, 974, 974, 974, 974, + 974, 974, 974, 974, 974, 974, 974, 974, 974, 974, + 974, 974, 974, 2514, 2657, 974, 974, 974, 974, 974, + 974, 974, 974, 974, 974, 974, 974, 974, 974, 974, + 974, 974, 974, 974, 974, 2514, 2514, 2658, 2658, 2658, + 2658, 2658, 2658, 2658, 2659, 2659, 1066, 1066, 2514, 1066, + 1066, 1066, 1066, 1066, 1066, 1066, 2514, 2514, 2660, 2660, + 2514, 2661, 2661, 2661, 2661, 2661, 2661, 2661, 2661, 2661, + 2662, 2662, 2662, 2662, 2662, 2662, 2662, 2662, 2662, 2663, + + 2514, 2664, 2514, 2665, 2514, 2666, 2667, 2667, 2667, 2514, + 2514, 2668, 2668, 1113, 1113, 1113, 2514, 2669, 2669, 2669, + 2514, 2670, 2671, 2671, 2671, 2672, 2672, 2672, 2673, 2514, + 2674, 2514, 2675, 2675, 2675, 2514, 2514, 2514, 2514, 2514, + 2514, 2676, 2676, 1143, 2677, 2677, 2677, 2514, 2514, 2678, + 2678, 2678, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2679, + 2679, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 2514, + 2679, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + + 2514, 2679, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 1161, 1161, 1161, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2679, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 2514, 2680, 2680, 2680, 2680, 2680, 2680, 2514, + 2681, 2681, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, + 2682, 2682, 2683, 2683, 2683, 2683, 2683, 2683, 2683, 2683, + 2683, 2684, 2684, 2684, 2684, 2684, 2684, 2684, 2684, 2685, + 2685, 2685, 2685, 2686, 2686, 2686, 2686, 2687, 2687, 2687, + 2687, 2514, 2514, 2688, 2514, 2514, 2514, 2688, 2688, 2688, + + 2688, 2514, 2514, 2689, 2689, 2689, 2514, 2514, 1143, 1143, + 1143, 2514, 2514, 2514, 1161, 2514, 2679, 1161, 1161, 1161, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + 2514, 2514, 2514, 1161, 1161, 2514, 2514, 2679, 1161, 1161, + 1161, 1161, 2514, 2514, 1161, 2514, 2679, 1161, 1161, 1161, + 2514, 2679, 1161, 1161, 1161, 1161, 1161, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 1161, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + + 2514, 2680, 2680, 2680, 2680, 2680, 1252, 1252, 1252, 1252, + 1252, 1252, 1252, 1252, 1252, 1252, 2682, 2683, 2683, 2683, + 2683, 2683, 2683, 2683, 2683, 2683, 2684, 2684, 2684, 2684, + 2684, 2684, 2684, 2514, 2514, 2688, 2690, 2514, 2514, 2690, + 2690, 1296, 1296, 2690, 1296, 1296, 1446, 1446, 2691, 1446, + 2690, 2514, 2688, 2688, 2688, 2514, 2689, 2689, 2689, 2514, + 2514, 1143, 1143, 1143, 2514, 2514, 1161, 2514, 2514, 1161, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 2514, 2514, 2679, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 2514, 2514, 2679, + 2514, 2514, 1161, 1161, 2514, 2692, 1161, 1161, 1161, 2514, + + 1161, 2514, 2514, 1161, 1161, 2514, 2514, 1161, 1161, 1161, + 2514, 2514, 2679, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 1161, + 1161, 1161, 2514, 2514, 2679, 1161, 1161, 1161, 2514, 2680, + 2680, 2680, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, + 1252, 2682, 2683, 2683, 2683, 2683, 2683, 2683, 2683, 2683, + 2684, 2684, 2684, 2684, 2684, 2684, 2514, 2514, 2688, 2690, + 2690, 2690, 2514, 2690, 1296, 2690, 1296, 2690, 1296, 1296, + 1296, 2693, 2514, 2688, 2688, 2689, 2689, 2689, 2514, 2514, + + 1143, 1143, 2514, 2514, 1161, 2514, 1161, 1161, 1161, 1161, + 2514, 2694, 1161, 1161, 1161, 1161, 1161, 2514, 2695, 2514, + 2514, 1161, 1161, 2692, 2692, 2514, 1161, 2514, 2514, 2514, + 2514, 2679, 2514, 1161, 1161, 2514, 2514, 2514, 2514, 2696, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 1161, 1161, 1161, 2514, + 2697, 1161, 1161, 2514, 2680, 2680, 2680, 1252, 1252, 1252, + 1252, 1252, 1252, 1252, 1252, 1252, 2682, 2683, 2683, 2683, + 2683, 2683, 2683, 2683, 2683, 2684, 2684, 2684, 2684, 2684, + + 2684, 2514, 2514, 2688, 2690, 2514, 2698, 2693, 2690, 1296, + 2690, 2690, 1446, 2693, 2693, 2698, 2693, 2693, 2693, 2688, + 2688, 2689, 2689, 2689, 2514, 2514, 1143, 2514, 2514, 1161, + 2514, 1161, 1161, 1161, 1161, 2694, 2694, 2514, 1161, 1161, + 1161, 1161, 2695, 2695, 2514, 2514, 2514, 1161, 1161, 2514, + 2514, 2514, 2514, 1161, 2514, 2514, 2514, 2699, 2514, 1161, + 2514, 2514, 2514, 2696, 2696, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 1161, 2697, 2697, 2514, 1161, + + 2514, 2680, 2680, 2680, 1252, 1252, 1252, 1252, 2683, 2683, + 2683, 2683, 2684, 2684, 2684, 2684, 2514, 2514, 2688, 2690, + 2514, 2698, 2698, 2698, 2698, 2698, 2698, 2698, 1296, 2693, + 2693, 2698, 2698, 2693, 2693, 2693, 2688, 2688, 2689, 2689, + 2689, 2514, 2514, 1143, 2514, 2514, 1161, 2514, 1161, 1161, + 1161, 2514, 2514, 2514, 2514, 1161, 1161, 1161, 2514, 2514, + 2514, 2514, 2514, 2514, 1161, 1161, 2514, 2514, 2514, 2514, + 2514, 2699, 2699, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 1161, 2514, 2514, 2514, 2514, 2514, 2680, 2680, + 2680, 1252, 1252, 1252, 1252, 2683, 2683, 2683, 2683, 2684, + 2684, 2684, 2684, 2514, 2514, 2514, 2514, 2688, 2690, 2698, + 2698, 2698, 2698, 2693, 2698, 2693, 2693, 2688, 2689, 2689, + 2514, 2514, 1143, 2514, 2514, 1161, 2514, 2514, 2514, 2514, + 1161, 2514, 2514, 2514, 2514, 2514, 1161, 1161, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 1161, 2514, 2514, + 2514, 2514, 2680, 2680, 2680, 1252, 1252, 2683, 2683, 2684, + 2684, 2684, 2514, 2514, 2514, 2514, 2698, 2693, 2688, 2689, + 2514, 2514, 1143, 2514, 2514, 1161, 2514, 2514, 2514, 1161, + 2514, 2514, 2514, 1161, 1161, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2680, + 2680, 2680, 1252, 1252, 2683, 2683, 2684, 2684, 2514, 2514, + 2698, 2688, 2689, 2514, 2514, 1143, 2514, 2514, 1161, 2514, + 2514, 2514, 1161, 2514, 2514, 2514, 1161, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2680, 2680, 2680, 1252, 1252, 2683, 2683, 2684, 2514, 2514, + 2688, 2689, 2514, 2514, 1143, 2514, 2514, 1161, 2514, 2514, + + 2514, 2514, 2514, 2514, 2514, 2514, 1161, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2680, 2680, + 1252, 1252, 2683, 2683, 2684, 2514, 2514, 2688, 2689, 2514, + 2514, 1143, 2514, 2514, 1161, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + + 2514, 2514, 2514, 2514, 2680, 2680, 1252, 1252, 2683, 2683, + 2514, 2514, 2514, 1143, 2514, 2514, 1161, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2680, 2680, 1252, 2683, 2514, 2514, 2514, 1143, 2514, 2514, + 1161, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2680, 2514, 2514, 2514, 1143, 2514, 2514, 1161, 2514, 2514, + + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 1143, 2514, 2514, 1161, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 1143, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 0, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514 + } ; -static yyconst flex_int16_t yy_nxt[15696] = +static yyconst flex_int16_t yy_nxt[15718] = { 0, - 58, 59, 60, 59, 61, 62, 63, 64, 65, 66, - 66, 61, 67, 68, 69, 70, 71, 72, 72, 61, - 61, 61, 73, 61, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 64, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 64, 64, - 58, 58, 61, 64, 97, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 64, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 64, - 64, 58, 98, 99, 100, 101, 102, 102, 102, 102, - 102, 102, 103, 104, 104, 105, 104, 104, 104, 106, - - 106, 104, 107, 107, 108, 109, 104, 109, 104, 104, - 110, 110, 104, 104, 104, 104, 104, 106, 106, 106, - 106, 106, 111, 106, 106, 112, 106, 106, 106, 106, - 106, 106, 106, 113, 114, 115, 106, 106, 106, 116, - 106, 106, 106, 104, 104, 104, 106, 104, 106, 106, - 106, 106, 106, 111, 106, 106, 112, 106, 106, 106, - 106, 106, 106, 106, 113, 114, 115, 106, 106, 106, - 116, 106, 106, 106, 104, 117, 118, 119, 120, 121, - 121, 121, 121, 121, 121, 122, 124, 124, 392, 392, - 393, 394, 394, 392, 392, 125, 125, 126, 127, 128, - - 127, 126, 126, 129, 129, 126, 126, 126, 130, 131, - 126, 132, 133, 126, 129, 129, 126, 126, 126, 126, - 126, 129, 129, 129, 134, 135, 129, 136, 129, 129, - 129, 129, 129, 129, 129, 137, 138, 129, 139, 129, - 140, 129, 129, 129, 129, 129, 129, 126, 126, 126, - 129, 126, 129, 129, 129, 134, 135, 129, 136, 129, - 129, 129, 129, 129, 129, 129, 137, 138, 129, 139, - 129, 140, 129, 129, 129, 129, 129, 129, 126, 141, - 142, 143, 144, 145, 145, 145, 145, 145, 145, 146, - 147, 147, 105, 147, 147, 148, 149, 149, 150, 147, - - 147, 151, 147, 147, 147, 147, 147, 149, 149, 147, - 147, 147, 147, 147, 149, 149, 149, 149, 149, 149, - 149, 149, 149, 149, 149, 149, 149, 149, 149, 152, - 149, 149, 149, 153, 149, 149, 149, 149, 149, 149, - 147, 147, 147, 149, 154, 149, 149, 149, 149, 149, - 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, - 152, 149, 149, 149, 153, 149, 149, 149, 149, 149, - 149, 147, 155, 156, 157, 158, 159, 159, 159, 159, - 159, 159, 160, 161, 162, 163, 162, 161, 161, 161, - 164, 165, 161, 161, 166, 167, 168, 169, 170, 161, - - 164, 164, 161, 161, 171, 161, 161, 164, 164, 164, - 172, 173, 164, 174, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 175, 164, 176, 164, 164, 164, - 164, 164, 164, 161, 161, 161, 164, 161, 164, 164, - 164, 172, 173, 164, 174, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 175, 164, 176, 164, 164, - 164, 164, 164, 164, 161, 161, 177, 161, 178, 161, - 161, 161, 161, 161, 161, 161, 180, 181, 180, 232, - 180, 181, 180, 182, 232, 235, 183, 182, 184, 235, - 183, 238, 184, 188, 189, 188, 238, 188, 189, 188, - - 190, 105, 105, 191, 190, 190, 105, 191, 105, 190, - 463, 463, 475, 356, 477, 477, 510, 476, 356, 485, - 485, 357, 233, 511, 268, 268, 357, 233, 236, 489, - 358, 2310, 236, 2292, 490, 358, 312, 239, 312, 512, - 508, 513, 239, 514, 356, 509, 2296, 510, 546, 356, - 521, 521, 357, 547, 511, 268, 268, 357, 185, 2295, - 186, 358, 185, 561, 186, 2281, 358, 312, 562, 312, - 512, 573, 513, 577, 514, 192, 574, 193, 578, 192, - 2280, 193, 194, 195, 196, 195, 194, 194, 194, 197, - 198, 199, 199, 200, 201, 202, 203, 194, 194, 204, - - 204, 194, 194, 199, 194, 194, 204, 204, 204, 204, - 204, 204, 205, 204, 204, 204, 204, 204, 204, 204, - 204, 206, 204, 204, 207, 208, 204, 204, 204, 204, - 204, 204, 194, 194, 194, 204, 194, 204, 204, 204, - 204, 204, 204, 205, 204, 204, 204, 204, 204, 204, - 204, 204, 206, 204, 204, 207, 208, 204, 204, 204, - 204, 204, 204, 199, 194, 209, 194, 210, 194, 194, - 194, 194, 194, 194, 194, 211, 211, 211, 211, 211, - 211, 515, 2326, 212, 377, 377, 212, 216, 217, 216, - 521, 521, 218, 516, 219, 427, 220, 221, 216, 217, - - 216, 558, 558, 218, 1256, 219, 1260, 220, 221, 225, - 226, 225, 515, 2213, 227, 2291, 227, 227, 227, 228, - 225, 226, 225, 563, 516, 227, 427, 227, 227, 227, - 228, 378, 379, 380, 381, 382, 382, 382, 382, 382, - 382, 383, 2326, 564, 377, 377, 558, 558, 2326, 2244, - 377, 377, 565, 566, 563, 409, 585, 213, 586, 214, - 213, 404, 214, 581, 582, 405, 656, 583, 410, 222, - 2260, 223, 584, 2252, 564, 592, 593, 2223, 594, 1255, - 222, 1259, 223, 565, 566, 597, 409, 585, 2214, 586, - 598, 229, 404, 230, 581, 582, 405, 656, 601, 410, - - 602, 602, 229, 602, 230, 244, 245, 246, 245, 244, - 247, 248, 249, 250, 251, 244, 244, 244, 244, 252, - 244, 244, 249, 249, 244, 253, 244, 244, 254, 255, - 249, 249, 249, 249, 256, 257, 249, 249, 249, 249, - 258, 249, 249, 249, 249, 249, 259, 249, 249, 249, - 249, 249, 249, 249, 249, 244, 244, 244, 249, 260, - 255, 249, 249, 249, 249, 256, 257, 249, 249, 249, - 249, 258, 249, 249, 249, 249, 249, 259, 249, 249, - 249, 249, 249, 249, 249, 249, 244, 261, 262, 263, - 264, 265, 265, 265, 265, 265, 265, 266, 270, 271, - - 270, 2182, 272, 273, 2213, 274, 275, 276, 359, 359, - 359, 277, 270, 271, 270, 652, 272, 273, 638, 274, - 275, 276, 463, 463, 2326, 277, 377, 377, 2326, 2218, - 377, 377, 2326, 406, 377, 377, 661, 377, 587, 278, - 589, 377, 699, 588, 734, 377, 652, 407, 735, 638, - 408, 2217, 413, 278, 411, 414, 740, 590, 415, 2182, - 412, 653, 653, 2148, 406, 662, 663, 661, 377, 587, - 278, 589, 377, 699, 588, 734, 377, 2183, 407, 735, - 279, 408, 280, 413, 278, 411, 414, 740, 590, 415, - 360, 412, 465, 466, 279, 467, 280, 281, 282, 283, - - 282, 281, 284, 285, 286, 287, 288, 289, 281, 281, - 281, 290, 281, 281, 286, 286, 281, 281, 281, 281, - 281, 286, 286, 286, 286, 286, 291, 286, 286, 286, - 286, 286, 292, 286, 286, 286, 286, 286, 293, 286, - 286, 286, 286, 286, 286, 286, 286, 281, 281, 281, - 286, 281, 286, 286, 286, 286, 286, 291, 286, 286, - 286, 286, 286, 292, 286, 286, 286, 286, 286, 293, - 286, 286, 286, 286, 286, 286, 286, 286, 281, 294, - 295, 296, 297, 298, 298, 298, 298, 298, 298, 299, - 105, 105, 105, 105, 105, 300, 301, 301, 302, 105, - - 105, 105, 105, 105, 105, 105, 105, 301, 301, 105, - 105, 105, 105, 303, 301, 301, 301, 301, 301, 304, - 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, - 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, - 105, 105, 105, 301, 105, 301, 301, 301, 301, 301, - 304, 301, 301, 301, 301, 301, 301, 301, 301, 301, - 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, - 301, 105, 305, 306, 307, 308, 309, 309, 309, 309, - 309, 309, 310, 313, 314, 315, 314, 313, 316, 317, - 318, 319, 313, 313, 313, 320, 321, 322, 323, 313, - - 324, 324, 313, 325, 326, 313, 327, 328, 318, 318, - 318, 318, 318, 329, 318, 318, 318, 318, 318, 318, - 318, 318, 318, 318, 318, 330, 318, 318, 318, 318, - 318, 318, 318, 313, 313, 313, 318, 331, 328, 318, - 318, 318, 318, 318, 329, 318, 318, 318, 318, 318, - 318, 318, 318, 318, 318, 318, 330, 318, 318, 318, - 318, 318, 318, 318, 313, 332, 333, 334, 335, 336, - 336, 336, 336, 336, 336, 337, 339, 340, 339, 653, - 653, 341, 2181, 339, 340, 339, 685, 685, 341, 342, - 359, 359, 359, 697, 697, 343, 342, 2142, 628, 628, - - 628, 741, 343, 2127, 344, 348, 349, 348, 697, 697, - 350, 344, 348, 349, 348, 717, 717, 350, 351, 361, - 742, 345, 485, 485, 352, 351, 718, 2106, 345, 717, - 717, 352, 741, 353, 2326, 344, 377, 377, 2101, 354, - 353, 2326, 344, 377, 377, 2098, 354, 377, 2089, 655, - 450, 742, 345, 743, 377, 719, 719, 385, 346, 345, - 416, 628, 628, 628, 353, 346, 2326, 2087, 377, 377, - 354, 353, 360, 2053, 657, 657, 657, 354, 377, 377, - 629, 450, 744, 423, 743, 377, 2104, 355, 657, 657, - 657, 416, 487, 488, 355, 2100, 363, 364, 365, 366, - - 367, 367, 367, 367, 367, 367, 368, 369, 369, 1264, - 377, 369, 369, 744, 423, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 727, 727, 369, 369, 369, 369, - 369, 386, 387, 388, 389, 390, 390, 390, 390, 390, - 390, 391, 2326, 629, 377, 377, 664, 664, 664, 745, - 745, 454, 664, 664, 664, 377, 658, 369, 369, 369, - 475, 369, 727, 727, 2326, 476, 377, 377, 745, 745, - 658, 489, 2326, 417, 377, 377, 490, 418, 747, 747, - 511, 419, 454, 463, 463, 377, 377, 1263, 369, 371, - 372, 373, 374, 375, 375, 375, 375, 375, 375, 376, - - 396, 437, 397, 397, 417, 463, 463, 2326, 418, 377, - 377, 511, 419, 398, 749, 749, 377, 749, 749, 420, - 377, 2040, 421, 512, 650, 392, 392, 638, 665, 422, - 638, 2029, 437, 508, 665, 729, 836, 836, 509, 2326, - 1954, 377, 377, 2020, 398, 836, 836, 1943, 424, 2080, - 420, 377, 377, 421, 512, 650, 425, 2058, 638, 513, - 422, 638, 426, 685, 685, 485, 485, 378, 379, 380, - 381, 382, 382, 382, 382, 382, 382, 383, 2326, 424, - 377, 377, 2326, 377, 377, 377, 2326, 425, 377, 377, - 513, 377, 429, 426, 515, 377, 430, 1987, 399, 377, - - 400, 700, 700, 700, 431, 401, 402, 403, 432, 428, - 1981, 700, 700, 700, 1979, 2326, 516, 377, 377, 485, - 485, 2050, 377, 429, 433, 515, 377, 430, 377, 399, - 377, 400, 434, 687, 688, 431, 401, 402, 403, 432, - 428, 435, 846, 2326, 436, 377, 377, 516, 2326, 546, - 377, 377, 477, 477, 547, 433, 438, 521, 521, 377, - 2045, 440, 1967, 434, 441, 2326, 439, 377, 377, 847, - 442, 848, 435, 846, 444, 436, 443, 2326, 377, 710, - 710, 445, 1951, 701, 521, 521, 2326, 438, 377, 377, - 710, 446, 440, 701, 849, 441, 850, 439, 851, 377, - - 847, 442, 848, 858, 858, 444, 724, 443, 447, 377, - 448, 852, 445, 449, 1938, 2326, 853, 377, 377, 858, - 858, 710, 446, 854, 451, 849, 855, 850, 377, 851, - 377, 452, 453, 561, 2326, 2326, 456, 724, 562, 447, - 1928, 448, 852, 1985, 449, 463, 463, 853, 618, 618, - 618, 377, 619, 620, 854, 451, 1983, 855, 856, 377, - 1892, 621, 452, 453, 457, 458, 459, 460, 461, 461, - 461, 461, 461, 461, 462, 2326, 2326, 867, 377, 377, - 377, 1886, 377, 2326, 2326, 1877, 463, 463, 1873, 856, - 2326, 2326, 377, 868, 463, 463, 1868, 730, 730, 730, - - 377, 463, 463, 478, 478, 558, 558, 377, 867, 377, - 558, 558, 2326, 573, 710, 710, 860, 860, 574, 377, - 377, 377, 1849, 377, 868, 710, 869, 377, 377, 377, - 622, 377, 725, 870, 377, 377, 377, 1834, 377, 469, - 470, 471, 472, 473, 473, 473, 473, 473, 473, 474, - 377, 479, 359, 730, 730, 730, 710, 869, 377, 480, - 860, 860, 1823, 725, 870, 377, 864, 864, 469, 470, - 471, 472, 473, 473, 473, 473, 473, 473, 474, 731, - 864, 864, 479, 1813, 481, 482, 871, 736, 736, 736, - 480, 1803, 469, 470, 471, 472, 473, 473, 473, 473, - - 473, 473, 474, 872, 469, 470, 471, 472, 473, 473, - 473, 473, 473, 473, 474, 481, 482, 871, 1792, 483, - 484, 1785, 469, 470, 471, 472, 473, 473, 473, 473, - 473, 473, 474, 577, 872, 731, 895, 895, 578, 469, - 470, 471, 472, 473, 473, 473, 473, 473, 473, 474, - 483, 484, 736, 736, 736, 1778, 873, 1852, 469, 470, - 471, 472, 473, 473, 473, 473, 473, 473, 474, 737, - 653, 653, 653, 653, 469, 470, 471, 472, 473, 473, - 473, 473, 473, 473, 474, 2326, 2326, 873, 2326, 1577, - 710, 710, 2326, 2326, 874, 1688, 485, 485, 1539, 2326, - - 2326, 726, 468, 485, 485, 1741, 2326, 2326, 1737, 468, - 485, 485, 359, 359, 359, 1497, 468, 485, 485, 583, - 523, 1704, 517, 468, 584, 874, 518, 875, 1702, 468, - 468, 468, 726, 468, 737, 519, 468, 468, 468, 520, - 468, 876, 567, 468, 468, 468, 568, 468, 877, 878, - 468, 468, 468, 517, 468, 569, 879, 518, 875, 570, - 468, 880, 751, 751, 751, 1468, 519, 468, 1694, 2326, - 520, 597, 876, 567, 468, 1449, 598, 568, 1439, 877, - 878, 468, 491, 491, 491, 881, 569, 879, 882, 1543, - 570, 1653, 880, 493, 360, 493, 494, 525, 526, 527, - - 528, 529, 529, 529, 529, 529, 529, 530, 495, 496, - 1653, 497, 394, 394, 1629, 539, 881, 909, 1614, 882, - 498, 1586, 499, 753, 500, 532, 533, 534, 535, 536, - 536, 536, 536, 536, 536, 537, 605, 605, 605, 495, - 496, 606, 497, 607, 752, 612, 612, 612, 909, 608, - 613, 498, 614, 499, 753, 500, 601, 1573, 615, 913, - 913, 602, 1687, 501, 502, 503, 504, 505, 505, 505, - 505, 505, 505, 506, 491, 491, 491, 1319, 912, 685, - 685, 685, 685, 697, 697, 493, 1567, 493, 494, 540, - 541, 542, 543, 544, 544, 544, 544, 544, 544, 545, - - 495, 496, 923, 497, 941, 651, 754, 754, 2326, 912, - 377, 377, 498, 942, 499, 945, 500, 755, 609, 638, - 946, 377, 638, 548, 697, 697, 2326, 616, 377, 377, - 1560, 495, 496, 923, 497, 941, 651, 1674, 549, 377, - 947, 763, 1777, 498, 942, 499, 945, 500, 755, 1289, - 638, 946, 377, 638, 548, 501, 502, 503, 504, 505, - 505, 505, 505, 505, 505, 506, 2326, 2326, 2326, 549, - 377, 947, 763, 924, 924, 727, 727, 2326, 1539, 2326, - 494, 532, 533, 534, 535, 536, 536, 536, 536, 536, - 536, 537, 551, 727, 727, 1271, 532, 533, 534, 535, - - 536, 536, 536, 536, 536, 536, 537, 639, 640, 641, - 642, 643, 643, 643, 643, 643, 643, 644, 717, 717, - 552, 553, 554, 555, 556, 556, 556, 556, 556, 556, - 557, 675, 676, 677, 678, 679, 679, 679, 679, 679, - 679, 680, 960, 960, 377, 377, 1203, 501, 507, 503, - 504, 505, 505, 505, 505, 505, 505, 506, 2326, 2326, - 2326, 468, 468, 2326, 2326, 1681, 605, 605, 605, 2326, - 1784, 2326, 2326, 883, 521, 521, 2326, 2326, 1480, 2326, - 492, 377, 377, 2326, 2326, 1478, 933, 558, 558, 492, - 492, 1181, 377, 531, 558, 558, 612, 612, 612, 765, - - 531, 2326, 2326, 887, 934, 531, 531, 492, 492, 492, - 1457, 492, 558, 558, 628, 628, 628, 933, 531, 1170, - 531, 531, 531, 377, 531, 2326, 2326, 531, 531, 531, - 765, 531, 719, 719, 1416, 934, 558, 558, 492, 638, - 638, 647, 531, 928, 948, 531, 531, 531, 609, 531, - 756, 531, 756, 2326, 1700, 757, 757, 1264, 531, 1802, - 2326, 674, 674, 618, 618, 618, 377, 891, 1264, 531, - 531, 531, 647, 531, 928, 948, 531, 949, 616, 639, - 640, 641, 642, 643, 643, 643, 643, 643, 643, 644, - 2326, 1260, 377, 377, 689, 689, 629, 377, 683, 760, - - 531, 630, 630, 377, 1065, 630, 630, 1260, 949, 630, - 630, 630, 630, 630, 630, 630, 630, 630, 1122, 1122, - 630, 630, 630, 630, 630, 2326, 2326, 710, 710, 683, - 760, 1256, 2326, 2326, 377, 1065, 653, 653, 897, 897, - 897, 1066, 638, 653, 653, 622, 362, 362, 1256, 638, - 492, 630, 630, 630, 1395, 630, 675, 676, 677, 678, - 679, 679, 679, 679, 679, 679, 680, 492, 1051, 638, - 638, 638, 1066, 638, 1053, 1391, 638, 638, 638, 492, - 638, 492, 630, 632, 633, 634, 635, 636, 636, 636, - 636, 636, 636, 637, 648, 1067, 1055, 649, 492, 1051, - - 638, 657, 657, 657, 2292, 2326, 2326, 638, 1389, 628, - 492, 1386, 2326, 2326, 370, 370, 653, 653, 384, 384, - 898, 682, 638, 653, 653, 648, 1067, 1384, 649, 638, - 956, 1020, 956, 492, 1134, 957, 957, 1129, 639, 640, - 641, 642, 643, 643, 643, 643, 643, 643, 644, 638, - 638, 638, 682, 638, 957, 957, 638, 638, 638, 1069, - 638, 1116, 1058, 1107, 492, 675, 676, 677, 678, 679, - 679, 679, 679, 679, 679, 680, 910, 910, 910, 2293, - 638, 684, 1102, 658, 664, 664, 664, 638, 666, 666, - 1069, 1268, 666, 666, 929, 929, 666, 666, 666, 666, - - 666, 666, 666, 666, 666, 930, 1070, 666, 666, 666, - 666, 666, 684, 690, 691, 692, 693, 694, 694, 694, - 694, 694, 694, 695, 1089, 675, 676, 677, 678, 679, - 679, 679, 679, 679, 679, 680, 930, 1070, 666, 666, - 666, 1085, 666, 2326, 2326, 1083, 2326, 1081, 377, 377, - 2326, 2326, 957, 957, 685, 685, 959, 959, 911, 769, - 674, 685, 685, 959, 959, 1250, 665, 674, 954, 666, - 668, 669, 670, 671, 672, 672, 672, 672, 672, 672, - 673, 492, 1072, 1059, 915, 915, 915, 674, 674, 674, - 769, 674, 2326, 2326, 674, 674, 674, 1073, 674, 2326, - - 2326, 960, 960, 685, 685, 943, 754, 754, 696, 674, - 685, 685, 492, 1072, 1059, 899, 674, 755, 674, 2326, - 939, 377, 377, 926, 958, 674, 958, 664, 1073, 959, - 959, 762, 377, 900, 901, 915, 674, 674, 674, 696, - 674, 910, 1074, 674, 674, 674, 899, 674, 755, 690, - 691, 692, 693, 694, 694, 694, 694, 694, 694, 695, - 2326, 2326, 762, 377, 900, 901, 916, 674, 2326, 2326, - 897, 697, 697, 1074, 674, 2326, 2326, 689, 1075, 697, - 697, 893, 2326, 2326, 1076, 689, 697, 697, 2326, 893, - 377, 377, 689, 697, 697, 455, 455, 524, 524, 689, - - 889, 377, 538, 538, 689, 689, 689, 889, 689, 1075, - 764, 1077, 689, 689, 689, 1076, 689, 361, 1078, 689, - 689, 689, 885, 689, 971, 1079, 689, 689, 689, 377, - 689, 2326, 377, 377, 377, 689, 550, 550, 700, 700, - 700, 764, 1077, 689, 805, 2326, 926, 926, 926, 1078, - 689, 885, 730, 730, 730, 971, 1079, 689, 702, 702, - 377, 1071, 702, 702, 631, 631, 702, 702, 702, 702, - 702, 702, 702, 702, 702, 805, 1068, 702, 702, 702, - 702, 702, 711, 712, 713, 714, 715, 715, 715, 715, - 715, 715, 716, 751, 363, 364, 365, 366, 367, 367, - - 367, 367, 367, 367, 368, 939, 939, 939, 702, 702, - 702, 736, 702, 2326, 2326, 730, 2326, 702, 377, 377, - 701, 2326, 2326, 700, 727, 727, 667, 667, 927, 834, - 710, 666, 727, 727, 731, 703, 703, 1080, 710, 702, - 704, 705, 706, 707, 708, 708, 708, 708, 708, 708, - 709, 720, 492, 721, 721, 1119, 1119, 710, 710, 710, - 834, 710, 2326, 2326, 722, 710, 710, 710, 1080, 710, - 1729, 1054, 664, 727, 727, 1833, 736, 736, 736, 710, - 943, 943, 943, 492, 954, 751, 751, 940, 710, 1797, - 2326, 657, 377, 377, 1885, 722, 710, 630, 700, 377, - - 2326, 2326, 1054, 377, 982, 1091, 710, 710, 710, 628, - 710, 727, 727, 1081, 1081, 1081, 775, 710, 711, 712, - 713, 714, 715, 715, 715, 715, 715, 715, 716, 2326, - 377, 377, 377, 618, 377, 982, 1091, 710, 2326, 2326, - 2326, 894, 377, 492, 710, 710, 710, 775, 710, 893, - 745, 745, 2326, 2326, 2326, 612, 362, 761, 737, 2326, - 2326, 2326, 944, 1052, 745, 745, 955, 1119, 1119, 890, - 362, 745, 745, 377, 492, 710, 889, 362, 2326, 2326, - 2326, 377, 605, 362, 362, 362, 377, 362, 761, 492, - 745, 745, 1121, 1121, 1052, 1082, 362, 362, 362, 362, - - 1056, 362, 1121, 1121, 362, 362, 362, 385, 362, 1122, - 1122, 886, 377, 2326, 362, 377, 377, 377, 885, 1092, - 492, 2326, 778, 362, 362, 362, 377, 362, 362, 491, - 2326, 1056, 1083, 1083, 1083, 362, 378, 379, 380, 381, - 382, 382, 382, 382, 382, 382, 383, 369, 1093, 2326, - 1092, 377, 377, 778, 362, 369, 369, 377, 359, 369, - 369, 736, 377, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 774, 1100, 369, 369, 369, 369, 369, 1093, - 1104, 386, 387, 388, 389, 390, 390, 390, 390, 390, - 390, 391, 456, 377, 1573, 1574, 1118, 739, 1118, 730, - - 492, 1119, 1119, 774, 1100, 369, 369, 369, 733, 369, - 723, 1104, 1674, 1675, 1084, 681, 1085, 1085, 1085, 1057, - 457, 458, 459, 460, 461, 461, 461, 461, 461, 461, - 462, 492, 1089, 897, 897, 657, 369, 371, 372, 373, - 374, 375, 375, 375, 375, 375, 375, 376, 369, 369, - 1057, 660, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 747, 747, 369, 369, 369, - 369, 369, 369, 1113, 646, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 369, 369, 369, 747, 747, - 369, 369, 369, 369, 2326, 2326, 645, 2326, 1086, 377, - - 377, 2326, 2326, 627, 1113, 463, 463, 625, 2326, 2326, - 377, 377, 463, 463, 1090, 1681, 1682, 785, 377, 463, - 463, 1573, 2326, 603, 2326, 377, 377, 377, 1700, 1701, - 600, 2326, 599, 377, 377, 787, 1123, 377, 377, 377, - 377, 377, 377, 596, 377, 377, 377, 377, 785, 377, - 1729, 1730, 377, 377, 377, 595, 377, 779, 369, 369, - 780, 369, 2326, 2326, 1674, 2326, 787, 1123, 377, 377, - 2326, 2326, 2326, 463, 463, 377, 377, 591, 2326, 377, - 1124, 749, 749, 377, 2326, 2326, 2326, 384, 779, 1131, - 1132, 780, 578, 929, 929, 749, 749, 1102, 910, 910, - - 2326, 384, 377, 377, 930, 1136, 377, 377, 377, 579, - 377, 1124, 576, 377, 384, 384, 384, 575, 384, 1137, - 1131, 1132, 2326, 2326, 2326, 972, 572, 793, 384, 384, - 384, 571, 384, 749, 749, 930, 1136, 377, 377, 384, - 2326, 2326, 2326, 377, 377, 384, 1107, 915, 915, 491, - 1137, 749, 749, 1116, 926, 926, 972, 384, 793, 384, - 395, 2326, 2326, 2326, 377, 377, 384, 384, 384, 377, - 384, 1120, 243, 1120, 377, 377, 1121, 1121, 2326, 1103, - 377, 377, 758, 243, 384, 384, 384, 241, 384, 1138, - 759, 377, 1681, 2326, 1129, 939, 939, 384, 241, 766, - - 767, 2326, 1139, 377, 377, 2326, 377, 768, 1140, 2326, - 1239, 1797, 1798, 758, 377, 384, 396, 2326, 397, 397, - 1138, 759, 377, 2326, 781, 377, 377, 1240, 1108, 398, - 766, 767, 770, 1139, 771, 1117, 377, 2326, 768, 1140, - 973, 1239, 377, 772, 2326, 377, 492, 377, 492, 1229, - 773, 2326, 2326, 377, 377, 781, 2326, 1231, 1240, 2326, - 398, 377, 377, 770, 776, 771, 2326, 377, 782, 1700, - 2326, 973, 377, 377, 772, 777, 1130, 492, 377, 492, - 1229, 773, 783, 378, 379, 380, 381, 382, 382, 382, - 382, 382, 382, 383, 2326, 776, 377, 377, 2326, 782, - - 377, 377, 2326, 377, 377, 377, 777, 377, 1729, 2326, - 1241, 377, 2326, 783, 2326, 377, 2326, 786, 377, 377, - 788, 1797, 2326, 2326, 784, 377, 377, 2326, 789, 377, - 2326, 2326, 2326, 1242, 377, 377, 377, 2326, 377, 377, - 377, 1241, 377, 790, 791, 377, 377, 2326, 786, 1149, - 377, 788, 792, 377, 796, 784, 794, 2326, 795, 789, - 377, 1134, 943, 943, 1242, 2326, 2326, 377, 377, 377, - 2326, 2326, 2326, 983, 790, 791, 377, 2326, 377, 377, - 1149, 377, 2326, 792, 377, 796, 2326, 794, 2326, 795, - 377, 377, 797, 2326, 2326, 377, 377, 798, 2326, 2326, - - 2326, 377, 377, 377, 983, 2326, 377, 377, 377, 377, - 377, 799, 2326, 377, 800, 2326, 1232, 2326, 377, 377, - 377, 2326, 2326, 797, 1243, 801, 492, 2326, 798, 802, - 377, 2326, 377, 2326, 985, 377, 377, 377, 2326, 377, - 377, 377, 799, 1135, 377, 800, 377, 1232, 2326, 377, - 2326, 377, 377, 377, 2326, 1243, 801, 492, 517, 803, - 802, 377, 518, 377, 806, 985, 2326, 2326, 377, 377, - 377, 519, 804, 1244, 1245, 520, 2326, 377, 2326, 807, - 377, 377, 377, 808, 954, 751, 751, 2326, 377, 517, - 803, 377, 1150, 518, 377, 806, 2326, 2326, 377, 377, - - 1246, 819, 519, 804, 1244, 1245, 520, 377, 2326, 377, - 807, 377, 2326, 2326, 808, 2326, 814, 377, 377, 377, - 984, 377, 377, 1150, 809, 815, 377, 816, 377, 810, - 2326, 1246, 819, 2326, 2326, 377, 377, 811, 377, 812, - 377, 2326, 377, 377, 377, 813, 377, 814, 1247, 2326, - 820, 984, 377, 817, 377, 809, 815, 377, 816, 377, - 810, 818, 2326, 2326, 377, 377, 955, 2326, 811, 2326, - 812, 821, 2326, 377, 979, 377, 813, 377, 377, 1247, - 2326, 820, 377, 377, 817, 377, 2326, 377, 377, 377, - 822, 377, 818, 377, 2326, 2326, 377, 377, 2326, 377, - - 377, 377, 821, 824, 377, 979, 377, 377, 377, 377, - 978, 377, 823, 377, 2326, 826, 377, 377, 377, 2326, - 2326, 822, 377, 825, 377, 2326, 827, 377, 377, 828, - 377, 1248, 377, 377, 824, 2326, 2326, 1002, 377, 377, - 377, 978, 377, 823, 377, 377, 826, 986, 2326, 2326, - 377, 377, 2326, 2326, 825, 377, 377, 827, 377, 377, - 828, 829, 1248, 377, 377, 830, 377, 2326, 1002, 377, - 377, 377, 2326, 831, 377, 377, 377, 2326, 986, 832, - 377, 2326, 377, 377, 377, 377, 377, 2326, 2326, 2326, - 2326, 2326, 829, 833, 377, 2326, 830, 377, 2326, 2326, - - 835, 836, 836, 2326, 831, 2326, 2326, 455, 377, 377, - 832, 377, 2326, 377, 2326, 2326, 377, 377, 377, 377, - 988, 1249, 1235, 377, 833, 377, 2326, 2326, 2326, 2326, - 2326, 835, 492, 2326, 455, 455, 455, 836, 836, 2326, - 836, 836, 2326, 455, 2326, 2326, 455, 2326, 2326, 377, - 377, 988, 1249, 1235, 377, 836, 836, 2326, 485, 485, - 2326, 455, 2326, 492, 468, 455, 1230, 1251, 1252, 492, - 455, 455, 455, 455, 455, 455, 838, 838, 838, 838, - 838, 838, 838, 838, 838, 838, 838, 1253, 455, 455, - 455, 468, 468, 468, 840, 468, 2326, 1230, 1251, 1252, - - 492, 455, 2326, 2326, 455, 469, 470, 471, 472, 473, - 473, 473, 473, 473, 473, 474, 2326, 2326, 1253, 455, - 2326, 2326, 468, 2326, 2326, 840, 2326, 485, 485, 2326, - 2326, 2326, 2326, 468, 485, 485, 2326, 2326, 2326, 2326, - 468, 485, 485, 478, 478, 2326, 1266, 468, 1267, 469, - 470, 471, 472, 473, 473, 473, 473, 473, 473, 474, - 468, 468, 468, 974, 468, 377, 841, 468, 468, 468, - 377, 468, 1278, 1279, 468, 468, 468, 1266, 468, 1267, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 839, 2326, - 2326, 468, 2326, 2326, 974, 2326, 377, 841, 468, 2326, - - 842, 377, 2326, 1278, 1279, 468, 2326, 2326, 469, 470, - 471, 472, 473, 473, 473, 473, 473, 473, 474, 839, - 469, 470, 471, 472, 473, 473, 473, 473, 473, 473, - 474, 842, 469, 470, 471, 472, 473, 473, 473, 473, - 473, 473, 474, 843, 844, 845, 845, 845, 845, 845, - 845, 845, 845, 845, 845, 845, 2326, 2326, 469, 470, - 471, 472, 473, 473, 473, 473, 473, 473, 474, 2326, - 2326, 2326, 2326, 2326, 843, 844, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 469, 470, 471, 472, 473, 473, - 473, 473, 473, 473, 474, 2326, 377, 990, 1089, 897, - - 897, 377, 469, 470, 471, 472, 473, 473, 473, 473, - 473, 473, 474, 469, 470, 471, 472, 473, 473, 473, - 473, 473, 473, 474, 491, 491, 491, 377, 990, 2326, - 2326, 2326, 377, 2326, 2326, 493, 1283, 493, 494, 857, - 857, 857, 857, 857, 857, 857, 857, 857, 857, 857, - 495, 496, 977, 497, 523, 931, 2326, 931, 2326, 989, - 932, 932, 498, 377, 499, 377, 500, 1283, 377, 377, - 377, 710, 1161, 377, 2326, 2326, 2326, 2326, 2326, 2326, - 1090, 495, 496, 977, 497, 2326, 858, 858, 2326, 2326, - 989, 2326, 524, 498, 377, 499, 377, 500, 539, 377, - - 377, 377, 710, 1161, 377, 501, 502, 503, 504, 505, - 505, 505, 505, 505, 505, 506, 2326, 2326, 2326, 524, - 524, 524, 377, 524, 2326, 1284, 377, 2326, 2326, 2326, - 494, 525, 526, 527, 528, 529, 529, 529, 529, 529, - 529, 530, 2326, 2326, 2326, 2326, 2326, 1166, 710, 710, - 524, 2326, 2326, 377, 858, 858, 1284, 377, 2326, 710, - 524, 532, 533, 534, 535, 536, 536, 536, 536, 536, - 536, 537, 540, 541, 542, 543, 544, 544, 544, 544, - 544, 544, 545, 1102, 910, 910, 2326, 524, 524, 524, - 710, 524, 1263, 1085, 1085, 2326, 1264, 501, 507, 503, - - 504, 505, 505, 505, 505, 505, 505, 506, 2326, 2326, - 2326, 1288, 377, 2326, 2326, 2326, 2326, 377, 524, 2326, - 2326, 2326, 2326, 1003, 521, 521, 2326, 2326, 2326, 2326, - 492, 377, 2326, 2326, 2326, 2326, 377, 995, 858, 858, - 2326, 2326, 1288, 377, 524, 858, 858, 2326, 377, 710, - 710, 524, 2326, 2326, 1003, 377, 377, 492, 492, 492, - 710, 492, 377, 558, 558, 1103, 2326, 377, 995, 531, - 936, 524, 524, 524, 1265, 524, 2326, 975, 524, 524, - 524, 976, 524, 2326, 377, 993, 377, 377, 492, 377, - 377, 710, 2326, 2326, 2326, 377, 531, 531, 531, 2326, - - 531, 936, 524, 2326, 558, 558, 2326, 2326, 975, 524, - 531, 2326, 976, 2326, 2326, 377, 993, 558, 558, 2326, - 377, 377, 1013, 531, 558, 558, 377, 531, 2326, 377, - 531, 2326, 2326, 2326, 377, 377, 377, 531, 531, 531, - 377, 531, 860, 860, 2326, 998, 2326, 377, 538, 377, - 531, 531, 531, 1013, 531, 2326, 2326, 531, 531, 531, - 377, 531, 1255, 1081, 1081, 377, 377, 377, 531, 1256, - 2326, 377, 2326, 2326, 2326, 538, 538, 538, 377, 538, - 377, 531, 377, 860, 860, 2326, 2326, 2326, 531, 538, - 2326, 2326, 2326, 2326, 2326, 2326, 860, 860, 2326, 2326, - - 710, 710, 538, 860, 860, 2326, 538, 2326, 980, 538, - 377, 710, 1001, 377, 377, 377, 538, 538, 538, 377, - 538, 981, 863, 377, 377, 1234, 935, 862, 377, 538, - 538, 538, 492, 538, 1293, 377, 538, 538, 538, 980, - 538, 377, 710, 1001, 1257, 377, 377, 538, 2326, 2326, - 377, 2326, 981, 863, 377, 377, 1234, 935, 862, 377, - 538, 2326, 551, 492, 2326, 1293, 377, 538, 532, 533, - 534, 535, 536, 536, 536, 536, 536, 536, 537, 532, - 533, 534, 535, 536, 536, 536, 536, 536, 536, 537, - 552, 553, 554, 555, 556, 556, 556, 556, 556, 556, - - 557, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 377, 377, 864, 864, 1308, 864, 864, 2326, 550, 864, - 864, 550, 2326, 2326, 2326, 550, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 864, 864, 2326, 2326, 653, 653, 550, - 2326, 377, 377, 638, 1297, 550, 550, 550, 550, 550, - 550, 377, 550, 550, 550, 866, 866, 866, 866, 866, - 866, 866, 866, 866, 866, 866, 550, 550, 550, 377, - 638, 638, 638, 377, 638, 1297, 550, 2326, 2326, 550, - 2326, 2326, 377, 550, 532, 533, 534, 535, 536, 536, - 536, 536, 536, 536, 537, 2326, 2326, 550, 630, 630, - - 377, 638, 630, 630, 377, 2326, 630, 630, 630, 630, - 630, 630, 630, 630, 630, 902, 377, 630, 630, 630, - 630, 630, 639, 640, 641, 642, 643, 643, 643, 643, - 643, 643, 644, 908, 908, 908, 908, 908, 908, 908, - 908, 908, 908, 908, 2326, 2326, 902, 377, 630, 630, - 630, 2326, 630, 2326, 639, 640, 641, 642, 643, 643, - 643, 643, 643, 643, 644, 639, 640, 641, 642, 643, - 643, 643, 643, 643, 643, 644, 1107, 915, 915, 630, - 632, 633, 634, 635, 636, 636, 636, 636, 636, 636, - 637, 630, 630, 2326, 2326, 630, 630, 630, 630, 630, - - 630, 630, 630, 630, 630, 630, 630, 630, 895, 895, - 630, 630, 630, 630, 630, 630, 377, 2326, 630, 630, - 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, - 630, 895, 895, 630, 630, 630, 630, 2326, 2326, 2326, - 2326, 2326, 710, 710, 2326, 2326, 2326, 377, 653, 653, - 2326, 2326, 2326, 710, 638, 653, 653, 2326, 1108, 2326, - 2326, 638, 653, 653, 2326, 2326, 2326, 937, 638, 675, - 676, 677, 678, 679, 679, 679, 679, 679, 679, 680, - 2326, 638, 638, 638, 710, 638, 2326, 2326, 638, 638, - 638, 903, 638, 1339, 1292, 638, 638, 638, 937, 638, - - 2326, 630, 630, 2326, 630, 2326, 2326, 2326, 2326, 904, - 377, 987, 638, 2326, 2326, 377, 377, 1000, 377, 638, - 905, 377, 903, 2326, 1339, 1292, 638, 2326, 2326, 639, - 640, 641, 642, 643, 643, 643, 643, 643, 643, 644, - 904, 377, 987, 2326, 906, 2326, 377, 377, 1000, 377, - 2326, 905, 377, 639, 640, 641, 642, 643, 643, 643, - 643, 643, 643, 644, 639, 640, 641, 642, 643, 643, - 643, 643, 643, 643, 644, 906, 907, 377, 2326, 1340, - 1341, 1309, 2326, 2326, 639, 640, 641, 642, 643, 643, - 643, 643, 643, 643, 644, 920, 920, 920, 920, 920, - - 920, 920, 920, 920, 920, 920, 2326, 907, 377, 917, - 1340, 1341, 639, 640, 641, 642, 643, 643, 643, 643, - 643, 643, 644, 666, 666, 2326, 2326, 666, 666, 2326, - 2326, 666, 666, 666, 666, 666, 666, 666, 666, 666, - 917, 918, 666, 666, 666, 666, 666, 675, 676, 677, - 678, 679, 679, 679, 679, 679, 679, 680, 675, 676, - 677, 678, 679, 679, 679, 679, 679, 679, 680, 2326, - 2326, 2326, 918, 666, 666, 666, 2326, 666, 2326, 2326, - 2326, 675, 676, 677, 678, 679, 679, 679, 679, 679, - 679, 680, 690, 691, 692, 693, 694, 694, 694, 694, - - 694, 694, 695, 2326, 666, 668, 669, 670, 671, 672, - 672, 672, 672, 672, 672, 673, 666, 666, 2326, 2326, - 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, - 666, 666, 666, 913, 913, 666, 666, 666, 666, 666, - 666, 1342, 2326, 666, 666, 666, 666, 666, 666, 666, - 666, 666, 666, 666, 666, 666, 913, 913, 666, 666, - 666, 666, 2326, 2326, 2326, 2326, 1116, 926, 926, 2326, - 2326, 2326, 1342, 685, 685, 2326, 2326, 2326, 1233, 674, - 685, 685, 2326, 2326, 2326, 1343, 674, 685, 685, 2326, - 2326, 2326, 492, 674, 922, 922, 922, 922, 922, 922, - - 922, 922, 922, 922, 922, 1236, 674, 674, 674, 1233, - 674, 2326, 1344, 674, 674, 674, 1343, 674, 919, 492, - 674, 674, 674, 492, 674, 2326, 666, 666, 2326, 666, - 2326, 2326, 2326, 2326, 377, 2326, 1236, 674, 2326, 377, - 1005, 685, 685, 1344, 674, 2326, 2326, 674, 1117, 919, - 492, 674, 1298, 2326, 675, 676, 677, 678, 679, 679, - 679, 679, 679, 679, 680, 377, 1295, 2326, 2326, 2326, - 377, 1005, 377, 377, 674, 674, 674, 2326, 674, 697, - 697, 2326, 2326, 1298, 994, 689, 377, 2326, 2326, 2326, - 2326, 377, 697, 697, 1337, 2326, 2326, 1295, 689, 1294, - - 697, 697, 2326, 377, 377, 674, 689, 2326, 2326, 1338, - 377, 377, 689, 689, 689, 994, 689, 377, 697, 697, - 2326, 2326, 377, 921, 689, 689, 689, 689, 377, 689, - 1294, 2326, 377, 689, 689, 689, 2326, 689, 2326, 2326, - 1338, 377, 377, 689, 2326, 2326, 2326, 1357, 1155, 1303, - 377, 689, 689, 689, 921, 689, 689, 2326, 2326, 377, - 1129, 939, 939, 377, 689, 377, 377, 690, 691, 692, - 693, 694, 694, 694, 694, 694, 694, 695, 1357, 1155, - 1303, 377, 689, 690, 691, 692, 693, 694, 694, 694, - 694, 694, 694, 695, 702, 702, 377, 377, 702, 702, - - 2326, 2326, 702, 702, 702, 702, 702, 702, 702, 702, - 702, 2326, 377, 702, 702, 702, 702, 702, 711, 712, - 713, 714, 715, 715, 715, 715, 715, 715, 716, 938, - 938, 938, 938, 938, 938, 938, 938, 938, 938, 938, - 2326, 2326, 1130, 377, 702, 702, 702, 2326, 702, 950, - 950, 950, 950, 950, 950, 950, 950, 950, 950, 950, - 951, 951, 951, 951, 951, 951, 951, 951, 951, 951, - 951, 1134, 943, 943, 2326, 702, 704, 705, 706, 707, - 708, 708, 708, 708, 708, 708, 709, 702, 702, 361, - 2326, 702, 702, 702, 702, 702, 702, 702, 702, 702, - - 702, 702, 702, 702, 924, 924, 702, 702, 702, 702, - 702, 702, 377, 2326, 702, 702, 702, 702, 702, 702, - 702, 702, 702, 702, 702, 702, 702, 924, 924, 702, - 702, 702, 702, 2326, 2326, 2326, 2326, 1543, 1543, 1543, - 2326, 2326, 2326, 377, 727, 727, 2326, 2326, 2326, 1304, - 710, 727, 727, 1135, 2326, 2326, 377, 710, 727, 727, - 385, 2326, 2326, 377, 710, 377, 363, 364, 365, 366, - 367, 367, 367, 367, 367, 367, 368, 710, 710, 710, - 1304, 710, 2326, 492, 710, 710, 710, 377, 710, 757, - 757, 710, 710, 710, 377, 710, 377, 702, 702, 2326, - - 702, 2326, 2326, 2326, 1374, 2326, 2326, 2326, 710, 2326, - 2326, 2326, 727, 727, 492, 710, 2326, 2326, 710, 1544, - 2326, 1382, 710, 952, 952, 952, 952, 952, 952, 952, - 952, 952, 952, 952, 386, 387, 388, 389, 390, 390, - 390, 390, 390, 390, 391, 710, 710, 710, 2326, 710, - 961, 963, 1382, 2326, 378, 379, 380, 381, 382, 382, - 382, 382, 382, 382, 383, 378, 379, 380, 381, 382, - 382, 382, 382, 382, 382, 383, 710, 720, 2326, 721, - 721, 961, 963, 2326, 962, 377, 377, 1383, 1007, 377, - 722, 377, 378, 379, 380, 381, 382, 382, 382, 382, - - 382, 382, 383, 2326, 378, 379, 380, 381, 382, 382, - 382, 382, 382, 382, 383, 962, 377, 377, 1383, 1007, - 377, 722, 377, 2326, 2326, 2326, 1385, 1387, 2326, 2326, - 964, 378, 379, 380, 381, 382, 382, 382, 382, 382, - 382, 383, 965, 2326, 711, 712, 713, 714, 715, 715, - 715, 715, 715, 715, 716, 369, 369, 1385, 1387, 369, - 369, 964, 2326, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 1388, 965, 369, 369, 369, 369, 369, 968, - 378, 379, 380, 381, 382, 382, 382, 382, 382, 382, - 383, 966, 378, 379, 380, 381, 382, 382, 382, 382, - - 382, 382, 383, 1388, 2326, 369, 369, 369, 2326, 369, - 968, 2326, 2326, 2326, 2326, 2326, 2326, 967, 2326, 2326, - 2326, 2326, 966, 2326, 2326, 378, 379, 380, 381, 382, - 382, 382, 382, 382, 382, 383, 369, 371, 372, 373, - 374, 375, 375, 375, 375, 375, 375, 376, 967, 378, - 379, 380, 381, 382, 382, 382, 382, 382, 382, 383, - 2326, 2326, 2326, 2326, 378, 379, 380, 381, 382, 382, - 382, 382, 382, 382, 383, 969, 1390, 997, 2326, 2326, - 970, 2326, 377, 2326, 2326, 1392, 2326, 377, 1042, 1042, - 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 1042, 2326, - - 991, 992, 2326, 996, 2326, 1393, 969, 1390, 997, 377, - 377, 970, 377, 377, 377, 377, 1392, 377, 377, 2326, - 378, 379, 380, 381, 382, 382, 382, 382, 382, 382, - 383, 991, 992, 377, 996, 999, 1393, 1009, 377, 2326, - 377, 377, 377, 377, 1004, 377, 377, 377, 377, 1006, - 1008, 2326, 1394, 377, 1010, 377, 377, 377, 377, 1012, - 377, 377, 377, 2326, 377, 377, 999, 1011, 1009, 377, - 377, 2326, 1014, 377, 377, 1004, 2326, 377, 377, 377, - 1006, 1008, 377, 1394, 377, 1010, 377, 377, 377, 377, - 1012, 377, 377, 377, 377, 1015, 377, 2326, 1011, 377, - - 1016, 377, 377, 1014, 377, 377, 377, 377, 377, 377, - 377, 377, 1017, 377, 1019, 1020, 1020, 1020, 1028, 377, - 1018, 1023, 2326, 377, 377, 377, 1015, 377, 377, 1029, - 377, 1016, 377, 377, 377, 377, 1022, 377, 377, 2326, - 377, 1396, 377, 1017, 1397, 1019, 1026, 2326, 377, 1028, - 377, 377, 1023, 377, 377, 377, 377, 1175, 377, 377, - 1029, 377, 1027, 377, 377, 377, 2326, 1022, 1024, 377, - 1025, 377, 1396, 1030, 2326, 1397, 377, 1026, 377, 377, - 377, 1031, 377, 1032, 377, 377, 2326, 377, 1175, 377, - 1033, 1035, 377, 1027, 377, 377, 377, 1021, 2326, 1024, - - 377, 1025, 377, 377, 1030, 1037, 2326, 377, 377, 377, - 377, 377, 1031, 377, 1032, 377, 377, 1034, 377, 377, - 377, 1033, 1035, 1038, 377, 377, 1036, 377, 377, 1041, - 492, 492, 1375, 1039, 377, 377, 1037, 1040, 377, 377, - 377, 377, 2326, 2326, 377, 456, 377, 2326, 1034, 377, - 377, 2326, 1377, 1043, 1038, 377, 2326, 1036, 2326, 377, - 1041, 492, 492, 1375, 1039, 2326, 377, 1044, 1040, 377, - 2326, 377, 2326, 457, 458, 459, 460, 461, 461, 461, - 461, 461, 461, 462, 1043, 2326, 469, 470, 471, 472, - 473, 473, 473, 473, 473, 473, 474, 2326, 1044, 2326, - - 2326, 1045, 1046, 1060, 1060, 1060, 1060, 1060, 1060, 1060, - 1060, 1060, 1060, 1060, 1263, 1085, 1085, 2326, 1264, 2326, - 2326, 469, 470, 471, 472, 473, 473, 473, 473, 473, - 473, 474, 1045, 1046, 2326, 2326, 2326, 1047, 2326, 2326, - 2326, 2326, 469, 470, 471, 472, 473, 473, 473, 473, - 473, 473, 474, 523, 2326, 2326, 2326, 469, 470, 471, - 472, 473, 473, 473, 473, 473, 473, 474, 1047, 1048, - 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, - 1061, 469, 470, 471, 472, 473, 473, 473, 473, 473, - 473, 474, 539, 2326, 2326, 2326, 1265, 2326, 1306, 2326, - - 1048, 1064, 1064, 1064, 1064, 1064, 1064, 1064, 1064, 1064, - 1064, 1064, 1178, 1398, 1062, 377, 377, 469, 470, 471, - 472, 473, 473, 473, 473, 473, 473, 474, 494, 1306, - 525, 526, 527, 528, 529, 529, 529, 529, 529, 529, - 530, 2326, 2326, 1178, 1398, 1062, 377, 377, 1420, 1424, - 1425, 2326, 1049, 532, 533, 534, 535, 536, 536, 536, - 536, 536, 536, 537, 2326, 2326, 540, 541, 542, 543, - 544, 544, 544, 544, 544, 544, 545, 1063, 377, 1420, - 1424, 1425, 377, 1049, 1087, 1087, 1087, 1087, 1087, 1087, - 1087, 1087, 1087, 1087, 1087, 501, 507, 503, 504, 505, - - 505, 505, 505, 505, 505, 506, 494, 551, 1063, 377, - 2326, 2326, 2326, 377, 2326, 1050, 1094, 2326, 2326, 1099, - 2326, 2326, 2326, 2326, 532, 533, 534, 535, 536, 536, - 536, 536, 536, 536, 537, 552, 553, 554, 555, 556, - 556, 556, 556, 556, 556, 557, 1050, 1094, 639, 640, - 641, 642, 643, 643, 643, 643, 643, 643, 644, 377, - 639, 640, 641, 642, 643, 643, 643, 643, 643, 643, - 644, 1095, 2326, 501, 507, 503, 504, 505, 505, 505, - 505, 505, 505, 506, 630, 630, 2326, 2326, 630, 630, - 377, 2326, 630, 630, 630, 630, 630, 630, 630, 630, - - 630, 1096, 1095, 630, 630, 630, 630, 630, 377, 1162, - 377, 1310, 377, 377, 377, 1153, 639, 640, 641, 642, - 643, 643, 643, 643, 643, 643, 644, 1097, 377, 377, - 377, 377, 1096, 2326, 630, 630, 630, 2326, 630, 377, - 1162, 377, 1310, 377, 377, 377, 1153, 639, 640, 641, - 642, 643, 643, 643, 643, 643, 643, 644, 1097, 377, - 377, 377, 377, 2326, 1098, 630, 632, 633, 634, 635, - 636, 636, 636, 636, 636, 636, 637, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 639, 640, 641, 642, 643, 643, - 643, 643, 643, 643, 644, 1098, 2326, 377, 2326, 2326, - - 377, 1180, 2326, 639, 640, 641, 642, 643, 643, 643, - 643, 643, 643, 644, 1105, 1105, 1105, 1105, 1105, 1105, - 1105, 1105, 1105, 1105, 1105, 666, 666, 1111, 377, 666, - 666, 377, 1180, 666, 666, 666, 666, 666, 666, 666, - 666, 666, 1109, 2326, 666, 666, 666, 666, 666, 377, - 1176, 377, 1317, 377, 1322, 377, 675, 676, 677, 678, - 679, 679, 679, 679, 679, 679, 680, 2326, 1168, 377, - 1184, 377, 1112, 1109, 377, 666, 666, 666, 2326, 666, - 377, 1176, 377, 1317, 377, 1322, 377, 675, 676, 677, - 678, 679, 679, 679, 679, 679, 679, 680, 1110, 1168, - - 377, 1184, 377, 1112, 1452, 377, 666, 668, 669, 670, - 671, 672, 672, 672, 672, 672, 672, 673, 690, 691, - 692, 693, 694, 694, 694, 694, 694, 694, 695, 1110, - 932, 932, 2326, 2326, 1143, 1452, 2326, 675, 676, 677, - 678, 679, 679, 679, 679, 679, 679, 680, 1114, 1114, - 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 702, - 702, 2326, 2326, 702, 702, 1143, 2326, 702, 702, 702, - 702, 702, 702, 702, 702, 702, 1125, 1305, 702, 702, - 702, 702, 702, 377, 378, 379, 380, 381, 382, 382, - 382, 382, 382, 382, 383, 711, 712, 713, 714, 715, - - 715, 715, 715, 715, 715, 716, 1126, 1125, 1305, 702, - 702, 702, 2326, 702, 377, 2326, 2326, 2326, 2326, 2326, - 711, 712, 713, 714, 715, 715, 715, 715, 715, 715, - 716, 1259, 1083, 1083, 2326, 2326, 2326, 1126, 1260, 2326, - 702, 704, 705, 706, 707, 708, 708, 708, 708, 708, - 708, 709, 1127, 377, 377, 377, 1296, 377, 377, 377, - 1186, 2326, 2326, 711, 712, 713, 714, 715, 715, 715, - 715, 715, 715, 716, 1141, 1185, 377, 1187, 1172, 377, - 377, 377, 2326, 1127, 377, 377, 377, 1296, 377, 377, - 377, 1186, 711, 712, 713, 714, 715, 715, 715, 715, - - 715, 715, 716, 1142, 1453, 1141, 1185, 377, 1187, 2326, - 377, 377, 377, 1261, 2326, 378, 379, 380, 381, 382, - 382, 382, 382, 382, 382, 383, 1144, 1193, 377, 377, - 492, 1145, 1192, 377, 1142, 1453, 2326, 378, 379, 380, - 381, 382, 382, 382, 382, 382, 382, 383, 2326, 2326, - 2326, 1380, 2326, 2326, 2326, 2326, 1146, 1144, 1193, 377, - 377, 492, 1145, 1192, 377, 378, 379, 380, 381, 382, - 382, 382, 382, 382, 382, 383, 378, 379, 380, 381, - 382, 382, 382, 382, 382, 382, 383, 1146, 1255, 1081, - 1081, 2326, 2326, 2326, 2326, 1256, 2326, 378, 379, 380, - - 381, 382, 382, 382, 382, 382, 382, 383, 378, 379, - 380, 381, 382, 382, 382, 382, 382, 382, 383, 1147, - 377, 377, 1154, 1148, 377, 377, 377, 377, 377, 1160, - 377, 377, 377, 377, 1208, 1151, 1152, 377, 377, 2326, - 1157, 1158, 1259, 1083, 1083, 2326, 2326, 2326, 2326, 1260, - 1147, 377, 377, 1154, 1148, 377, 377, 377, 377, 377, - 1160, 377, 377, 377, 377, 1208, 1151, 1152, 377, 377, - 1257, 1157, 1158, 378, 379, 380, 381, 382, 382, 382, - 382, 382, 382, 383, 377, 377, 377, 377, 377, 377, - 377, 377, 377, 2326, 377, 1459, 377, 1164, 377, 1156, - - 377, 1159, 1163, 1165, 377, 1167, 2326, 2326, 2326, 377, - 1170, 1170, 1170, 1169, 2326, 377, 377, 377, 377, 377, - 377, 377, 377, 377, 1261, 377, 1459, 377, 1164, 377, - 1156, 377, 1159, 1163, 1165, 377, 1167, 377, 377, 377, - 377, 377, 377, 377, 1169, 377, 2326, 377, 2326, 377, - 1174, 377, 2326, 1173, 2326, 1177, 1181, 1181, 1181, 1183, - 1179, 2326, 2326, 377, 2326, 377, 2326, 377, 377, 377, - 377, 377, 377, 377, 377, 377, 377, 1299, 377, 1188, - 377, 1174, 377, 377, 1173, 1189, 1177, 377, 377, 377, - 1183, 1179, 1171, 377, 377, 377, 377, 1191, 377, 377, - - 377, 1190, 377, 1194, 377, 377, 377, 2326, 1299, 377, - 1188, 2326, 2326, 2326, 377, 1329, 1189, 1210, 377, 377, - 377, 377, 377, 377, 377, 2326, 377, 377, 1191, 2326, - 377, 377, 1190, 2326, 1194, 377, 377, 1205, 1182, 2326, - 377, 1020, 1020, 1020, 2326, 2326, 1329, 2326, 1210, 1203, - 1203, 1203, 377, 377, 377, 463, 463, 2326, 377, 2326, - 377, 377, 1311, 1195, 377, 377, 1196, 1197, 1205, 377, - 377, 1461, 377, 377, 377, 1206, 377, 1198, 1199, 1200, - 377, 1207, 2326, 1201, 1211, 2326, 2326, 377, 377, 377, - 377, 377, 377, 1311, 2326, 377, 377, 1196, 1197, 2326, - - 377, 377, 1461, 377, 377, 377, 1206, 377, 1198, 1199, - 1200, 377, 1207, 377, 1201, 1211, 1209, 377, 377, 377, - 377, 1020, 1213, 1202, 377, 377, 1212, 2326, 377, 377, - 377, 1204, 377, 1218, 377, 1216, 377, 377, 1217, 377, - 377, 1214, 1219, 377, 377, 1215, 377, 1209, 377, 2326, - 377, 377, 1474, 1213, 377, 377, 377, 1212, 1220, 377, - 377, 377, 1222, 377, 1218, 377, 1216, 377, 377, 1217, - 377, 377, 1214, 1219, 377, 377, 1215, 377, 1221, 377, - 377, 377, 377, 1474, 377, 377, 2326, 2326, 2326, 1220, - 2326, 2326, 2326, 1222, 2326, 2326, 1223, 2326, 1475, 1476, - - 2326, 2326, 2326, 1813, 1813, 1813, 377, 2326, 2326, 1221, - 377, 377, 1224, 377, 1477, 377, 469, 470, 471, 472, - 473, 473, 473, 473, 473, 473, 474, 1223, 1225, 1475, - 1476, 469, 470, 471, 472, 473, 473, 473, 473, 473, - 473, 474, 1226, 1224, 2326, 1477, 469, 470, 471, 472, - 473, 473, 473, 473, 473, 473, 474, 469, 470, 471, - 472, 473, 473, 473, 473, 473, 473, 474, 494, 1237, - 2326, 2326, 1227, 1226, 469, 470, 471, 472, 473, 473, - 473, 473, 473, 473, 474, 1814, 2326, 469, 470, 471, - 472, 473, 473, 473, 473, 473, 473, 474, 532, 533, - - 534, 535, 536, 536, 536, 536, 536, 536, 537, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 1300, 1313, 638, - 1238, 1323, 1318, 1328, 377, 377, 1358, 2326, 1324, 1269, - 377, 377, 377, 377, 377, 501, 507, 503, 504, 505, - 505, 505, 505, 505, 505, 506, 494, 2326, 1300, 1313, - 2326, 1238, 1323, 1318, 1328, 377, 377, 1358, 2326, 1324, - 1269, 377, 377, 377, 377, 377, 1276, 1376, 1479, 1270, - 1483, 1484, 492, 1228, 532, 533, 534, 535, 536, 536, - 536, 536, 536, 536, 537, 639, 640, 641, 642, 643, - 643, 643, 643, 643, 643, 644, 640, 2326, 1376, 1479, - - 1270, 1483, 1484, 492, 1228, 2326, 2326, 1481, 1487, 2326, - 1482, 2326, 2326, 501, 507, 503, 504, 505, 505, 505, - 505, 505, 505, 506, 639, 640, 641, 642, 643, 643, - 643, 643, 643, 643, 644, 1271, 1271, 1271, 1481, 1487, - 1272, 1482, 1301, 1307, 1302, 2326, 2326, 2326, 1273, 1312, - 638, 2326, 2326, 2326, 1281, 2326, 638, 2326, 2326, 2326, - 2326, 2326, 2326, 377, 2326, 377, 2326, 377, 1275, 1488, - 377, 1325, 1336, 1301, 1307, 1302, 1277, 377, 377, 1280, - 1312, 2326, 2326, 675, 676, 677, 678, 679, 679, 679, - 679, 679, 679, 680, 377, 2326, 377, 1282, 377, 1275, - - 1488, 377, 1325, 1336, 1823, 1823, 1823, 1277, 377, 377, - 1280, 1181, 1181, 1181, 2326, 1489, 639, 1274, 641, 642, - 643, 643, 643, 643, 643, 643, 644, 640, 1282, 2326, - 2326, 2326, 2326, 640, 675, 676, 677, 678, 679, 679, - 679, 679, 679, 679, 680, 1285, 1489, 1490, 1491, 1326, - 2326, 2326, 2326, 675, 676, 677, 678, 679, 679, 679, - 679, 679, 679, 680, 690, 691, 692, 693, 694, 694, - 694, 694, 694, 694, 695, 2326, 1285, 2326, 1490, 1491, - 1326, 1286, 1334, 1365, 1335, 1367, 1824, 2326, 2326, 1492, - 377, 1379, 492, 1327, 377, 377, 492, 377, 1378, 1493, - - 1287, 711, 712, 713, 714, 715, 715, 715, 715, 715, - 715, 716, 1286, 1334, 1365, 1335, 1367, 1319, 1319, 1319, - 1492, 377, 1379, 492, 2326, 377, 377, 492, 377, 1378, - 1493, 1287, 1320, 2326, 2326, 1170, 1170, 1170, 2326, 711, - 712, 713, 714, 715, 715, 715, 715, 715, 715, 716, - 711, 712, 713, 714, 715, 715, 715, 715, 715, 715, - 716, 1289, 1289, 1289, 1314, 377, 1330, 1331, 2326, 1333, - 1332, 1359, 2326, 1315, 1813, 1813, 1813, 2326, 1360, 2326, - 1361, 1494, 377, 1432, 1366, 1362, 2326, 377, 377, 1363, - 377, 377, 377, 377, 377, 1314, 377, 1330, 1331, 1321, - - 1333, 1332, 1359, 377, 1315, 377, 377, 1364, 377, 1360, - 377, 1361, 1494, 377, 1432, 1366, 1362, 1316, 377, 377, - 1363, 377, 377, 377, 377, 377, 1368, 1446, 377, 377, - 377, 1289, 1289, 1289, 377, 377, 377, 377, 1364, 377, - 2326, 377, 378, 1290, 380, 381, 382, 382, 382, 382, - 382, 382, 383, 2326, 2326, 2326, 1814, 1368, 1446, 377, - 377, 377, 1370, 1467, 377, 1507, 377, 492, 377, 1429, - 2326, 469, 470, 471, 472, 473, 473, 473, 473, 473, - 473, 474, 469, 470, 471, 472, 473, 473, 473, 473, - 473, 473, 474, 1370, 1467, 377, 1507, 2326, 492, 377, - - 1429, 1291, 532, 533, 534, 535, 536, 536, 536, 536, - 536, 536, 537, 1430, 2326, 2326, 2326, 2326, 469, 470, - 471, 472, 473, 473, 473, 473, 473, 473, 474, 2326, - 2326, 2326, 1291, 1445, 378, 379, 380, 381, 382, 382, - 382, 382, 382, 382, 383, 2326, 2326, 2326, 1369, 2326, - 2326, 2326, 2326, 2326, 1979, 1979, 1979, 1371, 377, 2326, - 1433, 463, 463, 2326, 1445, 2326, 377, 377, 1434, 1431, - 1435, 1437, 1443, 2326, 377, 492, 377, 469, 470, 471, - 472, 473, 473, 473, 473, 473, 473, 474, 1371, 377, - 377, 1433, 377, 377, 377, 377, 377, 377, 377, 1434, - - 1431, 1435, 1437, 1443, 1381, 377, 492, 377, 1512, 469, - 470, 471, 472, 473, 473, 473, 473, 473, 473, 474, - 1399, 377, 2326, 377, 377, 377, 2326, 1170, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 1381, 1980, 2326, 2326, 1512, - 2326, 2326, 2326, 2326, 463, 463, 2326, 2326, 2326, 1514, - 377, 1399, 532, 533, 534, 535, 536, 536, 536, 536, - 536, 536, 537, 1400, 639, 640, 641, 642, 643, 643, - 643, 643, 643, 643, 644, 2326, 1444, 377, 377, 377, - 1514, 377, 2326, 2326, 2326, 1509, 2326, 1515, 377, 2326, - 1510, 1447, 639, 640, 641, 642, 643, 643, 643, 643, - - 643, 643, 644, 377, 1271, 1271, 1271, 1444, 377, 1401, - 1181, 1203, 1203, 1203, 2326, 2326, 1509, 1273, 1515, 377, - 1436, 1510, 1447, 1438, 1442, 653, 653, 1849, 1849, 1849, - 1402, 638, 1501, 1516, 377, 1454, 1345, 1346, 1347, 1348, - 1349, 1850, 1350, 377, 1351, 377, 377, 377, 377, 1352, - 2326, 1436, 1353, 1354, 1438, 1442, 1355, 1519, 638, 638, - 638, 1402, 638, 1501, 1516, 2326, 1454, 1345, 1346, 1347, - 1348, 1349, 1417, 1350, 377, 1351, 377, 377, 377, 377, - 1352, 1418, 1520, 1353, 1354, 2326, 1403, 1355, 1519, 638, - 2326, 1271, 2326, 1356, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 1417, 2326, 2326, 2326, 2326, 2326, 1851, - 463, 463, 1418, 1520, 2326, 1419, 377, 1521, 2326, 639, - 640, 641, 642, 643, 643, 643, 643, 643, 643, 644, - 2326, 639, 640, 641, 642, 643, 643, 643, 643, 643, - 643, 644, 1422, 377, 377, 377, 1419, 377, 1521, 1421, - 2326, 2326, 2326, 2326, 2326, 2326, 1439, 1439, 1439, 639, - 640, 641, 642, 643, 643, 643, 643, 643, 643, 644, - 2326, 1440, 1423, 1422, 377, 1522, 1203, 494, 675, 676, - 677, 678, 679, 679, 679, 679, 679, 679, 680, 2326, - 2326, 2326, 675, 676, 677, 678, 679, 679, 679, 679, - - 679, 679, 680, 1423, 377, 1372, 1522, 2326, 1523, 1524, - 1525, 2326, 1426, 1981, 1981, 1981, 675, 676, 677, 678, - 679, 679, 679, 679, 679, 679, 680, 1449, 1449, 1449, - 2326, 2326, 640, 2326, 2326, 377, 1372, 1427, 1441, 1523, - 1524, 1525, 1450, 1426, 501, 507, 503, 504, 505, 505, - 505, 505, 505, 505, 506, 494, 711, 712, 713, 714, - 715, 715, 715, 715, 715, 715, 716, 1428, 1427, 1448, - 1458, 1526, 1373, 1496, 1527, 377, 377, 377, 2326, 377, - 2326, 2326, 2326, 2326, 711, 712, 713, 714, 715, 715, - 715, 715, 715, 715, 716, 1982, 2326, 2326, 1428, 2326, - - 1448, 1458, 1526, 1373, 1496, 1527, 377, 377, 377, 1451, - 377, 711, 712, 713, 714, 715, 715, 715, 715, 715, - 715, 716, 501, 507, 503, 504, 505, 505, 505, 505, - 505, 505, 506, 1404, 1405, 1271, 1271, 1404, 1404, 1406, - 1407, 1404, 1404, 1404, 1404, 1404, 1404, 1408, 1404, 1404, - 1407, 1407, 1404, 1404, 1404, 1404, 1404, 1407, 1407, 1407, - 1409, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, - 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, - 1407, 1407, 1407, 1404, 1404, 1404, 1407, 1404, 1407, 1407, - 1407, 1409, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, - - 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, - 1407, 1407, 1407, 1407, 1404, 1410, 1411, 1412, 1413, 1414, - 1414, 1414, 1414, 1414, 1414, 1415, 2326, 2326, 2326, 2326, - 1455, 2326, 2326, 1460, 1319, 1319, 1319, 1462, 1463, 1464, - 1465, 1466, 463, 463, 2326, 2326, 2326, 377, 377, 1320, - 377, 1495, 1500, 2326, 1528, 1505, 377, 1534, 377, 492, - 377, 1455, 377, 377, 1460, 1468, 1468, 1468, 1462, 1463, - 1464, 1465, 1466, 377, 377, 377, 377, 377, 377, 377, - 1469, 377, 1495, 1500, 1485, 1528, 1505, 377, 1534, 377, - 492, 377, 2326, 377, 377, 1471, 1486, 1536, 2326, 1472, - - 1473, 1502, 2326, 2326, 377, 377, 377, 1517, 1289, 1497, - 1497, 1497, 1518, 377, 1550, 1485, 1456, 2326, 2326, 2326, - 377, 2326, 2326, 2326, 1498, 1508, 1471, 1486, 1536, 492, - 1472, 1473, 1502, 463, 463, 2326, 2326, 2326, 1517, 377, - 2326, 2326, 2326, 1518, 377, 1550, 2326, 1470, 2326, 2326, - 2326, 377, 1506, 1551, 1511, 1554, 1508, 377, 492, 377, - 492, 1503, 492, 2326, 377, 377, 377, 377, 377, 2326, - 377, 469, 470, 471, 472, 473, 473, 473, 473, 473, - 473, 474, 1504, 1506, 1551, 1511, 1554, 2326, 377, 492, - 377, 1499, 1503, 492, 1513, 377, 377, 377, 2326, 1319, - - 469, 470, 471, 472, 473, 473, 473, 473, 473, 473, - 474, 2326, 377, 1504, 469, 470, 471, 472, 473, 473, - 473, 473, 473, 473, 474, 1513, 469, 470, 471, 472, - 473, 473, 473, 473, 473, 473, 474, 1529, 2326, 2326, - 2326, 1555, 1558, 377, 1557, 1561, 377, 377, 532, 533, - 534, 535, 536, 536, 536, 536, 536, 536, 537, 2326, - 2326, 2326, 2326, 1530, 2326, 377, 377, 377, 1529, 1405, - 1271, 1271, 1555, 1558, 1531, 1557, 1561, 377, 377, 2326, - 2326, 2326, 1408, 639, 640, 641, 642, 643, 643, 643, - 643, 643, 643, 644, 1530, 1532, 377, 377, 377, 2326, - - 2326, 377, 1556, 2326, 639, 640, 641, 642, 643, 643, - 643, 643, 643, 643, 644, 1405, 1271, 1271, 2326, 377, - 1531, 2326, 1405, 1271, 1271, 1568, 1532, 1531, 1408, 1405, - 1271, 1271, 377, 1556, 1531, 1408, 1562, 1439, 1439, 1439, - 1569, 1532, 1535, 1563, 1405, 1271, 1271, 2326, 1532, 1531, - 377, 1533, 1440, 1564, 377, 1532, 1568, 1408, 1565, 377, - 1537, 1537, 1570, 377, 2326, 2326, 2326, 1562, 377, 377, - 1532, 1569, 1532, 2326, 1563, 377, 1571, 1576, 377, 1532, - 1449, 1449, 1449, 377, 1564, 377, 1532, 377, 2326, 1565, - 377, 377, 2326, 1570, 377, 1450, 1545, 1533, 2326, 377, - - 377, 1532, 2326, 2326, 1533, 2326, 377, 1571, 1576, 377, - 2326, 1533, 1531, 1404, 377, 2326, 2326, 2326, 377, 1559, - 2326, 377, 377, 1537, 1537, 2326, 1533, 1545, 1546, 1407, - 639, 640, 641, 642, 643, 643, 643, 643, 643, 643, - 644, 639, 640, 641, 642, 643, 643, 643, 643, 643, - 643, 644, 377, 1587, 1588, 1589, 1407, 1407, 1407, 1546, - 1407, 2326, 1566, 2326, 2326, 2326, 639, 640, 641, 642, - 643, 643, 643, 643, 643, 643, 644, 1987, 1987, 1987, - 2040, 2040, 2040, 2326, 1587, 1588, 1589, 1407, 1407, 1538, - 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1407, 1404, - - 1405, 1271, 1271, 1404, 1404, 1531, 1404, 1404, 1404, 1404, - 1404, 1404, 1404, 1408, 1404, 1404, 1537, 1537, 1404, 1404, - 1404, 1404, 1547, 1590, 1591, 1592, 1541, 711, 712, 713, - 714, 715, 715, 715, 715, 715, 715, 716, 2326, 2326, - 2326, 2326, 2326, 2326, 1593, 1548, 2326, 1594, 1595, 1596, - 1597, 2326, 1598, 1547, 1590, 1591, 1592, 1541, 2326, 1988, - 2326, 2326, 2041, 675, 676, 677, 678, 679, 679, 679, - 679, 679, 679, 680, 1549, 1593, 1548, 1552, 1594, 1595, - 1596, 1597, 1542, 1598, 2326, 2326, 1404, 1404, 2326, 1404, - 675, 676, 677, 678, 679, 679, 679, 679, 679, 679, - - 680, 2326, 2326, 1553, 2326, 1549, 1599, 1600, 1552, 1601, - 1602, 1603, 675, 676, 677, 678, 679, 679, 679, 679, - 679, 679, 680, 711, 712, 713, 714, 715, 715, 715, - 715, 715, 715, 716, 1553, 1575, 2326, 1599, 1600, 1604, - 1601, 1602, 1603, 1605, 2326, 2326, 377, 1580, 711, 712, - 713, 714, 715, 715, 715, 715, 715, 715, 716, 2326, - 2326, 2326, 377, 1606, 2326, 2326, 1575, 1577, 1577, 1577, - 1604, 1581, 1607, 1608, 1605, 463, 463, 377, 1580, 2326, - 2326, 377, 1578, 377, 2326, 1609, 1610, 2326, 377, 1611, - 2326, 2326, 377, 377, 1606, 377, 1468, 1468, 1468, 1628, - - 1612, 2326, 1581, 1607, 1608, 2326, 2326, 492, 377, 377, - 377, 1469, 377, 2326, 377, 377, 1609, 1610, 1582, 377, - 1611, 377, 1583, 377, 1615, 1616, 377, 2326, 1620, 1617, - 1628, 1612, 377, 2326, 1584, 1497, 1497, 1497, 492, 377, - 1630, 1439, 2326, 2326, 2326, 377, 377, 2326, 2326, 1579, - 1498, 2326, 377, 1583, 2326, 1615, 1616, 2326, 463, 463, - 1617, 2326, 2326, 377, 377, 1584, 492, 1631, 1621, 1624, - 1632, 1630, 2326, 492, 492, 1619, 377, 492, 1585, 469, - 470, 471, 472, 473, 473, 473, 473, 473, 473, 474, - 1622, 377, 377, 377, 2326, 377, 2326, 492, 1631, 1621, - - 1624, 1632, 1623, 1618, 492, 492, 1619, 492, 492, 1625, - 2326, 2326, 1633, 1634, 492, 2326, 2326, 1613, 2326, 2326, - 2326, 1622, 377, 2326, 1449, 2326, 2326, 2326, 1635, 1636, - 2326, 2326, 1626, 1623, 1618, 1637, 1638, 492, 492, 1639, - 1625, 463, 463, 1633, 1634, 492, 1627, 377, 469, 470, - 471, 472, 473, 473, 473, 473, 473, 473, 474, 1635, - 1636, 1640, 1641, 1626, 1642, 1646, 1637, 1638, 492, 1650, - 1639, 1536, 1665, 1666, 377, 377, 377, 1627, 377, 2326, - 532, 533, 534, 535, 536, 536, 536, 536, 536, 536, - 537, 1643, 1640, 1641, 2326, 1642, 1646, 1668, 1669, 2326, - - 1650, 377, 1536, 1665, 1666, 377, 2326, 1468, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 1672, 1644, 377, - 1683, 1684, 1643, 377, 463, 463, 2326, 2326, 1668, 1669, - 377, 2326, 377, 2326, 2326, 2326, 2326, 639, 640, 641, - 642, 643, 643, 643, 643, 643, 643, 644, 1672, 1644, - 377, 1683, 1684, 2326, 377, 2326, 1685, 377, 377, 377, - 1692, 377, 639, 640, 641, 642, 643, 643, 643, 643, - 643, 643, 644, 1405, 1271, 1271, 2326, 377, 1531, 1405, - 1271, 1271, 2326, 2326, 1531, 2326, 1408, 1685, 377, 1670, - 1497, 1692, 1408, 1405, 1271, 1271, 377, 2326, 1531, 1532, - - 377, 1696, 1647, 1648, 1648, 1532, 1408, 1531, 377, 2326, - 1676, 1405, 1271, 1271, 1671, 1535, 1531, 1695, 1677, 1532, - 1670, 377, 1645, 377, 1408, 377, 377, 377, 1532, 2326, - 1532, 377, 1696, 2326, 1678, 1679, 1532, 1532, 1655, 1648, - 1648, 1676, 1697, 1656, 2326, 1671, 377, 377, 1695, 1677, - 1532, 1657, 377, 1645, 377, 1533, 377, 377, 1698, 1532, - 1660, 1533, 2326, 1703, 1658, 1678, 1679, 2326, 1532, 2326, - 2326, 2326, 2326, 1697, 2326, 1539, 2326, 377, 377, 2326, - 2326, 1661, 2326, 1705, 1649, 1405, 1271, 1271, 1708, 1698, - 1531, 1660, 2326, 1539, 1703, 1658, 2326, 2326, 1408, 2326, - - 639, 640, 641, 642, 643, 643, 643, 643, 643, 643, - 644, 1532, 1661, 1663, 1705, 2326, 1709, 1710, 1711, 1708, - 1659, 1688, 1688, 1688, 2326, 2326, 639, 640, 641, 642, - 643, 643, 643, 643, 643, 643, 644, 2326, 2326, 2326, - 2326, 2326, 1532, 2326, 1663, 2326, 1662, 1709, 1710, 1711, - 1712, 1689, 1713, 675, 676, 677, 678, 679, 679, 679, - 679, 679, 679, 680, 2326, 2326, 1651, 1652, 1651, 1651, - 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1662, 1664, 1686, - 1714, 1712, 1689, 1713, 1715, 1716, 1717, 377, 1667, 1718, - 675, 676, 677, 678, 679, 679, 679, 679, 679, 679, - - 680, 2326, 2326, 1690, 2326, 2326, 1577, 1577, 1577, 1664, - 1686, 1714, 2326, 2326, 2326, 1715, 1716, 1717, 377, 1667, - 1718, 1578, 2326, 675, 676, 677, 678, 679, 679, 679, - 679, 679, 679, 680, 711, 712, 713, 714, 715, 715, - 715, 715, 715, 715, 716, 711, 712, 713, 714, 715, - 715, 715, 715, 715, 715, 716, 1691, 2326, 1706, 1719, - 1720, 1721, 1722, 1724, 1725, 1726, 377, 1727, 377, 2326, - 2326, 2326, 377, 1731, 2326, 2326, 1707, 377, 1732, 1735, - 377, 492, 492, 1723, 377, 2326, 2326, 1691, 1693, 1706, - 1719, 1720, 1721, 1722, 1724, 1725, 1726, 377, 1727, 377, - - 2326, 2326, 2326, 377, 1731, 2326, 2326, 1707, 377, 1732, - 1735, 377, 492, 492, 1723, 377, 463, 463, 2326, 2326, - 2326, 1733, 377, 492, 469, 470, 471, 472, 473, 473, - 473, 473, 473, 473, 474, 1943, 1943, 1943, 2326, 2326, - 2326, 492, 492, 492, 1734, 492, 1736, 1738, 1739, 377, - 377, 377, 1733, 377, 492, 1944, 2326, 2326, 2326, 2326, - 2326, 469, 470, 471, 472, 473, 473, 473, 473, 473, - 473, 474, 492, 492, 492, 1740, 492, 1736, 1738, 1739, - 377, 1742, 1577, 532, 533, 534, 535, 536, 536, 536, - 536, 536, 536, 537, 1743, 1744, 1745, 1746, 1747, 1749, - - 1757, 2326, 1770, 2326, 2326, 2326, 1740, 2326, 2326, 1868, - 1868, 1868, 1742, 2326, 2326, 1771, 2326, 2019, 2326, 1751, - 1648, 1648, 2326, 1869, 1752, 1743, 1744, 1745, 1746, 1747, - 1749, 1757, 1753, 1770, 639, 640, 641, 642, 643, 643, - 643, 643, 643, 643, 644, 1754, 1771, 639, 640, 641, - 642, 643, 643, 643, 643, 643, 643, 644, 1405, 1271, - 1271, 2326, 2326, 1531, 1655, 1648, 1648, 2326, 2326, 1656, - 2326, 1408, 2326, 1405, 1271, 1271, 1754, 1657, 1531, 2326, - 1773, 1748, 2326, 377, 1532, 1774, 1408, 1405, 1271, 1271, - 1658, 1870, 1531, 1405, 1271, 1271, 2326, 377, 1531, 1532, - - 1408, 1755, 2326, 1407, 1407, 1776, 1408, 377, 1788, 1407, - 1407, 1773, 1748, 1532, 377, 1532, 1774, 2326, 1789, 1532, - 2326, 1658, 1758, 1271, 1271, 2326, 377, 1656, 377, 2326, - 1532, 2326, 1655, 1648, 1648, 1657, 1776, 1656, 377, 1788, - 1533, 1775, 2326, 1794, 1532, 1657, 1659, 377, 1658, 1789, - 1532, 1760, 1271, 1271, 2326, 1756, 1752, 377, 1658, 2326, - 1758, 1271, 1271, 1781, 1753, 1656, 1778, 1778, 1778, 1533, - 377, 377, 1775, 1762, 1794, 1539, 1782, 1754, 377, 1658, - 1758, 1271, 1271, 2326, 2326, 1656, 1658, 1795, 2326, 1658, - 1758, 1271, 1271, 1657, 1781, 1656, 1779, 377, 1791, 2326, - - 2326, 377, 377, 1657, 1759, 1783, 1658, 1782, 1754, 1785, - 1785, 1785, 1790, 377, 1659, 377, 1658, 1658, 1795, 1765, - 377, 377, 2326, 1763, 1799, 1800, 1801, 1779, 377, 1791, - 1792, 1792, 1792, 1761, 1806, 1807, 1783, 1658, 1808, 1786, - 1809, 2326, 1759, 1790, 377, 1320, 377, 1658, 1780, 2326, - 1765, 377, 377, 1766, 1763, 1799, 1800, 1801, 1810, 1811, - 2326, 2326, 1759, 2326, 2326, 1806, 1807, 2326, 2326, 1808, - 1786, 1809, 1764, 639, 640, 641, 642, 643, 643, 643, - 643, 643, 643, 644, 1766, 1767, 1768, 1812, 1815, 1810, - 1811, 1787, 639, 640, 641, 642, 643, 643, 643, 643, - - 643, 643, 644, 1816, 1817, 1818, 1819, 1820, 2326, 2326, - 2326, 2326, 1793, 2326, 2326, 2326, 1767, 1768, 1812, 1815, - 1769, 675, 676, 677, 678, 679, 679, 679, 679, 679, - 679, 680, 2326, 2326, 1816, 1817, 1818, 1819, 1820, 1772, - 675, 676, 677, 678, 679, 679, 679, 679, 679, 679, - 680, 1769, 1688, 1688, 1688, 1803, 1803, 1803, 2326, 675, - 676, 677, 678, 679, 679, 679, 679, 679, 679, 680, - 1772, 1821, 1822, 1825, 1826, 1827, 1828, 1829, 1830, 1831, - 2326, 377, 1689, 1842, 1843, 1804, 1979, 1979, 1979, 711, - 712, 713, 714, 715, 715, 715, 715, 715, 715, 716, - - 1832, 1837, 1821, 1822, 1825, 1826, 1827, 1828, 1829, 1830, - 1831, 377, 377, 1689, 1842, 1843, 1804, 1834, 1834, 1834, - 1844, 1845, 1846, 1847, 2326, 2326, 1873, 1873, 1873, 2326, - 2326, 1832, 1837, 2326, 1690, 1838, 492, 1805, 1840, 1848, - 1841, 1440, 377, 492, 492, 1867, 1839, 1835, 1872, 377, - 377, 1844, 1845, 1846, 1847, 469, 470, 471, 472, 473, - 473, 473, 473, 473, 473, 474, 1838, 492, 1980, 1840, - 1848, 1841, 1853, 377, 492, 492, 1867, 1839, 1835, 1872, - 377, 377, 2326, 2326, 2326, 469, 470, 471, 472, 473, - 473, 473, 473, 473, 473, 474, 1854, 1875, 377, 1836, - - 377, 1879, 1880, 1853, 377, 2326, 2326, 2326, 1874, 2326, - 2326, 639, 640, 641, 642, 643, 643, 643, 643, 643, - 643, 644, 2326, 2326, 2326, 1881, 1884, 1854, 1875, 377, - 1889, 377, 1879, 1880, 1890, 2326, 639, 640, 641, 642, - 643, 643, 643, 643, 643, 643, 644, 1405, 1271, 1271, - 2326, 2326, 1531, 1760, 1271, 1271, 1881, 1884, 1752, 2326, - 1408, 1889, 1751, 1648, 1648, 1890, 1753, 1752, 1891, 1760, - 1271, 1271, 1882, 1532, 1752, 1753, 1894, 1895, 377, 1754, - 2326, 1855, 1753, 1876, 2326, 1760, 1271, 1271, 1754, 2326, - 1752, 1896, 1760, 1271, 1271, 1754, 1883, 1752, 1856, 1891, - - 377, 1897, 377, 1882, 1532, 1753, 1898, 1894, 1895, 377, - 1754, 1754, 1855, 2326, 1876, 1760, 1271, 1271, 1754, 1754, - 1752, 2326, 1896, 2326, 1899, 1900, 1754, 1883, 1753, 1533, - 2326, 377, 1897, 377, 2326, 1761, 2326, 1898, 2326, 2326, - 1901, 1754, 1754, 2326, 1755, 2326, 2326, 2326, 1902, 1754, - 2326, 1761, 1751, 1648, 1648, 1899, 1900, 1752, 1857, 2326, - 1778, 1778, 1778, 2326, 2326, 1753, 2326, 1761, 1758, 1271, - 1271, 1901, 1754, 1656, 1858, 1758, 1271, 1271, 1754, 1902, - 1656, 1657, 1760, 1271, 1271, 2326, 2326, 1752, 1657, 1857, - 1779, 1760, 1271, 1271, 1658, 1753, 1752, 1761, 1655, 1648, - - 1648, 1658, 1903, 1656, 1753, 1758, 1271, 1271, 1754, 1754, - 1656, 1762, 1904, 1905, 1655, 1648, 1648, 1754, 1657, 1656, - 1906, 1779, 1907, 1908, 1658, 1658, 2326, 1657, 1862, 2326, - 1909, 1658, 1658, 1903, 1859, 1913, 1914, 1915, 1924, 1754, - 1658, 1925, 1780, 1904, 1905, 1877, 1877, 1877, 1754, 2326, - 1759, 1906, 1926, 1907, 1908, 1658, 2326, 1860, 1864, 1862, - 1450, 1909, 1658, 2326, 1761, 2326, 1913, 1914, 1915, 1924, - 2326, 1658, 1925, 1861, 2326, 2326, 1792, 1792, 1792, 2326, - 1659, 2326, 2326, 1926, 2326, 2326, 2326, 1759, 2326, 1864, - 1865, 1320, 2326, 1785, 1785, 1785, 1863, 1930, 492, 639, - - 640, 641, 642, 643, 643, 643, 643, 643, 643, 644, - 639, 640, 641, 642, 643, 643, 643, 643, 643, 643, - 644, 1865, 1866, 1786, 1981, 1981, 1981, 1878, 1930, 492, - 675, 676, 677, 678, 679, 679, 679, 679, 679, 679, - 680, 675, 676, 677, 678, 679, 679, 679, 679, 679, - 679, 680, 1871, 1866, 1786, 1886, 1886, 1886, 1793, 1892, - 1892, 1892, 2326, 675, 676, 677, 678, 679, 679, 679, - 679, 679, 679, 680, 1469, 1787, 2326, 1803, 1803, 1803, - 1823, 1823, 1823, 1871, 492, 1887, 1934, 1935, 1936, 1937, - 1927, 711, 712, 713, 714, 715, 715, 715, 715, 715, - - 715, 716, 377, 492, 1942, 1910, 1982, 1804, 1911, 1928, - 1928, 1928, 1950, 2326, 1933, 492, 1887, 1934, 1935, 1936, - 1937, 1927, 1912, 1959, 1498, 1834, 1834, 1834, 2326, 1961, - 1849, 1849, 1849, 377, 492, 1942, 1910, 1888, 1804, 1911, - 2326, 1893, 2326, 1950, 1850, 1933, 2326, 2326, 1951, 1951, - 1951, 2326, 1957, 1912, 1959, 1835, 1962, 1963, 2326, 1805, - 1961, 377, 1824, 1916, 2326, 1964, 1960, 1958, 1966, 1917, - 1931, 1952, 377, 1918, 1919, 1868, 1868, 1868, 1920, 1921, - 1922, 2326, 1923, 1957, 2326, 2326, 1835, 1962, 1963, 1869, - 2326, 1929, 377, 2326, 1916, 1932, 2326, 1960, 1958, 1966, - - 1917, 1931, 1952, 377, 1918, 1919, 2326, 1836, 2326, 1920, - 1921, 1922, 1851, 1923, 469, 470, 471, 472, 473, 473, - 473, 473, 473, 473, 474, 1969, 1932, 1938, 1938, 1938, - 1953, 2326, 2326, 2326, 2326, 469, 470, 471, 472, 473, - 473, 473, 473, 473, 473, 474, 1405, 1271, 1271, 2326, - 1939, 1531, 2326, 2326, 1970, 2326, 1969, 1870, 2326, 1408, - 1751, 1648, 1648, 1971, 2326, 1752, 1760, 1271, 1271, 1940, - 2326, 1752, 1532, 1856, 1948, 1751, 1648, 1648, 2326, 1753, - 1752, 1939, 1760, 1271, 1271, 1970, 1754, 1752, 1753, 1946, - 1965, 377, 1754, 2326, 1971, 1753, 1972, 2326, 2326, 2326, - - 1940, 1754, 2326, 1532, 2326, 1948, 2326, 2326, 1754, 1941, - 1943, 1943, 1943, 1973, 640, 2326, 1974, 1754, 1975, 2326, - 1946, 1965, 377, 1754, 1758, 1271, 1271, 1972, 1533, 1656, - 1944, 2326, 1754, 1760, 1271, 1271, 1976, 1657, 1752, 1754, - 1977, 1978, 1755, 1984, 1973, 1986, 1753, 1974, 1761, 1975, - 1658, 2326, 2326, 1758, 1271, 1271, 2326, 1859, 1656, 1754, - 1758, 1271, 1271, 2326, 1858, 1656, 1657, 1976, 2326, 2326, - 2326, 1977, 1978, 1657, 1984, 2326, 1986, 1989, 1990, 1658, - 1481, 1658, 1886, 1886, 1886, 1485, 1658, 1947, 2326, 2326, - 1754, 639, 1945, 641, 642, 643, 643, 643, 643, 643, - - 643, 644, 1991, 1992, 2326, 1949, 1860, 1993, 1989, 1990, - 1658, 1481, 1887, 2326, 2326, 1861, 1485, 1658, 1947, 675, - 676, 677, 678, 679, 679, 679, 679, 679, 679, 680, - 1994, 2326, 1997, 1991, 1992, 1759, 1949, 2326, 1993, 2326, - 2326, 2326, 1764, 1887, 675, 676, 677, 678, 679, 679, - 679, 679, 679, 679, 680, 1954, 1954, 1954, 1998, 1995, - 2326, 1994, 1996, 1997, 1888, 1873, 1873, 1873, 1877, 1877, - 1877, 1967, 1967, 1967, 1999, 1955, 1892, 1892, 1892, 2002, - 1440, 2005, 2000, 1450, 2006, 2007, 1578, 2003, 2008, 1998, - 1995, 1469, 2001, 1996, 2004, 377, 1928, 1928, 1928, 2009, - - 2013, 2014, 2015, 2016, 2017, 1999, 2326, 2326, 2326, 2326, - 2002, 1498, 2005, 2000, 2326, 2006, 2007, 2326, 2003, 2008, - 2018, 2010, 2326, 2001, 2326, 2004, 377, 2326, 2326, 2326, - 2009, 2013, 2014, 2015, 2016, 2017, 711, 1956, 713, 714, - 715, 715, 715, 715, 715, 715, 716, 1874, 2011, 2326, - 1878, 2018, 2010, 1968, 2020, 2020, 2020, 2326, 1893, 469, - 470, 471, 472, 473, 473, 473, 473, 473, 473, 474, - 2021, 2326, 2012, 2326, 2326, 1938, 1938, 1938, 1929, 2011, - 492, 2326, 2326, 2026, 2027, 2032, 2326, 469, 470, 471, - 472, 473, 473, 473, 473, 473, 473, 474, 1939, 2326, - - 2033, 2326, 2326, 2012, 2326, 2326, 2326, 2029, 2029, 2029, - 2326, 492, 653, 653, 2026, 2027, 2032, 1940, 638, 1951, - 1951, 1951, 2034, 2030, 2326, 1760, 1271, 1271, 2326, 1939, - 1752, 2033, 2035, 377, 2326, 2036, 2022, 2037, 1753, 1758, - 1271, 1271, 1952, 2038, 1656, 638, 638, 638, 1940, 638, - 2039, 1754, 1657, 2034, 377, 2326, 2024, 1941, 2326, 2023, - 1954, 1954, 1954, 2035, 377, 1658, 2036, 377, 2037, 2326, - 2326, 2042, 2043, 1952, 2038, 2326, 638, 2326, 1943, 2025, - 1955, 2039, 1754, 2326, 2326, 377, 640, 2326, 2044, 2031, - 2023, 1967, 1967, 1967, 727, 727, 1658, 2326, 377, 2046, - - 710, 1953, 2042, 2043, 2047, 2048, 1578, 1761, 675, 676, - 677, 678, 679, 679, 679, 679, 679, 679, 680, 2044, - 2049, 1759, 2051, 2052, 2053, 2053, 2053, 710, 710, 710, - 2046, 710, 2055, 2057, 2059, 2047, 2048, 1987, 1987, 1987, - 2060, 2061, 2028, 2062, 2063, 2064, 2065, 2066, 2326, 2067, - 2068, 2049, 2069, 2051, 2052, 2070, 2071, 2072, 710, 2073, - 1954, 2074, 2078, 2055, 2057, 2059, 2079, 2081, 2084, 2326, - 2326, 2060, 2061, 1968, 2062, 2063, 2064, 2065, 2066, 2056, - 2067, 2068, 2075, 2069, 2076, 2326, 2070, 2071, 2072, 2326, - 2073, 2326, 2074, 2078, 1943, 1943, 1943, 2079, 2081, 2084, - - 2020, 2020, 2020, 2087, 2087, 2087, 2054, 1760, 1271, 1271, - 2056, 2326, 1752, 2075, 1944, 2076, 2021, 2326, 2326, 1988, - 1753, 469, 470, 471, 472, 473, 473, 473, 473, 473, - 473, 474, 2085, 1754, 2326, 2326, 2326, 2086, 469, 470, - 471, 472, 473, 473, 473, 473, 473, 473, 474, 492, - 2083, 1954, 1954, 1954, 2326, 377, 2029, 2029, 2029, 2091, - 2077, 2092, 2093, 2085, 1754, 2082, 2094, 2095, 2086, 2326, - 2326, 1955, 2030, 2089, 2089, 2089, 2019, 2040, 2040, 2040, - 492, 2083, 2022, 2096, 377, 2088, 377, 2097, 2105, 1761, - 2091, 2077, 2092, 2093, 2326, 2108, 2082, 2094, 2095, 2109, - - 675, 676, 677, 678, 679, 679, 679, 679, 679, 679, - 680, 2098, 2098, 2098, 2096, 377, 640, 2110, 2097, 2105, - 2101, 2101, 2101, 2106, 2106, 2106, 2108, 2053, 2053, 2053, - 2109, 2111, 2113, 2028, 2102, 2114, 2115, 2116, 2031, 2117, - 2118, 2119, 2112, 2120, 2121, 2122, 2123, 2124, 2110, 2125, - 2126, 2127, 2127, 2127, 2326, 2090, 2087, 2087, 2087, 2041, - 2326, 2326, 2111, 2113, 2131, 2129, 2114, 2115, 2116, 2132, - 2117, 2118, 2119, 2133, 2120, 2121, 2122, 2123, 2124, 2326, - 2125, 2126, 469, 470, 471, 472, 473, 473, 473, 473, - 473, 473, 474, 2099, 492, 2131, 2129, 2134, 2136, 2137, - - 2132, 2138, 2103, 2139, 2133, 2107, 2130, 2326, 2140, 2054, - 469, 470, 471, 472, 473, 473, 473, 473, 473, 473, - 474, 2326, 2326, 2326, 2326, 492, 2326, 2326, 2134, 2136, - 2137, 2326, 2138, 2128, 2139, 2141, 377, 2130, 2088, 2140, - 2144, 2326, 2089, 2089, 2089, 2145, 2146, 2135, 2142, 2142, - 2142, 2147, 2152, 675, 676, 677, 678, 679, 679, 679, - 679, 679, 679, 680, 2153, 2155, 2141, 377, 2098, 2098, - 2098, 2144, 2101, 2101, 2101, 2156, 2145, 2146, 2135, 2148, - 2148, 2148, 2147, 2152, 2157, 2326, 2102, 2106, 2106, 2106, - 2326, 2158, 2159, 2326, 2160, 2153, 2155, 2326, 2161, 2326, - - 2162, 2163, 2164, 640, 2165, 2166, 2156, 2167, 2168, 2169, - 2170, 2127, 2127, 2127, 2171, 2157, 2149, 492, 2173, 2326, - 2174, 2150, 2158, 2159, 2090, 2160, 2175, 2172, 2154, 2161, - 2143, 2162, 2163, 2164, 2176, 2165, 2166, 2177, 2167, 2168, - 2169, 2170, 2326, 2326, 2326, 2171, 2326, 2149, 492, 2173, - 2099, 2174, 2150, 2326, 2103, 2326, 2326, 2175, 2172, 2154, - 2326, 2151, 2326, 2178, 2179, 2176, 2180, 2326, 2177, 2107, - 469, 470, 471, 472, 473, 473, 473, 473, 473, 473, - 474, 675, 676, 677, 678, 679, 679, 679, 679, 679, - 679, 680, 2184, 2128, 2178, 2179, 2185, 2180, 2142, 2142, - - 2142, 2148, 2148, 2148, 2186, 2187, 2188, 2326, 2189, 2190, - 2191, 2192, 2326, 2193, 2194, 2195, 2196, 2197, 2198, 2199, - 2200, 2201, 2202, 2184, 640, 2203, 492, 2185, 2205, 2206, - 2207, 2208, 2209, 2210, 2211, 2186, 2187, 2188, 2149, 2189, - 2190, 2191, 2192, 2150, 2193, 2194, 2195, 2196, 2197, 2198, - 2199, 2200, 2201, 2202, 2204, 2212, 2203, 492, 2326, 2205, - 2206, 2207, 2208, 2209, 2210, 2211, 2326, 2326, 2215, 2149, - 2216, 2219, 2220, 2221, 2150, 2222, 2223, 2223, 2223, 2225, - 2143, 2226, 2227, 2151, 2228, 2204, 2212, 2229, 469, 470, - 471, 472, 473, 473, 473, 473, 473, 473, 474, 2215, - - 2230, 2216, 2219, 2220, 2221, 2231, 2222, 2232, 2233, 2234, - 2225, 2235, 2226, 2227, 2236, 2228, 2237, 2238, 2229, 469, - 470, 471, 472, 473, 473, 473, 473, 473, 473, 474, - 2239, 2230, 2240, 2241, 2242, 2243, 2231, 2246, 2232, 2233, - 2234, 2247, 2235, 2248, 2249, 2236, 2250, 2237, 2238, 2244, - 2244, 2244, 2223, 2223, 2223, 2251, 2253, 2254, 2224, 2255, - 2256, 2239, 2257, 2240, 2241, 2242, 2243, 2258, 2246, 2259, - 2261, 2262, 2247, 2263, 2248, 2249, 2264, 2250, 2223, 2223, - 2223, 2244, 2244, 2244, 2265, 2266, 2251, 2253, 2254, 2267, - 2255, 2256, 2268, 2257, 2269, 2270, 2271, 2272, 2258, 2273, - - 2259, 2261, 2262, 2326, 2263, 2274, 2275, 2264, 2276, 2277, - 2278, 2279, 1943, 1943, 1943, 2265, 2266, 2284, 2285, 2286, - 2267, 2287, 2288, 2268, 2289, 2269, 2270, 2271, 2272, 2326, - 2273, 2245, 1944, 2290, 2224, 2326, 2274, 2275, 2294, 2276, - 2277, 2278, 2279, 2280, 2280, 2280, 2297, 2298, 2284, 2285, - 2286, 2281, 2287, 2288, 2299, 2289, 1954, 1954, 1954, 2300, - 2224, 2301, 2302, 2245, 2290, 2280, 2280, 2280, 2303, 2294, - 2304, 2305, 2306, 2281, 2307, 2308, 1955, 2297, 2298, 2309, - 2310, 2310, 2310, 2312, 2313, 2299, 2314, 2315, 2316, 2317, - 2300, 2318, 2301, 2302, 2019, 2310, 2310, 2310, 2319, 2303, - - 2320, 2304, 2305, 2306, 2321, 2307, 2308, 2310, 2310, 2310, - 2309, 2223, 2223, 2223, 2312, 2313, 2326, 2314, 2315, 2316, - 2317, 2322, 2318, 2323, 2324, 2282, 2325, 2283, 2326, 2319, - 2326, 2320, 2310, 2310, 2310, 2321, 2326, 2326, 2028, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2282, 2326, 2283, - 2326, 2326, 2322, 2326, 2323, 2324, 2326, 2325, 2326, 2326, - 2326, 2326, 2311, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2311, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2311, - 2326, 2326, 2326, 2224, 2326, 2326, 2326, 2326, 2326, 2326, - - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2311, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 105, 105, 105, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, - 105, 215, 215, 215, 215, 215, 215, 215, 215, 215, - - 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 231, - 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, - 231, 231, 231, 231, 231, 231, 231, 231, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 234, 237, 237, 237, - 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, - 237, 237, 237, 237, 237, 237, 240, 240, 240, 240, - 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, - - 240, 240, 240, 240, 240, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, - 242, 242, 242, 242, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, - 269, 269, 311, 311, 311, 311, 311, 311, 311, 311, - 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, - 311, 338, 338, 338, 338, 338, 338, 338, 338, 338, - 338, 338, 338, 338, 338, 338, 338, 338, 338, 338, - - 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, - 347, 347, 347, 347, 347, 347, 347, 347, 347, 362, - 362, 362, 2326, 2326, 2326, 2326, 362, 2326, 2326, 2326, - 2326, 362, 362, 362, 362, 370, 370, 2326, 370, 370, - 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, - 370, 370, 370, 370, 377, 377, 2326, 2326, 2326, 2326, - 377, 2326, 2326, 2326, 2326, 377, 377, 377, 377, 384, - 384, 384, 2326, 2326, 2326, 384, 2326, 2326, 2326, 2326, - 384, 384, 384, 384, 455, 455, 2326, 2326, 2326, 2326, - 455, 2326, 2326, 2326, 455, 455, 455, 455, 455, 464, - - 2326, 464, 464, 464, 464, 464, 464, 464, 468, 468, - 2326, 2326, 2326, 2326, 468, 2326, 2326, 2326, 2326, 468, - 468, 468, 468, 486, 2326, 486, 486, 486, 486, 486, - 486, 492, 492, 2326, 492, 492, 2326, 492, 492, 492, - 492, 2326, 2326, 2326, 2326, 492, 492, 492, 492, 522, - 2326, 522, 522, 522, 522, 524, 524, 524, 2326, 2326, - 2326, 2326, 524, 2326, 2326, 2326, 2326, 524, 524, 524, - 524, 531, 531, 2326, 2326, 2326, 2326, 531, 2326, 2326, - 2326, 2326, 531, 531, 531, 531, 538, 538, 538, 2326, - 2326, 2326, 538, 2326, 2326, 2326, 2326, 538, 538, 538, - - 538, 550, 550, 2326, 2326, 2326, 2326, 550, 2326, 2326, - 2326, 550, 550, 550, 550, 550, 559, 2326, 559, 559, - 559, 559, 560, 2326, 2326, 560, 2326, 560, 580, 2326, - 2326, 580, 2326, 580, 604, 604, 604, 604, 604, 604, - 2326, 604, 604, 604, 604, 604, 604, 2326, 604, 604, - 604, 604, 604, 610, 610, 610, 610, 610, 610, 610, - 610, 610, 610, 610, 610, 610, 610, 610, 610, 610, - 610, 610, 611, 611, 611, 611, 611, 611, 2326, 611, - 611, 611, 611, 611, 611, 2326, 611, 611, 611, 611, - 611, 617, 617, 617, 617, 617, 617, 617, 617, 617, - - 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, - 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, - 623, 623, 623, 623, 623, 623, 623, 623, 623, 624, - 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, - 624, 624, 624, 2326, 624, 624, 624, 624, 626, 626, - 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, - 626, 626, 2326, 626, 626, 626, 626, 631, 631, 2326, - 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, - 631, 631, 631, 631, 631, 631, 638, 638, 2326, 2326, - 2326, 2326, 638, 2326, 2326, 2326, 2326, 638, 638, 638, - - 638, 654, 2326, 654, 654, 654, 654, 654, 659, 659, - 2326, 659, 659, 659, 659, 659, 659, 659, 659, 659, - 659, 659, 659, 659, 659, 659, 659, 667, 667, 2326, + 60, 61, 62, 61, 63, 64, 65, 66, 67, 68, + 68, 63, 69, 70, 71, 72, 73, 74, 63, 63, + 63, 75, 63, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 66, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 66, 66, 60, + 60, 63, 66, 99, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 66, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 66, 66, + 60, 100, 101, 102, 103, 104, 104, 104, 104, 104, + 104, 105, 106, 106, 107, 106, 106, 106, 108, 108, + + 106, 109, 109, 110, 111, 106, 111, 106, 106, 112, + 106, 106, 106, 106, 106, 108, 108, 108, 108, 108, + 113, 108, 108, 114, 108, 108, 108, 108, 108, 108, + 108, 115, 116, 117, 108, 108, 108, 118, 108, 108, + 108, 106, 106, 106, 108, 106, 108, 108, 108, 108, + 108, 113, 108, 108, 114, 108, 108, 108, 108, 108, + 108, 108, 115, 116, 117, 108, 108, 108, 118, 108, + 108, 108, 106, 119, 120, 121, 122, 123, 123, 123, + 123, 123, 123, 124, 126, 126, 392, 393, 2492, 394, + 604, 604, 2486, 127, 127, 128, 129, 130, 129, 128, + + 128, 131, 131, 128, 128, 128, 132, 133, 128, 134, + 135, 128, 131, 128, 128, 128, 128, 128, 131, 131, + 131, 136, 137, 131, 138, 131, 131, 131, 131, 131, + 131, 131, 139, 140, 131, 141, 131, 142, 131, 131, + 131, 131, 131, 131, 128, 128, 128, 131, 128, 131, + 131, 131, 136, 137, 131, 138, 131, 131, 131, 131, + 131, 131, 131, 139, 140, 131, 141, 131, 142, 131, + 131, 131, 131, 131, 131, 128, 143, 144, 145, 146, + 147, 147, 147, 147, 147, 147, 148, 149, 149, 107, + 149, 149, 150, 151, 151, 152, 149, 149, 153, 149, + + 149, 149, 149, 149, 151, 149, 149, 149, 149, 149, + 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 154, 151, 151, 151, 155, + 151, 151, 151, 151, 151, 151, 149, 149, 149, 151, + 156, 151, 151, 151, 151, 151, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 154, 151, 151, 151, + 155, 151, 151, 151, 151, 151, 151, 149, 157, 158, + 159, 160, 161, 161, 161, 161, 161, 161, 162, 163, + 164, 165, 164, 163, 163, 163, 166, 167, 163, 163, + 168, 169, 170, 171, 172, 163, 166, 163, 163, 173, + + 163, 163, 166, 166, 166, 174, 175, 166, 176, 166, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 177, + 166, 178, 166, 166, 166, 166, 166, 166, 163, 163, + 163, 166, 163, 166, 166, 166, 174, 175, 166, 176, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, + 177, 166, 178, 166, 166, 166, 166, 166, 166, 163, + 163, 179, 163, 180, 163, 163, 163, 163, 163, 163, + 163, 182, 183, 182, 234, 182, 183, 182, 184, 234, + 237, 185, 184, 186, 237, 185, 240, 186, 190, 191, + 190, 240, 190, 191, 190, 192, 107, 107, 193, 192, + + 192, 107, 193, 107, 192, 476, 490, 355, 509, 511, + 477, 491, 355, 510, 512, 356, 235, 513, 269, 269, + 356, 235, 238, 2514, 357, 376, 238, 2471, 514, 357, + 313, 241, 313, 515, 516, 405, 241, 517, 355, 406, + 511, 564, 547, 355, 2475, 512, 356, 548, 513, 269, + 269, 356, 187, 2474, 188, 357, 187, 562, 188, 514, + 357, 313, 563, 313, 515, 516, 405, 2459, 517, 194, + 406, 195, 564, 194, 2458, 195, 196, 197, 198, 197, + 196, 196, 196, 199, 200, 201, 201, 202, 203, 204, + 205, 196, 196, 206, 196, 196, 201, 196, 196, 206, + + 206, 206, 206, 206, 206, 207, 206, 206, 206, 206, + 206, 206, 206, 206, 208, 206, 206, 209, 210, 206, + 206, 206, 206, 206, 206, 196, 196, 196, 206, 196, + 206, 206, 206, 206, 206, 206, 207, 206, 206, 206, + 206, 206, 206, 206, 206, 208, 206, 206, 209, 210, + 206, 206, 206, 206, 206, 206, 201, 196, 211, 196, + 212, 196, 196, 196, 196, 196, 196, 196, 213, 213, + 213, 213, 213, 213, 565, 486, 214, 566, 574, 214, + 218, 219, 218, 575, 2470, 220, 464, 221, 567, 222, + 223, 218, 219, 218, 578, 2455, 220, 728, 221, 579, + + 222, 223, 227, 228, 227, 565, 2442, 229, 566, 229, + 229, 229, 230, 227, 228, 227, 2455, 654, 229, 567, + 229, 229, 229, 230, 377, 378, 379, 380, 381, 381, + 381, 381, 381, 381, 382, 2514, 2514, 376, 376, 582, + 583, 2514, 586, 376, 488, 489, 587, 410, 428, 215, + 657, 216, 215, 376, 216, 466, 467, 424, 468, 584, + 411, 224, 599, 225, 585, 594, 595, 600, 596, 730, + 582, 583, 224, 586, 225, 603, 2434, 587, 410, 428, + 604, 657, 476, 231, 376, 232, 656, 477, 424, 663, + 664, 411, 719, 720, 231, 721, 232, 246, 247, 248, + + 247, 246, 249, 250, 251, 252, 253, 246, 246, 246, + 246, 254, 246, 246, 251, 246, 255, 246, 246, 256, + 251, 251, 251, 251, 251, 257, 258, 251, 251, 251, + 251, 259, 251, 251, 251, 251, 251, 260, 251, 251, + 251, 251, 251, 251, 251, 251, 246, 246, 246, 251, + 261, 251, 251, 251, 251, 251, 257, 258, 251, 251, + 251, 251, 259, 251, 251, 251, 251, 251, 260, 251, + 251, 251, 251, 251, 251, 251, 251, 246, 262, 263, + 264, 265, 266, 266, 266, 266, 266, 266, 267, 271, + 272, 271, 653, 273, 274, 640, 275, 276, 277, 358, + + 358, 358, 278, 271, 272, 271, 1290, 273, 274, 686, + 275, 276, 277, 2514, 490, 376, 278, 591, 662, 491, + 2514, 407, 376, 653, 700, 376, 640, 735, 2514, 279, + 376, 736, 376, 518, 592, 408, 418, 519, 409, 2442, + 419, 2439, 741, 279, 420, 412, 520, 2408, 591, 662, + 521, 413, 407, 2432, 742, 700, 376, 2423, 735, 2420, + 279, 2419, 736, 376, 518, 592, 408, 418, 519, 409, + 280, 419, 281, 741, 279, 420, 412, 520, 688, 689, + 359, 521, 413, 1289, 280, 742, 281, 282, 283, 284, + 283, 282, 285, 286, 287, 288, 289, 290, 282, 282, + + 282, 291, 282, 282, 287, 282, 282, 282, 282, 282, + 287, 287, 287, 287, 287, 292, 287, 287, 287, 287, + 287, 293, 287, 287, 287, 287, 287, 294, 287, 287, + 287, 287, 287, 287, 287, 287, 282, 282, 282, 287, + 282, 287, 287, 287, 287, 287, 292, 287, 287, 287, + 287, 287, 293, 287, 287, 287, 287, 287, 294, 287, + 287, 287, 287, 287, 287, 287, 287, 282, 295, 296, + 297, 298, 299, 299, 299, 299, 299, 299, 300, 107, + 107, 107, 107, 107, 301, 302, 302, 303, 107, 107, + 107, 107, 107, 107, 107, 107, 302, 107, 107, 107, + + 107, 304, 302, 302, 302, 302, 302, 305, 302, 302, + 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, + 302, 302, 302, 302, 302, 302, 302, 302, 107, 107, + 107, 302, 107, 302, 302, 302, 302, 302, 305, 302, + 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, + 302, 302, 302, 302, 302, 302, 302, 302, 302, 107, + 306, 307, 308, 309, 310, 310, 310, 310, 310, 310, + 311, 314, 315, 316, 315, 314, 317, 318, 319, 320, + 314, 314, 314, 321, 322, 323, 324, 314, 325, 314, + 326, 327, 314, 327, 319, 319, 319, 319, 319, 319, + + 328, 319, 319, 319, 319, 319, 319, 319, 319, 319, + 319, 319, 329, 319, 319, 319, 319, 319, 319, 319, + 314, 314, 314, 319, 330, 319, 319, 319, 319, 319, + 319, 328, 319, 319, 319, 319, 319, 319, 319, 319, + 319, 319, 319, 329, 319, 319, 319, 319, 319, 319, + 319, 314, 331, 332, 333, 334, 335, 335, 335, 335, + 335, 335, 336, 338, 339, 338, 1625, 1626, 340, 509, + 338, 339, 338, 2418, 510, 340, 341, 358, 358, 358, + 2378, 342, 743, 341, 630, 630, 630, 2368, 342, 744, + 343, 347, 348, 347, 1737, 1738, 349, 343, 347, 348, + + 347, 2324, 568, 349, 350, 360, 569, 344, 745, 351, + 2514, 350, 376, 743, 344, 570, 351, 512, 352, 571, + 744, 343, 376, 2396, 353, 352, 652, 2393, 343, 414, + 513, 353, 415, 568, 2390, 416, 547, 569, 344, 745, + 640, 548, 384, 640, 345, 344, 570, 514, 512, 352, + 571, 345, 2514, 376, 711, 353, 352, 652, 359, 2373, + 414, 513, 353, 415, 727, 631, 416, 630, 630, 630, + 562, 640, 354, 2372, 640, 563, 2325, 1282, 514, 354, + 2324, 362, 363, 364, 365, 366, 366, 366, 366, 366, + 366, 367, 368, 368, 574, 727, 368, 368, 2359, 575, + + 368, 368, 368, 368, 368, 368, 368, 368, 368, 2356, + 368, 368, 368, 368, 368, 385, 386, 387, 388, 389, + 389, 389, 389, 389, 389, 390, 578, 2514, 2514, 376, + 376, 579, 584, 599, 516, 451, 455, 585, 600, 376, + 376, 368, 368, 368, 2514, 368, 376, 2514, 631, 376, + 603, 1281, 1286, 2350, 651, 604, 376, 640, 421, 376, + 640, 422, 658, 658, 658, 516, 451, 455, 423, 417, + 376, 376, 368, 370, 371, 372, 373, 374, 374, 374, + 374, 374, 374, 375, 397, 651, 398, 376, 640, 421, + 376, 640, 422, 2514, 2277, 376, 399, 395, 758, 423, + + 417, 425, 658, 658, 658, 376, 517, 757, 759, 426, + 2323, 607, 607, 607, 2271, 427, 608, 854, 609, 2514, + 2315, 376, 2312, 2514, 610, 376, 1285, 399, 1744, 1745, + 2304, 376, 425, 855, 2246, 439, 376, 517, 757, 759, + 426, 429, 1625, 659, 856, 440, 427, 1750, 854, 2221, + 377, 378, 379, 380, 381, 381, 381, 381, 381, 381, + 382, 2514, 376, 376, 855, 2514, 439, 376, 857, 2514, + 858, 376, 429, 376, 430, 856, 440, 376, 431, 2216, + 400, 376, 401, 659, 859, 860, 432, 402, 403, 404, + 433, 397, 611, 755, 863, 2213, 864, 438, 2514, 857, + + 376, 858, 1737, 756, 376, 430, 434, 1852, 376, 431, + 376, 400, 376, 401, 435, 859, 860, 432, 402, 403, + 404, 433, 865, 436, 861, 863, 437, 864, 438, 876, + 1744, 2514, 877, 376, 756, 1859, 2514, 434, 376, 2203, + 862, 376, 2201, 441, 445, 435, 442, 2514, 376, 376, + 878, 446, 443, 865, 436, 861, 2263, 437, 444, 376, + 876, 447, 879, 877, 2514, 2260, 376, 1765, 448, 882, + 449, 862, 1879, 450, 441, 445, 376, 442, 2248, 376, + 2153, 878, 446, 443, 457, 1625, 2514, 2514, 2514, 444, + 376, 2219, 447, 879, 2514, 880, 376, 2215, 464, 448, + + 882, 449, 452, 376, 450, 2140, 376, 376, 883, 453, + 454, 881, 458, 459, 460, 461, 462, 462, 462, 462, + 462, 462, 463, 665, 665, 665, 880, 2514, 2514, 2138, + 376, 376, 376, 452, 376, 2514, 2514, 376, 464, 883, + 453, 454, 881, 376, 2514, 2514, 464, 761, 2196, 761, + 2514, 376, 762, 884, 885, 464, 1765, 1766, 2193, 588, + 376, 376, 376, 2514, 589, 376, 479, 1798, 1799, 2189, + 376, 376, 376, 2180, 376, 376, 590, 768, 376, 376, + 376, 761, 376, 761, 884, 885, 968, 376, 376, 376, + 588, 376, 969, 376, 969, 589, 2090, 970, 665, 665, + + 665, 376, 2161, 358, 666, 2083, 376, 590, 768, 376, + 480, 701, 701, 701, 701, 701, 701, 481, 376, 470, + 471, 472, 473, 474, 474, 474, 474, 474, 474, 475, + 470, 471, 472, 473, 474, 474, 474, 474, 474, 474, + 475, 480, 482, 483, 886, 887, 1737, 2514, 481, 1744, + 2514, 470, 471, 472, 473, 474, 474, 474, 474, 474, + 474, 475, 470, 471, 472, 473, 474, 474, 474, 474, + 474, 474, 475, 482, 483, 886, 887, 484, 485, 666, + 470, 471, 472, 473, 474, 474, 474, 474, 474, 474, + 475, 2080, 702, 1873, 1874, 702, 888, 470, 471, 472, + + 473, 474, 474, 474, 474, 474, 474, 475, 484, 485, + 731, 731, 731, 2078, 889, 2073, 470, 471, 472, 473, + 474, 474, 474, 474, 474, 474, 475, 888, 731, 731, + 731, 2071, 470, 471, 472, 473, 474, 474, 474, 474, + 474, 474, 475, 2514, 2514, 889, 2514, 2150, 376, 2514, + 2514, 737, 737, 737, 486, 2514, 2514, 2145, 774, 469, + 486, 2514, 2514, 2058, 890, 469, 486, 2514, 2514, 2127, + 891, 469, 486, 737, 737, 737, 892, 469, 559, 358, + 358, 358, 893, 532, 910, 911, 469, 469, 469, 774, + 469, 732, 469, 469, 469, 890, 469, 2124, 469, 469, + + 469, 891, 469, 524, 469, 469, 469, 892, 469, 732, + 532, 532, 532, 893, 532, 910, 911, 469, 1765, 2514, + 2033, 918, 2514, 469, 376, 2514, 614, 614, 614, 469, + 2109, 615, 738, 616, 376, 469, 492, 492, 492, 617, + 921, 532, 2019, 769, 2077, 932, 2075, 494, 1979, 494, + 495, 2514, 918, 376, 738, 1972, 2514, 2514, 1962, 765, + 359, 496, 497, 376, 498, 376, 951, 559, 753, 753, + 753, 921, 532, 499, 769, 500, 932, 501, 952, 526, + 527, 528, 529, 530, 530, 530, 530, 530, 530, 531, + 765, 1798, 496, 497, 376, 498, 1914, 951, 1958, 532, + + 532, 532, 955, 532, 499, 722, 500, 618, 501, 952, + 2044, 956, 630, 630, 630, 940, 502, 503, 504, 505, + 506, 506, 506, 506, 506, 506, 507, 492, 492, 492, + 532, 957, 2514, 955, 958, 1798, 2514, 2041, 494, 1934, + 494, 495, 956, 620, 620, 620, 940, 621, 622, 754, + 518, 2022, 496, 497, 519, 498, 623, 959, 376, 1915, + 540, 1902, 957, 520, 499, 958, 500, 521, 501, 533, + 534, 535, 536, 537, 537, 537, 537, 537, 537, 538, + 2514, 518, 376, 496, 497, 519, 498, 1890, 959, 376, + 549, 767, 376, 631, 520, 499, 1880, 500, 521, 501, + + 1873, 2514, 620, 620, 620, 1867, 902, 502, 503, 504, + 505, 506, 506, 506, 506, 506, 506, 507, 2514, 2514, + 2514, 549, 767, 376, 624, 971, 1860, 971, 550, 2514, + 972, 2514, 495, 541, 542, 543, 544, 545, 545, 545, + 545, 545, 545, 546, 552, 1853, 1954, 1951, 533, 534, + 535, 536, 537, 537, 537, 537, 537, 537, 538, 550, + 641, 642, 643, 644, 645, 645, 645, 645, 645, 645, + 646, 2368, 553, 554, 555, 556, 557, 557, 557, 557, + 557, 557, 558, 624, 1937, 376, 533, 534, 535, 536, + 537, 537, 537, 537, 537, 537, 538, 1004, 502, 508, + + 504, 505, 506, 506, 506, 506, 506, 506, 507, 2514, + 2514, 2514, 1929, 1873, 2514, 2514, 376, 2514, 1971, 711, + 2514, 941, 2514, 2514, 1918, 522, 2514, 2514, 1004, 711, + 493, 942, 2514, 2514, 1630, 376, 726, 559, 1751, 2514, + 2514, 1845, 532, 559, 2514, 2369, 376, 376, 532, 995, + 654, 1842, 1588, 1814, 975, 640, 376, 493, 493, 493, + 711, 493, 942, 1809, 771, 772, 376, 726, 1801, 532, + 532, 532, 773, 532, 1005, 532, 532, 532, 376, 532, + 995, 1543, 640, 640, 640, 975, 640, 376, 493, 2514, + 2471, 376, 1769, 2514, 2514, 771, 772, 908, 908, 908, + + 532, 376, 805, 773, 654, 1005, 532, 632, 632, 640, + 1767, 632, 632, 640, 1511, 632, 632, 632, 632, 632, + 632, 632, 632, 632, 1758, 632, 632, 632, 632, 632, + 2514, 2514, 376, 805, 1488, 1478, 640, 640, 640, 1728, + 640, 654, 2514, 2514, 376, 376, 640, 658, 658, 658, + 1725, 990, 792, 376, 376, 376, 632, 632, 632, 1592, + 632, 607, 607, 607, 2472, 2514, 2514, 640, 894, 630, + 766, 1713, 1713, 640, 640, 640, 654, 640, 909, 1689, + 1009, 640, 990, 792, 376, 376, 376, 632, 634, 635, + 636, 637, 638, 638, 638, 638, 638, 638, 639, 649, + + 1674, 766, 650, 376, 640, 1017, 376, 977, 640, 640, + 640, 1009, 640, 676, 677, 678, 679, 680, 680, 680, + 680, 680, 680, 681, 1671, 614, 614, 614, 659, 1028, + 649, 1011, 898, 650, 376, 1640, 1017, 376, 977, 640, + 683, 1361, 611, 641, 642, 643, 644, 645, 645, 645, + 645, 645, 645, 646, 667, 667, 1356, 1346, 667, 667, + 1028, 1619, 667, 667, 667, 667, 667, 667, 667, 667, + 667, 683, 667, 667, 667, 667, 667, 944, 1138, 944, + 1138, 1612, 1137, 1139, 676, 677, 678, 679, 680, 680, + 680, 680, 680, 680, 681, 684, 919, 919, 919, 665, + + 665, 665, 1316, 667, 667, 667, 618, 667, 691, 692, + 693, 694, 695, 695, 695, 695, 695, 695, 696, 1603, + 685, 924, 924, 924, 1599, 1588, 684, 701, 701, 701, + 1295, 936, 936, 936, 667, 669, 670, 671, 672, 673, + 673, 673, 673, 673, 673, 674, 1575, 1033, 731, 731, + 731, 685, 1568, 676, 677, 678, 679, 680, 680, 680, + 680, 680, 680, 681, 676, 677, 678, 679, 680, 680, + 680, 680, 680, 680, 681, 2514, 2514, 920, 1033, 1041, + 666, 2514, 2514, 949, 949, 949, 686, 2514, 2514, 1549, + 1224, 675, 686, 2514, 2514, 1523, 1521, 675, 686, 2514, + + 1201, 376, 925, 675, 686, 2514, 758, 376, 702, 675, + 1041, 376, 937, 737, 737, 737, 759, 376, 675, 675, + 675, 779, 675, 1496, 675, 675, 675, 697, 675, 732, + 675, 675, 675, 1190, 675, 801, 675, 675, 675, 2514, + 675, 376, 376, 2514, 2514, 1465, 1460, 759, 376, 675, + 1452, 376, 779, 791, 698, 675, 1290, 665, 697, 690, + 1140, 675, 1140, 1290, 950, 1141, 801, 675, 691, 692, + 693, 694, 695, 695, 695, 695, 695, 695, 696, 376, + 2514, 2514, 376, 2514, 791, 376, 690, 690, 690, 1286, + 690, 698, 2514, 2514, 738, 376, 690, 1286, 2514, 2514, + + 376, 1282, 770, 698, 1032, 2514, 2514, 376, 690, 698, + 376, 1282, 1433, 976, 690, 981, 728, 690, 1428, 1426, + 2514, 711, 376, 690, 690, 690, 376, 690, 783, 1422, + 1420, 376, 376, 770, 1401, 690, 690, 690, 376, 690, + 376, 690, 690, 690, 976, 690, 981, 1034, 711, 711, + 711, 1313, 711, 1151, 690, 1146, 2514, 1141, 1141, 783, + 953, 953, 953, 376, 2514, 2514, 690, 965, 753, 753, + 1139, 376, 690, 703, 703, 728, 1139, 703, 703, 711, + 711, 703, 703, 703, 703, 703, 703, 703, 703, 703, + 493, 703, 703, 703, 703, 703, 712, 713, 714, 715, + + 716, 716, 716, 716, 716, 716, 717, 711, 711, 711, + 360, 711, 1137, 1134, 376, 1307, 1082, 704, 978, 1071, + 1124, 493, 703, 703, 703, 2514, 703, 376, 2514, 2514, + 668, 2514, 1119, 376, 1293, 2514, 2514, 376, 711, 728, + 701, 954, 1108, 376, 711, 376, 728, 1082, 966, 978, + 780, 711, 793, 703, 705, 706, 707, 708, 709, 709, + 709, 709, 709, 709, 710, 723, 979, 724, 376, 633, + 376, 711, 711, 711, 376, 711, 1083, 725, 711, 711, + 711, 780, 711, 793, 1104, 1102, 362, 363, 364, 365, + 366, 366, 366, 366, 366, 366, 367, 979, 2514, 2514, + + 2514, 376, 711, 1100, 2514, 2514, 2514, 1083, 725, 711, + 746, 2514, 2514, 2514, 376, 361, 746, 1275, 551, 539, + 376, 361, 997, 746, 525, 1243, 456, 980, 361, 972, + 972, 712, 713, 714, 715, 716, 716, 716, 716, 716, + 716, 717, 361, 361, 361, 376, 361, 970, 361, 361, + 361, 376, 361, 997, 970, 361, 361, 361, 980, 361, + 2514, 2514, 2514, 968, 2514, 965, 376, 1158, 383, 2514, + 2514, 376, 746, 361, 369, 361, 810, 361, 986, 361, + 464, 2514, 953, 949, 376, 376, 361, 377, 378, 379, + 380, 381, 381, 381, 381, 381, 381, 382, 384, 2514, + + 999, 376, 376, 711, 361, 361, 361, 810, 361, 986, + 1137, 781, 376, 376, 376, 376, 376, 2514, 2514, 936, + 1132, 690, 782, 2514, 2514, 675, 924, 919, 464, 640, + 908, 999, 904, 376, 464, 361, 368, 368, 1084, 376, + 368, 368, 781, 376, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 782, 368, 368, 368, 368, 368, 904, + 376, 376, 376, 993, 376, 376, 376, 376, 376, 1084, + 376, 385, 386, 387, 388, 389, 389, 389, 389, 389, + 389, 390, 376, 493, 1012, 368, 368, 368, 2514, 368, + 376, 376, 900, 2514, 993, 900, 376, 376, 896, 807, + + 376, 844, 844, 844, 844, 844, 844, 844, 844, 844, + 844, 844, 1075, 376, 493, 1012, 368, 370, 371, 372, + 373, 374, 374, 374, 374, 374, 374, 375, 368, 368, + 807, 376, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 748, 368, 368, 368, 368, + 368, 368, 896, 1089, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 748, 368, 368, + 368, 368, 2514, 2514, 376, 2514, 1019, 376, 2514, 2514, + 2514, 1085, 532, 464, 2514, 2514, 2514, 376, 376, 750, + 493, 469, 1057, 376, 383, 750, 968, 2514, 2514, 2514, + + 383, 753, 963, 737, 789, 376, 731, 1019, 750, 722, + 935, 728, 2514, 383, 376, 376, 376, 376, 376, 376, + 1086, 383, 383, 383, 376, 383, 728, 383, 383, 383, + 933, 383, 2514, 2514, 2514, 789, 368, 368, 798, 368, + 383, 383, 383, 750, 383, 2514, 376, 376, 383, 703, + 1087, 1086, 383, 701, 2514, 376, 376, 376, 383, 698, + 2514, 2514, 803, 376, 763, 698, 376, 376, 2514, 798, + 376, 383, 764, 376, 686, 383, 383, 383, 686, 383, + 840, 1087, 2514, 1013, 376, 922, 784, 667, 376, 785, + 775, 665, 776, 803, 376, 763, 376, 376, 376, 1088, + + 2514, 777, 376, 764, 376, 982, 383, 397, 778, 760, + 983, 840, 376, 658, 1013, 654, 2514, 784, 376, 399, + 785, 775, 786, 776, 787, 376, 654, 376, 376, 985, + 1088, 988, 777, 376, 906, 989, 982, 1090, 788, 778, + 632, 983, 2514, 376, 376, 2514, 2514, 376, 376, 630, + 399, 620, 905, 786, 376, 787, 794, 376, 376, 376, + 985, 790, 988, 376, 376, 797, 989, 904, 1090, 788, + 987, 795, 796, 377, 378, 379, 380, 381, 381, 381, + 381, 381, 381, 382, 614, 376, 901, 794, 376, 376, + 900, 607, 790, 2514, 376, 376, 797, 2514, 2514, 376, + + 376, 987, 795, 796, 2514, 376, 376, 897, 896, 376, + 376, 799, 2514, 800, 376, 804, 376, 2514, 2514, 376, + 376, 376, 802, 806, 376, 1024, 376, 376, 873, 376, + 376, 1000, 991, 2514, 873, 376, 376, 808, 809, 376, + 376, 376, 799, 811, 800, 812, 804, 376, 984, 813, + 869, 1091, 376, 802, 806, 376, 1024, 376, 376, 376, + 376, 376, 1000, 991, 869, 2514, 994, 376, 808, 809, + 376, 559, 559, 2514, 811, 376, 812, 376, 867, 984, + 813, 2514, 1091, 376, 376, 376, 2514, 825, 376, 814, + 376, 376, 820, 376, 815, 1001, 376, 994, 376, 1002, + + 996, 821, 816, 822, 817, 823, 867, 818, 376, 2514, + 819, 376, 376, 824, 2514, 376, 376, 826, 825, 1007, + 814, 376, 376, 820, 376, 815, 1001, 376, 522, 376, + 1002, 996, 821, 816, 822, 817, 823, 2514, 818, 376, + 522, 819, 492, 376, 824, 827, 376, 845, 826, 376, + 1007, 2514, 376, 376, 2514, 998, 376, 2514, 376, 376, + 828, 376, 2514, 376, 376, 830, 376, 1092, 992, 376, + 2514, 2514, 376, 376, 376, 1015, 827, 376, 832, 829, + 376, 833, 376, 835, 834, 831, 998, 836, 486, 376, + 486, 828, 376, 376, 376, 842, 830, 376, 1092, 992, + + 376, 842, 1069, 1003, 376, 376, 1015, 493, 1010, 832, + 829, 395, 833, 376, 835, 834, 831, 2514, 836, 376, + 2514, 2514, 376, 376, 376, 2514, 376, 376, 2514, 376, + 376, 376, 376, 376, 1003, 376, 837, 376, 493, 1010, + 376, 1006, 838, 752, 1093, 839, 1016, 750, 841, 750, + 2514, 2514, 457, 464, 2514, 2514, 464, 376, 2514, 2514, + 376, 842, 376, 376, 376, 842, 456, 837, 376, 842, + 456, 376, 1006, 838, 456, 1093, 839, 1016, 376, 841, + 458, 459, 460, 461, 462, 462, 462, 462, 462, 462, + 463, 748, 368, 456, 456, 456, 1036, 456, 456, 456, + + 746, 456, 456, 456, 2514, 2514, 746, 2514, 2514, 376, + 723, 358, 938, 737, 740, 842, 731, 734, 486, 2514, + 456, 711, 939, 469, 456, 728, 722, 1036, 456, 718, + 2514, 711, 456, 470, 471, 472, 473, 474, 474, 474, + 474, 474, 474, 475, 2514, 2514, 376, 456, 456, 456, + 469, 469, 469, 939, 469, 486, 2514, 2514, 698, 1022, + 469, 698, 711, 2514, 2514, 686, 682, 486, 944, 658, + 944, 2514, 469, 945, 486, 846, 661, 376, 456, 469, + 2514, 469, 711, 711, 376, 376, 376, 469, 469, 469, + 1022, 469, 711, 397, 1029, 967, 848, 1014, 1025, 469, + + 469, 469, 946, 469, 1094, 756, 469, 469, 469, 654, + 469, 648, 647, 629, 711, 376, 376, 376, 469, 847, + 2514, 627, 605, 711, 602, 1029, 601, 848, 1014, 1025, + 469, 849, 598, 946, 597, 1094, 756, 469, 593, 470, + 471, 472, 473, 474, 474, 474, 474, 474, 474, 475, + 847, 470, 471, 472, 473, 474, 474, 474, 474, 474, + 474, 475, 849, 470, 471, 472, 473, 474, 474, 474, + 474, 474, 474, 475, 850, 851, 376, 1023, 1021, 376, + 1026, 493, 376, 376, 376, 470, 471, 472, 473, 474, + 474, 474, 474, 474, 474, 475, 852, 1008, 1018, 1067, + + 1095, 1100, 1100, 1100, 579, 850, 851, 376, 1023, 1021, + 376, 1026, 493, 376, 376, 376, 470, 471, 472, 473, + 474, 474, 474, 474, 474, 474, 475, 852, 1008, 1018, + 1067, 1095, 470, 471, 472, 473, 474, 474, 474, 474, + 474, 474, 475, 853, 853, 853, 853, 853, 853, 853, + 853, 853, 853, 853, 470, 471, 472, 473, 474, 474, + 474, 474, 474, 474, 475, 470, 471, 472, 473, 474, + 474, 474, 474, 474, 474, 475, 492, 492, 492, 1096, + 580, 577, 1101, 576, 573, 572, 559, 494, 559, 494, + 495, 522, 522, 492, 486, 2514, 2514, 2514, 376, 376, + + 376, 496, 497, 376, 498, 1027, 524, 867, 478, 464, + 1096, 1020, 525, 499, 1031, 500, 1048, 501, 866, 866, + 866, 866, 866, 866, 866, 866, 866, 866, 866, 376, + 376, 376, 496, 497, 376, 498, 1027, 396, 395, 525, + 525, 525, 1020, 525, 499, 1031, 500, 1048, 501, 540, + 391, 2514, 245, 1102, 1102, 1102, 502, 503, 504, 505, + 506, 506, 506, 506, 506, 506, 507, 2514, 2514, 2514, + 525, 245, 1047, 376, 243, 1097, 376, 1051, 2514, 243, + 2514, 495, 526, 527, 528, 529, 530, 530, 530, 530, + 530, 530, 531, 2514, 2514, 2514, 2514, 2514, 2514, 1104, + + 1104, 1104, 376, 1047, 376, 867, 1097, 376, 1051, 1030, + 525, 533, 534, 535, 536, 537, 537, 537, 537, 537, + 537, 538, 541, 542, 543, 544, 545, 545, 545, 545, + 545, 545, 546, 376, 1103, 2514, 2514, 525, 525, 525, + 1030, 525, 1098, 2514, 2514, 2514, 2514, 502, 508, 504, + 505, 506, 506, 506, 506, 506, 506, 507, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 1034, 1034, 1034, 525, 2514, + 2514, 2514, 2514, 1098, 522, 2514, 2514, 2514, 493, 493, + 1105, 2514, 2514, 2514, 1073, 2514, 376, 867, 2514, 2514, + 2514, 376, 525, 867, 2514, 2514, 2514, 1037, 525, 559, + + 2514, 2514, 2514, 2514, 532, 1099, 493, 493, 493, 493, + 493, 559, 2514, 2514, 2514, 1073, 532, 376, 2514, 525, + 525, 525, 376, 525, 376, 525, 525, 525, 1037, 525, + 2514, 532, 532, 532, 376, 532, 1099, 493, 2514, 2514, + 1050, 1040, 1110, 532, 532, 532, 1035, 532, 2514, 559, + 525, 2514, 2514, 2514, 532, 376, 525, 2514, 376, 2514, + 2514, 2514, 532, 559, 2514, 376, 2514, 1044, 532, 1111, + 869, 1050, 1040, 1110, 532, 539, 2514, 2514, 2514, 2514, + 2514, 532, 532, 532, 2514, 532, 2514, 2514, 869, 376, + 2514, 2514, 493, 539, 2514, 532, 532, 532, 1044, 532, + + 1111, 2514, 539, 539, 539, 2514, 539, 711, 1042, 376, + 376, 1070, 532, 1117, 2514, 2514, 2514, 711, 1049, 1043, + 539, 539, 539, 493, 539, 869, 532, 2514, 2514, 2514, + 539, 947, 872, 539, 871, 493, 493, 1076, 869, 1042, + 376, 376, 1070, 539, 1117, 2514, 2514, 2514, 711, 1049, + 1043, 539, 2514, 2514, 2514, 2514, 1068, 539, 539, 539, + 2514, 539, 947, 872, 2514, 871, 493, 493, 1076, 1121, + 539, 539, 539, 2514, 539, 533, 534, 535, 536, 537, + 537, 537, 537, 537, 537, 538, 552, 1068, 539, 533, + 534, 535, 536, 537, 537, 537, 537, 537, 537, 538, + + 1121, 539, 875, 875, 875, 875, 875, 875, 875, 875, + 875, 875, 875, 2514, 553, 554, 555, 556, 557, 557, + 557, 557, 557, 557, 558, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 1130, 2514, 2514, 873, 2514, 2514, 873, + 2514, 551, 873, 2514, 551, 873, 2514, 551, 2514, 2514, + 551, 533, 534, 535, 536, 537, 537, 537, 537, 537, + 537, 538, 1148, 376, 1130, 2514, 1055, 1149, 551, 551, + 551, 551, 551, 551, 551, 551, 551, 551, 551, 551, + 641, 642, 643, 644, 645, 645, 645, 645, 645, 645, + 646, 2514, 2514, 1148, 376, 2514, 2514, 1055, 1149, 551, + + 2514, 2514, 551, 913, 2514, 551, 654, 2514, 551, 632, + 632, 640, 1153, 632, 632, 2514, 2514, 632, 632, 632, + 632, 632, 632, 632, 632, 632, 2514, 632, 632, 632, + 632, 632, 912, 1154, 913, 2514, 2514, 2514, 640, 640, + 640, 2514, 640, 1153, 1108, 908, 908, 641, 642, 643, + 644, 645, 645, 645, 645, 645, 645, 646, 632, 632, + 632, 2514, 632, 912, 1154, 2514, 1119, 919, 919, 640, + 641, 642, 643, 644, 645, 645, 645, 645, 645, 645, + 646, 2514, 1124, 924, 924, 2514, 2514, 2514, 2514, 632, + 634, 635, 636, 637, 638, 638, 638, 638, 638, 638, + + 639, 632, 632, 2514, 2514, 632, 632, 632, 632, 632, + 632, 632, 632, 632, 632, 632, 632, 632, 906, 632, + 632, 632, 632, 632, 632, 1109, 2514, 632, 632, 632, + 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, + 906, 632, 632, 632, 632, 2514, 2514, 1120, 1134, 936, + 936, 2514, 2514, 2514, 1155, 493, 654, 2514, 2514, 2514, + 2514, 640, 654, 1125, 2514, 2514, 1072, 640, 654, 2514, + 2514, 2514, 2514, 640, 917, 917, 917, 917, 917, 917, + 917, 917, 917, 917, 917, 1155, 493, 2514, 640, 640, + 640, 914, 640, 941, 640, 640, 640, 1072, 640, 1156, + + 640, 640, 640, 942, 640, 2514, 2514, 2514, 2514, 632, + 632, 2514, 632, 2514, 2514, 915, 2514, 1157, 686, 640, + 2514, 2514, 914, 675, 2514, 640, 2514, 2514, 2514, 1135, + 1156, 640, 2514, 2514, 942, 641, 642, 643, 644, 645, + 645, 645, 645, 645, 645, 646, 915, 916, 1157, 1166, + 675, 675, 675, 2514, 675, 641, 642, 643, 644, 645, + 645, 645, 645, 645, 645, 646, 641, 642, 643, 644, + 645, 645, 645, 645, 645, 645, 646, 2514, 916, 2514, + 1166, 675, 2514, 641, 642, 643, 644, 645, 645, 645, + 645, 645, 645, 646, 667, 667, 2514, 2514, 667, 667, + + 2514, 2514, 667, 667, 667, 667, 667, 667, 667, 667, + 667, 926, 667, 667, 667, 667, 667, 676, 677, 678, + 679, 680, 680, 680, 680, 680, 680, 681, 929, 929, + 929, 929, 929, 929, 929, 929, 929, 929, 929, 2514, + 376, 1177, 926, 667, 667, 667, 2514, 667, 2514, 676, + 677, 678, 679, 680, 680, 680, 680, 680, 680, 681, + 676, 677, 678, 679, 680, 680, 680, 680, 680, 680, + 681, 376, 1177, 2514, 667, 669, 670, 671, 672, 673, + 673, 673, 673, 673, 673, 674, 667, 667, 2514, 2514, 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, - 667, 667, 667, 667, 667, 667, 674, 674, 2326, 2326, - 2326, 2326, 674, 2326, 2326, 2326, 2326, 674, 674, 674, - 674, 686, 2326, 686, 686, 686, 686, 686, 686, 689, - 689, 2326, 2326, 2326, 2326, 689, 2326, 2326, 2326, 2326, - 689, 689, 689, 689, 698, 2326, 698, 698, 698, 698, - 703, 703, 2326, 703, 703, 703, 703, 703, 703, 703, - - 703, 703, 703, 703, 703, 703, 703, 703, 703, 710, - 710, 2326, 2326, 2326, 2326, 710, 2326, 2326, 2326, 2326, - 710, 710, 710, 710, 728, 2326, 728, 728, 728, 728, - 2326, 2326, 728, 732, 732, 2326, 732, 732, 732, 732, - 732, 732, 732, 732, 732, 732, 732, 732, 732, 732, - 732, 732, 738, 738, 2326, 738, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, - 738, 362, 362, 362, 2326, 2326, 2326, 2326, 362, 2326, - 2326, 2326, 2326, 362, 362, 362, 362, 746, 2326, 746, - 746, 746, 746, 369, 369, 2326, 369, 369, 369, 369, + + 667, 667, 667, 922, 667, 667, 667, 667, 667, 667, + 2514, 2514, 667, 667, 667, 667, 667, 667, 667, 667, + 667, 667, 667, 667, 667, 922, 667, 667, 667, 667, + 2514, 2514, 2514, 723, 2514, 1136, 2514, 2514, 2514, 2514, + 2514, 686, 2514, 2514, 2514, 939, 675, 686, 2514, 2514, + 2514, 2514, 675, 686, 2514, 2514, 2514, 376, 675, 691, + 692, 693, 694, 695, 695, 695, 695, 695, 695, 696, + 1038, 1169, 1039, 675, 675, 675, 939, 675, 927, 675, + 675, 675, 711, 675, 376, 675, 675, 675, 376, 675, + 1146, 949, 949, 2514, 667, 667, 2514, 667, 928, 1144, + + 2514, 1038, 1169, 1039, 675, 2514, 2514, 2514, 2514, 927, + 675, 2514, 2514, 711, 2514, 376, 675, 2514, 676, 677, + 678, 679, 680, 680, 680, 680, 680, 680, 681, 928, + 1144, 1151, 953, 953, 676, 677, 678, 679, 680, 680, + 680, 680, 680, 680, 681, 2514, 2514, 2514, 965, 753, + 753, 2514, 2514, 2514, 1173, 376, 698, 2514, 2514, 2514, + 376, 690, 698, 2514, 2514, 2514, 2514, 690, 698, 2514, + 2514, 1147, 376, 690, 698, 2514, 2514, 2514, 376, 690, + 493, 397, 1045, 1159, 1046, 1173, 376, 1052, 690, 690, + 690, 376, 690, 756, 690, 690, 690, 930, 690, 1074, + + 690, 690, 690, 376, 690, 1178, 690, 690, 690, 376, + 690, 493, 1152, 1045, 2514, 1046, 2514, 2514, 1052, 690, + 2514, 2514, 2514, 2514, 756, 690, 2514, 2514, 930, 966, + 1074, 690, 2514, 2514, 2514, 2514, 1178, 690, 2514, 2514, + 2514, 691, 692, 693, 694, 695, 695, 695, 695, 695, + 695, 696, 931, 931, 931, 931, 931, 931, 931, 931, + 931, 931, 931, 691, 692, 693, 694, 695, 695, 695, + 695, 695, 695, 696, 703, 703, 2514, 2514, 703, 703, + 2514, 2514, 703, 703, 703, 703, 703, 703, 703, 703, + 703, 2514, 703, 703, 703, 703, 703, 712, 713, 714, + + 715, 716, 716, 716, 716, 716, 716, 717, 948, 948, + 948, 948, 948, 948, 948, 948, 948, 948, 948, 376, + 376, 1164, 1171, 703, 703, 703, 2514, 703, 960, 960, + 960, 960, 960, 960, 960, 960, 960, 960, 960, 961, + 961, 961, 961, 961, 961, 961, 961, 961, 961, 961, + 376, 376, 1164, 1171, 703, 705, 706, 707, 708, 709, + 709, 709, 709, 709, 709, 710, 703, 703, 2514, 2514, + 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, + 703, 703, 703, 933, 703, 703, 703, 703, 703, 703, + 2514, 2514, 703, 703, 703, 703, 703, 703, 703, 703, + + 703, 703, 703, 703, 703, 933, 703, 703, 703, 703, + 2514, 2514, 376, 376, 1165, 2514, 2514, 2514, 376, 1162, + 2514, 728, 2514, 2514, 2514, 1174, 711, 728, 2514, 2514, + 2514, 2514, 711, 728, 2514, 2514, 2514, 376, 711, 1172, + 376, 1187, 376, 376, 376, 1165, 728, 360, 2514, 376, + 1162, 711, 2514, 711, 711, 711, 1174, 711, 2514, 711, + 711, 711, 384, 711, 376, 711, 711, 711, 376, 711, + 1172, 376, 1187, 376, 703, 703, 1186, 703, 711, 711, + 711, 2514, 711, 376, 711, 1176, 2514, 1189, 2514, 2514, + 711, 762, 2514, 2514, 2514, 376, 711, 962, 962, 962, + + 962, 962, 962, 962, 962, 962, 962, 962, 2514, 711, + 723, 2514, 943, 2514, 376, 2514, 1176, 376, 1189, 376, + 1179, 1183, 725, 362, 363, 364, 365, 366, 366, 366, + 366, 366, 366, 367, 2514, 385, 386, 387, 388, 389, + 389, 389, 389, 389, 389, 390, 2514, 2514, 376, 2514, + 376, 1179, 1183, 725, 2514, 377, 378, 379, 380, 381, + 381, 381, 381, 381, 381, 382, 1281, 1100, 1100, 1108, + 908, 908, 2514, 1282, 2514, 2514, 712, 713, 714, 715, + 716, 716, 716, 716, 716, 716, 717, 368, 368, 2514, + 2514, 368, 368, 2514, 2514, 368, 368, 368, 368, 368, + + 368, 368, 368, 368, 376, 368, 368, 368, 368, 368, + 2514, 1175, 377, 378, 379, 380, 381, 381, 381, 381, + 381, 381, 382, 1056, 1056, 1056, 1056, 1056, 1056, 1056, + 1056, 1056, 1056, 1056, 1180, 376, 368, 368, 368, 2514, + 368, 1058, 1175, 2514, 2514, 2514, 2514, 1283, 2514, 376, + 1109, 376, 1163, 1184, 376, 376, 376, 376, 1053, 2514, + 2514, 376, 1054, 2514, 2514, 1180, 457, 368, 370, 371, + 372, 373, 374, 374, 374, 374, 374, 374, 375, 397, + 376, 973, 376, 1163, 1184, 376, 376, 376, 376, 1053, + 1059, 399, 376, 1054, 458, 459, 460, 461, 462, 462, + + 462, 462, 462, 462, 463, 470, 471, 472, 473, 474, + 474, 474, 474, 474, 474, 475, 2514, 2514, 2514, 2514, + 2514, 1059, 399, 470, 471, 472, 473, 474, 474, 474, + 474, 474, 474, 475, 1060, 1061, 1185, 2514, 376, 376, + 376, 1193, 1199, 376, 1188, 377, 378, 379, 380, 381, + 381, 381, 381, 381, 381, 382, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 1060, 1061, 1185, 974, 376, + 376, 376, 1193, 1199, 376, 1188, 470, 471, 472, 473, + 474, 474, 474, 474, 474, 474, 475, 1062, 470, 471, + 472, 473, 474, 474, 474, 474, 474, 474, 475, 974, + + 2514, 2514, 2514, 376, 1194, 1197, 376, 376, 376, 1063, + 1228, 2514, 2514, 2514, 2514, 1192, 2514, 524, 1062, 2514, + 2514, 2514, 377, 378, 379, 380, 381, 381, 381, 381, + 381, 381, 382, 1064, 376, 1194, 1197, 376, 376, 376, + 1063, 1228, 470, 471, 472, 473, 474, 474, 474, 474, + 474, 474, 475, 470, 471, 472, 473, 474, 474, 474, + 474, 474, 474, 475, 1064, 1077, 1077, 1077, 1077, 1077, + 1077, 1077, 1077, 1077, 1077, 1077, 2514, 2514, 2514, 2514, + 2514, 470, 471, 472, 473, 474, 474, 474, 474, 474, + 474, 475, 495, 526, 527, 528, 529, 530, 530, 530, + + 530, 530, 530, 531, 1078, 1078, 1078, 1078, 1078, 1078, + 1078, 1078, 1078, 1078, 1078, 1065, 540, 1081, 1081, 1081, + 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1106, 1106, + 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1079, + 2514, 376, 376, 1210, 376, 1226, 1065, 1122, 1122, 1122, + 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 502, 508, + 504, 505, 506, 506, 506, 506, 506, 506, 507, 495, + 1079, 1080, 376, 376, 1210, 376, 1226, 1066, 533, 534, + 535, 536, 537, 537, 537, 537, 537, 537, 538, 541, + 542, 543, 544, 545, 545, 545, 545, 545, 545, 546, + + 376, 1112, 1080, 1235, 2514, 2514, 2514, 2514, 1066, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 533, 534, + 535, 536, 537, 537, 537, 537, 537, 537, 538, 552, + 2514, 376, 1112, 2514, 1235, 502, 508, 504, 505, 506, + 506, 506, 506, 506, 506, 507, 641, 642, 643, 644, + 645, 645, 645, 645, 645, 645, 646, 553, 554, 555, + 556, 557, 557, 557, 557, 557, 557, 558, 632, 632, + 1116, 2514, 632, 632, 2514, 2514, 632, 632, 632, 632, + 632, 632, 632, 632, 632, 1113, 632, 632, 632, 632, + 632, 376, 1208, 1227, 376, 1232, 1203, 376, 1182, 641, + + 642, 643, 644, 645, 645, 645, 645, 645, 645, 646, + 2514, 1114, 376, 376, 1212, 376, 1113, 632, 632, 632, + 2514, 632, 376, 1208, 1227, 376, 1232, 1203, 376, 1182, + 376, 641, 642, 643, 644, 645, 645, 645, 645, 645, + 645, 646, 1114, 376, 376, 1212, 376, 2514, 632, 634, + 635, 636, 637, 638, 638, 638, 638, 638, 638, 639, + 1115, 376, 1234, 493, 1252, 2514, 376, 1263, 641, 642, + 643, 644, 645, 645, 645, 645, 645, 645, 646, 1131, + 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + 2514, 1115, 2514, 1234, 493, 1252, 1126, 376, 1263, 641, + + 642, 643, 644, 645, 645, 645, 645, 645, 645, 646, + 667, 667, 2514, 2514, 667, 667, 2514, 2514, 667, 667, + 667, 667, 667, 667, 667, 667, 667, 1126, 667, 667, + 667, 667, 667, 1127, 376, 1264, 1236, 2514, 1209, 2514, + 1195, 676, 677, 678, 679, 680, 680, 680, 680, 680, + 680, 681, 2514, 376, 1253, 376, 1265, 493, 1266, 667, + 667, 667, 2514, 667, 1127, 376, 1264, 1236, 2514, 1209, + 945, 1195, 676, 677, 678, 679, 680, 680, 680, 680, + 680, 680, 681, 1128, 376, 1253, 376, 1265, 493, 1266, + 667, 669, 670, 671, 672, 673, 673, 673, 673, 673, + + 673, 674, 1129, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 676, 677, 678, 679, 680, 680, 680, 680, + 680, 680, 681, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 1267, 1268, 2514, 1129, 712, 713, 714, 715, 716, 716, + 716, 716, 716, 716, 717, 2514, 2514, 2514, 691, 692, + 693, 694, 695, 695, 695, 695, 695, 695, 696, 703, + 703, 1267, 1268, 703, 703, 1269, 2514, 703, 703, 703, + 703, 703, 703, 703, 703, 703, 1170, 703, 703, 703, + 703, 703, 1167, 1181, 1196, 376, 1168, 1198, 1190, 1190, + 1190, 2514, 1200, 376, 1213, 376, 1269, 376, 376, 1206, + + 376, 376, 1270, 376, 1205, 1271, 376, 1170, 703, 703, + 703, 2514, 703, 1167, 1181, 1196, 376, 1168, 1198, 2514, + 1201, 1201, 1201, 1200, 376, 1213, 376, 376, 376, 376, + 1206, 376, 376, 1270, 376, 1205, 1271, 376, 2514, 703, + 705, 706, 707, 708, 709, 709, 709, 709, 709, 709, + 710, 723, 1204, 1142, 1207, 1211, 1214, 1215, 376, 376, + 1229, 1230, 376, 725, 1255, 376, 1233, 376, 2514, 1191, + 2514, 376, 376, 376, 493, 1224, 1224, 1224, 376, 2514, + 1272, 376, 1273, 1204, 2514, 1207, 1211, 1214, 1215, 2514, + 376, 1229, 1230, 376, 725, 1255, 376, 1233, 376, 2514, + + 2514, 1202, 376, 376, 376, 493, 2514, 2514, 2514, 376, + 464, 1272, 376, 1273, 376, 376, 1231, 712, 713, 714, + 715, 716, 716, 716, 716, 716, 716, 717, 2514, 376, + 1238, 1237, 2514, 1240, 1274, 1276, 1239, 1143, 1242, 1256, + 1257, 376, 376, 376, 376, 376, 376, 1231, 376, 376, + 376, 376, 493, 493, 493, 1244, 1225, 1277, 1278, 1279, + 376, 1238, 1237, 1254, 1240, 1274, 1276, 1239, 1143, 1242, + 1256, 1257, 376, 376, 2514, 1034, 2514, 1245, 1241, 376, + 376, 376, 376, 493, 493, 493, 2514, 376, 1277, 1278, + 1279, 2514, 2514, 2514, 712, 713, 714, 715, 716, 716, + + 716, 716, 716, 716, 717, 397, 2514, 1160, 1245, 1241, + 2514, 1289, 1104, 1104, 1246, 1290, 1260, 399, 376, 470, + 471, 472, 473, 474, 474, 474, 474, 474, 474, 475, + 493, 470, 471, 472, 473, 474, 474, 474, 474, 474, + 474, 475, 2514, 2514, 2514, 1246, 2514, 1260, 399, 470, + 471, 472, 473, 474, 474, 474, 474, 474, 474, 475, + 1247, 493, 1285, 1102, 1102, 1119, 919, 919, 2514, 1286, + 2514, 377, 378, 379, 380, 381, 381, 381, 381, 381, + 381, 382, 2514, 1248, 2514, 2514, 1124, 924, 924, 2514, + 2514, 1247, 1291, 2514, 470, 471, 472, 473, 474, 474, + + 474, 474, 474, 474, 475, 2514, 1292, 1161, 2514, 1302, + 2514, 1303, 470, 471, 472, 473, 474, 474, 474, 474, + 474, 474, 475, 470, 471, 472, 473, 474, 474, 474, + 474, 474, 474, 475, 1258, 1259, 495, 1292, 1161, 1250, + 1302, 493, 1303, 1287, 2514, 493, 1120, 2514, 377, 378, + 379, 380, 381, 381, 381, 381, 381, 381, 382, 1034, + 1034, 1034, 711, 2514, 2514, 1258, 1259, 1125, 1312, 2514, + 1311, 2514, 493, 2514, 2514, 2514, 493, 1368, 640, 2514, + 1216, 2514, 1370, 1217, 1218, 1371, 2514, 1372, 1373, 1134, + 936, 936, 1369, 711, 1219, 1220, 1221, 1249, 2514, 1312, + + 1222, 1311, 502, 508, 504, 505, 506, 506, 506, 506, + 506, 506, 507, 1370, 1217, 1218, 1371, 2514, 1372, 1373, + 2514, 2514, 2514, 1369, 1300, 1219, 1220, 1221, 1249, 1261, + 2514, 1222, 1146, 949, 949, 1151, 953, 953, 1262, 2514, + 1223, 1374, 470, 471, 472, 473, 474, 474, 474, 474, + 474, 474, 475, 495, 642, 2514, 2514, 2514, 533, 534, + 535, 536, 537, 537, 537, 537, 537, 537, 538, 1262, + 1135, 2514, 1374, 1375, 2514, 1294, 2514, 1418, 1419, 1251, + 691, 692, 693, 694, 695, 695, 695, 695, 695, 695, + 696, 2514, 533, 534, 535, 536, 537, 537, 537, 537, + + 537, 537, 538, 2514, 1375, 723, 1294, 1308, 1418, 1419, + 1251, 2514, 2514, 1147, 1421, 2514, 1152, 939, 1423, 502, + 508, 504, 505, 506, 506, 506, 506, 506, 506, 507, + 641, 642, 643, 644, 645, 645, 645, 645, 645, 645, + 646, 1295, 1295, 1295, 2514, 1421, 1296, 2514, 939, 1423, + 2514, 2514, 2514, 2514, 1297, 1424, 640, 2514, 2514, 2514, + 1305, 2514, 640, 397, 2514, 1314, 2514, 2514, 2514, 2514, + 2514, 2514, 493, 1299, 1410, 756, 2514, 2514, 2514, 493, + 493, 1301, 1425, 1411, 1304, 2514, 1424, 2514, 493, 676, + 677, 678, 679, 680, 680, 680, 680, 680, 680, 681, + + 1409, 1412, 1306, 493, 1299, 1410, 756, 2514, 2514, 2514, + 493, 493, 1301, 1425, 1411, 1304, 2514, 2514, 2514, 493, + 2514, 641, 1298, 643, 644, 645, 645, 645, 645, 645, + 645, 646, 642, 1306, 2514, 2514, 2514, 2514, 642, 676, + 677, 678, 679, 680, 680, 680, 680, 680, 680, 681, + 2514, 2514, 2514, 2514, 1318, 1427, 1429, 378, 676, 677, + 678, 679, 680, 680, 680, 680, 680, 680, 681, 723, + 2514, 1309, 2514, 1319, 1415, 2514, 2514, 2514, 2514, 493, + 1320, 725, 2514, 2514, 2514, 1318, 1427, 1429, 378, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 378, 2514, 2514, + + 2514, 2514, 2514, 2514, 1319, 1415, 2514, 2514, 2514, 2514, + 493, 1320, 725, 2514, 2514, 378, 1322, 1321, 1323, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 1430, 1325, 1431, 1324, + 2514, 378, 2514, 1328, 2514, 712, 713, 714, 715, 716, + 716, 716, 716, 716, 716, 717, 2514, 1322, 1321, 1323, + 2514, 2514, 2514, 493, 1310, 1326, 378, 1430, 1325, 1431, + 1324, 1327, 1432, 378, 1328, 2514, 2514, 2514, 2514, 2514, + 378, 2514, 2514, 2514, 1416, 378, 1329, 1434, 1435, 378, + 2514, 2514, 378, 2514, 493, 1310, 1326, 2514, 378, 2514, + 2514, 2514, 1327, 1432, 2514, 1330, 2514, 2514, 2514, 2514, + + 378, 2514, 2514, 378, 2514, 2514, 2514, 1329, 1434, 1435, + 2514, 1331, 712, 713, 714, 715, 716, 716, 716, 716, + 716, 716, 717, 397, 2514, 1315, 1330, 1333, 1456, 1491, + 1332, 378, 2514, 2514, 2514, 399, 2514, 2514, 2514, 2514, + 2514, 2514, 1331, 2514, 2514, 2514, 378, 2514, 2514, 2514, + 2514, 2514, 378, 1492, 2514, 1334, 2514, 2514, 1333, 1456, + 1491, 1332, 2514, 2514, 2514, 2514, 399, 2514, 2514, 2514, + 378, 2514, 2514, 2514, 2514, 1337, 1338, 1500, 378, 2514, + 2514, 2514, 2514, 2514, 1492, 378, 1334, 1335, 1339, 377, + 378, 379, 380, 381, 381, 381, 381, 381, 381, 382, + + 1316, 1316, 1316, 2514, 2514, 2514, 1337, 1338, 1500, 711, + 1190, 1190, 1190, 378, 2514, 2514, 2514, 378, 1336, 1339, + 378, 1340, 2514, 1464, 378, 2514, 2514, 2514, 378, 2514, + 2514, 2514, 2514, 2514, 2514, 1346, 1346, 1346, 1341, 2514, + 711, 464, 2514, 378, 2514, 1517, 376, 1342, 378, 2514, + 1347, 2514, 1340, 378, 1464, 2514, 2514, 2514, 2514, 2514, + 2514, 378, 1344, 2514, 2514, 2514, 2514, 2514, 2514, 1341, + 2514, 2514, 2514, 376, 376, 376, 1517, 376, 1342, 1518, + 377, 1317, 379, 380, 381, 381, 381, 381, 381, 381, + 382, 1343, 1519, 1344, 1345, 1349, 2514, 2514, 2514, 1351, + + 2514, 2514, 2514, 2514, 376, 2514, 1190, 1201, 1201, 1201, + 1518, 2514, 2514, 378, 1520, 2514, 1348, 1356, 1356, 1356, + 2514, 1522, 464, 1519, 2514, 1345, 1349, 376, 2514, 2514, + 1351, 493, 1350, 2514, 2514, 2514, 378, 2514, 2514, 378, + 1524, 1352, 1413, 1527, 1353, 1520, 378, 2514, 2514, 2514, + 2514, 378, 1522, 2514, 376, 376, 376, 2514, 376, 2514, + 2514, 2514, 493, 1350, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 1524, 1352, 1413, 1527, 1353, 2514, 378, 2514, 2514, + 2514, 378, 1361, 1361, 1361, 376, 1355, 1201, 1354, 2514, + 2514, 2514, 2514, 1359, 2514, 2514, 2514, 2514, 1357, 2514, + + 2514, 2514, 1360, 2514, 1358, 2514, 2514, 2514, 1514, 2514, + 2514, 2514, 1515, 1516, 378, 1363, 1364, 1355, 2514, 2514, + 2514, 2514, 2514, 2514, 1359, 2514, 2514, 2514, 378, 2514, + 2514, 2514, 2514, 1360, 1365, 1358, 493, 1528, 2514, 1514, + 378, 1366, 1414, 1515, 1516, 378, 1363, 1364, 378, 2514, + 1367, 1531, 2514, 2514, 2514, 2514, 2514, 2514, 1390, 378, + 2514, 2514, 2514, 1362, 464, 1365, 2514, 493, 1528, 376, + 378, 2514, 1366, 1414, 2514, 378, 2514, 2514, 2514, 2514, + 378, 1367, 1531, 2514, 2514, 2514, 378, 2514, 2514, 1390, + 378, 1224, 1224, 1224, 2514, 1391, 376, 376, 376, 378, + + 376, 2514, 378, 2514, 2514, 2514, 378, 1532, 1392, 2514, + 378, 2514, 2514, 2514, 1376, 1377, 1378, 1379, 1380, 1381, + 2514, 1382, 1533, 1383, 1534, 1384, 1391, 376, 1385, 1224, + 1535, 1386, 1387, 2514, 2514, 1388, 378, 2514, 1532, 1392, + 2514, 2514, 2514, 2514, 2514, 1376, 1377, 1378, 1379, 1380, + 1381, 1398, 1382, 1533, 1383, 1534, 1384, 378, 723, 1385, + 1461, 1535, 1386, 1387, 378, 1397, 1388, 2514, 2514, 2514, + 939, 2514, 1389, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 1398, 711, 378, 2514, 2514, 2514, 397, 1393, + 1466, 2514, 378, 2514, 1463, 1394, 1397, 2514, 2514, 2514, + + 756, 939, 1395, 1402, 1525, 1396, 1536, 1526, 1399, 2514, + 2514, 2514, 2514, 2514, 711, 1529, 1537, 2514, 2514, 1539, + 1393, 378, 1281, 1100, 1100, 1463, 1394, 1530, 1555, 1282, + 1538, 756, 1400, 1395, 1403, 1525, 1396, 1536, 1526, 1399, + 2514, 2514, 1285, 1102, 1102, 2514, 1529, 1537, 378, 1286, + 1539, 2514, 2514, 2514, 378, 2514, 2514, 378, 1530, 1555, + 378, 1538, 2514, 1400, 2514, 1403, 378, 470, 471, 472, + 473, 474, 474, 474, 474, 474, 474, 475, 378, 470, + 471, 472, 473, 474, 474, 474, 474, 474, 474, 475, + 378, 470, 471, 472, 473, 474, 474, 474, 474, 474, + + 474, 475, 1404, 1283, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 1405, 533, 534, 535, 536, 537, 537, 537, 537, + 537, 537, 538, 1287, 493, 493, 1406, 2514, 2514, 2514, + 2514, 470, 471, 472, 473, 474, 474, 474, 474, 474, + 474, 475, 1405, 1289, 1104, 1104, 1559, 1290, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 493, 493, 1406, 2514, 2514, + 2514, 1436, 2514, 2514, 2514, 2514, 2514, 470, 471, 472, + 473, 474, 474, 474, 474, 474, 474, 475, 470, 471, + 472, 473, 474, 474, 474, 474, 474, 474, 475, 495, + 641, 642, 643, 644, 645, 645, 645, 645, 645, 645, + + 646, 2514, 723, 1553, 1462, 1471, 493, 493, 378, 2514, + 711, 1478, 1478, 1478, 725, 1557, 1407, 2514, 1556, 1417, + 1558, 2514, 493, 1561, 1291, 2514, 1479, 1295, 1295, 1295, + 378, 2514, 1437, 378, 1553, 2514, 1471, 493, 493, 378, + 1297, 711, 2514, 2514, 378, 725, 1557, 1407, 1453, 1556, + 1417, 1558, 1438, 493, 1561, 502, 508, 504, 505, 506, + 506, 506, 506, 506, 506, 507, 495, 533, 534, 535, + 536, 537, 537, 537, 537, 537, 537, 538, 1563, 1453, + 1564, 1565, 1408, 1438, 2514, 1457, 2514, 2514, 2514, 2514, + 2514, 2514, 1480, 2514, 1569, 641, 642, 643, 644, 645, + + 645, 645, 645, 645, 645, 646, 2514, 2514, 1439, 1563, + 2514, 1564, 1565, 1408, 676, 677, 678, 679, 680, 680, + 680, 680, 680, 680, 681, 1569, 2514, 2514, 2514, 2514, + 2514, 2514, 502, 508, 504, 505, 506, 506, 506, 506, + 506, 506, 507, 1440, 1441, 1295, 1295, 1440, 1440, 1442, + 1443, 1440, 1440, 1440, 1440, 1440, 1440, 1444, 1440, 1440, + 1443, 1440, 1440, 1440, 1440, 1440, 1443, 1443, 1443, 1445, + 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + 1443, 1443, 1440, 1440, 1440, 1443, 1440, 1443, 1443, 1443, + + 1445, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, 1443, + 1443, 1443, 1443, 1440, 1446, 1447, 1448, 1449, 1450, 1450, + 1450, 1450, 1450, 1450, 1451, 2514, 2514, 1454, 1570, 2514, + 2514, 2514, 2514, 2514, 2514, 1571, 654, 1316, 1316, 1316, + 2514, 640, 2514, 2514, 1455, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 1454, 1570, + 2514, 1488, 1488, 1488, 2514, 2514, 1571, 2514, 640, 640, + 640, 1458, 640, 1472, 1468, 1455, 1489, 641, 642, 643, + 644, 645, 645, 645, 645, 645, 645, 646, 641, 642, + + 643, 644, 645, 645, 645, 645, 645, 645, 646, 640, + 2514, 1295, 1458, 1459, 1472, 1468, 2514, 2514, 2514, 2514, + 378, 2514, 1572, 378, 2514, 2514, 2514, 2514, 1469, 2514, + 2514, 676, 677, 678, 679, 680, 680, 680, 680, 680, + 680, 681, 378, 1470, 1459, 378, 2514, 2514, 2514, 2514, + 2514, 2514, 1490, 1572, 2514, 2514, 2514, 676, 677, 678, + 679, 680, 680, 680, 680, 680, 680, 681, 397, 2514, + 1467, 2514, 2514, 2514, 1470, 2514, 2514, 2514, 2514, 2514, + 399, 2514, 1573, 464, 2514, 2514, 2514, 1473, 376, 2514, + 1474, 2514, 2514, 2514, 1574, 2514, 2514, 2514, 378, 2514, + + 1475, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 1576, 2514, + 1476, 399, 1577, 1573, 1481, 376, 376, 376, 1473, 376, + 1477, 1474, 2514, 2514, 2514, 1574, 2514, 378, 1482, 2514, + 378, 1475, 2514, 2514, 2514, 378, 2514, 2514, 2514, 1576, + 1483, 1476, 1578, 1577, 1484, 1481, 376, 2514, 1316, 2514, + 2514, 1477, 2514, 2514, 2514, 2514, 2514, 378, 2514, 1482, + 2514, 2514, 2514, 2514, 2514, 378, 1494, 1486, 2514, 2514, + 2514, 1483, 378, 1578, 2514, 1484, 378, 2514, 2514, 2514, + 1346, 1346, 1346, 378, 2514, 2514, 378, 2514, 2514, 2514, + 1554, 1485, 2514, 2514, 2514, 1347, 493, 1494, 1486, 1487, + + 1560, 1498, 2514, 378, 464, 2514, 2514, 2514, 493, 376, + 2514, 1583, 1493, 378, 2514, 2514, 2514, 378, 2514, 2514, + 2514, 1554, 1485, 1356, 1356, 1356, 1585, 493, 1497, 1566, + 1487, 1560, 1498, 378, 1567, 1499, 376, 376, 376, 493, + 376, 378, 1583, 1493, 1501, 711, 1502, 2514, 2514, 378, + 2514, 2514, 2514, 1606, 2514, 2514, 2514, 1585, 378, 1497, + 1566, 1495, 2514, 2514, 2514, 1567, 1499, 376, 378, 1346, + 2514, 2514, 711, 464, 2514, 1501, 711, 1502, 376, 1504, + 1505, 1361, 1361, 1361, 1606, 1602, 378, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 378, 2514, 2514, 2514, 378, + + 2514, 2514, 2514, 711, 1503, 376, 376, 376, 2514, 376, + 1504, 1505, 2514, 2514, 1508, 1506, 1602, 1511, 1511, 1511, + 2514, 2514, 1509, 464, 2514, 2514, 2514, 1620, 376, 2514, + 1621, 378, 1512, 2514, 2514, 378, 376, 2514, 1356, 2514, + 2514, 2514, 1510, 2514, 2514, 1508, 1506, 2514, 2514, 2514, + 2514, 2514, 2514, 1509, 1628, 376, 376, 376, 1620, 376, + 1540, 1621, 1507, 2514, 2514, 2514, 1629, 2514, 378, 2514, + 2514, 378, 1633, 1510, 2514, 2514, 2514, 378, 1543, 1543, + 1543, 378, 2514, 2514, 2514, 1628, 376, 1541, 1361, 2514, + 1641, 1540, 1642, 1544, 2514, 2514, 2514, 1629, 1513, 2514, + + 2514, 2514, 2514, 1633, 723, 378, 1600, 1643, 1546, 2514, + 2514, 2514, 1644, 2514, 1645, 1542, 939, 723, 1541, 1601, + 378, 1641, 1646, 1642, 2514, 711, 1647, 1550, 378, 725, + 397, 378, 1604, 1547, 1592, 1592, 1592, 1548, 1643, 1546, + 1648, 1649, 756, 1644, 378, 1645, 1542, 939, 1650, 1651, + 2514, 2514, 1652, 1646, 2514, 378, 711, 1647, 1653, 1545, + 725, 2514, 2514, 378, 1547, 2514, 2514, 2514, 1548, 2514, + 2514, 1648, 1649, 756, 2514, 378, 2514, 2514, 2514, 1650, + 1651, 378, 1551, 1652, 2514, 2514, 2514, 2514, 1552, 1653, + 378, 470, 471, 472, 473, 474, 474, 474, 474, 474, + + 474, 475, 470, 471, 472, 473, 474, 474, 474, 474, + 474, 474, 475, 1551, 2514, 1593, 2514, 2514, 2514, 1552, + 2514, 470, 471, 472, 473, 474, 474, 474, 474, 474, + 474, 475, 470, 471, 472, 473, 474, 474, 474, 474, + 474, 474, 475, 470, 471, 472, 473, 474, 474, 474, + 474, 474, 474, 475, 1562, 1579, 1654, 378, 2514, 2514, + 2514, 1655, 1656, 1441, 1295, 1295, 378, 2514, 1580, 1441, + 1295, 1295, 2514, 2514, 1580, 2514, 1444, 2514, 2514, 2514, + 2514, 2514, 1444, 2514, 2514, 1562, 1579, 1654, 1581, 2514, + 2514, 2514, 1655, 1656, 1581, 2514, 641, 642, 643, 644, + + 645, 645, 645, 645, 645, 645, 646, 1608, 533, 534, + 535, 536, 537, 537, 537, 537, 537, 537, 538, 1581, + 1657, 1441, 1295, 1295, 2514, 1581, 1580, 1441, 1295, 1295, + 2514, 1658, 1580, 1659, 1444, 2514, 2514, 2514, 1608, 378, + 1584, 2514, 2514, 2514, 1582, 2514, 1581, 2514, 2514, 2514, + 1582, 1657, 1581, 2514, 2514, 1441, 1295, 1295, 378, 2514, + 1580, 397, 1658, 1605, 1659, 1660, 1661, 1609, 1444, 2514, + 378, 1586, 1662, 399, 1663, 1664, 1607, 1581, 2514, 2514, + 1581, 1665, 1666, 1581, 641, 642, 643, 644, 645, 645, + 645, 645, 645, 645, 646, 1594, 1660, 1661, 1609, 1478, + + 1478, 1478, 1582, 1662, 399, 1663, 1664, 1607, 1582, 1580, + 1440, 1581, 1665, 1666, 1479, 2514, 378, 2514, 2514, 2514, + 1586, 2514, 378, 2514, 1595, 1443, 1594, 2514, 378, 1688, + 493, 2514, 2514, 2514, 2514, 2514, 1582, 2514, 2514, 2514, + 641, 642, 643, 644, 645, 645, 645, 645, 645, 645, + 646, 1679, 1443, 1443, 1443, 1595, 1443, 2514, 2514, 2514, + 1688, 493, 641, 642, 643, 644, 645, 645, 645, 645, + 645, 645, 646, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 1611, 2514, 2514, 1443, 1443, 1587, 1443, 1443, 1443, 1443, + 1443, 1443, 1443, 1443, 1443, 1440, 1441, 1295, 1295, 1440, + + 1440, 1580, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1444, + 1440, 1440, 1586, 1440, 1440, 1440, 1440, 1596, 378, 1690, + 1691, 1590, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 378, 2514, + 1597, 2514, 2514, 2514, 1610, 1692, 2514, 2514, 1596, 2514, + 1690, 1691, 1590, 2514, 378, 1488, 1488, 1488, 676, 677, + 678, 679, 680, 680, 680, 680, 680, 680, 681, 1598, + 1489, 1597, 2514, 2514, 2514, 1610, 1692, 1591, 2514, 2514, + 2514, 1440, 1440, 2514, 1440, 676, 677, 678, 679, 680, + 680, 680, 680, 680, 680, 681, 2514, 2514, 2514, 2514, + + 1598, 2514, 1617, 378, 1613, 2514, 378, 676, 677, 678, + 679, 680, 680, 680, 680, 680, 680, 681, 2514, 2514, + 1614, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 464, + 2514, 2514, 2514, 1617, 376, 1613, 1618, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 1614, 1616, 378, 2514, 2514, 2514, 1615, 2514, 378, + 2514, 376, 376, 376, 1622, 376, 1630, 1630, 1630, 2514, + 2514, 2514, 1693, 1623, 2514, 493, 1627, 378, 2514, 2514, + 464, 1631, 2514, 1616, 1678, 376, 1634, 2514, 1615, 2514, + 2514, 2514, 376, 2514, 1478, 1622, 2514, 2514, 2514, 2514, + + 2514, 1694, 378, 1693, 1623, 378, 493, 1627, 2514, 2514, + 2514, 378, 376, 376, 376, 1678, 376, 1634, 378, 2514, + 2514, 378, 2514, 2514, 378, 493, 2514, 378, 2514, 2514, + 2514, 1635, 1694, 2514, 2514, 378, 1511, 1511, 1511, 2514, + 2514, 1681, 2514, 376, 1695, 1488, 2514, 1632, 2514, 1667, + 464, 1512, 1543, 1543, 1543, 376, 493, 1636, 2514, 2514, + 2514, 1637, 1635, 2514, 2514, 2514, 2514, 1544, 1696, 1668, + 378, 1697, 1681, 1638, 1680, 1695, 2514, 378, 2514, 493, + 1667, 2514, 376, 376, 376, 2514, 376, 2514, 2514, 378, + 1669, 2514, 1637, 2514, 2514, 2514, 2514, 2514, 464, 1696, + + 1668, 2514, 1697, 376, 1638, 1680, 2514, 2514, 2514, 378, + 493, 1682, 1683, 376, 2514, 1511, 493, 1639, 2514, 1672, + 493, 1669, 1684, 1685, 1675, 1698, 1699, 493, 493, 1700, + 376, 376, 376, 1670, 376, 1686, 1701, 1702, 1703, 378, + 493, 1706, 1682, 1683, 1710, 378, 1673, 493, 2514, 1676, + 1672, 493, 1585, 1684, 1685, 711, 1698, 1699, 493, 493, + 1700, 376, 2514, 1543, 2514, 2514, 1686, 1701, 1702, 1703, + 2514, 493, 1706, 2514, 378, 1710, 2514, 1673, 2514, 1677, + 1676, 2514, 1731, 1585, 1746, 2514, 711, 378, 470, 471, + 472, 473, 474, 474, 474, 474, 474, 474, 475, 470, + + 471, 472, 473, 474, 474, 474, 474, 474, 474, 475, + 1677, 1687, 1704, 1731, 2514, 1746, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 470, 471, 472, 473, 474, 474, + 474, 474, 474, 474, 475, 2514, 2514, 2514, 2514, 1747, + 1755, 2514, 1687, 1704, 2514, 533, 534, 535, 536, 537, + 537, 537, 537, 537, 537, 538, 641, 642, 643, 644, + 645, 645, 645, 645, 645, 645, 646, 1441, 1295, 1295, + 1747, 1755, 1580, 1441, 1295, 1295, 2514, 2514, 1580, 2514, + 1444, 2514, 1441, 1295, 1295, 2514, 1444, 1580, 1707, 1708, + 1708, 2514, 1581, 1580, 723, 1444, 1726, 378, 1581, 2514, + + 397, 1584, 1729, 1441, 1295, 1295, 939, 1581, 1580, 1715, + 1708, 1708, 756, 1581, 1716, 1705, 1444, 378, 723, 2514, + 1727, 2514, 1717, 1581, 1756, 2514, 711, 1759, 1581, 1581, + 725, 2514, 2514, 1761, 1718, 2514, 2514, 939, 1581, 2514, + 2514, 2514, 1762, 756, 1581, 1763, 1705, 1768, 1582, 2514, + 2514, 2514, 2514, 2514, 1582, 1756, 1720, 711, 1759, 1581, + 2514, 725, 1721, 1588, 1761, 1718, 2514, 2514, 2514, 1709, + 1441, 1295, 1295, 1762, 2514, 1580, 1763, 2514, 1768, 2514, + 397, 2514, 1730, 1444, 1588, 2514, 2514, 1720, 1722, 1770, + 1719, 1735, 399, 1721, 1773, 1581, 641, 642, 643, 644, + + 645, 645, 645, 645, 645, 645, 646, 641, 642, 643, + 644, 645, 645, 645, 645, 645, 645, 646, 1774, 1722, + 1770, 2514, 1735, 399, 2514, 1773, 1581, 2514, 2514, 2514, + 1723, 378, 676, 677, 678, 679, 680, 680, 680, 680, + 680, 680, 681, 2514, 2514, 2514, 2514, 378, 2514, 1774, + 1711, 1712, 1711, 1711, 1711, 1711, 1711, 1711, 1711, 1711, + 1711, 1723, 1724, 2514, 2514, 2514, 2514, 2514, 2514, 1732, + 676, 677, 678, 679, 680, 680, 680, 680, 680, 680, + 681, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 1724, 2514, 2514, 2514, 2514, 1775, 1733, + + 1732, 1734, 2514, 2514, 2514, 2514, 2514, 676, 677, 678, + 679, 680, 680, 680, 680, 680, 680, 681, 1739, 1771, + 1748, 1776, 1777, 1741, 378, 1740, 2514, 2514, 2514, 1775, + 1733, 2514, 1734, 1780, 1751, 1751, 1751, 1772, 1742, 2514, + 2514, 2514, 1781, 2514, 378, 2514, 2514, 378, 2514, 1739, + 1771, 1748, 1776, 1777, 1741, 1778, 1740, 1630, 1630, 1630, + 1782, 1783, 378, 1752, 1780, 1749, 1779, 378, 1772, 1742, + 378, 1784, 1631, 1781, 1754, 378, 2514, 2514, 2514, 2514, + 2514, 1785, 1786, 378, 2514, 1787, 1778, 1788, 2514, 2514, + 464, 1782, 1783, 2514, 1752, 376, 1749, 1779, 1789, 1792, + + 1790, 1793, 1784, 1794, 1795, 1754, 1802, 378, 2514, 2514, + 2514, 2514, 1785, 1786, 2514, 1753, 1787, 1760, 1788, 2514, + 378, 1791, 376, 376, 376, 2514, 376, 1806, 493, 1789, + 1792, 1790, 1793, 493, 1794, 1795, 493, 493, 1757, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 1760, 2514, + 2514, 2514, 1791, 376, 1805, 1630, 1803, 378, 1806, 493, + 2514, 493, 493, 493, 493, 1807, 1810, 493, 493, 1796, + 470, 471, 472, 473, 474, 474, 474, 474, 474, 474, + 475, 2514, 1811, 1808, 1812, 1800, 1813, 1803, 1815, 378, + 493, 1804, 493, 493, 493, 2514, 1807, 1810, 1816, 2514, + + 1796, 2514, 470, 471, 472, 473, 474, 474, 474, 474, + 474, 474, 475, 1811, 1808, 1812, 1800, 1813, 2514, 1815, + 378, 493, 1804, 378, 1817, 1818, 378, 1819, 1821, 1816, + 378, 470, 471, 472, 473, 474, 474, 474, 474, 474, + 474, 475, 533, 534, 535, 536, 537, 537, 537, 537, + 537, 537, 538, 1829, 2514, 1817, 1818, 1848, 1819, 1821, + 2514, 1863, 2514, 641, 642, 643, 644, 645, 645, 645, + 645, 645, 645, 646, 1441, 1295, 1295, 2514, 1864, 1580, + 1823, 1708, 1708, 2514, 1829, 1824, 2514, 1444, 1848, 1715, + 1708, 1708, 1863, 1825, 1716, 1869, 1820, 1870, 2514, 1581, + + 2514, 723, 1717, 1843, 2514, 1826, 1441, 1295, 1295, 1864, + 2514, 1580, 1871, 939, 1718, 2514, 1441, 1295, 1295, 1444, + 2514, 1580, 2514, 2514, 2514, 2514, 1869, 1820, 1870, 1444, + 1581, 1581, 1443, 1441, 1295, 1295, 1826, 2514, 1580, 2514, + 2514, 1581, 2514, 1871, 939, 1718, 1444, 2514, 2514, 1443, + 2514, 1830, 1295, 1295, 2514, 1582, 1716, 1875, 1581, 1876, + 2514, 1827, 1581, 2514, 1717, 2514, 1715, 1708, 1708, 2514, + 1719, 1716, 1581, 1832, 1295, 1295, 1718, 2514, 1824, 1717, + 1830, 1295, 1295, 2514, 2514, 1716, 1825, 1828, 1875, 1581, + 1876, 1718, 2514, 1834, 2514, 2514, 2514, 1582, 1826, 1830, + + 1295, 1295, 2514, 378, 1716, 1718, 2514, 1718, 1830, 1295, + 1295, 2514, 1717, 1716, 1588, 397, 2514, 1846, 1877, 1878, + 1851, 1717, 1718, 723, 1718, 1844, 1883, 756, 1884, 1826, + 2514, 711, 1831, 1718, 1885, 725, 1718, 1837, 1886, 1887, + 2514, 1835, 2514, 2514, 2514, 1888, 2514, 1719, 1889, 1877, + 1878, 1851, 1892, 1893, 1833, 1718, 1894, 1883, 756, 1884, + 2514, 1831, 711, 2514, 1718, 1885, 725, 2514, 1837, 1886, + 1887, 1838, 1835, 2514, 2514, 378, 1888, 1849, 1895, 1889, + 1831, 2514, 2514, 1892, 1893, 2514, 2514, 1894, 2514, 1836, + 1839, 641, 642, 643, 644, 645, 645, 645, 645, 645, + + 645, 646, 1838, 2514, 2514, 2514, 1840, 1841, 1849, 1895, + 641, 642, 643, 644, 645, 645, 645, 645, 645, 645, + 646, 1839, 2514, 378, 2514, 2514, 676, 677, 678, 679, + 680, 680, 680, 680, 680, 680, 681, 1840, 1841, 2514, + 2514, 2514, 2514, 1896, 1850, 2514, 676, 677, 678, 679, + 680, 680, 680, 680, 680, 680, 681, 2514, 2514, 2514, + 676, 677, 678, 679, 680, 680, 680, 680, 680, 680, + 681, 397, 2514, 1847, 1896, 1850, 1853, 1853, 1853, 2514, + 2514, 2514, 1897, 399, 378, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 1860, 1860, 1860, 2514, 2514, 2514, 2514, 2514, + + 2514, 1867, 1867, 1867, 1898, 1854, 2514, 2514, 1751, 1751, + 1751, 1857, 1899, 1897, 399, 2514, 1347, 1900, 1901, 1856, + 378, 1861, 2514, 2514, 2514, 1904, 2514, 1858, 1866, 2514, + 2514, 2514, 1905, 1906, 1865, 1898, 1854, 1752, 378, 1890, + 1890, 1890, 1857, 1899, 1907, 1880, 1880, 1880, 1900, 1901, + 1856, 2514, 1861, 1902, 1902, 1902, 1904, 1855, 1858, 1866, + 378, 1908, 1909, 1905, 1906, 1865, 378, 1910, 1752, 378, + 1911, 1912, 2514, 1862, 1881, 1907, 378, 2514, 2514, 378, + 493, 2514, 1868, 2514, 2514, 2514, 1915, 1915, 1915, 1753, + 1922, 1926, 1908, 1909, 2514, 2514, 2514, 1920, 1910, 1923, + + 1927, 1911, 1912, 378, 493, 1881, 2514, 1928, 493, 1924, + 378, 493, 1919, 493, 1930, 1916, 1931, 1932, 1933, 1913, + 1891, 1922, 1926, 2514, 2514, 2514, 1882, 2514, 1920, 1925, + 1923, 1927, 1957, 2514, 1903, 493, 2514, 1921, 1928, 493, + 1924, 2514, 2514, 1960, 493, 1930, 1916, 1931, 1932, 1933, + 1913, 470, 471, 472, 473, 474, 474, 474, 474, 474, + 474, 475, 2514, 1957, 378, 2514, 2514, 1917, 1921, 2514, + 2514, 2514, 2514, 1938, 1960, 378, 470, 471, 472, 473, + 474, 474, 474, 474, 474, 474, 475, 470, 471, 472, + 473, 474, 474, 474, 474, 474, 474, 475, 1934, 1934, + + 1934, 2514, 2514, 2514, 1938, 1964, 2514, 2514, 2514, 2514, + 2514, 1965, 1935, 641, 642, 643, 644, 645, 645, 645, + 645, 645, 645, 646, 1441, 1295, 1295, 2514, 1966, 1580, + 1832, 1295, 1295, 2514, 2514, 1824, 1964, 1444, 2514, 1823, + 1708, 1708, 1965, 1825, 1824, 1832, 1295, 1295, 2514, 1581, + 1824, 378, 1825, 1969, 723, 1826, 1952, 1939, 1825, 1966, + 1832, 1295, 1295, 2514, 1826, 1824, 939, 1970, 1975, 397, + 1826, 1955, 1976, 1940, 2514, 1853, 1853, 1853, 2514, 1936, + 1581, 756, 378, 2514, 1969, 1826, 1826, 378, 1939, 1832, + 1295, 1295, 2514, 2514, 1824, 1826, 1977, 939, 1970, 1975, + + 2514, 1826, 1825, 1976, 1854, 1582, 1978, 2514, 1832, 1295, + 1295, 1833, 756, 1824, 1826, 1981, 1826, 1823, 1708, 1708, + 1827, 1825, 1824, 1830, 1295, 1295, 1833, 1977, 1716, 1982, + 1825, 1941, 2514, 1826, 2514, 1854, 1717, 1978, 1830, 1295, + 1295, 1833, 1826, 1716, 2514, 1826, 1981, 723, 1718, 1953, + 1983, 1717, 1832, 1295, 1295, 711, 1855, 1824, 2514, 725, + 1982, 2514, 1941, 1718, 1826, 1825, 1984, 1832, 1295, 1295, + 1833, 2514, 1824, 1826, 2514, 2514, 2514, 1826, 1985, 1718, + 1825, 1983, 1715, 1708, 1708, 2514, 711, 1716, 2514, 1942, + 725, 2514, 1826, 1986, 1718, 1834, 1987, 1984, 1943, 2514, + + 1830, 1295, 1295, 2514, 1831, 1716, 1988, 1718, 1826, 1985, + 2514, 1989, 1990, 1717, 1991, 1715, 1708, 1708, 1992, 1944, + 1716, 1993, 1946, 1826, 1986, 1718, 1994, 1987, 1717, 1958, + 1958, 1958, 2514, 1833, 2514, 2514, 2514, 1988, 1718, 1995, + 1718, 1948, 1989, 1990, 1479, 1991, 2514, 1996, 1945, 1992, + 2514, 2514, 1993, 1946, 2514, 378, 1718, 1994, 1962, 1962, + 1962, 2514, 1997, 1719, 1867, 1867, 1867, 2514, 2514, 2514, + 1995, 1718, 1948, 1489, 2514, 2514, 2514, 1949, 1996, 1347, + 2514, 1831, 641, 642, 643, 644, 645, 645, 645, 645, + 645, 645, 646, 1997, 2514, 2514, 1947, 641, 642, 643, + + 644, 645, 645, 645, 645, 645, 645, 646, 1949, 1950, + 1959, 2514, 2514, 2514, 2514, 378, 2514, 676, 677, 678, + 679, 680, 680, 680, 680, 680, 680, 681, 676, 677, + 678, 679, 680, 680, 680, 680, 680, 680, 681, 1963, + 1950, 1961, 1860, 1860, 1860, 1868, 1998, 2514, 2514, 2514, + 676, 677, 678, 679, 680, 680, 680, 680, 680, 680, + 681, 397, 2514, 1956, 2514, 2514, 2514, 2514, 2514, 2514, + 2002, 1861, 1961, 399, 1972, 1972, 1972, 1998, 1979, 1979, + 1979, 1880, 1880, 1880, 1890, 1890, 1890, 2003, 1902, 1902, + 1902, 2004, 378, 1512, 2005, 2014, 2015, 2514, 2514, 2016, + + 2017, 2002, 1861, 1973, 399, 1967, 2021, 493, 1968, 493, + 1881, 2028, 1999, 2514, 2514, 2000, 2514, 2514, 2003, 2514, + 2514, 2514, 2004, 1862, 2514, 2005, 2014, 2015, 378, 2001, + 2016, 2017, 2029, 493, 1973, 2030, 1967, 2021, 493, 1968, + 493, 1881, 2028, 1999, 2026, 378, 2000, 493, 378, 2514, + 2514, 2514, 2019, 2019, 2019, 1974, 2514, 2027, 2514, 1980, + 2001, 2031, 1882, 2029, 493, 1891, 2030, 1544, 2032, 1903, + 2006, 1915, 1915, 1915, 2023, 2026, 2007, 2514, 493, 2036, + 2008, 2009, 2047, 2049, 2018, 2010, 2011, 2012, 2027, 2013, + 2051, 723, 2031, 2042, 1934, 1934, 1934, 2048, 2052, 2032, + + 1916, 2006, 2514, 939, 2514, 2514, 2514, 2007, 1935, 2514, + 2036, 2008, 2009, 2047, 2049, 2018, 2010, 2011, 2012, 2024, + 2013, 2051, 2053, 2056, 2057, 2060, 2061, 2062, 2048, 2052, + 378, 1916, 2514, 2020, 939, 2033, 2033, 2033, 470, 471, + 472, 473, 474, 474, 474, 474, 474, 474, 475, 2025, + 2024, 2063, 1917, 2053, 2056, 2057, 2060, 2061, 2062, 1958, + 1958, 1958, 2514, 470, 471, 472, 473, 474, 474, 474, + 474, 474, 474, 475, 1479, 1936, 2034, 1972, 1972, 1972, + 2025, 2514, 2063, 2514, 2514, 1962, 1962, 1962, 2514, 470, + 471, 472, 473, 474, 474, 474, 474, 474, 474, 475, + + 1489, 2064, 2514, 723, 2514, 2043, 1973, 2034, 2514, 2514, + 2514, 711, 2514, 2514, 2514, 725, 2035, 641, 642, 643, + 644, 645, 645, 645, 645, 645, 645, 646, 1441, 1295, + 1295, 2514, 2064, 1580, 1823, 1708, 1708, 1973, 2065, 1824, + 1959, 1444, 711, 1832, 1295, 1295, 725, 1940, 1824, 1823, + 1708, 1708, 2514, 1581, 1824, 397, 1825, 2045, 1974, 1826, + 2066, 2067, 1825, 2054, 2514, 2037, 1963, 756, 1826, 2065, + 1832, 1295, 1295, 2514, 1826, 1824, 1830, 1295, 1295, 2068, + 2514, 1716, 2514, 1825, 1581, 2058, 2058, 2058, 2514, 1717, + 1826, 2066, 2067, 378, 2514, 1826, 2037, 2514, 756, 1826, + + 1631, 1718, 2514, 2514, 2514, 1826, 1832, 1295, 1295, 1582, + 2068, 1824, 1830, 1295, 1295, 1827, 397, 1716, 2046, 1825, + 2514, 2069, 2070, 2076, 1833, 1717, 1826, 2514, 399, 2082, + 1943, 1826, 1718, 1830, 1295, 1295, 2085, 1718, 1716, 2086, + 1525, 1529, 2087, 2088, 2089, 2038, 1717, 2514, 1979, 1979, + 1979, 1942, 2069, 2070, 2076, 2039, 2514, 1944, 1718, 399, + 2082, 2514, 1826, 1512, 2514, 2514, 2059, 2085, 1718, 2514, + 2086, 1525, 1529, 2087, 2088, 2089, 2038, 2071, 2071, 2071, + 2514, 2514, 2514, 378, 2514, 2514, 2039, 1945, 2514, 1718, + 2514, 2514, 2514, 1831, 641, 642, 643, 644, 645, 645, + + 645, 645, 645, 645, 646, 2040, 2073, 2073, 2073, 2078, + 2078, 2078, 2092, 2514, 1836, 676, 677, 678, 679, 680, + 680, 680, 680, 680, 680, 681, 2055, 2514, 2095, 1980, + 2514, 2050, 2080, 2080, 2080, 2096, 2040, 2083, 2083, 2083, + 2090, 2090, 2090, 2092, 676, 677, 678, 679, 680, 680, + 680, 680, 680, 680, 681, 2097, 2514, 2055, 2072, 2095, + 2093, 378, 2050, 2094, 2098, 2100, 2096, 2103, 2104, 2105, + 2106, 378, 2107, 2101, 2099, 2514, 2514, 2514, 2108, 2110, + 2102, 2113, 2019, 2019, 2019, 2111, 2097, 2074, 2115, 493, + 2079, 2093, 2514, 2514, 2094, 2098, 2100, 1544, 2103, 2104, + + 2105, 2106, 2514, 2107, 2101, 2099, 2114, 2116, 2117, 2108, + 493, 2102, 2113, 2081, 2514, 2514, 2111, 2514, 2084, 2115, + 493, 2091, 2514, 470, 471, 472, 473, 474, 474, 474, + 474, 474, 474, 475, 2112, 2118, 2119, 2114, 2116, 2117, + 2120, 493, 2514, 470, 471, 472, 473, 474, 474, 474, + 474, 474, 474, 475, 2514, 2514, 378, 2033, 2033, 2033, + 2514, 2514, 2130, 2020, 2514, 2112, 2118, 2119, 2514, 2131, + 2514, 2120, 2514, 470, 471, 472, 473, 474, 474, 474, + 474, 474, 474, 475, 1832, 1295, 1295, 2132, 2134, 1824, + 1830, 1295, 1295, 2130, 723, 1716, 2125, 1825, 2034, 397, + + 2131, 2128, 723, 1717, 2126, 2135, 939, 2514, 2136, 1826, + 711, 756, 2514, 2142, 725, 1718, 2143, 2121, 2132, 2134, + 2122, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2034, + 2514, 2514, 2514, 2138, 2138, 2138, 2135, 939, 2035, 2136, + 1826, 711, 756, 2123, 2142, 725, 1718, 2143, 2121, 641, + 642, 643, 644, 645, 645, 645, 645, 645, 645, 646, + 2137, 2140, 2140, 2140, 2144, 1833, 2514, 2133, 2514, 2146, + 2514, 1831, 676, 677, 678, 679, 680, 680, 680, 680, + 680, 680, 681, 2514, 2514, 2514, 2058, 2058, 2058, 2147, + 2148, 2137, 2149, 2151, 2152, 2144, 2514, 397, 2133, 2129, + + 2146, 1631, 378, 2155, 2514, 378, 2071, 2071, 2071, 399, + 2160, 378, 2514, 2514, 2139, 2073, 2073, 2073, 2162, 2163, + 2147, 2148, 2165, 2149, 2151, 2152, 2153, 2153, 2153, 2078, + 2078, 2078, 2166, 2514, 2155, 2080, 2080, 2080, 2167, 2168, + 399, 2160, 2141, 2083, 2083, 2083, 2090, 2090, 2090, 2162, + 2163, 2169, 2170, 2165, 2171, 2514, 2514, 2172, 2173, 2174, + 2175, 2157, 2156, 2166, 378, 2181, 2176, 2059, 2177, 2167, + 2168, 2178, 2179, 2186, 2187, 2158, 2514, 2188, 2201, 2201, + 2201, 2190, 2169, 2170, 2159, 2171, 2164, 2072, 2172, 2173, + 2174, 2175, 2157, 2156, 2199, 2200, 2074, 2176, 2514, 2177, + + 2514, 2514, 2178, 2179, 2186, 2187, 2158, 2154, 2188, 2182, + 2079, 2183, 2190, 2514, 2514, 2159, 2081, 2164, 2514, 2514, + 2514, 2514, 2514, 2514, 2084, 2199, 2200, 2091, 2514, 470, + 471, 472, 473, 474, 474, 474, 474, 474, 474, 475, + 2182, 2514, 2183, 2203, 2203, 2203, 2514, 2514, 470, 471, + 472, 473, 474, 474, 474, 474, 474, 474, 475, 2202, + 2514, 2514, 2205, 2514, 2206, 470, 471, 472, 473, 474, + 474, 474, 474, 474, 474, 475, 493, 493, 1832, 1295, + 1295, 2209, 723, 1824, 2194, 2191, 2185, 2184, 2514, 2210, + 723, 1825, 2195, 2205, 939, 2206, 2192, 2211, 711, 378, + + 2514, 2212, 725, 1826, 2138, 2138, 2138, 493, 493, 2213, + 2213, 2213, 2209, 2221, 2221, 2221, 2191, 2185, 2184, 397, + 2210, 2197, 2514, 2514, 2204, 939, 2220, 2192, 2211, 711, + 2223, 756, 2212, 725, 1826, 641, 642, 643, 644, 645, + 645, 645, 645, 645, 645, 646, 676, 677, 678, 679, + 680, 680, 680, 680, 680, 680, 681, 2220, 2514, 1833, + 2514, 2223, 756, 2514, 2514, 2514, 2514, 2514, 2514, 2140, + 2140, 2140, 2216, 2216, 2216, 2224, 2225, 397, 2226, 2198, + 2153, 2153, 2153, 2227, 2228, 2139, 2217, 2229, 2231, 399, + 2214, 2207, 2232, 2233, 2222, 2234, 2235, 2236, 2230, 2237, + + 2238, 2239, 2208, 2240, 2241, 2242, 2224, 2225, 2243, 2226, + 2244, 2245, 2249, 2514, 2227, 2228, 2514, 493, 2229, 2231, + 399, 2253, 2207, 2232, 2233, 2514, 2234, 2235, 2236, 2251, + 2237, 2238, 2239, 2208, 2240, 2241, 2242, 2514, 2514, 2243, + 2514, 2244, 2245, 2250, 378, 2514, 2514, 378, 493, 2514, + 2141, 2514, 2253, 2218, 2246, 2246, 2246, 2514, 2514, 2514, + 2251, 2154, 470, 471, 472, 473, 474, 474, 474, 474, + 474, 474, 475, 2254, 2250, 2255, 470, 471, 472, 473, + 474, 474, 474, 474, 474, 474, 475, 493, 470, 471, + 472, 473, 474, 474, 474, 474, 474, 474, 475, 2256, + + 2252, 2257, 2258, 723, 2254, 2261, 2255, 397, 723, 2264, + 2262, 2266, 2267, 2259, 2268, 939, 711, 2514, 493, 756, + 725, 2269, 2514, 2514, 2514, 2201, 2201, 2201, 2514, 2514, + 2256, 2252, 2257, 2258, 2514, 2247, 397, 2514, 2265, 2203, + 2203, 2203, 2266, 2267, 2259, 2268, 939, 711, 399, 2270, + 756, 725, 2269, 2514, 2514, 2514, 2273, 641, 642, 643, + 644, 645, 645, 645, 645, 645, 645, 646, 676, 677, + 678, 679, 680, 680, 680, 680, 680, 680, 681, 399, + 2270, 2271, 2271, 2271, 2274, 2275, 2276, 2273, 2213, 2213, + 2213, 2216, 2216, 2216, 2277, 2277, 2277, 2281, 2282, 2221, + + 2221, 2221, 2284, 378, 2514, 2217, 2202, 2285, 2514, 2286, + 2287, 2288, 2289, 2290, 2291, 2274, 2275, 2276, 2292, 2293, + 2204, 2294, 2295, 2296, 2297, 2298, 2299, 2300, 2281, 2282, + 2278, 2305, 2301, 2284, 378, 2279, 2302, 2303, 2285, 2283, + 2286, 2287, 2288, 2289, 2290, 2291, 2246, 2246, 2246, 2292, + 2293, 2306, 2294, 2295, 2296, 2297, 2298, 2299, 2300, 2309, + 2310, 2278, 2272, 2301, 2514, 2514, 2279, 2302, 2303, 2214, + 2283, 2514, 2218, 2514, 2514, 2280, 2514, 2271, 2271, 2271, + 2222, 723, 2306, 2313, 2514, 2514, 2514, 2514, 2308, 2311, + 2309, 2310, 493, 939, 2318, 470, 471, 472, 473, 474, + + 474, 474, 474, 474, 474, 475, 2514, 470, 471, 472, + 473, 474, 474, 474, 474, 474, 474, 475, 493, 2308, + 2311, 2514, 2514, 493, 939, 2318, 2319, 2247, 2307, 641, + 642, 643, 644, 645, 645, 645, 645, 645, 645, 646, + 723, 397, 2314, 2316, 2320, 2321, 2322, 2326, 711, 493, + 2327, 2328, 725, 756, 2277, 2277, 2277, 2319, 2272, 2307, + 676, 677, 678, 679, 680, 680, 680, 680, 680, 680, + 681, 2514, 2514, 2514, 2329, 2320, 2321, 2322, 2326, 711, + 2330, 2327, 2328, 725, 756, 397, 2331, 2317, 2332, 2333, + 2278, 2334, 2335, 2336, 2337, 2279, 2338, 399, 2339, 2340, + + 2341, 2342, 2343, 2344, 2351, 2329, 2345, 2346, 2347, 2348, + 2349, 2330, 493, 2354, 2355, 2362, 2363, 2331, 2364, 2332, + 2333, 2278, 2334, 2335, 2336, 2337, 2279, 2338, 399, 2339, + 2340, 2341, 2342, 2343, 2344, 2280, 2514, 2345, 2346, 2347, + 2348, 2349, 2514, 493, 2354, 2355, 2362, 2363, 2352, 2364, + 2365, 723, 378, 2357, 2514, 397, 2514, 2360, 2514, 2514, + 2514, 2514, 2514, 939, 2514, 2366, 2514, 756, 470, 471, + 472, 473, 474, 474, 474, 474, 474, 474, 475, 2352, + 2367, 2365, 470, 471, 472, 473, 474, 474, 474, 474, + 474, 474, 475, 493, 939, 723, 2366, 2358, 756, 2514, + + 2514, 2514, 2353, 711, 2370, 2371, 2374, 725, 2375, 2376, + 2377, 2367, 2380, 397, 2381, 2361, 2378, 2378, 2378, 2382, + 2383, 2384, 2385, 2386, 493, 399, 2387, 2388, 2389, 2514, + 2514, 2514, 2514, 2353, 711, 2370, 2371, 2374, 725, 2375, + 2376, 2377, 2391, 2380, 493, 2381, 2392, 2399, 2514, 2514, + 2382, 2383, 2384, 2385, 2386, 2514, 399, 2387, 2388, 2389, + 470, 471, 472, 473, 474, 474, 474, 474, 474, 474, + 475, 2400, 2401, 2402, 723, 493, 2394, 2392, 2399, 723, + 378, 2395, 397, 2514, 2397, 2514, 939, 711, 2408, 2408, + 2408, 725, 2403, 2404, 756, 2405, 2406, 2379, 2407, 2410, + + 2411, 2412, 2400, 2401, 2402, 2514, 470, 471, 472, 473, + 474, 474, 474, 474, 474, 474, 475, 939, 711, 2514, + 2514, 2514, 725, 2403, 2404, 756, 2405, 2406, 2413, 2407, + 2410, 2411, 2412, 397, 2414, 2398, 2378, 2378, 2378, 2415, + 2416, 2417, 2378, 2378, 2378, 399, 470, 471, 472, 473, + 474, 474, 474, 474, 474, 474, 475, 2426, 2427, 2413, + 2428, 723, 2429, 2421, 2430, 2414, 723, 2431, 2422, 2409, + 2415, 2416, 2417, 939, 711, 397, 399, 2424, 725, 2433, + 2514, 2514, 2514, 2408, 2408, 2408, 2514, 756, 2426, 2427, + 2436, 2428, 2514, 2429, 397, 2430, 2425, 2437, 2431, 2438, + + 378, 2434, 2434, 2434, 939, 711, 399, 2444, 2514, 725, + 2433, 2445, 723, 397, 2440, 2443, 2514, 2379, 756, 2446, + 2447, 2436, 2448, 2379, 939, 756, 2514, 723, 2437, 2441, + 2438, 2514, 2514, 2514, 2449, 711, 2450, 399, 2444, 725, + 2452, 2453, 2445, 2454, 2514, 397, 2514, 2425, 2514, 2514, + 2446, 2447, 2457, 2448, 2514, 939, 756, 399, 2434, 2434, + 2434, 378, 2514, 2514, 2409, 2449, 711, 2450, 2462, 2514, + 725, 2452, 2453, 2463, 2454, 723, 2464, 2456, 723, 397, + 2441, 2443, 2435, 2457, 2465, 2451, 711, 939, 399, 2466, + 725, 756, 2458, 2458, 2458, 2467, 2468, 2469, 2473, 2462, + + 2459, 723, 2476, 2456, 2463, 2477, 2478, 2464, 2514, 2479, + 2480, 2481, 378, 939, 2482, 2465, 2451, 711, 939, 2483, + 2466, 725, 756, 2458, 2458, 2458, 2467, 2468, 2469, 2473, + 2484, 2459, 2485, 2476, 2488, 2489, 2477, 2478, 2490, 2435, + 2479, 2480, 2481, 2491, 939, 2482, 2486, 2486, 2486, 2495, + 2483, 2492, 2492, 2492, 2486, 2486, 2486, 2496, 2497, 2498, + 2499, 2484, 2500, 2485, 2514, 2488, 2489, 2501, 2502, 2490, + 2492, 2492, 2492, 2460, 2491, 2461, 2492, 2492, 2492, 2503, + 2495, 2504, 2378, 2378, 2378, 2505, 2506, 2507, 2496, 2497, + 2498, 2499, 2508, 2500, 2509, 2494, 2514, 2510, 2501, 2502, + + 2511, 2514, 2512, 2513, 2460, 2514, 2461, 2492, 2492, 2492, + 2503, 2514, 2504, 2514, 2514, 2514, 2505, 2506, 2507, 2514, + 2514, 2514, 2514, 2508, 2514, 2509, 2494, 2487, 2510, 2514, + 2514, 2511, 2493, 2512, 2513, 2487, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2493, 2514, 2514, 2514, 2514, 2514, 2493, 2514, 2514, + 2514, 2514, 2514, 2379, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2493, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + + 125, 125, 125, 125, 125, 125, 125, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 217, 217, 217, 217, 217, 217, 217, 217, 217, + 217, 217, 217, 217, 217, 217, 217, 217, 217, 226, + 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, + 226, 226, 226, 226, 226, 226, 226, 233, 233, 233, + + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 233, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 239, 239, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, + 239, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 244, + 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, + 244, 244, 244, 244, 244, 244, 244, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + + 268, 268, 268, 268, 268, 270, 270, 270, 270, 270, + 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, + 270, 270, 270, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, + 312, 337, 337, 337, 337, 337, 337, 337, 337, 337, + 337, 337, 337, 337, 337, 337, 337, 337, 337, 346, + 346, 346, 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 361, 361, 361, + 2514, 2514, 2514, 361, 2514, 2514, 2514, 2514, 361, 361, + 361, 361, 369, 369, 2514, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 370, 370, 2326, 370, 370, 370, 370, 370, - 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, - 370, 748, 748, 2326, 748, 748, 748, 748, 748, 748, - 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, - 377, 377, 2326, 2326, 2326, 2326, 377, 2326, 2326, 2326, - 2326, 377, 377, 377, 377, 464, 2326, 464, 464, 464, - 464, 384, 384, 384, 2326, 2326, 2326, 384, 2326, 2326, - 2326, 2326, 384, 384, 384, 384, 750, 2326, 750, 750, - 750, 750, 455, 455, 2326, 2326, 2326, 2326, 455, 2326, - - 2326, 2326, 455, 455, 455, 455, 455, 837, 2326, 837, - 837, 837, 837, 468, 468, 2326, 2326, 2326, 2326, 468, - 2326, 2326, 2326, 2326, 468, 468, 468, 468, 486, 2326, - 486, 486, 486, 486, 492, 492, 2326, 492, 492, 2326, - 492, 492, 492, 492, 2326, 2326, 2326, 2326, 492, 492, - 492, 492, 522, 2326, 522, 522, 522, 522, 524, 524, - 524, 2326, 2326, 2326, 2326, 524, 2326, 2326, 2326, 2326, - 524, 524, 524, 524, 859, 2326, 859, 859, 859, 859, - 531, 531, 2326, 2326, 2326, 2326, 531, 2326, 2326, 2326, - 2326, 531, 531, 531, 531, 559, 2326, 559, 559, 559, - - 559, 538, 538, 538, 2326, 2326, 2326, 538, 2326, 2326, - 2326, 2326, 538, 538, 538, 538, 861, 2326, 861, 861, - 861, 861, 550, 550, 2326, 2326, 2326, 2326, 550, 2326, - 2326, 2326, 550, 550, 550, 550, 550, 865, 2326, 865, - 865, 865, 865, 560, 2326, 2326, 560, 2326, 560, 580, - 2326, 2326, 580, 2326, 580, 604, 604, 604, 604, 604, - 604, 2326, 604, 604, 604, 604, 604, 604, 2326, 604, - 604, 604, 604, 604, 884, 884, 2326, 884, 884, 884, - 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, - 884, 884, 884, 611, 611, 611, 611, 611, 611, 2326, - - 611, 611, 611, 611, 611, 611, 2326, 611, 611, 611, - 611, 611, 888, 888, 2326, 888, 888, 888, 888, 888, - 888, 888, 888, 888, 888, 888, 888, 888, 888, 888, - 888, 892, 892, 2326, 892, 892, 892, 892, 892, 892, - 892, 892, 892, 892, 892, 892, 892, 892, 892, 892, - 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, - 624, 624, 624, 624, 2326, 624, 624, 624, 624, 626, + 376, 376, 2514, 2514, 2514, 376, 2514, 2514, 2514, 2514, + 376, 376, 376, 376, 383, 383, 383, 2514, 2514, 383, + 2514, 2514, 2514, 2514, 383, 383, 383, 383, 456, 456, + 2514, 2514, 2514, 456, 2514, 2514, 2514, 456, 456, 456, + 456, 456, 465, 2514, 465, 465, 465, 465, 465, 465, + 465, 469, 469, 2514, 2514, 2514, 469, 2514, 2514, 2514, + 2514, 469, 469, 469, 469, 487, 2514, 487, 487, 487, + 487, 487, 487, 493, 493, 2514, 493, 493, 2514, 493, + 493, 493, 2514, 2514, 2514, 2514, 493, 493, 493, 493, + + 523, 2514, 523, 523, 523, 523, 525, 525, 525, 2514, + 2514, 2514, 525, 2514, 2514, 2514, 2514, 525, 525, 525, + 525, 532, 532, 2514, 2514, 2514, 532, 2514, 2514, 2514, + 2514, 532, 532, 532, 532, 539, 539, 539, 2514, 2514, + 539, 2514, 2514, 2514, 2514, 539, 539, 539, 539, 551, + 551, 2514, 2514, 2514, 551, 2514, 2514, 2514, 551, 551, + 551, 551, 551, 560, 2514, 560, 560, 560, 560, 561, + 2514, 561, 2514, 561, 581, 2514, 581, 2514, 581, 606, + 606, 606, 606, 606, 606, 2514, 606, 606, 606, 606, + 606, 2514, 606, 606, 606, 606, 606, 612, 612, 612, + + 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 613, 613, 613, 613, 613, + 613, 2514, 613, 613, 613, 613, 613, 2514, 613, 613, + 613, 613, 613, 619, 619, 619, 619, 619, 619, 619, + 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, + 619, 625, 625, 625, 625, 625, 625, 625, 625, 625, + 625, 625, 625, 625, 625, 625, 625, 625, 625, 626, + 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, + 626, 626, 2514, 626, 626, 626, 626, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, 628, 628, + + 2514, 628, 628, 628, 628, 633, 633, 2514, 633, 633, + 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, + 633, 633, 633, 640, 640, 2514, 2514, 2514, 640, 2514, + 2514, 2514, 2514, 640, 640, 640, 640, 655, 2514, 655, + 655, 655, 655, 655, 660, 660, 2514, 660, 660, 660, + 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, + 660, 660, 668, 668, 2514, 668, 668, 668, 668, 668, + 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, + 675, 675, 2514, 2514, 2514, 675, 2514, 2514, 2514, 2514, + 675, 675, 675, 675, 687, 2514, 687, 687, 687, 687, + + 687, 687, 690, 690, 2514, 2514, 2514, 690, 2514, 2514, + 2514, 2514, 690, 690, 690, 690, 699, 2514, 699, 699, + 699, 699, 704, 704, 2514, 704, 704, 704, 704, 704, + 704, 704, 704, 704, 704, 704, 704, 704, 704, 704, + 711, 711, 2514, 2514, 2514, 711, 2514, 2514, 2514, 2514, + 711, 711, 711, 711, 729, 2514, 729, 729, 729, 729, + 2514, 2514, 729, 733, 733, 2514, 733, 733, 733, 733, + 733, 733, 733, 733, 733, 733, 733, 733, 733, 733, + 733, 739, 739, 2514, 739, 739, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, 739, 361, + + 361, 361, 2514, 2514, 2514, 361, 2514, 2514, 2514, 2514, + 361, 361, 361, 361, 747, 2514, 747, 747, 747, 747, + 368, 368, 2514, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 369, 369, + 2514, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 749, 749, 2514, 749, + 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, + 749, 749, 749, 749, 376, 376, 2514, 2514, 2514, 376, + 2514, 2514, 2514, 2514, 376, 376, 376, 376, 465, 2514, + 465, 465, 465, 465, 383, 383, 383, 2514, 2514, 383, + + 2514, 2514, 2514, 2514, 383, 383, 383, 383, 751, 2514, + 751, 751, 751, 751, 456, 456, 2514, 2514, 2514, 456, + 2514, 2514, 2514, 456, 456, 456, 456, 456, 843, 2514, + 843, 843, 843, 843, 469, 469, 2514, 2514, 2514, 469, + 2514, 2514, 2514, 2514, 469, 469, 469, 469, 487, 2514, + 487, 487, 487, 487, 493, 493, 2514, 493, 493, 2514, + 493, 493, 493, 2514, 2514, 2514, 2514, 493, 493, 493, + 493, 523, 2514, 523, 523, 523, 523, 525, 525, 525, + 2514, 2514, 2514, 525, 2514, 2514, 2514, 2514, 525, 525, + 525, 525, 868, 2514, 868, 868, 868, 868, 532, 532, + + 2514, 2514, 2514, 532, 2514, 2514, 2514, 2514, 532, 532, + 532, 532, 560, 2514, 560, 560, 560, 560, 539, 539, + 539, 2514, 2514, 539, 2514, 2514, 2514, 2514, 539, 539, + 539, 539, 870, 2514, 870, 870, 870, 870, 551, 551, + 2514, 2514, 2514, 551, 2514, 2514, 2514, 551, 551, 551, + 551, 551, 874, 2514, 874, 874, 874, 874, 561, 2514, + 561, 2514, 561, 581, 2514, 581, 2514, 581, 606, 606, + 606, 606, 606, 606, 2514, 606, 606, 606, 606, 606, + 2514, 606, 606, 606, 606, 606, 895, 895, 2514, 895, + 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, + + 895, 895, 895, 895, 613, 613, 613, 613, 613, 613, + 2514, 613, 613, 613, 613, 613, 2514, 613, 613, 613, + 613, 613, 899, 899, 2514, 899, 899, 899, 899, 899, + 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, + 903, 903, 2514, 903, 903, 903, 903, 903, 903, 903, + 903, 903, 903, 903, 903, 903, 903, 903, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, 626, - 626, 626, 626, 2326, 626, 626, 626, 626, 630, 630, - 2326, 630, 630, 630, 630, 630, 630, 630, 630, 630, - - 630, 630, 630, 630, 630, 630, 630, 631, 631, 2326, - 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, - 631, 631, 631, 631, 631, 631, 896, 896, 2326, 896, - 896, 896, 896, 896, 896, 896, 896, 896, 896, 896, - 896, 896, 896, 896, 896, 638, 638, 2326, 2326, 2326, - 2326, 638, 2326, 2326, 2326, 2326, 638, 638, 638, 638, - 654, 2326, 654, 654, 654, 654, 659, 659, 2326, 659, - 659, 659, 659, 659, 659, 659, 659, 659, 659, 659, - 659, 659, 659, 659, 659, 666, 666, 2326, 666, 666, - 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, - - 666, 666, 666, 666, 667, 667, 2326, 667, 667, 667, + 626, 2514, 626, 626, 626, 626, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, 628, 2514, + 628, 628, 628, 628, 632, 632, 2514, 632, 632, 632, + + 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, + 632, 632, 633, 633, 2514, 633, 633, 633, 633, 633, + 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, + 907, 907, 2514, 907, 907, 907, 907, 907, 907, 907, + 907, 907, 907, 907, 907, 907, 907, 907, 640, 640, + 2514, 2514, 2514, 640, 2514, 2514, 2514, 2514, 640, 640, + 640, 640, 655, 2514, 655, 655, 655, 655, 660, 660, + 2514, 660, 660, 660, 660, 660, 660, 660, 660, 660, + 660, 660, 660, 660, 660, 660, 667, 667, 2514, 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, - 667, 667, 667, 914, 914, 2326, 914, 914, 914, 914, - 914, 914, 914, 914, 914, 914, 914, 914, 914, 914, - 914, 914, 674, 674, 2326, 2326, 2326, 2326, 674, 2326, - 2326, 2326, 2326, 674, 674, 674, 674, 686, 2326, 686, - 686, 686, 686, 689, 689, 2326, 2326, 2326, 2326, 689, - 2326, 2326, 2326, 2326, 689, 689, 689, 689, 698, 2326, - 698, 698, 698, 698, 702, 702, 2326, 702, 702, 702, - 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, - - 702, 702, 702, 703, 703, 2326, 703, 703, 703, 703, - 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, - 703, 703, 925, 925, 2326, 925, 925, 925, 925, 925, - 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, - 925, 710, 710, 2326, 2326, 2326, 2326, 710, 2326, 2326, - 2326, 2326, 710, 710, 710, 710, 728, 2326, 728, 728, - 728, 728, 732, 732, 2326, 732, 732, 732, 732, 732, - 732, 732, 732, 732, 732, 732, 732, 732, 732, 732, - 732, 738, 738, 2326, 738, 738, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, - - 362, 362, 362, 2326, 2326, 2326, 2326, 362, 2326, 2326, - 2326, 2326, 362, 362, 362, 362, 369, 369, 2326, 369, - 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 370, 370, 2326, 370, 370, - 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, - 370, 370, 370, 370, 384, 384, 384, 2326, 2326, 2326, - 384, 2326, 2326, 2326, 2326, 384, 384, 384, 384, 953, - 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, - 953, 953, 953, 953, 953, 953, 953, 953, 377, 377, - 2326, 2326, 2326, 2326, 377, 2326, 2326, 2326, 2326, 377, - - 377, 377, 377, 455, 455, 2326, 2326, 2326, 2326, 455, - 2326, 2326, 2326, 455, 455, 455, 455, 455, 468, 468, - 2326, 2326, 2326, 2326, 468, 2326, 2326, 2326, 2326, 468, - 468, 468, 468, 492, 492, 2326, 2326, 2326, 492, 492, - 2326, 2326, 2326, 2326, 492, 492, 492, 492, 524, 524, - 524, 2326, 2326, 2326, 2326, 524, 2326, 2326, 2326, 2326, - 524, 524, 524, 524, 538, 538, 538, 2326, 2326, 2326, - 538, 2326, 2326, 2326, 2326, 538, 538, 538, 538, 531, - 531, 2326, 2326, 2326, 2326, 531, 2326, 2326, 2326, 2326, - 531, 531, 531, 531, 550, 550, 2326, 2326, 2326, 2326, - - 550, 2326, 2326, 2326, 550, 550, 550, 550, 550, 560, - 2326, 2326, 560, 2326, 560, 580, 2326, 2326, 580, 2326, - 580, 884, 884, 2326, 884, 884, 884, 884, 884, 884, - 884, 884, 884, 884, 884, 884, 884, 884, 884, 884, - 888, 888, 2326, 888, 888, 888, 888, 888, 888, 888, - 888, 888, 888, 888, 888, 888, 888, 888, 888, 892, - 892, 2326, 892, 892, 892, 892, 892, 892, 892, 892, - 892, 892, 892, 892, 892, 892, 892, 892, 630, 630, - 2326, 630, 630, 630, 630, 630, 630, 630, 630, 630, - 630, 630, 630, 630, 630, 630, 630, 631, 631, 2326, - - 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, - 631, 631, 631, 631, 631, 631, 1088, 1088, 1088, 1088, - 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, - 1088, 1088, 1088, 1088, 1088, 638, 638, 2326, 2326, 2326, - 2326, 638, 2326, 2326, 2326, 2326, 638, 638, 638, 638, - 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, - 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 666, - 666, 2326, 666, 666, 666, 666, 666, 666, 666, 666, - 666, 666, 666, 666, 666, 666, 666, 666, 667, 667, - 2326, 667, 667, 667, 667, 667, 667, 667, 667, 667, - - 667, 667, 667, 667, 667, 667, 667, 1106, 1106, 1106, - 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, - 1106, 1106, 1106, 1106, 1106, 1106, 674, 674, 2326, 2326, - 2326, 2326, 674, 2326, 2326, 2326, 2326, 674, 674, 674, - 674, 689, 689, 2326, 2326, 2326, 2326, 689, 2326, 2326, - 2326, 2326, 689, 689, 689, 689, 702, 702, 2326, 702, - 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, - 702, 702, 702, 702, 702, 703, 703, 2326, 703, 703, - 703, 703, 703, 703, 703, 703, 703, 703, 703, 703, - 703, 703, 703, 703, 1115, 1115, 1115, 1115, 1115, 1115, - 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, - 1115, 1115, 1115, 710, 710, 2326, 2326, 2326, 2326, 710, - 2326, 2326, 2326, 2326, 710, 710, 710, 710, 1128, 1128, - 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, - 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1133, 1133, 1133, - 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, - 1133, 1133, 1133, 1133, 1133, 1133, 369, 369, 2326, 369, + 667, 667, 667, 667, 668, 668, 2514, 668, 668, 668, + 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, + 668, 668, 923, 923, 2514, 923, 923, 923, 923, 923, + 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, + 675, 675, 2514, 2514, 2514, 675, 2514, 2514, 2514, 2514, + 675, 675, 675, 675, 687, 2514, 687, 687, 687, 687, + 690, 690, 2514, 2514, 2514, 690, 2514, 2514, 2514, 2514, + 690, 690, 690, 690, 699, 2514, 699, 699, 699, 699, + 703, 703, 2514, 703, 703, 703, 703, 703, 703, 703, + 703, 703, 703, 703, 703, 703, 703, 703, 704, 704, + + 2514, 704, 704, 704, 704, 704, 704, 704, 704, 704, + 704, 704, 704, 704, 704, 704, 934, 934, 2514, 934, + 934, 934, 934, 934, 934, 934, 934, 934, 934, 934, + 934, 934, 934, 934, 711, 711, 2514, 2514, 2514, 711, + 2514, 2514, 2514, 2514, 711, 711, 711, 711, 729, 2514, + 729, 729, 729, 729, 733, 733, 2514, 733, 733, 733, + 733, 733, 733, 733, 733, 733, 733, 733, 733, 733, + 733, 733, 739, 739, 2514, 739, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, 739, 739, + 361, 361, 361, 2514, 2514, 2514, 361, 2514, 2514, 2514, + + 2514, 361, 361, 361, 361, 368, 368, 2514, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 369, 369, 2514, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 953, 953, 2326, 953, 953, - 953, 953, 953, 953, 953, 953, 953, 953, 953, 953, - - 953, 953, 953, 953, 377, 377, 2326, 2326, 2326, 2326, - 377, 2326, 2326, 2326, 2326, 377, 377, 377, 377, 468, - 468, 2326, 2326, 2326, 2326, 468, 2326, 2326, 2326, 2326, - 468, 468, 468, 468, 492, 492, 2326, 2326, 2326, 492, - 492, 492, 2326, 2326, 2326, 492, 492, 492, 492, 531, - 531, 2326, 2326, 2326, 2326, 531, 2326, 2326, 2326, 2326, - 531, 531, 531, 531, 560, 2326, 2326, 560, 2326, 560, - 580, 2326, 2326, 580, 2326, 580, 1254, 1254, 1254, 1254, - 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, - 1254, 1254, 1254, 1254, 1254, 1258, 1258, 1258, 1258, 1258, - - 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, - 1258, 1258, 1258, 1258, 1262, 1262, 1262, 1262, 1262, 1262, - 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, - 1262, 1262, 1262, 630, 630, 2326, 630, 630, 630, 630, - 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, - 630, 630, 1088, 1088, 2326, 1088, 1088, 1088, 1088, 1088, - 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, - 1088, 638, 638, 2326, 2326, 2326, 2326, 638, 2326, 2326, - 2326, 2326, 638, 638, 638, 638, 1101, 1101, 2326, 1101, - 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, 1101, - - 1101, 1101, 1101, 1101, 1101, 666, 666, 2326, 666, 666, - 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, - 666, 666, 666, 666, 1106, 1106, 2326, 1106, 1106, 1106, - 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, - 1106, 1106, 1106, 674, 674, 2326, 2326, 2326, 2326, 674, - 2326, 2326, 2326, 2326, 674, 674, 674, 674, 689, 689, - 2326, 2326, 2326, 2326, 689, 2326, 2326, 2326, 2326, 689, - 689, 689, 689, 702, 702, 2326, 702, 702, 702, 702, - 702, 702, 702, 702, 702, 702, 702, 702, 702, 702, - 702, 702, 1115, 1115, 2326, 1115, 1115, 1115, 1115, 1115, - - 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, - 1115, 710, 710, 2326, 2326, 2326, 2326, 710, 2326, 2326, - 2326, 2326, 710, 710, 710, 710, 1128, 1128, 2326, 1128, - 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, - 1128, 1128, 1128, 1128, 1128, 1133, 1133, 2326, 1133, 1133, + 369, 383, 383, 383, 2514, 2514, 383, 2514, 2514, 2514, + 2514, 383, 383, 383, 383, 964, 964, 964, 964, 964, + 964, 964, 964, 964, 964, 964, 964, 964, 964, 964, + 964, 964, 964, 376, 376, 2514, 2514, 376, 376, 2514, + 2514, 2514, 2514, 376, 376, 376, 376, 456, 456, 2514, + 2514, 2514, 456, 2514, 2514, 2514, 456, 456, 456, 456, + + 456, 469, 469, 2514, 2514, 2514, 469, 2514, 2514, 2514, + 2514, 469, 469, 469, 469, 493, 493, 2514, 2514, 493, + 493, 2514, 2514, 2514, 2514, 493, 493, 493, 493, 525, + 525, 525, 2514, 2514, 2514, 525, 2514, 2514, 2514, 2514, + 525, 525, 525, 525, 539, 539, 539, 2514, 2514, 539, + 2514, 2514, 2514, 2514, 539, 539, 539, 539, 532, 532, + 2514, 2514, 2514, 532, 2514, 2514, 2514, 2514, 532, 532, + 532, 532, 551, 551, 2514, 2514, 2514, 551, 2514, 2514, + 2514, 551, 551, 551, 551, 551, 561, 2514, 561, 2514, + 561, 581, 2514, 581, 2514, 581, 895, 895, 2514, 895, + + 895, 895, 895, 895, 895, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 899, 899, 2514, 899, 899, 899, + 899, 899, 899, 899, 899, 899, 899, 899, 899, 899, + 899, 899, 903, 903, 2514, 903, 903, 903, 903, 903, + 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, + 632, 632, 2514, 632, 632, 632, 632, 632, 632, 632, + 632, 632, 632, 632, 632, 632, 632, 632, 633, 633, + 2514, 633, 633, 633, 633, 633, 633, 633, 633, 633, + 633, 633, 633, 633, 633, 633, 1107, 1107, 1107, 1107, + 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, + + 1107, 1107, 1107, 1107, 640, 640, 2514, 2514, 2514, 640, + 2514, 2514, 2514, 2514, 640, 640, 640, 640, 1118, 1118, + 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, + 1118, 1118, 1118, 1118, 1118, 1118, 667, 667, 2514, 667, + 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, + 667, 667, 667, 667, 668, 668, 2514, 668, 668, 668, + 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, + 668, 668, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + 675, 675, 2514, 2514, 2514, 675, 2514, 2514, 2514, 2514, + + 675, 675, 675, 675, 690, 690, 2514, 2514, 2514, 690, + 2514, 2514, 2514, 2514, 690, 690, 690, 690, 703, 703, + 2514, 703, 703, 703, 703, 703, 703, 703, 703, 703, + 703, 703, 703, 703, 703, 703, 704, 704, 2514, 704, + 704, 704, 704, 704, 704, 704, 704, 704, 704, 704, + 704, 704, 704, 704, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, - 1133, 1133, 1133, 1133, 377, 377, 2326, 377, 377, 2326, - 2326, 2326, 2326, 377, 2326, 2326, 2326, 2326, 377, 377, - 377, 377, 468, 468, 2326, 2326, 2326, 2326, 468, 2326, - 2326, 2326, 2326, 468, 468, 468, 468, 492, 492, 2326, - - 2326, 2326, 492, 492, 2326, 2326, 2326, 2326, 492, 492, - 492, 492, 531, 531, 2326, 2326, 2326, 2326, 531, 2326, - 2326, 2326, 2326, 531, 531, 531, 531, 560, 2326, 2326, - 560, 2326, 560, 580, 2326, 2326, 580, 2326, 580, 1254, - 1254, 2326, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, - 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1258, 1258, - 2326, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1258, - 1258, 1258, 1258, 1258, 1258, 1258, 1258, 1262, 1262, 2326, - 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, - 1262, 1262, 1262, 1262, 1262, 1262, 638, 638, 2326, 2326, - - 2326, 2326, 638, 2326, 2326, 2326, 2326, 638, 638, 638, - 638, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, - 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, - 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, - 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1540, 1572, - 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, - 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1654, 1654, - 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, - 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1673, 1673, 1673, - 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, 1673, - - 1673, 1673, 1673, 1673, 1673, 1673, 1680, 1680, 1680, 1680, - 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, 1680, - 1680, 1680, 1680, 1680, 1680, 1699, 1699, 1699, 1699, 1699, - 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, 1699, - 1699, 1699, 1699, 1699, 1728, 1728, 1728, 1728, 1728, 1728, - 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, - 1728, 1728, 1728, 1750, 1750, 1750, 1750, 1750, 1750, 1750, - 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, - 1750, 1750, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, - 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, - - 1796, 57, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326 - + 1133, 1133, 711, 711, 2514, 2514, 711, 711, 2514, 2514, + 2514, 2514, 711, 711, 711, 711, 1145, 1145, 1145, 1145, + 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, + + 1145, 1145, 1145, 1145, 1150, 1150, 1150, 1150, 1150, 1150, + 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, + 1150, 1150, 368, 368, 2514, 368, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 964, 964, 2514, 964, 964, 964, 964, 964, 964, 964, + 964, 964, 964, 964, 964, 964, 964, 964, 376, 376, + 2514, 2514, 376, 376, 2514, 2514, 2514, 2514, 376, 376, + 376, 376, 469, 469, 2514, 2514, 2514, 469, 2514, 2514, + 2514, 2514, 469, 469, 469, 469, 493, 493, 2514, 2514, + 493, 493, 493, 2514, 2514, 2514, 493, 493, 493, 493, + + 532, 532, 2514, 2514, 2514, 532, 2514, 2514, 2514, 2514, + 532, 532, 532, 532, 561, 2514, 561, 2514, 561, 581, + 2514, 581, 2514, 581, 1280, 1280, 1280, 1280, 1280, 1280, + 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, + 1280, 1280, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, + 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, + 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, + 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 632, 632, + 2514, 632, 632, 632, 632, 632, 632, 632, 632, 632, + 632, 632, 632, 632, 632, 632, 1107, 1107, 2514, 1107, + + 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, + 1107, 1107, 1107, 1107, 640, 640, 2514, 2514, 2514, 640, + 2514, 2514, 2514, 2514, 640, 640, 640, 640, 1118, 1118, + 2514, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, + 1118, 1118, 1118, 1118, 1118, 1118, 667, 667, 2514, 667, + 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, + 667, 667, 667, 667, 1123, 1123, 2514, 1123, 1123, 1123, + 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + 1123, 1123, 675, 675, 2514, 2514, 2514, 675, 2514, 2514, + 2514, 2514, 675, 675, 675, 675, 690, 690, 2514, 2514, + + 2514, 690, 2514, 2514, 2514, 2514, 690, 690, 690, 690, + 703, 703, 2514, 703, 703, 703, 703, 703, 703, 703, + 703, 703, 703, 703, 703, 703, 703, 703, 1133, 1133, + 2514, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, 1133, + 1133, 1133, 1133, 1133, 1133, 1133, 711, 711, 2514, 2514, + 711, 711, 2514, 2514, 2514, 2514, 711, 711, 711, 711, + 1145, 1145, 2514, 1145, 1145, 1145, 1145, 1145, 1145, 1145, + 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1150, 1150, + 2514, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1150, + 1150, 1150, 1150, 1150, 1150, 1150, 376, 376, 2514, 2514, + + 376, 376, 2514, 2514, 2514, 2514, 376, 376, 376, 376, + 469, 469, 2514, 2514, 2514, 469, 2514, 2514, 2514, 2514, + 469, 469, 469, 469, 493, 493, 2514, 2514, 493, 493, + 2514, 2514, 2514, 2514, 493, 493, 493, 493, 532, 532, + 2514, 2514, 2514, 532, 2514, 2514, 2514, 2514, 532, 532, + 532, 532, 561, 2514, 561, 2514, 561, 581, 2514, 581, + 2514, 581, 1280, 1280, 2514, 1280, 1280, 1280, 1280, 1280, + 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, + 1284, 1284, 2514, 1284, 1284, 1284, 1284, 1284, 1284, 1284, + 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1288, 1288, + + 2514, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, 1288, + 1288, 1288, 1288, 1288, 1288, 1288, 640, 640, 2514, 2514, + 2514, 640, 2514, 2514, 2514, 2514, 640, 640, 640, 640, + 675, 675, 2514, 2514, 2514, 675, 2514, 2514, 2514, 2514, + 675, 675, 675, 675, 1440, 1440, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, + 1440, 1440, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, + 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, 1589, + 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, + 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1624, 1714, 1714, + + 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, 1714, + 1714, 1714, 1714, 1714, 1714, 1714, 1736, 1736, 1736, 1736, + 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, 1736, + 1736, 1736, 1736, 1736, 1743, 1743, 1743, 1743, 1743, 1743, + 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, 1743, + 1743, 1743, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, + 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, 1764, + 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, + 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1797, 1822, 1822, + 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, 1822, + + 1822, 1822, 1822, 1822, 1822, 1822, 1872, 1872, 1872, 1872, + 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, 1872, + 1872, 1872, 1872, 1872, 59, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514 } ; -static yyconst flex_int16_t yy_chk[15696] = +static yyconst flex_int16_t yy_chk[15718] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -2966,7 +3031,7 @@ static yyconst flex_int16_t yy_chk[15696] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, + 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, @@ -2976,8 +3041,8 @@ static yyconst flex_int16_t yy_chk[15696] = 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 5, 6, 67, 67, - 69, 70, 70, 69, 69, 5, 6, 7, 7, 7, + 3, 3, 3, 3, 5, 6, 71, 71, 2493, 71, + 232, 232, 2487, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, @@ -2987,7 +3052,7 @@ static yyconst flex_int16_t yy_chk[15696] = 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -2997,8 +3062,8 @@ static yyconst flex_int16_t yy_chk[15696] = 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 11, 11, 11, 11, 11, 11, 11, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, @@ -3008,44 +3073,43 @@ static yyconst flex_int16_t yy_chk[15696] = 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 13, 13, 13, 27, - 14, 14, 14, 13, 28, 29, 13, 14, 13, 30, - 14, 31, 14, 15, 15, 15, 32, 16, 16, 16, - - 15, 39, 40, 15, 16, 15, 47, 16, 48, 16, - 103, 103, 108, 55, 109, 109, 131, 108, 56, 122, - 122, 55, 27, 134, 39, 40, 56, 28, 29, 125, - 55, 2311, 30, 2293, 125, 56, 47, 31, 48, 135, - 130, 136, 32, 137, 55, 130, 2286, 131, 151, 56, - 144, 144, 55, 151, 134, 39, 40, 56, 13, 2285, - 13, 55, 14, 166, 14, 2283, 56, 47, 166, 48, - 135, 183, 136, 191, 137, 15, 183, 15, 191, 16, - 2282, 16, 19, 19, 19, 19, 19, 19, 19, 19, + 11, 13, 13, 13, 27, 14, 14, 14, 13, 28, + 29, 13, 14, 13, 30, 14, 31, 14, 15, 15, + 15, 32, 16, 16, 16, 15, 39, 40, 15, 16, + + 15, 47, 16, 48, 16, 110, 127, 57, 132, 133, + 110, 127, 58, 132, 136, 57, 27, 137, 39, 40, + 58, 28, 29, 77, 57, 77, 30, 2472, 138, 58, + 47, 31, 48, 139, 140, 77, 32, 141, 57, 77, + 133, 174, 153, 58, 2464, 136, 57, 153, 137, 39, + 40, 58, 13, 2463, 13, 57, 14, 168, 14, 138, + 58, 47, 168, 48, 139, 140, 77, 2461, 141, 15, + 77, 15, 174, 16, 2460, 16, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 21, 21, 21, 22, 22, - 22, 138, 85, 21, 85, 85, 22, 23, 23, 23, - 146, 146, 23, 139, 23, 85, 23, 23, 24, 24, - - 24, 158, 158, 24, 1257, 24, 1261, 24, 24, 25, - 25, 25, 138, 2182, 25, 2279, 25, 25, 25, 25, - 26, 26, 26, 172, 139, 26, 85, 26, 26, 26, - 26, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 77, 173, 77, 77, 160, 160, 75, 2245, - 75, 75, 174, 175, 172, 77, 205, 21, 206, 21, - 22, 75, 22, 197, 197, 75, 268, 200, 77, 23, - 2243, 23, 200, 2233, 173, 210, 210, 2224, 210, 1257, - 24, 1261, 24, 174, 175, 221, 77, 205, 2182, 206, - 221, 25, 75, 25, 197, 197, 75, 268, 228, 77, - - 230, 230, 26, 228, 26, 37, 37, 37, 37, 37, + 19, 19, 19, 19, 19, 19, 19, 19, 21, 21, + 21, 22, 22, 22, 175, 122, 21, 176, 185, 22, + 23, 23, 23, 185, 2457, 23, 103, 23, 177, 23, + 23, 24, 24, 24, 193, 2455, 24, 334, 24, 193, + + 24, 24, 25, 25, 25, 175, 2442, 25, 176, 25, + 25, 25, 25, 26, 26, 26, 2439, 265, 26, 177, + 26, 26, 26, 26, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 79, 87, 79, 87, 199, + 199, 85, 207, 85, 122, 122, 208, 79, 87, 21, + 269, 21, 22, 85, 22, 103, 103, 85, 103, 202, + 79, 23, 223, 23, 202, 212, 212, 223, 212, 334, + 199, 199, 24, 207, 24, 230, 2435, 208, 79, 87, + 230, 269, 476, 25, 85, 25, 265, 476, 85, 281, + 281, 79, 323, 323, 26, 323, 26, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, @@ -3054,21 +3118,20 @@ static yyconst flex_int16_t yy_chk[15696] = 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 41, 41, - - 41, 2145, 41, 41, 2214, 41, 41, 41, 59, 59, - 59, 41, 42, 42, 42, 259, 42, 42, 259, 42, - 42, 42, 101, 101, 76, 42, 76, 76, 78, 2187, - 78, 78, 79, 76, 79, 79, 278, 76, 207, 41, - 208, 78, 312, 207, 344, 79, 259, 76, 345, 259, - 76, 2186, 79, 42, 78, 79, 353, 208, 79, 2183, - 78, 266, 266, 2151, 76, 280, 280, 278, 76, 207, - 41, 208, 78, 312, 207, 344, 79, 2145, 76, 345, - 41, 76, 41, 79, 42, 78, 79, 353, 208, 79, - 59, 78, 101, 101, 42, 101, 42, 43, 43, 43, - - 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 41, + 41, 41, 260, 41, 41, 260, 41, 41, 41, 61, + + 61, 61, 41, 42, 42, 42, 1291, 42, 42, 298, + 42, 42, 42, 78, 490, 78, 42, 210, 279, 490, + 80, 78, 80, 260, 313, 78, 260, 343, 83, 41, + 83, 344, 80, 142, 210, 78, 83, 142, 78, 2423, + 83, 2420, 352, 42, 83, 80, 142, 2409, 210, 279, + 142, 80, 78, 2407, 353, 313, 78, 2396, 343, 2393, + 41, 2392, 344, 80, 142, 210, 78, 83, 142, 78, + 41, 83, 41, 352, 42, 83, 80, 142, 298, 298, + 61, 142, 80, 1291, 42, 353, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, @@ -3076,9 +3139,10 @@ static yyconst flex_int16_t yy_chk[15696] = 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, @@ -3086,1604 +3150,1607 @@ static yyconst flex_int16_t yy_chk[15696] = 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 49, 49, 49, 49, 49, 49, 49, + 45, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 51, 51, 51, 264, - 264, 51, 2144, 52, 52, 52, 299, 299, 52, 51, - 60, 60, 60, 308, 308, 51, 52, 2143, 245, 245, - - 245, 354, 52, 2128, 51, 53, 53, 53, 310, 310, - 53, 52, 54, 54, 54, 320, 320, 54, 53, 62, - 356, 51, 120, 120, 53, 54, 322, 2107, 52, 322, - 322, 54, 354, 53, 80, 51, 80, 80, 2103, 53, - 54, 94, 52, 94, 94, 2099, 54, 80, 2090, 264, - 94, 356, 51, 357, 94, 323, 323, 65, 51, 52, - 80, 246, 246, 246, 53, 52, 83, 2088, 83, 83, - 53, 54, 60, 2054, 270, 270, 270, 54, 80, 83, - 245, 94, 358, 83, 357, 94, 2049, 53, 271, 271, - 271, 80, 120, 120, 54, 2047, 62, 62, 62, 62, - - 62, 62, 62, 62, 62, 62, 62, 63, 63, 1265, - 83, 63, 63, 358, 83, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 337, 337, 63, 63, 63, 63, - 63, 65, 65, 65, 65, 65, 65, 65, 65, 65, - 65, 65, 96, 246, 96, 96, 282, 282, 282, 366, - 366, 96, 283, 283, 283, 96, 270, 63, 63, 63, - 475, 63, 335, 335, 81, 475, 81, 81, 368, 368, - 271, 489, 89, 81, 89, 89, 489, 81, 376, 376, - 495, 81, 96, 381, 381, 89, 96, 1265, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - - 72, 89, 72, 72, 81, 383, 383, 82, 81, 82, - 82, 495, 81, 72, 389, 389, 89, 391, 391, 82, - 82, 2041, 82, 496, 257, 392, 392, 257, 282, 82, - 257, 2031, 89, 508, 283, 335, 460, 460, 508, 84, - 2028, 84, 84, 2022, 72, 462, 462, 2019, 84, 2017, - 82, 82, 84, 82, 496, 257, 84, 1990, 257, 497, - 82, 257, 84, 297, 297, 472, 472, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 74, 84, - 74, 74, 87, 84, 87, 87, 86, 84, 86, 86, - 497, 74, 87, 84, 498, 87, 87, 1988, 74, 86, - - 74, 314, 314, 314, 87, 74, 74, 74, 87, 86, - 1982, 315, 315, 315, 1980, 88, 499, 88, 88, 474, - 474, 1977, 74, 87, 88, 498, 87, 87, 88, 74, - 86, 74, 88, 297, 297, 87, 74, 74, 74, 87, - 86, 88, 510, 90, 88, 90, 90, 499, 91, 546, - 91, 91, 477, 477, 546, 88, 90, 504, 504, 88, - 1972, 91, 1968, 88, 91, 92, 90, 92, 92, 511, - 91, 512, 88, 510, 92, 88, 91, 328, 92, 328, - 328, 92, 1953, 314, 506, 506, 93, 90, 93, 93, - 328, 92, 91, 315, 513, 91, 514, 90, 515, 93, - - 511, 91, 512, 528, 528, 92, 328, 91, 93, 92, - 93, 516, 92, 93, 1941, 95, 517, 95, 95, 530, - 530, 328, 92, 518, 95, 513, 519, 514, 95, 515, - 93, 95, 95, 561, 98, 98, 97, 328, 561, 93, - 1929, 93, 516, 1904, 93, 98, 98, 517, 238, 238, - 238, 98, 238, 238, 518, 95, 1902, 519, 520, 95, - 1893, 238, 95, 95, 97, 97, 97, 97, 97, 97, - 97, 97, 97, 97, 97, 99, 99, 563, 98, 98, - 98, 1888, 98, 100, 100, 1878, 99, 99, 1874, 520, - 102, 102, 99, 564, 100, 100, 1870, 339, 339, 339, - - 100, 102, 102, 110, 110, 535, 535, 102, 563, 98, - 537, 537, 329, 573, 329, 329, 543, 543, 573, 99, - 99, 99, 1851, 99, 564, 329, 565, 100, 100, 100, - 238, 100, 329, 566, 102, 102, 102, 1836, 102, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 99, 111, 99, 340, 340, 340, 329, 565, 100, 112, - 545, 545, 1824, 329, 566, 102, 555, 555, 110, 110, - 110, 110, 110, 110, 110, 110, 110, 110, 110, 339, - 557, 557, 111, 1814, 113, 114, 567, 348, 348, 348, - 112, 1805, 111, 111, 111, 111, 111, 111, 111, 111, - - 111, 111, 111, 568, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 113, 114, 567, 1793, 115, - 116, 1787, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 577, 568, 340, 637, 637, 577, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 115, 116, 349, 349, 349, 1780, 569, 1745, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 348, - 642, 642, 644, 644, 116, 116, 116, 116, 116, 116, - 116, 116, 116, 116, 116, 117, 117, 569, 330, 1693, - 330, 330, 118, 118, 570, 1690, 117, 117, 1653, 119, - - 119, 330, 117, 118, 118, 1638, 121, 121, 1628, 118, - 119, 119, 359, 359, 359, 1613, 119, 121, 121, 583, - 148, 1589, 140, 121, 583, 570, 140, 581, 1587, 117, - 117, 117, 330, 117, 349, 140, 118, 118, 118, 140, - 118, 582, 176, 119, 119, 119, 176, 119, 585, 586, - 121, 121, 121, 140, 121, 176, 587, 140, 581, 176, - 117, 588, 393, 393, 393, 1585, 140, 118, 1578, 118, - 140, 597, 582, 176, 119, 1566, 597, 176, 1559, 585, - 586, 121, 127, 127, 127, 589, 176, 587, 590, 1544, - 176, 1542, 588, 127, 359, 127, 127, 148, 148, 148, - - 148, 148, 148, 148, 148, 148, 148, 148, 127, 127, - 1538, 127, 394, 394, 1515, 150, 589, 656, 1498, 590, - 127, 1469, 127, 394, 127, 149, 149, 149, 149, 149, - 149, 149, 149, 149, 149, 149, 232, 232, 232, 127, - 127, 232, 127, 232, 393, 235, 235, 235, 656, 232, - 235, 127, 235, 127, 394, 127, 601, 1573, 235, 673, - 673, 601, 1573, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 128, 128, 128, 1456, 661, 678, - 678, 680, 680, 693, 693, 128, 1450, 128, 128, 150, + 49, 49, 49, 51, 51, 51, 1496, 1496, 51, 509, + 52, 52, 52, 2390, 509, 52, 51, 62, 62, 62, + 2379, 51, 355, 52, 247, 247, 247, 2369, 52, 356, + 51, 55, 55, 55, 1612, 1612, 55, 52, 56, 56, + + 56, 2274, 178, 56, 55, 64, 178, 51, 357, 55, + 81, 56, 81, 355, 52, 178, 56, 496, 55, 178, + 356, 51, 81, 2359, 55, 56, 259, 2356, 52, 81, + 497, 56, 81, 178, 2350, 81, 547, 178, 51, 357, + 259, 547, 67, 259, 51, 52, 178, 498, 496, 55, + 178, 52, 329, 81, 329, 55, 56, 259, 62, 2329, + 81, 497, 56, 81, 329, 247, 81, 248, 248, 248, + 562, 259, 55, 2328, 259, 562, 2274, 1283, 498, 56, + 2325, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 65, 65, 574, 329, 65, 65, 2315, 574, + + 65, 65, 65, 65, 65, 65, 65, 65, 65, 2312, + 65, 65, 65, 65, 65, 67, 67, 67, 67, 67, + 67, 67, 67, 67, 67, 67, 578, 96, 98, 96, + 98, 578, 584, 599, 499, 96, 98, 584, 599, 96, + 98, 65, 65, 65, 82, 65, 82, 84, 248, 84, + 603, 1283, 1287, 2304, 258, 603, 82, 258, 84, 84, + 258, 84, 271, 271, 271, 499, 96, 98, 84, 82, + 96, 98, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 74, 258, 74, 82, 258, 84, + 84, 258, 84, 86, 2280, 86, 74, 395, 397, 84, + + 82, 86, 272, 272, 272, 86, 500, 395, 397, 86, + 2273, 234, 234, 234, 2272, 86, 234, 511, 234, 88, + 2263, 88, 2260, 92, 234, 92, 1287, 74, 1619, 1619, + 2248, 88, 86, 512, 2247, 92, 86, 500, 395, 397, + 86, 88, 1625, 271, 513, 92, 86, 1625, 511, 2222, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 76, 88, 76, 512, 89, 92, 89, 514, 91, + 515, 91, 88, 76, 89, 513, 92, 89, 89, 2218, + 76, 91, 76, 272, 516, 517, 89, 76, 76, 76, + 89, 394, 234, 394, 519, 2214, 520, 91, 90, 514, + + 90, 515, 1737, 394, 76, 89, 90, 1737, 89, 89, + 90, 76, 91, 76, 90, 516, 517, 89, 76, 76, + 76, 89, 521, 90, 518, 519, 90, 520, 91, 564, + 1744, 93, 565, 93, 394, 1744, 94, 90, 94, 2204, + 518, 90, 2202, 93, 94, 90, 93, 95, 94, 95, + 566, 94, 93, 521, 90, 518, 2196, 90, 93, 95, + 564, 94, 567, 565, 402, 2193, 402, 1765, 95, 569, + 95, 518, 1765, 95, 93, 94, 402, 93, 2180, 94, + 2154, 566, 94, 93, 99, 1624, 1624, 100, 100, 93, + 95, 2149, 94, 567, 97, 568, 97, 2147, 100, 95, + + 569, 95, 97, 100, 95, 2141, 97, 402, 570, 97, + 97, 568, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 283, 283, 283, 568, 101, 101, 2139, + 100, 100, 100, 97, 100, 102, 102, 97, 101, 570, + 97, 97, 568, 101, 104, 104, 102, 399, 2127, 399, + 399, 102, 399, 571, 582, 104, 1640, 1640, 2124, 209, + 104, 100, 399, 405, 209, 405, 112, 1671, 1671, 2119, + 101, 101, 101, 2109, 101, 405, 209, 405, 102, 102, + 102, 756, 102, 756, 571, 582, 756, 104, 104, 104, + 209, 104, 757, 399, 757, 209, 2091, 757, 284, 284, + + 284, 101, 2086, 101, 283, 2084, 405, 209, 405, 102, + 113, 315, 315, 315, 316, 316, 316, 114, 104, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 113, 115, 116, 583, 586, 1736, 1736, 114, 1743, + 1743, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 115, 116, 583, 586, 117, 118, 284, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 2081, 315, 1758, 1758, 316, 587, 116, 116, 116, + + 116, 116, 116, 116, 116, 116, 116, 116, 117, 118, + 338, 338, 338, 2079, 588, 2074, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 587, 339, 339, + 339, 2072, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 119, 119, 588, 409, 2069, 409, 120, + 120, 347, 347, 347, 119, 121, 121, 2064, 409, 119, + 120, 123, 123, 2059, 589, 120, 121, 157, 157, 2044, + 590, 121, 123, 348, 348, 348, 591, 123, 157, 358, + 358, 358, 592, 157, 648, 648, 119, 119, 119, 409, + 119, 338, 120, 120, 120, 589, 120, 2041, 121, 121, + + 121, 590, 121, 150, 123, 123, 123, 591, 123, 339, + 157, 157, 157, 592, 157, 648, 648, 119, 1764, 1764, + 2035, 657, 406, 120, 406, 120, 237, 237, 237, 121, + 2022, 237, 347, 237, 406, 123, 129, 129, 129, 237, + 662, 157, 2020, 406, 1991, 700, 1989, 129, 1980, 129, + 129, 401, 657, 401, 348, 1974, 158, 158, 1963, 401, + 358, 129, 129, 401, 129, 406, 735, 158, 392, 392, + 392, 662, 158, 129, 406, 129, 700, 129, 736, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, - - 128, 128, 699, 128, 734, 258, 396, 396, 401, 661, - 401, 401, 128, 735, 128, 740, 128, 396, 232, 258, - 741, 401, 258, 152, 695, 695, 404, 235, 404, 404, - 1440, 128, 128, 699, 128, 734, 258, 1674, 153, 404, - 742, 404, 1674, 128, 735, 128, 740, 128, 396, 1430, - 258, 741, 401, 258, 152, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 129, 129, 129, 153, - 404, 742, 404, 709, 709, 714, 714, 129, 1411, 129, - 129, 152, 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 154, 716, 716, 1403, 153, 153, 153, 153, - - 153, 153, 153, 153, 153, 153, 153, 249, 249, 249, - 249, 249, 249, 249, 249, 249, 249, 249, 717, 717, - 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, - 154, 286, 286, 286, 286, 286, 286, 286, 286, 286, - 286, 286, 756, 756, 838, 838, 1356, 129, 129, 129, - 129, 129, 129, 129, 129, 129, 129, 129, 141, 141, - 141, 845, 845, 141, 141, 1681, 605, 605, 605, 141, - 1681, 141, 141, 605, 141, 141, 155, 155, 1344, 406, - 141, 406, 406, 156, 156, 1342, 723, 155, 155, 857, - 857, 1327, 406, 155, 156, 156, 612, 612, 612, 406, - - 156, 157, 157, 612, 723, 866, 866, 141, 141, 141, - 1320, 141, 157, 157, 628, 628, 628, 723, 157, 1316, - 155, 155, 155, 406, 155, 159, 159, 156, 156, 156, - 406, 156, 719, 719, 1273, 723, 159, 159, 141, 908, - 908, 255, 159, 719, 743, 157, 157, 157, 605, 157, - 398, 155, 398, 398, 1700, 398, 398, 1264, 156, 1700, - 156, 920, 920, 618, 618, 618, 398, 618, 1262, 159, - 159, 159, 255, 159, 719, 743, 157, 744, 612, 255, - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 400, 1260, 400, 400, 922, 922, 628, 398, 292, 400, - - 159, 248, 248, 400, 867, 248, 248, 1258, 744, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 931, 931, - 248, 248, 248, 248, 248, 261, 261, 938, 938, 292, - 400, 1256, 262, 262, 400, 867, 261, 261, 645, 645, - 645, 868, 261, 262, 262, 618, 950, 950, 1254, 262, - 848, 248, 248, 248, 1252, 248, 292, 292, 292, 292, - 292, 292, 292, 292, 292, 292, 292, 852, 848, 261, - 261, 261, 868, 261, 850, 1248, 262, 262, 262, 850, - 262, 848, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 256, 869, 852, 256, 852, 848, - - 261, 657, 657, 657, 2281, 263, 263, 262, 1246, 262, - 850, 1243, 265, 265, 951, 951, 263, 263, 952, 952, - 645, 291, 263, 265, 265, 256, 869, 1241, 256, 265, - 753, 1202, 753, 855, 1135, 753, 753, 1130, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 263, - 263, 263, 291, 263, 956, 956, 265, 265, 265, 871, - 265, 1117, 855, 1108, 855, 291, 291, 291, 291, 291, - 291, 291, 291, 291, 291, 291, 660, 660, 660, 2281, - 263, 293, 1103, 657, 664, 664, 664, 265, 285, 285, - 871, 1093, 285, 285, 720, 720, 285, 285, 285, 285, - - 285, 285, 285, 285, 285, 720, 872, 285, 285, 285, - 285, 285, 293, 301, 301, 301, 301, 301, 301, 301, - 301, 301, 301, 301, 1090, 293, 293, 293, 293, 293, - 293, 293, 293, 293, 293, 293, 720, 872, 285, 285, - 285, 1086, 285, 294, 294, 1084, 408, 1082, 408, 408, - 295, 295, 957, 957, 294, 294, 958, 958, 660, 408, - 294, 295, 295, 959, 959, 1077, 664, 295, 955, 285, - 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, - 285, 856, 874, 856, 681, 681, 681, 294, 294, 294, - 408, 294, 296, 296, 295, 295, 295, 875, 295, 298, - - 298, 960, 960, 296, 296, 944, 754, 754, 304, 296, - 298, 298, 856, 874, 856, 646, 298, 754, 294, 403, - 940, 403, 403, 927, 755, 295, 755, 295, 875, 755, - 755, 403, 403, 646, 646, 916, 296, 296, 296, 304, - 296, 911, 876, 298, 298, 298, 646, 298, 754, 304, - 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, - 305, 305, 403, 403, 646, 646, 681, 296, 306, 306, - 898, 305, 305, 876, 298, 307, 307, 305, 877, 306, - 306, 893, 309, 309, 878, 306, 307, 307, 405, 892, - 405, 405, 307, 309, 309, 1042, 1042, 1060, 1060, 309, - - 889, 405, 1061, 1061, 305, 305, 305, 888, 305, 877, - 405, 879, 306, 306, 306, 878, 306, 362, 880, 307, - 307, 307, 885, 307, 768, 881, 309, 309, 309, 768, - 309, 435, 405, 435, 435, 305, 1064, 1064, 700, 700, - 700, 405, 879, 306, 435, 306, 718, 718, 718, 880, - 307, 884, 730, 730, 730, 768, 881, 309, 317, 317, - 768, 873, 317, 317, 1087, 1087, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 435, 870, 317, 317, 317, - 317, 317, 318, 318, 318, 318, 318, 318, 318, 318, - 318, 318, 318, 752, 362, 362, 362, 362, 362, 362, - - 362, 362, 362, 362, 362, 733, 733, 733, 317, 317, - 317, 737, 317, 332, 332, 731, 452, 705, 452, 452, - 700, 333, 333, 701, 332, 332, 1105, 1105, 718, 452, - 332, 669, 333, 333, 730, 1114, 1114, 882, 333, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 324, 851, 324, 324, 1118, 1118, 332, 332, 332, - 452, 332, 334, 334, 324, 333, 333, 333, 882, 333, - 1729, 851, 665, 334, 334, 1729, 736, 736, 736, 334, - 739, 739, 739, 851, 751, 751, 751, 733, 332, 1797, - 411, 658, 411, 411, 1797, 324, 333, 633, 333, 778, - - 336, 336, 851, 411, 778, 899, 334, 334, 334, 629, - 334, 336, 336, 886, 886, 886, 411, 336, 324, 324, - 324, 324, 324, 324, 324, 324, 324, 324, 324, 402, - 778, 402, 402, 622, 411, 778, 899, 334, 363, 363, - 363, 621, 402, 849, 336, 336, 336, 411, 336, 620, - 363, 363, 364, 364, 364, 616, 363, 402, 736, 365, - 365, 365, 739, 849, 364, 364, 751, 1119, 1119, 615, - 364, 365, 365, 402, 849, 336, 613, 365, 367, 367, - 367, 779, 609, 363, 363, 363, 779, 363, 402, 853, - 367, 367, 1120, 1120, 849, 886, 367, 364, 364, 364, - - 853, 364, 1121, 1121, 365, 365, 365, 384, 365, 1122, - 1122, 608, 779, 413, 363, 413, 413, 779, 606, 900, - 853, 507, 413, 367, 367, 367, 413, 367, 364, 502, - 364, 853, 890, 890, 890, 365, 377, 377, 377, 377, - 377, 377, 377, 377, 377, 377, 377, 372, 901, 410, - 900, 410, 410, 413, 367, 370, 370, 413, 360, 370, - 370, 355, 410, 370, 370, 370, 370, 370, 370, 370, - 370, 370, 410, 909, 370, 370, 370, 370, 370, 901, - 912, 384, 384, 384, 384, 384, 384, 384, 384, 384, - 384, 384, 455, 410, 1457, 1457, 928, 351, 928, 346, - - 854, 928, 928, 410, 909, 370, 370, 370, 342, 370, - 327, 912, 1560, 1560, 890, 290, 894, 894, 894, 854, - 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, - 455, 854, 897, 897, 897, 279, 370, 370, 370, 370, - 370, 370, 370, 370, 370, 370, 370, 370, 371, 371, - 854, 277, 371, 371, 371, 371, 371, 371, 371, 371, - 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, - 371, 374, 374, 923, 254, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 378, 378, 252, 418, 894, 418, - - 418, 379, 379, 243, 923, 378, 378, 241, 380, 380, - 418, 378, 379, 379, 897, 1567, 1567, 418, 379, 380, - 380, 1572, 1572, 229, 420, 380, 420, 420, 1586, 1586, - 223, 414, 222, 414, 414, 420, 933, 420, 378, 378, - 378, 418, 378, 214, 414, 379, 379, 379, 418, 379, - 1614, 1614, 380, 380, 380, 213, 380, 414, 374, 374, - 414, 374, 382, 382, 1673, 1673, 420, 933, 420, 378, - 386, 386, 386, 382, 382, 414, 379, 209, 379, 382, - 934, 386, 386, 380, 387, 387, 387, 386, 414, 941, - 942, 414, 193, 929, 929, 387, 387, 910, 910, 910, - - 424, 387, 424, 424, 929, 945, 382, 382, 382, 192, - 382, 934, 186, 424, 386, 386, 386, 185, 386, 946, - 941, 942, 388, 388, 388, 769, 178, 424, 387, 387, - 387, 177, 387, 388, 388, 929, 945, 382, 769, 388, - 390, 390, 390, 769, 424, 386, 915, 915, 915, 142, - 946, 390, 390, 926, 926, 926, 769, 390, 424, 387, - 71, 387, 399, 57, 399, 399, 388, 388, 388, 769, - 388, 930, 36, 930, 769, 399, 930, 930, 407, 910, - 407, 407, 399, 35, 390, 390, 390, 34, 390, 947, - 399, 407, 1680, 1680, 939, 939, 939, 388, 33, 407, - - 407, 415, 948, 415, 415, 0, 399, 407, 949, 0, - 1065, 1694, 1694, 399, 415, 390, 397, 0, 397, 397, - 947, 399, 407, 409, 415, 409, 409, 1066, 915, 397, - 407, 407, 409, 948, 409, 926, 409, 0, 407, 949, - 770, 1065, 770, 409, 0, 415, 1054, 770, 1051, 1051, - 409, 412, 0, 412, 412, 415, 0, 1054, 1066, 416, - 397, 416, 416, 409, 412, 409, 0, 409, 416, 1699, - 1699, 770, 416, 770, 409, 412, 939, 1054, 770, 1051, - 1051, 409, 416, 397, 397, 397, 397, 397, 397, 397, - 397, 397, 397, 397, 417, 412, 417, 417, 421, 416, - - 421, 421, 419, 416, 419, 419, 412, 417, 1728, 1728, - 1067, 421, 0, 416, 0, 419, 422, 419, 422, 422, - 421, 1796, 1796, 426, 417, 426, 426, 0, 422, 422, - 0, 0, 423, 1068, 423, 423, 426, 425, 417, 425, - 425, 1067, 421, 422, 422, 423, 419, 0, 419, 969, - 425, 421, 423, 969, 426, 417, 425, 0, 425, 422, - 422, 943, 943, 943, 1068, 0, 427, 426, 427, 427, - 0, 0, 0, 780, 422, 422, 423, 0, 780, 427, - 969, 425, 0, 423, 969, 426, 0, 425, 428, 425, - 428, 428, 427, 429, 0, 429, 429, 428, 0, 0, - - 430, 428, 430, 430, 780, 431, 429, 431, 431, 780, - 427, 429, 0, 430, 430, 0, 1055, 432, 431, 432, - 432, 0, 0, 427, 1069, 431, 1055, 0, 428, 432, - 432, 0, 428, 433, 782, 433, 433, 429, 436, 782, - 436, 436, 429, 943, 430, 430, 433, 1055, 0, 431, - 434, 436, 434, 434, 0, 1069, 431, 1055, 500, 433, - 432, 432, 500, 434, 436, 782, 437, 0, 437, 437, - 782, 500, 434, 1070, 1071, 500, 0, 433, 441, 437, - 441, 441, 436, 437, 954, 954, 954, 0, 970, 500, - 433, 441, 970, 500, 434, 436, 439, 0, 439, 439, - - 1072, 441, 500, 434, 1070, 1071, 500, 978, 0, 439, - 437, 978, 0, 0, 437, 438, 439, 438, 438, 970, - 781, 781, 441, 970, 438, 439, 781, 439, 438, 438, - 0, 1072, 441, 440, 0, 440, 440, 438, 978, 438, - 439, 442, 978, 442, 442, 438, 440, 439, 1073, 0, - 442, 781, 781, 440, 442, 438, 439, 781, 439, 438, - 438, 440, 443, 0, 443, 443, 954, 0, 438, 0, - 438, 443, 0, 775, 775, 443, 438, 440, 775, 1073, - 444, 442, 444, 444, 440, 442, 445, 984, 445, 445, - 444, 984, 440, 444, 446, 0, 446, 446, 447, 445, - - 447, 447, 443, 446, 775, 775, 443, 446, 774, 775, - 774, 447, 445, 774, 448, 447, 448, 448, 984, 0, - 0, 444, 984, 446, 444, 0, 448, 448, 787, 448, - 445, 1075, 800, 787, 446, 0, 0, 800, 446, 774, - 783, 774, 447, 445, 774, 783, 447, 783, 449, 0, - 449, 449, 0, 450, 446, 450, 450, 448, 448, 787, - 448, 449, 1075, 800, 787, 449, 450, 451, 800, 451, - 451, 783, 453, 450, 453, 453, 783, 0, 783, 450, - 451, 454, 988, 454, 454, 453, 988, 0, 0, 0, - 457, 457, 449, 451, 454, 0, 449, 450, 0, 0, - - 453, 457, 457, 0, 450, 0, 464, 457, 464, 464, - 450, 451, 0, 988, 0, 0, 453, 988, 785, 464, - 785, 1076, 1058, 785, 451, 454, 458, 458, 0, 459, - 459, 453, 1058, 0, 457, 457, 457, 458, 458, 0, - 459, 459, 0, 458, 461, 461, 459, 469, 469, 785, - 464, 785, 1076, 1058, 785, 461, 461, 0, 469, 469, - 0, 461, 0, 1058, 469, 457, 1052, 1078, 1079, 1052, - 458, 458, 458, 459, 459, 459, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 1080, 461, 461, - 461, 469, 469, 469, 480, 469, 0, 1052, 1078, 1079, - - 1052, 458, 0, 458, 459, 468, 468, 468, 468, 468, - 468, 468, 468, 468, 468, 468, 470, 470, 1080, 461, - 0, 0, 469, 471, 471, 480, 0, 470, 470, 0, - 473, 473, 0, 470, 471, 471, 0, 0, 0, 0, - 471, 473, 473, 478, 478, 0, 1091, 473, 1092, 480, - 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, - 470, 470, 470, 771, 470, 771, 481, 471, 471, 471, - 771, 471, 1100, 1104, 473, 473, 473, 1091, 473, 1092, - 0, 0, 0, 0, 0, 0, 0, 0, 479, 0, - 0, 470, 0, 470, 771, 0, 771, 481, 471, 0, - - 482, 771, 0, 1100, 1104, 473, 0, 0, 478, 478, - 478, 478, 478, 478, 478, 478, 478, 478, 478, 479, - 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, - 481, 482, 479, 479, 479, 479, 479, 479, 479, 479, - 479, 479, 479, 483, 484, 485, 485, 485, 485, 485, - 485, 485, 485, 485, 485, 485, 0, 0, 482, 482, - 482, 482, 482, 482, 482, 482, 482, 482, 482, 0, - 0, 0, 0, 0, 483, 484, 0, 0, 0, 0, - 0, 0, 0, 0, 483, 483, 483, 483, 483, 483, - 483, 483, 483, 483, 483, 0, 788, 788, 1089, 1089, - - 1089, 788, 484, 484, 484, 484, 484, 484, 484, 484, - 484, 484, 484, 486, 486, 486, 486, 486, 486, 486, - 486, 486, 486, 486, 491, 491, 491, 788, 788, 0, - 0, 0, 788, 0, 0, 491, 1123, 491, 491, 521, - 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, - 491, 491, 773, 491, 524, 722, 0, 722, 722, 786, - 722, 722, 491, 773, 491, 786, 491, 1123, 773, 982, - 786, 722, 982, 982, 525, 525, 525, 0, 0, 0, - 1089, 491, 491, 773, 491, 0, 525, 525, 0, 0, - 786, 0, 525, 491, 773, 491, 786, 491, 538, 773, - - 982, 786, 722, 982, 982, 491, 491, 491, 491, 491, - 491, 491, 491, 491, 491, 491, 492, 492, 492, 525, - 525, 525, 989, 525, 0, 1124, 989, 492, 0, 492, - 492, 524, 524, 524, 524, 524, 524, 524, 524, 524, - 524, 524, 526, 526, 526, 0, 728, 989, 728, 728, - 525, 0, 0, 989, 526, 526, 1124, 989, 0, 728, - 526, 531, 531, 531, 531, 531, 531, 531, 531, 531, - 531, 531, 538, 538, 538, 538, 538, 538, 538, 538, - 538, 538, 538, 1102, 1102, 1102, 0, 526, 526, 526, - 728, 526, 1085, 1085, 1085, 0, 1085, 492, 492, 492, - - 492, 492, 492, 492, 492, 492, 492, 492, 501, 501, - 501, 1132, 801, 501, 501, 0, 0, 801, 526, 501, - 526, 501, 501, 801, 501, 501, 527, 527, 527, 0, - 501, 793, 0, 529, 529, 529, 793, 793, 527, 527, - 0, 0, 1132, 801, 527, 529, 529, 725, 801, 725, - 725, 529, 532, 532, 801, 1144, 1145, 501, 501, 501, - 725, 501, 793, 532, 532, 1102, 0, 793, 793, 532, - 725, 527, 527, 527, 1085, 527, 0, 772, 529, 529, - 529, 772, 529, 0, 791, 791, 1144, 1145, 501, 791, - 772, 725, 0, 533, 533, 772, 532, 532, 532, 0, - - 532, 725, 527, 0, 533, 533, 534, 534, 772, 529, - 533, 0, 772, 536, 536, 791, 791, 534, 534, 0, - 791, 772, 811, 534, 536, 536, 772, 532, 0, 796, - 536, 540, 540, 540, 796, 811, 1151, 533, 533, 533, - 811, 533, 540, 540, 0, 796, 0, 1163, 540, 1168, - 534, 534, 534, 811, 534, 0, 0, 536, 536, 536, - 796, 536, 1081, 1081, 1081, 796, 811, 1151, 533, 1081, - 533, 811, 541, 541, 541, 540, 540, 540, 1163, 540, - 1168, 534, 1173, 541, 541, 542, 542, 542, 536, 541, - 0, 0, 544, 544, 544, 0, 542, 542, 724, 0, - - 724, 724, 542, 544, 544, 0, 540, 0, 776, 544, - 799, 724, 799, 1173, 1179, 799, 541, 541, 541, 776, - 541, 777, 549, 777, 776, 1057, 724, 548, 777, 542, - 542, 542, 1057, 542, 1146, 1146, 544, 544, 544, 776, - 544, 799, 724, 799, 1081, 1179, 799, 541, 0, 541, - 776, 0, 777, 549, 777, 776, 1057, 724, 548, 777, - 542, 0, 550, 1057, 0, 1146, 1146, 544, 548, 548, - 548, 548, 548, 548, 548, 548, 548, 548, 548, 549, - 549, 549, 549, 549, 549, 549, 549, 549, 549, 549, + 401, 1798, 129, 129, 401, 129, 1798, 735, 1959, 158, + + 158, 158, 741, 158, 129, 722, 129, 237, 129, 736, + 1954, 742, 630, 630, 630, 722, 129, 129, 129, 129, + 129, 129, 129, 129, 129, 129, 129, 130, 130, 130, + 158, 743, 158, 741, 744, 1797, 1797, 1951, 130, 1936, + 130, 130, 742, 240, 240, 240, 722, 240, 240, 392, + 501, 1918, 130, 130, 501, 130, 240, 745, 784, 1917, + 152, 1903, 743, 501, 130, 744, 130, 501, 130, 151, + 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, + 404, 501, 404, 130, 130, 501, 130, 1891, 745, 784, + 154, 404, 404, 630, 501, 130, 1882, 130, 501, 130, + + 1872, 1872, 620, 620, 620, 1868, 620, 130, 130, 130, + 130, 130, 130, 130, 130, 130, 130, 130, 131, 131, + 131, 154, 404, 404, 240, 759, 1862, 759, 155, 131, + 759, 131, 131, 152, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 156, 1855, 1845, 1842, 154, 154, + 154, 154, 154, 154, 154, 154, 154, 154, 154, 155, + 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, + 251, 2324, 156, 156, 156, 156, 156, 156, 156, 156, + 156, 156, 156, 620, 1818, 792, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 794, 131, 131, + + 131, 131, 131, 131, 131, 131, 131, 131, 131, 143, + 143, 143, 1812, 1873, 143, 143, 792, 328, 1873, 328, + 143, 723, 143, 143, 1801, 143, 159, 159, 794, 328, + 143, 723, 161, 161, 1757, 783, 328, 159, 1753, 262, + 262, 1728, 159, 161, 408, 2324, 408, 765, 161, 783, + 262, 1725, 1713, 1699, 765, 262, 408, 143, 143, 143, + 328, 143, 723, 1688, 408, 408, 783, 328, 1674, 159, + 159, 159, 408, 159, 795, 161, 161, 161, 765, 161, + 783, 1670, 262, 262, 262, 765, 262, 408, 143, 431, + 2459, 431, 1643, 263, 263, 408, 408, 647, 647, 647, + + 159, 431, 431, 408, 263, 795, 161, 250, 250, 263, + 1641, 250, 250, 262, 1639, 250, 250, 250, 250, 250, + 250, 250, 250, 250, 1631, 250, 250, 250, 250, 250, + 264, 264, 431, 431, 1618, 1611, 263, 263, 263, 1603, + 263, 264, 421, 403, 421, 403, 264, 658, 658, 658, + 1599, 778, 421, 778, 421, 403, 250, 250, 250, 1593, + 250, 607, 607, 607, 2459, 266, 266, 263, 607, 263, + 403, 1591, 1587, 264, 264, 264, 266, 264, 647, 1564, + 799, 266, 778, 421, 778, 421, 403, 250, 250, 250, + 250, 250, 250, 250, 250, 250, 250, 250, 250, 257, + + 1549, 403, 257, 767, 264, 807, 801, 767, 266, 266, + 266, 799, 266, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 1544, 614, 614, 614, 658, 818, + 257, 801, 614, 257, 767, 1512, 807, 801, 767, 266, + 292, 1507, 607, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 286, 286, 1503, 1495, 286, 286, + 818, 1489, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 292, 286, 286, 286, 286, 286, 939, 940, 939, + 940, 1479, 939, 940, 292, 292, 292, 292, 292, 292, + 292, 292, 292, 292, 292, 293, 661, 661, 661, 665, + + 665, 665, 1469, 286, 286, 286, 614, 286, 302, 302, + 302, 302, 302, 302, 302, 302, 302, 302, 302, 1465, + 294, 682, 682, 682, 1460, 1447, 293, 701, 701, 701, + 1439, 719, 719, 719, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 1432, 823, 731, 731, + 731, 294, 1423, 293, 293, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 294, 294, 294, 294, 294, 294, + 294, 294, 294, 294, 294, 295, 295, 661, 823, 829, + 665, 296, 296, 734, 734, 734, 295, 297, 297, 1401, + 1389, 295, 296, 299, 299, 1375, 1373, 296, 297, 411, + + 1354, 411, 682, 297, 299, 427, 758, 427, 701, 299, + 829, 411, 719, 737, 737, 737, 758, 427, 295, 295, + 295, 411, 295, 1347, 296, 296, 296, 305, 296, 731, + 297, 297, 297, 1343, 297, 427, 299, 299, 299, 420, + 299, 420, 411, 306, 306, 1313, 1307, 758, 427, 295, + 1297, 420, 411, 420, 306, 296, 1290, 296, 305, 306, + 942, 297, 942, 1288, 734, 942, 427, 299, 305, 305, + 305, 305, 305, 305, 305, 305, 305, 305, 305, 822, + 307, 307, 420, 407, 420, 407, 306, 306, 306, 1286, + 306, 307, 308, 308, 737, 407, 307, 1284, 310, 310, + + 766, 1282, 407, 308, 822, 331, 331, 771, 308, 310, + 822, 1280, 1278, 766, 310, 771, 331, 306, 1273, 1271, + 414, 331, 414, 307, 307, 307, 407, 307, 414, 1267, + 1265, 766, 414, 407, 1243, 308, 308, 308, 771, 308, + 835, 310, 310, 310, 766, 310, 771, 1223, 331, 331, + 331, 1158, 331, 1152, 307, 1147, 307, 1141, 1140, 414, + 740, 740, 740, 414, 332, 332, 308, 753, 753, 753, + 1139, 835, 310, 318, 318, 332, 1138, 318, 318, 331, + 332, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 860, 318, 318, 318, 318, 318, 319, 319, 319, 319, + + 319, 319, 319, 319, 319, 319, 319, 332, 332, 332, + 361, 332, 1137, 1135, 768, 1132, 876, 1131, 768, 860, + 1125, 860, 318, 318, 318, 412, 318, 412, 333, 333, + 1122, 422, 1120, 422, 1111, 335, 335, 412, 332, 333, + 332, 740, 1109, 422, 333, 768, 335, 876, 753, 768, + 412, 335, 422, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 318, 325, 769, 325, 412, 1106, + 769, 333, 333, 333, 422, 333, 877, 325, 335, 335, + 335, 412, 335, 422, 1105, 1103, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 769, 362, 362, + + 362, 769, 333, 1101, 363, 363, 363, 877, 325, 335, + 362, 364, 364, 364, 786, 362, 363, 1095, 1081, 1078, + 770, 363, 786, 364, 1077, 1057, 1056, 770, 364, 972, + 971, 325, 325, 325, 325, 325, 325, 325, 325, 325, + 325, 325, 362, 362, 362, 786, 362, 970, 363, 363, + 363, 770, 363, 786, 969, 364, 364, 364, 770, 364, + 366, 366, 366, 968, 436, 966, 436, 963, 962, 377, + 377, 775, 366, 362, 961, 960, 436, 366, 775, 363, + 377, 363, 954, 950, 788, 377, 364, 376, 376, 376, + 376, 376, 376, 376, 376, 376, 376, 376, 383, 413, + + 788, 413, 775, 948, 366, 366, 366, 436, 366, 775, + 944, 413, 377, 377, 377, 788, 377, 378, 378, 937, + 935, 931, 413, 379, 379, 929, 925, 920, 378, 917, + 909, 788, 904, 378, 379, 366, 369, 369, 878, 379, + 369, 369, 413, 377, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 413, 369, 369, 369, 369, 369, 903, + 378, 378, 378, 781, 378, 781, 379, 379, 379, 878, + 379, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 802, 864, 802, 369, 369, 369, 433, 369, + 433, 378, 900, 378, 781, 899, 781, 379, 896, 433, + + 433, 464, 464, 464, 464, 464, 464, 464, 464, 464, + 464, 464, 864, 802, 864, 802, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 370, 370, + 433, 433, 370, 370, 370, 370, 370, 370, 370, 370, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, + 373, 373, 895, 883, 373, 373, 373, 373, 373, 373, + 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, + 373, 373, 381, 381, 809, 418, 809, 418, 385, 385, + 385, 879, 875, 381, 386, 386, 386, 418, 381, 385, + 866, 853, 845, 844, 385, 386, 761, 387, 387, 387, + + 386, 754, 752, 738, 418, 809, 732, 809, 387, 720, + 718, 717, 425, 387, 425, 381, 381, 381, 418, 381, + 880, 385, 385, 385, 425, 385, 715, 386, 386, 386, + 710, 386, 389, 389, 389, 418, 373, 373, 425, 373, + 387, 387, 387, 389, 387, 400, 381, 400, 389, 706, + 881, 880, 385, 702, 429, 425, 429, 400, 386, 696, + 386, 415, 429, 415, 400, 694, 429, 803, 453, 425, + 453, 387, 400, 415, 681, 389, 389, 389, 679, 389, + 453, 881, 410, 803, 410, 674, 415, 670, 400, 415, + 410, 666, 410, 429, 410, 400, 772, 429, 803, 882, + + 416, 410, 416, 400, 415, 772, 389, 398, 410, 398, + 772, 453, 416, 659, 803, 646, 417, 415, 417, 398, + 415, 410, 416, 410, 417, 410, 644, 772, 417, 774, + 882, 777, 410, 774, 639, 777, 772, 884, 417, 410, + 635, 772, 419, 416, 419, 423, 424, 423, 424, 631, + 398, 624, 623, 416, 419, 417, 423, 423, 424, 417, + 774, 419, 777, 776, 774, 424, 777, 622, 884, 417, + 776, 423, 423, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 618, 419, 617, 423, 423, 424, + 615, 611, 419, 426, 776, 426, 424, 428, 430, 428, + + 430, 776, 423, 423, 432, 426, 432, 610, 608, 428, + 430, 426, 434, 426, 434, 430, 432, 435, 437, 435, + 437, 779, 428, 432, 434, 814, 814, 789, 558, 435, + 437, 789, 779, 438, 556, 438, 426, 434, 435, 773, + 428, 430, 426, 437, 426, 438, 430, 432, 773, 438, + 546, 885, 779, 428, 432, 434, 814, 814, 789, 782, + 435, 437, 789, 779, 544, 442, 782, 442, 434, 435, + 773, 538, 536, 440, 437, 440, 438, 442, 531, 773, + 438, 439, 885, 439, 790, 440, 441, 442, 441, 439, + 782, 785, 440, 439, 439, 790, 791, 782, 441, 791, + + 785, 440, 439, 440, 439, 441, 529, 439, 442, 443, + 439, 443, 797, 441, 508, 790, 440, 443, 442, 797, + 439, 443, 785, 440, 439, 439, 790, 791, 507, 441, + 791, 785, 440, 439, 440, 439, 441, 444, 439, 444, + 505, 439, 503, 797, 441, 444, 787, 478, 443, 444, + 797, 445, 443, 445, 446, 787, 446, 447, 780, 447, + 445, 805, 448, 445, 448, 447, 446, 886, 780, 447, + 449, 450, 449, 450, 448, 805, 444, 787, 448, 446, + 444, 449, 449, 450, 449, 447, 787, 450, 475, 780, + 473, 445, 805, 793, 445, 463, 447, 446, 886, 780, + + 447, 461, 858, 793, 800, 448, 805, 858, 800, 448, + 446, 393, 449, 449, 450, 449, 447, 451, 450, 451, + 452, 454, 452, 454, 793, 455, 806, 455, 465, 451, + 465, 796, 452, 454, 793, 800, 451, 455, 858, 800, + 465, 796, 451, 391, 887, 452, 806, 390, 454, 388, + 458, 458, 456, 382, 459, 459, 380, 806, 460, 460, + 451, 458, 796, 452, 454, 459, 458, 451, 455, 460, + 459, 465, 796, 451, 460, 887, 452, 806, 825, 454, + 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, + 456, 375, 371, 458, 458, 458, 825, 459, 459, 459, + + 367, 460, 460, 460, 462, 462, 365, 470, 470, 825, + 721, 359, 721, 354, 350, 462, 345, 341, 470, 729, + 462, 729, 721, 470, 458, 336, 324, 825, 459, 321, + 459, 729, 460, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 471, 471, 812, 462, 462, 462, + 470, 470, 470, 721, 470, 471, 472, 472, 311, 812, + 471, 309, 729, 474, 474, 300, 291, 472, 725, 280, + 725, 725, 472, 725, 474, 479, 278, 812, 462, 474, + 726, 470, 726, 725, 819, 815, 804, 471, 471, 471, + 812, 471, 726, 755, 819, 755, 481, 804, 815, 472, + + 472, 472, 726, 472, 888, 755, 474, 474, 474, 267, + 474, 256, 254, 245, 725, 819, 815, 804, 471, 480, + 471, 243, 231, 726, 225, 819, 224, 481, 804, 815, + 472, 482, 216, 726, 215, 888, 755, 474, 211, 479, + 479, 479, 479, 479, 479, 479, 479, 479, 479, 479, + 480, 481, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 482, 480, 480, 480, 480, 480, 480, 480, + 480, 480, 480, 480, 483, 484, 811, 813, 811, 813, + 816, 856, 798, 808, 816, 482, 482, 482, 482, 482, + 482, 482, 482, 482, 482, 482, 485, 798, 808, 856, + + 889, 897, 897, 897, 195, 483, 484, 811, 813, 811, + 813, 816, 856, 798, 808, 816, 484, 484, 484, 484, + 484, 484, 484, 484, 484, 484, 484, 485, 798, 808, + 856, 889, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, 486, 486, 486, 486, 486, 486, 486, + 486, 486, 486, 486, 485, 485, 485, 485, 485, 485, + 485, 485, 485, 485, 485, 487, 487, 487, 487, 487, + 487, 487, 487, 487, 487, 487, 492, 492, 492, 890, + 194, 188, 897, 187, 180, 179, 162, 492, 160, 492, + 492, 148, 146, 144, 124, 526, 526, 526, 817, 821, + + 810, 492, 492, 834, 492, 817, 525, 526, 111, 105, + 890, 810, 526, 492, 821, 492, 834, 492, 522, 522, + 522, 522, 522, 522, 522, 522, 522, 522, 522, 817, + 821, 810, 492, 492, 834, 492, 817, 73, 72, 526, + 526, 526, 810, 526, 492, 821, 492, 834, 492, 539, + 69, 59, 36, 901, 901, 901, 492, 492, 492, 492, + 492, 492, 492, 492, 492, 492, 492, 493, 493, 493, + 526, 35, 833, 838, 34, 891, 833, 838, 493, 33, + 493, 493, 525, 525, 525, 525, 525, 525, 525, 525, + 525, 525, 525, 527, 527, 527, 0, 0, 0, 905, + + 905, 905, 820, 833, 838, 527, 891, 833, 838, 820, + 527, 532, 532, 532, 532, 532, 532, 532, 532, 532, + 532, 532, 539, 539, 539, 539, 539, 539, 539, 539, + 539, 539, 539, 820, 901, 0, 0, 527, 527, 527, + 820, 527, 892, 0, 0, 0, 0, 493, 493, 493, + 493, 493, 493, 493, 493, 493, 493, 493, 502, 502, + 502, 0, 0, 502, 502, 824, 824, 824, 527, 502, + 527, 502, 502, 892, 502, 528, 528, 528, 862, 502, + 905, 530, 530, 530, 862, 0, 826, 528, 533, 533, + 0, 824, 528, 530, 0, 0, 0, 826, 530, 533, + + 534, 534, 0, 0, 533, 893, 502, 502, 502, 862, + 502, 534, 0, 0, 0, 862, 534, 826, 0, 528, + 528, 528, 824, 528, 837, 530, 530, 530, 826, 530, + 0, 533, 533, 533, 828, 533, 893, 502, 535, 535, + 837, 828, 910, 534, 534, 534, 824, 534, 0, 535, + 528, 0, 537, 537, 535, 837, 530, 0, 831, 541, + 541, 541, 533, 537, 0, 828, 0, 831, 537, 911, + 541, 837, 828, 910, 534, 541, 534, 542, 542, 542, + 0, 535, 535, 535, 0, 535, 0, 0, 542, 831, + 0, 0, 859, 542, 0, 537, 537, 537, 831, 537, + + 911, 0, 541, 541, 541, 727, 541, 727, 830, 836, + 830, 859, 535, 918, 543, 543, 543, 727, 836, 830, + 542, 542, 542, 859, 542, 543, 537, 545, 545, 545, + 543, 727, 550, 541, 549, 865, 857, 865, 545, 830, + 836, 830, 859, 545, 918, 0, 0, 0, 727, 836, + 830, 542, 0, 542, 0, 0, 857, 543, 543, 543, + 0, 543, 727, 550, 0, 549, 865, 857, 865, 921, + 545, 545, 545, 0, 545, 549, 549, 549, 549, 549, + 549, 549, 549, 549, 549, 549, 551, 857, 543, 550, 550, 550, 550, 550, 550, 550, 550, 550, 550, 550, - 550, 552, 552, 0, 553, 553, 0, 0, 554, 554, - 1162, 1184, 552, 552, 1162, 553, 553, 0, 552, 554, - 554, 553, 556, 556, 0, 554, 639, 639, 0, 0, - 0, 0, 0, 556, 556, 0, 0, 639, 639, 556, - 0, 1162, 1184, 639, 1150, 552, 552, 552, 553, 553, - 553, 1150, 554, 554, 554, 558, 558, 558, 558, 558, - 558, 558, 558, 558, 558, 558, 556, 556, 556, 993, - 639, 639, 639, 993, 639, 1150, 552, 0, 0, 553, - 0, 553, 1150, 554, 559, 559, 559, 559, 559, 559, - 559, 559, 559, 559, 559, 0, 0, 556, 631, 631, - - 993, 639, 631, 631, 993, 0, 631, 631, 631, 631, - 631, 631, 631, 631, 631, 647, 1185, 631, 631, 631, - 631, 631, 638, 638, 638, 638, 638, 638, 638, 638, - 638, 638, 638, 653, 653, 653, 653, 653, 653, 653, - 653, 653, 653, 653, 0, 0, 647, 1185, 631, 631, - 631, 0, 631, 0, 647, 647, 647, 647, 647, 647, - 647, 647, 647, 647, 647, 654, 654, 654, 654, 654, - 654, 654, 654, 654, 654, 654, 1107, 1107, 1107, 631, - 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, - 631, 632, 632, 0, 0, 632, 632, 632, 632, 632, - - 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, - 632, 632, 632, 632, 635, 635, 1186, 0, 635, 635, - 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, - 635, 635, 635, 635, 635, 635, 635, 640, 640, 0, - 726, 0, 726, 726, 641, 641, 0, 1186, 640, 640, - 0, 643, 643, 726, 640, 641, 641, 0, 1107, 0, - 0, 641, 643, 643, 0, 0, 0, 726, 643, 674, - 674, 674, 674, 674, 674, 674, 674, 674, 674, 674, - 0, 640, 640, 640, 726, 640, 0, 0, 641, 641, - 641, 648, 641, 1196, 1143, 643, 643, 643, 726, 643, - - 0, 635, 635, 0, 635, 0, 0, 0, 0, 649, - 798, 784, 640, 0, 640, 798, 784, 798, 1143, 641, - 650, 784, 648, 0, 1196, 1143, 643, 0, 0, 648, - 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, - 649, 798, 784, 0, 651, 0, 798, 784, 798, 1143, - 0, 650, 784, 649, 649, 649, 649, 649, 649, 649, - 649, 649, 649, 649, 650, 650, 650, 650, 650, 650, - 650, 650, 650, 650, 650, 651, 652, 1164, 0, 1197, - 1198, 1164, 0, 0, 651, 651, 651, 651, 651, 651, - 651, 651, 651, 651, 651, 685, 685, 685, 685, 685, - - 685, 685, 685, 685, 685, 685, 0, 652, 1164, 682, - 1197, 1198, 652, 652, 652, 652, 652, 652, 652, 652, - 652, 652, 652, 667, 667, 0, 0, 667, 667, 0, - 0, 667, 667, 667, 667, 667, 667, 667, 667, 667, - 682, 683, 667, 667, 667, 667, 667, 682, 682, 682, - 682, 682, 682, 682, 682, 682, 682, 682, 686, 686, + 921, 545, 559, 559, 559, 559, 559, 559, 559, 559, + 559, 559, 559, 0, 551, 551, 551, 551, 551, 551, + 551, 551, 551, 551, 551, 553, 553, 0, 554, 554, + 0, 555, 555, 932, 557, 557, 553, 0, 0, 554, + 0, 553, 555, 0, 554, 557, 0, 555, 0, 0, + 557, 560, 560, 560, 560, 560, 560, 560, 560, 560, + 560, 560, 951, 841, 932, 0, 841, 952, 553, 553, + 553, 554, 554, 554, 555, 555, 555, 557, 557, 557, + 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, + 640, 0, 0, 951, 841, 641, 641, 841, 952, 553, + + 0, 0, 554, 650, 554, 555, 641, 0, 557, 633, + 633, 641, 955, 633, 633, 0, 0, 633, 633, 633, + 633, 633, 633, 633, 633, 633, 0, 633, 633, 633, + 633, 633, 649, 956, 650, 0, 0, 0, 641, 641, + 641, 0, 641, 955, 908, 908, 908, 650, 650, 650, + 650, 650, 650, 650, 650, 650, 650, 650, 633, 633, + 633, 0, 633, 649, 956, 0, 919, 919, 919, 641, + 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, + 649, 0, 924, 924, 924, 0, 0, 0, 0, 633, + 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, + + 633, 634, 634, 0, 0, 634, 634, 634, 634, 634, + 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, + 634, 634, 634, 637, 637, 908, 0, 637, 637, 637, + 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, + 637, 637, 637, 637, 637, 642, 642, 919, 936, 936, + 936, 643, 643, 0, 957, 861, 642, 645, 645, 0, + 0, 642, 643, 924, 0, 0, 861, 643, 645, 0, + 0, 0, 0, 645, 654, 654, 654, 654, 654, 654, + 654, 654, 654, 654, 654, 957, 861, 0, 642, 642, + 642, 651, 642, 941, 643, 643, 643, 861, 643, 958, + + 645, 645, 645, 941, 645, 0, 0, 676, 676, 637, + 637, 0, 637, 0, 0, 652, 0, 959, 676, 642, + 0, 642, 651, 676, 0, 643, 0, 0, 0, 936, + 958, 645, 0, 0, 941, 651, 651, 651, 651, 651, + 651, 651, 651, 651, 651, 651, 652, 653, 959, 979, + 676, 676, 676, 0, 676, 652, 652, 652, 652, 652, + 652, 652, 652, 652, 652, 652, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 0, 653, 0, + 979, 676, 0, 653, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 653, 668, 668, 0, 0, 668, 668, + + 0, 0, 668, 668, 668, 668, 668, 668, 668, 668, + 668, 683, 668, 668, 668, 668, 668, 675, 675, 675, + 675, 675, 675, 675, 675, 675, 675, 675, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, 0, - 0, 0, 683, 667, 667, 667, 0, 667, 0, 0, - 0, 683, 683, 683, 683, 683, 683, 683, 683, 683, - 683, 683, 689, 689, 689, 689, 689, 689, 689, 689, - - 689, 689, 689, 0, 667, 667, 667, 667, 667, 667, - 667, 667, 667, 667, 667, 667, 668, 668, 0, 0, - 668, 668, 668, 668, 668, 668, 668, 668, 668, 668, - 668, 668, 668, 668, 668, 668, 668, 668, 668, 671, - 671, 1199, 0, 671, 671, 671, 671, 671, 671, 671, - 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, - 671, 671, 675, 675, 0, 0, 1116, 1116, 1116, 676, - 676, 0, 1199, 675, 675, 0, 677, 677, 1056, 675, - 676, 676, 0, 0, 0, 1200, 676, 677, 677, 0, - 0, 0, 1056, 677, 697, 697, 697, 697, 697, 697, - - 697, 697, 697, 697, 697, 1059, 675, 675, 675, 1056, - 675, 0, 1201, 676, 676, 676, 1200, 676, 684, 1059, - 677, 677, 677, 1056, 677, 0, 671, 671, 0, 671, - 679, 679, 0, 0, 803, 0, 1059, 675, 0, 803, - 803, 679, 679, 1201, 676, 0, 676, 679, 1116, 684, - 1059, 677, 1152, 0, 684, 684, 684, 684, 684, 684, - 684, 684, 684, 684, 684, 803, 1148, 0, 690, 690, - 803, 803, 1148, 1152, 679, 679, 679, 0, 679, 690, - 690, 691, 691, 1152, 792, 690, 792, 0, 0, 692, - 692, 792, 691, 691, 1195, 0, 0, 1148, 691, 1147, - - 692, 692, 0, 1148, 1152, 679, 692, 694, 694, 1195, - 1206, 1147, 690, 690, 690, 792, 690, 792, 694, 694, - 0, 0, 792, 696, 694, 691, 691, 691, 975, 691, - 1147, 0, 975, 692, 692, 692, 0, 692, 0, 0, - 1195, 1206, 1147, 690, 0, 0, 0, 1205, 975, 1157, - 1208, 694, 694, 694, 696, 694, 691, 0, 691, 975, - 1129, 1129, 1129, 975, 692, 1205, 1157, 696, 696, 696, - 696, 696, 696, 696, 696, 696, 696, 696, 1205, 975, - 1157, 1208, 694, 698, 698, 698, 698, 698, 698, 698, - 698, 698, 698, 698, 703, 703, 1205, 1157, 703, 703, - - 0, 0, 703, 703, 703, 703, 703, 703, 703, 703, - 703, 0, 1210, 703, 703, 703, 703, 703, 710, 710, - 710, 710, 710, 710, 710, 710, 710, 710, 710, 727, - 727, 727, 727, 727, 727, 727, 727, 727, 727, 727, - 0, 0, 1129, 1210, 703, 703, 703, 0, 703, 745, - 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, - 747, 747, 747, 747, 747, 747, 747, 747, 747, 747, - 747, 1134, 1134, 1134, 0, 703, 703, 703, 703, 703, - 703, 703, 703, 703, 703, 703, 703, 704, 704, 746, - 0, 704, 704, 704, 704, 704, 704, 704, 704, 704, - - 704, 704, 704, 704, 704, 704, 704, 704, 704, 704, - 707, 707, 1213, 0, 707, 707, 707, 707, 707, 707, - 707, 707, 707, 707, 707, 707, 707, 707, 707, 707, - 707, 707, 707, 711, 711, 0, 0, 1416, 1416, 1416, - 712, 712, 0, 1213, 711, 711, 0, 713, 713, 1158, - 711, 712, 712, 1134, 0, 0, 1158, 712, 713, 713, - 750, 0, 0, 1217, 713, 1221, 746, 746, 746, 746, - 746, 746, 746, 746, 746, 746, 746, 711, 711, 711, - 1158, 711, 0, 1230, 712, 712, 712, 1158, 712, 757, - 757, 713, 713, 713, 1217, 713, 1221, 707, 707, 0, - - 707, 715, 715, 0, 1230, 0, 0, 0, 711, 0, - 0, 0, 715, 715, 1230, 712, 0, 712, 715, 1416, - 0, 1239, 713, 749, 749, 749, 749, 749, 749, 749, - 749, 749, 749, 749, 750, 750, 750, 750, 750, 750, - 750, 750, 750, 750, 750, 715, 715, 715, 0, 715, - 759, 761, 1239, 0, 757, 757, 757, 757, 757, 757, - 757, 757, 757, 757, 757, 758, 758, 758, 758, 758, - 758, 758, 758, 758, 758, 758, 715, 721, 0, 721, - 721, 759, 761, 0, 760, 996, 805, 1240, 805, 996, - 721, 805, 761, 761, 761, 761, 761, 761, 761, 761, - - 761, 761, 761, 0, 759, 759, 759, 759, 759, 759, - 759, 759, 759, 759, 759, 760, 996, 805, 1240, 805, - 996, 721, 805, 0, 0, 0, 1242, 1244, 0, 0, - 762, 760, 760, 760, 760, 760, 760, 760, 760, 760, - 760, 760, 763, 0, 721, 721, 721, 721, 721, 721, - 721, 721, 721, 721, 721, 748, 748, 1242, 1244, 748, - 748, 762, 0, 748, 748, 748, 748, 748, 748, 748, - 748, 748, 1245, 763, 748, 748, 748, 748, 748, 766, - 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, - 762, 764, 763, 763, 763, 763, 763, 763, 763, 763, - - 763, 763, 763, 1245, 0, 748, 748, 748, 0, 748, - 766, 0, 0, 0, 0, 0, 0, 765, 0, 0, - 0, 0, 764, 0, 0, 766, 766, 766, 766, 766, - 766, 766, 766, 766, 766, 766, 748, 748, 748, 748, - 748, 748, 748, 748, 748, 748, 748, 748, 765, 764, - 764, 764, 764, 764, 764, 764, 764, 764, 764, 764, - 0, 0, 0, 0, 765, 765, 765, 765, 765, 765, - 765, 765, 765, 765, 765, 767, 1247, 795, 0, 0, - 767, 0, 795, 0, 0, 1249, 0, 795, 836, 836, - 836, 836, 836, 836, 836, 836, 836, 836, 836, 0, - - 789, 790, 0, 794, 0, 1250, 767, 1247, 795, 789, - 790, 767, 794, 795, 789, 790, 1249, 794, 795, 0, - 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, - 767, 789, 790, 807, 794, 797, 1250, 807, 807, 0, - 789, 790, 797, 794, 802, 789, 790, 797, 794, 804, - 806, 0, 1251, 802, 808, 810, 804, 806, 802, 810, - 810, 804, 806, 0, 807, 808, 797, 809, 807, 807, - 808, 0, 812, 797, 812, 802, 0, 809, 797, 812, - 804, 806, 809, 1251, 802, 808, 810, 804, 806, 802, - 810, 810, 804, 806, 813, 813, 808, 0, 809, 813, - - 814, 808, 814, 812, 816, 812, 815, 814, 809, 816, - 812, 815, 815, 809, 817, 818, 818, 818, 824, 820, - 816, 820, 0, 817, 820, 813, 813, 819, 817, 824, - 813, 814, 819, 814, 824, 816, 819, 815, 814, 0, - 816, 1266, 815, 815, 1267, 817, 822, 0, 822, 824, - 820, 818, 820, 822, 817, 820, 818, 999, 819, 817, - 824, 999, 823, 819, 821, 824, 0, 819, 821, 821, - 821, 823, 1266, 825, 0, 1267, 823, 822, 825, 822, - 826, 826, 818, 826, 822, 826, 0, 818, 999, 829, - 827, 830, 999, 823, 829, 821, 830, 818, 0, 821, - - 821, 821, 823, 827, 825, 832, 0, 823, 827, 825, - 832, 826, 826, 828, 826, 832, 826, 828, 828, 831, - 829, 827, 830, 833, 831, 829, 831, 830, 833, 835, - 1231, 1233, 1231, 834, 827, 835, 832, 834, 834, 827, - 835, 832, 0, 0, 828, 837, 832, 0, 828, 828, - 831, 0, 1233, 839, 833, 831, 0, 831, 0, 833, - 835, 1231, 1233, 1231, 834, 0, 835, 840, 834, 834, - 0, 835, 0, 837, 837, 837, 837, 837, 837, 837, - 837, 837, 837, 837, 839, 0, 839, 839, 839, 839, - 839, 839, 839, 839, 839, 839, 839, 0, 840, 0, - - 0, 841, 842, 858, 858, 858, 858, 858, 858, 858, - 858, 858, 858, 858, 1263, 1263, 1263, 0, 1263, 0, - 0, 840, 840, 840, 840, 840, 840, 840, 840, 840, - 840, 840, 841, 842, 0, 0, 0, 843, 0, 0, - 0, 0, 841, 841, 841, 841, 841, 841, 841, 841, - 841, 841, 841, 859, 0, 0, 0, 842, 842, 842, - 842, 842, 842, 842, 842, 842, 842, 842, 843, 844, - 860, 860, 860, 860, 860, 860, 860, 860, 860, 860, - 860, 843, 843, 843, 843, 843, 843, 843, 843, 843, - 843, 843, 861, 0, 0, 0, 1263, 0, 1160, 0, - - 844, 864, 864, 864, 864, 864, 864, 864, 864, 864, - 864, 864, 1002, 1268, 862, 1160, 1002, 844, 844, 844, - 844, 844, 844, 844, 844, 844, 844, 844, 846, 1160, - 859, 859, 859, 859, 859, 859, 859, 859, 859, 859, - 859, 0, 0, 1002, 1268, 862, 1160, 1002, 1279, 1283, - 1284, 0, 846, 862, 862, 862, 862, 862, 862, 862, - 862, 862, 862, 862, 0, 0, 861, 861, 861, 861, - 861, 861, 861, 861, 861, 861, 861, 863, 1003, 1279, - 1283, 1284, 1003, 846, 895, 895, 895, 895, 895, 895, - 895, 895, 895, 895, 895, 846, 846, 846, 846, 846, - - 846, 846, 846, 846, 846, 846, 847, 865, 863, 1003, - 0, 0, 0, 1003, 0, 847, 902, 0, 0, 907, - 0, 0, 0, 0, 863, 863, 863, 863, 863, 863, - 863, 863, 863, 863, 863, 865, 865, 865, 865, 865, - 865, 865, 865, 865, 865, 865, 847, 902, 907, 907, - 907, 907, 907, 907, 907, 907, 907, 907, 907, 1293, - 902, 902, 902, 902, 902, 902, 902, 902, 902, 902, - 902, 903, 0, 847, 847, 847, 847, 847, 847, 847, - 847, 847, 847, 847, 896, 896, 0, 0, 896, 896, - 1293, 0, 896, 896, 896, 896, 896, 896, 896, 896, - - 896, 904, 903, 896, 896, 896, 896, 896, 973, 983, - 983, 1165, 973, 1295, 983, 973, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 905, 1298, 1304, - 1165, 1310, 904, 0, 896, 896, 896, 0, 896, 973, - 983, 983, 1165, 973, 1295, 983, 973, 904, 904, 904, - 904, 904, 904, 904, 904, 904, 904, 904, 905, 1298, - 1304, 1165, 1310, 0, 906, 896, 896, 896, 896, 896, - 896, 896, 896, 896, 896, 896, 896, 0, 0, 0, - 0, 0, 0, 0, 905, 905, 905, 905, 905, 905, - 905, 905, 905, 905, 905, 906, 0, 1005, 0, 0, - - 1312, 1005, 0, 906, 906, 906, 906, 906, 906, 906, - 906, 906, 906, 906, 913, 913, 913, 913, 913, 913, - 913, 913, 913, 913, 913, 914, 914, 919, 1005, 914, - 914, 1312, 1005, 914, 914, 914, 914, 914, 914, 914, - 914, 914, 917, 0, 914, 914, 914, 914, 914, 991, - 1000, 1000, 1172, 991, 1176, 1000, 919, 919, 919, 919, - 919, 919, 919, 919, 919, 919, 919, 0, 991, 1172, - 1008, 1176, 921, 917, 1008, 914, 914, 914, 0, 914, - 991, 1000, 1000, 1172, 991, 1176, 1000, 917, 917, 917, - 917, 917, 917, 917, 917, 917, 917, 917, 918, 991, - - 1172, 1008, 1176, 921, 1314, 1008, 914, 914, 914, 914, - 914, 914, 914, 914, 914, 914, 914, 914, 921, 921, - 921, 921, 921, 921, 921, 921, 921, 921, 921, 918, - 932, 932, 0, 0, 963, 1314, 0, 918, 918, 918, - 918, 918, 918, 918, 918, 918, 918, 918, 924, 924, - 924, 924, 924, 924, 924, 924, 924, 924, 924, 925, - 925, 0, 0, 925, 925, 963, 0, 925, 925, 925, - 925, 925, 925, 925, 925, 925, 935, 1159, 925, 925, - 925, 925, 925, 1159, 963, 963, 963, 963, 963, 963, - 963, 963, 963, 963, 963, 932, 932, 932, 932, 932, - - 932, 932, 932, 932, 932, 932, 936, 935, 1159, 925, - 925, 925, 0, 925, 1159, 0, 0, 0, 0, 0, - 935, 935, 935, 935, 935, 935, 935, 935, 935, 935, - 935, 1083, 1083, 1083, 0, 0, 0, 936, 1083, 0, - 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, - 925, 925, 937, 995, 1010, 1009, 1149, 995, 1010, 1009, - 1010, 0, 0, 936, 936, 936, 936, 936, 936, 936, - 936, 936, 936, 936, 961, 1009, 1011, 1012, 995, 1149, - 1011, 1012, 0, 937, 995, 1010, 1009, 1149, 995, 1010, - 1009, 1010, 937, 937, 937, 937, 937, 937, 937, 937, - - 937, 937, 937, 962, 1315, 961, 1009, 1011, 1012, 0, - 1149, 1011, 1012, 1083, 0, 961, 961, 961, 961, 961, - 961, 961, 961, 961, 961, 961, 964, 1018, 1017, 1018, - 1236, 965, 1017, 1018, 962, 1315, 0, 962, 962, 962, - 962, 962, 962, 962, 962, 962, 962, 962, 0, 0, - 0, 1236, 0, 0, 0, 0, 966, 964, 1018, 1017, - 1018, 1236, 965, 1017, 1018, 964, 964, 964, 964, 964, - 964, 964, 964, 964, 964, 964, 965, 965, 965, 965, - 965, 965, 965, 965, 965, 965, 965, 966, 1255, 1255, - 1255, 0, 0, 0, 0, 1255, 0, 966, 966, 966, - - 966, 966, 966, 966, 966, 966, 966, 966, 967, 967, - 967, 967, 967, 967, 967, 967, 967, 967, 967, 968, - 971, 972, 974, 968, 971, 972, 974, 977, 979, 981, - 974, 977, 979, 981, 1026, 971, 972, 981, 1026, 0, - 977, 979, 1259, 1259, 1259, 0, 0, 0, 0, 1259, - 968, 971, 972, 974, 968, 971, 972, 974, 977, 979, - 981, 974, 977, 979, 981, 1026, 971, 972, 981, 1026, - 1255, 977, 979, 968, 968, 968, 968, 968, 968, 968, - 968, 968, 968, 968, 976, 980, 986, 985, 976, 980, - 986, 985, 990, 0, 987, 1323, 990, 986, 987, 976, - - 992, 980, 985, 987, 992, 990, 0, 0, 0, 1323, - 994, 994, 994, 992, 0, 976, 980, 986, 985, 976, - 980, 986, 985, 990, 1259, 987, 1323, 990, 986, 987, - 976, 992, 980, 985, 987, 992, 990, 994, 997, 998, - 1323, 994, 997, 998, 992, 1001, 0, 1004, 0, 1001, - 998, 1004, 0, 997, 0, 1001, 1006, 1006, 1006, 1007, - 1004, 0, 0, 1007, 0, 1324, 0, 1007, 994, 997, - 998, 1013, 994, 997, 998, 1013, 1001, 1153, 1004, 1013, - 1001, 998, 1004, 1006, 997, 1014, 1001, 1006, 1153, 1014, - 1007, 1004, 994, 1014, 1007, 1015, 1324, 1016, 1007, 1015, - - 1016, 1015, 1013, 1019, 1016, 1019, 1013, 0, 1153, 1019, - 1013, 0, 0, 0, 1006, 1187, 1014, 1028, 1006, 1153, - 1014, 1028, 1187, 1023, 1014, 0, 1015, 1023, 1016, 0, - 1015, 1016, 1015, 0, 1019, 1016, 1019, 1023, 1006, 0, - 1019, 1020, 1020, 1020, 1021, 1021, 1187, 0, 1028, 1022, - 1022, 1022, 1028, 1187, 1023, 1021, 1021, 0, 1023, 0, - 1024, 1021, 1166, 1020, 1024, 1025, 1020, 1020, 1023, 1025, - 1029, 1326, 1166, 1330, 1029, 1024, 1022, 1020, 1020, 1020, - 1022, 1025, 0, 1020, 1029, 0, 0, 1332, 1021, 1021, - 1021, 1024, 1021, 1166, 0, 1024, 1025, 1020, 1020, 0, - - 1025, 1029, 1326, 1166, 1330, 1029, 1024, 1022, 1020, 1020, - 1020, 1022, 1025, 1031, 1020, 1029, 1027, 1031, 1332, 1021, - 1027, 1021, 1031, 1020, 1027, 1032, 1030, 0, 1030, 1032, - 1033, 1022, 1030, 1036, 1033, 1034, 1035, 1036, 1035, 1034, - 1035, 1032, 1037, 1034, 1031, 1033, 1037, 1027, 1031, 0, - 1037, 1027, 1338, 1031, 1038, 1027, 1032, 1030, 1038, 1030, - 1032, 1033, 1043, 1030, 1036, 1033, 1034, 1035, 1036, 1035, - 1034, 1035, 1032, 1037, 1034, 1039, 1033, 1037, 1040, 1039, - 1041, 1037, 1040, 1338, 1041, 1038, 0, 0, 0, 1038, - 0, 0, 0, 1043, 0, 0, 1044, 0, 1339, 1340, - - 0, 0, 0, 1709, 1709, 1709, 1039, 0, 0, 1040, - 1039, 1041, 1045, 1040, 1341, 1041, 1043, 1043, 1043, 1043, - 1043, 1043, 1043, 1043, 1043, 1043, 1043, 1044, 1046, 1339, - 1340, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, - 1044, 1044, 1047, 1045, 0, 1341, 1045, 1045, 1045, 1045, - 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1046, 1046, 1046, - 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1049, 1062, - 0, 0, 1049, 1047, 1048, 1048, 1048, 1048, 1048, 1048, - 1048, 1048, 1048, 1048, 1048, 1709, 0, 1047, 1047, 1047, - 1047, 1047, 1047, 1047, 1047, 1047, 1047, 1047, 1062, 1062, - - 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 0, - 0, 0, 0, 0, 1098, 1098, 1098, 1154, 1169, 1098, - 1063, 1177, 1174, 1183, 1169, 1154, 1207, 1098, 1178, 1094, - 1174, 1183, 1177, 1207, 1178, 1049, 1049, 1049, 1049, 1049, - 1049, 1049, 1049, 1049, 1049, 1049, 1050, 0, 1154, 1169, - 1050, 1063, 1177, 1174, 1183, 1169, 1154, 1207, 0, 1178, - 1094, 1174, 1183, 1177, 1207, 1178, 1098, 1232, 1343, 1095, - 1346, 1347, 1232, 1050, 1063, 1063, 1063, 1063, 1063, 1063, - 1063, 1063, 1063, 1063, 1063, 1094, 1094, 1094, 1094, 1094, - 1094, 1094, 1094, 1094, 1094, 1094, 1098, 0, 1232, 1343, - - 1095, 1346, 1347, 1232, 1050, 0, 0, 1345, 1349, 0, - 1345, 0, 0, 1050, 1050, 1050, 1050, 1050, 1050, 1050, - 1050, 1050, 1050, 1050, 1095, 1095, 1095, 1095, 1095, 1095, - 1095, 1095, 1095, 1095, 1095, 1096, 1096, 1096, 1345, 1349, - 1096, 1345, 1155, 1161, 1156, 1097, 1097, 1097, 1096, 1167, - 1097, 1099, 1099, 1099, 1110, 0, 1099, 0, 1097, 0, - 0, 0, 0, 1155, 1099, 1156, 0, 1161, 1097, 1350, - 1167, 1180, 1194, 1155, 1161, 1156, 1099, 1180, 1194, 1109, - 1167, 0, 0, 1110, 1110, 1110, 1110, 1110, 1110, 1110, - 1110, 1110, 1110, 1110, 1155, 0, 1156, 1111, 1161, 1097, - - 1350, 1167, 1180, 1194, 1718, 1718, 1718, 1099, 1180, 1194, - 1109, 1181, 1181, 1181, 0, 1351, 1096, 1096, 1096, 1096, - 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1097, 1111, 0, - 0, 0, 0, 1099, 1109, 1109, 1109, 1109, 1109, 1109, - 1109, 1109, 1109, 1109, 1109, 1125, 1351, 1352, 1353, 1181, - 0, 0, 0, 1111, 1111, 1111, 1111, 1111, 1111, 1111, - 1111, 1111, 1111, 1111, 1112, 1112, 1112, 1112, 1112, 1112, - 1112, 1112, 1112, 1112, 1112, 0, 1125, 0, 1352, 1353, - 1181, 1126, 1192, 1218, 1193, 1220, 1718, 0, 0, 1354, - 1218, 1235, 1234, 1181, 1192, 1193, 1235, 1220, 1234, 1355, - - 1127, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, - 1125, 1125, 1126, 1192, 1218, 1193, 1220, 1175, 1175, 1175, - 1354, 1218, 1235, 1234, 0, 1192, 1193, 1235, 1220, 1234, - 1355, 1127, 1175, 0, 0, 1170, 1170, 1170, 0, 1126, - 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, + 980, 990, 683, 668, 668, 668, 0, 668, 0, 683, + 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, + 687, 687, 687, 687, 687, 687, 687, 687, 687, 687, + 687, 980, 990, 0, 668, 668, 668, 668, 668, 668, + 668, 668, 668, 668, 668, 668, 669, 669, 0, 0, + 669, 669, 669, 669, 669, 669, 669, 669, 669, 669, + + 669, 669, 669, 669, 669, 669, 669, 669, 672, 672, + 0, 0, 672, 672, 672, 672, 672, 672, 672, 672, + 672, 672, 672, 672, 672, 672, 672, 672, 672, 672, + 677, 677, 0, 938, 0, 938, 678, 678, 0, 0, + 0, 677, 680, 680, 0, 938, 677, 678, 0, 0, + 0, 0, 678, 680, 0, 0, 0, 827, 680, 690, + 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, + 827, 982, 827, 677, 677, 677, 938, 677, 684, 678, + 678, 678, 947, 678, 982, 680, 680, 680, 827, 680, + 949, 949, 949, 0, 672, 672, 0, 672, 685, 947, + + 0, 827, 982, 827, 677, 0, 677, 0, 0, 684, + 678, 0, 0, 947, 0, 982, 680, 0, 684, 684, + 684, 684, 684, 684, 684, 684, 684, 684, 684, 685, + 947, 953, 953, 953, 685, 685, 685, 685, 685, 685, + 685, 685, 685, 685, 685, 691, 691, 0, 965, 965, + 965, 692, 692, 0, 986, 991, 691, 693, 693, 0, + 986, 691, 692, 695, 695, 0, 0, 692, 693, 0, + 0, 949, 832, 693, 695, 0, 0, 0, 839, 695, + 863, 967, 832, 967, 832, 986, 991, 839, 691, 691, + 691, 986, 691, 967, 692, 692, 692, 697, 692, 863, + + 693, 693, 693, 832, 693, 992, 695, 695, 695, 839, + 695, 863, 953, 832, 0, 832, 0, 0, 839, 691, + 0, 0, 0, 0, 967, 692, 0, 692, 697, 965, + 863, 693, 0, 0, 0, 0, 992, 695, 0, 0, + 0, 697, 697, 697, 697, 697, 697, 697, 697, 697, + 697, 697, 698, 698, 698, 698, 698, 698, 698, 698, + 698, 698, 698, 699, 699, 699, 699, 699, 699, 699, + 699, 699, 699, 699, 704, 704, 0, 0, 704, 704, + 0, 0, 704, 704, 704, 704, 704, 704, 704, 704, + 704, 0, 704, 704, 704, 704, 704, 711, 711, 711, + + 711, 711, 711, 711, 711, 711, 711, 711, 728, 728, + 728, 728, 728, 728, 728, 728, 728, 728, 728, 977, + 984, 977, 984, 704, 704, 704, 0, 704, 746, 746, + 746, 746, 746, 746, 746, 746, 746, 746, 746, 748, + 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, + 977, 984, 977, 984, 704, 704, 704, 704, 704, 704, + 704, 704, 704, 704, 704, 704, 705, 705, 0, 0, + 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, + 705, 705, 705, 705, 705, 705, 705, 705, 708, 708, + 0, 0, 708, 708, 708, 708, 708, 708, 708, 708, + + 708, 708, 708, 708, 708, 708, 708, 708, 708, 708, + 712, 712, 975, 997, 978, 0, 713, 713, 978, 975, + 0, 712, 714, 714, 0, 987, 712, 713, 0, 0, + 0, 0, 713, 714, 0, 716, 716, 985, 714, 985, + 1001, 1003, 987, 975, 997, 978, 716, 747, 0, 978, + 975, 716, 0, 712, 712, 712, 987, 712, 0, 713, + 713, 713, 751, 713, 1002, 714, 714, 714, 985, 714, + 985, 1001, 1003, 987, 708, 708, 1002, 708, 716, 716, + 716, 0, 716, 989, 712, 989, 0, 1005, 0, 762, + 713, 762, 713, 0, 0, 1002, 714, 750, 750, 750, + + 750, 750, 750, 750, 750, 750, 750, 750, 0, 716, + 724, 0, 724, 0, 989, 0, 989, 993, 1005, 998, + 993, 998, 724, 747, 747, 747, 747, 747, 747, 747, + 747, 747, 747, 747, 0, 751, 751, 751, 751, 751, + 751, 751, 751, 751, 751, 751, 763, 0, 993, 0, + 998, 993, 998, 724, 0, 762, 762, 762, 762, 762, + 762, 762, 762, 762, 762, 762, 1100, 1100, 1100, 1108, + 1108, 1108, 0, 1100, 0, 0, 724, 724, 724, 724, + 724, 724, 724, 724, 724, 724, 724, 749, 749, 0, + 0, 749, 749, 0, 0, 749, 749, 749, 749, 749, + + 749, 749, 749, 749, 988, 749, 749, 749, 749, 749, + 0, 988, 763, 763, 763, 763, 763, 763, 763, 763, + 763, 763, 763, 842, 842, 842, 842, 842, 842, 842, + 842, 842, 842, 842, 994, 988, 749, 749, 749, 0, + 749, 846, 988, 0, 0, 0, 0, 1100, 0, 840, + 1108, 994, 976, 999, 1006, 999, 1009, 1016, 840, 0, + 0, 976, 840, 0, 0, 994, 843, 749, 749, 749, + 749, 749, 749, 749, 749, 749, 749, 749, 749, 760, + 840, 760, 994, 976, 999, 1006, 999, 1009, 1016, 840, + 847, 760, 976, 840, 843, 843, 843, 843, 843, 843, + + 843, 843, 843, 843, 843, 846, 846, 846, 846, 846, + 846, 846, 846, 846, 846, 846, 0, 0, 0, 0, + 0, 847, 760, 847, 847, 847, 847, 847, 847, 847, + 847, 847, 847, 847, 848, 849, 1000, 0, 1004, 1010, + 1000, 1010, 1017, 1024, 1004, 760, 760, 760, 760, 760, + 760, 760, 760, 760, 760, 760, 764, 0, 0, 0, + 0, 0, 0, 0, 0, 848, 849, 1000, 764, 1004, + 1010, 1000, 1010, 1017, 1024, 1004, 849, 849, 849, 849, + 849, 849, 849, 849, 849, 849, 849, 850, 848, 848, + 848, 848, 848, 848, 848, 848, 848, 848, 848, 764, + + 0, 0, 0, 1008, 1011, 1014, 1011, 1039, 1014, 851, + 1039, 0, 0, 0, 0, 1008, 0, 868, 850, 0, + 0, 0, 764, 764, 764, 764, 764, 764, 764, 764, + 764, 764, 764, 852, 1008, 1011, 1014, 1011, 1039, 1014, + 851, 1039, 850, 850, 850, 850, 850, 850, 850, 850, + 850, 850, 850, 851, 851, 851, 851, 851, 851, 851, + 851, 851, 851, 851, 852, 867, 867, 867, 867, 867, + 867, 867, 867, 867, 867, 867, 0, 0, 0, 0, + 0, 852, 852, 852, 852, 852, 852, 852, 852, 852, + 852, 852, 854, 868, 868, 868, 868, 868, 868, 868, + + 868, 868, 868, 868, 869, 869, 869, 869, 869, 869, + 869, 869, 869, 869, 869, 854, 870, 873, 873, 873, + 873, 873, 873, 873, 873, 873, 873, 873, 906, 906, + 906, 906, 906, 906, 906, 906, 906, 906, 906, 871, + 0, 1028, 1053, 1028, 1037, 1037, 854, 922, 922, 922, + 922, 922, 922, 922, 922, 922, 922, 922, 854, 854, + 854, 854, 854, 854, 854, 854, 854, 854, 854, 855, + 871, 872, 1028, 1053, 1028, 1037, 1037, 855, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, 871, 870, + 870, 870, 870, 870, 870, 870, 870, 870, 870, 870, + + 1046, 912, 872, 1046, 0, 0, 0, 0, 855, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 872, 872, + 872, 872, 872, 872, 872, 872, 872, 872, 872, 874, + 0, 1046, 912, 0, 1046, 855, 855, 855, 855, 855, + 855, 855, 855, 855, 855, 855, 912, 912, 912, 912, + 912, 912, 912, 912, 912, 912, 912, 874, 874, 874, + 874, 874, 874, 874, 874, 874, 874, 874, 907, 907, + 916, 0, 907, 907, 0, 0, 907, 907, 907, 907, + 907, 907, 907, 907, 907, 913, 907, 907, 907, 907, + 907, 1038, 1026, 1038, 1043, 1043, 1020, 1026, 996, 916, + + 916, 916, 916, 916, 916, 916, 916, 916, 916, 916, + 0, 914, 996, 1020, 1030, 1055, 913, 907, 907, 907, + 0, 907, 1038, 1026, 1038, 1043, 1043, 1020, 1026, 996, + 1030, 913, 913, 913, 913, 913, 913, 913, 913, 913, + 913, 913, 914, 996, 1020, 1030, 1055, 0, 907, 907, + 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, + 915, 1030, 1045, 1067, 1067, 0, 1045, 1082, 914, 914, + 914, 914, 914, 914, 914, 914, 914, 914, 914, 933, + 933, 933, 933, 933, 933, 933, 933, 933, 933, 933, + 0, 915, 0, 1045, 1067, 1067, 926, 1045, 1082, 915, + + 915, 915, 915, 915, 915, 915, 915, 915, 915, 915, + 923, 923, 0, 0, 923, 923, 0, 0, 923, 923, + 923, 923, 923, 923, 923, 923, 923, 926, 923, 923, + 923, 923, 923, 927, 1047, 1083, 1047, 0, 1027, 0, + 1012, 926, 926, 926, 926, 926, 926, 926, 926, 926, + 926, 926, 0, 1012, 1068, 1027, 1084, 1068, 1085, 923, + 923, 923, 0, 923, 927, 1047, 1083, 1047, 945, 1027, + 945, 1012, 927, 927, 927, 927, 927, 927, 927, 927, + 927, 927, 927, 928, 1012, 1068, 1027, 1084, 1068, 1085, + 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, + + 923, 923, 930, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 928, 928, 928, 928, 928, 928, 928, 928, + 928, 928, 928, 0, 0, 0, 0, 0, 0, 0, + 1086, 1087, 0, 930, 945, 945, 945, 945, 945, 945, + 945, 945, 945, 945, 945, 0, 0, 0, 930, 930, + 930, 930, 930, 930, 930, 930, 930, 930, 930, 934, + 934, 1086, 1087, 934, 934, 1088, 0, 934, 934, 934, + 934, 934, 934, 934, 934, 934, 983, 934, 934, 934, + 934, 934, 981, 995, 1013, 983, 981, 1015, 1007, 1007, + 1007, 0, 1018, 995, 1031, 981, 1088, 1022, 1013, 1023, + + 1015, 1018, 1089, 1031, 1022, 1090, 1023, 983, 934, 934, + 934, 0, 934, 981, 995, 1013, 983, 981, 1015, 0, + 1019, 1019, 1019, 1018, 995, 1031, 981, 1007, 1022, 1013, + 1023, 1015, 1018, 1089, 1031, 1022, 1090, 1023, 0, 934, + 934, 934, 934, 934, 934, 934, 934, 934, 934, 934, + 934, 943, 1021, 943, 1025, 1029, 1032, 1033, 1007, 1019, + 1040, 1041, 1029, 943, 1071, 1021, 1044, 1025, 0, 1007, + 0, 1032, 1033, 1040, 1071, 1036, 1036, 1036, 1041, 0, + 1091, 1044, 1093, 1021, 0, 1025, 1029, 1032, 1033, 0, + 1019, 1040, 1041, 1029, 943, 1071, 1021, 1044, 1025, 1035, + + 1035, 1019, 1032, 1033, 1040, 1071, 0, 0, 1035, 1041, + 1035, 1091, 1044, 1093, 1036, 1035, 1042, 943, 943, 943, + 943, 943, 943, 943, 943, 943, 943, 943, 946, 1042, + 1049, 1048, 0, 1051, 1094, 1096, 1050, 946, 1054, 1072, + 1073, 1049, 1035, 1035, 1035, 1036, 1035, 1042, 1048, 1050, + 1051, 1054, 1070, 1072, 1073, 1058, 1036, 1097, 1098, 1099, + 1042, 1049, 1048, 1070, 1051, 1094, 1096, 1050, 946, 1054, + 1072, 1073, 1049, 1035, 0, 1035, 0, 1059, 1052, 1048, + 1050, 1051, 1054, 1070, 1072, 1073, 0, 1052, 1097, 1098, + 1099, 0, 0, 0, 946, 946, 946, 946, 946, 946, + + 946, 946, 946, 946, 946, 973, 0, 973, 1059, 1052, + 0, 1104, 1104, 1104, 1060, 1104, 1076, 973, 1052, 1058, + 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, + 1076, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1059, + 1059, 1059, 0, 0, 0, 1060, 0, 1076, 973, 1060, + 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, + 1061, 1076, 1102, 1102, 1102, 1119, 1119, 1119, 0, 1102, + 0, 973, 973, 973, 973, 973, 973, 973, 973, 973, + 973, 973, 974, 1062, 0, 0, 1124, 1124, 1124, 0, + 0, 1061, 1104, 0, 1061, 1061, 1061, 1061, 1061, 1061, + + 1061, 1061, 1061, 1061, 1061, 0, 1110, 974, 0, 1117, + 0, 1121, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, + 1062, 1062, 1062, 1064, 1064, 1064, 1064, 1064, 1064, 1064, + 1064, 1064, 1064, 1064, 1074, 1075, 1065, 1110, 974, 1065, + 1117, 1074, 1121, 1102, 0, 1075, 1119, 0, 974, 974, + 974, 974, 974, 974, 974, 974, 974, 974, 974, 1034, + 1034, 1034, 1144, 0, 0, 1074, 1075, 1124, 1149, 0, + 1144, 0, 1074, 1115, 1115, 1115, 1075, 1216, 1115, 0, + 1034, 0, 1217, 1034, 1034, 1218, 1115, 1219, 1220, 1134, + 1134, 1134, 1216, 1144, 1034, 1034, 1034, 1063, 0, 1149, + + 1034, 1144, 1065, 1065, 1065, 1065, 1065, 1065, 1065, 1065, + 1065, 1065, 1065, 1217, 1034, 1034, 1218, 0, 1219, 1220, + 0, 0, 0, 1216, 1115, 1034, 1034, 1034, 1063, 1079, + 0, 1034, 1146, 1146, 1146, 1151, 1151, 1151, 1080, 0, + 1034, 1221, 1063, 1063, 1063, 1063, 1063, 1063, 1063, 1063, + 1063, 1063, 1063, 1066, 1115, 0, 1066, 0, 1079, 1079, + 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1080, + 1134, 0, 1221, 1222, 0, 1112, 0, 1263, 1264, 1066, + 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + 1129, 0, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, + + 1080, 1080, 1080, 0, 1222, 1136, 1112, 1136, 1263, 1264, + 1066, 0, 0, 1146, 1266, 0, 1151, 1136, 1268, 1066, + 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, + 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, + 1112, 1113, 1113, 1113, 0, 1266, 1113, 0, 1136, 1268, + 0, 1114, 1114, 1114, 1113, 1269, 1114, 1116, 1116, 1116, + 1127, 0, 1116, 1159, 1114, 1159, 0, 0, 0, 0, + 1116, 0, 1254, 1114, 1254, 1159, 1164, 1164, 1164, 1253, + 1256, 1116, 1270, 1255, 1126, 0, 1269, 0, 1255, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, - 1127, 1141, 1141, 1141, 1170, 1175, 1188, 1189, 0, 1191, - 1190, 1209, 0, 1170, 1813, 1813, 1813, 0, 1211, 0, - 1212, 1357, 1358, 1292, 1219, 1214, 0, 1188, 1292, 1215, - 1189, 1190, 1357, 1209, 1191, 1170, 1175, 1188, 1189, 1175, - - 1191, 1190, 1209, 1211, 1170, 1212, 1214, 1216, 1219, 1211, - 1215, 1212, 1357, 1358, 1292, 1219, 1214, 1170, 1188, 1292, - 1215, 1189, 1190, 1357, 1209, 1191, 1222, 1308, 1359, 1216, - 1362, 1289, 1289, 1289, 1211, 1308, 1212, 1214, 1216, 1219, - 0, 1215, 1141, 1141, 1141, 1141, 1141, 1141, 1141, 1141, - 1141, 1141, 1141, 1142, 1142, 1142, 1813, 1222, 1308, 1359, - 1216, 1362, 1225, 1335, 1365, 1374, 1308, 1376, 1335, 1289, - 0, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, - 1222, 1222, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, - 1223, 1223, 1223, 1225, 1335, 1365, 1374, 0, 1376, 1335, - - 1289, 1142, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, - 1238, 1238, 1238, 1289, 0, 0, 0, 0, 1225, 1225, - 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 0, - 0, 0, 1142, 1307, 1142, 1142, 1142, 1142, 1142, 1142, - 1142, 1142, 1142, 1142, 1142, 1171, 1171, 1171, 1224, 0, - 1171, 1171, 0, 0, 1900, 1900, 1900, 1226, 1307, 0, - 1294, 1171, 1171, 0, 1307, 0, 1294, 1171, 1296, 1291, - 1297, 1300, 1305, 0, 1296, 1379, 1297, 1224, 1224, 1224, - 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1226, 1307, - 1291, 1294, 1300, 1305, 1171, 1171, 1171, 1294, 1171, 1296, - - 1291, 1297, 1300, 1305, 1237, 1296, 1379, 1297, 1380, 1226, - 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, 1226, - 1269, 1291, 0, 1300, 1305, 1171, 0, 1171, 1182, 1182, - 1182, 0, 0, 1182, 1182, 1237, 1900, 0, 0, 1380, - 0, 0, 0, 0, 1182, 1182, 0, 0, 0, 1382, - 1182, 1269, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, - 1237, 1237, 1237, 1270, 1269, 1269, 1269, 1269, 1269, 1269, - 1269, 1269, 1269, 1269, 1269, 0, 1306, 1182, 1182, 1182, - 1382, 1182, 0, 0, 0, 1377, 0, 1383, 1306, 0, - 1377, 1309, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, - - 1270, 1270, 1270, 1309, 1271, 1271, 1271, 1306, 1182, 1271, - 1182, 1203, 1203, 1203, 1274, 1274, 1377, 1271, 1383, 1306, - 1299, 1377, 1309, 1301, 1303, 1274, 1274, 1744, 1744, 1744, - 1271, 1274, 1366, 1384, 1309, 1317, 1203, 1203, 1203, 1203, - 1203, 1744, 1203, 1299, 1203, 1301, 1366, 1317, 1303, 1203, - 0, 1299, 1203, 1203, 1301, 1303, 1203, 1387, 1274, 1274, - 1274, 1271, 1274, 1366, 1384, 0, 1317, 1203, 1203, 1203, - 1203, 1203, 1275, 1203, 1299, 1203, 1301, 1366, 1317, 1303, - 1203, 1276, 1389, 1203, 1203, 0, 1271, 1203, 1387, 1274, - 0, 1274, 0, 1203, 1204, 1204, 1204, 0, 0, 1204, - - 1204, 0, 0, 1275, 0, 0, 0, 0, 0, 1744, - 1204, 1204, 1276, 1389, 0, 1277, 1204, 1391, 0, 1275, - 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, - 0, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, 1276, - 1276, 1276, 1281, 1204, 1204, 1204, 1277, 1204, 1391, 1280, - 1854, 1854, 1854, 0, 0, 0, 1302, 1302, 1302, 1277, - 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, - 1854, 1302, 1282, 1281, 1204, 1392, 1204, 1228, 1280, 1280, - 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 0, - 0, 0, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, - - 1281, 1281, 1281, 1282, 1302, 1228, 1392, 0, 1393, 1394, - 1395, 0, 1285, 1901, 1901, 1901, 1282, 1282, 1282, 1282, - 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1313, 1313, 1313, - 0, 0, 1854, 0, 0, 1302, 1228, 1286, 1302, 1393, - 1394, 1395, 1313, 1285, 1228, 1228, 1228, 1228, 1228, 1228, - 1228, 1228, 1228, 1228, 1228, 1229, 1285, 1285, 1285, 1285, - 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1287, 1286, 1311, - 1322, 1396, 1229, 1361, 1397, 1313, 1322, 1311, 0, 1361, - 0, 0, 0, 0, 1286, 1286, 1286, 1286, 1286, 1286, - 1286, 1286, 1286, 1286, 1286, 1901, 0, 0, 1287, 0, - - 1311, 1322, 1396, 1229, 1361, 1397, 1313, 1322, 1311, 1313, - 1361, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, - 1287, 1287, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, - 1229, 1229, 1229, 1272, 1272, 1272, 1272, 1272, 1272, 1272, - 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, - 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, - 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, - 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, - 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, - 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, - - 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, - 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, 1272, - 1272, 1272, 1272, 1272, 1272, 1272, 1290, 1290, 1290, 0, - 1318, 1290, 1290, 1325, 1319, 1319, 1319, 1328, 1329, 1331, - 1333, 1334, 1290, 1290, 0, 0, 0, 1318, 1290, 1319, - 1325, 1360, 1364, 0, 1398, 1372, 1329, 1402, 1328, 1372, - 1331, 1318, 1334, 1333, 1325, 1336, 1336, 1336, 1328, 1329, - 1331, 1333, 1334, 1364, 1360, 1290, 1290, 1290, 1318, 1290, - 1336, 1325, 1360, 1364, 1348, 1398, 1372, 1329, 1402, 1328, - 1372, 1331, 0, 1334, 1333, 1337, 1348, 1409, 0, 1337, - - 1337, 1367, 0, 0, 1364, 1360, 1290, 1386, 1290, 1363, - 1363, 1363, 1386, 1336, 1424, 1348, 1319, 1321, 1321, 1321, - 1367, 0, 1321, 1321, 1363, 1375, 1337, 1348, 1409, 1375, - 1337, 1337, 1367, 1321, 1321, 0, 0, 0, 1386, 1321, - 0, 0, 0, 1386, 1336, 1424, 0, 1336, 0, 0, - 0, 1367, 1373, 1425, 1378, 1429, 1375, 1363, 1373, 1431, - 1375, 1369, 1378, 0, 1433, 1437, 1321, 1321, 1321, 0, - 1321, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, 1368, - 1368, 1368, 1370, 1373, 1425, 1378, 1429, 0, 1363, 1373, - 1431, 1363, 1369, 1378, 1381, 1433, 1437, 1321, 0, 1321, - - 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, 1369, - 1369, 0, 1438, 1370, 1371, 1371, 1371, 1371, 1371, 1371, - 1371, 1371, 1371, 1371, 1371, 1381, 1370, 1370, 1370, 1370, - 1370, 1370, 1370, 1370, 1370, 1370, 1370, 1399, 0, 0, - 0, 1432, 1436, 1438, 1435, 1442, 1443, 1432, 1381, 1381, - 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 1381, 0, - 0, 0, 0, 1400, 0, 1435, 1442, 1436, 1399, 1401, - 1401, 1401, 1432, 1436, 1401, 1435, 1442, 1443, 1432, 0, - 0, 0, 1401, 1399, 1399, 1399, 1399, 1399, 1399, 1399, - 1399, 1399, 1399, 1399, 1400, 1401, 1435, 1442, 1436, 0, - - 0, 1444, 1434, 0, 1400, 1400, 1400, 1400, 1400, 1400, - 1400, 1400, 1400, 1400, 1400, 1404, 1404, 1404, 0, 1434, - 1404, 0, 1405, 1405, 1405, 1452, 1401, 1405, 1404, 1408, - 1408, 1408, 1444, 1434, 1408, 1405, 1445, 1439, 1439, 1439, - 1453, 1404, 1408, 1446, 1415, 1415, 1415, 0, 1405, 1415, - 1434, 1401, 1439, 1447, 1446, 1408, 1452, 1415, 1448, 1445, - 1415, 1415, 1454, 1458, 0, 0, 0, 1445, 1459, 1454, - 1415, 1453, 1404, 0, 1446, 1448, 1455, 1461, 1447, 1405, - 1449, 1449, 1449, 1462, 1447, 1446, 1408, 1455, 0, 1448, - 1445, 1463, 0, 1454, 1458, 1449, 1418, 1404, 0, 1459, - - 1454, 1415, 0, 0, 1405, 0, 1448, 1455, 1461, 1447, - 0, 1408, 1410, 1410, 1462, 0, 0, 0, 1455, 1439, - 0, 1466, 1463, 1410, 1410, 0, 1415, 1418, 1419, 1410, - 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, - 1417, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, 1418, - 1418, 1418, 1466, 1471, 1472, 1473, 1410, 1410, 1410, 1419, - 1410, 0, 1449, 0, 0, 0, 1419, 1419, 1419, 1419, - 1419, 1419, 1419, 1419, 1419, 1419, 1419, 1906, 1906, 1906, - 1966, 1966, 1966, 0, 1471, 1472, 1473, 1410, 1410, 1410, - 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1413, - - 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, - 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, - 1413, 1413, 1421, 1474, 1475, 1476, 1413, 1427, 1427, 1427, - 1427, 1427, 1427, 1427, 1427, 1427, 1427, 1427, 0, 0, - 0, 0, 0, 0, 1477, 1422, 0, 1478, 1479, 1480, - 1481, 0, 1482, 1421, 1474, 1475, 1476, 1413, 0, 1906, - 0, 0, 1966, 1421, 1421, 1421, 1421, 1421, 1421, 1421, - 1421, 1421, 1421, 1421, 1423, 1477, 1422, 1426, 1478, 1479, - 1480, 1481, 1413, 1482, 0, 0, 1413, 1413, 0, 1413, - 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, - - 1422, 0, 0, 1428, 0, 1423, 1483, 1484, 1426, 1485, - 1486, 1487, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, - 1423, 1423, 1423, 1426, 1426, 1426, 1426, 1426, 1426, 1426, - 1426, 1426, 1426, 1426, 1428, 1460, 0, 1483, 1484, 1488, - 1485, 1486, 1487, 1489, 0, 0, 1460, 1465, 1428, 1428, - 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1441, - 1441, 1441, 1465, 1490, 1441, 1441, 1460, 1464, 1464, 1464, - 1488, 1467, 1491, 1492, 1489, 1441, 1441, 1460, 1465, 0, - 0, 1441, 1464, 1467, 0, 1493, 1494, 0, 1500, 1495, - 0, 0, 1494, 1465, 1490, 1495, 1468, 1468, 1468, 1514, - - 1496, 0, 1467, 1491, 1492, 0, 0, 1506, 1441, 1441, - 1441, 1468, 1441, 0, 1467, 1464, 1493, 1494, 1468, 1500, - 1495, 1496, 1468, 1494, 1501, 1502, 1495, 0, 1506, 1503, - 1514, 1496, 1502, 0, 1468, 1497, 1497, 1497, 1506, 1441, - 1516, 1441, 1451, 1451, 1451, 1501, 1464, 1451, 1451, 1464, - 1497, 0, 1496, 1468, 0, 1501, 1502, 0, 1451, 1451, - 1503, 0, 0, 1502, 1451, 1468, 1505, 1517, 1507, 1510, - 1518, 1516, 0, 1507, 1508, 1505, 1501, 1510, 1468, 1503, - 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, 1503, - 1508, 1451, 1451, 1451, 0, 1451, 0, 1505, 1517, 1507, - - 1510, 1518, 1509, 1504, 1507, 1508, 1505, 1509, 1510, 1511, - 0, 0, 1519, 1520, 1511, 0, 0, 1497, 0, 0, - 0, 1508, 1451, 0, 1451, 1470, 1470, 1470, 1521, 1522, - 1470, 1470, 1512, 1509, 1504, 1523, 1524, 1512, 1509, 1525, - 1511, 1470, 1470, 1519, 1520, 1511, 1513, 1470, 1504, 1504, - 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1504, 1521, - 1522, 1526, 1527, 1512, 1528, 1534, 1523, 1524, 1512, 1536, - 1525, 1541, 1550, 1551, 1470, 1470, 1470, 1513, 1470, 0, - 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, 1513, - 1513, 1529, 1526, 1527, 0, 1528, 1534, 1554, 1555, 0, - - 1536, 1561, 1541, 1550, 1551, 1470, 0, 1470, 1499, 1499, - 1499, 0, 0, 1499, 1499, 0, 0, 1558, 1530, 1555, - 1568, 1569, 1529, 1558, 1499, 1499, 0, 0, 1554, 1555, - 1499, 0, 1561, 0, 0, 0, 0, 1529, 1529, 1529, - 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1529, 1558, 1530, - 1555, 1568, 1569, 0, 1558, 0, 1570, 1499, 1499, 1499, - 1576, 1499, 1530, 1530, 1530, 1530, 1530, 1530, 1530, 1530, - 1530, 1530, 1530, 1531, 1531, 1531, 0, 1570, 1531, 1532, - 1532, 1532, 0, 0, 1532, 0, 1531, 1570, 1499, 1556, - 1499, 1576, 1532, 1533, 1533, 1533, 1580, 0, 1533, 1531, - - 1556, 1582, 1535, 1535, 1535, 1532, 1533, 1535, 1570, 0, - 1562, 1539, 1539, 1539, 1557, 1535, 1539, 1581, 1563, 1533, - 1556, 1563, 1532, 1581, 1539, 1562, 1557, 1580, 1535, 0, - 1531, 1556, 1582, 0, 1564, 1565, 1532, 1539, 1543, 1543, - 1543, 1562, 1583, 1543, 0, 1557, 1565, 1564, 1581, 1563, - 1533, 1543, 1563, 1532, 1581, 1531, 1562, 1557, 1584, 1535, - 1545, 1532, 0, 1588, 1543, 1564, 1565, 0, 1539, 0, - 0, 0, 0, 1583, 0, 1533, 0, 1565, 1564, 0, - 0, 1546, 0, 1590, 1535, 1537, 1537, 1537, 1592, 1584, - 1537, 1545, 0, 1539, 1588, 1543, 0, 0, 1537, 0, - - 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, - 1545, 1537, 1546, 1548, 1590, 0, 1593, 1594, 1595, 1592, - 1543, 1574, 1574, 1574, 0, 0, 1546, 1546, 1546, 1546, - 1546, 1546, 1546, 1546, 1546, 1546, 1546, 0, 0, 0, - 0, 0, 1537, 0, 1548, 0, 1547, 1593, 1594, 1595, - 1596, 1574, 1597, 1548, 1548, 1548, 1548, 1548, 1548, 1548, - 1548, 1548, 1548, 1548, 0, 0, 1537, 1537, 1537, 1537, - 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1547, 1549, 1571, - 1598, 1596, 1574, 1597, 1599, 1600, 1601, 1571, 1552, 1602, - 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, 1547, - - 1547, 0, 0, 1574, 0, 0, 1577, 1577, 1577, 1549, - 1571, 1598, 0, 0, 0, 1599, 1600, 1601, 1571, 1552, - 1602, 1577, 0, 1549, 1549, 1549, 1549, 1549, 1549, 1549, - 1549, 1549, 1549, 1549, 1552, 1552, 1552, 1552, 1552, 1552, - 1552, 1552, 1552, 1552, 1552, 1553, 1553, 1553, 1553, 1553, - 1553, 1553, 1553, 1553, 1553, 1553, 1575, 0, 1591, 1603, - 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1575, 0, - 0, 0, 1612, 1615, 0, 0, 1591, 1616, 1617, 1620, - 1615, 1621, 1622, 1606, 1611, 0, 0, 1575, 1577, 1591, - 1603, 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1575, - - 1579, 1579, 1579, 1612, 1615, 1579, 1579, 1591, 1616, 1617, - 1620, 1615, 1621, 1622, 1606, 1611, 1579, 1579, 0, 0, - 0, 1618, 1579, 1619, 1617, 1617, 1617, 1617, 1617, 1617, - 1617, 1617, 1617, 1617, 1617, 1943, 1943, 1943, 0, 0, - 0, 1623, 1624, 1625, 1619, 1626, 1624, 1629, 1632, 1579, - 1579, 1579, 1618, 1579, 1619, 1943, 0, 0, 0, 0, - 0, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, 1618, - 1618, 1618, 1623, 1624, 1625, 1636, 1626, 1624, 1629, 1632, - 1579, 1639, 1579, 1627, 1627, 1627, 1627, 1627, 1627, 1627, - 1627, 1627, 1627, 1627, 1640, 1641, 1642, 1643, 1644, 1646, - - 1650, 0, 1665, 0, 0, 0, 1636, 0, 0, 1771, - 1771, 1771, 1639, 0, 0, 1666, 0, 1943, 0, 1647, - 1647, 1647, 0, 1771, 1647, 1640, 1641, 1642, 1643, 1644, - 1646, 1650, 1647, 1665, 1644, 1644, 1644, 1644, 1644, 1644, - 1644, 1644, 1644, 1644, 1644, 1647, 1666, 1643, 1643, 1643, - 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1643, 1645, 1645, - 1645, 0, 0, 1645, 1648, 1648, 1648, 0, 0, 1648, - 0, 1645, 0, 1649, 1649, 1649, 1647, 1648, 1649, 0, - 1668, 1645, 0, 1669, 1645, 1670, 1649, 1651, 1651, 1651, - 1648, 1771, 1651, 1652, 1652, 1652, 0, 1670, 1652, 1649, - - 1651, 1647, 0, 1651, 1651, 1672, 1652, 1676, 1683, 1652, - 1652, 1668, 1645, 1651, 1669, 1645, 1670, 0, 1684, 1652, - 0, 1648, 1654, 1654, 1654, 0, 1672, 1654, 1670, 0, - 1649, 0, 1655, 1655, 1655, 1654, 1672, 1655, 1676, 1683, - 1645, 1671, 0, 1689, 1651, 1655, 1648, 1671, 1654, 1684, - 1652, 1656, 1656, 1656, 0, 1649, 1656, 1672, 1655, 0, - 1657, 1657, 1657, 1677, 1656, 1657, 1675, 1675, 1675, 1651, - 1677, 1691, 1671, 1657, 1689, 1652, 1678, 1656, 1671, 1654, - 1658, 1658, 1658, 0, 0, 1658, 1657, 1692, 0, 1655, - 1659, 1659, 1659, 1658, 1677, 1659, 1675, 1678, 1686, 0, - - 0, 1677, 1691, 1659, 1654, 1679, 1658, 1678, 1656, 1682, - 1682, 1682, 1685, 1679, 1655, 1686, 1659, 1657, 1692, 1660, - 1685, 1695, 0, 1658, 1696, 1697, 1698, 1675, 1678, 1686, - 1687, 1687, 1687, 1656, 1702, 1703, 1679, 1658, 1704, 1682, - 1705, 0, 1657, 1685, 1679, 1687, 1686, 1659, 1675, 0, - 1660, 1685, 1695, 1661, 1658, 1696, 1697, 1698, 1706, 1707, - 0, 0, 1658, 0, 0, 1702, 1703, 0, 0, 1704, - 1682, 1705, 1659, 1660, 1660, 1660, 1660, 1660, 1660, 1660, - 1660, 1660, 1660, 1660, 1661, 1662, 1663, 1708, 1710, 1706, - 1707, 1682, 1661, 1661, 1661, 1661, 1661, 1661, 1661, 1661, - - 1661, 1661, 1661, 1711, 1712, 1713, 1714, 1715, 0, 0, - 0, 0, 1687, 0, 0, 0, 1662, 1663, 1708, 1710, - 1664, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, - 1662, 1662, 0, 0, 1711, 1712, 1713, 1714, 1715, 1667, - 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, 1663, - 1663, 1664, 1688, 1688, 1688, 1701, 1701, 1701, 0, 1664, - 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, 1664, - 1667, 1716, 1717, 1719, 1720, 1722, 1723, 1724, 1725, 1726, - 0, 1731, 1688, 1737, 1738, 1701, 1979, 1979, 1979, 1667, - 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, 1667, - - 1727, 1732, 1716, 1717, 1719, 1720, 1722, 1723, 1724, 1725, - 1726, 1727, 1731, 1688, 1737, 1738, 1701, 1730, 1730, 1730, - 1739, 1740, 1741, 1742, 0, 0, 1777, 1777, 1777, 0, - 0, 1727, 1732, 0, 1688, 1733, 1734, 1701, 1735, 1743, - 1736, 1777, 1727, 1735, 1736, 1770, 1734, 1730, 1773, 1774, - 1775, 1739, 1740, 1741, 1742, 1732, 1732, 1732, 1732, 1732, - 1732, 1732, 1732, 1732, 1732, 1732, 1733, 1734, 1979, 1735, - 1743, 1736, 1746, 1776, 1735, 1736, 1770, 1734, 1730, 1773, - 1774, 1775, 0, 0, 0, 1733, 1733, 1733, 1733, 1733, - 1733, 1733, 1733, 1733, 1733, 1733, 1747, 1779, 1781, 1730, - - 1782, 1786, 1788, 1746, 1776, 0, 0, 0, 1777, 0, - 0, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, 1746, - 1746, 1746, 0, 0, 0, 1789, 1794, 1747, 1779, 1781, - 1799, 1782, 1786, 1788, 1800, 0, 1747, 1747, 1747, 1747, - 1747, 1747, 1747, 1747, 1747, 1747, 1747, 1748, 1748, 1748, - 0, 0, 1748, 1750, 1750, 1750, 1789, 1794, 1750, 0, - 1748, 1799, 1751, 1751, 1751, 1800, 1750, 1751, 1801, 1752, - 1752, 1752, 1790, 1748, 1752, 1751, 1804, 1806, 1790, 1750, - 0, 1748, 1752, 1783, 0, 1753, 1753, 1753, 1751, 0, - 1753, 1807, 1755, 1755, 1755, 1752, 1791, 1755, 1753, 1801, - - 1783, 1808, 1791, 1790, 1748, 1755, 1809, 1804, 1806, 1790, - 1750, 1753, 1748, 0, 1783, 1754, 1754, 1754, 1755, 1751, - 1754, 0, 1807, 0, 1810, 1811, 1752, 1791, 1754, 1748, - 0, 1783, 1808, 1791, 0, 1750, 0, 1809, 0, 0, - 1812, 1754, 1753, 0, 1751, 0, 0, 0, 1815, 1755, - 0, 1752, 1756, 1756, 1756, 1810, 1811, 1756, 1754, 0, - 1778, 1778, 1778, 0, 0, 1756, 0, 1753, 1758, 1758, - 1758, 1812, 1754, 1758, 1755, 1759, 1759, 1759, 1756, 1815, - 1759, 1758, 1760, 1760, 1760, 0, 0, 1760, 1759, 1754, - 1778, 1761, 1761, 1761, 1758, 1760, 1761, 1754, 1762, 1762, - - 1762, 1759, 1816, 1762, 1761, 1763, 1763, 1763, 1760, 1756, - 1763, 1762, 1817, 1818, 1764, 1764, 1764, 1761, 1763, 1764, - 1819, 1778, 1820, 1821, 1762, 1758, 0, 1764, 1763, 0, - 1822, 1763, 1759, 1816, 1756, 1825, 1826, 1827, 1829, 1760, - 1764, 1830, 1778, 1817, 1818, 1784, 1784, 1784, 1761, 0, - 1758, 1819, 1831, 1820, 1821, 1762, 0, 1759, 1765, 1763, - 1784, 1822, 1763, 0, 1760, 0, 1825, 1826, 1827, 1829, - 0, 1764, 1830, 1761, 0, 0, 1792, 1792, 1792, 0, - 1762, 0, 0, 1831, 0, 0, 0, 1763, 0, 1765, - 1767, 1792, 0, 1785, 1785, 1785, 1764, 1835, 1840, 1765, - - 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, 1765, - 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, 1766, - 1766, 1767, 1768, 1785, 1981, 1981, 1981, 1784, 1835, 1840, - 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, 1767, - 1767, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, 1769, - 1769, 1769, 1772, 1768, 1785, 1798, 1798, 1798, 1792, 1802, - 1802, 1802, 0, 1768, 1768, 1768, 1768, 1768, 1768, 1768, - 1768, 1768, 1768, 1768, 1802, 1785, 0, 1803, 1803, 1803, - 1823, 1823, 1823, 1772, 1841, 1798, 1842, 1845, 1846, 1848, - 1832, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, 1772, - - 1772, 1772, 1832, 1839, 1852, 1823, 1981, 1803, 1823, 1833, - 1833, 1833, 1867, 0, 1839, 1841, 1798, 1842, 1845, 1846, - 1848, 1832, 1823, 1875, 1833, 1834, 1834, 1834, 0, 1879, - 1849, 1849, 1849, 1832, 1839, 1852, 1823, 1798, 1803, 1823, - 0, 1802, 0, 1867, 1849, 1839, 0, 0, 1869, 1869, - 1869, 0, 1872, 1823, 1875, 1834, 1880, 1881, 0, 1803, - 1879, 1882, 1823, 1828, 0, 1882, 1876, 1872, 1884, 1828, - 1837, 1869, 1876, 1828, 1828, 1868, 1868, 1868, 1828, 1828, - 1828, 0, 1828, 1872, 0, 0, 1834, 1880, 1881, 1868, - 0, 1833, 1882, 0, 1828, 1838, 0, 1876, 1872, 1884, - - 1828, 1837, 1869, 1876, 1828, 1828, 0, 1834, 0, 1828, - 1828, 1828, 1849, 1828, 1837, 1837, 1837, 1837, 1837, 1837, - 1837, 1837, 1837, 1837, 1837, 1887, 1838, 1850, 1850, 1850, - 1869, 0, 1864, 1864, 1864, 1838, 1838, 1838, 1838, 1838, - 1838, 1838, 1838, 1838, 1838, 1838, 1855, 1855, 1855, 0, - 1850, 1855, 1864, 0, 1889, 0, 1887, 1868, 0, 1855, - 1856, 1856, 1856, 1890, 0, 1856, 1857, 1857, 1857, 1850, - 0, 1857, 1855, 1856, 1864, 1858, 1858, 1858, 0, 1857, - 1858, 1850, 1859, 1859, 1859, 1889, 1856, 1859, 1858, 1857, - 1883, 1883, 1857, 0, 1890, 1859, 1891, 0, 0, 0, - - 1850, 1858, 0, 1855, 0, 1864, 0, 0, 1859, 1850, - 1853, 1853, 1853, 1894, 1864, 0, 1895, 1856, 1896, 0, - 1857, 1883, 1883, 1857, 1860, 1860, 1860, 1891, 1855, 1860, - 1853, 0, 1858, 1861, 1861, 1861, 1897, 1860, 1861, 1859, - 1898, 1899, 1856, 1903, 1894, 1905, 1861, 1895, 1857, 1896, - 1860, 0, 0, 1862, 1862, 1862, 0, 1858, 1862, 1861, - 1863, 1863, 1863, 0, 1859, 1863, 1862, 1897, 0, 0, - 0, 1898, 1899, 1863, 1903, 0, 1905, 1907, 1908, 1862, - 1910, 1860, 1886, 1886, 1886, 1911, 1863, 1862, 0, 0, - 1861, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, - - 1853, 1853, 1912, 1913, 0, 1866, 1860, 1914, 1907, 1908, - 1862, 1910, 1886, 0, 0, 1861, 1911, 1863, 1862, 1865, - 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, 1865, - 1915, 0, 1917, 1912, 1913, 1862, 1866, 0, 1914, 0, - 0, 0, 1863, 1886, 1866, 1866, 1866, 1866, 1866, 1866, - 1866, 1866, 1866, 1866, 1866, 1871, 1871, 1871, 1918, 1916, - 0, 1915, 1916, 1917, 1886, 1873, 1873, 1873, 1877, 1877, - 1877, 1885, 1885, 1885, 1919, 1871, 1892, 1892, 1892, 1921, - 1873, 1922, 1920, 1877, 1923, 1924, 1885, 1921, 1926, 1918, - 1916, 1892, 1920, 1916, 1921, 1927, 1928, 1928, 1928, 1930, - - 1934, 1936, 1937, 1939, 1940, 1919, 0, 0, 0, 0, - 1921, 1928, 1922, 1920, 0, 1923, 1924, 0, 1921, 1926, - 1942, 1931, 0, 1920, 0, 1921, 1927, 0, 0, 0, - 1930, 1934, 1936, 1937, 1939, 1940, 1871, 1871, 1871, 1871, - 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1873, 1932, 0, - 1877, 1942, 1931, 1885, 1944, 1944, 1944, 0, 1892, 1931, - 1931, 1931, 1931, 1931, 1931, 1931, 1931, 1931, 1931, 1931, - 1944, 0, 1933, 0, 0, 1938, 1938, 1938, 1928, 1932, - 1933, 0, 0, 1950, 1952, 1957, 0, 1932, 1932, 1932, - 1932, 1932, 1932, 1932, 1932, 1932, 1932, 1932, 1938, 0, - - 1958, 1945, 1945, 1933, 1948, 1948, 1948, 1955, 1955, 1955, - 0, 1933, 1945, 1945, 1950, 1952, 1957, 1938, 1945, 1951, - 1951, 1951, 1959, 1955, 1948, 1946, 1946, 1946, 0, 1938, - 1946, 1958, 1960, 1960, 0, 1961, 1944, 1962, 1946, 1947, - 1947, 1947, 1951, 1963, 1947, 1945, 1945, 1945, 1938, 1945, - 1964, 1946, 1947, 1959, 1965, 0, 1948, 1938, 0, 1946, - 1954, 1954, 1954, 1960, 1960, 1947, 1961, 1964, 1962, 0, - 0, 1969, 1970, 1951, 1963, 0, 1945, 0, 1945, 1949, - 1954, 1964, 1946, 1956, 1956, 1965, 1948, 0, 1971, 1955, - 1946, 1967, 1967, 1967, 1956, 1956, 1947, 0, 1964, 1973, - - 1956, 1951, 1969, 1970, 1974, 1975, 1967, 1946, 1949, 1949, - 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1949, 1971, - 1976, 1947, 1978, 1983, 1984, 1984, 1984, 1956, 1956, 1956, - 1973, 1956, 1985, 1989, 1991, 1974, 1975, 1987, 1987, 1987, - 1992, 1994, 1954, 1995, 1996, 1997, 1998, 1999, 0, 2000, - 2001, 1976, 2002, 1978, 1983, 2004, 2005, 2006, 1956, 2007, - 1956, 2009, 2013, 1985, 1989, 1991, 2016, 2018, 2027, 0, - 0, 1992, 1994, 1967, 1995, 1996, 1997, 1998, 1999, 1987, - 2000, 2001, 2010, 2002, 2011, 0, 2004, 2005, 2006, 0, - 2007, 0, 2009, 2013, 2015, 2015, 2015, 2016, 2018, 2027, - - 2020, 2020, 2020, 2034, 2034, 2034, 1984, 2023, 2023, 2023, - 1987, 0, 2023, 2010, 2015, 2011, 2020, 0, 0, 1987, - 2023, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, - 2010, 2010, 2032, 2023, 2024, 2024, 2024, 2033, 2011, 2011, - 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2012, - 2025, 2026, 2026, 2026, 2024, 2035, 2029, 2029, 2029, 2037, - 2012, 2038, 2039, 2032, 2023, 2024, 2042, 2043, 2033, 0, - 0, 2026, 2029, 2036, 2036, 2036, 2015, 2040, 2040, 2040, - 2012, 2025, 2020, 2044, 2039, 2034, 2035, 2045, 2050, 2023, - 2037, 2012, 2038, 2039, 0, 2052, 2024, 2042, 2043, 2055, - - 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025, - 2025, 2046, 2046, 2046, 2044, 2039, 2024, 2056, 2045, 2050, - 2048, 2048, 2048, 2051, 2051, 2051, 2052, 2053, 2053, 2053, - 2055, 2057, 2058, 2026, 2048, 2059, 2060, 2061, 2029, 2062, - 2063, 2063, 2057, 2064, 2065, 2067, 2068, 2069, 2056, 2070, - 2071, 2074, 2074, 2074, 0, 2036, 2087, 2087, 2087, 2040, - 0, 0, 2057, 2058, 2078, 2076, 2059, 2060, 2061, 2079, - 2062, 2063, 2063, 2080, 2064, 2065, 2067, 2068, 2069, 0, - 2070, 2071, 2075, 2075, 2075, 2075, 2075, 2075, 2075, 2075, - 2075, 2075, 2075, 2046, 2077, 2078, 2076, 2081, 2083, 2084, - - 2079, 2085, 2048, 2086, 2080, 2051, 2077, 0, 2091, 2053, - 2076, 2076, 2076, 2076, 2076, 2076, 2076, 2076, 2076, 2076, - 2076, 2082, 2082, 2082, 0, 2077, 0, 0, 2081, 2083, - 2084, 0, 2085, 2074, 2086, 2092, 2093, 2077, 2087, 2091, - 2095, 2082, 2089, 2089, 2089, 2096, 2097, 2082, 2094, 2094, - 2094, 2100, 2104, 2083, 2083, 2083, 2083, 2083, 2083, 2083, - 2083, 2083, 2083, 2083, 2105, 2108, 2092, 2093, 2098, 2098, - 2098, 2095, 2101, 2101, 2101, 2109, 2096, 2097, 2082, 2102, - 2102, 2102, 2100, 2104, 2110, 0, 2101, 2106, 2106, 2106, - 0, 2112, 2113, 0, 2114, 2105, 2108, 0, 2115, 0, - - 2116, 2117, 2118, 2082, 2119, 2121, 2109, 2122, 2123, 2124, - 2126, 2127, 2127, 2127, 2129, 2110, 2102, 2130, 2131, 0, - 2132, 2102, 2112, 2113, 2089, 2114, 2133, 2130, 2106, 2115, - 2094, 2116, 2117, 2118, 2137, 2119, 2121, 2138, 2122, 2123, - 2124, 2126, 2135, 2135, 2135, 2129, 0, 2102, 2130, 2131, - 2098, 2132, 2102, 0, 2101, 0, 0, 2133, 2130, 2106, - 0, 2102, 2135, 2139, 2140, 2137, 2141, 0, 2138, 2106, - 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, 2129, - 2129, 2136, 2136, 2136, 2136, 2136, 2136, 2136, 2136, 2136, - 2136, 2136, 2146, 2127, 2139, 2140, 2147, 2141, 2142, 2142, - - 2142, 2148, 2148, 2148, 2149, 2150, 2152, 0, 2153, 2154, - 2155, 2156, 0, 2157, 2158, 2160, 2161, 2162, 2163, 2164, - 2165, 2166, 2167, 2146, 2135, 2169, 2172, 2147, 2174, 2175, - 2176, 2177, 2178, 2179, 2180, 2149, 2150, 2152, 2148, 2153, - 2154, 2155, 2156, 2148, 2157, 2158, 2160, 2161, 2162, 2163, - 2164, 2165, 2166, 2167, 2171, 2181, 2169, 2172, 0, 2174, - 2175, 2176, 2177, 2178, 2179, 2180, 0, 0, 2184, 2148, - 2185, 2188, 2189, 2190, 2148, 2191, 2192, 2192, 2192, 2193, - 2142, 2194, 2196, 2148, 2198, 2171, 2181, 2200, 2171, 2171, - 2171, 2171, 2171, 2171, 2171, 2171, 2171, 2171, 2171, 2184, - - 2202, 2185, 2188, 2189, 2190, 2203, 2191, 2205, 2206, 2207, - 2193, 2209, 2194, 2196, 2210, 2198, 2212, 2215, 2200, 2204, - 2204, 2204, 2204, 2204, 2204, 2204, 2204, 2204, 2204, 2204, - 2216, 2202, 2217, 2218, 2219, 2220, 2203, 2222, 2205, 2206, - 2207, 2226, 2209, 2227, 2229, 2210, 2230, 2212, 2215, 2221, - 2221, 2221, 2223, 2223, 2223, 2232, 2234, 2235, 2192, 2237, - 2238, 2216, 2239, 2217, 2218, 2219, 2220, 2240, 2222, 2241, - 2246, 2247, 2226, 2249, 2227, 2229, 2251, 2230, 2242, 2242, - 2242, 2244, 2244, 2244, 2252, 2253, 2232, 2234, 2235, 2255, - 2237, 2238, 2256, 2239, 2257, 2258, 2259, 2260, 2240, 2261, - - 2241, 2246, 2247, 0, 2249, 2262, 2263, 2251, 2264, 2265, - 2266, 2267, 2276, 2276, 2276, 2252, 2253, 2269, 2270, 2271, - 2255, 2272, 2273, 2256, 2274, 2257, 2258, 2259, 2260, 0, - 2261, 2221, 2276, 2277, 2223, 0, 2262, 2263, 2284, 2264, - 2265, 2266, 2267, 2268, 2268, 2268, 2287, 2288, 2269, 2270, - 2271, 2268, 2272, 2273, 2290, 2274, 2278, 2278, 2278, 2291, - 2242, 2294, 2295, 2244, 2277, 2280, 2280, 2280, 2296, 2284, - 2297, 2298, 2300, 2280, 2301, 2302, 2278, 2287, 2288, 2303, - 2305, 2305, 2305, 2306, 2307, 2290, 2308, 2309, 2312, 2314, - 2291, 2315, 2294, 2295, 2276, 2310, 2310, 2310, 2317, 2296, - - 2319, 2297, 2298, 2300, 2320, 2301, 2302, 2313, 2313, 2313, - 2303, 2318, 2318, 2318, 2306, 2307, 0, 2308, 2309, 2312, - 2314, 2321, 2315, 2322, 2323, 2268, 2324, 2268, 0, 2317, - 0, 2319, 2325, 2325, 2325, 2320, 0, 0, 2278, 0, - 0, 0, 0, 0, 0, 0, 0, 2280, 0, 2280, - 0, 0, 2321, 0, 2322, 2323, 0, 2324, 0, 0, - 0, 0, 2305, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2310, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2313, - 0, 0, 0, 2318, 0, 0, 0, 0, 0, 0, + 1253, 1256, 1128, 1254, 1114, 1254, 1159, 1162, 1162, 1162, + 1253, 1256, 1116, 1270, 1255, 1126, 1165, 1165, 1165, 1255, + 0, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, + 1113, 1113, 1114, 1128, 1166, 1166, 1166, 0, 1116, 1126, + 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, + 1163, 1163, 1163, 0, 1162, 1272, 1274, 1164, 1128, 1128, + 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1142, + 0, 1142, 0, 1163, 1259, 1168, 1168, 1168, 0, 1259, + 1166, 1142, 1167, 1167, 1167, 1162, 1272, 1274, 1162, 1170, + 1170, 1170, 0, 0, 1169, 1169, 1169, 1165, 1171, 1171, + + 1171, 1172, 1172, 1172, 1163, 1259, 0, 1175, 1175, 1175, + 1259, 1166, 1142, 0, 0, 1166, 1168, 1167, 1169, 1173, + 1173, 1173, 1174, 1174, 1174, 0, 1275, 1172, 1276, 1170, + 0, 1163, 0, 1175, 0, 1142, 1142, 1142, 1142, 1142, + 1142, 1142, 1142, 1142, 1142, 1142, 1143, 1168, 1167, 1169, + 1176, 1176, 1176, 1260, 1143, 1173, 1168, 1275, 1172, 1276, + 1170, 1174, 1277, 1167, 1175, 1177, 1177, 1177, 0, 0, + 1170, 1178, 1178, 1178, 1260, 1169, 1176, 1292, 1293, 1171, + 0, 0, 1172, 0, 1260, 1143, 1173, 0, 1175, 1179, + 1179, 1179, 1174, 1277, 0, 1177, 0, 1180, 1180, 1180, + + 1173, 0, 0, 1174, 1183, 1183, 1183, 1176, 1292, 1293, + 0, 1178, 1143, 1143, 1143, 1143, 1143, 1143, 1143, 1143, + 1143, 1143, 1143, 1160, 0, 1160, 1177, 1180, 1303, 1341, + 1179, 1176, 1181, 1181, 1181, 1160, 1182, 1182, 1182, 1186, + 1186, 1186, 1178, 1188, 1188, 1188, 1177, 1185, 1185, 1185, + 0, 0, 1178, 1342, 0, 1181, 0, 0, 1180, 1303, + 1341, 1179, 1187, 1187, 1187, 0, 1160, 1184, 1184, 1184, + 1179, 0, 1193, 1193, 1193, 1185, 1186, 1353, 1180, 0, + 1189, 1189, 1189, 0, 1342, 1183, 1181, 1182, 1187, 1160, + 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, + + 1161, 1161, 1161, 0, 0, 0, 1185, 1186, 1353, 1311, + 1190, 1190, 1190, 1181, 1161, 0, 0, 1182, 1184, 1187, + 1186, 1189, 0, 1311, 1188, 0, 0, 0, 1185, 0, + 1191, 1191, 1192, 1192, 1192, 1195, 1195, 1195, 1190, 1191, + 1311, 1191, 0, 1187, 0, 1369, 1191, 1190, 1184, 0, + 1195, 0, 1189, 1193, 1311, 1194, 1194, 1194, 1198, 1198, + 1198, 1189, 1192, 0, 0, 1196, 1196, 1196, 0, 1190, + 1199, 1199, 1199, 1191, 1191, 1191, 1369, 1191, 1190, 1370, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, + 1161, 1190, 1371, 1192, 1194, 1196, 1197, 1197, 1197, 1198, + + 1200, 1200, 1200, 0, 1191, 0, 1191, 1201, 1201, 1201, + 1370, 1202, 1202, 1192, 1372, 0, 1195, 1204, 1204, 1204, + 1202, 1374, 1202, 1371, 0, 1194, 1196, 1202, 0, 0, + 1198, 1257, 1197, 1205, 1205, 1205, 1194, 0, 0, 1198, + 1376, 1200, 1257, 1378, 1201, 1372, 1196, 1203, 1203, 1203, + 0, 1199, 1374, 0, 1202, 1202, 1202, 0, 1202, 1206, + 1206, 1206, 1257, 1197, 1207, 1207, 1207, 1208, 1208, 1208, + 0, 1376, 1200, 1257, 1378, 1201, 0, 1197, 1209, 1209, + 1209, 1200, 1210, 1210, 1210, 1202, 1203, 1202, 1201, 1211, + 1211, 1211, 0, 1208, 1212, 1212, 1212, 0, 1204, 1213, + + 1213, 1213, 1209, 0, 1207, 1214, 1214, 1214, 1368, 1215, + 1215, 1215, 1368, 1368, 1205, 1211, 1212, 1203, 1227, 1227, + 1227, 1229, 1229, 1229, 1208, 1231, 1231, 1231, 1203, 1226, + 1226, 1226, 0, 1209, 1213, 1207, 1258, 1379, 0, 1368, + 1206, 1214, 1258, 1368, 1368, 1207, 1211, 1212, 1208, 0, + 1215, 1381, 0, 1225, 1225, 1228, 1228, 1228, 1226, 1209, + 0, 0, 1225, 1210, 1225, 1213, 0, 1258, 1379, 1225, + 1211, 0, 1214, 1258, 0, 1212, 1234, 1234, 1234, 0, + 1213, 1215, 1381, 1230, 1230, 1230, 1214, 0, 0, 1226, + 1215, 1224, 1224, 1224, 0, 1228, 1225, 1225, 1225, 1227, + + 1225, 0, 1229, 1238, 1238, 1238, 1231, 1382, 1230, 0, + 1226, 1239, 1239, 1239, 1224, 1224, 1224, 1224, 1224, 1224, + 0, 1224, 1383, 1224, 1384, 1224, 1228, 1225, 1224, 1225, + 1385, 1224, 1224, 0, 0, 1224, 1228, 0, 1382, 1230, + 1237, 1237, 1237, 0, 0, 1224, 1224, 1224, 1224, 1224, + 1224, 1239, 1224, 1383, 1224, 1384, 1224, 1234, 1308, 1224, + 1308, 1385, 1224, 1224, 1230, 1237, 1224, 1232, 1232, 1232, + 1308, 0, 1224, 1233, 1233, 1233, 1235, 1235, 1235, 1236, + 1236, 1236, 1239, 1310, 1238, 1240, 1240, 1240, 1314, 1232, + 1314, 0, 1239, 0, 1310, 1233, 1237, 1241, 1241, 1241, + + 1314, 1308, 1235, 1244, 1377, 1236, 1386, 1377, 1240, 1242, + 1242, 1242, 0, 0, 1310, 1380, 1387, 0, 0, 1388, + 1232, 1237, 1281, 1281, 1281, 1310, 1233, 1380, 1409, 1281, + 1387, 1314, 1241, 1235, 1245, 1377, 1236, 1386, 1377, 1240, + 0, 0, 1285, 1285, 1285, 0, 1380, 1387, 1232, 1285, + 1388, 0, 0, 0, 1233, 0, 0, 1235, 1380, 1409, + 1236, 1387, 0, 1241, 0, 1245, 1240, 1244, 1244, 1244, + 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1244, 1241, 1245, + 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, + 1242, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, + + 1246, 1246, 1247, 1281, 0, 0, 0, 0, 0, 0, + 0, 1248, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, + 1262, 1262, 1262, 1285, 1411, 1413, 1249, 1320, 1320, 1320, + 0, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, 1247, + 1247, 1247, 1248, 1289, 1289, 1289, 1413, 1289, 0, 1322, + 1322, 1322, 1325, 1325, 1325, 1411, 1413, 1249, 1331, 1331, + 1331, 1294, 0, 1319, 1319, 1319, 0, 1248, 1248, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1249, 1249, + 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1251, + 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, 1294, + + 1294, 0, 1309, 1407, 1309, 1319, 1415, 1407, 1320, 0, + 1309, 1329, 1329, 1329, 1309, 1412, 1251, 0, 1410, 1261, + 1412, 0, 1410, 1416, 1289, 0, 1329, 1295, 1295, 1295, + 1322, 0, 1295, 1325, 1407, 0, 1319, 1415, 1407, 1331, + 1295, 1309, 0, 0, 1319, 1309, 1412, 1251, 1299, 1410, + 1261, 1412, 1295, 1410, 1416, 1251, 1251, 1251, 1251, 1251, + 1251, 1251, 1251, 1251, 1251, 1251, 1252, 1261, 1261, 1261, + 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1418, 1299, + 1419, 1420, 1252, 1295, 0, 1304, 0, 0, 0, 0, + 0, 0, 1329, 0, 1424, 1299, 1299, 1299, 1299, 1299, + + 1299, 1299, 1299, 1299, 1299, 1299, 0, 0, 1295, 1418, + 0, 1419, 1420, 1252, 1304, 1304, 1304, 1304, 1304, 1304, + 1304, 1304, 1304, 1304, 1304, 1424, 0, 0, 0, 0, + 0, 0, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, + 1252, 1252, 1252, 1296, 1296, 1296, 1296, 1296, 1296, 1296, + 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, + 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, + 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, + 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, + 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, + + 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, + 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, + 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, + 1296, 1296, 1296, 1296, 1296, 1298, 1298, 1300, 1426, 1337, + 1337, 1337, 1321, 1321, 1321, 1428, 1298, 1316, 1316, 1316, + 0, 1298, 0, 0, 1301, 0, 0, 0, 0, 0, + 0, 1339, 1339, 1339, 1351, 1351, 1351, 0, 1300, 1426, + 0, 1340, 1340, 1340, 0, 0, 1428, 0, 1298, 1298, + 1298, 1305, 1298, 1321, 1316, 1301, 1340, 1300, 1300, 1300, + 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1301, 1301, + + 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1298, + 0, 1298, 1305, 1306, 1321, 1316, 0, 1318, 1318, 1318, + 1337, 0, 1429, 1321, 0, 0, 0, 0, 1316, 0, + 0, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, 1305, + 1305, 1305, 1339, 1318, 1306, 1351, 1323, 1323, 1323, 1324, + 1324, 1324, 1340, 1429, 1315, 1315, 1315, 1306, 1306, 1306, + 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1306, 1315, 0, + 1315, 0, 1317, 1317, 1318, 0, 1326, 1326, 1326, 0, + 1315, 1317, 1430, 1317, 1327, 1327, 1327, 1323, 1317, 0, + 1324, 1330, 1330, 1330, 1431, 1328, 1328, 1328, 1318, 0, + + 1326, 0, 1332, 1332, 1332, 1333, 1333, 1333, 1433, 0, + 1327, 1315, 1434, 1430, 1330, 1317, 1317, 1317, 1323, 1317, + 1328, 1324, 1334, 1334, 1334, 1431, 0, 1323, 1332, 0, + 1324, 1326, 1336, 1336, 1336, 1315, 1345, 1345, 1345, 1433, + 1333, 1327, 1435, 1434, 1334, 1330, 1317, 0, 1317, 0, + 0, 1328, 1335, 1335, 1335, 0, 0, 1326, 0, 1332, + 1338, 1338, 1338, 0, 0, 1327, 1345, 1336, 1350, 1350, + 1350, 1333, 1330, 1435, 0, 1334, 1328, 1344, 1344, 1344, + 1346, 1346, 1346, 1332, 0, 0, 1333, 1349, 1349, 1349, + 1408, 1335, 0, 1348, 1348, 1346, 1408, 1345, 1336, 1338, + + 1414, 1350, 1348, 1334, 1348, 1352, 1352, 1352, 1414, 1348, + 0, 1438, 1344, 1336, 1359, 1359, 1359, 1345, 1355, 1355, + 1355, 1408, 1335, 1356, 1356, 1356, 1445, 1408, 1349, 1422, + 1338, 1414, 1350, 1335, 1422, 1352, 1348, 1348, 1348, 1414, + 1348, 1338, 1438, 1344, 1355, 1463, 1356, 0, 0, 1350, + 1358, 1358, 1358, 1468, 1360, 1360, 1360, 1445, 1344, 1349, + 1422, 1346, 1357, 1357, 0, 1422, 1352, 1348, 1349, 1348, + 0, 1357, 1464, 1357, 0, 1355, 1463, 1356, 1357, 1358, + 1360, 1361, 1361, 1361, 1468, 1464, 1352, 1363, 1363, 1363, + 1364, 1364, 1364, 0, 0, 1359, 1365, 1365, 1365, 1355, + + 1366, 1366, 1366, 1464, 1356, 1357, 1357, 1357, 0, 1357, + 1358, 1360, 1362, 1362, 1364, 1361, 1464, 1367, 1367, 1367, + 0, 1362, 1365, 1362, 1390, 1390, 1390, 1491, 1362, 0, + 1492, 1358, 1367, 0, 0, 1360, 1357, 0, 1357, 1391, + 1391, 1391, 1366, 0, 0, 1364, 1361, 1392, 1392, 1392, + 1395, 1395, 1395, 1365, 1500, 1362, 1362, 1362, 1491, 1362, + 1390, 1492, 1361, 1393, 1393, 1393, 1502, 0, 1363, 0, + 0, 1364, 1506, 1366, 1394, 1394, 1394, 1365, 1396, 1396, + 1396, 1366, 1397, 1397, 1397, 1500, 1362, 1393, 1362, 0, + 1514, 1390, 1515, 1396, 1398, 1398, 1398, 1502, 1367, 0, + + 1399, 1399, 1399, 1506, 1461, 1390, 1461, 1516, 1397, 1400, + 1400, 1400, 1517, 0, 1518, 1394, 1461, 1462, 1393, 1462, + 1391, 1514, 1519, 1515, 0, 1462, 1520, 1402, 1392, 1462, + 1466, 1395, 1466, 1399, 1452, 1452, 1452, 1400, 1516, 1397, + 1521, 1522, 1466, 1517, 1393, 1518, 1394, 1461, 1523, 1524, + 0, 0, 1525, 1519, 0, 1394, 1462, 1520, 1526, 1396, + 1462, 0, 0, 1397, 1399, 0, 0, 0, 1400, 0, + 0, 1521, 1522, 1466, 0, 1398, 1470, 1470, 1470, 1523, + 1524, 1399, 1404, 1525, 0, 1472, 1472, 1472, 1405, 1526, + 1400, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, 1402, + + 1402, 1402, 1403, 1403, 1403, 1403, 1403, 1403, 1403, 1403, + 1403, 1403, 1403, 1404, 0, 1452, 0, 0, 0, 1405, + 0, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, 1404, + 1404, 1404, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1405, + 1405, 1405, 1405, 1406, 1406, 1406, 1406, 1406, 1406, 1406, + 1406, 1406, 1406, 1406, 1417, 1436, 1527, 1470, 1476, 1476, + 1476, 1528, 1529, 1437, 1437, 1437, 1472, 0, 1437, 1440, + 1440, 1440, 0, 0, 1440, 0, 1437, 1473, 1473, 1473, + 0, 0, 1440, 0, 0, 1417, 1436, 1527, 1437, 1477, + 1477, 1477, 1528, 1529, 1440, 0, 1436, 1436, 1436, 1436, + + 1436, 1436, 1436, 1436, 1436, 1436, 1436, 1473, 1417, 1417, + 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1437, + 1530, 1441, 1441, 1441, 0, 1440, 1441, 1444, 1444, 1444, + 0, 1531, 1444, 1532, 1441, 1471, 1471, 1471, 1473, 1476, + 1444, 1474, 1474, 1474, 1437, 0, 1441, 1467, 1467, 1467, + 1440, 1530, 1444, 0, 0, 1451, 1451, 1451, 1473, 0, + 1451, 1467, 1531, 1467, 1532, 1533, 1534, 1474, 1451, 0, + 1477, 1451, 1535, 1467, 1536, 1537, 1471, 1441, 0, 0, + 1451, 1538, 1539, 1444, 1453, 1453, 1453, 1453, 1453, 1453, + 1453, 1453, 1453, 1453, 1453, 1454, 1533, 1534, 1474, 1478, + + 1478, 1478, 1441, 1535, 1467, 1536, 1537, 1471, 1444, 1446, + 1446, 1451, 1538, 1539, 1478, 0, 1471, 0, 0, 0, + 1446, 0, 1474, 0, 1455, 1446, 1454, 0, 1467, 1563, + 1554, 0, 0, 0, 0, 0, 1451, 1482, 1482, 1482, + 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, 1454, + 1454, 1554, 1446, 1446, 1446, 1455, 1446, 1483, 1483, 1483, + 1563, 1554, 1455, 1455, 1455, 1455, 1455, 1455, 1455, 1455, + 1455, 1455, 1455, 1497, 1497, 1497, 0, 0, 0, 0, + 1478, 0, 0, 1446, 1446, 1446, 1446, 1446, 1446, 1446, + 1446, 1446, 1446, 1446, 1446, 1449, 1449, 1449, 1449, 1449, + + 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1449, + 1449, 1449, 1449, 1449, 1449, 1449, 1449, 1457, 1482, 1565, + 1566, 1449, 1475, 1475, 1475, 1498, 1498, 1498, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1483, 0, + 1458, 0, 0, 0, 1475, 1567, 0, 0, 1457, 0, + 1565, 1566, 1449, 0, 1497, 1488, 1488, 1488, 1457, 1457, + 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1457, 1459, + 1488, 1458, 1487, 1487, 1487, 1475, 1567, 1449, 1481, 1481, + 1481, 1449, 1449, 0, 1449, 1458, 1458, 1458, 1458, 1458, + 1458, 1458, 1458, 1458, 1458, 1458, 1484, 1484, 1484, 0, + + 1459, 0, 1487, 1475, 1481, 0, 1498, 1459, 1459, 1459, + 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1480, 1480, + 1484, 1485, 1485, 1485, 1493, 1493, 1493, 1480, 0, 1480, + 1486, 1486, 1486, 1487, 1480, 1481, 1488, 1494, 1494, 1494, + 1499, 1499, 1499, 1501, 1501, 1501, 1504, 1504, 1504, 0, + 0, 1484, 1486, 1487, 1508, 1508, 1508, 1485, 0, 1481, + 0, 1480, 1480, 1480, 1493, 1480, 1505, 1505, 1505, 1490, + 1490, 0, 1568, 1494, 0, 1553, 1499, 1484, 1490, 0, + 1490, 1505, 0, 1486, 1553, 1490, 1508, 0, 1485, 1509, + 1509, 1509, 1480, 0, 1480, 1493, 1510, 1510, 1510, 0, + + 0, 1569, 1485, 1568, 1494, 1493, 1553, 1499, 1540, 1540, + 1540, 1486, 1490, 1490, 1490, 1553, 1490, 1508, 1494, 0, + 0, 1499, 0, 0, 1501, 1556, 0, 1504, 1541, 1541, + 1541, 1510, 1569, 0, 0, 1508, 1511, 1511, 1511, 1513, + 1513, 1556, 0, 1490, 1570, 1490, 0, 1505, 1513, 1540, + 1513, 1511, 1543, 1543, 1543, 1513, 1556, 1511, 1546, 1546, + 1546, 1511, 1510, 0, 1542, 1542, 1542, 1543, 1571, 1541, + 1509, 1572, 1556, 1511, 1555, 1570, 0, 1510, 0, 1555, + 1540, 0, 1513, 1513, 1513, 0, 1513, 1545, 1545, 1540, + 1542, 0, 1511, 1547, 1547, 1547, 1545, 0, 1545, 1571, + + 1541, 0, 1572, 1545, 1511, 1555, 1548, 1548, 1548, 1541, + 1555, 1557, 1558, 1513, 0, 1513, 1557, 1511, 0, 1547, + 1558, 1542, 1559, 1560, 1550, 1573, 1574, 1559, 1560, 1575, + 1545, 1545, 1545, 1543, 1545, 1561, 1576, 1577, 1578, 1546, + 1561, 1583, 1557, 1558, 1585, 1542, 1548, 1557, 0, 1551, + 1547, 1558, 1590, 1559, 1560, 1602, 1573, 1574, 1559, 1560, + 1575, 1545, 0, 1545, 0, 0, 1561, 1576, 1577, 1578, + 0, 1561, 1583, 0, 1547, 1585, 0, 1548, 0, 1552, + 1551, 0, 1606, 1590, 1620, 0, 1602, 1548, 1550, 1550, + 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1551, + + 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, 1551, + 1552, 1562, 1579, 1606, 0, 1620, 1613, 1613, 1613, 0, + 0, 0, 0, 0, 1552, 1552, 1552, 1552, 1552, 1552, + 1552, 1552, 1552, 1552, 1552, 0, 1634, 1634, 1634, 1621, + 1628, 0, 1562, 1579, 0, 1562, 1562, 1562, 1562, 1562, + 1562, 1562, 1562, 1562, 1562, 1562, 1579, 1579, 1579, 1579, + 1579, 1579, 1579, 1579, 1579, 1579, 1579, 1580, 1580, 1580, + 1621, 1628, 1580, 1581, 1581, 1581, 0, 0, 1581, 0, + 1580, 0, 1582, 1582, 1582, 0, 1581, 1582, 1584, 1584, + 1584, 0, 1580, 1584, 1600, 1582, 1600, 1613, 1581, 0, + + 1604, 1584, 1604, 1588, 1588, 1588, 1600, 1582, 1588, 1592, + 1592, 1592, 1604, 1584, 1592, 1581, 1588, 1634, 1601, 0, + 1601, 0, 1592, 1580, 1629, 0, 1601, 1633, 1588, 1581, + 1601, 0, 0, 1636, 1592, 0, 0, 1600, 1582, 0, + 0, 0, 1637, 1604, 1584, 1638, 1581, 1642, 1580, 0, + 1610, 1610, 1610, 0, 1581, 1629, 1594, 1601, 1633, 1588, + 0, 1601, 1595, 1582, 1636, 1592, 1605, 1605, 1605, 1584, + 1586, 1586, 1586, 1637, 0, 1586, 1638, 0, 1642, 0, + 1605, 0, 1605, 1586, 1588, 0, 0, 1594, 1596, 1644, + 1592, 1610, 1605, 1595, 1646, 1586, 1594, 1594, 1594, 1594, + + 1594, 1594, 1594, 1594, 1594, 1594, 1594, 1595, 1595, 1595, + 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1595, 1647, 1596, + 1644, 0, 1610, 1605, 0, 1646, 1586, 0, 0, 0, + 1597, 1610, 1596, 1596, 1596, 1596, 1596, 1596, 1596, 1596, + 1596, 1596, 1596, 1607, 1607, 1607, 0, 1605, 0, 1647, + 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, 1586, + 1586, 1597, 1598, 1608, 1608, 1608, 1609, 1609, 1609, 1607, + 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, + 1597, 1615, 1615, 1615, 0, 0, 1614, 1614, 1614, 1616, + 1616, 1616, 0, 1598, 1622, 1622, 1622, 0, 1648, 1608, + + 1607, 1609, 1617, 1617, 1617, 0, 0, 1598, 1598, 1598, + 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1598, 1614, 1645, + 1622, 1649, 1650, 1616, 1607, 1615, 1623, 1623, 1623, 1648, + 1608, 0, 1609, 1652, 1626, 1626, 1626, 1645, 1617, 1627, + 1627, 1627, 1653, 0, 1608, 0, 0, 1609, 0, 1614, + 1645, 1622, 1649, 1650, 1616, 1651, 1615, 1630, 1630, 1630, + 1654, 1655, 1615, 1626, 1652, 1623, 1651, 1614, 1645, 1617, + 1616, 1656, 1630, 1653, 1627, 1622, 1635, 1635, 1635, 1632, + 1632, 1657, 1658, 1617, 0, 1659, 1651, 1660, 1632, 0, + 1632, 1654, 1655, 0, 1626, 1632, 1623, 1651, 1661, 1663, + + 1662, 1664, 1656, 1665, 1666, 1627, 1675, 1623, 1667, 1667, + 1667, 0, 1657, 1658, 0, 1626, 1659, 1635, 1660, 0, + 1627, 1662, 1632, 1632, 1632, 0, 1632, 1679, 1680, 1661, + 1663, 1662, 1664, 1678, 1665, 1666, 1681, 1682, 1630, 1668, + 1668, 1668, 1669, 1669, 1669, 1672, 1672, 1672, 1635, 1673, + 1673, 1673, 1662, 1632, 1678, 1632, 1676, 1635, 1679, 1680, + 0, 1683, 1685, 1686, 1678, 1683, 1689, 1681, 1682, 1668, + 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, 1675, + 1675, 0, 1692, 1684, 1693, 1672, 1697, 1676, 1700, 1667, + 1684, 1677, 1683, 1685, 1686, 0, 1683, 1689, 1701, 0, + + 1668, 0, 1676, 1676, 1676, 1676, 1676, 1676, 1676, 1676, + 1676, 1676, 1676, 1692, 1684, 1693, 1672, 1697, 0, 1700, + 1668, 1684, 1677, 1669, 1702, 1703, 1672, 1704, 1706, 1701, + 1673, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, 1677, + 1677, 1677, 1687, 1687, 1687, 1687, 1687, 1687, 1687, 1687, + 1687, 1687, 1687, 1710, 0, 1702, 1703, 1731, 1704, 1706, + 0, 1746, 0, 1704, 1704, 1704, 1704, 1704, 1704, 1704, + 1704, 1704, 1704, 1704, 1705, 1705, 1705, 0, 1747, 1705, + 1707, 1707, 1707, 0, 1710, 1707, 0, 1705, 1731, 1708, + 1708, 1708, 1746, 1707, 1708, 1752, 1705, 1755, 0, 1705, + + 0, 1726, 1708, 1726, 0, 1707, 1709, 1709, 1709, 1747, + 0, 1709, 1756, 1726, 1708, 0, 1711, 1711, 1711, 1709, + 0, 1711, 1732, 1732, 1732, 0, 1752, 1705, 1755, 1711, + 1705, 1709, 1711, 1712, 1712, 1712, 1707, 0, 1712, 0, + 0, 1711, 0, 1756, 1726, 1708, 1712, 0, 0, 1712, + 0, 1714, 1714, 1714, 0, 1705, 1714, 1759, 1712, 1761, + 0, 1707, 1709, 0, 1714, 0, 1715, 1715, 1715, 0, + 1708, 1715, 1711, 1716, 1716, 1716, 1714, 0, 1716, 1715, + 1717, 1717, 1717, 0, 0, 1717, 1716, 1709, 1759, 1712, + 1761, 1715, 0, 1717, 1735, 1735, 1735, 1711, 1716, 1718, + + 1718, 1718, 0, 1732, 1718, 1717, 0, 1714, 1719, 1719, + 1719, 0, 1718, 1719, 1712, 1729, 0, 1729, 1762, 1763, + 1735, 1719, 1715, 1727, 1718, 1727, 1767, 1729, 1768, 1716, + 0, 1727, 1714, 1719, 1769, 1727, 1717, 1720, 1770, 1771, + 0, 1718, 1733, 1733, 1733, 1772, 0, 1715, 1773, 1762, + 1763, 1735, 1775, 1776, 1716, 1718, 1777, 1767, 1729, 1768, + 0, 1717, 1727, 0, 1719, 1769, 1727, 0, 1720, 1770, + 1771, 1721, 1718, 0, 0, 1735, 1772, 1733, 1778, 1773, + 1718, 0, 0, 1775, 1776, 0, 0, 1777, 0, 1719, + 1722, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, 1720, + + 1720, 1720, 1721, 1734, 1734, 1734, 1723, 1724, 1733, 1778, + 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, 1721, + 1721, 1722, 0, 1733, 0, 0, 1722, 1722, 1722, 1722, + 1722, 1722, 1722, 1722, 1722, 1722, 1722, 1723, 1724, 1739, + 1739, 1739, 0, 1779, 1734, 0, 1724, 1724, 1724, 1724, + 1724, 1724, 1724, 1724, 1724, 1724, 1724, 1730, 1730, 1730, + 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, 1723, + 1723, 1730, 0, 1730, 1779, 1734, 1738, 1738, 1738, 1740, + 1740, 1740, 1780, 1730, 1734, 1741, 1741, 1741, 1742, 1742, + 1742, 0, 1745, 1745, 1745, 1748, 1748, 1748, 1749, 1749, + + 1749, 1750, 1750, 1750, 1781, 1738, 0, 0, 1751, 1751, + 1751, 1741, 1782, 1780, 1730, 0, 1750, 1783, 1784, 1740, + 1739, 1745, 1754, 1754, 1754, 1786, 0, 1742, 1749, 1760, + 1760, 1760, 1787, 1789, 1748, 1781, 1738, 1751, 1730, 1774, + 1774, 1774, 1741, 1782, 1790, 1766, 1766, 1766, 1783, 1784, + 1740, 0, 1745, 1785, 1785, 1785, 1786, 1738, 1742, 1749, + 1740, 1791, 1792, 1787, 1789, 1748, 1741, 1793, 1751, 1742, + 1794, 1795, 0, 1745, 1766, 1790, 1748, 0, 0, 1749, + 1805, 0, 1750, 1796, 1796, 1796, 1799, 1799, 1799, 1751, + 1805, 1809, 1791, 1792, 1800, 1800, 1800, 1803, 1793, 1806, + + 1810, 1794, 1795, 1754, 1806, 1766, 0, 1811, 1808, 1807, + 1760, 1805, 1802, 1807, 1813, 1799, 1814, 1815, 1816, 1796, + 1774, 1805, 1809, 0, 0, 0, 1766, 0, 1803, 1808, + 1806, 1810, 1848, 0, 1785, 1806, 0, 1804, 1811, 1808, + 1807, 0, 0, 1854, 1807, 1813, 1799, 1814, 1815, 1816, + 1796, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1803, + 1803, 1803, 0, 1848, 1796, 0, 0, 1799, 1804, 0, + 1849, 1849, 1849, 1819, 1854, 1800, 1802, 1802, 1802, 1802, + 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1804, 1804, 1804, + 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1817, 1817, + + 1817, 1850, 1850, 1850, 1819, 1861, 1851, 1851, 1851, 0, + 0, 1863, 1817, 1819, 1819, 1819, 1819, 1819, 1819, 1819, + 1819, 1819, 1819, 1819, 1820, 1820, 1820, 0, 1864, 1820, + 1822, 1822, 1822, 0, 0, 1822, 1861, 1820, 0, 1823, + 1823, 1823, 1863, 1822, 1823, 1824, 1824, 1824, 0, 1820, + 1824, 1849, 1823, 1869, 1843, 1822, 1843, 1820, 1824, 1864, + 1825, 1825, 1825, 0, 1823, 1825, 1843, 1871, 1875, 1846, + 1824, 1846, 1876, 1825, 0, 1853, 1853, 1853, 0, 1817, + 1820, 1846, 1850, 0, 1869, 1825, 1822, 1851, 1820, 1826, + 1826, 1826, 0, 0, 1826, 1823, 1877, 1843, 1871, 1875, + + 0, 1824, 1826, 1876, 1853, 1820, 1878, 0, 1827, 1827, + 1827, 1822, 1846, 1827, 1826, 1881, 1825, 1828, 1828, 1828, + 1823, 1827, 1828, 1830, 1830, 1830, 1824, 1877, 1830, 1883, + 1828, 1826, 0, 1827, 0, 1853, 1830, 1878, 1831, 1831, + 1831, 1825, 1828, 1831, 0, 1826, 1881, 1844, 1830, 1844, + 1884, 1831, 1832, 1832, 1832, 1844, 1853, 1832, 0, 1844, + 1883, 0, 1826, 1831, 1827, 1832, 1885, 1833, 1833, 1833, + 1826, 0, 1833, 1828, 1856, 1856, 1856, 1832, 1886, 1830, + 1833, 1884, 1834, 1834, 1834, 0, 1844, 1834, 0, 1827, + 1844, 0, 1833, 1887, 1831, 1834, 1888, 1885, 1828, 0, + + 1835, 1835, 1835, 0, 1830, 1835, 1889, 1834, 1832, 1886, + 0, 1892, 1893, 1835, 1894, 1836, 1836, 1836, 1895, 1831, + 1836, 1896, 1835, 1833, 1887, 1835, 1897, 1888, 1836, 1852, + 1852, 1852, 0, 1832, 1857, 1857, 1857, 1889, 1834, 1898, + 1836, 1837, 1892, 1893, 1852, 1894, 0, 1899, 1833, 1895, + 0, 0, 1896, 1835, 0, 1856, 1835, 1897, 1859, 1859, + 1859, 0, 1900, 1834, 1867, 1867, 1867, 0, 0, 0, + 1898, 1836, 1837, 1859, 0, 0, 0, 1839, 1899, 1867, + 0, 1835, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, + 1837, 1837, 1837, 1900, 0, 0, 1836, 1838, 1838, 1838, + + 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1838, 1839, 1840, + 1852, 1858, 1858, 1858, 0, 1857, 0, 1839, 1839, 1839, + 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1839, 1841, 1841, + 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1841, 1859, + 1840, 1858, 1860, 1860, 1860, 1867, 1901, 1847, 1847, 1847, + 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, 1840, + 1840, 1847, 0, 1847, 1865, 1865, 1865, 1866, 1866, 1866, + 1904, 1860, 1858, 1847, 1874, 1874, 1874, 1901, 1879, 1879, + 1879, 1880, 1880, 1880, 1890, 1890, 1890, 1905, 1902, 1902, + 1902, 1906, 1858, 1879, 1907, 1909, 1910, 0, 0, 1911, + + 1912, 1904, 1860, 1874, 1847, 1865, 1916, 1923, 1866, 1924, + 1880, 1926, 1902, 0, 0, 1902, 0, 0, 1905, 0, + 0, 0, 1906, 1860, 0, 1907, 1909, 1910, 1847, 1902, + 1911, 1912, 1929, 1922, 1874, 1930, 1865, 1916, 1923, 1866, + 1924, 1880, 1926, 1902, 1922, 1865, 1902, 1925, 1866, 1913, + 1913, 1913, 1914, 1914, 1914, 1874, 0, 1925, 0, 1879, + 1902, 1931, 1880, 1929, 1922, 1890, 1930, 1914, 1932, 1902, + 1908, 1915, 1915, 1915, 1919, 1922, 1908, 0, 1925, 1937, + 1908, 1908, 1957, 1960, 1913, 1908, 1908, 1908, 1925, 1908, + 1964, 1952, 1931, 1952, 1934, 1934, 1934, 1957, 1965, 1932, + + 1915, 1908, 0, 1952, 0, 0, 0, 1908, 1934, 0, + 1937, 1908, 1908, 1957, 1960, 1913, 1908, 1908, 1908, 1920, + 1908, 1964, 1966, 1969, 1970, 1973, 1975, 1976, 1957, 1965, + 1913, 1915, 0, 1914, 1952, 1935, 1935, 1935, 1919, 1919, + 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1919, 1921, + 1920, 1977, 1915, 1966, 1969, 1970, 1973, 1975, 1976, 1958, + 1958, 1958, 0, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1958, 1934, 1935, 1972, 1972, 1972, + 1921, 0, 1977, 0, 0, 1962, 1962, 1962, 0, 1921, + 1921, 1921, 1921, 1921, 1921, 1921, 1921, 1921, 1921, 1921, + + 1962, 1978, 0, 1953, 0, 1953, 1972, 1935, 0, 0, + 0, 1953, 1967, 1967, 1967, 1953, 1935, 1938, 1938, 1938, + 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1939, 1939, + 1939, 0, 1978, 1939, 1940, 1940, 1940, 1972, 1981, 1940, + 1958, 1939, 1953, 1941, 1941, 1941, 1953, 1940, 1941, 1942, + 1942, 1942, 0, 1939, 1942, 1955, 1941, 1955, 1972, 1940, + 1982, 1983, 1942, 1967, 0, 1941, 1962, 1955, 1941, 1981, + 1943, 1943, 1943, 0, 1942, 1943, 1944, 1944, 1944, 1984, + 0, 1944, 0, 1943, 1939, 1971, 1971, 1971, 0, 1944, + 1940, 1982, 1983, 1967, 0, 1943, 1941, 0, 1955, 1941, + + 1971, 1944, 1956, 1956, 1956, 1942, 1945, 1945, 1945, 1939, + 1984, 1945, 1946, 1946, 1946, 1940, 1956, 1946, 1956, 1945, + 0, 1985, 1986, 1990, 1941, 1946, 1943, 0, 1956, 1994, + 1942, 1945, 1944, 1947, 1947, 1947, 1996, 1946, 1947, 1997, + 1999, 2000, 2001, 2002, 2003, 1946, 1947, 0, 1979, 1979, + 1979, 1943, 1985, 1986, 1990, 1948, 0, 1944, 1947, 1956, + 1994, 0, 1945, 1979, 0, 0, 1971, 1996, 1946, 0, + 1997, 1999, 2000, 2001, 2002, 2003, 1946, 1987, 1987, 1987, + 1968, 1968, 1968, 1956, 0, 0, 1948, 1945, 0, 1947, + 1961, 1961, 1961, 1946, 1948, 1948, 1948, 1948, 1948, 1948, + + 1948, 1948, 1948, 1948, 1948, 1950, 1988, 1988, 1988, 1992, + 1992, 1992, 2005, 0, 1947, 1949, 1949, 1949, 1949, 1949, + 1949, 1949, 1949, 1949, 1949, 1949, 1968, 0, 2007, 1979, + 0, 1961, 1993, 1993, 1993, 2008, 1950, 1995, 1995, 1995, + 2004, 2004, 2004, 2005, 1950, 1950, 1950, 1950, 1950, 1950, + 1950, 1950, 1950, 1950, 1950, 2009, 0, 1968, 1987, 2007, + 2006, 1968, 1961, 2006, 2010, 2011, 2008, 2012, 2013, 2014, + 2016, 1961, 2017, 2011, 2010, 2018, 2018, 2018, 2021, 2023, + 2011, 2026, 2019, 2019, 2019, 2024, 2009, 1988, 2028, 2026, + 1992, 2006, 0, 0, 2006, 2010, 2011, 2019, 2012, 2013, + + 2014, 2016, 0, 2017, 2011, 2010, 2027, 2029, 2031, 2021, + 2027, 2011, 2026, 1993, 0, 0, 2024, 0, 1995, 2028, + 2026, 2004, 0, 2024, 2024, 2024, 2024, 2024, 2024, 2024, + 2024, 2024, 2024, 2024, 2025, 2032, 2034, 2027, 2029, 2031, + 2036, 2027, 0, 2023, 2023, 2023, 2023, 2023, 2023, 2023, + 2023, 2023, 2023, 2023, 0, 0, 2018, 2033, 2033, 2033, + 0, 0, 2047, 2019, 0, 2025, 2032, 2034, 0, 2048, + 0, 2036, 0, 2025, 2025, 2025, 2025, 2025, 2025, 2025, + 2025, 2025, 2025, 2025, 2037, 2037, 2037, 2049, 2051, 2037, + 2038, 2038, 2038, 2047, 2042, 2038, 2042, 2037, 2033, 2045, + + 2048, 2045, 2043, 2038, 2043, 2052, 2042, 0, 2053, 2037, + 2043, 2045, 0, 2060, 2043, 2038, 2062, 2037, 2049, 2051, + 2039, 2050, 2050, 2050, 2055, 2055, 2055, 0, 0, 2033, + 2054, 2054, 2054, 2056, 2056, 2056, 2052, 2042, 2033, 2053, + 2037, 2043, 2045, 2040, 2060, 2043, 2038, 2062, 2037, 2039, + 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, 2039, + 2054, 2057, 2057, 2057, 2063, 2037, 0, 2050, 0, 2065, + 0, 2038, 2040, 2040, 2040, 2040, 2040, 2040, 2040, 2040, + 2040, 2040, 2040, 2046, 2046, 2046, 2058, 2058, 2058, 2066, + 2067, 2054, 2068, 2070, 2075, 2063, 0, 2046, 2050, 2046, + + 2065, 2058, 2050, 2077, 0, 2055, 2071, 2071, 2071, 2046, + 2085, 2054, 0, 0, 2056, 2073, 2073, 2073, 2087, 2088, + 2066, 2067, 2092, 2068, 2070, 2075, 2076, 2076, 2076, 2078, + 2078, 2078, 2093, 0, 2077, 2080, 2080, 2080, 2094, 2095, + 2046, 2085, 2057, 2083, 2083, 2083, 2090, 2090, 2090, 2087, + 2088, 2096, 2097, 2092, 2098, 0, 0, 2099, 2100, 2102, + 2103, 2080, 2078, 2093, 2046, 2110, 2104, 2058, 2105, 2094, + 2095, 2106, 2108, 2115, 2116, 2080, 0, 2118, 2132, 2132, + 2132, 2120, 2096, 2097, 2083, 2098, 2090, 2071, 2099, 2100, + 2102, 2103, 2080, 2078, 2130, 2131, 2073, 2104, 0, 2105, + + 0, 0, 2106, 2108, 2115, 2116, 2080, 2076, 2118, 2111, + 2078, 2112, 2120, 0, 0, 2083, 2080, 2090, 2133, 2133, + 2133, 0, 0, 0, 2083, 2130, 2131, 2090, 0, 2110, + 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, 2110, + 2111, 0, 2112, 2134, 2134, 2134, 0, 0, 2111, 2111, + 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2111, 2132, + 0, 0, 2135, 0, 2136, 2112, 2112, 2112, 2112, 2112, + 2112, 2112, 2112, 2112, 2112, 2112, 2113, 2114, 2121, 2121, + 2121, 2142, 2125, 2121, 2125, 2122, 2114, 2113, 0, 2143, + 2126, 2121, 2126, 2135, 2125, 2136, 2123, 2144, 2126, 2133, + + 0, 2145, 2126, 2121, 2138, 2138, 2138, 2113, 2114, 2146, + 2146, 2146, 2142, 2151, 2151, 2151, 2122, 2114, 2113, 2128, + 2143, 2128, 0, 0, 2134, 2125, 2150, 2123, 2144, 2126, + 2152, 2128, 2145, 2126, 2121, 2122, 2122, 2122, 2122, 2122, + 2122, 2122, 2122, 2122, 2122, 2122, 2123, 2123, 2123, 2123, + 2123, 2123, 2123, 2123, 2123, 2123, 2123, 2150, 0, 2121, + 0, 2152, 2128, 2129, 2129, 2129, 2137, 2137, 2137, 2140, + 2140, 2140, 2148, 2148, 2148, 2155, 2156, 2129, 2157, 2129, + 2153, 2153, 2153, 2158, 2159, 2138, 2148, 2160, 2161, 2129, + 2146, 2137, 2162, 2163, 2151, 2164, 2165, 2166, 2160, 2167, + + 2167, 2168, 2140, 2169, 2171, 2172, 2155, 2156, 2173, 2157, + 2174, 2175, 2181, 0, 2158, 2159, 0, 2184, 2160, 2161, + 2129, 2186, 2137, 2162, 2163, 0, 2164, 2165, 2166, 2184, + 2167, 2167, 2168, 2140, 2169, 2171, 2172, 0, 0, 2173, + 0, 2174, 2175, 2183, 2129, 0, 0, 2137, 2184, 0, + 2140, 0, 2186, 2148, 2179, 2179, 2179, 0, 0, 0, + 2184, 2153, 2182, 2182, 2182, 2182, 2182, 2182, 2182, 2182, + 2182, 2182, 2182, 2187, 2183, 2188, 2181, 2181, 2181, 2181, + 2181, 2181, 2181, 2181, 2181, 2181, 2181, 2185, 2183, 2183, + 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2183, 2189, + + 2185, 2190, 2191, 2194, 2187, 2194, 2188, 2197, 2195, 2197, + 2195, 2199, 2200, 2192, 2205, 2194, 2195, 0, 2185, 2197, + 2195, 2206, 2198, 2198, 2198, 2201, 2201, 2201, 0, 0, + 2189, 2185, 2190, 2191, 0, 2179, 2198, 0, 2198, 2203, + 2203, 2203, 2199, 2200, 2192, 2205, 2194, 2195, 2198, 2208, + 2197, 2195, 2206, 2207, 2207, 2207, 2210, 2191, 2191, 2191, + 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2192, 2192, + 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2192, 2198, + 2208, 2209, 2209, 2209, 2211, 2212, 2215, 2210, 2213, 2213, + 2213, 2216, 2216, 2216, 2217, 2217, 2217, 2219, 2220, 2221, + + 2221, 2221, 2223, 2198, 0, 2216, 2201, 2224, 0, 2225, + 2226, 2227, 2228, 2230, 2231, 2211, 2212, 2215, 2232, 2233, + 2203, 2234, 2235, 2236, 2237, 2238, 2240, 2241, 2219, 2220, + 2217, 2249, 2242, 2223, 2207, 2217, 2243, 2245, 2224, 2221, + 2225, 2226, 2227, 2228, 2230, 2231, 2246, 2246, 2246, 2232, + 2233, 2250, 2234, 2235, 2236, 2237, 2238, 2240, 2241, 2253, + 2254, 2217, 2209, 2242, 0, 0, 2217, 2243, 2245, 2213, + 2221, 0, 2216, 0, 0, 2217, 0, 2271, 2271, 2271, + 2221, 2261, 2250, 2261, 0, 0, 0, 0, 2252, 2256, + 2253, 2254, 2252, 2261, 2266, 2249, 2249, 2249, 2249, 2249, + + 2249, 2249, 2249, 2249, 2249, 2249, 0, 2250, 2250, 2250, + 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2251, 2252, + 2256, 0, 0, 2252, 2261, 2266, 2267, 2246, 2251, 2258, + 2258, 2258, 2258, 2258, 2258, 2258, 2258, 2258, 2258, 2258, + 2262, 2264, 2262, 2264, 2268, 2269, 2270, 2275, 2262, 2251, + 2276, 2278, 2262, 2264, 2277, 2277, 2277, 2267, 2271, 2251, + 2259, 2259, 2259, 2259, 2259, 2259, 2259, 2259, 2259, 2259, + 2259, 2265, 2265, 2265, 2279, 2268, 2269, 2270, 2275, 2262, + 2281, 2276, 2278, 2262, 2264, 2265, 2282, 2265, 2283, 2284, + 2277, 2285, 2286, 2287, 2288, 2277, 2289, 2265, 2290, 2292, + + 2293, 2294, 2295, 2296, 2305, 2279, 2297, 2298, 2299, 2300, + 2302, 2281, 2307, 2310, 2311, 2318, 2319, 2282, 2320, 2283, + 2284, 2277, 2285, 2286, 2287, 2288, 2277, 2289, 2265, 2290, + 2292, 2293, 2294, 2295, 2296, 2277, 0, 2297, 2298, 2299, + 2300, 2302, 0, 2307, 2310, 2311, 2318, 2319, 2306, 2320, + 2321, 2313, 2265, 2313, 0, 2316, 0, 2316, 0, 0, + 0, 0, 0, 2313, 0, 2322, 0, 2316, 2305, 2305, + 2305, 2305, 2305, 2305, 2305, 2305, 2305, 2305, 2305, 2306, + 2323, 2321, 2306, 2306, 2306, 2306, 2306, 2306, 2306, 2306, + 2306, 2306, 2306, 2308, 2313, 2314, 2322, 2314, 2316, 2317, + + 2317, 2317, 2308, 2314, 2326, 2327, 2330, 2314, 2331, 2332, + 2333, 2323, 2336, 2317, 2337, 2317, 2334, 2334, 2334, 2338, + 2339, 2341, 2342, 2344, 2308, 2317, 2346, 2348, 2349, 0, + 0, 0, 0, 2308, 2314, 2326, 2327, 2330, 2314, 2331, + 2332, 2333, 2351, 2336, 2353, 2337, 2355, 2363, 0, 0, + 2338, 2339, 2341, 2342, 2344, 0, 2317, 2346, 2348, 2349, + 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, + 2352, 2364, 2367, 2370, 2357, 2353, 2357, 2355, 2363, 2358, + 2317, 2358, 2360, 0, 2360, 0, 2357, 2358, 2376, 2376, + 2376, 2358, 2371, 2372, 2360, 2373, 2374, 2334, 2375, 2377, + + 2380, 2381, 2364, 2367, 2370, 0, 2351, 2351, 2351, 2351, + 2351, 2351, 2351, 2351, 2351, 2351, 2351, 2357, 2358, 2361, + 2361, 2361, 2358, 2371, 2372, 2360, 2373, 2374, 2383, 2375, + 2377, 2380, 2381, 2361, 2384, 2361, 2378, 2378, 2378, 2385, + 2387, 2388, 2406, 2406, 2406, 2361, 2391, 2391, 2391, 2391, + 2391, 2391, 2391, 2391, 2391, 2391, 2391, 2399, 2401, 2383, + 2402, 2394, 2403, 2394, 2404, 2384, 2395, 2405, 2395, 2376, + 2385, 2387, 2388, 2394, 2395, 2397, 2361, 2397, 2395, 2410, + 2398, 2398, 2398, 2408, 2408, 2408, 0, 2397, 2399, 2401, + 2413, 2402, 0, 2403, 2398, 2404, 2398, 2416, 2405, 2419, + + 2361, 2412, 2412, 2412, 2394, 2395, 2398, 2427, 0, 2395, + 2410, 2428, 2421, 2424, 2421, 2424, 0, 2378, 2397, 2429, + 2430, 2413, 2431, 2406, 2421, 2424, 0, 2422, 2416, 2422, + 2419, 2425, 2425, 2425, 2432, 2422, 2433, 2398, 2427, 2422, + 2436, 2437, 2428, 2438, 0, 2425, 0, 2425, 0, 0, + 2429, 2430, 2444, 2431, 0, 2421, 2424, 2425, 2434, 2434, + 2434, 2398, 0, 0, 2408, 2432, 2422, 2433, 2446, 0, + 2422, 2436, 2437, 2447, 2438, 2440, 2448, 2440, 2441, 2443, + 2441, 2443, 2412, 2444, 2449, 2434, 2441, 2440, 2425, 2450, + 2441, 2443, 2445, 2445, 2445, 2451, 2452, 2454, 2462, 2446, + + 2445, 2456, 2465, 2456, 2447, 2466, 2467, 2448, 0, 2469, + 2470, 2473, 2425, 2456, 2474, 2449, 2434, 2441, 2440, 2475, + 2450, 2441, 2443, 2458, 2458, 2458, 2451, 2452, 2454, 2462, + 2476, 2458, 2477, 2465, 2480, 2481, 2466, 2467, 2482, 2434, + 2469, 2470, 2473, 2483, 2456, 2474, 2478, 2478, 2478, 2488, + 2475, 2485, 2485, 2485, 2486, 2486, 2486, 2489, 2490, 2491, + 2494, 2476, 2495, 2477, 0, 2480, 2481, 2497, 2498, 2482, + 2492, 2492, 2492, 2445, 2483, 2445, 2496, 2496, 2496, 2499, + 2488, 2501, 2502, 2502, 2502, 2503, 2504, 2505, 2489, 2490, + 2491, 2494, 2506, 2495, 2507, 2486, 0, 2508, 2497, 2498, + + 2510, 0, 2511, 2512, 2458, 0, 2458, 2513, 2513, 2513, + 2499, 0, 2501, 0, 0, 0, 2503, 2504, 2505, 0, + 0, 0, 0, 2506, 0, 2507, 2486, 2478, 2508, 0, + 0, 2510, 2485, 2511, 2512, 2486, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2325, 2327, 2327, 2327, 2327, 2327, - 2327, 2327, 2327, 2327, 2327, 2327, 2327, 2327, 2327, 2327, - 2327, 2327, 2327, 2327, 2328, 2328, 2328, 2328, 2328, 2328, - 2328, 2328, 2328, 2328, 2328, 2328, 2328, 2328, 2328, 2328, - 2328, 2328, 2328, 2329, 2329, 2329, 2329, 2329, 2329, 2329, - 2329, 2329, 2329, 2329, 2329, 2329, 2329, 2329, 2329, 2329, - 2329, 2329, 2330, 2330, 2330, 2330, 2330, 2330, 2330, 2330, - 2330, 2330, 2330, 2330, 2330, 2330, 2330, 2330, 2330, 2330, - 2330, 2331, 2331, 2331, 2331, 2331, 2331, 2331, 2331, 2331, - - 2331, 2331, 2331, 2331, 2331, 2331, 2331, 2331, 2331, 2331, - 2332, 2332, 2332, 2332, 2332, 2332, 2332, 2332, 2332, 2332, - 2332, 2332, 2332, 2332, 2332, 2332, 2332, 2332, 2332, 2333, - 2333, 2333, 2333, 2333, 2333, 2333, 2333, 2333, 2333, 2333, - 2333, 2333, 2333, 2333, 2333, 2333, 2333, 2333, 2334, 2334, - 2334, 2334, 2334, 2334, 2334, 2334, 2334, 2334, 2334, 2334, - 2334, 2334, 2334, 2334, 2334, 2334, 2334, 2335, 2335, 2335, - 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, 2335, - 2335, 2335, 2335, 2335, 2335, 2335, 2336, 2336, 2336, 2336, - 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, 2336, - - 2336, 2336, 2336, 2336, 2336, 2337, 2337, 2337, 2337, 2337, - 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, 2337, - 2337, 2337, 2337, 2337, 2338, 2338, 2338, 2338, 2338, 2338, - 2338, 2338, 2338, 2338, 2338, 2338, 2338, 2338, 2338, 2338, - 2338, 2338, 2338, 2339, 2339, 2339, 2339, 2339, 2339, 2339, - 2339, 2339, 2339, 2339, 2339, 2339, 2339, 2339, 2339, 2339, - 2339, 2339, 2340, 2340, 2340, 2340, 2340, 2340, 2340, 2340, - 2340, 2340, 2340, 2340, 2340, 2340, 2340, 2340, 2340, 2340, - 2340, 2341, 2341, 2341, 2341, 2341, 2341, 2341, 2341, 2341, - 2341, 2341, 2341, 2341, 2341, 2341, 2341, 2341, 2341, 2341, - - 2342, 2342, 2342, 2342, 2342, 2342, 2342, 2342, 2342, 2342, - 2342, 2342, 2342, 2342, 2342, 2342, 2342, 2342, 2342, 2343, - 2343, 2343, 0, 0, 0, 0, 2343, 0, 0, 0, - 0, 2343, 2343, 2343, 2343, 2344, 2344, 0, 2344, 2344, - 2344, 2344, 2344, 2344, 2344, 2344, 2344, 2344, 2344, 2344, - 2344, 2344, 2344, 2344, 2345, 2345, 0, 0, 0, 0, - 2345, 0, 0, 0, 0, 2345, 2345, 2345, 2345, 2346, - 2346, 2346, 0, 0, 0, 2346, 0, 0, 0, 0, - 2346, 2346, 2346, 2346, 2347, 2347, 0, 0, 0, 0, - 2347, 0, 0, 0, 2347, 2347, 2347, 2347, 2347, 2348, - - 0, 2348, 2348, 2348, 2348, 2348, 2348, 2348, 2349, 2349, - 0, 0, 0, 0, 2349, 0, 0, 0, 0, 2349, - 2349, 2349, 2349, 2350, 0, 2350, 2350, 2350, 2350, 2350, - 2350, 2351, 2351, 0, 2351, 2351, 0, 2351, 2351, 2351, - 2351, 0, 0, 0, 0, 2351, 2351, 2351, 2351, 2352, - 0, 2352, 2352, 2352, 2352, 2353, 2353, 2353, 0, 0, - 0, 0, 2353, 0, 0, 0, 0, 2353, 2353, 2353, - 2353, 2354, 2354, 0, 0, 0, 0, 2354, 0, 0, - 0, 0, 2354, 2354, 2354, 2354, 2355, 2355, 2355, 0, - 0, 0, 2355, 0, 0, 0, 0, 2355, 2355, 2355, - - 2355, 2356, 2356, 0, 0, 0, 0, 2356, 0, 0, - 0, 2356, 2356, 2356, 2356, 2356, 2357, 0, 2357, 2357, - 2357, 2357, 2358, 0, 0, 2358, 0, 2358, 2359, 0, - 0, 2359, 0, 2359, 2360, 2360, 2360, 2360, 2360, 2360, - 0, 2360, 2360, 2360, 2360, 2360, 2360, 0, 2360, 2360, - 2360, 2360, 2360, 2361, 2361, 2361, 2361, 2361, 2361, 2361, - 2361, 2361, 2361, 2361, 2361, 2361, 2361, 2361, 2361, 2361, - 2361, 2361, 2362, 2362, 2362, 2362, 2362, 2362, 0, 2362, - 2362, 2362, 2362, 2362, 2362, 0, 2362, 2362, 2362, 2362, - 2362, 2363, 2363, 2363, 2363, 2363, 2363, 2363, 2363, 2363, - - 2363, 2363, 2363, 2363, 2363, 2363, 2363, 2363, 2363, 2363, - 2364, 2364, 2364, 2364, 2364, 2364, 2364, 2364, 2364, 2364, - 2364, 2364, 2364, 2364, 2364, 2364, 2364, 2364, 2364, 2365, - 2365, 2365, 2365, 2365, 2365, 2365, 2365, 2365, 2365, 2365, - 2365, 2365, 2365, 0, 2365, 2365, 2365, 2365, 2366, 2366, - 2366, 2366, 2366, 2366, 2366, 2366, 2366, 2366, 2366, 2366, - 2366, 2366, 0, 2366, 2366, 2366, 2366, 2367, 2367, 0, - 2367, 2367, 2367, 2367, 2367, 2367, 2367, 2367, 2367, 2367, - 2367, 2367, 2367, 2367, 2367, 2367, 2368, 2368, 0, 0, - 0, 0, 2368, 0, 0, 0, 0, 2368, 2368, 2368, - - 2368, 2369, 0, 2369, 2369, 2369, 2369, 2369, 2370, 2370, - 0, 2370, 2370, 2370, 2370, 2370, 2370, 2370, 2370, 2370, - 2370, 2370, 2370, 2370, 2370, 2370, 2370, 2371, 2371, 0, - 2371, 2371, 2371, 2371, 2371, 2371, 2371, 2371, 2371, 2371, - 2371, 2371, 2371, 2371, 2371, 2371, 2372, 2372, 0, 0, - 0, 0, 2372, 0, 0, 0, 0, 2372, 2372, 2372, - 2372, 2373, 0, 2373, 2373, 2373, 2373, 2373, 2373, 2374, - 2374, 0, 0, 0, 0, 2374, 0, 0, 0, 0, - 2374, 2374, 2374, 2374, 2375, 0, 2375, 2375, 2375, 2375, - 2376, 2376, 0, 2376, 2376, 2376, 2376, 2376, 2376, 2376, - - 2376, 2376, 2376, 2376, 2376, 2376, 2376, 2376, 2376, 2377, - 2377, 0, 0, 0, 0, 2377, 0, 0, 0, 0, - 2377, 2377, 2377, 2377, 2378, 0, 2378, 2378, 2378, 2378, - 0, 0, 2378, 2379, 2379, 0, 2379, 2379, 2379, 2379, - 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, - 2379, 2379, 2380, 2380, 0, 2380, 2380, 2380, 2380, 2380, - 2380, 2380, 2380, 2380, 2380, 2380, 2380, 2380, 2380, 2380, - 2380, 2381, 2381, 2381, 0, 0, 0, 0, 2381, 0, - 0, 0, 0, 2381, 2381, 2381, 2381, 2382, 0, 2382, - 2382, 2382, 2382, 2383, 2383, 0, 2383, 2383, 2383, 2383, - - 2383, 2383, 2383, 2383, 2383, 2383, 2383, 2383, 2383, 2383, - 2383, 2383, 2384, 2384, 0, 2384, 2384, 2384, 2384, 2384, - 2384, 2384, 2384, 2384, 2384, 2384, 2384, 2384, 2384, 2384, - 2384, 2385, 2385, 0, 2385, 2385, 2385, 2385, 2385, 2385, - 2385, 2385, 2385, 2385, 2385, 2385, 2385, 2385, 2385, 2385, - 2386, 2386, 0, 0, 0, 0, 2386, 0, 0, 0, - 0, 2386, 2386, 2386, 2386, 2387, 0, 2387, 2387, 2387, - 2387, 2388, 2388, 2388, 0, 0, 0, 2388, 0, 0, - 0, 0, 2388, 2388, 2388, 2388, 2389, 0, 2389, 2389, - 2389, 2389, 2390, 2390, 0, 0, 0, 0, 2390, 0, - - 0, 0, 2390, 2390, 2390, 2390, 2390, 2391, 0, 2391, - 2391, 2391, 2391, 2392, 2392, 0, 0, 0, 0, 2392, - 0, 0, 0, 0, 2392, 2392, 2392, 2392, 2393, 0, - 2393, 2393, 2393, 2393, 2394, 2394, 0, 2394, 2394, 0, - 2394, 2394, 2394, 2394, 0, 0, 0, 0, 2394, 2394, - 2394, 2394, 2395, 0, 2395, 2395, 2395, 2395, 2396, 2396, - 2396, 0, 0, 0, 0, 2396, 0, 0, 0, 0, - 2396, 2396, 2396, 2396, 2397, 0, 2397, 2397, 2397, 2397, - 2398, 2398, 0, 0, 0, 0, 2398, 0, 0, 0, - 0, 2398, 2398, 2398, 2398, 2399, 0, 2399, 2399, 2399, - - 2399, 2400, 2400, 2400, 0, 0, 0, 2400, 0, 0, - 0, 0, 2400, 2400, 2400, 2400, 2401, 0, 2401, 2401, - 2401, 2401, 2402, 2402, 0, 0, 0, 0, 2402, 0, - 0, 0, 2402, 2402, 2402, 2402, 2402, 2403, 0, 2403, - 2403, 2403, 2403, 2404, 0, 0, 2404, 0, 2404, 2405, - 0, 0, 2405, 0, 2405, 2406, 2406, 2406, 2406, 2406, - 2406, 0, 2406, 2406, 2406, 2406, 2406, 2406, 0, 2406, - 2406, 2406, 2406, 2406, 2407, 2407, 0, 2407, 2407, 2407, - 2407, 2407, 2407, 2407, 2407, 2407, 2407, 2407, 2407, 2407, - 2407, 2407, 2407, 2408, 2408, 2408, 2408, 2408, 2408, 0, - - 2408, 2408, 2408, 2408, 2408, 2408, 0, 2408, 2408, 2408, - 2408, 2408, 2409, 2409, 0, 2409, 2409, 2409, 2409, 2409, - 2409, 2409, 2409, 2409, 2409, 2409, 2409, 2409, 2409, 2409, - 2409, 2410, 2410, 0, 2410, 2410, 2410, 2410, 2410, 2410, - 2410, 2410, 2410, 2410, 2410, 2410, 2410, 2410, 2410, 2410, - 2411, 2411, 2411, 2411, 2411, 2411, 2411, 2411, 2411, 2411, - 2411, 2411, 2411, 2411, 0, 2411, 2411, 2411, 2411, 2412, - 2412, 2412, 2412, 2412, 2412, 2412, 2412, 2412, 2412, 2412, - 2412, 2412, 2412, 0, 2412, 2412, 2412, 2412, 2413, 2413, - 0, 2413, 2413, 2413, 2413, 2413, 2413, 2413, 2413, 2413, - - 2413, 2413, 2413, 2413, 2413, 2413, 2413, 2414, 2414, 0, - 2414, 2414, 2414, 2414, 2414, 2414, 2414, 2414, 2414, 2414, - 2414, 2414, 2414, 2414, 2414, 2414, 2415, 2415, 0, 2415, - 2415, 2415, 2415, 2415, 2415, 2415, 2415, 2415, 2415, 2415, - 2415, 2415, 2415, 2415, 2415, 2416, 2416, 0, 0, 0, - 0, 2416, 0, 0, 0, 0, 2416, 2416, 2416, 2416, - 2417, 0, 2417, 2417, 2417, 2417, 2418, 2418, 0, 2418, - 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, 2418, - 2418, 2418, 2418, 2418, 2418, 2419, 2419, 0, 2419, 2419, - 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, 2419, - - 2419, 2419, 2419, 2419, 2420, 2420, 0, 2420, 2420, 2420, - 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, 2420, - 2420, 2420, 2420, 2421, 2421, 0, 2421, 2421, 2421, 2421, - 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, 2421, - 2421, 2421, 2422, 2422, 0, 0, 0, 0, 2422, 0, - 0, 0, 0, 2422, 2422, 2422, 2422, 2423, 0, 2423, - 2423, 2423, 2423, 2424, 2424, 0, 0, 0, 0, 2424, - 0, 0, 0, 0, 2424, 2424, 2424, 2424, 2425, 0, - 2425, 2425, 2425, 2425, 2426, 2426, 0, 2426, 2426, 2426, - 2426, 2426, 2426, 2426, 2426, 2426, 2426, 2426, 2426, 2426, - - 2426, 2426, 2426, 2427, 2427, 0, 2427, 2427, 2427, 2427, - 2427, 2427, 2427, 2427, 2427, 2427, 2427, 2427, 2427, 2427, - 2427, 2427, 2428, 2428, 0, 2428, 2428, 2428, 2428, 2428, - 2428, 2428, 2428, 2428, 2428, 2428, 2428, 2428, 2428, 2428, - 2428, 2429, 2429, 0, 0, 0, 0, 2429, 0, 0, - 0, 0, 2429, 2429, 2429, 2429, 2430, 0, 2430, 2430, - 2430, 2430, 2431, 2431, 0, 2431, 2431, 2431, 2431, 2431, - 2431, 2431, 2431, 2431, 2431, 2431, 2431, 2431, 2431, 2431, - 2431, 2432, 2432, 0, 2432, 2432, 2432, 2432, 2432, 2432, - 2432, 2432, 2432, 2432, 2432, 2432, 2432, 2432, 2432, 2432, - - 2433, 2433, 2433, 0, 0, 0, 0, 2433, 0, 0, - 0, 0, 2433, 2433, 2433, 2433, 2434, 2434, 0, 2434, - 2434, 2434, 2434, 2434, 2434, 2434, 2434, 2434, 2434, 2434, - 2434, 2434, 2434, 2434, 2434, 2435, 2435, 0, 2435, 2435, - 2435, 2435, 2435, 2435, 2435, 2435, 2435, 2435, 2435, 2435, - 2435, 2435, 2435, 2435, 2436, 2436, 2436, 0, 0, 0, - 2436, 0, 0, 0, 0, 2436, 2436, 2436, 2436, 2437, - 2437, 2437, 2437, 2437, 2437, 2437, 2437, 2437, 2437, 2437, - 2437, 2437, 2437, 2437, 2437, 2437, 2437, 2437, 2438, 2438, - 0, 0, 0, 0, 2438, 0, 0, 0, 0, 2438, - - 2438, 2438, 2438, 2439, 2439, 0, 0, 0, 0, 2439, - 0, 0, 0, 2439, 2439, 2439, 2439, 2439, 2440, 2440, - 0, 0, 0, 0, 2440, 0, 0, 0, 0, 2440, - 2440, 2440, 2440, 2441, 2441, 0, 0, 0, 2441, 2441, - 0, 0, 0, 0, 2441, 2441, 2441, 2441, 2442, 2442, - 2442, 0, 0, 0, 0, 2442, 0, 0, 0, 0, - 2442, 2442, 2442, 2442, 2443, 2443, 2443, 0, 0, 0, - 2443, 0, 0, 0, 0, 2443, 2443, 2443, 2443, 2444, - 2444, 0, 0, 0, 0, 2444, 0, 0, 0, 0, - 2444, 2444, 2444, 2444, 2445, 2445, 0, 0, 0, 0, - - 2445, 0, 0, 0, 2445, 2445, 2445, 2445, 2445, 2446, - 0, 0, 2446, 0, 2446, 2447, 0, 0, 2447, 0, - 2447, 2448, 2448, 0, 2448, 2448, 2448, 2448, 2448, 2448, - 2448, 2448, 2448, 2448, 2448, 2448, 2448, 2448, 2448, 2448, - 2449, 2449, 0, 2449, 2449, 2449, 2449, 2449, 2449, 2449, - 2449, 2449, 2449, 2449, 2449, 2449, 2449, 2449, 2449, 2450, - 2450, 0, 2450, 2450, 2450, 2450, 2450, 2450, 2450, 2450, - 2450, 2450, 2450, 2450, 2450, 2450, 2450, 2450, 2451, 2451, - 0, 2451, 2451, 2451, 2451, 2451, 2451, 2451, 2451, 2451, - 2451, 2451, 2451, 2451, 2451, 2451, 2451, 2452, 2452, 0, - - 2452, 2452, 2452, 2452, 2452, 2452, 2452, 2452, 2452, 2452, - 2452, 2452, 2452, 2452, 2452, 2452, 2453, 2453, 2453, 2453, - 2453, 2453, 2453, 2453, 2453, 2453, 2453, 2453, 2453, 2453, - 2453, 2453, 2453, 2453, 2453, 2454, 2454, 0, 0, 0, - 0, 2454, 0, 0, 0, 0, 2454, 2454, 2454, 2454, - 2455, 2455, 2455, 2455, 2455, 2455, 2455, 2455, 2455, 2455, - 2455, 2455, 2455, 2455, 2455, 2455, 2455, 2455, 2455, 2456, - 2456, 0, 2456, 2456, 2456, 2456, 2456, 2456, 2456, 2456, - 2456, 2456, 2456, 2456, 2456, 2456, 2456, 2456, 2457, 2457, - 0, 2457, 2457, 2457, 2457, 2457, 2457, 2457, 2457, 2457, - - 2457, 2457, 2457, 2457, 2457, 2457, 2457, 2458, 2458, 2458, - 2458, 2458, 2458, 2458, 2458, 2458, 2458, 2458, 2458, 2458, - 2458, 2458, 2458, 2458, 2458, 2458, 2459, 2459, 0, 0, - 0, 0, 2459, 0, 0, 0, 0, 2459, 2459, 2459, - 2459, 2460, 2460, 0, 0, 0, 0, 2460, 0, 0, - 0, 0, 2460, 2460, 2460, 2460, 2461, 2461, 0, 2461, - 2461, 2461, 2461, 2461, 2461, 2461, 2461, 2461, 2461, 2461, - 2461, 2461, 2461, 2461, 2461, 2462, 2462, 0, 2462, 2462, - 2462, 2462, 2462, 2462, 2462, 2462, 2462, 2462, 2462, 2462, - 2462, 2462, 2462, 2462, 2463, 2463, 2463, 2463, 2463, 2463, - - 2463, 2463, 2463, 2463, 2463, 2463, 2463, 2463, 2463, 2463, - 2463, 2463, 2463, 2464, 2464, 0, 0, 0, 0, 2464, - 0, 0, 0, 0, 2464, 2464, 2464, 2464, 2465, 2465, - 2465, 2465, 2465, 2465, 2465, 2465, 2465, 2465, 2465, 2465, - 2465, 2465, 2465, 2465, 2465, 2465, 2465, 2466, 2466, 2466, - 2466, 2466, 2466, 2466, 2466, 2466, 2466, 2466, 2466, 2466, - 2466, 2466, 2466, 2466, 2466, 2466, 2467, 2467, 0, 2467, - 2467, 2467, 2467, 2467, 2467, 2467, 2467, 2467, 2467, 2467, - 2467, 2467, 2467, 2467, 2467, 2468, 2468, 0, 2468, 2468, - 2468, 2468, 2468, 2468, 2468, 2468, 2468, 2468, 2468, 2468, - - 2468, 2468, 2468, 2468, 2469, 2469, 0, 0, 0, 0, - 2469, 0, 0, 0, 0, 2469, 2469, 2469, 2469, 2470, - 2470, 0, 0, 0, 0, 2470, 0, 0, 0, 0, - 2470, 2470, 2470, 2470, 2471, 2471, 0, 0, 0, 2471, - 2471, 2471, 0, 0, 0, 2471, 2471, 2471, 2471, 2472, - 2472, 0, 0, 0, 0, 2472, 0, 0, 0, 0, - 2472, 2472, 2472, 2472, 2473, 0, 0, 2473, 0, 2473, - 2474, 0, 0, 2474, 0, 2474, 2475, 2475, 2475, 2475, - 2475, 2475, 2475, 2475, 2475, 2475, 2475, 2475, 2475, 2475, - 2475, 2475, 2475, 2475, 2475, 2476, 2476, 2476, 2476, 2476, - - 2476, 2476, 2476, 2476, 2476, 2476, 2476, 2476, 2476, 2476, - 2476, 2476, 2476, 2476, 2477, 2477, 2477, 2477, 2477, 2477, - 2477, 2477, 2477, 2477, 2477, 2477, 2477, 2477, 2477, 2477, - 2477, 2477, 2477, 2478, 2478, 0, 2478, 2478, 2478, 2478, - 2478, 2478, 2478, 2478, 2478, 2478, 2478, 2478, 2478, 2478, - 2478, 2478, 2479, 2479, 0, 2479, 2479, 2479, 2479, 2479, - 2479, 2479, 2479, 2479, 2479, 2479, 2479, 2479, 2479, 2479, - 2479, 2480, 2480, 0, 0, 0, 0, 2480, 0, 0, - 0, 0, 2480, 2480, 2480, 2480, 2481, 2481, 0, 2481, - 2481, 2481, 2481, 2481, 2481, 2481, 2481, 2481, 2481, 2481, - - 2481, 2481, 2481, 2481, 2481, 2482, 2482, 0, 2482, 2482, - 2482, 2482, 2482, 2482, 2482, 2482, 2482, 2482, 2482, 2482, - 2482, 2482, 2482, 2482, 2483, 2483, 0, 2483, 2483, 2483, - 2483, 2483, 2483, 2483, 2483, 2483, 2483, 2483, 2483, 2483, - 2483, 2483, 2483, 2484, 2484, 0, 0, 0, 0, 2484, - 0, 0, 0, 0, 2484, 2484, 2484, 2484, 2485, 2485, - 0, 0, 0, 0, 2485, 0, 0, 0, 0, 2485, - 2485, 2485, 2485, 2486, 2486, 0, 2486, 2486, 2486, 2486, - 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, 2486, - 2486, 2486, 2487, 2487, 0, 2487, 2487, 2487, 2487, 2487, - - 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, 2487, - 2487, 2488, 2488, 0, 0, 0, 0, 2488, 0, 0, - 0, 0, 2488, 2488, 2488, 2488, 2489, 2489, 0, 2489, - 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, 2489, - 2489, 2489, 2489, 2489, 2489, 2490, 2490, 0, 2490, 2490, - 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, 2490, - 2490, 2490, 2490, 2490, 2491, 2491, 0, 2491, 2491, 0, - 0, 0, 0, 2491, 0, 0, 0, 0, 2491, 2491, - 2491, 2491, 2492, 2492, 0, 0, 0, 0, 2492, 0, - 0, 0, 0, 2492, 2492, 2492, 2492, 2493, 2493, 0, - - 0, 0, 2493, 2493, 0, 0, 0, 0, 2493, 2493, - 2493, 2493, 2494, 2494, 0, 0, 0, 0, 2494, 0, - 0, 0, 0, 2494, 2494, 2494, 2494, 2495, 0, 0, - 2495, 0, 2495, 2496, 0, 0, 2496, 0, 2496, 2497, - 2497, 0, 2497, 2497, 2497, 2497, 2497, 2497, 2497, 2497, - 2497, 2497, 2497, 2497, 2497, 2497, 2497, 2497, 2498, 2498, - 0, 2498, 2498, 2498, 2498, 2498, 2498, 2498, 2498, 2498, - 2498, 2498, 2498, 2498, 2498, 2498, 2498, 2499, 2499, 0, - 2499, 2499, 2499, 2499, 2499, 2499, 2499, 2499, 2499, 2499, - 2499, 2499, 2499, 2499, 2499, 2499, 2500, 2500, 0, 0, - - 0, 0, 2500, 0, 0, 0, 0, 2500, 2500, 2500, - 2500, 2501, 2501, 2501, 2501, 2501, 2501, 2501, 2501, 2501, - 2501, 2501, 2501, 2501, 2501, 2501, 2501, 2501, 2501, 2501, - 2502, 2502, 2502, 2502, 2502, 2502, 2502, 2502, 2502, 2502, - 2502, 2502, 2502, 2502, 2502, 2502, 2502, 2502, 2502, 2503, - 2503, 2503, 2503, 2503, 2503, 2503, 2503, 2503, 2503, 2503, - 2503, 2503, 2503, 2503, 2503, 2503, 2503, 2503, 2504, 2504, - 2504, 2504, 2504, 2504, 2504, 2504, 2504, 2504, 2504, 2504, - 2504, 2504, 2504, 2504, 2504, 2504, 2504, 2505, 2505, 2505, - 2505, 2505, 2505, 2505, 2505, 2505, 2505, 2505, 2505, 2505, - - 2505, 2505, 2505, 2505, 2505, 2505, 2506, 2506, 2506, 2506, - 2506, 2506, 2506, 2506, 2506, 2506, 2506, 2506, 2506, 2506, - 2506, 2506, 2506, 2506, 2506, 2507, 2507, 2507, 2507, 2507, - 2507, 2507, 2507, 2507, 2507, 2507, 2507, 2507, 2507, 2507, - 2507, 2507, 2507, 2507, 2508, 2508, 2508, 2508, 2508, 2508, - 2508, 2508, 2508, 2508, 2508, 2508, 2508, 2508, 2508, 2508, - 2508, 2508, 2508, 2509, 2509, 2509, 2509, 2509, 2509, 2509, - 2509, 2509, 2509, 2509, 2509, 2509, 2509, 2509, 2509, 2509, - 2509, 2509, 2510, 2510, 2510, 2510, 2510, 2510, 2510, 2510, - 2510, 2510, 2510, 2510, 2510, 2510, 2510, 2510, 2510, 2510, - - 2510, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, 2326, - 2326, 2326, 2326, 2326, 2326 - + 0, 2492, 0, 0, 0, 0, 0, 2496, 0, 0, + 0, 0, 0, 2502, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2513, 2515, + 2515, 2515, 2515, 2515, 2515, 2515, 2515, 2515, 2515, 2515, + + 2515, 2515, 2515, 2515, 2515, 2515, 2515, 2516, 2516, 2516, + 2516, 2516, 2516, 2516, 2516, 2516, 2516, 2516, 2516, 2516, + 2516, 2516, 2516, 2516, 2516, 2517, 2517, 2517, 2517, 2517, + 2517, 2517, 2517, 2517, 2517, 2517, 2517, 2517, 2517, 2517, + 2517, 2517, 2517, 2518, 2518, 2518, 2518, 2518, 2518, 2518, + 2518, 2518, 2518, 2518, 2518, 2518, 2518, 2518, 2518, 2518, + 2518, 2519, 2519, 2519, 2519, 2519, 2519, 2519, 2519, 2519, + 2519, 2519, 2519, 2519, 2519, 2519, 2519, 2519, 2519, 2520, + 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2520, + 2520, 2520, 2520, 2520, 2520, 2520, 2520, 2521, 2521, 2521, + + 2521, 2521, 2521, 2521, 2521, 2521, 2521, 2521, 2521, 2521, + 2521, 2521, 2521, 2521, 2521, 2522, 2522, 2522, 2522, 2522, + 2522, 2522, 2522, 2522, 2522, 2522, 2522, 2522, 2522, 2522, + 2522, 2522, 2522, 2523, 2523, 2523, 2523, 2523, 2523, 2523, + 2523, 2523, 2523, 2523, 2523, 2523, 2523, 2523, 2523, 2523, + 2523, 2524, 2524, 2524, 2524, 2524, 2524, 2524, 2524, 2524, + 2524, 2524, 2524, 2524, 2524, 2524, 2524, 2524, 2524, 2525, + 2525, 2525, 2525, 2525, 2525, 2525, 2525, 2525, 2525, 2525, + 2525, 2525, 2525, 2525, 2525, 2525, 2525, 2526, 2526, 2526, + 2526, 2526, 2526, 2526, 2526, 2526, 2526, 2526, 2526, 2526, + + 2526, 2526, 2526, 2526, 2526, 2527, 2527, 2527, 2527, 2527, + 2527, 2527, 2527, 2527, 2527, 2527, 2527, 2527, 2527, 2527, + 2527, 2527, 2527, 2528, 2528, 2528, 2528, 2528, 2528, 2528, + 2528, 2528, 2528, 2528, 2528, 2528, 2528, 2528, 2528, 2528, + 2528, 2529, 2529, 2529, 2529, 2529, 2529, 2529, 2529, 2529, + 2529, 2529, 2529, 2529, 2529, 2529, 2529, 2529, 2529, 2530, + 2530, 2530, 2530, 2530, 2530, 2530, 2530, 2530, 2530, 2530, + 2530, 2530, 2530, 2530, 2530, 2530, 2530, 2531, 2531, 2531, + 0, 0, 0, 2531, 0, 0, 0, 0, 2531, 2531, + 2531, 2531, 2532, 2532, 0, 2532, 2532, 2532, 2532, 2532, + + 2532, 2532, 2532, 2532, 2532, 2532, 2532, 2532, 2532, 2532, + 2533, 2533, 0, 0, 0, 2533, 0, 0, 0, 0, + 2533, 2533, 2533, 2533, 2534, 2534, 2534, 0, 0, 2534, + 0, 0, 0, 0, 2534, 2534, 2534, 2534, 2535, 2535, + 0, 0, 0, 2535, 0, 0, 0, 2535, 2535, 2535, + 2535, 2535, 2536, 0, 2536, 2536, 2536, 2536, 2536, 2536, + 2536, 2537, 2537, 0, 0, 0, 2537, 0, 0, 0, + 0, 2537, 2537, 2537, 2537, 2538, 0, 2538, 2538, 2538, + 2538, 2538, 2538, 2539, 2539, 0, 2539, 2539, 0, 2539, + 2539, 2539, 0, 0, 0, 0, 2539, 2539, 2539, 2539, + + 2540, 0, 2540, 2540, 2540, 2540, 2541, 2541, 2541, 0, + 0, 0, 2541, 0, 0, 0, 0, 2541, 2541, 2541, + 2541, 2542, 2542, 0, 0, 0, 2542, 0, 0, 0, + 0, 2542, 2542, 2542, 2542, 2543, 2543, 2543, 0, 0, + 2543, 0, 0, 0, 0, 2543, 2543, 2543, 2543, 2544, + 2544, 0, 0, 0, 2544, 0, 0, 0, 2544, 2544, + 2544, 2544, 2544, 2545, 0, 2545, 2545, 2545, 2545, 2546, + 0, 2546, 0, 2546, 2547, 0, 2547, 0, 2547, 2548, + 2548, 2548, 2548, 2548, 2548, 0, 2548, 2548, 2548, 2548, + 2548, 0, 2548, 2548, 2548, 2548, 2548, 2549, 2549, 2549, + + 2549, 2549, 2549, 2549, 2549, 2549, 2549, 2549, 2549, 2549, + 2549, 2549, 2549, 2549, 2549, 2550, 2550, 2550, 2550, 2550, + 2550, 0, 2550, 2550, 2550, 2550, 2550, 0, 2550, 2550, + 2550, 2550, 2550, 2551, 2551, 2551, 2551, 2551, 2551, 2551, + 2551, 2551, 2551, 2551, 2551, 2551, 2551, 2551, 2551, 2551, + 2551, 2552, 2552, 2552, 2552, 2552, 2552, 2552, 2552, 2552, + 2552, 2552, 2552, 2552, 2552, 2552, 2552, 2552, 2552, 2553, + 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, 2553, + 2553, 2553, 0, 2553, 2553, 2553, 2553, 2554, 2554, 2554, + 2554, 2554, 2554, 2554, 2554, 2554, 2554, 2554, 2554, 2554, + + 0, 2554, 2554, 2554, 2554, 2555, 2555, 0, 2555, 2555, + 2555, 2555, 2555, 2555, 2555, 2555, 2555, 2555, 2555, 2555, + 2555, 2555, 2555, 2556, 2556, 0, 0, 0, 2556, 0, + 0, 0, 0, 2556, 2556, 2556, 2556, 2557, 0, 2557, + 2557, 2557, 2557, 2557, 2558, 2558, 0, 2558, 2558, 2558, + 2558, 2558, 2558, 2558, 2558, 2558, 2558, 2558, 2558, 2558, + 2558, 2558, 2559, 2559, 0, 2559, 2559, 2559, 2559, 2559, + 2559, 2559, 2559, 2559, 2559, 2559, 2559, 2559, 2559, 2559, + 2560, 2560, 0, 0, 0, 2560, 0, 0, 0, 0, + 2560, 2560, 2560, 2560, 2561, 0, 2561, 2561, 2561, 2561, + + 2561, 2561, 2562, 2562, 0, 0, 0, 2562, 0, 0, + 0, 0, 2562, 2562, 2562, 2562, 2563, 0, 2563, 2563, + 2563, 2563, 2564, 2564, 0, 2564, 2564, 2564, 2564, 2564, + 2564, 2564, 2564, 2564, 2564, 2564, 2564, 2564, 2564, 2564, + 2565, 2565, 0, 0, 0, 2565, 0, 0, 0, 0, + 2565, 2565, 2565, 2565, 2566, 0, 2566, 2566, 2566, 2566, + 0, 0, 2566, 2567, 2567, 0, 2567, 2567, 2567, 2567, + 2567, 2567, 2567, 2567, 2567, 2567, 2567, 2567, 2567, 2567, + 2567, 2568, 2568, 0, 2568, 2568, 2568, 2568, 2568, 2568, + 2568, 2568, 2568, 2568, 2568, 2568, 2568, 2568, 2568, 2569, + + 2569, 2569, 0, 0, 0, 2569, 0, 0, 0, 0, + 2569, 2569, 2569, 2569, 2570, 0, 2570, 2570, 2570, 2570, + 2571, 2571, 0, 2571, 2571, 2571, 2571, 2571, 2571, 2571, + 2571, 2571, 2571, 2571, 2571, 2571, 2571, 2571, 2572, 2572, + 0, 2572, 2572, 2572, 2572, 2572, 2572, 2572, 2572, 2572, + 2572, 2572, 2572, 2572, 2572, 2572, 2573, 2573, 0, 2573, + 2573, 2573, 2573, 2573, 2573, 2573, 2573, 2573, 2573, 2573, + 2573, 2573, 2573, 2573, 2574, 2574, 0, 0, 0, 2574, + 0, 0, 0, 0, 2574, 2574, 2574, 2574, 2575, 0, + 2575, 2575, 2575, 2575, 2576, 2576, 2576, 0, 0, 2576, + + 0, 0, 0, 0, 2576, 2576, 2576, 2576, 2577, 0, + 2577, 2577, 2577, 2577, 2578, 2578, 0, 0, 0, 2578, + 0, 0, 0, 2578, 2578, 2578, 2578, 2578, 2579, 0, + 2579, 2579, 2579, 2579, 2580, 2580, 0, 0, 0, 2580, + 0, 0, 0, 0, 2580, 2580, 2580, 2580, 2581, 0, + 2581, 2581, 2581, 2581, 2582, 2582, 0, 2582, 2582, 0, + 2582, 2582, 2582, 0, 0, 0, 0, 2582, 2582, 2582, + 2582, 2583, 0, 2583, 2583, 2583, 2583, 2584, 2584, 2584, + 0, 0, 0, 2584, 0, 0, 0, 0, 2584, 2584, + 2584, 2584, 2585, 0, 2585, 2585, 2585, 2585, 2586, 2586, + + 0, 0, 0, 2586, 0, 0, 0, 0, 2586, 2586, + 2586, 2586, 2587, 0, 2587, 2587, 2587, 2587, 2588, 2588, + 2588, 0, 0, 2588, 0, 0, 0, 0, 2588, 2588, + 2588, 2588, 2589, 0, 2589, 2589, 2589, 2589, 2590, 2590, + 0, 0, 0, 2590, 0, 0, 0, 2590, 2590, 2590, + 2590, 2590, 2591, 0, 2591, 2591, 2591, 2591, 2592, 0, + 2592, 0, 2592, 2593, 0, 2593, 0, 2593, 2594, 2594, + 2594, 2594, 2594, 2594, 0, 2594, 2594, 2594, 2594, 2594, + 0, 2594, 2594, 2594, 2594, 2594, 2595, 2595, 0, 2595, + 2595, 2595, 2595, 2595, 2595, 2595, 2595, 2595, 2595, 2595, + + 2595, 2595, 2595, 2595, 2596, 2596, 2596, 2596, 2596, 2596, + 0, 2596, 2596, 2596, 2596, 2596, 0, 2596, 2596, 2596, + 2596, 2596, 2597, 2597, 0, 2597, 2597, 2597, 2597, 2597, + 2597, 2597, 2597, 2597, 2597, 2597, 2597, 2597, 2597, 2597, + 2598, 2598, 0, 2598, 2598, 2598, 2598, 2598, 2598, 2598, + 2598, 2598, 2598, 2598, 2598, 2598, 2598, 2598, 2599, 2599, + 2599, 2599, 2599, 2599, 2599, 2599, 2599, 2599, 2599, 2599, + 2599, 0, 2599, 2599, 2599, 2599, 2600, 2600, 2600, 2600, + 2600, 2600, 2600, 2600, 2600, 2600, 2600, 2600, 2600, 0, + 2600, 2600, 2600, 2600, 2601, 2601, 0, 2601, 2601, 2601, + + 2601, 2601, 2601, 2601, 2601, 2601, 2601, 2601, 2601, 2601, + 2601, 2601, 2602, 2602, 0, 2602, 2602, 2602, 2602, 2602, + 2602, 2602, 2602, 2602, 2602, 2602, 2602, 2602, 2602, 2602, + 2603, 2603, 0, 2603, 2603, 2603, 2603, 2603, 2603, 2603, + 2603, 2603, 2603, 2603, 2603, 2603, 2603, 2603, 2604, 2604, + 0, 0, 0, 2604, 0, 0, 0, 0, 2604, 2604, + 2604, 2604, 2605, 0, 2605, 2605, 2605, 2605, 2606, 2606, + 0, 2606, 2606, 2606, 2606, 2606, 2606, 2606, 2606, 2606, + 2606, 2606, 2606, 2606, 2606, 2606, 2607, 2607, 0, 2607, + 2607, 2607, 2607, 2607, 2607, 2607, 2607, 2607, 2607, 2607, + + 2607, 2607, 2607, 2607, 2608, 2608, 0, 2608, 2608, 2608, + 2608, 2608, 2608, 2608, 2608, 2608, 2608, 2608, 2608, 2608, + 2608, 2608, 2609, 2609, 0, 2609, 2609, 2609, 2609, 2609, + 2609, 2609, 2609, 2609, 2609, 2609, 2609, 2609, 2609, 2609, + 2610, 2610, 0, 0, 0, 2610, 0, 0, 0, 0, + 2610, 2610, 2610, 2610, 2611, 0, 2611, 2611, 2611, 2611, + 2612, 2612, 0, 0, 0, 2612, 0, 0, 0, 0, + 2612, 2612, 2612, 2612, 2613, 0, 2613, 2613, 2613, 2613, + 2614, 2614, 0, 2614, 2614, 2614, 2614, 2614, 2614, 2614, + 2614, 2614, 2614, 2614, 2614, 2614, 2614, 2614, 2615, 2615, + + 0, 2615, 2615, 2615, 2615, 2615, 2615, 2615, 2615, 2615, + 2615, 2615, 2615, 2615, 2615, 2615, 2616, 2616, 0, 2616, + 2616, 2616, 2616, 2616, 2616, 2616, 2616, 2616, 2616, 2616, + 2616, 2616, 2616, 2616, 2617, 2617, 0, 0, 0, 2617, + 0, 0, 0, 0, 2617, 2617, 2617, 2617, 2618, 0, + 2618, 2618, 2618, 2618, 2619, 2619, 0, 2619, 2619, 2619, + 2619, 2619, 2619, 2619, 2619, 2619, 2619, 2619, 2619, 2619, + 2619, 2619, 2620, 2620, 0, 2620, 2620, 2620, 2620, 2620, + 2620, 2620, 2620, 2620, 2620, 2620, 2620, 2620, 2620, 2620, + 2621, 2621, 2621, 0, 0, 0, 2621, 0, 0, 0, + + 0, 2621, 2621, 2621, 2621, 2622, 2622, 0, 2622, 2622, + 2622, 2622, 2622, 2622, 2622, 2622, 2622, 2622, 2622, 2622, + 2622, 2622, 2622, 2623, 2623, 0, 2623, 2623, 2623, 2623, + 2623, 2623, 2623, 2623, 2623, 2623, 2623, 2623, 2623, 2623, + 2623, 2624, 2624, 2624, 0, 0, 2624, 0, 0, 0, + 0, 2624, 2624, 2624, 2624, 2625, 2625, 2625, 2625, 2625, + 2625, 2625, 2625, 2625, 2625, 2625, 2625, 2625, 2625, 2625, + 2625, 2625, 2625, 2626, 2626, 0, 0, 2626, 2626, 0, + 0, 0, 0, 2626, 2626, 2626, 2626, 2627, 2627, 0, + 0, 0, 2627, 0, 0, 0, 2627, 2627, 2627, 2627, + + 2627, 2628, 2628, 0, 0, 0, 2628, 0, 0, 0, + 0, 2628, 2628, 2628, 2628, 2629, 2629, 0, 0, 2629, + 2629, 0, 0, 0, 0, 2629, 2629, 2629, 2629, 2630, + 2630, 2630, 0, 0, 0, 2630, 0, 0, 0, 0, + 2630, 2630, 2630, 2630, 2631, 2631, 2631, 0, 0, 2631, + 0, 0, 0, 0, 2631, 2631, 2631, 2631, 2632, 2632, + 0, 0, 0, 2632, 0, 0, 0, 0, 2632, 2632, + 2632, 2632, 2633, 2633, 0, 0, 0, 2633, 0, 0, + 0, 2633, 2633, 2633, 2633, 2633, 2634, 0, 2634, 0, + 2634, 2635, 0, 2635, 0, 2635, 2636, 2636, 0, 2636, + + 2636, 2636, 2636, 2636, 2636, 2636, 2636, 2636, 2636, 2636, + 2636, 2636, 2636, 2636, 2637, 2637, 0, 2637, 2637, 2637, + 2637, 2637, 2637, 2637, 2637, 2637, 2637, 2637, 2637, 2637, + 2637, 2637, 2638, 2638, 0, 2638, 2638, 2638, 2638, 2638, + 2638, 2638, 2638, 2638, 2638, 2638, 2638, 2638, 2638, 2638, + 2639, 2639, 0, 2639, 2639, 2639, 2639, 2639, 2639, 2639, + 2639, 2639, 2639, 2639, 2639, 2639, 2639, 2639, 2640, 2640, + 0, 2640, 2640, 2640, 2640, 2640, 2640, 2640, 2640, 2640, + 2640, 2640, 2640, 2640, 2640, 2640, 2641, 2641, 2641, 2641, + 2641, 2641, 2641, 2641, 2641, 2641, 2641, 2641, 2641, 2641, + + 2641, 2641, 2641, 2641, 2642, 2642, 0, 0, 0, 2642, + 0, 0, 0, 0, 2642, 2642, 2642, 2642, 2643, 2643, + 2643, 2643, 2643, 2643, 2643, 2643, 2643, 2643, 2643, 2643, + 2643, 2643, 2643, 2643, 2643, 2643, 2644, 2644, 0, 2644, + 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2644, + 2644, 2644, 2644, 2644, 2645, 2645, 0, 2645, 2645, 2645, + 2645, 2645, 2645, 2645, 2645, 2645, 2645, 2645, 2645, 2645, + 2645, 2645, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, + 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, + 2647, 2647, 0, 0, 0, 2647, 0, 0, 0, 0, + + 2647, 2647, 2647, 2647, 2648, 2648, 0, 0, 0, 2648, + 0, 0, 0, 0, 2648, 2648, 2648, 2648, 2649, 2649, + 0, 2649, 2649, 2649, 2649, 2649, 2649, 2649, 2649, 2649, + 2649, 2649, 2649, 2649, 2649, 2649, 2650, 2650, 0, 2650, + 2650, 2650, 2650, 2650, 2650, 2650, 2650, 2650, 2650, 2650, + 2650, 2650, 2650, 2650, 2651, 2651, 2651, 2651, 2651, 2651, + 2651, 2651, 2651, 2651, 2651, 2651, 2651, 2651, 2651, 2651, + 2651, 2651, 2652, 2652, 0, 0, 2652, 2652, 0, 0, + 0, 0, 2652, 2652, 2652, 2652, 2653, 2653, 2653, 2653, + 2653, 2653, 2653, 2653, 2653, 2653, 2653, 2653, 2653, 2653, + + 2653, 2653, 2653, 2653, 2654, 2654, 2654, 2654, 2654, 2654, + 2654, 2654, 2654, 2654, 2654, 2654, 2654, 2654, 2654, 2654, + 2654, 2654, 2655, 2655, 0, 2655, 2655, 2655, 2655, 2655, + 2655, 2655, 2655, 2655, 2655, 2655, 2655, 2655, 2655, 2655, + 2656, 2656, 0, 2656, 2656, 2656, 2656, 2656, 2656, 2656, + 2656, 2656, 2656, 2656, 2656, 2656, 2656, 2656, 2657, 2657, + 0, 0, 2657, 2657, 0, 0, 0, 0, 2657, 2657, + 2657, 2657, 2658, 2658, 0, 0, 0, 2658, 0, 0, + 0, 0, 2658, 2658, 2658, 2658, 2659, 2659, 0, 0, + 2659, 2659, 2659, 0, 0, 0, 2659, 2659, 2659, 2659, + + 2660, 2660, 0, 0, 0, 2660, 0, 0, 0, 0, + 2660, 2660, 2660, 2660, 2661, 0, 2661, 0, 2661, 2662, + 0, 2662, 0, 2662, 2663, 2663, 2663, 2663, 2663, 2663, + 2663, 2663, 2663, 2663, 2663, 2663, 2663, 2663, 2663, 2663, + 2663, 2663, 2664, 2664, 2664, 2664, 2664, 2664, 2664, 2664, + 2664, 2664, 2664, 2664, 2664, 2664, 2664, 2664, 2664, 2664, + 2665, 2665, 2665, 2665, 2665, 2665, 2665, 2665, 2665, 2665, + 2665, 2665, 2665, 2665, 2665, 2665, 2665, 2665, 2666, 2666, + 0, 2666, 2666, 2666, 2666, 2666, 2666, 2666, 2666, 2666, + 2666, 2666, 2666, 2666, 2666, 2666, 2667, 2667, 0, 2667, + + 2667, 2667, 2667, 2667, 2667, 2667, 2667, 2667, 2667, 2667, + 2667, 2667, 2667, 2667, 2668, 2668, 0, 0, 0, 2668, + 0, 0, 0, 0, 2668, 2668, 2668, 2668, 2669, 2669, + 0, 2669, 2669, 2669, 2669, 2669, 2669, 2669, 2669, 2669, + 2669, 2669, 2669, 2669, 2669, 2669, 2670, 2670, 0, 2670, + 2670, 2670, 2670, 2670, 2670, 2670, 2670, 2670, 2670, 2670, + 2670, 2670, 2670, 2670, 2671, 2671, 0, 2671, 2671, 2671, + 2671, 2671, 2671, 2671, 2671, 2671, 2671, 2671, 2671, 2671, + 2671, 2671, 2672, 2672, 0, 0, 0, 2672, 0, 0, + 0, 0, 2672, 2672, 2672, 2672, 2673, 2673, 0, 0, + + 0, 2673, 0, 0, 0, 0, 2673, 2673, 2673, 2673, + 2674, 2674, 0, 2674, 2674, 2674, 2674, 2674, 2674, 2674, + 2674, 2674, 2674, 2674, 2674, 2674, 2674, 2674, 2675, 2675, + 0, 2675, 2675, 2675, 2675, 2675, 2675, 2675, 2675, 2675, + 2675, 2675, 2675, 2675, 2675, 2675, 2676, 2676, 0, 0, + 2676, 2676, 0, 0, 0, 0, 2676, 2676, 2676, 2676, + 2677, 2677, 0, 2677, 2677, 2677, 2677, 2677, 2677, 2677, + 2677, 2677, 2677, 2677, 2677, 2677, 2677, 2677, 2678, 2678, + 0, 2678, 2678, 2678, 2678, 2678, 2678, 2678, 2678, 2678, + 2678, 2678, 2678, 2678, 2678, 2678, 2679, 2679, 0, 0, + + 2679, 2679, 0, 0, 0, 0, 2679, 2679, 2679, 2679, + 2680, 2680, 0, 0, 0, 2680, 0, 0, 0, 0, + 2680, 2680, 2680, 2680, 2681, 2681, 0, 0, 2681, 2681, + 0, 0, 0, 0, 2681, 2681, 2681, 2681, 2682, 2682, + 0, 0, 0, 2682, 0, 0, 0, 0, 2682, 2682, + 2682, 2682, 2683, 0, 2683, 0, 2683, 2684, 0, 2684, + 0, 2684, 2685, 2685, 0, 2685, 2685, 2685, 2685, 2685, + 2685, 2685, 2685, 2685, 2685, 2685, 2685, 2685, 2685, 2685, + 2686, 2686, 0, 2686, 2686, 2686, 2686, 2686, 2686, 2686, + 2686, 2686, 2686, 2686, 2686, 2686, 2686, 2686, 2687, 2687, + + 0, 2687, 2687, 2687, 2687, 2687, 2687, 2687, 2687, 2687, + 2687, 2687, 2687, 2687, 2687, 2687, 2688, 2688, 0, 0, + 0, 2688, 0, 0, 0, 0, 2688, 2688, 2688, 2688, + 2689, 2689, 0, 0, 0, 2689, 0, 0, 0, 0, + 2689, 2689, 2689, 2689, 2690, 2690, 2690, 2690, 2690, 2690, + 2690, 2690, 2690, 2690, 2690, 2690, 2690, 2690, 2690, 2690, + 2690, 2690, 2691, 2691, 2691, 2691, 2691, 2691, 2691, 2691, + 2691, 2691, 2691, 2691, 2691, 2691, 2691, 2691, 2691, 2691, + 2692, 2692, 2692, 2692, 2692, 2692, 2692, 2692, 2692, 2692, + 2692, 2692, 2692, 2692, 2692, 2692, 2692, 2692, 2693, 2693, + + 2693, 2693, 2693, 2693, 2693, 2693, 2693, 2693, 2693, 2693, + 2693, 2693, 2693, 2693, 2693, 2693, 2694, 2694, 2694, 2694, + 2694, 2694, 2694, 2694, 2694, 2694, 2694, 2694, 2694, 2694, + 2694, 2694, 2694, 2694, 2695, 2695, 2695, 2695, 2695, 2695, + 2695, 2695, 2695, 2695, 2695, 2695, 2695, 2695, 2695, 2695, + 2695, 2695, 2696, 2696, 2696, 2696, 2696, 2696, 2696, 2696, + 2696, 2696, 2696, 2696, 2696, 2696, 2696, 2696, 2696, 2696, + 2697, 2697, 2697, 2697, 2697, 2697, 2697, 2697, 2697, 2697, + 2697, 2697, 2697, 2697, 2697, 2697, 2697, 2697, 2698, 2698, + 2698, 2698, 2698, 2698, 2698, 2698, 2698, 2698, 2698, 2698, + + 2698, 2698, 2698, 2698, 2698, 2698, 2699, 2699, 2699, 2699, + 2699, 2699, 2699, 2699, 2699, 2699, 2699, 2699, 2699, 2699, + 2699, 2699, 2699, 2699, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + + 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, 2514, + 2514, 2514, 2514, 2514, 2514, 2514, 2514 } ; /* The intent behind this definition is that it'll catch @@ -4959,10 +5026,13 @@ do {\ + -#line 4967 "ob_proxy_parser_gbk_lex.c" +/* limit the length of int_num from 1 to 17 in case of int64_t out of bound, 17 -> [ ( length of 2^64 ) - 2 ]*/ +/* binlog relate SQL */ +#line 5037 "ob_proxy_parser_gbk_lex.c" #define INITIAL 0 #define hint 1 @@ -4989,9 +5059,10 @@ do {\ #define prepare 22 #define insert_all_expr 23 #define set_expr 24 -#define show_topology 25 -#define show_tables 26 -#define proxy_icmd_state 27 +#define show_elastic_id 25 +#define show_topology 26 +#define show_tables 27 +#define proxy_icmd_state 28 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way @@ -5233,11 +5304,11 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 386 "ob_proxy_parser_gbk.l" +#line 398 "ob_proxy_parser_gbk.l" /* basic dml stmt: */ -#line 5243 "ob_proxy_parser_gbk_lex.c" +#line 5314 "ob_proxy_parser_gbk_lex.c" yylval = yylval_param; @@ -5294,13 +5365,13 @@ YY_DECL while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 2327 ) + if ( yy_current_state >= 2515 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 15602 ); + while ( yy_base[yy_current_state] != 15625 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -5326,86 +5397,86 @@ YY_DECL case 1: YY_RULE_SETUP -#line 389 "ob_proxy_parser_gbk.l" +#line 401 "ob_proxy_parser_gbk.l" { SET_DML_STMT(OBPROXY_T_SELECT); PUSH_STATE(in_expr); return SELECT; } YY_BREAK case 2: YY_RULE_SETUP -#line 390 "ob_proxy_parser_gbk.l" +#line 402 "ob_proxy_parser_gbk.l" { SET_DML_STMT(OBPROXY_T_DELETE); PUSH_STATE_IF_NOT_ICMD(in_expr); return DELETE; } YY_BREAK case 3: YY_RULE_SETUP -#line 391 "ob_proxy_parser_gbk.l" +#line 403 "ob_proxy_parser_gbk.l" { SET_DML_STMT(OBPROXY_T_INSERT); return INSERT; } YY_BREAK case 4: YY_RULE_SETUP -#line 392 "ob_proxy_parser_gbk.l" +#line 404 "ob_proxy_parser_gbk.l" { SET_DML_STMT(OBPROXY_T_UPDATE); return UPDATE; } YY_BREAK case 5: YY_RULE_SETUP -#line 393 "ob_proxy_parser_gbk.l" +#line 405 "ob_proxy_parser_gbk.l" { SET_DML_STMT(OBPROXY_T_REPLACE); return REPLACE; } YY_BREAK case 6: YY_RULE_SETUP -#line 394 "ob_proxy_parser_gbk.l" +#line 406 "ob_proxy_parser_gbk.l" { SET_DML_STMT(OBPROXY_T_MERGE); return MERGE; } YY_BREAK case 7: YY_RULE_SETUP -#line 395 "ob_proxy_parser_gbk.l" +#line 407 "ob_proxy_parser_gbk.l" { SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW; } YY_BREAK case 8: YY_RULE_SETUP -#line 396 "ob_proxy_parser_gbk.l" +#line 408 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(XA); } YY_BREAK /* if begin is for starting transaction, will set has_anonymous_block = false in yacc */ case 9: YY_RULE_SETUP -#line 398 "ob_proxy_parser_gbk.l" +#line 410 "ob_proxy_parser_gbk.l" { SET_HAS_ANONYMOUS_BLOCK(); RETURN_NON_RESERVED_KEYWORD(BEGI); } YY_BREAK case 10: YY_RULE_SETUP -#line 399 "ob_proxy_parser_gbk.l" +#line 411 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(START); } YY_BREAK case 11: YY_RULE_SETUP -#line 400 "ob_proxy_parser_gbk.l" +#line 412 "ob_proxy_parser_gbk.l" { SET_BASIC_STMT(OBPROXY_T_COMMIT); RETURN_IGNORED_WORD(); } YY_BREAK case 12: YY_RULE_SETUP -#line 401 "ob_proxy_parser_gbk.l" +#line 413 "ob_proxy_parser_gbk.l" { SET_BASIC_STMT(OBPROXY_T_ROLLBACK); RETURN_IGNORED_WORD(); } YY_BREAK case 13: YY_RULE_SETUP -#line 402 "ob_proxy_parser_gbk.l" +#line 414 "ob_proxy_parser_gbk.l" { SET_BASIC_STMT(OBPROXY_T_SET); PUSH_STATE_IF_NOT_ICMD(set_expr); return SET; } YY_BREAK case 14: YY_RULE_SETUP -#line 403 "ob_proxy_parser_gbk.l" +#line 415 "ob_proxy_parser_gbk.l" { SET_BASIC_STMT(OBPROXY_T_CALL); return CALL; } YY_BREAK case 15: YY_RULE_SETUP -#line 404 "ob_proxy_parser_gbk.l" +#line 416 "ob_proxy_parser_gbk.l" { SET_HAS_ANONYMOUS_BLOCK(); PUSH_STATE(in_anonymous_block); } YY_BREAK case 16: YY_RULE_SETUP -#line 405 "ob_proxy_parser_gbk.l" +#line 417 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = ob_proxy_parser_gbk_yyget_extra(yyscanner); if (OB_NOTNULL(p)) { - if (OBPROXY_T_INSERT == p->cur_stmt_type_) + if (OBPROXY_T_INSERT == p->cur_stmt_type_) PUSH_STATE(insert_all_expr); } return WHEN; } @@ -5413,338 +5484,338 @@ YY_RULE_SETUP /* basic ddl stmt */ case 17: YY_RULE_SETUP -#line 413 "ob_proxy_parser_gbk.l" +#line 425 "ob_proxy_parser_gbk.l" { return CREATE; } YY_BREAK case 18: YY_RULE_SETUP -#line 414 "ob_proxy_parser_gbk.l" +#line 426 "ob_proxy_parser_gbk.l" { return DROP; } YY_BREAK case 19: YY_RULE_SETUP -#line 415 "ob_proxy_parser_gbk.l" +#line 427 "ob_proxy_parser_gbk.l" { return ALTER; } YY_BREAK case 20: YY_RULE_SETUP -#line 416 "ob_proxy_parser_gbk.l" +#line 428 "ob_proxy_parser_gbk.l" { return TRUNCATE; } YY_BREAK case 21: YY_RULE_SETUP -#line 417 "ob_proxy_parser_gbk.l" +#line 429 "ob_proxy_parser_gbk.l" { return RENAME; } YY_BREAK case 22: YY_RULE_SETUP -#line 418 "ob_proxy_parser_gbk.l" +#line 430 "ob_proxy_parser_gbk.l" { return INDEX; } YY_BREAK case 23: YY_RULE_SETUP -#line 419 "ob_proxy_parser_gbk.l" +#line 431 "ob_proxy_parser_gbk.l" { return TABLE; } YY_BREAK case 24: YY_RULE_SETUP -#line 420 "ob_proxy_parser_gbk.l" +#line 432 "ob_proxy_parser_gbk.l" { return STATUS; } YY_BREAK case 25: YY_RULE_SETUP -#line 421 "ob_proxy_parser_gbk.l" +#line 433 "ob_proxy_parser_gbk.l" { return FROM; } YY_BREAK case 26: YY_RULE_SETUP -#line 422 "ob_proxy_parser_gbk.l" +#line 434 "ob_proxy_parser_gbk.l" { return UNIQUE; } YY_BREAK /* ps stmt */ case 27: YY_RULE_SETUP -#line 425 "ob_proxy_parser_gbk.l" +#line 437 "ob_proxy_parser_gbk.l" { return USING; } YY_BREAK case 28: YY_RULE_SETUP -#line 426 "ob_proxy_parser_gbk.l" +#line 438 "ob_proxy_parser_gbk.l" { PUSH_STATE(prepare); return PREPARE; } YY_BREAK case 29: YY_RULE_SETUP -#line 427 "ob_proxy_parser_gbk.l" +#line 439 "ob_proxy_parser_gbk.l" { return EXECUTE; } YY_BREAK case 30: YY_RULE_SETUP -#line 428 "ob_proxy_parser_gbk.l" -{ return DEALLOCATE; } +#line 440 "ob_proxy_parser_gbk.l" +{ return DEALLOCATE; } YY_BREAK /* oracle ddl stmt */ case 31: YY_RULE_SETUP -#line 432 "ob_proxy_parser_gbk.l" +#line 444 "ob_proxy_parser_gbk.l" { return GRANT; } YY_BREAK case 32: YY_RULE_SETUP -#line 433 "ob_proxy_parser_gbk.l" +#line 445 "ob_proxy_parser_gbk.l" { return REVOKE; } YY_BREAK case 33: YY_RULE_SETUP -#line 434 "ob_proxy_parser_gbk.l" +#line 446 "ob_proxy_parser_gbk.l" { return ANALYZE; } YY_BREAK case 34: YY_RULE_SETUP -#line 435 "ob_proxy_parser_gbk.l" +#line 447 "ob_proxy_parser_gbk.l" { return PURGE; } YY_BREAK case 35: YY_RULE_SETUP -#line 436 "ob_proxy_parser_gbk.l" +#line 448 "ob_proxy_parser_gbk.l" { return COMMENT; } YY_BREAK case 36: YY_RULE_SETUP -#line 437 "ob_proxy_parser_gbk.l" +#line 449 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(FLASHBACK); } YY_BREAK case 37: YY_RULE_SETUP -#line 438 "ob_proxy_parser_gbk.l" +#line 450 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(AUDIT); } YY_BREAK case 38: YY_RULE_SETUP -#line 439 "ob_proxy_parser_gbk.l" +#line 451 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(NOAUDIT); } YY_BREAK case 39: YY_RULE_SETUP -#line 441 "ob_proxy_parser_gbk.l" +#line 453 "ob_proxy_parser_gbk.l" { return GROUP;} YY_BREAK case 40: YY_RULE_SETUP -#line 442 "ob_proxy_parser_gbk.l" +#line 454 "ob_proxy_parser_gbk.l" { return HAVING;} YY_BREAK case 41: YY_RULE_SETUP -#line 443 "ob_proxy_parser_gbk.l" +#line 455 "ob_proxy_parser_gbk.l" { return ORDER;} YY_BREAK case 42: YY_RULE_SETUP -#line 444 "ob_proxy_parser_gbk.l" +#line 456 "ob_proxy_parser_gbk.l" { return FOR;} YY_BREAK case 43: YY_RULE_SETUP -#line 445 "ob_proxy_parser_gbk.l" +#line 457 "ob_proxy_parser_gbk.l" { return UNION;} YY_BREAK case 44: YY_RULE_SETUP -#line 446 "ob_proxy_parser_gbk.l" +#line 458 "ob_proxy_parser_gbk.l" { return AS; } YY_BREAK case 45: YY_RULE_SETUP -#line 447 "ob_proxy_parser_gbk.l" +#line 459 "ob_proxy_parser_gbk.l" { return WHERE; } YY_BREAK case 46: YY_RULE_SETUP -#line 448 "ob_proxy_parser_gbk.l" +#line 460 "ob_proxy_parser_gbk.l" { return VALUES; } YY_BREAK case 47: YY_RULE_SETUP -#line 449 "ob_proxy_parser_gbk.l" +#line 461 "ob_proxy_parser_gbk.l" { return VALUES; } YY_BREAK case 48: YY_RULE_SETUP -#line 450 "ob_proxy_parser_gbk.l" +#line 462 "ob_proxy_parser_gbk.l" { SET_HAS_EXPLAIN(); return EXPLAIN; } YY_BREAK case 49: YY_RULE_SETUP -#line 451 "ob_proxy_parser_gbk.l" +#line 463 "ob_proxy_parser_gbk.l" { SET_HAS_EXPLAIN(); return DESC; } YY_BREAK case 50: YY_RULE_SETUP -#line 452 "ob_proxy_parser_gbk.l" +#line 464 "ob_proxy_parser_gbk.l" { SET_HAS_EXPLAIN(); return DESCRIBE; } YY_BREAK /*change from non_reserved to reserved according https://dev.mysql.com/doc/refman/5.6/en/keywords.html*/ case 51: YY_RULE_SETUP -#line 454 "ob_proxy_parser_gbk.l" +#line 466 "ob_proxy_parser_gbk.l" { return READ; } YY_BREAK case 52: YY_RULE_SETUP -#line 455 "ob_proxy_parser_gbk.l" +#line 467 "ob_proxy_parser_gbk.l" { return WITH; } YY_BREAK case 53: YY_RULE_SETUP -#line 456 "ob_proxy_parser_gbk.l" +#line 468 "ob_proxy_parser_gbk.l" { return USE; } YY_BREAK case 54: YY_RULE_SETUP -#line 457 "ob_proxy_parser_gbk.l" +#line 469 "ob_proxy_parser_gbk.l" { return LIMIT; } YY_BREAK case 55: YY_RULE_SETUP -#line 458 "ob_proxy_parser_gbk.l" +#line 470 "ob_proxy_parser_gbk.l" { return ALL; } YY_BREAK case 56: YY_RULE_SETUP -#line 459 "ob_proxy_parser_gbk.l" +#line 471 "ob_proxy_parser_gbk.l" { return LIKE; } YY_BREAK case 57: YY_RULE_SETUP -#line 460 "ob_proxy_parser_gbk.l" +#line 472 "ob_proxy_parser_gbk.l" { return PARTITION; } YY_BREAK case 58: YY_RULE_SETUP -#line 461 "ob_proxy_parser_gbk.l" +#line 473 "ob_proxy_parser_gbk.l" { return BINARY; } YY_BREAK case 59: YY_RULE_SETUP -#line 462 "ob_proxy_parser_gbk.l" -{ return GROUP_NAME; } +#line 474 "ob_proxy_parser_gbk.l" +{ RETURN_NON_RESERVED_KEYWORD(GROUP_NAME); } YY_BREAK /* to make bison easy, do not return these reserved keyword in non strict mode */ case 60: YY_RULE_SETUP -#line 465 "ob_proxy_parser_gbk.l" +#line 477 "ob_proxy_parser_gbk.l" { RETURN_IGNORED_WORD(); } YY_BREAK case 61: YY_RULE_SETUP -#line 466 "ob_proxy_parser_gbk.l" +#line 478 "ob_proxy_parser_gbk.l" { RETURN_IGNORED_WORD(); } YY_BREAK case 62: YY_RULE_SETUP -#line 467 "ob_proxy_parser_gbk.l" +#line 479 "ob_proxy_parser_gbk.l" { RETURN_IGNORED_WORD(); } YY_BREAK case 63: YY_RULE_SETUP -#line 468 "ob_proxy_parser_gbk.l" +#line 480 "ob_proxy_parser_gbk.l" { RETURN_IGNORED_WORD(); } YY_BREAK case 64: YY_RULE_SETUP -#line 469 "ob_proxy_parser_gbk.l" +#line 481 "ob_proxy_parser_gbk.l" { RETURN_IGNORED_WORD(); } YY_BREAK /* no reserved keyword , don't forget to add these keyword in .y */ /*refer: https://dev.mysql.com/doc/refman/5.6/en/keywords.html*/ case 65: YY_RULE_SETUP -#line 473 "ob_proxy_parser_gbk.l" +#line 485 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(QUICK); } YY_BREAK case 66: YY_RULE_SETUP -#line 474 "ob_proxy_parser_gbk.l" +#line 486 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(COUNT); } YY_BREAK case 67: YY_RULE_SETUP -#line 475 "ob_proxy_parser_gbk.l" +#line 487 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(WARNINGS); } YY_BREAK case 68: YY_RULE_SETUP -#line 476 "ob_proxy_parser_gbk.l" +#line 488 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(ERRORS); } YY_BREAK case 69: YY_RULE_SETUP -#line 477 "ob_proxy_parser_gbk.l" +#line 489 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(TRACE); } YY_BREAK case 70: YY_RULE_SETUP -#line 478 "ob_proxy_parser_gbk.l" +#line 490 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(TRANSACTION); } YY_BREAK case 71: YY_RULE_SETUP -#line 480 "ob_proxy_parser_gbk.l" +#line 492 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(ONLY); } YY_BREAK case 72: YY_RULE_SETUP -#line 482 "ob_proxy_parser_gbk.l" +#line 494 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(CONSISTENT); } YY_BREAK case 73: YY_RULE_SETUP -#line 483 "ob_proxy_parser_gbk.l" +#line 495 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(SNAPSHOT); } YY_BREAK case 74: YY_RULE_SETUP -#line 485 "ob_proxy_parser_gbk.l" +#line 497 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(HELP); } YY_BREAK /*set names*/ case 75: /* rule 75 can match eol */ YY_RULE_SETUP -#line 489 "ob_proxy_parser_gbk.l" +#line 501 "ob_proxy_parser_gbk.l" { SET_BASIC_STMT(OBPROXY_T_SET_NAMES); return SET_NAMES; } YY_BREAK /*set charset*/ case 76: /* rule 76 can match eol */ YY_RULE_SETUP -#line 491 "ob_proxy_parser_gbk.l" +#line 503 "ob_proxy_parser_gbk.l" { SET_BASIC_STMT(OBPROXY_T_SET_CHARSET); return SET_CHARSET; } YY_BREAK /*set passwd*/ case 77: /* rule 77 can match eol */ YY_RULE_SETUP -#line 493 "ob_proxy_parser_gbk.l" +#line 505 "ob_proxy_parser_gbk.l" { SET_BASIC_STMT(OBPROXY_T_SET_PASSWORD); return SET_PASSWORD; } YY_BREAK /*set default*/ case 78: /* rule 78 can match eol */ YY_RULE_SETUP -#line 495 "ob_proxy_parser_gbk.l" +#line 507 "ob_proxy_parser_gbk.l" { SET_BASIC_STMT(OBPROXY_T_SET_DEFAULT); return SET_DEFAULT; } YY_BREAK case 79: /* rule 79 can match eol */ YY_RULE_SETUP -#line 497 "ob_proxy_parser_gbk.l" +#line 509 "ob_proxy_parser_gbk.l" { SET_BASIC_STMT(OBPROXY_T_SET_OB_READ_CONSISTENCY); return SET_OB_READ_CONSISTENCY; } YY_BREAK case 80: /* rule 80 can match eol */ YY_RULE_SETUP -#line 498 "ob_proxy_parser_gbk.l" +#line 510 "ob_proxy_parser_gbk.l" { SET_BASIC_STMT(OBPROXY_T_SET_TX_READ_ONLY); return SET_TX_READ_ONLY; } YY_BREAK /*internal cmd*/ @@ -5752,453 +5823,459 @@ YY_RULE_SETUP case 81: /* rule 81 can match eol */ YY_RULE_SETUP -#line 502 "ob_proxy_parser_gbk.l" +#line 514 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_NET); return SHOW_PROXYNET; } YY_BREAK case 82: YY_RULE_SETUP -#line 503 "ob_proxy_parser_gbk.l" +#line 515 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(THREAD); } YY_BREAK case 83: YY_RULE_SETUP -#line 504 "ob_proxy_parser_gbk.l" +#line 516 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(CONNECTION); } YY_BREAK case 84: YY_RULE_SETUP -#line 506 "ob_proxy_parser_gbk.l" +#line 518 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(OFFSET); } YY_BREAK /*show session*/ case 85: /* rule 85 can match eol */ YY_RULE_SETUP -#line 509 "ob_proxy_parser_gbk.l" +#line 521 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_GLOBAL_SESSION); return SHOW_GLOBALSESSION; } YY_BREAK case 86: /* rule 86 can match eol */ YY_RULE_SETUP -#line 510 "ob_proxy_parser_gbk.l" +#line 522 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_SESSION); return SHOW_PROXYSESSION; } YY_BREAK case 87: /* rule 87 can match eol */ YY_RULE_SETUP -#line 511 "ob_proxy_parser_gbk.l" +#line 523 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_PROCESSLIST); return SHOW_PROCESSLIST; } YY_BREAK case 88: YY_RULE_SETUP -#line 512 "ob_proxy_parser_gbk.l" +#line 524 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(ATTRIBUTE); } YY_BREAK case 89: YY_RULE_SETUP -#line 513 "ob_proxy_parser_gbk.l" +#line 525 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(VARIABLES); } YY_BREAK case 90: YY_RULE_SETUP -#line 515 "ob_proxy_parser_gbk.l" +#line 527 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(STAT); } YY_BREAK /*show config*/ case 91: /* rule 91 can match eol */ YY_RULE_SETUP -#line 518 "ob_proxy_parser_gbk.l" +#line 530 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_CONFIG); PUSH_STATE(proxy_icmd_state); return SHOW_PROXYCONFIG; } YY_BREAK case 92: YY_RULE_SETUP -#line 520 "ob_proxy_parser_gbk.l" +#line 532 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(DIFF); } YY_BREAK case 93: YY_RULE_SETUP -#line 521 "ob_proxy_parser_gbk.l" +#line 533 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(USER); } YY_BREAK case 94: YY_RULE_SETUP -#line 522 "ob_proxy_parser_gbk.l" +#line 534 "ob_proxy_parser_gbk.l" { POP_STATE(); return LIKE; } YY_BREAK /*show sm*/ case 95: /* rule 95 can match eol */ YY_RULE_SETUP -#line 525 "ob_proxy_parser_gbk.l" +#line 537 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_SM); return SHOW_PROXYSM; } YY_BREAK /*show cluster*/ case 96: /* rule 96 can match eol */ YY_RULE_SETUP -#line 528 "ob_proxy_parser_gbk.l" +#line 540 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_CLUSTER); return SHOW_PROXYCLUSTER; } YY_BREAK /*show resource*/ case 97: /* rule 97 can match eol */ YY_RULE_SETUP -#line 531 "ob_proxy_parser_gbk.l" +#line 543 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_RESOURCE); return SHOW_PROXYRESOURCE; } YY_BREAK /*show congestion*/ case 98: /* rule 98 can match eol */ YY_RULE_SETUP -#line 534 "ob_proxy_parser_gbk.l" +#line 546 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_CONGESTION); return SHOW_PROXYCONGESTION; } YY_BREAK /*show route*/ case 99: /* rule 99 can match eol */ YY_RULE_SETUP -#line 537 "ob_proxy_parser_gbk.l" +#line 549 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_ROUTE); return SHOW_PROXYROUTE; } YY_BREAK case 100: YY_RULE_SETUP -#line 539 "ob_proxy_parser_gbk.l" +#line 551 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(ROUTINE); } YY_BREAK /*show vip*/ case 101: /* rule 101 can match eol */ YY_RULE_SETUP -#line 542 "ob_proxy_parser_gbk.l" +#line 554 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_VIP); return SHOW_PROXYVIP; } YY_BREAK /*show memory*/ case 102: /* rule 102 can match eol */ YY_RULE_SETUP -#line 545 "ob_proxy_parser_gbk.l" +#line 557 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_MEMORY); return SHOW_PROXYMEMORY; } YY_BREAK case 103: YY_RULE_SETUP -#line 546 "ob_proxy_parser_gbk.l" +#line 558 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(OBJPOOL); } YY_BREAK /*show sqlaudit*/ case 104: /* rule 104 can match eol */ YY_RULE_SETUP -#line 549 "ob_proxy_parser_gbk.l" +#line 561 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_SQLAUDIT); return SHOW_SQLAUDIT; } YY_BREAK /*show warnlog*/ case 105: /* rule 105 can match eol */ YY_RULE_SETUP -#line 552 "ob_proxy_parser_gbk.l" +#line 564 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_WARNLOG); return SHOW_WARNLOG; } YY_BREAK /*show stat*/ case 106: /* rule 106 can match eol */ YY_RULE_SETUP -#line 555 "ob_proxy_parser_gbk.l" +#line 567 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_STAT); return SHOW_PROXYSTAT; } YY_BREAK case 107: YY_RULE_SETUP -#line 556 "ob_proxy_parser_gbk.l" +#line 568 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(REFRESH); } YY_BREAK /*show trace*/ case 108: /* rule 108 can match eol */ YY_RULE_SETUP -#line 559 "ob_proxy_parser_gbk.l" +#line 571 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_TRACE); return SHOW_PROXYTRACE; } YY_BREAK /*show info*/ case 109: /* rule 109 can match eol */ YY_RULE_SETUP -#line 562 "ob_proxy_parser_gbk.l" +#line 574 "ob_proxy_parser_gbk.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_INFO); return SHOW_PROXYINFO; } YY_BREAK case 110: YY_RULE_SETUP -#line 563 "ob_proxy_parser_gbk.l" +#line 575 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(UPGRADE); } YY_BREAK case 111: YY_RULE_SETUP -#line 564 "ob_proxy_parser_gbk.l" +#line 576 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(IDC); } YY_BREAK case 112: /* rule 112 can match eol */ YY_RULE_SETUP -#line 566 "ob_proxy_parser_gbk.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_topology); return SHOW_TOPOLOGY; } +#line 578 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_elastic_id ); return SHOW_ELASTIC_ID; } YY_BREAK case 113: YY_RULE_SETUP -#line 567 "ob_proxy_parser_gbk.l" +#line 579 "ob_proxy_parser_gbk.l" { POP_STATE(); PUSH_STATE(INITIAL); return FROM; } YY_BREAK case 114: YY_RULE_SETUP -#line 568 "ob_proxy_parser_gbk.l" +#line 580 "ob_proxy_parser_gbk.l" { POP_STATE(); PUSH_STATE(INITIAL); return WHERE; } YY_BREAK -case YY_STATE_EOF(show_topology): -#line 569 "ob_proxy_parser_gbk.l" +case YY_STATE_EOF(show_elastic_id): +#line 581 "ob_proxy_parser_gbk.l" { return END_P; } YY_BREAK case 115: /* rule 115 can match eol */ YY_RULE_SETUP -#line 570 "ob_proxy_parser_gbk.l" +#line 582 "ob_proxy_parser_gbk.l" { } YY_BREAK case 116: YY_RULE_SETUP -#line 571 "ob_proxy_parser_gbk.l" +#line 583 "ob_proxy_parser_gbk.l" { POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } YY_BREAK case 117: YY_RULE_SETUP -#line 572 "ob_proxy_parser_gbk.l" +#line 584 "ob_proxy_parser_gbk.l" { return ERROR; } YY_BREAK case 118: /* rule 118 can match eol */ YY_RULE_SETUP -#line 574 "ob_proxy_parser_gbk.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_DB_VERSION; } +#line 586 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_TOPOLOGY; } YY_BREAK case 119: /* rule 119 can match eol */ YY_RULE_SETUP -#line 575 "ob_proxy_parser_gbk.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_DATABASES; } +#line 588 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_DB_VERSION; } YY_BREAK case 120: /* rule 120 can match eol */ YY_RULE_SETUP -#line 577 "ob_proxy_parser_gbk.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_tables); return SHOW_TABLES; } +#line 589 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_DATABASES; } YY_BREAK case 121: /* rule 121 can match eol */ YY_RULE_SETUP -#line 578 "ob_proxy_parser_gbk.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_tables); return SHOW_FULL_TABLES; } +#line 591 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_tables); return SHOW_TABLES; } YY_BREAK case 122: +/* rule 122 can match eol */ YY_RULE_SETUP -#line 580 "ob_proxy_parser_gbk.l" -{ POP_STATE(); PUSH_STATE(INITIAL); return FROM; } +#line 592 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_tables); return SHOW_FULL_TABLES; } YY_BREAK case 123: YY_RULE_SETUP -#line 581 "ob_proxy_parser_gbk.l" +#line 594 "ob_proxy_parser_gbk.l" +{ POP_STATE(); PUSH_STATE(INITIAL); return FROM; } + YY_BREAK +case 124: +YY_RULE_SETUP +#line 595 "ob_proxy_parser_gbk.l" { POP_STATE(); PUSH_STATE(INITIAL); return LIKE; } YY_BREAK case YY_STATE_EOF(show_tables): -#line 582 "ob_proxy_parser_gbk.l" +#line 596 "ob_proxy_parser_gbk.l" { return END_P; } YY_BREAK -case 124: -/* rule 124 can match eol */ -YY_RULE_SETUP -#line 583 "ob_proxy_parser_gbk.l" -{ } - YY_BREAK case 125: +/* rule 125 can match eol */ YY_RULE_SETUP -#line 584 "ob_proxy_parser_gbk.l" -{ POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } +#line 597 "ob_proxy_parser_gbk.l" +{ } YY_BREAK case 126: YY_RULE_SETUP -#line 585 "ob_proxy_parser_gbk.l" -{ return ERROR; } +#line 598 "ob_proxy_parser_gbk.l" +{ POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } YY_BREAK case 127: -/* rule 127 can match eol */ YY_RULE_SETUP -#line 586 "ob_proxy_parser_gbk.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_COLUMNS; } +#line 599 "ob_proxy_parser_gbk.l" +{ return ERROR; } YY_BREAK case 128: /* rule 128 can match eol */ YY_RULE_SETUP -#line 587 "ob_proxy_parser_gbk.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_INDEX; } +#line 600 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_COLUMNS; } YY_BREAK case 129: /* rule 129 can match eol */ YY_RULE_SETUP -#line 589 "ob_proxy_parser_gbk.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_CREATE_TABLE; } +#line 601 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_INDEX; } YY_BREAK case 130: /* rule 130 can match eol */ YY_RULE_SETUP -#line 590 "ob_proxy_parser_gbk.l" -{ SET_DML_STMT(OBPROXY_T_SELECT); return SELECT_DATABASE; } +#line 603 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_CREATE_TABLE; } YY_BREAK case 131: /* rule 131 can match eol */ YY_RULE_SETUP -#line 591 "ob_proxy_parser_gbk.l" -{ SET_DML_STMT(OBPROXY_T_SELECT_PROXY_VERSION); return SELECT_PROXY_VERSION; } +#line 604 "ob_proxy_parser_gbk.l" +{ SET_DML_STMT(OBPROXY_T_SELECT); return SELECT_DATABASE; } YY_BREAK -/*alter config*/ case 132: /* rule 132 can match eol */ YY_RULE_SETUP -#line 594 "ob_proxy_parser_gbk.l" -{ SET_ICMD_STMT(OBPROXY_T_ICMD_ALTER_CONFIG); return ALTER_PROXYCONFIG; } +#line 605 "ob_proxy_parser_gbk.l" +{ SET_DML_STMT(OBPROXY_T_SELECT_PROXY_VERSION); return SELECT_PROXY_VERSION; } YY_BREAK -/*alter resource*/ +/*alter config*/ case 133: /* rule 133 can match eol */ YY_RULE_SETUP -#line 597 "ob_proxy_parser_gbk.l" -{ SET_ICMD_STMT(OBPROXY_T_ICMD_ALTER_RESOURCE); return ALTER_PROXYRESOURCE; } +#line 608 "ob_proxy_parser_gbk.l" +{ SET_ICMD_STMT(OBPROXY_T_ICMD_ALTER_CONFIG); return ALTER_PROXYCONFIG; } YY_BREAK -/*ping proxy*/ +/*alter resource*/ case 134: /* rule 134 can match eol */ YY_RULE_SETUP -#line 600 "ob_proxy_parser_gbk.l" -{ SET_ICMD_STMT(OBPROXY_T_PING_PROXY); return PING_PROXY; } +#line 611 "ob_proxy_parser_gbk.l" +{ SET_ICMD_STMT(OBPROXY_T_ICMD_ALTER_RESOURCE); return ALTER_PROXYRESOURCE; } YY_BREAK -/*kill*/ +/*ping proxy*/ case 135: /* rule 135 can match eol */ YY_RULE_SETUP -#line 603 "ob_proxy_parser_gbk.l" -{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_SESSION); return KILL_PROXYSESSION; } +#line 614 "ob_proxy_parser_gbk.l" +{ SET_ICMD_STMT(OBPROXY_T_PING_PROXY); return PING_PROXY; } YY_BREAK +/*kill*/ case 136: /* rule 136 can match eol */ YY_RULE_SETUP -#line 604 "ob_proxy_parser_gbk.l" -{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_GLOBAL_SESSION); return KILL_GLOBALSESSION; } +#line 617 "ob_proxy_parser_gbk.l" +{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_SESSION); return KILL_PROXYSESSION; } YY_BREAK case 137: +/* rule 137 can match eol */ YY_RULE_SETUP -#line 605 "ob_proxy_parser_gbk.l" -{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_MYSQL); return KILL; } +#line 618 "ob_proxy_parser_gbk.l" +{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_GLOBAL_SESSION); return KILL_GLOBALSESSION; } YY_BREAK case 138: YY_RULE_SETUP -#line 606 "ob_proxy_parser_gbk.l" -{ RETURN_NON_RESERVED_KEYWORD(QUERY); } +#line 619 "ob_proxy_parser_gbk.l" +{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_MYSQL); return KILL; } YY_BREAK -/* obproxy_route_addr */ case 139: -/* rule 139 can match eol */ YY_RULE_SETUP -#line 609 "ob_proxy_parser_gbk.l" -{ return SELECT_OBPROXY_ROUTE_ADDR; } +#line 620 "ob_proxy_parser_gbk.l" +{ RETURN_NON_RESERVED_KEYWORD(QUERY); } YY_BREAK +/* obproxy_route_addr */ case 140: /* rule 140 can match eol */ YY_RULE_SETUP -#line 610 "ob_proxy_parser_gbk.l" +#line 623 "ob_proxy_parser_gbk.l" +{ return SELECT_OBPROXY_ROUTE_ADDR; } + YY_BREAK +case 141: +/* rule 141 can match eol */ +YY_RULE_SETUP +#line 624 "ob_proxy_parser_gbk.l" { return SET_OBPROXY_ROUTE_ADDR; } YY_BREAK /* identifer */ -case 141: +case 142: YY_RULE_SETUP -#line 613 "ob_proxy_parser_gbk.l" +#line 627 "ob_proxy_parser_gbk.l" { SET_FOUND_ROWS(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 142: +case 143: YY_RULE_SETUP -#line 614 "ob_proxy_parser_gbk.l" +#line 628 "ob_proxy_parser_gbk.l" { SET_ROW_COUNT(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 143: +case 144: YY_RULE_SETUP -#line 615 "ob_proxy_parser_gbk.l" +#line 629 "ob_proxy_parser_gbk.l" { SET_LAST_INSERT_ID(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 144: +case 145: YY_RULE_SETUP -#line 616 "ob_proxy_parser_gbk.l" +#line 630 "ob_proxy_parser_gbk.l" { return ','; } YY_BREAK -case 145: +case 146: YY_RULE_SETUP -#line 617 "ob_proxy_parser_gbk.l" +#line 631 "ob_proxy_parser_gbk.l" { RETURN_INT_NUM(); } YY_BREAK -case 146: +case 147: YY_RULE_SETUP -#line 618 "ob_proxy_parser_gbk.l" +#line 632 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 147: +case 148: YY_RULE_SETUP -#line 619 "ob_proxy_parser_gbk.l" +#line 633 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_SINGLE); } YY_BREAK -case 148: +case 149: YY_RULE_SETUP -#line 620 "ob_proxy_parser_gbk.l" +#line 634 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_DOUBLE); } YY_BREAK -case 149: +case 150: YY_RULE_SETUP -#line 621 "ob_proxy_parser_gbk.l" +#line 635 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_BACK); } YY_BREAK -case 150: +case 151: YY_RULE_SETUP -#line 622 "ob_proxy_parser_gbk.l" +#line 636 "ob_proxy_parser_gbk.l" { RETURN_NUMBER_VAL(); } YY_BREAK -case 151: +case 152: YY_RULE_SETUP -#line 623 "ob_proxy_parser_gbk.l" +#line 637 "ob_proxy_parser_gbk.l" { return PLACE_HOLDER; } YY_BREAK -case 152: +case 153: YY_RULE_SETUP -#line 624 "ob_proxy_parser_gbk.l" +#line 638 "ob_proxy_parser_gbk.l" { return yytext[0]; } YY_BREAK -case 153: +case 154: YY_RULE_SETUP -#line 625 "ob_proxy_parser_gbk.l" +#line 639 "ob_proxy_parser_gbk.l" { RETURN_WITH_CALL_CHECK(yytext[0]); } YY_BREAK -case 154: +case 155: YY_RULE_SETUP -#line 626 "ob_proxy_parser_gbk.l" +#line 640 "ob_proxy_parser_gbk.l" { RETURN_WITH_CALL_CHECK('('); } YY_BREAK -case 155: +case 156: YY_RULE_SETUP -#line 627 "ob_proxy_parser_gbk.l" +#line 641 "ob_proxy_parser_gbk.l" { RETURN_WITH_CALL_CHECK(')'); } YY_BREAK -case 156: -/* rule 156 can match eol */ +case 157: +/* rule 157 can match eol */ YY_RULE_SETUP -#line 628 "ob_proxy_parser_gbk.l" +#line 642 "ob_proxy_parser_gbk.l" { } YY_BREAK /* hint option */ -case 157: -/* rule 157 can match eol */ +case 158: +/* rule 158 can match eol */ YY_RULE_SETUP -#line 631 "ob_proxy_parser_gbk.l" +#line 645 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_expr); PUSH_STATE(hint); @@ -6206,20 +6283,20 @@ YY_RULE_SETUP return SELECT_HINT_BEGIN; } YY_BREAK -case 158: -/* rule 158 can match eol */ +case 159: +/* rule 159 can match eol */ YY_RULE_SETUP -#line 637 "ob_proxy_parser_gbk.l" +#line 651 "ob_proxy_parser_gbk.l" { PUSH_STATE(hint); SET_BASIC_STMT(OBPROXY_T_UPDATE); return UPDATE_HINT_BEGIN; } YY_BREAK -case 159: -/* rule 159 can match eol */ +case 160: +/* rule 160 can match eol */ YY_RULE_SETUP -#line 642 "ob_proxy_parser_gbk.l" +#line 656 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_expr); PUSH_STATE(hint); @@ -6227,95 +6304,125 @@ YY_RULE_SETUP return DELETE_HINT_BEGIN; } YY_BREAK -case 160: -/* rule 160 can match eol */ +case 161: +/* rule 161 can match eol */ YY_RULE_SETUP -#line 648 "ob_proxy_parser_gbk.l" +#line 662 "ob_proxy_parser_gbk.l" { PUSH_STATE(hint); SET_BASIC_STMT(OBPROXY_T_INSERT); return INSERT_HINT_BEGIN; } YY_BREAK -case 161: -/* rule 161 can match eol */ +case 162: +/* rule 162 can match eol */ YY_RULE_SETUP -#line 653 "ob_proxy_parser_gbk.l" +#line 667 "ob_proxy_parser_gbk.l" { PUSH_STATE(hint); SET_BASIC_STMT(OBPROXY_T_REPLACE); return REPLACE_HINT_BEGIN; } YY_BREAK -case 162: -/* rule 162 can match eol */ +case 163: +/* rule 163 can match eol */ YY_RULE_SETUP -#line 658 "ob_proxy_parser_gbk.l" +#line 672 "ob_proxy_parser_gbk.l" { PUSH_STATE(hint); SET_BASIC_STMT(OBPROXY_T_MERGE); return MERGE_HINT_BEGIN; } YY_BREAK -case 163: -/* rule 163 can match eol */ +case 164: +/* rule 164 can match eol */ YY_RULE_SETUP -#line 664 "ob_proxy_parser_gbk.l" -{ return AUTOCOMMIT_0; } +#line 678 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW_MASTER_STATUS); return SHOW_MASTER_STATUS; } YY_BREAK -case 164: +case 165: +/* rule 165 can match eol */ +YY_RULE_SETUP +#line 679 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW_BINARY_LOGS); return SHOW_BINARY_LOGS; } + YY_BREAK +case 166: +/* rule 166 can match eol */ +YY_RULE_SETUP +#line 680 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW_BINLOG_EVENTS); return SHOW_BINLOG_EVENTS; } + YY_BREAK +case 167: +/* rule 167 can match eol */ YY_RULE_SETUP -#line 665 "ob_proxy_parser_gbk.l" +#line 681 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_PURGE_BINARY_LOGS); return PURGE_BINARY_LOGS; } + YY_BREAK +case 168: +/* rule 168 can match eol */ +YY_RULE_SETUP +#line 682 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_RESET_MASTER); return RESET_MASTER; } + YY_BREAK +case 169: +/* rule 169 can match eol */ +YY_RULE_SETUP +#line 683 "ob_proxy_parser_gbk.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW_BINLOG_SERVER_FOR_TENANT); return SHOW_BINLOG_SERVER_FOR_TENANT; } + YY_BREAK +case 170: +YY_RULE_SETUP +#line 685 "ob_proxy_parser_gbk.l" { return GLOBAL; } YY_BREAK -case 165: +case 171: YY_RULE_SETUP -#line 666 "ob_proxy_parser_gbk.l" +#line 686 "ob_proxy_parser_gbk.l" { return SESSION; } YY_BREAK -case 166: +case 172: YY_RULE_SETUP -#line 667 "ob_proxy_parser_gbk.l" +#line 687 "ob_proxy_parser_gbk.l" { RETURN_INT_NUM(); } YY_BREAK -case 167: +case 173: YY_RULE_SETUP -#line 668 "ob_proxy_parser_gbk.l" +#line 688 "ob_proxy_parser_gbk.l" { return ','; } YY_BREAK -case 168: +case 174: YY_RULE_SETUP -#line 669 "ob_proxy_parser_gbk.l" +#line 689 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 169: +case 175: YY_RULE_SETUP -#line 670 "ob_proxy_parser_gbk.l" +#line 690 "ob_proxy_parser_gbk.l" { RETURN_NUMBER_VAL(); } YY_BREAK -case 170: -/* rule 170 can match eol */ +case 176: +/* rule 176 can match eol */ YY_RULE_SETUP -#line 671 "ob_proxy_parser_gbk.l" +#line 691 "ob_proxy_parser_gbk.l" { } YY_BREAK -case 171: +case 177: YY_RULE_SETUP -#line 672 "ob_proxy_parser_gbk.l" +#line 692 "ob_proxy_parser_gbk.l" { return yytext[0]; } YY_BREAK case YY_STATE_EOF(set_expr): -#line 673 "ob_proxy_parser_gbk.l" +#line 693 "ob_proxy_parser_gbk.l" { return END_P; } YY_BREAK -case 172: +case 178: YY_RULE_SETUP -#line 674 "ob_proxy_parser_gbk.l" +#line 694 "ob_proxy_parser_gbk.l" { POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } YY_BREAK -case 173: +case 179: YY_RULE_SETUP -#line 676 "ob_proxy_parser_gbk.l" +#line 696 "ob_proxy_parser_gbk.l" { PUSH_STATE(sq); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6326,9 +6433,9 @@ YY_RULE_SETUP } } YY_BREAK -case 174: +case 180: YY_RULE_SETUP -#line 686 "ob_proxy_parser_gbk.l" +#line 706 "ob_proxy_parser_gbk.l" { PUSH_STATE(dq); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6339,9 +6446,9 @@ YY_RULE_SETUP } } YY_BREAK -case 175: +case 181: YY_RULE_SETUP -#line 696 "ob_proxy_parser_gbk.l" +#line 716 "ob_proxy_parser_gbk.l" { PUSH_STATE(bt); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6352,90 +6459,90 @@ YY_RULE_SETUP } } YY_BREAK -case 176: +case 182: YY_RULE_SETUP -#line 705 "ob_proxy_parser_gbk.l" +#line 725 "ob_proxy_parser_gbk.l" { return ERROR; } YY_BREAK -case 177: +case 183: YY_RULE_SETUP -#line 707 "ob_proxy_parser_gbk.l" +#line 727 "ob_proxy_parser_gbk.l" { POP_STATE(); RETURN_IGNORED_WORD(); } YY_BREAK -case 178: +case 184: YY_RULE_SETUP -#line 708 "ob_proxy_parser_gbk.l" +#line 728 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 179: +case 185: YY_RULE_SETUP -#line 710 "ob_proxy_parser_gbk.l" +#line 730 "ob_proxy_parser_gbk.l" { return '('; } YY_BREAK -case 180: +case 186: YY_RULE_SETUP -#line 711 "ob_proxy_parser_gbk.l" +#line 731 "ob_proxy_parser_gbk.l" { return ')'; } YY_BREAK -case 181: +case 187: YY_RULE_SETUP -#line 712 "ob_proxy_parser_gbk.l" +#line 732 "ob_proxy_parser_gbk.l" { return QUERY_TIMEOUT; } YY_BREAK -case 182: +case 188: YY_RULE_SETUP -#line 713 "ob_proxy_parser_gbk.l" +#line 733 "ob_proxy_parser_gbk.l" { RETURN_INT_NUM(); } YY_BREAK -case 183: +case 189: YY_RULE_SETUP -#line 714 "ob_proxy_parser_gbk.l" +#line 734 "ob_proxy_parser_gbk.l" { return READ_CONSISTENCY; } YY_BREAK -case 184: +case 190: YY_RULE_SETUP -#line 715 "ob_proxy_parser_gbk.l" +#line 735 "ob_proxy_parser_gbk.l" { return WEAK; } YY_BREAK -case 185: +case 191: YY_RULE_SETUP -#line 716 "ob_proxy_parser_gbk.l" +#line 736 "ob_proxy_parser_gbk.l" { return STRONG; } YY_BREAK -case 186: +case 192: YY_RULE_SETUP -#line 717 "ob_proxy_parser_gbk.l" +#line 737 "ob_proxy_parser_gbk.l" { return FROZEN; } YY_BREAK -case 187: +case 193: YY_RULE_SETUP -#line 718 "ob_proxy_parser_gbk.l" +#line 738 "ob_proxy_parser_gbk.l" { return INDEX; } YY_BREAK -case 188: +case 194: YY_RULE_SETUP -#line 719 "ob_proxy_parser_gbk.l" +#line 739 "ob_proxy_parser_gbk.l" { return yytext[0]; } YY_BREAK -case 189: +case 195: YY_RULE_SETUP -#line 720 "ob_proxy_parser_gbk.l" +#line 740 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 190: +case 196: YY_RULE_SETUP -#line 721 "ob_proxy_parser_gbk.l" +#line 741 "ob_proxy_parser_gbk.l" { POP_STATE(); return HINT_END; } YY_BREAK -case 191: +case 197: YY_RULE_SETUP -#line 722 "ob_proxy_parser_gbk.l" +#line 742 "ob_proxy_parser_gbk.l" {} YY_BREAK /* comment */ -case 192: +case 198: YY_RULE_SETUP -#line 725 "ob_proxy_parser_gbk.l" +#line 745 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_c_comment); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6450,25 +6557,25 @@ YY_RULE_SETUP } } YY_BREAK -case 193: +case 199: YY_RULE_SETUP -#line 739 "ob_proxy_parser_gbk.l" +#line 759 "ob_proxy_parser_gbk.l" { POP_STATE(); } YY_BREAK -case 194: -/* rule 194 can match eol */ +case 200: +/* rule 200 can match eol */ YY_RULE_SETUP -#line 740 "ob_proxy_parser_gbk.l" +#line 760 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 195: +case 201: YY_RULE_SETUP -#line 741 "ob_proxy_parser_gbk.l" +#line 761 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 196: +case 202: YY_RULE_SETUP -#line 743 "ob_proxy_parser_gbk.l" +#line 763 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -6479,15 +6586,15 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 197: +case 203: YY_RULE_SETUP -#line 753 "ob_proxy_parser_gbk.l" +#line 773 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_old_comment_expr); } YY_BREAK -case 198: -/* rule 198 can match eol */ +case 204: +/* rule 204 can match eol */ YY_RULE_SETUP -#line 754 "ob_proxy_parser_gbk.l" +#line 774 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_old_comment_expr); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6497,10 +6604,10 @@ YY_RULE_SETUP } } YY_BREAK -case 199: -/* rule 199 can match eol */ +case 205: +/* rule 205 can match eol */ YY_RULE_SETUP -#line 763 "ob_proxy_parser_gbk.l" +#line 783 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_old_comment_expr); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6512,9 +6619,9 @@ YY_RULE_SETUP } } YY_BREAK -case 200: +case 206: YY_RULE_SETUP -#line 774 "ob_proxy_parser_gbk.l" +#line 794 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -6523,9 +6630,9 @@ YY_RULE_SETUP } } YY_BREAK -case 201: +case 207: YY_RULE_SETUP -#line 782 "ob_proxy_parser_gbk.l" +#line 802 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -6536,29 +6643,29 @@ YY_RULE_SETUP } } YY_BREAK -case 202: +case 208: YY_RULE_SETUP -#line 792 "ob_proxy_parser_gbk.l" +#line 812 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 203: +case 209: YY_RULE_SETUP -#line 793 "ob_proxy_parser_gbk.l" +#line 813 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_SINGLE); } YY_BREAK -case 204: +case 210: YY_RULE_SETUP -#line 794 "ob_proxy_parser_gbk.l" +#line 814 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_DOUBLE); } YY_BREAK -case 205: +case 211: YY_RULE_SETUP -#line 795 "ob_proxy_parser_gbk.l" +#line 815 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_BACK); } YY_BREAK -case 206: +case 212: YY_RULE_SETUP -#line 796 "ob_proxy_parser_gbk.l" +#line 816 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -6570,160 +6677,171 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 207: +case 213: YY_RULE_SETUP -#line 806 "ob_proxy_parser_gbk.l" +#line 826 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 208: +case 214: YY_RULE_SETUP -#line 808 "ob_proxy_parser_gbk.l" +#line 828 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(ODP_COMMENT); } YY_BREAK -case 209: -/* rule 209 can match eol */ +case 215: +/* rule 215 can match eol */ YY_RULE_SETUP -#line 809 "ob_proxy_parser_gbk.l" +#line 829 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(GROUP_ID); } YY_BREAK -case 210: -/* rule 210 can match eol */ +case 216: +/* rule 216 can match eol */ YY_RULE_SETUP -#line 810 "ob_proxy_parser_gbk.l" +#line 830 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(TABLE_ID); } YY_BREAK -case 211: -/* rule 211 can match eol */ +case 217: +/* rule 217 can match eol */ YY_RULE_SETUP -#line 811 "ob_proxy_parser_gbk.l" +#line 831 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(TABLE_NAME); } YY_BREAK -case 212: -/* rule 212 can match eol */ +case 218: +/* rule 218 can match eol */ YY_RULE_SETUP -#line 812 "ob_proxy_parser_gbk.l" +#line 832 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(ELASTIC_ID); } YY_BREAK -case 213: -/* rule 213 can match eol */ +case 219: +/* rule 219 can match eol */ YY_RULE_SETUP -#line 813 "ob_proxy_parser_gbk.l" +#line 833 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(TESTLOAD); } YY_BREAK -case 214: -/* rule 214 can match eol */ +case 220: +/* rule 220 can match eol */ YY_RULE_SETUP -#line 814 "ob_proxy_parser_gbk.l" +#line 834 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(DISASTER_STATUS); } YY_BREAK -case 215: -/* rule 215 can match eol */ +case 221: +/* rule 221 can match eol */ YY_RULE_SETUP -#line 815 "ob_proxy_parser_gbk.l" +#line 835 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(TNT_ID); } YY_BREAK -case 216: -/* rule 216 can match eol */ +case 222: +/* rule 222 can match eol */ YY_RULE_SETUP -#line 816 "ob_proxy_parser_gbk.l" +#line 836 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(TRACE_ID); } YY_BREAK -case 217: -/* rule 217 can match eol */ +case 223: +/* rule 223 can match eol */ YY_RULE_SETUP -#line 817 "ob_proxy_parser_gbk.l" +#line 837 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT_NAME_OB_DOT(NAME_OB_DOT); } YY_BREAK -case 218: -/* rule 218 can match eol */ +case 224: +/* rule 224 can match eol */ YY_RULE_SETUP -#line 818 "ob_proxy_parser_gbk.l" +#line 838 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(RPC_ID); } YY_BREAK -case 219: +case 225: +/* rule 225 can match eol */ YY_RULE_SETUP -#line 820 "ob_proxy_parser_gbk.l" +#line 839 "ob_proxy_parser_gbk.l" +{ PUSH_STATE(in_odp_comment_expr); return TARGET_DB_SERVER; } + YY_BREAK +case 226: +YY_RULE_SETUP +#line 841 "ob_proxy_parser_gbk.l" { return GROUP_ID; } YY_BREAK -case 220: +case 227: YY_RULE_SETUP -#line 821 "ob_proxy_parser_gbk.l" +#line 842 "ob_proxy_parser_gbk.l" { return TABLE_ID; } YY_BREAK -case 221: +case 228: YY_RULE_SETUP -#line 822 "ob_proxy_parser_gbk.l" +#line 843 "ob_proxy_parser_gbk.l" { return TABLE_NAME; } YY_BREAK -case 222: +case 229: YY_RULE_SETUP -#line 823 "ob_proxy_parser_gbk.l" +#line 844 "ob_proxy_parser_gbk.l" { return ELASTIC_ID; } YY_BREAK -case 223: +case 230: YY_RULE_SETUP -#line 824 "ob_proxy_parser_gbk.l" +#line 845 "ob_proxy_parser_gbk.l" { return TESTLOAD; } YY_BREAK -case 224: +case 231: YY_RULE_SETUP -#line 825 "ob_proxy_parser_gbk.l" +#line 846 "ob_proxy_parser_gbk.l" { return DISASTER_STATUS; } YY_BREAK -case 225: +case 232: YY_RULE_SETUP -#line 826 "ob_proxy_parser_gbk.l" +#line 847 "ob_proxy_parser_gbk.l" { return TNT_ID; } YY_BREAK -case 226: +case 233: YY_RULE_SETUP -#line 827 "ob_proxy_parser_gbk.l" +#line 848 "ob_proxy_parser_gbk.l" { return TRACE_ID; } YY_BREAK -case 227: +case 234: YY_RULE_SETUP -#line 828 "ob_proxy_parser_gbk.l" +#line 849 "ob_proxy_parser_gbk.l" { return RPC_ID; } YY_BREAK -case 228: +case 235: YY_RULE_SETUP -#line 829 "ob_proxy_parser_gbk.l" +#line 850 "ob_proxy_parser_gbk.l" +{ return TARGET_DB_SERVER; } + YY_BREAK +case 236: +YY_RULE_SETUP +#line 851 "ob_proxy_parser_gbk.l" { ENTER_QUOTE_STATE(comment_sq); } YY_BREAK -case 229: +case 237: YY_RULE_SETUP -#line 830 "ob_proxy_parser_gbk.l" +#line 852 "ob_proxy_parser_gbk.l" { return ','; } YY_BREAK -case 230: +case 238: YY_RULE_SETUP -#line 831 "ob_proxy_parser_gbk.l" +#line 853 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 231: +case 239: YY_RULE_SETUP -#line 832 "ob_proxy_parser_gbk.l" +#line 854 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_odp_comment_value_expr); return yytext[0]; } YY_BREAK -case 232: +case 240: YY_RULE_SETUP -#line 833 "ob_proxy_parser_gbk.l" +#line 855 "ob_proxy_parser_gbk.l" { return yytext[0]; } YY_BREAK -case 233: -/* rule 233 can match eol */ +case 241: +/* rule 241 can match eol */ YY_RULE_SETUP -#line 834 "ob_proxy_parser_gbk.l" +#line 856 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 234: +case 242: YY_RULE_SETUP -#line 835 "ob_proxy_parser_gbk.l" +#line 857 "ob_proxy_parser_gbk.l" { return ERROR; } YY_BREAK -case 235: +case 243: YY_RULE_SETUP -#line 836 "ob_proxy_parser_gbk.l" +#line 858 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -6735,22 +6853,22 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 236: +case 244: YY_RULE_SETUP -#line 847 "ob_proxy_parser_gbk.l" +#line 869 "ob_proxy_parser_gbk.l" { ENTER_QUOTE_STATE(comment_sq); } YY_BREAK -case 237: +case 245: YY_RULE_SETUP -#line 848 "ob_proxy_parser_gbk.l" +#line 870 "ob_proxy_parser_gbk.l" { POP_STATE(); return ','; } YY_BREAK -case 238: +case 246: YY_RULE_SETUP -#line 852 "ob_proxy_parser_gbk.l" +#line 874 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -6763,15 +6881,15 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 239: -/* rule 239 can match eol */ +case 247: +/* rule 247 can match eol */ YY_RULE_SETUP -#line 863 "ob_proxy_parser_gbk.l" +#line 885 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 240: +case 248: YY_RULE_SETUP -#line 864 "ob_proxy_parser_gbk.l" +#line 886 "ob_proxy_parser_gbk.l" { do { PUSH_STATE(in_odp_comment_value_expr_calc) @@ -6784,10 +6902,10 @@ YY_RULE_SETUP } while (0); } YY_BREAK -case 241: -/* rule 241 can match eol */ +case 249: +/* rule 249 can match eol */ YY_RULE_SETUP -#line 876 "ob_proxy_parser_gbk.l" +#line 898 "ob_proxy_parser_gbk.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6800,9 +6918,9 @@ YY_RULE_SETUP } } YY_BREAK -case 242: +case 250: YY_RULE_SETUP -#line 888 "ob_proxy_parser_gbk.l" +#line 910 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -6810,90 +6928,95 @@ YY_RULE_SETUP } } YY_BREAK -case 243: +case 251: YY_RULE_SETUP -#line 895 "ob_proxy_parser_gbk.l" +#line 917 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_dbp_comment_expr); RETURN_SHARD_COMMENT(DBP_COMMENT); } YY_BREAK -case 244: +case 252: YY_RULE_SETUP -#line 896 "ob_proxy_parser_gbk.l" +#line 918 "ob_proxy_parser_gbk.l" { return ROUTE_TAG; } YY_BREAK -case 245: +case 253: YY_RULE_SETUP -#line 897 "ob_proxy_parser_gbk.l" +#line 919 "ob_proxy_parser_gbk.l" { return SYS_TAG; } YY_BREAK -case 246: +case 254: YY_RULE_SETUP -#line 898 "ob_proxy_parser_gbk.l" +#line 920 "ob_proxy_parser_gbk.l" { return SCAN_ALL; } YY_BREAK -case 247: +case 255: +YY_RULE_SETUP +#line 921 "ob_proxy_parser_gbk.l" +{ return STICKY_SESSION; } + YY_BREAK +case 256: YY_RULE_SETUP -#line 899 "ob_proxy_parser_gbk.l" +#line 922 "ob_proxy_parser_gbk.l" { return SHARD_KEY; } YY_BREAK -case 248: +case 257: YY_RULE_SETUP -#line 900 "ob_proxy_parser_gbk.l" +#line 923 "ob_proxy_parser_gbk.l" { return TABLE_NAME;} YY_BREAK -case 249: +case 258: YY_RULE_SETUP -#line 901 "ob_proxy_parser_gbk.l" +#line 924 "ob_proxy_parser_gbk.l" { return PARALL; } YY_BREAK -case 250: +case 259: YY_RULE_SETUP -#line 902 "ob_proxy_parser_gbk.l" +#line 925 "ob_proxy_parser_gbk.l" { return GROUP_ID; } YY_BREAK -case 251: +case 260: YY_RULE_SETUP -#line 903 "ob_proxy_parser_gbk.l" +#line 926 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_dbp_comment_trace_expr); return TRACE; } YY_BREAK -case 252: +case 261: YY_RULE_SETUP -#line 904 "ob_proxy_parser_gbk.l" +#line 927 "ob_proxy_parser_gbk.l" { ENTER_QUOTE_STATE(comment_sq); } YY_BREAK -case 253: +case 262: YY_RULE_SETUP -#line 905 "ob_proxy_parser_gbk.l" +#line 928 "ob_proxy_parser_gbk.l" { return yytext[0]; } YY_BREAK -case 254: +case 263: YY_RULE_SETUP -#line 906 "ob_proxy_parser_gbk.l" +#line 929 "ob_proxy_parser_gbk.l" { return '('; } YY_BREAK -case 255: +case 264: YY_RULE_SETUP -#line 907 "ob_proxy_parser_gbk.l" +#line 930 "ob_proxy_parser_gbk.l" { return ')'; } YY_BREAK -case 256: +case 265: YY_RULE_SETUP -#line 908 "ob_proxy_parser_gbk.l" +#line 931 "ob_proxy_parser_gbk.l" { return ','; } YY_BREAK -case 257: -/* rule 257 can match eol */ +case 266: +/* rule 266 can match eol */ YY_RULE_SETUP -#line 909 "ob_proxy_parser_gbk.l" +#line 932 "ob_proxy_parser_gbk.l" { } YY_BREAK -case 258: +case 267: YY_RULE_SETUP -#line 910 "ob_proxy_parser_gbk.l" +#line 933 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 259: +case 268: YY_RULE_SETUP -#line 912 "ob_proxy_parser_gbk.l" +#line 935 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -6905,39 +7028,39 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 260: +case 269: YY_RULE_SETUP -#line 922 "ob_proxy_parser_gbk.l" +#line 945 "ob_proxy_parser_gbk.l" {return yytext[0];} YY_BREAK -case 261: +case 270: YY_RULE_SETUP -#line 923 "ob_proxy_parser_gbk.l" +#line 946 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_dbp_comment_trace_value_expr); return '('; } YY_BREAK -case 262: -/* rule 262 can match eol */ +case 271: +/* rule 271 can match eol */ YY_RULE_SETUP -#line 924 "ob_proxy_parser_gbk.l" +#line 947 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 263: +case 272: YY_RULE_SETUP -#line 926 "ob_proxy_parser_gbk.l" +#line 949 "ob_proxy_parser_gbk.l" { ENTER_QUOTE_STATE(comment_sq); } YY_BREAK -case 264: +case 273: YY_RULE_SETUP -#line 927 "ob_proxy_parser_gbk.l" +#line 950 "ob_proxy_parser_gbk.l" { POP_STATE(); POP_STATE(); return ')'; } YY_BREAK -case 265: +case 274: YY_RULE_SETUP -#line 932 "ob_proxy_parser_gbk.l" +#line 955 "ob_proxy_parser_gbk.l" { do { PUSH_STATE(in_dbp_comment_trace_value_expr_calc) @@ -6951,9 +7074,9 @@ YY_RULE_SETUP } while (0); } YY_BREAK -case 266: +case 275: YY_RULE_SETUP -#line 944 "ob_proxy_parser_gbk.l" +#line 967 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -6967,15 +7090,15 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 267: -/* rule 267 can match eol */ +case 276: +/* rule 276 can match eol */ YY_RULE_SETUP -#line 956 "ob_proxy_parser_gbk.l" +#line 979 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 268: +case 277: YY_RULE_SETUP -#line 957 "ob_proxy_parser_gbk.l" +#line 980 "ob_proxy_parser_gbk.l" { do { PUSH_STATE(in_dbp_comment_trace_value_expr_calc) @@ -6988,10 +7111,10 @@ YY_RULE_SETUP } while (0); } YY_BREAK -case 269: -/* rule 269 can match eol */ +case 278: +/* rule 278 can match eol */ YY_RULE_SETUP -#line 969 "ob_proxy_parser_gbk.l" +#line 992 "ob_proxy_parser_gbk.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7004,9 +7127,9 @@ YY_RULE_SETUP } } YY_BREAK -case 270: +case 279: YY_RULE_SETUP -#line 981 "ob_proxy_parser_gbk.l" +#line 1004 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7015,9 +7138,9 @@ YY_RULE_SETUP } YY_BREAK /* quote */ -case 271: +case 280: YY_RULE_SETUP -#line 989 "ob_proxy_parser_gbk.l" +#line 1012 "ob_proxy_parser_gbk.l" { PUSH_STATE(sq); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7028,10 +7151,10 @@ YY_RULE_SETUP } } YY_BREAK -case 272: -/* rule 272 can match eol */ +case 281: +/* rule 281 can match eol */ YY_RULE_SETUP -#line 999 "ob_proxy_parser_gbk.l" +#line 1022 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7039,9 +7162,9 @@ YY_RULE_SETUP } } YY_BREAK -case 273: +case 282: YY_RULE_SETUP -#line 1006 "ob_proxy_parser_gbk.l" +#line 1029 "ob_proxy_parser_gbk.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7059,32 +7182,32 @@ YY_RULE_SETUP } } YY_BREAK -case 274: +case 283: YY_RULE_SETUP -#line 1023 "ob_proxy_parser_gbk.l" +#line 1046 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 275: -/* rule 275 can match eol */ +case 284: +/* rule 284 can match eol */ YY_RULE_SETUP -#line 1024 "ob_proxy_parser_gbk.l" +#line 1047 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 276: -/* rule 276 can match eol */ +case 285: +/* rule 285 can match eol */ YY_RULE_SETUP -#line 1025 "ob_proxy_parser_gbk.l" +#line 1048 "ob_proxy_parser_gbk.l" {} YY_BREAK case YY_STATE_EOF(sq): -#line 1026 "ob_proxy_parser_gbk.l" +#line 1049 "ob_proxy_parser_gbk.l" { return ERROR; } YY_BREAK /* comment sq return name_str */ -case 277: -/* rule 277 can match eol */ +case 286: +/* rule 286 can match eol */ YY_RULE_SETUP -#line 1029 "ob_proxy_parser_gbk.l" +#line 1052 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7092,9 +7215,9 @@ YY_RULE_SETUP } } YY_BREAK -case 278: +case 287: YY_RULE_SETUP -#line 1036 "ob_proxy_parser_gbk.l" +#line 1059 "ob_proxy_parser_gbk.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7106,31 +7229,31 @@ YY_RULE_SETUP } } YY_BREAK -case 279: +case 288: YY_RULE_SETUP -#line 1047 "ob_proxy_parser_gbk.l" +#line 1070 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 280: -/* rule 280 can match eol */ +case 289: +/* rule 289 can match eol */ YY_RULE_SETUP -#line 1048 "ob_proxy_parser_gbk.l" +#line 1071 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 281: -/* rule 281 can match eol */ +case 290: +/* rule 290 can match eol */ YY_RULE_SETUP -#line 1049 "ob_proxy_parser_gbk.l" +#line 1072 "ob_proxy_parser_gbk.l" {} YY_BREAK case YY_STATE_EOF(comment_sq): -#line 1050 "ob_proxy_parser_gbk.l" +#line 1073 "ob_proxy_parser_gbk.l" { return ERROR; } YY_BREAK /* dquote */ -case 282: +case 291: YY_RULE_SETUP -#line 1053 "ob_proxy_parser_gbk.l" +#line 1076 "ob_proxy_parser_gbk.l" { PUSH_STATE(dq); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7141,10 +7264,10 @@ YY_RULE_SETUP } } YY_BREAK -case 283: -/* rule 283 can match eol */ +case 292: +/* rule 292 can match eol */ YY_RULE_SETUP -#line 1063 "ob_proxy_parser_gbk.l" +#line 1086 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7152,9 +7275,9 @@ YY_RULE_SETUP } } YY_BREAK -case 284: +case 293: YY_RULE_SETUP -#line 1070 "ob_proxy_parser_gbk.l" +#line 1093 "ob_proxy_parser_gbk.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7172,31 +7295,31 @@ YY_RULE_SETUP } } YY_BREAK -case 285: +case 294: YY_RULE_SETUP -#line 1087 "ob_proxy_parser_gbk.l" +#line 1110 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 286: -/* rule 286 can match eol */ +case 295: +/* rule 295 can match eol */ YY_RULE_SETUP -#line 1088 "ob_proxy_parser_gbk.l" +#line 1111 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 287: -/* rule 287 can match eol */ +case 296: +/* rule 296 can match eol */ YY_RULE_SETUP -#line 1089 "ob_proxy_parser_gbk.l" +#line 1112 "ob_proxy_parser_gbk.l" {} YY_BREAK case YY_STATE_EOF(dq): -#line 1090 "ob_proxy_parser_gbk.l" +#line 1113 "ob_proxy_parser_gbk.l" { return ERROR; } YY_BREAK /* backtick */ -case 288: +case 297: YY_RULE_SETUP -#line 1094 "ob_proxy_parser_gbk.l" +#line 1117 "ob_proxy_parser_gbk.l" { PUSH_STATE(bt); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7207,9 +7330,9 @@ YY_RULE_SETUP } } YY_BREAK -case 289: +case 298: YY_RULE_SETUP -#line 1104 "ob_proxy_parser_gbk.l" +#line 1127 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (NULL != p && NULL != p->tmp_buf_ && p->tmp_len_ + 1 < OBPROXY_MAX_NAME_LENGTH) { @@ -7217,10 +7340,10 @@ YY_RULE_SETUP } } YY_BREAK -case 290: -/* rule 290 can match eol */ +case 299: +/* rule 299 can match eol */ YY_RULE_SETUP -#line 1111 "ob_proxy_parser_gbk.l" +#line 1134 "ob_proxy_parser_gbk.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (NULL != p && NULL != p->tmp_buf_ && p->tmp_len_ + yyleng < OBPROXY_MAX_NAME_LENGTH) { @@ -7229,9 +7352,9 @@ YY_RULE_SETUP } } YY_BREAK -case 291: +case 300: YY_RULE_SETUP -#line 1119 "ob_proxy_parser_gbk.l" +#line 1142 "ob_proxy_parser_gbk.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7245,248 +7368,242 @@ YY_RULE_SETUP } YY_BREAK case YY_STATE_EOF(bt): -#line 1131 "ob_proxy_parser_gbk.l" +#line 1154 "ob_proxy_parser_gbk.l" { return ERROR; } YY_BREAK -case 292: +case 301: YY_RULE_SETUP -#line 1135 "ob_proxy_parser_gbk.l" +#line 1158 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 293: -/* rule 293 can match eol */ +case 302: +/* rule 302 can match eol */ YY_RULE_SETUP -#line 1136 "ob_proxy_parser_gbk.l" +#line 1159 "ob_proxy_parser_gbk.l" {} YY_BREAK -case 294: +case 303: YY_RULE_SETUP -#line 1137 "ob_proxy_parser_gbk.l" +#line 1160 "ob_proxy_parser_gbk.l" { POP_STATE(); RETURN_IGNORED_WORD(); } YY_BREAK case YY_STATE_EOF(bt_in_expr): -#line 1138 "ob_proxy_parser_gbk.l" +#line 1161 "ob_proxy_parser_gbk.l" { return ERROR; } YY_BREAK /* some useful keyword */ -case 295: -/* rule 295 can match eol */ +case 304: +/* rule 304 can match eol */ YY_RULE_SETUP -#line 1141 "ob_proxy_parser_gbk.l" +#line 1164 "ob_proxy_parser_gbk.l" { RETURN_IGNORED_WORD_FOR_DUAL(); } YY_BREAK -case 296: +case 305: YY_RULE_SETUP -#line 1142 "ob_proxy_parser_gbk.l" +#line 1165 "ob_proxy_parser_gbk.l" { POP_STATE(); PUSH_STATE(INITIAL); return FROM; } YY_BREAK -case 297: +case 306: YY_RULE_SETUP -#line 1143 "ob_proxy_parser_gbk.l" +#line 1166 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_subquery); return '('; } YY_BREAK -case 298: +case 307: YY_RULE_SETUP -#line 1144 "ob_proxy_parser_gbk.l" +#line 1167 "ob_proxy_parser_gbk.l" { PUSH_STATE(dq); } YY_BREAK -case 299: +case 308: YY_RULE_SETUP -#line 1145 "ob_proxy_parser_gbk.l" +#line 1168 "ob_proxy_parser_gbk.l" { PUSH_STATE(sq); } YY_BREAK -case 300: +case 309: YY_RULE_SETUP -#line 1146 "ob_proxy_parser_gbk.l" +#line 1169 "ob_proxy_parser_gbk.l" { PUSH_STATE(bt_in_expr); } YY_BREAK -case 301: +case 310: YY_RULE_SETUP -#line 1147 "ob_proxy_parser_gbk.l" +#line 1170 "ob_proxy_parser_gbk.l" { SET_FOUND_ROWS(); RETURN_IGNORED_WORD(); } YY_BREAK -case 302: +case 311: YY_RULE_SETUP -#line 1148 "ob_proxy_parser_gbk.l" +#line 1171 "ob_proxy_parser_gbk.l" { SET_ROW_COUNT(); RETURN_IGNORED_WORD(); } YY_BREAK -case 303: +case 312: YY_RULE_SETUP -#line 1149 "ob_proxy_parser_gbk.l" +#line 1172 "ob_proxy_parser_gbk.l" { SET_LAST_INSERT_ID(); RETURN_IGNORED_WORD(); } YY_BREAK -case 304: +case 313: YY_RULE_SETUP -#line 1150 "ob_proxy_parser_gbk.l" +#line 1173 "ob_proxy_parser_gbk.l" { SET_GLOBAL_SET_STMT(); RETURN_IGNORED_WORD(); } YY_BREAK -case 305: -/* rule 305 can match eol */ +case 314: +/* rule 314 can match eol */ YY_RULE_SETUP -#line 1151 "ob_proxy_parser_gbk.l" +#line 1174 "ob_proxy_parser_gbk.l" { RETURN_COL_NAME(TX_READ_ONLY); } YY_BREAK -case 306: -/* rule 306 can match eol */ -YY_RULE_SETUP -#line 1152 "ob_proxy_parser_gbk.l" -{ return AUTOCOMMIT_0; } - YY_BREAK -case 307: +case 315: YY_RULE_SETUP -#line 1153 "ob_proxy_parser_gbk.l" +#line 1175 "ob_proxy_parser_gbk.l" { RETURN_IGNORED_WORD(); } YY_BREAK case YY_STATE_EOF(in_expr): -#line 1154 "ob_proxy_parser_gbk.l" +#line 1176 "ob_proxy_parser_gbk.l" { return END_P; } YY_BREAK -case 308: -/* rule 308 can match eol */ +case 316: +/* rule 316 can match eol */ YY_RULE_SETUP -#line 1155 "ob_proxy_parser_gbk.l" +#line 1177 "ob_proxy_parser_gbk.l" { } YY_BREAK -case 309: +case 317: YY_RULE_SETUP -#line 1156 "ob_proxy_parser_gbk.l" +#line 1178 "ob_proxy_parser_gbk.l" { POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } YY_BREAK -case 310: +case 318: YY_RULE_SETUP -#line 1157 "ob_proxy_parser_gbk.l" +#line 1179 "ob_proxy_parser_gbk.l" { RETURN_IGNORED_WORD(); } YY_BREAK -case 311: +case 319: YY_RULE_SETUP -#line 1159 "ob_proxy_parser_gbk.l" +#line 1181 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_expr); return SELECT; } YY_BREAK -case 312: +case 320: YY_RULE_SETUP -#line 1160 "ob_proxy_parser_gbk.l" +#line 1182 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_subquery); return '('; } YY_BREAK -case 313: +case 321: YY_RULE_SETUP -#line 1161 "ob_proxy_parser_gbk.l" +#line 1183 "ob_proxy_parser_gbk.l" { POP_STATE(); return ')'; } YY_BREAK -case 314: +case 322: YY_RULE_SETUP -#line 1162 "ob_proxy_parser_gbk.l" +#line 1184 "ob_proxy_parser_gbk.l" { PUSH_STATE(dq); } YY_BREAK -case 315: +case 323: YY_RULE_SETUP -#line 1163 "ob_proxy_parser_gbk.l" +#line 1185 "ob_proxy_parser_gbk.l" { PUSH_STATE(sq); } YY_BREAK case YY_STATE_EOF(in_subquery): -#line 1164 "ob_proxy_parser_gbk.l" +#line 1186 "ob_proxy_parser_gbk.l" { return END_P; } YY_BREAK -case 316: -/* rule 316 can match eol */ +case 324: +/* rule 324 can match eol */ YY_RULE_SETUP -#line 1165 "ob_proxy_parser_gbk.l" +#line 1187 "ob_proxy_parser_gbk.l" { } YY_BREAK -case 317: +case 325: YY_RULE_SETUP -#line 1166 "ob_proxy_parser_gbk.l" +#line 1188 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_no_select_query); RETURN_IGNORED_WORD(); } YY_BREAK -case 318: +case 326: YY_RULE_SETUP -#line 1168 "ob_proxy_parser_gbk.l" +#line 1190 "ob_proxy_parser_gbk.l" { PUSH_STATE(in_subquery); return '('; } YY_BREAK -case 319: +case 327: YY_RULE_SETUP -#line 1169 "ob_proxy_parser_gbk.l" +#line 1191 "ob_proxy_parser_gbk.l" { POP_STATE(); POP_STATE(); return ')'; } YY_BREAK -case 320: +case 328: YY_RULE_SETUP -#line 1170 "ob_proxy_parser_gbk.l" +#line 1192 "ob_proxy_parser_gbk.l" { PUSH_STATE(dq); } YY_BREAK -case 321: +case 329: YY_RULE_SETUP -#line 1171 "ob_proxy_parser_gbk.l" +#line 1193 "ob_proxy_parser_gbk.l" { PUSH_STATE(sq); } YY_BREAK -case 322: +case 330: YY_RULE_SETUP -#line 1172 "ob_proxy_parser_gbk.l" +#line 1194 "ob_proxy_parser_gbk.l" { SET_FOUND_ROWS(); RETURN_IGNORED_WORD(); } YY_BREAK -case 323: +case 331: YY_RULE_SETUP -#line 1173 "ob_proxy_parser_gbk.l" +#line 1195 "ob_proxy_parser_gbk.l" { SET_ROW_COUNT(); RETURN_IGNORED_WORD(); } YY_BREAK -case 324: +case 332: YY_RULE_SETUP -#line 1174 "ob_proxy_parser_gbk.l" +#line 1196 "ob_proxy_parser_gbk.l" { SET_LAST_INSERT_ID(); RETURN_IGNORED_WORD(); } YY_BREAK -case 325: +case 333: YY_RULE_SETUP -#line 1175 "ob_proxy_parser_gbk.l" +#line 1197 "ob_proxy_parser_gbk.l" { RETURN_IGNORED_WORD(); } YY_BREAK case YY_STATE_EOF(in_no_select_query): -#line 1176 "ob_proxy_parser_gbk.l" +#line 1198 "ob_proxy_parser_gbk.l" { return END_P; } YY_BREAK -case 326: -/* rule 326 can match eol */ +case 334: +/* rule 334 can match eol */ YY_RULE_SETUP -#line 1177 "ob_proxy_parser_gbk.l" +#line 1199 "ob_proxy_parser_gbk.l" { } YY_BREAK -case 327: +case 335: YY_RULE_SETUP -#line 1178 "ob_proxy_parser_gbk.l" +#line 1200 "ob_proxy_parser_gbk.l" { RETURN_IGNORED_WORD(); } YY_BREAK -case 328: +case 336: YY_RULE_SETUP -#line 1180 "ob_proxy_parser_gbk.l" +#line 1202 "ob_proxy_parser_gbk.l" { return FROM; } YY_BREAK -case 329: +case 337: YY_RULE_SETUP -#line 1181 "ob_proxy_parser_gbk.l" +#line 1203 "ob_proxy_parser_gbk.l" { return yytext[0]; } YY_BREAK -case 330: +case 338: YY_RULE_SETUP -#line 1182 "ob_proxy_parser_gbk.l" +#line 1204 "ob_proxy_parser_gbk.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 331: +case 339: YY_RULE_SETUP -#line 1183 "ob_proxy_parser_gbk.l" +#line 1205 "ob_proxy_parser_gbk.l" { POP_STATE(); } YY_BREAK -case 332: +case 340: YY_RULE_SETUP -#line 1184 "ob_proxy_parser_gbk.l" +#line 1206 "ob_proxy_parser_gbk.l" { POP_STATE(); } YY_BREAK -case 333: +case 341: YY_RULE_SETUP -#line 1186 "ob_proxy_parser_gbk.l" -{ POP_STATE(); return BEGI;} +#line 1208 "ob_proxy_parser_gbk.l" +{ POP_STATE(); RETURN_NON_RESERVED_KEYWORD(BEGI);} YY_BREAK -case 334: +case 342: YY_RULE_SETUP -#line 1187 "ob_proxy_parser_gbk.l" +#line 1209 "ob_proxy_parser_gbk.l" {} YY_BREAK case YY_STATE_EOF(INITIAL): @@ -7505,21 +7622,22 @@ case YY_STATE_EOF(in_dbp_comment_trace_value_expr_calc): case YY_STATE_EOF(in_anonymous_block): case YY_STATE_EOF(prepare): case YY_STATE_EOF(insert_all_expr): +case YY_STATE_EOF(show_topology): case YY_STATE_EOF(proxy_icmd_state): -#line 1189 "ob_proxy_parser_gbk.l" +#line 1211 "ob_proxy_parser_gbk.l" { return END_P; } YY_BREAK -case 335: +case 343: YY_RULE_SETUP -#line 1190 "ob_proxy_parser_gbk.l" +#line 1212 "ob_proxy_parser_gbk.l" { RETURN_IGNORED_WORD(); } YY_BREAK -case 336: +case 344: YY_RULE_SETUP -#line 1191 "ob_proxy_parser_gbk.l" +#line 1213 "ob_proxy_parser_gbk.l" ECHO; YY_BREAK -#line 7525 "ob_proxy_parser_gbk_lex.c" +#line 7643 "ob_proxy_parser_gbk_lex.c" case YY_END_OF_BUFFER: { @@ -7811,7 +7929,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 2327 ) + if ( yy_current_state >= 2515 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -7840,11 +7958,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 2327 ) + if ( yy_current_state >= 2515 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 2326); + yy_is_jam = (yy_current_state == 2514); return yy_is_jam ? 0 : yy_current_state; } @@ -8669,7 +8787,7 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 1191 "ob_proxy_parser_gbk.l" +#line 1213 "ob_proxy_parser_gbk.l" inline void *ob_proxy_parser_gbk_yyalloc(size_t bytes,void *yyscanner) @@ -8879,96 +8997,104 @@ extern int ob_proxy_parser_gbk_yydebug; UNION = 333, FOR = 334, TX_READ_ONLY = 335, - AUTOCOMMIT_0 = 336, - SELECT_OBPROXY_ROUTE_ADDR = 337, - SET_OBPROXY_ROUTE_ADDR = 338, - NAME_OB_DOT = 339, - NAME_OB = 340, - EXPLAIN = 341, - DESC = 342, - DESCRIBE = 343, - NAME_STR = 344, - USE = 345, - HELP = 346, - SET_NAMES = 347, - SET_CHARSET = 348, - SET_PASSWORD = 349, - SET_DEFAULT = 350, - SET_OB_READ_CONSISTENCY = 351, - SET_TX_READ_ONLY = 352, - GLOBAL = 353, - SESSION = 354, - NUMBER_VAL = 355, - GROUP_ID = 356, - TABLE_ID = 357, - ELASTIC_ID = 358, - TESTLOAD = 359, - ODP_COMMENT = 360, - TNT_ID = 361, - DISASTER_STATUS = 362, - TRACE_ID = 363, - RPC_ID = 364, + SELECT_OBPROXY_ROUTE_ADDR = 336, + SET_OBPROXY_ROUTE_ADDR = 337, + NAME_OB_DOT = 338, + NAME_OB = 339, + EXPLAIN = 340, + DESC = 341, + DESCRIBE = 342, + NAME_STR = 343, + USE = 344, + HELP = 345, + SET_NAMES = 346, + SET_CHARSET = 347, + SET_PASSWORD = 348, + SET_DEFAULT = 349, + SET_OB_READ_CONSISTENCY = 350, + SET_TX_READ_ONLY = 351, + GLOBAL = 352, + SESSION = 353, + NUMBER_VAL = 354, + GROUP_ID = 355, + TABLE_ID = 356, + ELASTIC_ID = 357, + TESTLOAD = 358, + ODP_COMMENT = 359, + TNT_ID = 360, + DISASTER_STATUS = 361, + TRACE_ID = 362, + RPC_ID = 363, + TARGET_DB_SERVER = 364, DBP_COMMENT = 365, ROUTE_TAG = 366, SYS_TAG = 367, TABLE_NAME = 368, SCAN_ALL = 369, - PARALL = 370, - SHARD_KEY = 371, - INT_NUM = 372, - SHOW_PROXYNET = 373, - THREAD = 374, - CONNECTION = 375, - LIMIT = 376, - OFFSET = 377, - SHOW_PROCESSLIST = 378, - SHOW_PROXYSESSION = 379, - SHOW_GLOBALSESSION = 380, - ATTRIBUTE = 381, - VARIABLES = 382, - ALL = 383, - STAT = 384, - SHOW_PROXYCONFIG = 385, - DIFF = 386, - USER = 387, - LIKE = 388, - SHOW_PROXYSM = 389, - SHOW_PROXYCLUSTER = 390, - SHOW_PROXYRESOURCE = 391, - SHOW_PROXYCONGESTION = 392, - SHOW_PROXYROUTE = 393, - PARTITION = 394, - ROUTINE = 395, - SHOW_PROXYVIP = 396, - SHOW_PROXYMEMORY = 397, - OBJPOOL = 398, - SHOW_SQLAUDIT = 399, - SHOW_WARNLOG = 400, - SHOW_PROXYSTAT = 401, - REFRESH = 402, - SHOW_PROXYTRACE = 403, - SHOW_PROXYINFO = 404, - BINARY = 405, - UPGRADE = 406, - IDC = 407, - SHOW_TOPOLOGY = 408, - GROUP_NAME = 409, - SHOW_DB_VERSION = 410, - SHOW_DATABASES = 411, - SHOW_TABLES = 412, - SHOW_FULL_TABLES = 413, - SELECT_DATABASE = 414, - SHOW_CREATE_TABLE = 415, - SELECT_PROXY_VERSION = 416, - SHOW_COLUMNS = 417, - SHOW_INDEX = 418, - ALTER_PROXYCONFIG = 419, - ALTER_PROXYRESOURCE = 420, - PING_PROXY = 421, - KILL_PROXYSESSION = 422, - KILL_GLOBALSESSION = 423, - KILL = 424, - QUERY = 425 + STICKY_SESSION = 370, + PARALL = 371, + SHARD_KEY = 372, + INT_NUM = 373, + SHOW_PROXYNET = 374, + THREAD = 375, + CONNECTION = 376, + LIMIT = 377, + OFFSET = 378, + SHOW_PROCESSLIST = 379, + SHOW_PROXYSESSION = 380, + SHOW_GLOBALSESSION = 381, + ATTRIBUTE = 382, + VARIABLES = 383, + ALL = 384, + STAT = 385, + SHOW_PROXYCONFIG = 386, + DIFF = 387, + USER = 388, + LIKE = 389, + SHOW_PROXYSM = 390, + SHOW_PROXYCLUSTER = 391, + SHOW_PROXYRESOURCE = 392, + SHOW_PROXYCONGESTION = 393, + SHOW_PROXYROUTE = 394, + PARTITION = 395, + ROUTINE = 396, + SHOW_PROXYVIP = 397, + SHOW_PROXYMEMORY = 398, + OBJPOOL = 399, + SHOW_SQLAUDIT = 400, + SHOW_WARNLOG = 401, + SHOW_PROXYSTAT = 402, + REFRESH = 403, + SHOW_PROXYTRACE = 404, + SHOW_PROXYINFO = 405, + BINARY = 406, + UPGRADE = 407, + IDC = 408, + SHOW_ELASTIC_ID = 409, + SHOW_TOPOLOGY = 410, + GROUP_NAME = 411, + SHOW_DB_VERSION = 412, + SHOW_DATABASES = 413, + SHOW_TABLES = 414, + SHOW_FULL_TABLES = 415, + SELECT_DATABASE = 416, + SHOW_CREATE_TABLE = 417, + SELECT_PROXY_VERSION = 418, + SHOW_COLUMNS = 419, + SHOW_INDEX = 420, + ALTER_PROXYCONFIG = 421, + ALTER_PROXYRESOURCE = 422, + PING_PROXY = 423, + KILL_PROXYSESSION = 424, + KILL_GLOBALSESSION = 425, + KILL = 426, + QUERY = 427, + SHOW_MASTER_STATUS = 428, + SHOW_BINARY_LOGS = 429, + SHOW_BINLOG_EVENTS = 430, + PURGE_BINARY_LOGS = 431, + RESET_MASTER = 432, + SHOW_BINLOG_SERVER_FOR_TENANT = 433 }; #endif diff --git a/src/obproxy/opsql/parser/ob_proxy_parser_gbk_lex.h b/src/obproxy/opsql/parser/ob_proxy_parser_gbk_lex.h index 13dc516c8..2f58de10a 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parser_gbk_lex.h +++ b/src/obproxy/opsql/parser/ob_proxy_parser_gbk_lex.h @@ -244,9 +244,10 @@ void ob_proxy_parser_gbk_yyfree (void * ,yyscan_t yyscanner ); #define prepare 22 #define insert_all_expr 23 #define set_expr 24 -#define show_topology 25 -#define show_tables 26 -#define proxy_icmd_state 27 +#define show_elastic_id 25 +#define show_topology 26 +#define show_tables 27 +#define proxy_icmd_state 28 #endif @@ -364,9 +365,9 @@ extern int ob_proxy_parser_gbk_yylex \ #undef YY_DECL #endif -#line 1191 "ob_proxy_parser_gbk.l" +#line 1213 "ob_proxy_parser_gbk.l" -#line 371 "ob_proxy_parser_gbk_lex.h" +#line 372 "ob_proxy_parser_gbk_lex.h" #undef ob_proxy_parser_gbk_yyIN_HEADER #endif /* ob_proxy_parser_gbk_yyHEADER_H */ diff --git a/src/obproxy/opsql/parser/ob_proxy_parser_gbk_tab.c b/src/obproxy/opsql/parser/ob_proxy_parser_gbk_tab.c index ad65b907b..4dec0fda4 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parser_gbk_tab.c +++ b/src/obproxy/opsql/parser/ob_proxy_parser_gbk_tab.c @@ -112,9 +112,6 @@ static inline void handle_stmt_end(ObProxyParseResult* result) case OBPROXY_T_SELECT_TX_RO: result->stmt_type_ = OBPROXY_T_SELECT; break; - case OBPROXY_T_SET_AC_0: - result->stmt_type_ = OBPROXY_T_OTHERS; - break; case OBPROXY_T_BEGIN: result->stmt_type_ = OBPROXY_T_OTHERS; break; @@ -133,7 +130,7 @@ static inline void handle_stmt_end(ObProxyParseResult* result) } } else { result->stmt_type_ = result->cur_stmt_type_; - } + } if (OBPROXY_T_TEXT_PS_PREPARE == result->text_ps_inner_stmt_type_) { ObProxyBasicStmtType tmp_type = result->cur_stmt_type_; @@ -459,96 +456,104 @@ extern int ob_proxy_parser_gbk_yydebug; UNION = 333, FOR = 334, TX_READ_ONLY = 335, - AUTOCOMMIT_0 = 336, - SELECT_OBPROXY_ROUTE_ADDR = 337, - SET_OBPROXY_ROUTE_ADDR = 338, - NAME_OB_DOT = 339, - NAME_OB = 340, - EXPLAIN = 341, - DESC = 342, - DESCRIBE = 343, - NAME_STR = 344, - USE = 345, - HELP = 346, - SET_NAMES = 347, - SET_CHARSET = 348, - SET_PASSWORD = 349, - SET_DEFAULT = 350, - SET_OB_READ_CONSISTENCY = 351, - SET_TX_READ_ONLY = 352, - GLOBAL = 353, - SESSION = 354, - NUMBER_VAL = 355, - GROUP_ID = 356, - TABLE_ID = 357, - ELASTIC_ID = 358, - TESTLOAD = 359, - ODP_COMMENT = 360, - TNT_ID = 361, - DISASTER_STATUS = 362, - TRACE_ID = 363, - RPC_ID = 364, + SELECT_OBPROXY_ROUTE_ADDR = 336, + SET_OBPROXY_ROUTE_ADDR = 337, + NAME_OB_DOT = 338, + NAME_OB = 339, + EXPLAIN = 340, + DESC = 341, + DESCRIBE = 342, + NAME_STR = 343, + USE = 344, + HELP = 345, + SET_NAMES = 346, + SET_CHARSET = 347, + SET_PASSWORD = 348, + SET_DEFAULT = 349, + SET_OB_READ_CONSISTENCY = 350, + SET_TX_READ_ONLY = 351, + GLOBAL = 352, + SESSION = 353, + NUMBER_VAL = 354, + GROUP_ID = 355, + TABLE_ID = 356, + ELASTIC_ID = 357, + TESTLOAD = 358, + ODP_COMMENT = 359, + TNT_ID = 360, + DISASTER_STATUS = 361, + TRACE_ID = 362, + RPC_ID = 363, + TARGET_DB_SERVER = 364, DBP_COMMENT = 365, ROUTE_TAG = 366, SYS_TAG = 367, TABLE_NAME = 368, SCAN_ALL = 369, - PARALL = 370, - SHARD_KEY = 371, - INT_NUM = 372, - SHOW_PROXYNET = 373, - THREAD = 374, - CONNECTION = 375, - LIMIT = 376, - OFFSET = 377, - SHOW_PROCESSLIST = 378, - SHOW_PROXYSESSION = 379, - SHOW_GLOBALSESSION = 380, - ATTRIBUTE = 381, - VARIABLES = 382, - ALL = 383, - STAT = 384, - SHOW_PROXYCONFIG = 385, - DIFF = 386, - USER = 387, - LIKE = 388, - SHOW_PROXYSM = 389, - SHOW_PROXYCLUSTER = 390, - SHOW_PROXYRESOURCE = 391, - SHOW_PROXYCONGESTION = 392, - SHOW_PROXYROUTE = 393, - PARTITION = 394, - ROUTINE = 395, - SHOW_PROXYVIP = 396, - SHOW_PROXYMEMORY = 397, - OBJPOOL = 398, - SHOW_SQLAUDIT = 399, - SHOW_WARNLOG = 400, - SHOW_PROXYSTAT = 401, - REFRESH = 402, - SHOW_PROXYTRACE = 403, - SHOW_PROXYINFO = 404, - BINARY = 405, - UPGRADE = 406, - IDC = 407, - SHOW_TOPOLOGY = 408, - GROUP_NAME = 409, - SHOW_DB_VERSION = 410, - SHOW_DATABASES = 411, - SHOW_TABLES = 412, - SHOW_FULL_TABLES = 413, - SELECT_DATABASE = 414, - SHOW_CREATE_TABLE = 415, - SELECT_PROXY_VERSION = 416, - SHOW_COLUMNS = 417, - SHOW_INDEX = 418, - ALTER_PROXYCONFIG = 419, - ALTER_PROXYRESOURCE = 420, - PING_PROXY = 421, - KILL_PROXYSESSION = 422, - KILL_GLOBALSESSION = 423, - KILL = 424, - QUERY = 425 + STICKY_SESSION = 370, + PARALL = 371, + SHARD_KEY = 372, + INT_NUM = 373, + SHOW_PROXYNET = 374, + THREAD = 375, + CONNECTION = 376, + LIMIT = 377, + OFFSET = 378, + SHOW_PROCESSLIST = 379, + SHOW_PROXYSESSION = 380, + SHOW_GLOBALSESSION = 381, + ATTRIBUTE = 382, + VARIABLES = 383, + ALL = 384, + STAT = 385, + SHOW_PROXYCONFIG = 386, + DIFF = 387, + USER = 388, + LIKE = 389, + SHOW_PROXYSM = 390, + SHOW_PROXYCLUSTER = 391, + SHOW_PROXYRESOURCE = 392, + SHOW_PROXYCONGESTION = 393, + SHOW_PROXYROUTE = 394, + PARTITION = 395, + ROUTINE = 396, + SHOW_PROXYVIP = 397, + SHOW_PROXYMEMORY = 398, + OBJPOOL = 399, + SHOW_SQLAUDIT = 400, + SHOW_WARNLOG = 401, + SHOW_PROXYSTAT = 402, + REFRESH = 403, + SHOW_PROXYTRACE = 404, + SHOW_PROXYINFO = 405, + BINARY = 406, + UPGRADE = 407, + IDC = 408, + SHOW_ELASTIC_ID = 409, + SHOW_TOPOLOGY = 410, + GROUP_NAME = 411, + SHOW_DB_VERSION = 412, + SHOW_DATABASES = 413, + SHOW_TABLES = 414, + SHOW_FULL_TABLES = 415, + SELECT_DATABASE = 416, + SHOW_CREATE_TABLE = 417, + SELECT_PROXY_VERSION = 418, + SHOW_COLUMNS = 419, + SHOW_INDEX = 420, + ALTER_PROXYCONFIG = 421, + ALTER_PROXYRESOURCE = 422, + PING_PROXY = 423, + KILL_PROXYSESSION = 424, + KILL_GLOBALSESSION = 425, + KILL = 426, + QUERY = 427, + SHOW_MASTER_STATUS = 428, + SHOW_BINARY_LOGS = 429, + SHOW_BINLOG_EVENTS = 430, + PURGE_BINARY_LOGS = 431, + RESET_MASTER = 432, + SHOW_BINLOG_SERVER_FOR_TENANT = 433 }; #endif @@ -811,22 +816,22 @@ union yyalloc #endif /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 322 +#define YYFINAL 314 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 1614 +#define YYLAST 1384 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 182 +#define YYNTOKENS 190 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 137 +#define YYNNTS 138 /* YYNRULES -- Number of rules. */ -#define YYNRULES 442 +#define YYNRULES 435 /* YYNRULES -- Number of states. */ -#define YYNSTATES 713 +#define YYNSTATES 715 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 425 +#define YYMAXUTOK 433 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -837,16 +842,16 @@ static const yytype_uint8 yytranslate[] = 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 180, 2, 2, 2, 2, - 175, 176, 181, 2, 173, 2, 177, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 171, - 2, 174, 2, 2, 172, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 188, 2, 2, 2, 2, + 183, 184, 189, 2, 181, 2, 185, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 179, + 2, 182, 2, 2, 180, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 178, 2, 179, 2, 2, 2, 2, + 2, 2, 2, 186, 2, 187, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -876,7 +881,8 @@ static const yytype_uint8 yytranslate[] = 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 170 + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178 }; #if YYDEBUG @@ -887,234 +893,231 @@ static const yytype_uint16 yyprhs[] = 0, 0, 3, 5, 7, 9, 12, 15, 18, 22, 24, 27, 31, 33, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, - 68, 70, 72, 74, 76, 78, 80, 82, 84, 88, - 91, 94, 97, 100, 103, 106, 108, 110, 113, 115, - 117, 119, 121, 122, 124, 126, 129, 131, 133, 135, - 137, 139, 141, 143, 145, 148, 153, 156, 158, 160, - 164, 167, 171, 174, 177, 181, 185, 187, 189, 191, - 193, 195, 197, 199, 201, 203, 206, 208, 210, 212, - 213, 216, 217, 219, 222, 228, 232, 234, 238, 241, - 245, 247, 249, 251, 253, 255, 257, 259, 261, 263, - 265, 267, 269, 271, 273, 276, 279, 283, 289, 293, - 299, 300, 303, 304, 307, 311, 315, 321, 323, 325, - 329, 335, 343, 345, 349, 351, 353, 355, 357, 359, - 361, 367, 369, 373, 379, 380, 382, 386, 388, 390, - 392, 395, 399, 401, 403, 406, 408, 411, 415, 419, - 421, 423, 425, 426, 430, 432, 436, 440, 446, 449, - 452, 457, 460, 463, 467, 469, 474, 481, 486, 492, - 499, 504, 508, 510, 512, 514, 516, 519, 523, 529, - 536, 543, 550, 557, 564, 572, 579, 586, 593, 600, - 609, 618, 619, 622, 625, 628, 630, 634, 636, 641, - 646, 650, 657, 662, 667, 674, 678, 680, 684, 685, - 689, 693, 697, 701, 705, 709, 713, 717, 721, 725, - 731, 735, 736, 738, 739, 741, 743, 745, 747, 750, - 752, 755, 757, 760, 763, 767, 768, 770, 773, 775, - 778, 780, 783, 786, 787, 790, 795, 797, 802, 808, - 810, 815, 820, 826, 827, 829, 831, 833, 834, 836, - 840, 844, 847, 849, 851, 853, 855, 857, 859, 861, - 863, 865, 867, 869, 871, 873, 875, 877, 879, 881, - 883, 885, 887, 889, 891, 893, 894, 897, 902, 907, - 908, 911, 912, 915, 918, 920, 922, 926, 929, 933, - 938, 940, 943, 944, 947, 951, 954, 957, 960, 961, - 964, 968, 971, 975, 978, 982, 986, 991, 993, 996, - 999, 1003, 1006, 1009, 1010, 1012, 1014, 1017, 1020, 1024, - 1027, 1029, 1032, 1034, 1037, 1040, 1043, 1046, 1047, 1049, - 1053, 1059, 1062, 1066, 1069, 1070, 1072, 1075, 1078, 1081, - 1084, 1089, 1095, 1101, 1105, 1107, 1110, 1114, 1118, 1121, - 1124, 1128, 1132, 1133, 1136, 1138, 1142, 1146, 1150, 1151, - 1153, 1155, 1159, 1162, 1166, 1169, 1172, 1174, 1175, 1178, - 1183, 1186, 1188, 1192, 1195, 1200, 1204, 1210, 1212, 1214, - 1216, 1218, 1220, 1222, 1224, 1226, 1228, 1230, 1232, 1234, - 1236, 1238, 1240, 1242, 1244, 1246, 1248, 1250, 1252, 1254, - 1256, 1258, 1260, 1262, 1264, 1266, 1268, 1270, 1272, 1274, - 1276, 1278, 1280, 1282, 1284, 1286, 1288, 1290, 1292, 1294, - 1296, 1298, 1300 + 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, + 90, 93, 96, 99, 102, 105, 108, 110, 112, 115, + 117, 119, 121, 123, 124, 126, 128, 131, 133, 135, + 137, 139, 141, 143, 145, 147, 150, 155, 158, 160, + 162, 166, 169, 173, 176, 179, 183, 187, 189, 191, + 193, 195, 197, 199, 201, 203, 205, 208, 210, 212, + 214, 215, 218, 219, 221, 224, 230, 234, 236, 240, + 242, 244, 246, 248, 250, 252, 254, 256, 258, 260, + 262, 264, 266, 268, 271, 274, 278, 284, 288, 294, + 295, 298, 299, 302, 306, 310, 316, 318, 320, 324, + 330, 338, 340, 344, 346, 350, 352, 354, 356, 358, + 360, 362, 368, 370, 374, 380, 381, 383, 387, 389, + 391, 393, 396, 400, 402, 404, 407, 409, 412, 416, + 420, 422, 424, 426, 427, 431, 433, 437, 441, 447, + 450, 453, 458, 461, 464, 468, 470, 475, 482, 487, + 493, 500, 505, 509, 511, 513, 515, 517, 520, 524, + 530, 537, 544, 551, 558, 565, 573, 580, 587, 594, + 601, 610, 619, 626, 627, 630, 633, 636, 638, 642, + 644, 649, 654, 658, 665, 669, 674, 679, 686, 690, + 692, 696, 697, 701, 705, 709, 713, 717, 721, 725, + 729, 733, 737, 741, 747, 751, 752, 754, 755, 757, + 759, 761, 763, 766, 768, 771, 773, 776, 779, 783, + 784, 786, 789, 791, 794, 796, 799, 802, 803, 806, + 811, 813, 818, 824, 826, 831, 836, 842, 843, 845, + 847, 849, 850, 852, 856, 860, 863, 865, 867, 869, + 871, 873, 875, 877, 879, 881, 883, 885, 887, 889, + 891, 893, 895, 897, 899, 901, 903, 905, 907, 909, + 911, 913, 915, 917, 919, 921, 922, 925, 930, 935, + 936, 939, 940, 943, 946, 948, 950, 954, 957, 961, + 966, 968, 971, 972, 975, 979, 982, 985, 988, 989, + 992, 996, 999, 1003, 1006, 1010, 1014, 1019, 1021, 1024, + 1027, 1031, 1034, 1037, 1038, 1040, 1042, 1045, 1048, 1052, + 1055, 1057, 1060, 1062, 1065, 1068, 1071, 1074, 1075, 1077, + 1081, 1087, 1090, 1094, 1097, 1098, 1100, 1103, 1106, 1109, + 1112, 1117, 1123, 1129, 1133, 1135, 1138, 1142, 1146, 1149, + 1152, 1156, 1160, 1161, 1164, 1166, 1170, 1174, 1178, 1179, + 1181, 1183, 1187, 1190, 1194, 1197, 1200, 1202, 1203, 1206, + 1211, 1214, 1216, 1220, 1223, 1228, 1232, 1238, 1240, 1242, + 1244, 1246, 1248, 1250, 1252, 1254, 1256, 1258, 1260, 1262, + 1264, 1266, 1268, 1270, 1272, 1274, 1276, 1278, 1280, 1282, + 1284, 1286, 1288, 1290, 1292, 1294 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int16 yyrhs[] = { - 183, 0, -1, 184, -1, 1, -1, 185, -1, 184, - 185, -1, 186, 50, -1, 186, 171, -1, 186, 171, - 50, -1, 171, -1, 171, 50, -1, 56, 186, 171, - -1, 187, -1, 246, 187, -1, 188, -1, 237, -1, - 242, -1, 238, -1, 239, -1, 240, -1, 189, -1, - 307, -1, 272, -1, 208, -1, 273, -1, 311, -1, - 312, -1, 220, -1, 221, -1, 222, -1, 223, -1, - 224, -1, 225, -1, 226, -1, 190, -1, 199, -1, - 241, -1, 313, -1, 260, 204, 203, -1, 201, 188, - -1, 201, 237, -1, 201, 239, -1, 201, 240, -1, - 201, 238, -1, 201, 241, -1, 191, -1, 200, -1, - 14, 192, -1, 15, -1, 16, -1, 17, -1, 18, - -1, -1, 19, -1, 64, -1, 21, 64, -1, 188, - -1, 237, -1, 238, -1, 240, -1, 239, -1, 313, - -1, 226, -1, 241, -1, 172, 85, -1, 194, 173, - 172, 85, -1, 172, 85, -1, 195, -1, 193, -1, - 29, 318, 27, -1, 30, 318, -1, 30, 318, 31, - -1, 197, 196, -1, 198, 194, -1, 15, 29, 318, - -1, 32, 29, 318, -1, 22, -1, 23, -1, 24, - -1, 25, -1, 53, -1, 26, -1, 54, -1, 55, - -1, 202, -1, 202, 85, -1, 86, -1, 87, -1, - 88, -1, -1, 27, 233, -1, -1, 230, -1, 5, - 80, -1, 5, 80, 204, 27, 233, -1, 5, 80, - 230, -1, 161, -1, 161, 71, 318, -1, 12, 81, - -1, 12, 81, 230, -1, 205, -1, 206, -1, 207, - -1, 218, -1, 219, -1, 209, -1, 217, -1, 216, - -1, 159, -1, 156, -1, 214, -1, 215, -1, 210, - -1, 211, -1, 160, 227, -1, 202, 227, -1, 162, - 27, 85, -1, 162, 27, 85, 27, 85, -1, 163, - 27, 85, -1, 163, 27, 85, 27, 85, -1, -1, - 133, 85, -1, -1, 27, 85, -1, 157, 213, 212, - -1, 158, 213, 212, -1, 11, 19, 20, 213, 212, - -1, 155, -1, 153, -1, 153, 27, 85, -1, 153, - 72, 154, 174, 85, -1, 153, 27, 85, 72, 154, - 174, 85, -1, 82, -1, 83, 174, 117, -1, 92, - -1, 93, -1, 94, -1, 95, -1, 96, -1, 97, - -1, 13, 227, 175, 228, 176, -1, 318, -1, 318, - 177, 318, -1, 318, 177, 318, 177, 318, -1, -1, - 229, -1, 228, 173, 229, -1, 85, -1, 117, -1, - 100, -1, 172, 85, -1, 172, 172, 85, -1, 49, - -1, 231, -1, 230, 231, -1, 232, -1, 175, 176, - -1, 175, 188, 176, -1, 175, 230, 176, -1, 315, - -1, 234, -1, 188, -1, -1, 175, 236, 176, -1, - 85, -1, 236, 173, 85, -1, 263, 316, 314, -1, - 263, 316, 314, 235, 234, -1, 265, 233, -1, 261, - 233, -1, 262, 271, 27, 233, -1, 266, 316, -1, - 12, 243, -1, 244, 173, 243, -1, 244, -1, 172, - 85, 174, 245, -1, 172, 172, 98, 85, 174, 245, - -1, 98, 85, 174, 245, -1, 172, 172, 85, 174, - 245, -1, 172, 172, 99, 85, 174, 245, -1, 99, - 85, 174, 245, -1, 85, 174, 245, -1, 85, -1, - 117, -1, 100, -1, 247, -1, 247, 246, -1, 40, - 248, 41, -1, 40, 105, 256, 255, 41, -1, 40, - 102, 174, 259, 255, 41, -1, 40, 113, 174, 259, - 255, 41, -1, 40, 101, 174, 259, 255, 41, -1, - 40, 103, 174, 259, 255, 41, -1, 40, 104, 174, - 259, 255, 41, -1, 40, 84, 85, 174, 258, 255, - 41, -1, 40, 108, 174, 257, 255, 41, -1, 40, - 109, 174, 257, 255, 41, -1, 40, 106, 174, 259, - 255, 41, -1, 40, 107, 174, 259, 255, 41, -1, - 40, 110, 111, 174, 178, 250, 179, 41, -1, 40, - 110, 112, 174, 178, 252, 179, 41, -1, -1, 248, - 249, -1, 42, 85, -1, 43, 85, -1, 85, -1, - 251, 173, 250, -1, 251, -1, 101, 175, 259, 176, - -1, 113, 175, 259, 176, -1, 114, 175, 176, -1, - 114, 175, 115, 174, 259, 176, -1, 116, 175, 253, - 176, -1, 68, 175, 257, 176, -1, 68, 175, 257, - 180, 257, 176, -1, 254, 173, 253, -1, 254, -1, - 85, 174, 259, -1, -1, 255, 173, 256, -1, 101, - 174, 259, -1, 102, 174, 259, -1, 113, 174, 259, - -1, 103, 174, 259, -1, 104, 174, 259, -1, 108, - 174, 257, -1, 109, 174, 257, -1, 106, 174, 259, - -1, 107, 174, 259, -1, 85, 177, 85, 174, 258, - -1, 85, 174, 258, -1, -1, 259, -1, -1, 259, - -1, 85, -1, 89, -1, 5, -1, 33, 267, -1, - 8, -1, 34, 267, -1, 6, -1, 35, 267, -1, - 7, 264, -1, 36, 267, 264, -1, -1, 128, -1, - 128, 52, -1, 9, -1, 37, 267, -1, 10, -1, - 38, 267, -1, 268, 39, -1, -1, 269, 268, -1, - 44, 175, 117, 176, -1, 117, -1, 45, 175, 270, - 176, -1, 64, 175, 85, 85, 176, -1, 85, -1, - 85, 175, 117, 176, -1, 85, 175, 85, 176, -1, - 85, 175, 85, 85, 176, -1, -1, 46, -1, 47, - -1, 48, -1, -1, 69, -1, 11, 306, 66, -1, - 11, 306, 67, -1, 11, 68, -1, 277, -1, 279, - -1, 280, -1, 283, -1, 281, -1, 285, -1, 286, - -1, 287, -1, 288, -1, 290, -1, 291, -1, 292, - -1, 293, -1, 294, -1, 296, -1, 297, -1, 299, - -1, 300, -1, 301, -1, 302, -1, 303, -1, 304, - -1, 305, -1, -1, 121, 117, -1, 121, 117, 173, - 117, -1, 121, 117, 122, 117, -1, -1, 133, 85, - -1, -1, 133, 85, -1, 118, 278, -1, 119, -1, - 120, -1, 120, 117, 274, -1, 130, 275, -1, 130, - 131, 275, -1, 130, 131, 132, 275, -1, 123, -1, - 125, 282, -1, -1, 126, 85, -1, 126, 133, 85, - -1, 126, 128, -1, 133, 85, -1, 124, 284, -1, - -1, 126, 275, -1, 126, 117, 275, -1, 129, 275, - -1, 129, 117, 275, -1, 127, 275, -1, 127, 117, - 275, -1, 127, 128, 275, -1, 127, 128, 117, 275, - -1, 134, -1, 134, 117, -1, 135, 275, -1, 135, - 152, 275, -1, 136, 275, -1, 137, 289, -1, -1, - 85, -1, 128, -1, 128, 85, -1, 138, 276, -1, - 138, 140, 276, -1, 138, 139, -1, 141, -1, 141, - 85, -1, 142, -1, 142, 143, -1, 144, 274, -1, - 144, 117, -1, 145, 295, -1, -1, 117, -1, 117, - 173, 117, -1, 117, 173, 117, 173, 85, -1, 146, - 275, -1, 146, 147, 275, -1, 148, 298, -1, -1, - 117, -1, 117, 117, -1, 149, 150, -1, 149, 151, - -1, 149, 152, -1, 164, 12, 85, 174, -1, 164, - 12, 85, 174, 85, -1, 164, 12, 85, 174, 117, - -1, 165, 6, 85, -1, 166, -1, 167, 117, -1, - 167, 117, 117, -1, 168, 85, 117, -1, 168, 85, - -1, 169, 117, -1, 169, 120, 117, -1, 169, 170, - 117, -1, -1, 70, 181, -1, 56, -1, 57, 58, - 308, -1, 65, 56, 85, -1, 65, 57, 85, -1, - -1, 309, -1, 310, -1, 309, 173, 310, -1, 59, - 60, -1, 61, 62, 63, -1, 90, 85, -1, 91, - 85, -1, 85, -1, -1, 139, 85, -1, 139, 175, - 85, 176, -1, 316, 314, -1, 318, -1, 318, 177, - 318, -1, 318, 318, -1, 318, 177, 318, 318, -1, - 318, 71, 318, -1, 318, 177, 318, 71, 318, -1, - 57, -1, 65, -1, 56, -1, 58, -1, 62, -1, - 67, -1, 66, -1, 70, -1, 69, -1, 68, -1, - 119, -1, 120, -1, 122, -1, 126, -1, 127, -1, - 129, -1, 131, -1, 132, -1, 143, -1, 147, -1, - 151, -1, 152, -1, 170, -1, 101, -1, 102, -1, - 103, -1, 104, -1, 154, -1, 105, -1, 106, -1, - 107, -1, 108, -1, 109, -1, 110, -1, 111, -1, - 112, -1, 113, -1, 115, -1, 114, -1, 116, -1, - 64, -1, 53, -1, 54, -1, 55, -1, 85, -1, - 317, -1 + 191, 0, -1, 192, -1, 1, -1, 193, -1, 192, + 193, -1, 194, 50, -1, 194, 179, -1, 194, 179, + 50, -1, 179, -1, 179, 50, -1, 56, 194, 179, + -1, 195, -1, 254, 195, -1, 196, -1, 245, -1, + 250, -1, 246, -1, 247, -1, 248, -1, 197, -1, + 316, -1, 280, -1, 215, -1, 281, -1, 320, -1, + 321, -1, 228, -1, 229, -1, 230, -1, 231, -1, + 232, -1, 233, -1, 234, -1, 198, -1, 207, -1, + 249, -1, 282, -1, 322, -1, 268, 212, 211, -1, + 209, 196, -1, 209, 245, -1, 209, 247, -1, 209, + 248, -1, 209, 246, -1, 209, 249, -1, 199, -1, + 208, -1, 14, 200, -1, 15, -1, 16, -1, 17, + -1, 18, -1, -1, 19, -1, 64, -1, 21, 64, + -1, 196, -1, 245, -1, 246, -1, 248, -1, 247, + -1, 322, -1, 234, -1, 249, -1, 180, 84, -1, + 202, 181, 180, 84, -1, 180, 84, -1, 203, -1, + 201, -1, 29, 327, 27, -1, 30, 327, -1, 30, + 327, 31, -1, 205, 204, -1, 206, 202, -1, 15, + 29, 327, -1, 32, 29, 327, -1, 22, -1, 23, + -1, 24, -1, 25, -1, 53, -1, 26, -1, 54, + -1, 55, -1, 210, -1, 210, 84, -1, 85, -1, + 86, -1, 87, -1, -1, 27, 241, -1, -1, 238, + -1, 5, 80, -1, 5, 80, 212, 27, 241, -1, + 5, 80, 238, -1, 163, -1, 163, 71, 327, -1, + 213, -1, 214, -1, 226, -1, 227, -1, 216, -1, + 224, -1, 225, -1, 223, -1, 161, -1, 158, -1, + 221, -1, 222, -1, 217, -1, 218, -1, 162, 235, + -1, 210, 327, -1, 164, 27, 84, -1, 164, 27, + 84, 27, 84, -1, 165, 27, 84, -1, 165, 27, + 84, 27, 84, -1, -1, 134, 84, -1, -1, 27, + 84, -1, 159, 220, 219, -1, 160, 220, 219, -1, + 11, 19, 20, 220, 219, -1, 157, -1, 154, -1, + 154, 27, 84, -1, 154, 72, 156, 182, 84, -1, + 154, 27, 84, 72, 156, 182, 84, -1, 155, -1, + 155, 27, 84, -1, 81, -1, 82, 182, 118, -1, + 91, -1, 92, -1, 93, -1, 94, -1, 95, -1, + 96, -1, 13, 235, 183, 236, 184, -1, 327, -1, + 327, 185, 327, -1, 327, 185, 327, 185, 327, -1, + -1, 237, -1, 236, 181, 237, -1, 84, -1, 118, + -1, 99, -1, 180, 84, -1, 180, 180, 84, -1, + 49, -1, 239, -1, 238, 239, -1, 240, -1, 183, + 184, -1, 183, 196, 184, -1, 183, 238, 184, -1, + 324, -1, 242, -1, 196, -1, -1, 183, 244, 184, + -1, 84, -1, 244, 181, 84, -1, 271, 325, 323, + -1, 271, 325, 323, 243, 242, -1, 273, 241, -1, + 269, 241, -1, 270, 279, 27, 241, -1, 274, 325, + -1, 12, 251, -1, 252, 181, 251, -1, 252, -1, + 180, 84, 182, 253, -1, 180, 180, 97, 84, 182, + 253, -1, 97, 84, 182, 253, -1, 180, 180, 84, + 182, 253, -1, 180, 180, 98, 84, 182, 253, -1, + 98, 84, 182, 253, -1, 84, 182, 253, -1, 84, + -1, 118, -1, 99, -1, 255, -1, 255, 254, -1, + 40, 256, 41, -1, 40, 104, 264, 263, 41, -1, + 40, 101, 182, 267, 263, 41, -1, 40, 113, 182, + 267, 263, 41, -1, 40, 100, 182, 267, 263, 41, + -1, 40, 102, 182, 267, 263, 41, -1, 40, 103, + 182, 267, 263, 41, -1, 40, 83, 84, 182, 266, + 263, 41, -1, 40, 107, 182, 265, 263, 41, -1, + 40, 108, 182, 265, 263, 41, -1, 40, 105, 182, + 267, 263, 41, -1, 40, 106, 182, 267, 263, 41, + -1, 40, 110, 111, 182, 186, 258, 187, 41, -1, + 40, 110, 112, 182, 186, 260, 187, 41, -1, 40, + 109, 182, 267, 263, 41, -1, -1, 256, 257, -1, + 42, 84, -1, 43, 84, -1, 84, -1, 259, 181, + 258, -1, 259, -1, 100, 183, 267, 184, -1, 113, + 183, 267, 184, -1, 114, 183, 184, -1, 114, 183, + 116, 182, 267, 184, -1, 115, 183, 184, -1, 117, + 183, 261, 184, -1, 68, 183, 265, 184, -1, 68, + 183, 265, 188, 265, 184, -1, 262, 181, 261, -1, + 262, -1, 84, 182, 267, -1, -1, 263, 181, 264, + -1, 100, 182, 267, -1, 101, 182, 267, -1, 113, + 182, 267, -1, 102, 182, 267, -1, 103, 182, 267, + -1, 107, 182, 265, -1, 108, 182, 265, -1, 105, + 182, 267, -1, 106, 182, 267, -1, 109, 182, 267, + -1, 84, 185, 84, 182, 266, -1, 84, 182, 266, + -1, -1, 267, -1, -1, 267, -1, 84, -1, 88, + -1, 5, -1, 33, 275, -1, 8, -1, 34, 275, + -1, 6, -1, 35, 275, -1, 7, 272, -1, 36, + 275, 272, -1, -1, 129, -1, 129, 52, -1, 9, + -1, 37, 275, -1, 10, -1, 38, 275, -1, 276, + 39, -1, -1, 277, 276, -1, 44, 183, 118, 184, + -1, 118, -1, 45, 183, 278, 184, -1, 64, 183, + 84, 84, 184, -1, 84, -1, 84, 183, 118, 184, + -1, 84, 183, 84, 184, -1, 84, 183, 84, 84, + 184, -1, -1, 46, -1, 47, -1, 48, -1, -1, + 69, -1, 11, 315, 66, -1, 11, 315, 67, -1, + 11, 68, -1, 286, -1, 288, -1, 289, -1, 292, + -1, 290, -1, 294, -1, 295, -1, 296, -1, 297, + -1, 299, -1, 300, -1, 301, -1, 302, -1, 303, + -1, 305, -1, 306, -1, 308, -1, 309, -1, 310, + -1, 311, -1, 312, -1, 313, -1, 314, -1, 173, + -1, 174, -1, 175, -1, 176, -1, 177, -1, 178, + -1, -1, 122, 118, -1, 122, 118, 181, 118, -1, + 122, 118, 123, 118, -1, -1, 134, 84, -1, -1, + 134, 84, -1, 119, 287, -1, 120, -1, 121, -1, + 121, 118, 283, -1, 131, 284, -1, 131, 132, 284, + -1, 131, 132, 133, 284, -1, 124, -1, 126, 291, + -1, -1, 127, 84, -1, 127, 134, 84, -1, 127, + 129, -1, 134, 84, -1, 125, 293, -1, -1, 127, + 284, -1, 127, 118, 284, -1, 130, 284, -1, 130, + 118, 284, -1, 128, 284, -1, 128, 118, 284, -1, + 128, 129, 284, -1, 128, 129, 118, 284, -1, 135, + -1, 135, 118, -1, 136, 284, -1, 136, 153, 284, + -1, 137, 284, -1, 138, 298, -1, -1, 84, -1, + 129, -1, 129, 84, -1, 139, 285, -1, 139, 141, + 285, -1, 139, 140, -1, 142, -1, 142, 84, -1, + 143, -1, 143, 144, -1, 145, 283, -1, 145, 118, + -1, 146, 304, -1, -1, 118, -1, 118, 181, 118, + -1, 118, 181, 118, 181, 84, -1, 147, 284, -1, + 147, 148, 284, -1, 149, 307, -1, -1, 118, -1, + 118, 118, -1, 150, 151, -1, 150, 152, -1, 150, + 153, -1, 166, 12, 84, 182, -1, 166, 12, 84, + 182, 84, -1, 166, 12, 84, 182, 118, -1, 167, + 6, 84, -1, 168, -1, 169, 118, -1, 169, 118, + 118, -1, 170, 84, 118, -1, 170, 84, -1, 171, + 118, -1, 171, 121, 118, -1, 171, 172, 118, -1, + -1, 70, 189, -1, 56, -1, 57, 58, 317, -1, + 65, 56, 84, -1, 65, 57, 84, -1, -1, 318, + -1, 319, -1, 318, 181, 319, -1, 59, 60, -1, + 61, 62, 63, -1, 89, 84, -1, 90, 84, -1, + 84, -1, -1, 140, 84, -1, 140, 183, 84, 184, + -1, 325, 323, -1, 327, -1, 327, 185, 327, -1, + 327, 327, -1, 327, 185, 327, 327, -1, 327, 71, + 327, -1, 327, 185, 327, 71, 327, -1, 57, -1, + 65, -1, 56, -1, 58, -1, 62, -1, 67, -1, + 66, -1, 70, -1, 69, -1, 68, -1, 120, -1, + 121, -1, 123, -1, 127, -1, 128, -1, 130, -1, + 132, -1, 133, -1, 144, -1, 148, -1, 152, -1, + 153, -1, 172, -1, 156, -1, 53, -1, 54, -1, + 55, -1, 84, -1, 326, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 336, 336, 337, 339, 340, 342, 343, 344, 345, - 346, 347, 349, 350, 352, 353, 354, 355, 356, 357, - 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, - 368, 369, 370, 371, 372, 373, 374, 375, 377, 379, - 380, 381, 382, 383, 384, 386, 387, 389, 390, 391, - 392, 393, 395, 396, 397, 398, 400, 401, 402, 403, - 404, 405, 406, 407, 409, 416, 424, 432, 433, 436, - 442, 447, 453, 456, 459, 464, 470, 471, 472, 473, - 474, 475, 476, 477, 479, 480, 482, 483, 484, 486, - 487, 489, 490, 492, 493, 494, 496, 497, 499, 500, - 502, 503, 504, 505, 506, 507, 509, 510, 511, 512, - 513, 514, 515, 516, 517, 518, 524, 529, 536, 541, - 548, 549, 551, 552, 554, 558, 563, 568, 570, 571, - 576, 581, 588, 591, 597, 598, 599, 600, 601, 602, - 605, 607, 611, 616, 624, 627, 632, 637, 642, 647, - 652, 657, 662, 670, 671, 673, 675, 676, 677, 679, - 680, 682, 684, 685, 687, 688, 690, 694, 695, 696, - 697, 698, 703, 705, 706, 708, 712, 716, 720, 724, - 728, 732, 736, 741, 746, 752, 753, 755, 756, 757, - 758, 759, 760, 761, 762, 768, 769, 770, 771, 772, - 773, 775, 776, 778, 779, 780, 782, 783, 785, 790, - 795, 796, 797, 799, 800, 802, 803, 805, 813, 814, - 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, - 831, 833, 834, 836, 837, 839, 840, 842, 843, 844, - 845, 846, 847, 848, 849, 851, 852, 853, 855, 856, - 857, 858, 859, 860, 861, 863, 864, 865, 866, 871, - 872, 873, 874, 876, 877, 878, 879, 881, 882, 885, - 886, 887, 890, 891, 892, 893, 894, 895, 896, 897, - 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, - 908, 909, 910, 911, 912, 917, 919, 923, 928, 936, - 937, 941, 942, 945, 947, 948, 949, 953, 954, 955, - 959, 961, 963, 964, 965, 966, 967, 970, 972, 973, - 974, 975, 976, 977, 978, 979, 980, 984, 985, 989, - 990, 995, 998, 1000, 1001, 1002, 1003, 1007, 1008, 1009, - 1013, 1014, 1018, 1019, 1023, 1024, 1027, 1029, 1030, 1031, - 1032, 1036, 1037, 1040, 1042, 1043, 1044, 1048, 1049, 1050, - 1054, 1055, 1056, 1060, 1064, 1068, 1069, 1073, 1074, 1078, - 1079, 1080, 1083, 1084, 1087, 1091, 1092, 1093, 1095, 1096, - 1098, 1099, 1102, 1103, 1106, 1112, 1115, 1117, 1118, 1119, - 1121, 1126, 1129, 1133, 1137, 1142, 1146, 1152, 1153, 1154, - 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, - 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, - 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, - 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, - 1195, 1197, 1198 + 0, 334, 334, 335, 337, 338, 340, 341, 342, 343, + 344, 345, 347, 348, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, + 366, 367, 368, 369, 370, 371, 372, 373, 374, 376, + 378, 379, 380, 381, 382, 383, 385, 386, 388, 389, + 390, 391, 392, 394, 395, 396, 397, 399, 400, 401, + 402, 403, 404, 405, 406, 408, 415, 423, 431, 432, + 435, 441, 446, 452, 455, 458, 463, 469, 470, 471, + 472, 473, 474, 475, 476, 478, 479, 481, 482, 483, + 485, 486, 488, 489, 491, 492, 493, 495, 496, 498, + 499, 500, 501, 502, 504, 505, 506, 507, 508, 509, + 510, 511, 512, 513, 514, 521, 526, 533, 538, 545, + 546, 548, 549, 551, 555, 560, 565, 567, 568, 573, + 578, 585, 586, 592, 595, 601, 602, 603, 604, 605, + 606, 609, 611, 615, 620, 628, 631, 636, 641, 646, + 651, 656, 661, 666, 674, 675, 677, 679, 680, 681, + 683, 684, 686, 688, 689, 691, 692, 694, 698, 699, + 700, 701, 702, 707, 709, 710, 712, 716, 720, 724, + 728, 732, 736, 740, 745, 750, 756, 757, 759, 760, + 761, 762, 763, 764, 765, 766, 772, 773, 774, 775, + 776, 777, 778, 779, 780, 782, 783, 784, 786, 787, + 789, 794, 799, 800, 801, 802, 804, 805, 807, 808, + 810, 818, 819, 821, 822, 823, 824, 825, 826, 827, + 828, 829, 830, 831, 837, 839, 840, 842, 843, 845, + 846, 848, 849, 850, 851, 852, 853, 854, 855, 857, + 858, 859, 861, 862, 863, 864, 865, 866, 867, 869, + 870, 871, 872, 877, 878, 879, 880, 882, 883, 884, + 885, 887, 888, 891, 892, 893, 896, 897, 898, 899, + 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, + 910, 911, 912, 913, 914, 915, 916, 917, 918, 920, + 921, 922, 923, 924, 925, 930, 932, 936, 941, 949, + 950, 954, 955, 958, 960, 961, 962, 966, 967, 968, + 972, 974, 976, 977, 978, 979, 980, 983, 985, 986, + 987, 988, 989, 990, 991, 992, 993, 997, 998, 1002, + 1003, 1008, 1011, 1013, 1014, 1015, 1016, 1020, 1021, 1022, + 1026, 1027, 1031, 1032, 1036, 1037, 1040, 1042, 1043, 1044, + 1045, 1049, 1050, 1053, 1055, 1056, 1057, 1061, 1062, 1063, + 1067, 1068, 1069, 1073, 1077, 1081, 1082, 1086, 1087, 1091, + 1092, 1093, 1096, 1097, 1100, 1104, 1105, 1106, 1108, 1109, + 1111, 1112, 1115, 1116, 1119, 1125, 1128, 1130, 1131, 1132, + 1134, 1139, 1142, 1146, 1150, 1155, 1159, 1165, 1166, 1167, + 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, + 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, + 1188, 1189, 1190, 1191, 1193, 1194 }; #endif @@ -1137,26 +1140,29 @@ static const char *const yytname[] = "ONLY", "WITH", "CONSISTENT", "SNAPSHOT", "INDEX", "XA", "WARNINGS", "ERRORS", "TRACE", "QUICK", "COUNT", "AS", "WHERE", "VALUES", "ORDER", "GROUP", "HAVING", "INTO", "UNION", "FOR", "TX_READ_ONLY", - "AUTOCOMMIT_0", "SELECT_OBPROXY_ROUTE_ADDR", "SET_OBPROXY_ROUTE_ADDR", - "NAME_OB_DOT", "NAME_OB", "EXPLAIN", "DESC", "DESCRIBE", "NAME_STR", - "USE", "HELP", "SET_NAMES", "SET_CHARSET", "SET_PASSWORD", "SET_DEFAULT", + "SELECT_OBPROXY_ROUTE_ADDR", "SET_OBPROXY_ROUTE_ADDR", "NAME_OB_DOT", + "NAME_OB", "EXPLAIN", "DESC", "DESCRIBE", "NAME_STR", "USE", "HELP", + "SET_NAMES", "SET_CHARSET", "SET_PASSWORD", "SET_DEFAULT", "SET_OB_READ_CONSISTENCY", "SET_TX_READ_ONLY", "GLOBAL", "SESSION", "NUMBER_VAL", "GROUP_ID", "TABLE_ID", "ELASTIC_ID", "TESTLOAD", "ODP_COMMENT", "TNT_ID", "DISASTER_STATUS", "TRACE_ID", "RPC_ID", - "DBP_COMMENT", "ROUTE_TAG", "SYS_TAG", "TABLE_NAME", "SCAN_ALL", - "PARALL", "SHARD_KEY", "INT_NUM", "SHOW_PROXYNET", "THREAD", - "CONNECTION", "LIMIT", "OFFSET", "SHOW_PROCESSLIST", "SHOW_PROXYSESSION", - "SHOW_GLOBALSESSION", "ATTRIBUTE", "VARIABLES", "ALL", "STAT", - "SHOW_PROXYCONFIG", "DIFF", "USER", "LIKE", "SHOW_PROXYSM", - "SHOW_PROXYCLUSTER", "SHOW_PROXYRESOURCE", "SHOW_PROXYCONGESTION", - "SHOW_PROXYROUTE", "PARTITION", "ROUTINE", "SHOW_PROXYVIP", - "SHOW_PROXYMEMORY", "OBJPOOL", "SHOW_SQLAUDIT", "SHOW_WARNLOG", - "SHOW_PROXYSTAT", "REFRESH", "SHOW_PROXYTRACE", "SHOW_PROXYINFO", - "BINARY", "UPGRADE", "IDC", "SHOW_TOPOLOGY", "GROUP_NAME", - "SHOW_DB_VERSION", "SHOW_DATABASES", "SHOW_TABLES", "SHOW_FULL_TABLES", - "SELECT_DATABASE", "SHOW_CREATE_TABLE", "SELECT_PROXY_VERSION", - "SHOW_COLUMNS", "SHOW_INDEX", "ALTER_PROXYCONFIG", "ALTER_PROXYRESOURCE", - "PING_PROXY", "KILL_PROXYSESSION", "KILL_GLOBALSESSION", "KILL", "QUERY", + "TARGET_DB_SERVER", "DBP_COMMENT", "ROUTE_TAG", "SYS_TAG", "TABLE_NAME", + "SCAN_ALL", "STICKY_SESSION", "PARALL", "SHARD_KEY", "INT_NUM", + "SHOW_PROXYNET", "THREAD", "CONNECTION", "LIMIT", "OFFSET", + "SHOW_PROCESSLIST", "SHOW_PROXYSESSION", "SHOW_GLOBALSESSION", + "ATTRIBUTE", "VARIABLES", "ALL", "STAT", "SHOW_PROXYCONFIG", "DIFF", + "USER", "LIKE", "SHOW_PROXYSM", "SHOW_PROXYCLUSTER", + "SHOW_PROXYRESOURCE", "SHOW_PROXYCONGESTION", "SHOW_PROXYROUTE", + "PARTITION", "ROUTINE", "SHOW_PROXYVIP", "SHOW_PROXYMEMORY", "OBJPOOL", + "SHOW_SQLAUDIT", "SHOW_WARNLOG", "SHOW_PROXYSTAT", "REFRESH", + "SHOW_PROXYTRACE", "SHOW_PROXYINFO", "BINARY", "UPGRADE", "IDC", + "SHOW_ELASTIC_ID", "SHOW_TOPOLOGY", "GROUP_NAME", "SHOW_DB_VERSION", + "SHOW_DATABASES", "SHOW_TABLES", "SHOW_FULL_TABLES", "SELECT_DATABASE", + "SHOW_CREATE_TABLE", "SELECT_PROXY_VERSION", "SHOW_COLUMNS", + "SHOW_INDEX", "ALTER_PROXYCONFIG", "ALTER_PROXYRESOURCE", "PING_PROXY", + "KILL_PROXYSESSION", "KILL_GLOBALSESSION", "KILL", "QUERY", + "SHOW_MASTER_STATUS", "SHOW_BINARY_LOGS", "SHOW_BINLOG_EVENTS", + "PURGE_BINARY_LOGS", "RESET_MASTER", "SHOW_BINLOG_SERVER_FOR_TENANT", "';'", "'@'", "','", "'='", "'('", "')'", "'.'", "'{'", "'}'", "'#'", "'*'", "$accept", "root", "sql_stmts", "sql_stmt", "comment_stmt", "stmt", "select_stmt", "explain_stmt", "ddl_stmt", "mysql_ddl_stmt", @@ -1165,10 +1171,10 @@ static const char *const yytname[] = "text_ps_prepare_stmt", "text_ps_execute_stmt", "text_ps_stmt", "oracle_ddl_stmt", "explain_or_desc_stmt", "explain_or_desc", "opt_from", "select_expr_list", "select_tx_read_only_stmt", - "select_proxy_version_stmt", "set_autocommit_0_stmt", "hooked_stmt", - "shard_special_stmt", "show_columns_stmt", "show_index_stmt", - "opt_show_like", "opt_show_from", "show_tables_stmt", - "show_table_status_stmt", "show_db_version_stmt", "show_es_id_stmt", + "select_proxy_version_stmt", "hooked_stmt", "shard_special_stmt", + "show_columns_stmt", "show_index_stmt", "opt_show_like", "opt_show_from", + "show_tables_stmt", "show_table_status_stmt", "show_db_version_stmt", + "show_es_id_stmt", "show_topology_stmt", "select_obproxy_route_addr_stmt", "set_obproxy_route_addr_stmt", "set_names_stmt", "set_charset_stmt", "set_password_stmt", "set_default_stmt", "set_ob_read_consistency_stmt", @@ -1185,8 +1191,8 @@ static const char *const yytname[] = "insert_with_opt_hint", "insert_all_when", "replace_with_opt_hint", "merge_with_opt_hint", "hint_list_with_end", "hint_list", "hint", "opt_read_consistency", "opt_quick", "show_stmt", "icmd_stmt", - "opt_limit", "opt_like", "opt_large_like", "show_proxynet", - "opt_show_net", "show_proxyconfig", "show_processlist", + "binlog_stmt", "opt_limit", "opt_like", "opt_large_like", + "show_proxynet", "opt_show_net", "show_proxyconfig", "show_processlist", "show_globalsession", "opt_show_global_session", "show_proxysession", "opt_show_session", "show_proxysm", "show_proxycluster", "show_proxyresource", "show_proxycongestion", "opt_show_congestion", @@ -1224,59 +1230,58 @@ static const yytype_uint16 yytoknum[] = 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, - 425, 59, 64, 44, 61, 40, 41, 46, 123, 125, - 35, 42 + 425, 426, 427, 428, 429, 430, 431, 432, 433, 59, + 64, 44, 61, 40, 41, 46, 123, 125, 35, 42 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint16 yyr1[] = { - 0, 182, 183, 183, 184, 184, 185, 185, 185, 185, - 185, 185, 186, 186, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 188, 189, - 189, 189, 189, 189, 189, 190, 190, 191, 191, 191, - 191, 191, 192, 192, 192, 192, 193, 193, 193, 193, - 193, 193, 193, 193, 194, 194, 195, 196, 196, 197, - 198, 198, 199, 199, 199, 199, 200, 200, 200, 200, - 200, 200, 200, 200, 201, 201, 202, 202, 202, 203, - 203, 204, 204, 205, 205, 205, 206, 206, 207, 207, - 208, 208, 208, 208, 208, 208, 209, 209, 209, 209, - 209, 209, 209, 209, 209, 209, 210, 210, 211, 211, - 212, 212, 213, 213, 214, 214, 215, 216, 217, 217, - 217, 217, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 227, 227, 228, 228, 228, 229, 229, 229, - 229, 229, 229, 230, 230, 231, 232, 232, 232, 233, - 233, 234, 235, 235, 236, 236, 237, 237, 238, 239, - 240, 241, 242, 243, 243, 244, 244, 244, 244, 244, - 244, 244, 245, 245, 245, 246, 246, 247, 247, 247, - 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, - 247, 248, 248, 249, 249, 249, 250, 250, 251, 251, - 251, 251, 251, 252, 252, 253, 253, 254, 255, 255, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 257, 257, 258, 258, 259, 259, 260, 260, 261, - 261, 262, 262, 263, 263, 264, 264, 264, 265, 265, - 266, 266, 267, 268, 268, 269, 269, 269, 269, 269, - 269, 269, 269, 270, 270, 270, 270, 271, 271, 272, - 272, 272, 273, 273, 273, 273, 273, 273, 273, 273, - 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, - 273, 273, 273, 273, 273, 274, 274, 274, 274, 275, - 275, 276, 276, 277, 278, 278, 278, 279, 279, 279, - 280, 281, 282, 282, 282, 282, 282, 283, 284, 284, - 284, 284, 284, 284, 284, 284, 284, 285, 285, 286, - 286, 287, 288, 289, 289, 289, 289, 290, 290, 290, - 291, 291, 292, 292, 293, 293, 294, 295, 295, 295, - 295, 296, 296, 297, 298, 298, 298, 299, 299, 299, - 300, 300, 300, 301, 302, 303, 303, 304, 304, 305, - 305, 305, 306, 306, 307, 307, 307, 307, 308, 308, - 309, 309, 310, 310, 311, 312, 313, 314, 314, 314, - 315, 316, 316, 316, 316, 316, 316, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 318, 318 + 0, 190, 191, 191, 192, 192, 193, 193, 193, 193, + 193, 193, 194, 194, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 196, + 197, 197, 197, 197, 197, 197, 198, 198, 199, 199, + 199, 199, 199, 200, 200, 200, 200, 201, 201, 201, + 201, 201, 201, 201, 201, 202, 202, 203, 204, 204, + 205, 206, 206, 207, 207, 207, 207, 208, 208, 208, + 208, 208, 208, 208, 208, 209, 209, 210, 210, 210, + 211, 211, 212, 212, 213, 213, 213, 214, 214, 215, + 215, 215, 215, 215, 216, 216, 216, 216, 216, 216, + 216, 216, 216, 216, 216, 217, 217, 218, 218, 219, + 219, 220, 220, 221, 221, 222, 223, 224, 224, 224, + 224, 225, 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 235, 235, 236, 236, 236, 237, 237, + 237, 237, 237, 237, 238, 238, 239, 240, 240, 240, + 241, 241, 242, 243, 243, 244, 244, 245, 245, 246, + 247, 248, 249, 250, 251, 251, 252, 252, 252, 252, + 252, 252, 252, 253, 253, 253, 254, 254, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 256, 256, 257, 257, 257, 258, 258, + 259, 259, 259, 259, 259, 259, 260, 260, 261, 261, + 262, 263, 263, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 265, 265, 266, 266, 267, + 267, 268, 268, 269, 269, 270, 270, 271, 271, 272, + 272, 272, 273, 273, 274, 274, 275, 276, 276, 277, + 277, 277, 277, 277, 277, 277, 277, 278, 278, 278, + 278, 279, 279, 280, 280, 280, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 282, + 282, 282, 282, 282, 282, 283, 283, 283, 283, 284, + 284, 285, 285, 286, 287, 287, 287, 288, 288, 288, + 289, 290, 291, 291, 291, 291, 291, 292, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 294, 294, 295, + 295, 296, 297, 298, 298, 298, 298, 299, 299, 299, + 300, 300, 301, 301, 302, 302, 303, 304, 304, 304, + 304, 305, 305, 306, 307, 307, 307, 308, 308, 308, + 309, 309, 309, 310, 311, 312, 312, 313, 313, 314, + 314, 314, 315, 315, 316, 316, 316, 316, 317, 317, + 318, 318, 319, 319, 320, 321, 322, 323, 323, 323, + 324, 325, 325, 325, 325, 325, 325, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 327, 327 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -1285,31 +1290,32 @@ static const yytype_uint8 yyr2[] = 0, 2, 1, 1, 1, 2, 2, 2, 3, 1, 2, 3, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, - 2, 2, 2, 2, 2, 1, 1, 2, 1, 1, - 1, 1, 0, 1, 1, 2, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 4, 2, 1, 1, 3, - 2, 3, 2, 2, 3, 3, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 1, 1, 1, 0, - 2, 0, 1, 2, 5, 3, 1, 3, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, + 2, 2, 2, 2, 2, 2, 1, 1, 2, 1, + 1, 1, 1, 0, 1, 1, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 4, 2, 1, 1, + 3, 2, 3, 2, 2, 3, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, + 0, 2, 0, 1, 2, 5, 3, 1, 3, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 2, 3, 5, 3, 5, 0, + 2, 0, 2, 3, 3, 5, 1, 1, 3, 5, + 7, 1, 3, 1, 3, 1, 1, 1, 1, 1, + 1, 5, 1, 3, 5, 0, 1, 3, 1, 1, + 1, 2, 3, 1, 1, 2, 1, 2, 3, 3, + 1, 1, 1, 0, 3, 1, 3, 3, 5, 2, + 2, 4, 2, 2, 3, 1, 4, 6, 4, 5, + 6, 4, 3, 1, 1, 1, 1, 2, 3, 5, + 6, 6, 6, 6, 6, 7, 6, 6, 6, 6, + 8, 8, 6, 0, 2, 2, 2, 1, 3, 1, + 4, 4, 3, 6, 3, 4, 4, 6, 3, 1, + 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 5, 3, 0, 1, 0, 1, 1, + 1, 1, 2, 1, 2, 1, 2, 2, 3, 0, + 1, 2, 1, 2, 1, 2, 2, 0, 2, 4, + 1, 4, 5, 1, 4, 4, 5, 0, 1, 1, + 1, 0, 1, 3, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 2, 3, 5, 3, 5, - 0, 2, 0, 2, 3, 3, 5, 1, 1, 3, - 5, 7, 1, 3, 1, 1, 1, 1, 1, 1, - 5, 1, 3, 5, 0, 1, 3, 1, 1, 1, - 2, 3, 1, 1, 2, 1, 2, 3, 3, 1, - 1, 1, 0, 3, 1, 3, 3, 5, 2, 2, - 4, 2, 2, 3, 1, 4, 6, 4, 5, 6, - 4, 3, 1, 1, 1, 1, 2, 3, 5, 6, - 6, 6, 6, 6, 7, 6, 6, 6, 6, 8, - 8, 0, 2, 2, 2, 1, 3, 1, 4, 4, - 3, 6, 4, 4, 6, 3, 1, 3, 0, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, - 3, 0, 1, 0, 1, 1, 1, 1, 2, 1, - 2, 1, 2, 2, 3, 0, 1, 2, 1, 2, - 1, 2, 2, 0, 2, 4, 1, 4, 5, 1, - 4, 4, 5, 0, 1, 1, 1, 0, 1, 3, - 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 4, 4, 0, 2, 0, 2, 2, 1, 1, 3, 2, 3, 4, @@ -1324,9 +1330,7 @@ static const yytype_uint8 yyr2[] = 2, 1, 3, 2, 4, 3, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1 + 1, 1, 1, 1, 1, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -1334,532 +1338,486 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint16 yydefact[] = { - 0, 3, 237, 241, 245, 239, 248, 250, 372, 0, - 0, 52, 48, 49, 50, 51, 76, 77, 78, 79, - 81, 0, 0, 0, 253, 253, 253, 253, 253, 253, - 201, 80, 82, 83, 374, 0, 0, 132, 0, 386, - 86, 87, 88, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 310, 318, 312, 299, 327, 299, 299, 333, - 301, 340, 342, 295, 347, 299, 354, 0, 128, 127, - 109, 122, 122, 108, 0, 96, 0, 0, 0, 0, - 364, 0, 0, 0, 9, 0, 2, 4, 0, 12, - 14, 20, 34, 45, 0, 0, 35, 46, 0, 84, - 100, 101, 102, 23, 105, 112, 113, 110, 111, 107, - 106, 103, 104, 27, 28, 29, 30, 31, 32, 33, - 15, 17, 18, 19, 36, 16, 0, 185, 91, 0, - 267, 0, 0, 0, 22, 24, 272, 273, 274, 276, - 275, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 21, - 25, 26, 37, 93, 246, 243, 0, 271, 0, 0, - 98, 0, 0, 0, 0, 172, 174, 438, 439, 440, - 399, 397, 400, 401, 437, 398, 403, 402, 406, 405, - 404, 441, 420, 421, 422, 423, 425, 426, 427, 428, - 429, 430, 431, 432, 433, 435, 434, 436, 407, 408, - 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, - 424, 419, 0, 442, 141, 53, 0, 54, 47, 0, - 0, 70, 0, 0, 0, 0, 259, 256, 238, 0, - 253, 240, 242, 245, 249, 251, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 374, - 0, 378, 0, 0, 0, 384, 385, 304, 305, 303, - 299, 299, 299, 317, 0, 0, 311, 299, 0, 307, - 328, 299, 329, 331, 334, 335, 332, 0, 339, 301, - 337, 341, 343, 345, 0, 344, 348, 346, 299, 351, - 355, 353, 357, 358, 359, 0, 0, 0, 120, 120, - 114, 0, 0, 0, 0, 0, 365, 368, 369, 0, - 0, 10, 1, 5, 6, 7, 237, 0, 56, 68, - 67, 72, 62, 57, 58, 60, 59, 63, 61, 0, - 73, 39, 40, 43, 41, 42, 44, 85, 115, 13, - 186, 0, 89, 92, 153, 155, 161, 169, 160, 159, - 387, 391, 268, 0, 387, 168, 171, 0, 95, 247, - 122, 373, 269, 270, 99, 0, 0, 0, 0, 0, - 0, 144, 0, 55, 74, 69, 71, 75, 0, 263, - 0, 0, 252, 254, 244, 0, 0, 0, 0, 0, + 0, 3, 241, 245, 249, 243, 252, 254, 382, 0, + 0, 53, 49, 50, 51, 52, 77, 78, 79, 80, + 82, 0, 0, 0, 257, 257, 257, 257, 257, 257, + 203, 81, 83, 84, 384, 0, 0, 133, 0, 396, + 87, 88, 89, 0, 0, 135, 136, 137, 138, 139, + 140, 0, 320, 328, 322, 309, 337, 309, 309, 343, + 311, 350, 352, 305, 357, 309, 364, 0, 127, 131, + 126, 108, 121, 121, 107, 0, 97, 0, 0, 0, + 0, 374, 0, 0, 0, 299, 300, 301, 302, 303, + 304, 9, 0, 2, 4, 0, 12, 14, 20, 34, + 46, 0, 0, 35, 47, 0, 85, 99, 100, 23, + 103, 111, 112, 109, 110, 106, 104, 105, 101, 102, + 27, 28, 29, 30, 31, 32, 33, 15, 17, 18, + 19, 36, 16, 0, 186, 92, 0, 271, 0, 0, + 0, 22, 24, 37, 276, 277, 278, 280, 279, 281, + 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + 292, 293, 294, 295, 296, 297, 298, 21, 25, 26, + 38, 94, 250, 247, 0, 275, 0, 0, 0, 0, + 0, 0, 173, 175, 431, 432, 433, 409, 407, 410, + 411, 408, 413, 412, 416, 415, 414, 434, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, + 430, 429, 0, 435, 142, 54, 0, 55, 48, 0, + 0, 71, 0, 0, 0, 0, 263, 260, 242, 0, + 257, 244, 246, 249, 253, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 218, 0, 0, 231, 231, 0, 0, 0, 187, 0, - 0, 205, 202, 11, 0, 0, 375, 379, 380, 376, - 377, 133, 295, 299, 319, 299, 299, 323, 299, 321, - 313, 315, 0, 316, 299, 308, 300, 330, 336, 302, - 338, 296, 0, 352, 356, 129, 0, 123, 0, 124, - 125, 97, 116, 118, 0, 363, 366, 367, 370, 371, - 8, 66, 64, 0, 156, 0, 0, 0, 38, 154, - 0, 390, 0, 0, 393, 0, 162, 0, 120, 182, - 184, 183, 181, 0, 0, 0, 0, 0, 0, 173, - 152, 147, 149, 148, 0, 0, 145, 142, 0, 264, - 265, 266, 0, 0, 0, 0, 233, 235, 236, 218, - 218, 218, 218, 233, 0, 0, 0, 0, 0, 0, - 0, 231, 231, 0, 0, 218, 218, 218, 232, 218, - 0, 0, 218, 203, 204, 382, 0, 0, 306, 320, - 324, 299, 325, 322, 314, 309, 0, 0, 349, 0, - 0, 121, 0, 0, 360, 0, 157, 158, 90, 388, - 0, 395, 392, 170, 0, 0, 94, 126, 177, 180, - 175, 0, 0, 0, 150, 0, 0, 140, 0, 255, - 257, 0, 0, 261, 260, 218, 234, 0, 0, 0, - 0, 230, 0, 220, 221, 223, 224, 227, 228, 225, - 226, 222, 188, 0, 0, 0, 0, 0, 0, 0, - 0, 383, 381, 326, 298, 297, 0, 0, 130, 117, - 119, 361, 362, 65, 0, 0, 394, 164, 0, 167, - 178, 0, 0, 151, 146, 143, 258, 262, 0, 191, - 189, 192, 193, 233, 219, 197, 198, 195, 196, 0, - 0, 0, 0, 0, 207, 0, 0, 190, 350, 0, - 389, 396, 0, 163, 176, 179, 194, 229, 0, 0, - 0, 0, 0, 0, 231, 0, 131, 165, 0, 0, - 0, 210, 0, 0, 216, 199, 206, 0, 200, 208, - 209, 0, 0, 212, 0, 213, 231, 0, 217, 215, - 0, 211, 214 + 384, 0, 388, 0, 0, 0, 394, 395, 314, 315, + 313, 309, 309, 309, 327, 0, 0, 321, 309, 0, + 317, 338, 309, 339, 341, 344, 345, 342, 0, 349, + 311, 347, 351, 353, 355, 0, 354, 358, 356, 309, + 361, 365, 363, 367, 368, 369, 0, 0, 0, 0, + 119, 119, 113, 0, 0, 0, 0, 0, 375, 378, + 379, 0, 0, 10, 1, 5, 6, 7, 241, 0, + 57, 69, 68, 73, 63, 58, 59, 61, 60, 64, + 62, 0, 74, 40, 41, 44, 42, 43, 45, 86, + 114, 13, 187, 0, 90, 93, 154, 156, 162, 170, + 161, 160, 397, 401, 272, 0, 397, 169, 172, 0, + 96, 251, 121, 383, 273, 274, 0, 0, 0, 0, + 0, 0, 145, 0, 56, 75, 70, 72, 76, 0, + 267, 0, 0, 256, 258, 248, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 221, 0, 0, 235, 235, 0, 0, 0, + 0, 188, 0, 0, 207, 204, 11, 0, 0, 385, + 389, 390, 386, 387, 134, 305, 309, 329, 309, 309, + 333, 309, 331, 323, 325, 0, 326, 309, 318, 310, + 340, 346, 312, 348, 306, 0, 362, 366, 128, 0, + 132, 122, 0, 123, 124, 98, 115, 117, 0, 373, + 376, 377, 380, 381, 8, 67, 65, 0, 157, 0, + 0, 0, 39, 155, 0, 400, 0, 0, 403, 0, + 163, 0, 119, 183, 185, 184, 182, 0, 0, 0, + 0, 0, 0, 174, 153, 148, 150, 149, 0, 0, + 146, 143, 0, 268, 269, 270, 0, 0, 0, 0, + 237, 239, 240, 221, 221, 221, 221, 237, 0, 0, + 0, 0, 0, 0, 0, 235, 235, 0, 0, 0, + 221, 221, 221, 236, 221, 221, 0, 0, 221, 205, + 206, 392, 0, 0, 316, 330, 334, 309, 335, 332, + 324, 319, 0, 0, 359, 0, 0, 120, 0, 0, + 370, 0, 158, 159, 91, 398, 0, 405, 402, 171, + 0, 0, 95, 125, 178, 181, 176, 0, 0, 0, + 151, 0, 0, 141, 0, 259, 261, 0, 0, 265, + 264, 221, 238, 0, 0, 0, 0, 234, 0, 223, + 224, 226, 227, 230, 231, 228, 229, 232, 225, 189, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 393, + 391, 336, 308, 307, 0, 0, 129, 116, 118, 371, + 372, 66, 0, 0, 404, 165, 0, 168, 179, 0, + 0, 152, 147, 144, 262, 266, 0, 192, 190, 193, + 194, 237, 222, 198, 199, 196, 197, 202, 0, 0, + 0, 0, 0, 0, 209, 0, 0, 191, 360, 0, + 399, 406, 0, 164, 177, 180, 195, 233, 0, 0, + 0, 0, 0, 0, 0, 235, 0, 130, 166, 0, + 0, 0, 212, 214, 0, 0, 219, 200, 208, 0, + 201, 210, 211, 0, 0, 215, 0, 216, 235, 0, + 220, 218, 0, 213, 217 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 85, 86, 87, 88, 89, 356, 91, 92, 93, - 228, 329, 340, 330, 331, 94, 95, 96, 97, 98, - 99, 478, 352, 100, 101, 102, 103, 104, 105, 106, - 459, 308, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 222, 505, 506, 353, 354, - 355, 357, 358, 575, 638, 120, 121, 122, 123, 124, - 125, 175, 176, 492, 126, 127, 258, 422, 663, 664, - 666, 693, 694, 534, 410, 537, 595, 538, 128, 129, - 130, 131, 165, 132, 133, 238, 239, 240, 512, 363, - 134, 135, 295, 279, 290, 136, 269, 137, 138, 139, - 276, 140, 273, 141, 142, 143, 144, 286, 145, 146, - 147, 148, 149, 297, 150, 151, 301, 152, 153, 154, - 155, 156, 157, 158, 169, 159, 426, 427, 428, 160, - 161, 162, 481, 359, 360, 223, 361 + -1, 92, 93, 94, 95, 96, 348, 98, 99, 100, + 218, 321, 332, 322, 323, 101, 102, 103, 104, 105, + 106, 472, 344, 107, 108, 109, 110, 111, 112, 453, + 300, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 212, 499, 500, 345, 346, + 347, 349, 350, 571, 636, 127, 128, 129, 130, 131, + 132, 182, 183, 486, 133, 134, 249, 415, 663, 664, + 666, 695, 696, 529, 402, 532, 591, 533, 135, 136, + 137, 138, 173, 139, 140, 228, 229, 230, 506, 355, + 141, 142, 143, 286, 270, 281, 144, 260, 145, 146, + 147, 267, 148, 264, 149, 150, 151, 152, 277, 153, + 154, 155, 156, 157, 288, 158, 159, 292, 160, 161, + 162, 163, 164, 165, 166, 177, 167, 419, 420, 421, + 168, 169, 170, 475, 351, 352, 213, 353 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -485 +#define YYPACT_NINF -479 static const yytype_int16 yypact[] = { - 392, -485, 32, -485, 42, -485, -485, -485, 49, -12, - 1337, 63, 91, -485, -485, -485, -485, -485, -485, -485, - -485, 1337, 1337, 172, 31, 31, 31, 31, 31, 31, - 145, -485, -485, -485, 830, 151, 161, -485, 102, -485, - -485, -485, -485, 138, 210, -485, -485, -485, -485, -485, - -485, 124, -485, 105, -33, 169, 190, -45, 176, -5, - 57, 231, 174, 34, 203, 35, 204, 56, 50, -485, - -485, 291, 291, -485, 1337, 251, 296, 297, 313, 320, - -485, 211, 242, -65, 279, 330, 559, -485, 17, -485, - -485, -485, -485, -485, 23, 159, -485, -485, 230, 1444, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, 995, 292, 158, 680, - 265, 1337, 680, 1337, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -8, 283, -485, 316, -485, 156, 193, - 158, 164, 254, 255, -31, -485, 168, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, 167, -485, 166, -485, 280, -485, -485, 1337, - 318, 315, 1337, 175, 177, 178, 179, -485, -485, 308, - 31, -485, -485, 42, -485, -485, 272, 185, 186, 188, - 189, 171, 191, 192, 194, 195, 201, 196, 68, -485, - 202, 244, 276, 282, 232, -485, -485, -485, 247, -485, - 26, -36, 30, -485, -32, 286, -485, 150, 289, -485, - -485, 176, -485, -485, -485, 290, -485, 293, -485, 243, - -485, -485, -485, -485, 266, -485, 208, -485, 176, -485, - 267, -485, -485, -485, -485, 300, 233, 301, 256, 256, - -485, 1337, 305, 306, 307, 309, 278, 294, -485, 295, - 302, -485, -485, -485, -485, 346, -485, 328, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, 335, - 250, -485, -485, -485, -485, -485, -485, 12, -485, -485, - -485, 9, 404, 158, -485, -485, -485, -485, -485, -485, - 298, 1112, -485, 406, 298, -485, -485, 407, -4, -485, - 291, -485, -485, -485, 158, 33, 261, 262, 268, 106, - -20, 14, 1337, -485, -485, -485, -485, -485, 321, 223, - 354, -14, -485, -485, -485, 269, 39, 39, 39, 39, - -83, 270, 277, 281, 284, 285, 287, 288, 317, 319, - -485, 39, 39, 39, 39, 322, 323, 39, -485, 355, - 356, -485, -485, -485, 390, 391, -485, 303, -485, -485, - -485, -485, 331, 176, -485, 176, 60, -485, 176, -485, - -485, -485, 369, -485, 176, -485, -485, -485, -485, -485, - -485, -52, 339, -485, -485, 388, 324, -485, 378, -485, - -485, -485, 437, 438, 325, -485, -485, -485, -485, -485, - -485, -485, -485, 299, -485, 314, 139, 680, -485, -485, - -35, -485, 1337, 1337, -485, 680, -13, 680, 256, -485, - -485, -485, -485, 33, 33, 33, 326, 381, 382, -485, - -485, -485, -485, -485, -11, -27, -485, 304, 327, -485, - -485, -485, 329, 383, -50, 332, 39, -485, -485, -485, - -485, -485, -485, 39, 384, 39, 39, 39, 39, 39, - 39, 39, 39, 39, -17, -485, -485, -485, -485, -485, - 333, 334, -485, -485, -485, -485, 429, 244, -485, -485, - -485, 176, -485, -485, -485, -485, 353, 377, 336, 347, - 417, -485, 419, 421, -2, 422, -485, -485, -485, -485, - 428, -485, 1230, -485, 433, 80, -485, -485, -485, -485, - -485, 33, 340, 345, -485, 435, 14, -485, 1337, -485, - -485, 348, 349, -485, -485, -485, -485, -16, -7, -1, - 0, -485, 357, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, 171, 2, 3, 5, 6, 86, 453, - 7, -485, -485, -485, -485, -485, 447, 361, -485, -485, - -485, -485, -485, -485, 363, 1337, -485, -485, 123, -485, - -485, 33, 33, -485, -485, -485, -485, -485, 8, -485, - -485, -485, -485, 39, -485, -485, -485, -485, -485, 367, - 368, 371, 405, 344, 413, 412, 365, -485, -485, 494, - -485, -485, 505, -485, -485, -485, -485, -485, 39, 39, - -70, 513, 560, 86, 39, 561, -485, -485, 424, 427, - 430, -485, 431, 432, 434, -485, -485, 18, -485, -485, - -485, 39, 39, -485, 513, -485, 39, 441, -485, -485, - 442, -485, -485 + 418, -479, 36, -479, -62, -479, -479, -479, 47, -14, + 1104, 50, 68, -479, -479, -479, -479, -479, -479, -479, + -479, 1104, 1104, 116, 8, 8, 8, 8, 8, 8, + 300, -479, -479, -479, 770, 109, 51, -479, 29, -479, + -479, -479, -479, 137, 157, -479, -479, -479, -479, -479, + -479, 129, -479, 221, 54, 71, 210, -54, 124, -2, + -36, 182, 172, 92, 217, -15, 224, 148, 49, 297, + -479, -479, 319, 319, -479, 1104, 285, 328, 330, 348, + 355, -479, 254, 291, -40, -479, -479, -479, -479, -479, + -479, 327, 379, 595, -479, -8, -479, -479, -479, -479, + -479, 11, 200, -479, -479, 360, 1212, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, 944, 341, 201, 95, 316, 1104, 95, + 1104, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, 0, 334, -479, 367, -479, 199, 218, 208, 305, + 308, -11, -479, 230, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, 216, -479, 227, -479, 350, -479, -479, 1104, + 388, 385, 1104, 234, 235, 237, 238, -479, -479, 383, + 8, -479, -479, -62, -479, -479, 353, 256, 257, 263, + 264, 212, 267, 275, 277, 278, 279, 198, 280, 46, + -479, 286, 76, 380, 384, 345, -479, -479, -479, 351, + -479, -25, -44, 38, -479, -16, 386, -479, 207, 392, + -479, -479, 124, -479, -479, -479, 393, -479, 394, -479, + 346, -479, -479, -479, -479, 361, -479, 301, -479, 124, + -479, 363, -479, -479, -479, -479, 400, 329, 402, 403, + 354, 354, -479, 1104, 405, 406, 407, 409, 376, 377, + -479, 378, 397, -479, -479, -479, -479, 447, -479, 414, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, 417, 325, -479, -479, -479, -479, -479, -479, 13, + -479, -479, -479, 10, 489, 201, -479, -479, -479, -479, + -479, -479, 381, 206, -479, 490, 381, -479, -479, 491, + 3, -479, 319, -479, -479, -479, 120, 337, 338, 340, + 147, -14, 2, 1104, -479, -479, -479, -479, -479, 408, + 284, 439, -7, -479, -479, -479, 342, 136, 136, 136, + 136, -27, 343, 347, 349, 352, 356, 357, 358, 359, + 364, 365, -479, 136, 136, 136, 136, 136, 366, 368, + 136, -479, 443, 444, -479, -479, -479, 470, 471, -479, + 370, -479, -479, -479, -479, 410, 124, -479, 124, 41, + -479, 124, -479, -479, -479, 451, -479, 124, -479, -479, + -479, -479, -479, -479, -69, 427, -479, -479, 464, 387, + -479, -479, 468, -479, -479, -479, 532, 535, 389, -479, + -479, -479, -479, -479, -479, -479, -479, 390, -479, 382, + 169, 95, -479, -479, -29, -479, 1104, 1104, -479, 95, + -9, 95, 354, -479, -479, -479, -479, 120, 120, 120, + 416, 506, 515, -479, -479, -479, -479, -479, 7, 110, + -479, 429, 431, -479, -479, -479, 432, 538, -53, 442, + 136, -479, -479, -479, -479, -479, -479, 136, 550, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, -13, + -479, -479, -479, -479, -479, -479, 450, 452, -479, -479, + -479, -479, 574, 76, -479, -479, -479, 124, -479, -479, + -479, -479, 521, 522, 460, 486, 559, -479, 560, 561, + 26, 562, -479, -479, -479, -479, 563, -479, 1070, -479, + 569, 70, -479, -479, -479, -479, -479, 120, 472, 473, + -479, 572, 2, -479, 1104, -479, -479, 474, 475, -479, + -479, -479, -479, -5, -4, -3, -1, -479, 479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + 212, 9, 15, 17, 18, 19, 140, 589, 20, -479, + -479, -479, -479, -479, 578, 481, -479, -479, -479, -479, + -479, -479, 480, 1104, -479, -479, 111, -479, -479, 120, + 120, -479, -479, -479, -479, -479, 21, -479, -479, -479, + -479, 136, -479, -479, -479, -479, -479, -479, 482, 483, + 484, 485, 487, 488, 492, 495, 496, -479, -479, 585, + -479, -479, 587, -479, -479, -479, -479, -479, 136, 136, + -59, 508, 588, 633, 140, 136, 652, -479, -479, 510, + 511, 514, -479, -479, 516, 513, 518, -479, -479, 42, + -479, -479, -479, 136, 136, -479, 588, -479, 136, 517, + -479, -479, 519, -479, -479 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -485, -485, -485, 520, 575, 484, 4, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, 448, -485, -485, -485, -485, -485, -485, -485, - -296, -62, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, 525, 55, -485, 36, -148, -302, - -485, -129, 45, -485, -485, 126, 147, 163, 187, 200, - -485, 241, -485, -477, 496, -485, -485, -485, -57, -485, - -485, -77, -485, -309, 15, -387, -484, -391, -485, -485, - -485, -485, 386, -485, -485, 264, 393, -485, -485, -485, - -485, -485, 198, -56, 342, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, 85, -485, - -485, 540, 271, -485, 173, -485, -10 + -479, -479, -479, 607, 668, 571, 1, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, 534, -479, -479, -479, -479, -479, -479, -287, + -60, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, 605, 632, -479, 126, -146, -281, + -479, -134, 138, -479, -479, 128, 131, 141, 151, 164, + -479, 339, -479, -455, 577, -479, -479, -479, 28, -479, + -479, 12, -479, -227, 103, -402, -478, -381, -479, -479, + -479, -479, 494, -479, -479, 253, 493, -479, -479, -479, + -479, -479, -479, 290, -55, 436, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, 174, + -479, -479, 621, 369, -479, 97, -479, -10 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -442 +#define YYTABLE_NINF -435 static const yytype_int16 yytable[] = { - 224, 282, 283, 365, 90, 519, 520, 521, 522, 299, - 309, 230, 231, 460, 326, 368, 578, 579, 580, -91, - 535, 536, 374, -92, 612, 649, 542, 539, 326, 3, - 4, 5, 6, 7, 650, 592, 10, -166, 90, 601, - 651, 652, 24, 655, 656, 690, 657, 658, 667, 676, - 569, 479, 318, 440, 378, 319, 24, 25, 26, 27, - 28, 29, -441, 500, 224, 171, 479, 324, 166, 170, - 556, 514, 479, 171, 584, 233, 234, 305, 172, 173, - 284, 435, 225, 631, 226, 326, 172, 173, 278, 224, - 90, 523, 436, 274, 524, 235, 441, 278, 328, 501, - 275, 442, 341, 515, 640, 320, 691, 281, 39, 418, - 419, 420, 163, 24, 502, 632, 236, 167, 489, 168, - 229, 557, 306, 285, 517, 596, 593, 227, 518, 310, - 90, 503, 596, 490, 603, 604, 605, 606, 607, 608, - 570, 379, 611, 433, 609, 610, 586, 438, 237, 587, - 491, 293, 174, 421, 348, 294, 613, 613, -166, 278, - 174, 585, 574, 278, 674, 675, 613, 351, 278, 677, - 164, 351, 613, 613, 479, 613, 613, 551, 613, 613, - 613, 613, 298, -441, 351, 474, 504, 659, 325, -441, - 287, 496, 577, 278, 705, 327, 288, 289, 706, 660, - 661, 232, 662, 476, 497, 498, 302, 303, 304, 261, - 597, 598, 599, 600, 434, 437, 439, 262, 263, 384, - 333, 445, 387, 265, 342, 447, 614, 615, 616, 246, - 617, 270, 271, 620, 272, 326, 3, 4, 5, 6, - 7, 334, 453, 267, 268, 343, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 400, 335, 257, 372, - 373, 344, 596, 24, 25, 26, 27, 28, 29, 509, - 510, 511, 401, 402, 403, 404, 264, 405, 406, 407, - 408, 336, 444, 278, 409, 345, 648, 688, 689, 241, - 242, 243, 244, 245, 337, 266, 672, 697, 346, 673, - 277, 461, 278, 424, 364, 425, 366, 280, 488, 278, - 707, 708, 415, 416, 351, 567, 291, 292, 307, 710, - 296, 300, 311, 312, 313, 314, 315, 317, 316, 321, - 322, 339, 30, 351, 362, 369, 370, 371, 375, 376, - 377, 380, 381, 382, 383, 385, 386, 392, 568, 431, - 388, 484, 389, 390, 391, 475, 573, 395, 576, 396, - 397, 429, 398, 399, 432, 411, 412, 430, 413, 414, - 417, 443, 507, 423, 446, 448, 287, 549, 449, 550, - 552, 452, 553, 451, 454, 455, 457, 456, 555, 458, - 462, 463, 464, 1, 465, 466, 470, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 467, 468, 471, 16, 17, 18, 19, 20, 469, - 472, 21, 22, 473, 23, 24, 25, 26, 27, 28, - 29, 477, 30, 485, 487, 493, 494, 480, 508, 513, - 543, 544, 495, 516, 525, 31, 32, 33, 34, 35, - 545, 526, 294, 546, 554, 527, 558, 36, 528, 529, - 559, 530, 531, 561, 562, 563, 582, 583, 591, 602, - 624, 565, 571, 572, 37, 38, 547, 39, 40, 41, - 42, 588, 43, 44, 45, 46, 47, 48, 49, 50, - 566, 532, 621, 533, 625, 623, 540, 541, 560, 564, - 581, 627, 628, 589, 629, 590, 630, 633, 594, 626, - 51, 618, 619, 634, 641, 52, 53, 54, 637, 642, - 643, 665, 55, 682, 646, 647, 56, 57, 58, 59, - 60, 653, 668, 61, 62, 669, 63, 64, 65, 670, - 66, 67, 678, 679, 685, 68, 680, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 636, 84, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 645, 686, - 681, 16, 17, 18, 19, 20, 683, 684, 21, 22, - 687, 23, 24, 25, 26, 27, 28, 29, 692, 30, - 699, 695, 698, 700, 701, 702, 323, 704, 703, 260, - 349, 367, 31, 32, 33, 34, 35, 711, 712, 332, - 639, 499, 644, 350, 36, 671, 696, 709, 654, 394, - 548, 450, 622, 393, 338, 486, 0, 0, 0, 0, - 0, 37, 38, 0, 39, 40, 41, 42, 0, 43, - 44, 45, 46, 47, 48, 49, 50, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, - 0, 0, 52, 53, 54, 326, 0, 0, 0, 55, - 0, 0, 0, 56, 57, 58, 59, 60, 0, 0, - 61, 62, 0, 63, 64, 65, 0, 66, 67, 0, - 0, 0, 68, 24, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 0, - 84, 0, 0, 177, 178, 179, 180, 181, 182, 0, - 0, 0, 183, 0, 184, 185, 186, 187, 188, 189, - 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 191, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 0, 0, 208, - 209, 0, 210, 0, 0, 0, 211, 212, 0, 213, - 0, 214, 215, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 216, 0, 0, 0, 217, 0, 0, - 0, 218, 219, 0, 220, 2, 3, 4, 5, 6, + 214, 97, 273, 274, 534, 357, 513, 514, 515, 516, + 290, 220, 221, 301, 454, 318, 318, 3, 4, 5, + 6, 7, 530, 531, 10, 360, 535, -92, 609, 538, + -93, 588, 574, 575, 576, 97, 647, 648, 649, 597, + 650, -167, 316, 24, 24, 25, 26, 27, 28, 29, + 653, 494, 223, 224, 552, 565, 654, 691, 655, 656, + 657, 667, 676, -434, 473, 214, 174, 172, 433, 215, + 178, 216, 225, 369, 428, 318, 296, 508, 310, 473, + 269, 311, 275, 179, 180, 429, 495, 411, 412, 413, + 269, 580, 226, 426, 97, 39, 340, 219, 278, 272, + 318, 496, 320, 24, 279, 280, 333, 253, 254, 269, + 629, 509, 553, 434, 217, 175, 171, 176, 435, 269, + 497, 297, 638, 605, 606, 692, 227, 276, 24, 592, + 414, 589, 312, 289, 97, 417, 592, 418, 599, 600, + 601, 602, 603, 604, 630, 222, 607, 608, 184, 185, + 186, 187, 188, 189, 566, 517, 431, 190, 518, 547, + 191, 192, 193, 194, 195, 196, 181, 252, 610, 370, + -167, 317, 269, 677, 570, 269, 610, 610, 610, 197, + 610, 265, 498, 343, 674, 675, 343, 581, 266, 473, + 610, 319, -434, 343, 468, 573, 610, 470, 610, 610, + 610, 610, 610, 268, 483, 269, 427, 430, 432, 375, + 284, 255, 378, 438, 285, 198, 199, 440, 200, 484, + 511, 256, 201, 202, 512, 203, 707, 204, 205, 325, + 708, 490, 326, 334, 446, 356, 335, 358, 485, 206, + 658, 257, 327, 207, 491, 492, 336, 208, 209, 258, + 259, 210, 328, 659, 660, 661, 337, 662, 269, 184, + 185, 186, 187, 188, 189, 329, 282, 211, 190, 338, + 592, 191, 192, 193, 194, 195, 196, 476, 231, 232, + 233, 234, 235, 699, 364, 365, 593, 594, 595, 596, + 197, 582, 672, 455, 583, 673, 391, 689, 690, 293, + 294, 295, 482, 611, 612, 613, 712, 614, 615, 408, + 409, 618, 392, 393, 394, 395, 283, 396, 397, 398, + 399, 400, 709, 710, 298, 401, 198, 199, 271, 200, + 503, 504, 505, 201, 202, 287, 203, 564, 204, 205, + 437, 269, 291, 478, 469, 569, 299, 572, 261, 262, + 206, 263, 343, 563, 207, 304, 303, 305, 208, 209, + 306, 307, 210, 501, 646, 318, 3, 4, 5, 6, + 7, 545, 308, 546, 548, 309, 549, 313, 211, 314, + 331, 30, 551, 236, 343, 354, 361, 362, 363, 367, + 366, 477, 368, 24, 25, 26, 27, 28, 29, 372, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 371, 373, 248, 374, 376, 377, 379, 380, 1, + 381, 382, 383, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 386, 387, 388, + 16, 17, 18, 19, 20, 389, 390, 21, 22, 403, + 23, 24, 25, 26, 27, 28, 29, 404, 30, 405, + 406, 407, 410, 424, 422, 416, 567, 568, 423, 425, + 436, 31, 32, 33, 34, 35, 439, 441, 442, 444, + 278, 447, 445, 36, 448, 449, 450, 451, 452, 456, + 457, 458, 621, 459, 460, 461, 462, 464, 465, 37, + 38, 466, 39, 40, 41, 42, 467, 43, 44, 45, + 46, 47, 48, 49, 50, 463, 471, 479, 481, 487, + 488, 474, 489, 507, 510, 519, 502, 539, 540, 520, + 541, 521, 285, 542, 522, 550, 555, 51, 523, 524, + 525, 526, 52, 53, 54, 554, 527, 528, 536, 55, + 537, 543, 557, 56, 57, 58, 59, 60, 634, 558, + 61, 62, 559, 63, 64, 65, 562, 66, 67, 556, + 561, 560, 68, 69, 643, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 578, 85, 86, 87, 88, 89, 90, 91, 577, 579, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 584, 585, 586, 16, 17, 18, + 19, 20, 587, 671, 21, 22, 590, 23, 24, 25, + 26, 27, 28, 29, 598, 30, 616, 619, 617, 622, + 623, 624, 625, 626, 627, 628, 631, 632, 31, 32, + 33, 34, 35, 635, 639, 640, 641, 665, 644, 645, + 36, 651, 668, 669, 670, 678, 679, 680, 681, 687, + 682, 688, 694, 684, 697, 683, 37, 38, 685, 39, + 40, 41, 42, 686, 43, 44, 45, 46, 47, 48, + 49, 50, 693, 700, 701, 702, 703, 705, 704, 706, + 315, 713, 251, 714, 341, 359, 324, 302, 642, 637, + 493, 342, 698, 652, 51, 544, 443, 620, 711, 52, + 53, 54, 330, 384, 0, 480, 55, 385, 0, 0, + 56, 57, 58, 59, 60, 0, 0, 61, 62, 0, + 63, 64, 65, 0, 66, 67, 0, 0, 0, 68, + 69, 0, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 0, 85, 86, + 87, 88, 89, 90, 91, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, - 221, 0, 16, 17, 18, 19, 20, 0, 0, 21, + 0, 0, 16, 17, 18, 19, 20, 0, 0, 21, 22, 0, 23, 24, 25, 26, 27, 28, 29, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 31, 32, 33, 259, 35, 0, 0, + 0, 0, 0, 31, 32, 33, 250, 35, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 37, 38, 0, 39, 40, 41, 42, 0, - 43, 44, 45, 46, 47, 48, 49, 50, 0, 0, + 0, 37, 38, 0, 39, 40, 41, 42, 0, 43, + 44, 45, 46, 47, 48, 49, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, - 0, 0, 0, 52, 53, 54, 0, 0, 0, 0, - 55, 0, 0, 0, 56, 57, 58, 59, 60, 0, - 0, 61, 62, 0, 63, 64, 65, 0, 66, 67, - 0, 0, 0, 68, 0, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 0, 0, 0, 16, 17, 18, - 19, 20, 0, 0, 21, 22, 0, 23, 24, 25, - 26, 27, 28, 29, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 31, 32, - 33, 259, 35, 0, 0, 0, 0, 0, 0, 0, - 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 37, 38, 0, - 39, 40, 41, 42, 0, 43, 44, 45, 46, 47, - 48, 49, 50, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, + 0, 0, 0, 0, 52, 53, 54, 0, 0, 0, + 0, 55, 0, 0, 0, 56, 57, 58, 59, 60, + 0, 0, 61, 62, 0, 63, 64, 65, 0, 66, + 67, 0, 0, 0, 68, 69, 0, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 0, 85, 86, 87, 88, 89, 90, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 0, 0, 0, 16, 17, 18, 19, + 20, 0, 0, 21, 22, 0, 23, 24, 25, 26, + 27, 28, 29, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 31, 32, 33, + 250, 35, 0, 0, 0, 0, 0, 0, 0, 36, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 37, 38, 0, 39, 40, + 41, 42, 0, 43, 44, 45, 46, 47, 48, 49, + 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 52, 53, 54, 0, 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 59, 60, 0, 0, 61, 62, 0, 63, - 64, 65, 0, 66, 67, 0, 0, 0, 68, 0, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 177, 178, 179, 180, 181, - 182, 0, 0, 0, 183, 0, 184, 185, 186, 187, - 188, 189, 190, 482, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 191, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 0, - 0, 208, 209, 0, 210, 0, 0, 0, 211, 212, - 0, 213, 0, 214, 215, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 216, 0, 0, 0, 217, - 0, 0, 0, 218, 219, 0, 220, 0, 0, 0, + 64, 65, 0, 66, 67, 0, 0, 0, 68, 69, + 0, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 0, 85, 86, 87, + 88, 89, 90, 184, 185, 186, 187, 188, 189, 0, + 0, 0, 190, 0, 0, 191, 192, 193, 194, 195, + 196, 633, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 197, 0, 0, 184, 185, 186, + 187, 188, 189, 0, 0, 0, 190, 0, 0, 191, + 192, 193, 194, 195, 196, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, + 198, 199, 0, 200, 0, 0, 0, 201, 202, 0, + 203, 0, 204, 205, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 206, 0, 0, 0, 207, 0, + 0, 0, 208, 209, 198, 199, 210, 200, 0, 0, + 0, 201, 202, 0, 203, 0, 204, 205, 0, 0, + 0, 0, 211, 0, 0, 0, 0, 0, 206, 0, + 0, 0, 207, 0, 0, 0, 208, 209, 0, 0, + 210, 0, 0, 0, 0, 184, 185, 186, 187, 188, + 189, 0, 0, 0, 190, 0, 211, 191, 192, 193, + 194, 195, 196, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 221, 177, 178, 179, 180, 181, 182, 483, - 0, 0, 183, 0, 184, 185, 186, 187, 188, 189, - 190, 635, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 0, 0, 208, - 209, 0, 210, 0, 0, 0, 211, 212, 0, 213, - 0, 214, 215, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 216, 0, 0, 0, 217, 0, 0, - 0, 218, 219, 0, 220, 0, 0, 0, 0, 0, - 177, 178, 179, 180, 181, 182, 0, 0, 0, 183, - 221, 184, 185, 186, 187, 188, 189, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 191, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 192, 193, - 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 207, 0, 0, 208, 209, 0, 210, - 0, 0, 0, 211, 212, 0, 213, 0, 214, 215, + 0, 0, 198, 199, 0, 200, 0, 0, 0, 201, + 202, 0, 203, 0, 204, 205, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 206, 0, 0, 0, + 207, 0, 0, 0, 208, 209, 0, 0, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 216, 0, 0, 0, 217, 0, 0, 0, 218, 219, - 0, 220, 0, 0, 0, 0, 0, 177, 178, 179, - 180, 181, 182, 0, 0, 0, 183, 221, 184, 185, - 186, 187, 188, 189, 190, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 347, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 0, 0, 208, 209, 0, 210, 0, 0, 0, - 211, 212, 0, 213, 0, 214, 215, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 216, 0, 0, - 0, 217, 0, 0, 0, 218, 219, 0, 220, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 221 + 0, 0, 0, 0, 211 }; static const yytype_int16 yycheck[] = { - 10, 57, 58, 132, 0, 396, 397, 398, 399, 65, - 72, 21, 22, 309, 5, 163, 493, 494, 495, 27, - 411, 412, 170, 27, 41, 41, 417, 414, 5, 6, - 7, 8, 9, 10, 41, 85, 13, 50, 34, 523, - 41, 41, 33, 41, 41, 115, 41, 41, 41, 41, - 85, 353, 117, 85, 85, 120, 33, 34, 35, 36, - 37, 38, 50, 49, 74, 85, 368, 50, 19, 81, - 122, 85, 374, 85, 85, 44, 45, 27, 98, 99, - 85, 117, 19, 85, 21, 5, 98, 99, 133, 99, - 86, 174, 128, 126, 177, 64, 128, 133, 94, 85, - 133, 133, 98, 117, 581, 170, 176, 152, 85, 41, - 42, 43, 80, 33, 100, 117, 85, 68, 85, 70, - 29, 173, 72, 128, 85, 516, 176, 64, 89, 74, - 126, 117, 523, 100, 525, 526, 527, 528, 529, 530, - 175, 172, 533, 117, 531, 532, 173, 117, 117, 176, - 117, 117, 172, 85, 99, 121, 173, 173, 171, 133, - 172, 172, 175, 133, 641, 642, 173, 175, 133, 653, - 128, 175, 173, 173, 476, 173, 173, 117, 173, 173, - 173, 173, 147, 171, 175, 176, 172, 101, 171, 177, - 133, 85, 488, 133, 176, 172, 139, 140, 180, 113, - 114, 29, 116, 351, 98, 99, 150, 151, 152, 58, - 519, 520, 521, 522, 270, 271, 272, 56, 57, 229, - 94, 277, 232, 85, 98, 281, 535, 536, 537, 84, - 539, 126, 127, 542, 129, 5, 6, 7, 8, 9, - 10, 94, 298, 119, 120, 98, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 85, 94, 113, 66, - 67, 98, 653, 33, 34, 35, 36, 37, 38, 46, - 47, 48, 101, 102, 103, 104, 174, 106, 107, 108, - 109, 94, 132, 133, 113, 98, 595, 678, 679, 25, - 26, 27, 28, 29, 94, 85, 173, 684, 98, 176, - 131, 311, 133, 59, 131, 61, 133, 117, 370, 133, - 701, 702, 111, 112, 175, 176, 85, 143, 27, 706, - 117, 117, 71, 27, 27, 12, 6, 85, 117, 50, - 0, 172, 40, 175, 69, 52, 20, 181, 174, 85, - 85, 173, 175, 177, 64, 27, 31, 39, 477, 117, - 175, 361, 175, 175, 175, 351, 485, 85, 487, 174, - 174, 85, 174, 174, 117, 174, 174, 85, 174, 174, - 174, 85, 382, 171, 85, 85, 133, 433, 85, 435, - 436, 173, 438, 117, 117, 85, 85, 154, 444, 133, - 85, 85, 85, 1, 85, 117, 50, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 117, 117, 85, 22, 23, 24, 25, 26, 117, - 85, 29, 30, 173, 32, 33, 34, 35, 36, 37, - 38, 27, 40, 27, 27, 174, 174, 139, 117, 85, - 85, 85, 174, 174, 174, 53, 54, 55, 56, 57, - 60, 174, 121, 62, 85, 174, 117, 65, 174, 174, - 72, 174, 174, 85, 27, 27, 85, 85, 85, 85, - 117, 172, 482, 483, 82, 83, 173, 85, 86, 87, - 88, 177, 90, 91, 92, 93, 94, 95, 96, 97, - 176, 174, 63, 174, 117, 551, 174, 174, 174, 174, - 174, 154, 85, 176, 85, 176, 85, 85, 176, 173, - 118, 178, 178, 85, 174, 123, 124, 125, 85, 174, - 85, 68, 130, 179, 176, 176, 134, 135, 136, 137, - 138, 174, 85, 141, 142, 174, 144, 145, 146, 176, - 148, 149, 175, 175, 179, 153, 175, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 572, 171, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 588, 85, - 175, 22, 23, 24, 25, 26, 173, 175, 29, 30, - 85, 32, 33, 34, 35, 36, 37, 38, 85, 40, - 176, 41, 41, 176, 174, 174, 86, 173, 176, 34, - 126, 163, 53, 54, 55, 56, 57, 176, 176, 94, - 575, 380, 586, 127, 65, 635, 683, 704, 613, 243, - 432, 289, 547, 240, 94, 364, -1, -1, -1, -1, - -1, 82, 83, -1, 85, 86, 87, 88, -1, 90, - 91, 92, 93, 94, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 118, -1, -1, - -1, -1, 123, 124, 125, 5, -1, -1, -1, 130, - -1, -1, -1, 134, 135, 136, 137, 138, -1, -1, - 141, 142, -1, 144, 145, 146, -1, 148, 149, -1, - -1, -1, 153, 33, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, 169, -1, - 171, -1, -1, 53, 54, 55, 56, 57, 58, -1, - -1, -1, 62, -1, 64, 65, 66, 67, 68, 69, - 70, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 85, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, -1, -1, 119, - 120, -1, 122, -1, -1, -1, 126, 127, -1, 129, - -1, 131, 132, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 143, -1, -1, -1, 147, -1, -1, - -1, 151, 152, -1, 154, 5, 6, 7, 8, 9, + 10, 0, 57, 58, 406, 139, 387, 388, 389, 390, + 65, 21, 22, 73, 301, 5, 5, 6, 7, 8, + 9, 10, 403, 404, 13, 171, 407, 27, 41, 410, + 27, 84, 487, 488, 489, 34, 41, 41, 41, 517, + 41, 50, 50, 33, 33, 34, 35, 36, 37, 38, + 41, 49, 44, 45, 123, 84, 41, 116, 41, 41, + 41, 41, 41, 50, 345, 75, 19, 129, 84, 19, + 84, 21, 64, 84, 118, 5, 27, 84, 118, 360, + 134, 121, 84, 97, 98, 129, 84, 41, 42, 43, + 134, 84, 84, 118, 93, 84, 106, 29, 134, 153, + 5, 99, 101, 33, 140, 141, 105, 56, 57, 134, + 84, 118, 181, 129, 64, 68, 80, 70, 134, 134, + 118, 72, 577, 525, 526, 184, 118, 129, 33, 510, + 84, 184, 172, 148, 133, 59, 517, 61, 519, 520, + 521, 522, 523, 524, 118, 29, 527, 528, 53, 54, + 55, 56, 57, 58, 183, 182, 118, 62, 185, 118, + 65, 66, 67, 68, 69, 70, 180, 58, 181, 180, + 179, 179, 134, 651, 183, 134, 181, 181, 181, 84, + 181, 127, 180, 183, 639, 640, 183, 180, 134, 470, + 181, 180, 179, 183, 184, 482, 181, 343, 181, 181, + 181, 181, 181, 132, 84, 134, 261, 262, 263, 219, + 118, 182, 222, 268, 122, 120, 121, 272, 123, 99, + 84, 84, 127, 128, 88, 130, 184, 132, 133, 101, + 188, 84, 101, 105, 289, 138, 105, 140, 118, 144, + 100, 84, 101, 148, 97, 98, 105, 152, 153, 120, + 121, 156, 101, 113, 114, 115, 105, 117, 134, 53, + 54, 55, 56, 57, 58, 101, 84, 172, 62, 105, + 651, 65, 66, 67, 68, 69, 70, 71, 25, 26, + 27, 28, 29, 685, 66, 67, 513, 514, 515, 516, + 84, 181, 181, 303, 184, 184, 84, 678, 679, 151, + 152, 153, 362, 530, 531, 532, 708, 534, 535, 111, + 112, 538, 100, 101, 102, 103, 144, 105, 106, 107, + 108, 109, 703, 704, 27, 113, 120, 121, 118, 123, + 46, 47, 48, 127, 128, 118, 130, 471, 132, 133, + 133, 134, 118, 353, 343, 479, 27, 481, 127, 128, + 144, 130, 183, 184, 148, 27, 71, 27, 152, 153, + 12, 6, 156, 373, 591, 5, 6, 7, 8, 9, + 10, 426, 118, 428, 429, 84, 431, 50, 172, 0, + 180, 40, 437, 83, 183, 69, 52, 20, 189, 84, + 182, 185, 84, 33, 34, 35, 36, 37, 38, 183, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 181, 185, 113, 64, 27, 31, 183, 183, 1, + 183, 183, 39, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 84, 182, 182, + 22, 23, 24, 25, 26, 182, 182, 29, 30, 182, + 32, 33, 34, 35, 36, 37, 38, 182, 40, 182, + 182, 182, 182, 118, 84, 179, 476, 477, 84, 118, + 84, 53, 54, 55, 56, 57, 84, 84, 84, 118, + 134, 118, 181, 65, 84, 156, 84, 84, 134, 84, + 84, 84, 547, 84, 118, 118, 118, 50, 84, 81, + 82, 84, 84, 85, 86, 87, 181, 89, 90, 91, + 92, 93, 94, 95, 96, 118, 27, 27, 27, 182, + 182, 140, 182, 84, 182, 182, 118, 84, 84, 182, + 60, 182, 122, 62, 182, 84, 72, 119, 182, 182, + 182, 182, 124, 125, 126, 118, 182, 182, 182, 131, + 182, 181, 84, 135, 136, 137, 138, 139, 568, 27, + 142, 143, 27, 145, 146, 147, 184, 149, 150, 182, + 180, 182, 154, 155, 584, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 84, 173, 174, 175, 176, 177, 178, 179, 182, 84, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 185, 184, 184, 22, 23, 24, + 25, 26, 84, 633, 29, 30, 184, 32, 33, 34, + 35, 36, 37, 38, 84, 40, 186, 63, 186, 118, + 118, 181, 156, 84, 84, 84, 84, 84, 53, 54, + 55, 56, 57, 84, 182, 182, 84, 68, 184, 184, + 65, 182, 84, 182, 184, 183, 183, 183, 183, 84, + 183, 84, 84, 181, 41, 187, 81, 82, 183, 84, + 85, 86, 87, 187, 89, 90, 91, 92, 93, 94, + 95, 96, 184, 41, 184, 184, 182, 184, 182, 181, + 93, 184, 34, 184, 133, 171, 101, 75, 582, 571, + 371, 134, 684, 610, 119, 425, 280, 543, 706, 124, + 125, 126, 101, 230, -1, 356, 131, 233, -1, -1, + 135, 136, 137, 138, 139, -1, -1, 142, 143, -1, + 145, 146, 147, -1, 149, 150, -1, -1, -1, 154, + 155, -1, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, -1, 173, 174, + 175, 176, 177, 178, 179, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, - 170, -1, 22, 23, 24, 25, 26, -1, -1, 29, + -1, -1, 22, 23, 24, 25, 26, -1, -1, 29, 30, -1, 32, 33, 34, 35, 36, 37, 38, -1, 40, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1, -1, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 82, 83, -1, 85, 86, 87, 88, -1, - 90, 91, 92, 93, 94, 95, 96, 97, -1, -1, + -1, 81, 82, -1, 84, 85, 86, 87, -1, 89, + 90, 91, 92, 93, 94, 95, 96, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 118, -1, - -1, -1, -1, 123, 124, 125, -1, -1, -1, -1, - 130, -1, -1, -1, 134, 135, 136, 137, 138, -1, - -1, 141, 142, -1, 144, 145, 146, -1, 148, 149, - -1, -1, -1, 153, -1, 155, 156, 157, 158, 159, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 119, + -1, -1, -1, -1, 124, 125, 126, -1, -1, -1, + -1, 131, -1, -1, -1, 135, 136, 137, 138, 139, + -1, -1, 142, 143, -1, 145, 146, 147, -1, 149, + 150, -1, -1, -1, 154, 155, -1, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, -1, -1, -1, 22, 23, 24, - 25, 26, -1, -1, 29, 30, -1, 32, 33, 34, - 35, 36, 37, 38, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 53, 54, - 55, 56, 57, -1, -1, -1, -1, -1, -1, -1, - 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 82, 83, -1, - 85, 86, 87, 88, -1, 90, 91, 92, 93, 94, - 95, 96, 97, -1, -1, -1, -1, -1, -1, -1, + 170, 171, -1, 173, 174, 175, 176, 177, 178, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, -1, -1, -1, 22, 23, 24, 25, + 26, -1, -1, 29, 30, -1, 32, 33, 34, 35, + 36, 37, 38, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 53, 54, 55, + 56, 57, -1, -1, -1, -1, -1, -1, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 118, -1, -1, -1, -1, 123, 124, - 125, -1, -1, -1, -1, 130, -1, -1, -1, 134, - 135, 136, 137, 138, -1, -1, 141, 142, -1, 144, - 145, 146, -1, 148, 149, -1, -1, -1, 153, -1, - 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 53, 54, 55, 56, 57, - 58, -1, -1, -1, 62, -1, 64, 65, 66, 67, - 68, 69, 70, 71, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 85, -1, -1, + -1, -1, -1, -1, -1, 81, 82, -1, 84, 85, + 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, + 96, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, -1, - -1, 119, 120, -1, 122, -1, -1, -1, 126, 127, - -1, 129, -1, 131, 132, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 143, -1, -1, -1, 147, - -1, -1, -1, 151, 152, -1, 154, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 170, 53, 54, 55, 56, 57, 58, 177, - -1, -1, 62, -1, 64, 65, 66, 67, 68, 69, + -1, -1, -1, 119, -1, -1, -1, -1, 124, 125, + 126, -1, -1, -1, -1, 131, -1, -1, -1, 135, + 136, 137, 138, 139, -1, -1, 142, 143, -1, 145, + 146, 147, -1, 149, 150, -1, -1, -1, 154, 155, + -1, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, -1, 173, 174, 175, + 176, 177, 178, 53, 54, 55, 56, 57, 58, -1, + -1, -1, 62, -1, -1, 65, 66, 67, 68, 69, 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 85, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, -1, -1, 119, - 120, -1, 122, -1, -1, -1, 126, 127, -1, 129, - -1, 131, 132, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 143, -1, -1, -1, 147, -1, -1, - -1, 151, 152, -1, 154, -1, -1, -1, -1, -1, - 53, 54, 55, 56, 57, 58, -1, -1, -1, 62, - 170, 64, 65, 66, 67, 68, 69, 70, -1, -1, + -1, -1, -1, -1, 84, -1, -1, 53, 54, 55, + 56, 57, 58, -1, -1, -1, 62, -1, -1, 65, + 66, 67, 68, 69, 70, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 84, -1, + 120, 121, -1, 123, -1, -1, -1, 127, 128, -1, + 130, -1, 132, 133, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 144, -1, -1, -1, 148, -1, + -1, -1, 152, 153, 120, 121, 156, 123, -1, -1, + -1, 127, 128, -1, 130, -1, 132, 133, -1, -1, + -1, -1, 172, -1, -1, -1, -1, -1, 144, -1, + -1, -1, 148, -1, -1, -1, 152, 153, -1, -1, + 156, -1, -1, -1, -1, 53, 54, 55, 56, 57, + 58, -1, -1, -1, 62, -1, 172, 65, 66, 67, + 68, 69, 70, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 84, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 85, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, -1, -1, 119, 120, -1, 122, - -1, -1, -1, 126, 127, -1, 129, -1, 131, 132, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 143, -1, -1, -1, 147, -1, -1, -1, 151, 152, - -1, 154, -1, -1, -1, -1, -1, 53, 54, 55, - 56, 57, 58, -1, -1, -1, 62, 170, 64, 65, - 66, 67, 68, 69, 70, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 85, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, -1, 119, 120, -1, 122, -1, -1, -1, - 126, 127, -1, 129, -1, 131, 132, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 143, -1, -1, - -1, 147, -1, -1, -1, 151, 152, -1, 154, -1, + -1, -1, 120, 121, -1, 123, -1, -1, -1, 127, + 128, -1, 130, -1, 132, 133, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 144, -1, -1, -1, + 148, -1, -1, -1, 152, 153, -1, -1, 156, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 170 + -1, -1, -1, -1, 172 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -1869,75 +1827,75 @@ static const yytype_uint16 yystos[] = 0, 1, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 22, 23, 24, 25, 26, 29, 30, 32, 33, 34, 35, 36, 37, 38, - 40, 53, 54, 55, 56, 57, 65, 82, 83, 85, - 86, 87, 88, 90, 91, 92, 93, 94, 95, 96, - 97, 118, 123, 124, 125, 130, 134, 135, 136, 137, - 138, 141, 142, 144, 145, 146, 148, 149, 153, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 171, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 197, 198, 199, 200, 201, 202, - 205, 206, 207, 208, 209, 210, 211, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 237, 238, 239, 240, 241, 242, 246, 247, 260, 261, - 262, 263, 265, 266, 272, 273, 277, 279, 280, 281, - 283, 285, 286, 287, 288, 290, 291, 292, 293, 294, - 296, 297, 299, 300, 301, 302, 303, 304, 305, 307, - 311, 312, 313, 80, 128, 264, 19, 68, 70, 306, - 81, 85, 98, 99, 172, 243, 244, 53, 54, 55, - 56, 57, 58, 62, 64, 65, 66, 67, 68, 69, - 70, 85, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 119, 120, - 122, 126, 127, 129, 131, 132, 143, 147, 151, 152, - 154, 170, 227, 317, 318, 19, 21, 64, 192, 29, - 318, 318, 29, 44, 45, 64, 85, 117, 267, 268, - 269, 267, 267, 267, 267, 267, 84, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 113, 248, 56, - 186, 58, 56, 57, 174, 85, 85, 119, 120, 278, - 126, 127, 129, 284, 126, 133, 282, 131, 133, 275, - 117, 152, 275, 275, 85, 128, 289, 133, 139, 140, - 276, 85, 143, 117, 121, 274, 117, 295, 147, 275, - 117, 298, 150, 151, 152, 27, 72, 27, 213, 213, - 227, 71, 27, 27, 12, 6, 117, 85, 117, 120, - 170, 50, 0, 185, 50, 171, 5, 172, 188, 193, - 195, 196, 226, 237, 238, 239, 240, 241, 313, 172, - 194, 188, 237, 238, 239, 240, 241, 85, 227, 187, - 246, 175, 204, 230, 231, 232, 188, 233, 234, 315, - 316, 318, 69, 271, 316, 233, 316, 204, 230, 52, - 20, 181, 66, 67, 230, 174, 85, 85, 85, 172, - 173, 175, 177, 64, 318, 27, 31, 318, 175, 175, - 175, 175, 39, 268, 264, 85, 174, 174, 174, 174, - 85, 101, 102, 103, 104, 106, 107, 108, 109, 113, - 256, 174, 174, 174, 174, 111, 112, 174, 41, 42, - 43, 85, 249, 171, 59, 61, 308, 309, 310, 85, - 85, 117, 117, 117, 275, 117, 128, 275, 117, 275, - 85, 128, 133, 85, 132, 275, 85, 275, 85, 85, - 276, 117, 173, 275, 117, 85, 154, 85, 133, 212, - 212, 318, 85, 85, 85, 85, 117, 117, 117, 117, - 50, 85, 85, 173, 176, 188, 230, 27, 203, 231, - 139, 314, 71, 177, 318, 27, 314, 27, 213, 85, - 100, 117, 245, 174, 174, 174, 85, 98, 99, 243, - 49, 85, 100, 117, 172, 228, 229, 318, 117, 46, - 47, 48, 270, 85, 85, 117, 174, 85, 89, 259, - 259, 259, 259, 174, 177, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 255, 259, 259, 257, 259, 257, - 174, 174, 259, 85, 85, 60, 62, 173, 274, 275, - 275, 117, 275, 275, 85, 275, 122, 173, 117, 72, - 174, 85, 27, 27, 174, 172, 176, 176, 233, 85, - 175, 318, 318, 233, 175, 235, 233, 212, 245, 245, - 245, 174, 85, 85, 85, 172, 173, 176, 177, 176, - 176, 85, 85, 176, 176, 258, 259, 255, 255, 255, - 255, 258, 85, 259, 259, 259, 259, 259, 259, 257, - 257, 259, 41, 173, 255, 255, 255, 255, 178, 178, - 255, 63, 310, 275, 117, 117, 173, 154, 85, 85, - 85, 85, 117, 85, 85, 71, 318, 85, 236, 234, - 245, 174, 174, 85, 229, 318, 176, 176, 255, 41, - 41, 41, 41, 174, 256, 41, 41, 41, 41, 101, - 113, 114, 116, 250, 251, 68, 252, 41, 85, 174, - 176, 318, 173, 176, 245, 245, 41, 258, 175, 175, - 175, 175, 179, 173, 175, 179, 85, 85, 259, 259, - 115, 176, 85, 253, 254, 41, 250, 257, 41, 176, - 176, 174, 174, 176, 173, 176, 180, 259, 259, 253, - 257, 176, 176 + 40, 53, 54, 55, 56, 57, 65, 81, 82, 84, + 85, 86, 87, 89, 90, 91, 92, 93, 94, 95, + 96, 119, 124, 125, 126, 131, 135, 136, 137, 138, + 139, 142, 143, 145, 146, 147, 149, 150, 154, 155, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 173, 174, 175, 176, 177, + 178, 179, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 205, 206, 207, 208, 209, 210, 213, 214, 215, + 216, 217, 218, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 245, 246, 247, + 248, 249, 250, 254, 255, 268, 269, 270, 271, 273, + 274, 280, 281, 282, 286, 288, 289, 290, 292, 294, + 295, 296, 297, 299, 300, 301, 302, 303, 305, 306, + 308, 309, 310, 311, 312, 313, 314, 316, 320, 321, + 322, 80, 129, 272, 19, 68, 70, 315, 84, 97, + 98, 180, 251, 252, 53, 54, 55, 56, 57, 58, + 62, 65, 66, 67, 68, 69, 70, 84, 120, 121, + 123, 127, 128, 130, 132, 133, 144, 148, 152, 153, + 156, 172, 235, 326, 327, 19, 21, 64, 200, 29, + 327, 327, 29, 44, 45, 64, 84, 118, 275, 276, + 277, 275, 275, 275, 275, 275, 83, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 113, 256, + 56, 194, 58, 56, 57, 182, 84, 84, 120, 121, + 287, 127, 128, 130, 293, 127, 134, 291, 132, 134, + 284, 118, 153, 284, 284, 84, 129, 298, 134, 140, + 141, 285, 84, 144, 118, 122, 283, 118, 304, 148, + 284, 118, 307, 151, 152, 153, 27, 72, 27, 27, + 220, 220, 235, 71, 27, 27, 12, 6, 118, 84, + 118, 121, 172, 50, 0, 193, 50, 179, 5, 180, + 196, 201, 203, 204, 234, 245, 246, 247, 248, 249, + 322, 180, 202, 196, 245, 246, 247, 248, 249, 84, + 327, 195, 254, 183, 212, 238, 239, 240, 196, 241, + 242, 324, 325, 327, 69, 279, 325, 241, 325, 212, + 238, 52, 20, 189, 66, 67, 182, 84, 84, 84, + 180, 181, 183, 185, 64, 327, 27, 31, 327, 183, + 183, 183, 183, 39, 276, 272, 84, 182, 182, 182, + 182, 84, 100, 101, 102, 103, 105, 106, 107, 108, + 109, 113, 264, 182, 182, 182, 182, 182, 111, 112, + 182, 41, 42, 43, 84, 257, 179, 59, 61, 317, + 318, 319, 84, 84, 118, 118, 118, 284, 118, 129, + 284, 118, 284, 84, 129, 134, 84, 133, 284, 84, + 284, 84, 84, 285, 118, 181, 284, 118, 84, 156, + 84, 84, 134, 219, 219, 327, 84, 84, 84, 84, + 118, 118, 118, 118, 50, 84, 84, 181, 184, 196, + 238, 27, 211, 239, 140, 323, 71, 185, 327, 27, + 323, 27, 220, 84, 99, 118, 253, 182, 182, 182, + 84, 97, 98, 251, 49, 84, 99, 118, 180, 236, + 237, 327, 118, 46, 47, 48, 278, 84, 84, 118, + 182, 84, 88, 267, 267, 267, 267, 182, 185, 182, + 182, 182, 182, 182, 182, 182, 182, 182, 182, 263, + 267, 267, 265, 267, 265, 267, 182, 182, 267, 84, + 84, 60, 62, 181, 283, 284, 284, 118, 284, 284, + 84, 284, 123, 181, 118, 72, 182, 84, 27, 27, + 182, 180, 184, 184, 241, 84, 183, 327, 327, 241, + 183, 243, 241, 219, 253, 253, 253, 182, 84, 84, + 84, 180, 181, 184, 185, 184, 184, 84, 84, 184, + 184, 266, 267, 263, 263, 263, 263, 266, 84, 267, + 267, 267, 267, 267, 267, 265, 265, 267, 267, 41, + 181, 263, 263, 263, 263, 263, 186, 186, 263, 63, + 319, 284, 118, 118, 181, 156, 84, 84, 84, 84, + 118, 84, 84, 71, 327, 84, 244, 242, 253, 182, + 182, 84, 237, 327, 184, 184, 263, 41, 41, 41, + 41, 182, 264, 41, 41, 41, 41, 41, 100, 113, + 114, 115, 117, 258, 259, 68, 260, 41, 84, 182, + 184, 327, 181, 184, 253, 253, 41, 266, 183, 183, + 183, 183, 183, 187, 181, 183, 187, 84, 84, 267, + 267, 116, 184, 184, 84, 261, 262, 41, 258, 265, + 41, 184, 184, 182, 182, 184, 181, 184, 188, 267, + 267, 261, 265, 184, 184 }; #define yyerrok (yyerrstatus = 0) @@ -2945,42 +2903,42 @@ YYLTYPE yylloc; case 37: - { result->cur_stmt_type_ = OBPROXY_T_OTHERS; ;} + {;} break; - case 47: + case 38: - { result->cur_stmt_type_ = OBPROXY_T_CREATE; ;} + { result->cur_stmt_type_ = OBPROXY_T_OTHERS; ;} break; case 48: - { result->cur_stmt_type_ = OBPROXY_T_DROP; ;} + { result->cur_stmt_type_ = OBPROXY_T_CREATE; ;} break; case 49: - { result->cur_stmt_type_ = OBPROXY_T_ALTER; ;} + { result->cur_stmt_type_ = OBPROXY_T_DROP; ;} break; case 50: - { result->cur_stmt_type_ = OBPROXY_T_TRUNCATE; ;} + { result->cur_stmt_type_ = OBPROXY_T_ALTER; ;} break; case 51: - { result->cur_stmt_type_ = OBPROXY_T_RENAME; ;} + { result->cur_stmt_type_ = OBPROXY_T_TRUNCATE; ;} break; - case 53: + case 52: - { result->sub_stmt_type_ = OBPROXY_T_SUB_CREATE_TABLE; ;} + { result->cur_stmt_type_ = OBPROXY_T_RENAME; ;} break; case 54: - { result->sub_stmt_type_ = OBPROXY_T_SUB_CREATE_INDEX; ;} + { result->sub_stmt_type_ = OBPROXY_T_SUB_CREATE_TABLE; ;} break; case 55: @@ -2990,7 +2948,7 @@ YYLTYPE yylloc; case 56: - {;} + { result->sub_stmt_type_ = OBPROXY_T_SUB_CREATE_INDEX; ;} break; case 57: @@ -3030,6 +2988,11 @@ YYLTYPE yylloc; case 64: + {;} + break; + + case 65: + { ObProxyTextPsParseNode *node = NULL; malloc_parse_node(node); @@ -3038,7 +3001,7 @@ YYLTYPE yylloc; ;} break; - case 65: + case 66: { ObProxyTextPsParseNode *node = NULL; @@ -3048,7 +3011,7 @@ YYLTYPE yylloc; ;} break; - case 66: + case 67: { ObProxyTextPsParseNode *node = NULL; @@ -3058,7 +3021,7 @@ YYLTYPE yylloc; ;} break; - case 69: + case 70: { result->text_ps_inner_stmt_type_ = OBPROXY_T_TEXT_PS_PREPARE; @@ -3066,7 +3029,7 @@ YYLTYPE yylloc; ;} break; - case 70: + case 71: { result->cur_stmt_type_ = OBPROXY_T_TEXT_PS_EXECUTE; @@ -3074,7 +3037,7 @@ YYLTYPE yylloc; ;} break; - case 71: + case 72: { result->cur_stmt_type_ = OBPROXY_T_TEXT_PS_EXECUTE; @@ -3082,19 +3045,19 @@ YYLTYPE yylloc; ;} break; - case 72: + case 73: { ;} break; - case 73: + case 74: { ;} break; - case 74: + case 75: { result->cur_stmt_type_ = OBPROXY_T_TEXT_PS_DROP; @@ -3102,7 +3065,7 @@ YYLTYPE yylloc; ;} break; - case 75: + case 76: { result->cur_stmt_type_ = OBPROXY_T_TEXT_PS_DROP; @@ -3110,74 +3073,74 @@ YYLTYPE yylloc; ;} break; - case 76: + case 77: { result->cur_stmt_type_ = OBPROXY_T_GRANT; ;} break; - case 77: + case 78: { result->cur_stmt_type_ = OBPROXY_T_REVOKE; ;} break; - case 78: + case 79: { result->cur_stmt_type_ = OBPROXY_T_ANALYZE; ;} break; - case 79: + case 80: { result->cur_stmt_type_ = OBPROXY_T_PURGE; ;} break; - case 80: + case 81: { result->cur_stmt_type_ = OBPROXY_T_FLASHBACK; ;} break; - case 81: + case 82: { result->cur_stmt_type_ = OBPROXY_T_COMMENT; ;} break; - case 82: + case 83: { result->cur_stmt_type_ = OBPROXY_T_AUDIT; ;} break; - case 83: + case 84: { result->cur_stmt_type_ = OBPROXY_T_NOAUDIT; ;} break; - case 86: + case 87: {;} break; - case 87: + case 88: {;} break; - case 88: + case 89: {;} break; - case 93: + case 94: { result->cur_stmt_type_ = OBPROXY_T_SELECT_TX_RO; ;} break; - case 97: + case 98: { result->col_name_ = (yyvsp[(3) - (3)].str); ;} break; - case 98: + case 99: - { result->cur_stmt_type_ = OBPROXY_T_SET_AC_0; ;} + {;} break; case 100: @@ -3217,17 +3180,17 @@ YYLTYPE yylloc; case 107: - {;} + { result->sub_stmt_type_ = OBPROXY_T_SUB_SELECT_DATABASE; ;} break; case 108: - { result->sub_stmt_type_ = OBPROXY_T_SUB_SELECT_DATABASE; ;} + { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_DATABASES; ;} break; case 109: - { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_DATABASES; ;} + {;} break; case 110: @@ -3247,23 +3210,19 @@ YYLTYPE yylloc; case 113: - {;} - break; - - case 114: - { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_CREATE_TABLE; ;} break; - case 115: + case 114: { + result->table_info_.table_name_ = (yyvsp[(2) - (2)].str); result->cur_stmt_type_ = OBPROXY_T_DESC; result->sub_stmt_type_ = OBPROXY_T_SUB_DESC_TABLE; ;} break; - case 116: + case 115: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_COLUMNS; @@ -3271,7 +3230,7 @@ YYLTYPE yylloc; ;} break; - case 117: + case 116: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_COLUMNS; @@ -3280,7 +3239,7 @@ YYLTYPE yylloc; ;} break; - case 118: + case 117: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_INDEX; @@ -3288,7 +3247,7 @@ YYLTYPE yylloc; ;} break; - case 119: + case 118: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_INDEX; @@ -3297,98 +3256,106 @@ YYLTYPE yylloc; ;} break; - case 120: + case 119: {;} break; - case 121: + case 120: { result->table_info_.table_name_ = (yyvsp[(2) - (2)].str); ;} break; - case 122: + case 121: {;} break; - case 123: + case 122: { result->table_info_.database_name_ = (yyvsp[(2) - (2)].str); ;} break; - case 124: + case 123: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TABLES; ;} break; - case 125: + case 124: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_FULL_TABLES; ;} break; - case 126: + case 125: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TABLE_STATUS; ;} break; - case 127: + case 126: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_DB_VERSION; ;} break; - case 128: + case 127: - { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; ;} + { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; ;} break; - case 129: + case 128: { SET_ICMD_ONE_STRING((yyvsp[(3) - (3)].str)); - result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; + result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; ;} break; - case 130: + case 129: { SET_ICMD_SECOND_STRING((yyvsp[(5) - (5)].str)); - result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; + result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; ;} break; - case 131: + case 130: { SET_ICMD_ONE_STRING((yyvsp[(3) - (7)].str)); SET_ICMD_SECOND_STRING((yyvsp[(7) - (7)].str)); - result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; + result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; ;} break; + case 131: + + { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; ;} + break; + case 132: - { result->cur_stmt_type_ = OBPROXY_T_SELECT_ROUTE_ADDR; ;} + { + result->table_info_.table_name_ = (yyvsp[(3) - (3)].str); + result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; + ;} break; case 133: - { - result->cur_stmt_type_ = OBPROXY_T_SET_ROUTE_ADDR; - result->cmd_info_.integer_[0] = (yyvsp[(3) - (3)].num); - ;} + { result->cur_stmt_type_ = OBPROXY_T_SELECT_ROUTE_ADDR; ;} break; case 134: - {;} + { + result->cur_stmt_type_ = OBPROXY_T_SET_ROUTE_ADDR; + result->cmd_info_.integer_[0] = (yyvsp[(3) - (3)].num); + ;} break; case 135: @@ -3416,14 +3383,19 @@ YYLTYPE yylloc; {;} break; - case 141: + case 140: + + {;} + break; + + case 142: { result->table_info_.table_name_ = (yyvsp[(1) - (1)].str); ;} break; - case 142: + case 143: { result->table_info_.package_name_ = (yyvsp[(1) - (3)].str); @@ -3431,7 +3403,7 @@ YYLTYPE yylloc; ;} break; - case 143: + case 144: { result->table_info_.database_name_ = (yyvsp[(1) - (5)].str); @@ -3440,14 +3412,14 @@ YYLTYPE yylloc; ;} break; - case 144: + case 145: { result->call_parse_info_.node_count_ = 0; ;} break; - case 145: + case 146: { result->call_parse_info_.node_count_ = 0; @@ -3455,14 +3427,14 @@ YYLTYPE yylloc; ;} break; - case 146: + case 147: { add_call_node(result->call_parse_info_, (yyvsp[(3) - (3)].node)); ;} break; - case 147: + case 148: { malloc_call_node((yyval.node), CALL_TOKEN_STR_VAL); @@ -3470,7 +3442,7 @@ YYLTYPE yylloc; ;} break; - case 148: + case 149: { malloc_call_node((yyval.node), CALL_TOKEN_INT_VAL); @@ -3478,7 +3450,7 @@ YYLTYPE yylloc; ;} break; - case 149: + case 150: { malloc_call_node((yyval.node), CALL_TOKEN_NUMBER_VAL); @@ -3486,7 +3458,7 @@ YYLTYPE yylloc; ;} break; - case 150: + case 151: { malloc_call_node((yyval.node), CALL_TOKEN_USER_VAR); @@ -3494,7 +3466,7 @@ YYLTYPE yylloc; ;} break; - case 151: + case 152: { malloc_call_node((yyval.node), CALL_TOKEN_SYS_VAR); @@ -3502,7 +3474,7 @@ YYLTYPE yylloc; ;} break; - case 152: + case 153: { result->placeholder_list_idx_++; @@ -3511,7 +3483,7 @@ YYLTYPE yylloc; ;} break; - case 166: + case 167: { handle_stmt_end(result); @@ -3519,7 +3491,7 @@ YYLTYPE yylloc; ;} break; - case 171: + case 172: { handle_stmt_end(result); @@ -3527,56 +3499,56 @@ YYLTYPE yylloc; ;} break; - case 175: + case 176: { add_set_var_node(result->set_parse_info_, (yyvsp[(4) - (4)].var_node), (yyvsp[(2) - (4)].str), SET_VAR_USER); ;} break; - case 176: + case 177: { add_set_var_node(result->set_parse_info_, (yyvsp[(6) - (6)].var_node), (yyvsp[(4) - (6)].str), SET_VAR_SYS); ;} break; - case 177: + case 178: { add_set_var_node(result->set_parse_info_, (yyvsp[(4) - (4)].var_node), (yyvsp[(2) - (4)].str), SET_VAR_SYS); ;} break; - case 178: + case 179: { add_set_var_node(result->set_parse_info_, (yyvsp[(5) - (5)].var_node), (yyvsp[(3) - (5)].str), SET_VAR_SYS); ;} break; - case 179: + case 180: { add_set_var_node(result->set_parse_info_, (yyvsp[(6) - (6)].var_node), (yyvsp[(4) - (6)].str), SET_VAR_SYS); ;} break; - case 180: + case 181: { add_set_var_node(result->set_parse_info_, (yyvsp[(4) - (4)].var_node), (yyvsp[(2) - (4)].str), SET_VAR_SYS); ;} break; - case 181: + case 182: { add_set_var_node(result->set_parse_info_, (yyvsp[(3) - (3)].var_node), (yyvsp[(1) - (3)].str), SET_VAR_SYS); ;} break; - case 182: + case 183: { malloc_set_var_node((yyval.var_node), SET_VALUE_TYPE_STR); @@ -3584,7 +3556,7 @@ YYLTYPE yylloc; ;} break; - case 183: + case 184: { malloc_set_var_node((yyval.var_node), SET_VALUE_TYPE_INT); @@ -3592,7 +3564,7 @@ YYLTYPE yylloc; ;} break; - case 184: + case 185: { malloc_set_var_node((yyval.var_node), SET_VALUE_TYPE_NUMBER); @@ -3600,42 +3572,42 @@ YYLTYPE yylloc; ;} break; - case 187: + case 188: {;} break; - case 188: + case 189: {;} break; - case 189: + case 190: { result->dbmesh_route_info_.tb_idx_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 190: + case 191: { result->dbmesh_route_info_.table_name_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 191: + case 192: { result->dbmesh_route_info_.group_idx_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 192: + case 193: { result->dbmesh_route_info_.es_idx_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 193: + case 194: { result->dbmesh_route_info_.testload_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 194: + case 195: { malloc_shard_column_node((yyval.shard_node), (yyvsp[(2) - (7)].str), (yyvsp[(3) - (7)].str), DBMESH_TOKEN_STR_VAL); @@ -3644,52 +3616,57 @@ YYLTYPE yylloc; ;} break; - case 195: + case 196: { result->trace_id_ = (yyvsp[(4) - (6)].str); ;} break; - case 196: + case 197: { result->rpc_id_ = (yyvsp[(4) - (6)].str); ;} break; - case 197: + case 198: { result->dbmesh_route_info_.tnt_id_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 198: + case 199: { result->dbmesh_route_info_.disaster_status_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 199: + case 200: {;} break; - case 200: + case 201: {;} break; - case 201: + case 202: - {;} + { result->target_db_server_ = (yyvsp[(4) - (6)].str); ;} break; case 203: + {;} + break; + + case 205: + { result->has_simple_route_info_ = true; result->simple_route_info_.table_name_ = (yyvsp[(2) - (2)].str); ;} break; - case 204: + case 206: { result->simple_route_info_.part_key_ = (yyvsp[(2) - (2)].str); ;} break; - case 208: + case 210: { result->dbp_route_info_.has_group_info_ = true; @@ -3697,7 +3674,7 @@ YYLTYPE yylloc; ;} break; - case 209: + case 211: { result->dbp_route_info_.has_group_info_ = true; @@ -3705,37 +3682,42 @@ YYLTYPE yylloc; ;} break; - case 210: + case 212: { result->dbp_route_info_.scan_all_ = true; ;} break; - case 211: + case 213: { result->dbp_route_info_.scan_all_ = true; ;} break; - case 212: + case 214: + + { result->dbp_route_info_.sticky_session_ = true; ;} + break; + + case 215: {result->dbp_route_info_.has_shard_key_ = true;;} break; - case 213: + case 216: { result->trace_id_ = (yyvsp[(3) - (4)].str); ;} break; - case 214: + case 217: { result->trace_id_ = (yyvsp[(3) - (6)].str); result->rpc_id_ = (yyvsp[(5) - (6)].str); ;} break; - case 215: + case 218: {;} break; - case 217: + case 220: { if (result->dbp_route_info_.shard_key_count_ < OBPROXY_MAX_DBP_SHARD_KEY_NUM) { @@ -3746,52 +3728,57 @@ YYLTYPE yylloc; ;} break; - case 220: + case 223: { result->dbmesh_route_info_.group_idx_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 221: + case 224: { result->dbmesh_route_info_.tb_idx_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 222: + case 225: { result->dbmesh_route_info_.table_name_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 223: + case 226: { result->dbmesh_route_info_.es_idx_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 224: + case 227: { result->dbmesh_route_info_.testload_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 225: + case 228: { result->trace_id_ = (yyvsp[(3) - (3)].str); ;} break; - case 226: + case 229: { result->rpc_id_ = (yyvsp[(3) - (3)].str); ;} break; - case 227: + case 230: { result->dbmesh_route_info_.tnt_id_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 228: + case 231: { result->dbmesh_route_info_.disaster_status_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 229: + case 232: + + { result->target_db_server_ = (yyvsp[(3) - (3)].str); ;} + break; + + case 233: { malloc_shard_column_node((yyval.shard_node), (yyvsp[(1) - (5)].str), (yyvsp[(3) - (5)].str), DBMESH_TOKEN_STR_VAL); @@ -3800,32 +3787,32 @@ YYLTYPE yylloc; ;} break; - case 230: + case 234: {;} break; - case 231: + case 235: { (yyval.str).str_ = NULL; (yyval.str).str_len_ = 0; ;} break; - case 233: + case 237: { (yyval.str).str_ = NULL; (yyval.str).str_len_ = 0; ;} break; - case 255: + case 259: { result->query_timeout_ = (yyvsp[(3) - (4)].num); ;} break; - case 256: + case 260: {;} break; - case 258: + case 262: { add_hint_index(result->dbmesh_route_info_, (yyvsp[(3) - (5)].str)); @@ -3833,75 +3820,105 @@ YYLTYPE yylloc; ;} break; - case 259: + case 263: {;} break; - case 260: + case 264: {;} break; - case 261: + case 265: {;} break; - case 262: + case 266: {;} break; - case 263: + case 267: {;} break; - case 264: + case 268: { SET_READ_CONSISTENCY(OBPROXY_READ_CONSISTENCY_WEAK); ;} break; - case 265: + case 269: { SET_READ_CONSISTENCY(OBPROXY_READ_CONSISTENCY_STRONG); ;} break; - case 266: + case 270: { SET_READ_CONSISTENCY(OBPROXY_READ_CONSISTENCY_FROZEN); ;} break; - case 269: + case 273: { result->cur_stmt_type_ = OBPROXY_T_SHOW_WARNINGS; ;} break; - case 270: + case 274: { result->cur_stmt_type_ = OBPROXY_T_SHOW_ERRORS; ;} break; - case 271: + case 275: { result->cur_stmt_type_ = OBPROXY_T_SHOW_TRACE; ;} break; - case 295: + case 299: + + {;} + break; + + case 300: + + {;} + break; + + case 301: + + {;} + break; + + case 302: + + {;} + break; + + case 303: + + {;} + break; + + case 304: + + {;} + break; + + case 305: { ;} break; - case 296: + case 306: { result->cmd_info_.integer_[2] = (yyvsp[(2) - (2)].num);/*row*/ ;} break; - case 297: + case 307: { result->cmd_info_.integer_[1] = (yyvsp[(2) - (4)].num);/*offset*/ @@ -3909,7 +3926,7 @@ YYLTYPE yylloc; ;} break; - case 298: + case 308: { result->cmd_info_.integer_[1] = (yyvsp[(4) - (4)].num);/*offset*/ @@ -3917,342 +3934,342 @@ YYLTYPE yylloc; ;} break; - case 299: + case 309: {;} break; - case 300: + case 310: { result->cmd_info_.string_[0] = (yyvsp[(2) - (2)].str);;} break; - case 301: + case 311: {;} break; - case 302: + case 312: { result->cmd_info_.string_[1] = (yyvsp[(2) - (2)].str);;} break; - case 304: + case 314: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_NET_THREAD); ;} break; - case 305: + case 315: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_NET_CONNECTION); ;} break; - case 306: + case 316: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_NET_CONNECTION, (yyvsp[(2) - (3)].num)); ;} break; - case 307: + case 317: {;} break; - case 308: + case 318: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_CONFIG_DIFF); ;} break; - case 309: + case 319: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_CONFIG_DIFF_USER); ;} break; - case 310: + case 320: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_LIST); ;} break; - case 312: + case 322: {SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_GLOBAL_SESSION_LIST);;} break; - case 313: + case 323: {SET_ICMD_SUB_AND_ONE_STRING(OBPROXY_T_SUB_GLOBAL_SESSION_LIST_INFO, (yyvsp[(2) - (2)].str));;} break; - case 314: + case 324: {SET_ICMD_SUB_AND_ONE_STRING(OBPROXY_T_SUB_GLOBAL_SESSION_LIST_LIKE, (yyvsp[(3) - (3)].str));;} break; - case 315: + case 325: {SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_GLOBAL_SESSION_LIST_INFO_ALL);;} break; - case 316: + case 326: {result->cmd_info_.string_[0] = (yyvsp[(2) - (2)].str);;} break; - case 318: + case 328: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_LIST_INTERNAL); ;} break; - case 319: + case 329: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_ATTRIBUTE); ;} break; - case 320: + case 330: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_SESSION_ATTRIBUTE, (yyvsp[(2) - (3)].num)); ;} break; - case 321: + case 331: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_STAT); ;} break; - case 322: + case 332: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_SESSION_STAT, (yyvsp[(2) - (3)].num)); ;} break; - case 323: + case 333: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_VARIABLES_LOCAL); ;} break; - case 324: + case 334: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_SESSION_VARIABLES_LOCAL, (yyvsp[(2) - (3)].num)); ;} break; - case 325: + case 335: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_VARIABLES_ALL); ;} break; - case 326: + case 336: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_SESSION_VARIABLES_ALL, (yyvsp[(3) - (4)].num)); ;} break; - case 327: + case 337: {;} break; - case 328: + case 338: { SET_ICMD_ONE_ID((yyvsp[(2) - (2)].num)); ;} break; - case 329: + case 339: {;} break; - case 330: + case 340: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_INFO_IDC); ;} break; - case 331: + case 341: {;} break; - case 333: + case 343: {;} break; - case 334: + case 344: { SET_ICMD_ONE_STRING((yyvsp[(1) - (1)].str)); ;} break; - case 335: + case 345: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_CONGEST_ALL);;} break; - case 336: + case 346: { SET_ICMD_SUB_AND_ONE_STRING(OBPROXY_T_SUB_CONGEST_ALL, (yyvsp[(2) - (2)].str));;} break; - case 337: + case 347: {;} break; - case 338: + case 348: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_ROUTE_ROUTINE); ;} break; - case 339: + case 349: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_ROUTE_PARTITION); ;} break; - case 340: + case 350: {;} break; - case 341: + case 351: { SET_ICMD_ONE_STRING((yyvsp[(2) - (2)].str)); ;} break; - case 342: + case 352: {;} break; - case 343: + case 353: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_MEMORY_OBJPOOL); ;} break; - case 344: + case 354: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SQLAUDIT_AUDIT_ID); ;} break; - case 345: + case 355: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_SQLAUDIT_SM_ID, (yyvsp[(2) - (2)].num)); ;} break; - case 347: + case 357: {;} break; - case 348: + case 358: { SET_ICMD_SECOND_ID((yyvsp[(1) - (1)].num)); ;} break; - case 349: + case 359: { SET_ICMD_TWO_ID((yyvsp[(3) - (3)].num), (yyvsp[(1) - (3)].num)); ;} break; - case 350: + case 360: { SET_ICMD_TWO_ID((yyvsp[(3) - (5)].num), (yyvsp[(1) - (5)].num)); SET_ICMD_ONE_STRING((yyvsp[(5) - (5)].str)); ;} break; - case 351: + case 361: {;} break; - case 352: + case 362: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_STAT_REFRESH); ;} break; - case 354: + case 364: {;} break; - case 355: + case 365: { SET_ICMD_ONE_ID((yyvsp[(1) - (1)].num)); ;} break; - case 356: + case 366: { SET_ICMD_SUB_AND_TWO_ID(OBPROXY_T_SUB_TRACE_LIMIT, (yyvsp[(1) - (2)].num),(yyvsp[(2) - (2)].num)); ;} break; - case 357: + case 367: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_INFO_BINARY); ;} break; - case 358: + case 368: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_INFO_UPGRADE); ;} break; - case 359: + case 369: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_INFO_IDC); ;} break; - case 360: + case 370: { SET_ICMD_ONE_STRING((yyvsp[(3) - (4)].str)); ;} break; - case 361: + case 371: { SET_ICMD_TWO_STRING((yyvsp[(3) - (5)].str), (yyvsp[(5) - (5)].str)); ;} break; - case 362: + case 372: { SET_ICMD_CONFIG_INT_VALUE((yyvsp[(3) - (5)].str), (yyvsp[(5) - (5)].num)); ;} break; - case 363: + case 373: { SET_ICMD_ONE_STRING((yyvsp[(3) - (3)].str)); ;} break; - case 364: + case 374: {;} break; - case 365: + case 375: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_KILL_CS, (yyvsp[(2) - (2)].num)); ;} break; - case 366: + case 376: { SET_ICMD_SUB_AND_TWO_ID(OBPROXY_T_SUB_KILL_SS, (yyvsp[(2) - (3)].num), (yyvsp[(3) - (3)].num)); ;} break; - case 367: + case 377: {SET_ICMD_TYPE_STRING_INT_VALUE(OBPROXY_T_SUB_KILL_GLOBAL_SS_ID, (yyvsp[(2) - (3)].str),(yyvsp[(3) - (3)].num));;} break; - case 368: + case 378: {SET_ICMD_SUB_AND_ONE_STRING(OBPROXY_T_SUB_KILL_GLOBAL_SS_DBKEY, (yyvsp[(2) - (2)].str));;} break; - case 369: + case 379: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_KILL_CONNECTION, (yyvsp[(2) - (2)].num)); ;} break; - case 370: + case 380: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_KILL_CONNECTION, (yyvsp[(3) - (3)].num)); ;} break; - case 371: + case 381: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_KILL_QUERY, (yyvsp[(3) - (3)].num)); ;} break; - case 374: + case 384: { result->has_anonymous_block_ = false ; @@ -4260,22 +4277,22 @@ YYLTYPE yylloc; ;} break; - case 375: + case 385: { result->cur_stmt_type_ = OBPROXY_T_BEGIN; ;} break; - case 376: + case 386: { result->cur_stmt_type_ = OBPROXY_T_BEGIN; ;} break; - case 377: + case 387: { result->cur_stmt_type_ = OBPROXY_T_BEGIN; ;} break; - case 384: + case 394: { result->cur_stmt_type_ = OBPROXY_T_USE_DB; @@ -4283,27 +4300,27 @@ YYLTYPE yylloc; ;} break; - case 385: + case 395: { result->cur_stmt_type_ = OBPROXY_T_HELP; ;} break; - case 387: + case 397: {;} break; - case 388: + case 398: { result->part_name_ = (yyvsp[(2) - (2)].str); ;} break; - case 389: + case 399: { result->part_name_ = (yyvsp[(3) - (4)].str); ;} break; - case 390: + case 400: { handle_stmt_end(result); @@ -4311,14 +4328,14 @@ YYLTYPE yylloc; ;} break; - case 391: + case 401: { result->table_info_.table_name_ = (yyvsp[(1) - (1)].str); ;} break; - case 392: + case 402: { result->table_info_.database_name_ = (yyvsp[(1) - (3)].str); @@ -4326,7 +4343,7 @@ YYLTYPE yylloc; ;} break; - case 393: + case 403: { UPDATE_ALIAS_NAME((yyvsp[(2) - (2)].str)); @@ -4334,7 +4351,7 @@ YYLTYPE yylloc; ;} break; - case 394: + case 404: { UPDATE_ALIAS_NAME((yyvsp[(4) - (4)].str)); @@ -4343,7 +4360,7 @@ YYLTYPE yylloc; ;} break; - case 395: + case 405: { UPDATE_ALIAS_NAME((yyvsp[(3) - (3)].str)); @@ -4351,7 +4368,7 @@ YYLTYPE yylloc; ;} break; - case 396: + case 406: { UPDATE_ALIAS_NAME((yyvsp[(5) - (5)].str)); diff --git a/src/obproxy/opsql/parser/ob_proxy_parser_gbk_tab.h b/src/obproxy/opsql/parser/ob_proxy_parser_gbk_tab.h index df8485c14..6ecd470af 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parser_gbk_tab.h +++ b/src/obproxy/opsql/parser/ob_proxy_parser_gbk_tab.h @@ -134,96 +134,104 @@ extern int ob_proxy_parser_gbk_yydebug; UNION = 333, FOR = 334, TX_READ_ONLY = 335, - AUTOCOMMIT_0 = 336, - SELECT_OBPROXY_ROUTE_ADDR = 337, - SET_OBPROXY_ROUTE_ADDR = 338, - NAME_OB_DOT = 339, - NAME_OB = 340, - EXPLAIN = 341, - DESC = 342, - DESCRIBE = 343, - NAME_STR = 344, - USE = 345, - HELP = 346, - SET_NAMES = 347, - SET_CHARSET = 348, - SET_PASSWORD = 349, - SET_DEFAULT = 350, - SET_OB_READ_CONSISTENCY = 351, - SET_TX_READ_ONLY = 352, - GLOBAL = 353, - SESSION = 354, - NUMBER_VAL = 355, - GROUP_ID = 356, - TABLE_ID = 357, - ELASTIC_ID = 358, - TESTLOAD = 359, - ODP_COMMENT = 360, - TNT_ID = 361, - DISASTER_STATUS = 362, - TRACE_ID = 363, - RPC_ID = 364, + SELECT_OBPROXY_ROUTE_ADDR = 336, + SET_OBPROXY_ROUTE_ADDR = 337, + NAME_OB_DOT = 338, + NAME_OB = 339, + EXPLAIN = 340, + DESC = 341, + DESCRIBE = 342, + NAME_STR = 343, + USE = 344, + HELP = 345, + SET_NAMES = 346, + SET_CHARSET = 347, + SET_PASSWORD = 348, + SET_DEFAULT = 349, + SET_OB_READ_CONSISTENCY = 350, + SET_TX_READ_ONLY = 351, + GLOBAL = 352, + SESSION = 353, + NUMBER_VAL = 354, + GROUP_ID = 355, + TABLE_ID = 356, + ELASTIC_ID = 357, + TESTLOAD = 358, + ODP_COMMENT = 359, + TNT_ID = 360, + DISASTER_STATUS = 361, + TRACE_ID = 362, + RPC_ID = 363, + TARGET_DB_SERVER = 364, DBP_COMMENT = 365, ROUTE_TAG = 366, SYS_TAG = 367, TABLE_NAME = 368, SCAN_ALL = 369, - PARALL = 370, - SHARD_KEY = 371, - INT_NUM = 372, - SHOW_PROXYNET = 373, - THREAD = 374, - CONNECTION = 375, - LIMIT = 376, - OFFSET = 377, - SHOW_PROCESSLIST = 378, - SHOW_PROXYSESSION = 379, - SHOW_GLOBALSESSION = 380, - ATTRIBUTE = 381, - VARIABLES = 382, - ALL = 383, - STAT = 384, - SHOW_PROXYCONFIG = 385, - DIFF = 386, - USER = 387, - LIKE = 388, - SHOW_PROXYSM = 389, - SHOW_PROXYCLUSTER = 390, - SHOW_PROXYRESOURCE = 391, - SHOW_PROXYCONGESTION = 392, - SHOW_PROXYROUTE = 393, - PARTITION = 394, - ROUTINE = 395, - SHOW_PROXYVIP = 396, - SHOW_PROXYMEMORY = 397, - OBJPOOL = 398, - SHOW_SQLAUDIT = 399, - SHOW_WARNLOG = 400, - SHOW_PROXYSTAT = 401, - REFRESH = 402, - SHOW_PROXYTRACE = 403, - SHOW_PROXYINFO = 404, - BINARY = 405, - UPGRADE = 406, - IDC = 407, - SHOW_TOPOLOGY = 408, - GROUP_NAME = 409, - SHOW_DB_VERSION = 410, - SHOW_DATABASES = 411, - SHOW_TABLES = 412, - SHOW_FULL_TABLES = 413, - SELECT_DATABASE = 414, - SHOW_CREATE_TABLE = 415, - SELECT_PROXY_VERSION = 416, - SHOW_COLUMNS = 417, - SHOW_INDEX = 418, - ALTER_PROXYCONFIG = 419, - ALTER_PROXYRESOURCE = 420, - PING_PROXY = 421, - KILL_PROXYSESSION = 422, - KILL_GLOBALSESSION = 423, - KILL = 424, - QUERY = 425 + STICKY_SESSION = 370, + PARALL = 371, + SHARD_KEY = 372, + INT_NUM = 373, + SHOW_PROXYNET = 374, + THREAD = 375, + CONNECTION = 376, + LIMIT = 377, + OFFSET = 378, + SHOW_PROCESSLIST = 379, + SHOW_PROXYSESSION = 380, + SHOW_GLOBALSESSION = 381, + ATTRIBUTE = 382, + VARIABLES = 383, + ALL = 384, + STAT = 385, + SHOW_PROXYCONFIG = 386, + DIFF = 387, + USER = 388, + LIKE = 389, + SHOW_PROXYSM = 390, + SHOW_PROXYCLUSTER = 391, + SHOW_PROXYRESOURCE = 392, + SHOW_PROXYCONGESTION = 393, + SHOW_PROXYROUTE = 394, + PARTITION = 395, + ROUTINE = 396, + SHOW_PROXYVIP = 397, + SHOW_PROXYMEMORY = 398, + OBJPOOL = 399, + SHOW_SQLAUDIT = 400, + SHOW_WARNLOG = 401, + SHOW_PROXYSTAT = 402, + REFRESH = 403, + SHOW_PROXYTRACE = 404, + SHOW_PROXYINFO = 405, + BINARY = 406, + UPGRADE = 407, + IDC = 408, + SHOW_ELASTIC_ID = 409, + SHOW_TOPOLOGY = 410, + GROUP_NAME = 411, + SHOW_DB_VERSION = 412, + SHOW_DATABASES = 413, + SHOW_TABLES = 414, + SHOW_FULL_TABLES = 415, + SELECT_DATABASE = 416, + SHOW_CREATE_TABLE = 417, + SELECT_PROXY_VERSION = 418, + SHOW_COLUMNS = 419, + SHOW_INDEX = 420, + ALTER_PROXYCONFIG = 421, + ALTER_PROXYRESOURCE = 422, + PING_PROXY = 423, + KILL_PROXYSESSION = 424, + KILL_GLOBALSESSION = 425, + KILL = 426, + QUERY = 427, + SHOW_MASTER_STATUS = 428, + SHOW_BINARY_LOGS = 429, + SHOW_BINLOG_EVENTS = 430, + PURGE_BINARY_LOGS = 431, + RESET_MASTER = 432, + SHOW_BINLOG_SERVER_FOR_TENANT = 433 }; #endif diff --git a/src/obproxy/opsql/parser/ob_proxy_parser_utf8_lex.c b/src/obproxy/opsql/parser/ob_proxy_parser_utf8_lex.c index b7c45705e..b220208da 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parser_utf8_lex.c +++ b/src/obproxy/opsql/parser/ob_proxy_parser_utf8_lex.c @@ -348,8 +348,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); yyg->yy_hold_char = *yy_cp; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 336 -#define YY_END_OF_BUFFER 337 +#define YY_NUM_RULES 344 +#define YY_END_OF_BUFFER 345 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -357,294 +357,314 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[2597] = +static yyconst flex_int16_t yy_accept[2787] = { 0, - 146, 146, 189, 189, 0, 0, 0, 0, 202, 202, - 230, 230, 0, 0, 0, 0, 0, 0, 258, 258, + 147, 147, 195, 195, 0, 0, 0, 0, 208, 208, + 238, 238, 0, 0, 0, 0, 0, 0, 267, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 307, 307, 0, 0, - 0, 0, 325, 325, 330, 330, 0, 0, 168, 168, - 0, 0, 0, 0, 0, 0, 337, 335, 156, 156, - 152, 282, 146, 146, 271, 153, 152, 144, 335, 152, - 152, 145, 151, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 288, 335, 335, 335, - - 335, 335, 335, 191, 336, 189, 188, 191, 191, 182, - 189, 189, 189, 189, 189, 189, 191, 191, 191, 191, - 191, 191, 195, 194, 195, 197, 197, 336, 197, 197, - 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, - 197, 197, 197, 197, 197, 197, 207, 207, 202, 207, - 207, 202, 202, 207, 207, 207, 207, 207, 207, 207, - 234, 233, 233, 230, 228, 234, 230, 229, 230, 232, - 231, 230, 230, 230, 230, 230, 234, 234, 240, 239, - 239, 236, 240, 237, 240, 240, 242, 241, 241, 241, - 242, 242, 242, 260, 257, 257, 258, 252, 253, 260, - - 258, 256, 258, 258, 258, 258, 258, 258, 260, 260, - 262, 261, 336, 336, 268, 267, 267, 265, 263, 264, - 268, 268, 268, 270, 269, 269, 269, 270, 270, 270, - 277, 278, 336, 272, 273, 336, 283, 284, 336, 290, - 291, 293, 294, 310, 308, 308, 298, 307, 307, 299, - 297, 310, 309, 310, 307, 307, 307, 307, 307, 300, - 310, 310, 310, 310, 310, 310, 334, 334, 317, 316, - 316, 314, 316, 315, 312, 313, 317, 317, 317, 317, - 327, 326, 326, 320, 325, 325, 321, 318, 319, 327, - 325, 325, 325, 327, 327, 327, 327, 327, 327, 331, - - 330, 332, 329, 330, 336, 336, 336, 336, 336, 336, - 178, 178, 176, 170, 170, 174, 168, 168, 173, 176, - 167, 176, 176, 166, 172, 171, 171, 168, 168, 168, - 175, 176, 176, 176, 176, 176, 176, 117, 115, 115, - 115, 117, 116, 117, 117, 117, 126, 124, 124, 124, - 126, 125, 126, 126, 126, 336, 336, 336, 156, 0, - 148, 0, 0, 0, 0, 0, 0, 0, 156, 146, - 156, 156, 156, 156, 156, 156, 146, 0, 0, 0, - 0, 0, 0, 0, 147, 0, 0, 0, 0, 0, - 0, 145, 0, 150, 192, 150, 145, 146, 146, 146, - - 44, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 8, 0, 149, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 315, 315, 0, 0, + 0, 0, 333, 333, 338, 338, 0, 0, 174, 174, + 0, 0, 0, 0, 0, 0, 0, 0, 345, 343, + 157, 157, 153, 291, 147, 147, 280, 154, 153, 145, + 343, 153, 153, 146, 152, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 297, 343, + + 343, 343, 343, 343, 343, 197, 344, 195, 194, 197, + 197, 188, 195, 195, 195, 195, 195, 195, 197, 197, + 197, 197, 197, 197, 201, 200, 201, 203, 203, 344, + 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, 213, 213, + 208, 213, 213, 208, 208, 213, 213, 213, 213, 213, + 213, 213, 242, 241, 241, 238, 236, 242, 238, 237, + 238, 240, 239, 238, 238, 238, 238, 238, 242, 242, + 248, 247, 247, 244, 248, 245, 248, 248, 250, 249, + 249, 249, 250, 250, 250, 269, 266, 266, 267, 261, + + 262, 269, 267, 265, 267, 267, 267, 267, 267, 267, + 269, 269, 271, 270, 344, 344, 277, 276, 276, 274, + 272, 273, 277, 277, 277, 279, 278, 278, 278, 279, + 279, 279, 286, 287, 344, 281, 282, 344, 292, 293, + 344, 299, 300, 302, 303, 318, 316, 316, 307, 315, + 315, 308, 306, 318, 317, 318, 315, 315, 315, 315, + 309, 318, 318, 318, 318, 318, 318, 342, 342, 325, + 324, 324, 322, 324, 323, 320, 321, 325, 325, 325, + 325, 335, 334, 334, 328, 333, 333, 329, 326, 327, + 335, 333, 333, 333, 335, 335, 335, 335, 335, 335, + + 339, 338, 340, 337, 338, 344, 344, 344, 344, 344, + 344, 184, 184, 182, 176, 176, 180, 174, 174, 179, + 182, 173, 182, 182, 172, 178, 177, 174, 174, 181, + 182, 182, 182, 182, 182, 182, 117, 115, 115, 115, + 117, 116, 117, 117, 117, 127, 125, 125, 125, 127, + 126, 127, 127, 127, 344, 344, 344, 157, 0, 149, + 0, 0, 0, 0, 0, 0, 0, 157, 147, 157, + 157, 157, 157, 157, 157, 147, 0, 0, 0, 0, + 0, 0, 0, 148, 0, 0, 0, 0, 0, 0, + 146, 0, 0, 146, 151, 198, 151, 146, 147, 147, + + 147, 44, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 8, 0, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 189, 0, 0, 0, 0, 0, 0, 0, 190, 182, - 182, 189, 189, 189, 189, 189, 189, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 193, 0, 0, 0, + 0, 195, 0, 0, 0, 0, 0, 0, 0, 196, + 188, 188, 195, 195, 195, 195, 195, 195, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 199, 0, 0, - 217, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 196, 0, 0, 0, 0, + 0, 223, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 204, 0, 0, 0, 0, - 0, 0, 0, 202, 0, 0, 0, 0, 0, 0, - 0, 203, 0, 0, 0, 0, 0, 0, 0, 206, - 202, 202, 0, 205, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 230, 0, - 235, 230, 230, 230, 230, 230, 230, 230, 230, 0, - 0, 0, 238, 0, 0, 0, 241, 0, 0, 258, - - 258, 258, 0, 259, 258, 258, 258, 258, 258, 258, - 0, 0, 0, 0, 0, 266, 0, 0, 0, 269, - 0, 0, 277, 0, 0, 279, 0, 0, 280, 272, - 0, 0, 274, 0, 0, 275, 0, 285, 0, 0, - 0, 286, 290, 289, 293, 292, 308, 0, 308, 307, - 308, 308, 308, 308, 308, 308, 307, 0, 0, 0, - 0, 0, 0, 0, 0, 307, 307, 307, 307, 307, - 307, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 316, 0, 316, 0, 0, 0, 0, 326, 0, 326, - 325, 326, 326, 326, 326, 326, 326, 325, 0, 0, - - 0, 0, 0, 0, 0, 325, 325, 325, 0, 0, - 0, 0, 0, 0, 0, 0, 330, 0, 0, 0, - 0, 0, 0, 330, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 170, 0, 170, 168, 170, 170, 170, - 170, 170, 170, 168, 0, 0, 0, 0, 0, 0, - 166, 0, 169, 169, 166, 168, 0, 168, 168, 168, - 0, 0, 0, 0, 0, 0, 0, 0, 115, 0, - 115, 0, 0, 0, 0, 124, 0, 124, 0, 0, + 0, 0, 0, 0, 0, 0, 210, 0, 0, 0, + 0, 0, 0, 0, 208, 0, 0, 0, 0, 0, + 0, 0, 209, 0, 0, 0, 0, 0, 0, 0, + 212, 208, 208, 0, 211, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 238, + 0, 243, 238, 238, 238, 238, 238, 238, 238, 238, + 0, 0, 0, 246, 0, 0, 0, 249, 0, 0, + + 267, 267, 267, 0, 268, 267, 267, 267, 267, 267, + 267, 267, 0, 0, 0, 0, 0, 275, 0, 0, + 0, 278, 0, 0, 286, 0, 0, 288, 0, 0, + 289, 281, 0, 0, 283, 0, 0, 284, 0, 294, + 0, 0, 0, 295, 299, 298, 302, 301, 316, 0, + 316, 315, 316, 316, 316, 316, 316, 316, 315, 0, + 0, 0, 0, 0, 0, 0, 0, 315, 315, 315, + 315, 315, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 324, 0, 324, 0, 0, 0, 0, 334, 0, + 334, 333, 334, 334, 334, 334, 334, 334, 333, 0, + + 0, 0, 0, 0, 0, 0, 333, 333, 333, 0, + 0, 0, 0, 0, 0, 0, 0, 338, 0, 0, + 0, 0, 0, 0, 338, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 176, 0, 176, 174, 176, 176, + 176, 176, 176, 176, 174, 0, 0, 0, 0, 0, + 0, 172, 0, 0, 172, 175, 175, 172, 174, 174, + 174, 0, 0, 0, 0, 0, 0, 0, 0, 115, + 0, 115, 0, 0, 0, 0, 125, 0, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 156, 156, 156, 156, 156, 156, - - 156, 156, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 156, 0, 0, 150, 0, 0, 146, 55, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 42, 146, 146, 146, 146, 146, 146, 146, 111, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 13, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, - 53, 146, 146, 146, 146, 146, 146, 0, 0, 0, - - 0, 0, 0, 0, 0, 146, 146, 154, 155, 144, - 0, 0, 189, 189, 189, 189, 189, 189, 189, 189, - 179, 180, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 157, 157, 157, 157, 157, + + 157, 157, 157, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 146, 157, 0, 146, 0, 0, 151, + 0, 146, 0, 147, 55, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 42, 147, 147, 147, 147, + 147, 147, 147, 111, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 13, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 53, 147, 147, 147, + + 147, 147, 147, 0, 0, 0, 0, 0, 0, 0, + 0, 147, 147, 155, 156, 145, 0, 0, 188, 188, + 195, 195, 195, 195, 195, 195, 195, 195, 185, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 202, 202, 0, 0, 0, 0, - 0, 0, 0, 0, 202, 202, 0, 230, 230, 230, - 230, 230, 230, 230, 230, 233, 229, 239, 237, 241, - 258, 258, 258, 258, 258, 258, 258, 258, 257, 254, - 255, 256, 262, 261, 267, 264, 269, 281, 0, 281, - - 0, 0, 276, 0, 276, 0, 0, 287, 0, 287, - 0, 0, 0, 308, 308, 308, 308, 308, 308, 308, - 308, 0, 0, 308, 0, 0, 0, 0, 307, 307, - 307, 307, 307, 307, 307, 307, 297, 0, 0, 316, - 0, 0, 312, 313, 0, 326, 326, 326, 326, 326, - 326, 326, 326, 0, 0, 326, 0, 325, 325, 325, - 325, 325, 318, 319, 0, 330, 330, 330, 0, 0, - 0, 170, 170, 170, 170, 170, 170, 170, 170, 0, - 0, 170, 0, 0, 169, 0, 0, 168, 0, 0, - 168, 168, 168, 168, 168, 167, 0, 115, 0, 0, - - 0, 124, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 146, 146, 156, 0, 0, 0, 156, 156, 156, - 0, 0, 150, 0, 150, 150, 146, 146, 146, 146, - 146, 146, 14, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 49, 18, 146, 146, 146, 146, 146, 25, - 146, 146, 146, 74, 146, 146, 146, 146, 61, 137, - 146, 56, 146, 146, 146, 146, 146, 146, 71, 146, - 146, 146, 146, 146, 146, 146, 51, 146, 146, 146, - 146, 146, 146, 146, 146, 0, 0, 7, 146, 146, - 90, 146, 146, 146, 146, 146, 146, 146, 146, 146, - - 146, 146, 146, 146, 16, 146, 52, 0, 0, 0, - 189, 189, 189, 189, 189, 184, 0, 0, 0, 0, - 208, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 202, 202, 0, 0, 0, 230, 230, - 230, 230, 230, 230, 230, 230, 258, 245, 258, 258, - 258, 258, 258, 258, 0, 0, 0, 0, 0, 0, - 307, 307, 308, 308, 308, 308, 0, 0, 0, 0, - 307, 307, 296, 307, 307, 307, 0, 316, 316, 316, - 0, 0, 325, 325, 326, 326, 326, 326, 0, 325, - 325, 325, 328, 177, 168, 168, 170, 170, 170, 170, - - 0, 0, 169, 0, 169, 169, 0, 0, 168, 168, - 168, 115, 115, 115, 0, 113, 0, 124, 124, 124, - 0, 122, 123, 92, 94, 93, 156, 19, 146, 146, - 37, 9, 146, 146, 146, 146, 146, 66, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 31, - 39, 146, 146, 146, 22, 146, 0, 0, 146, 54, - 146, 6, 146, 146, 146, 41, 146, 0, 0, 146, - 34, 138, 65, 146, 146, 146, 146, 146, 146, 146, - 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 146, 10, 146, 23, 146, 69, 146, 146, - - 43, 146, 146, 146, 27, 47, 146, 146, 45, 189, - 187, 189, 189, 189, 243, 0, 0, 0, 0, 0, - 198, 0, 0, 0, 202, 200, 230, 230, 230, 230, - 230, 230, 230, 230, 258, 258, 258, 258, 258, 258, - 251, 0, 0, 281, 0, 0, 0, 0, 276, 0, - 0, 0, 0, 287, 0, 0, 308, 0, 0, 0, - 307, 307, 0, 307, 0, 0, 307, 307, 307, 333, - 316, 0, 326, 325, 325, 325, 170, 0, 0, 168, - 168, 168, 115, 114, 124, 0, 0, 146, 146, 58, - 146, 11, 146, 146, 17, 146, 146, 146, 2, 146, - - 68, 146, 146, 146, 146, 146, 40, 146, 60, 3, - 0, 0, 0, 0, 146, 146, 0, 0, 0, 146, - 146, 84, 146, 0, 0, 0, 146, 146, 21, 146, - 32, 146, 146, 146, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 146, 24, 82, - 146, 146, 26, 4, 146, 46, 146, 146, 186, 189, - 189, 185, 0, 0, 0, 0, 218, 0, 0, 215, - 0, 202, 230, 230, 230, 227, 230, 230, 225, 230, - 244, 258, 258, 258, 258, 258, 0, 0, 0, 0, - - 0, 0, 307, 307, 0, 0, 0, 0, 0, 307, - 307, 0, 307, 0, 0, 0, 0, 0, 0, 0, - 0, 304, 307, 307, 311, 325, 325, 325, 0, 0, - 168, 164, 168, 0, 0, 0, 33, 146, 35, 146, - 146, 146, 15, 63, 0, 0, 0, 146, 29, 48, - 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, - 146, 146, 0, 0, 0, 38, 103, 146, 0, 0, - 28, 107, 5, 146, 100, 146, 0, 0, 0, 0, + 0, 0, 0, 208, 208, 0, 0, 0, 0, 0, + 0, 0, 0, 208, 208, 0, 238, 238, 238, 238, + 238, 238, 238, 238, 238, 241, 237, 247, 245, 249, + 267, 267, 267, 267, 267, 267, 267, 267, 267, 266, + + 263, 264, 265, 271, 270, 276, 273, 278, 290, 0, + 290, 0, 0, 285, 0, 285, 0, 0, 296, 0, + 296, 0, 0, 0, 316, 316, 316, 316, 316, 316, + 316, 316, 0, 0, 316, 0, 0, 0, 315, 315, + 315, 315, 315, 315, 315, 306, 0, 0, 324, 0, + 0, 320, 321, 0, 334, 334, 334, 334, 334, 334, + 334, 334, 0, 0, 334, 0, 333, 333, 333, 333, + 333, 326, 327, 0, 338, 338, 338, 0, 0, 0, + 176, 176, 176, 176, 176, 176, 176, 176, 0, 0, + 172, 176, 0, 172, 0, 0, 175, 0, 172, 0, + + 174, 174, 174, 174, 174, 173, 0, 115, 0, 0, + 0, 125, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 147, 147, 157, 0, 0, 0, 146, 157, 157, + 157, 0, 146, 151, 0, 151, 0, 151, 146, 147, + 147, 147, 147, 147, 147, 14, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 49, 18, 147, 147, 147, + 147, 147, 25, 147, 147, 147, 74, 147, 147, 147, + 147, 61, 138, 147, 56, 147, 147, 147, 147, 147, + 147, 71, 147, 147, 147, 147, 147, 147, 147, 51, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 0, + + 0, 7, 147, 147, 90, 147, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 16, 147, + 52, 0, 0, 0, 188, 188, 195, 195, 195, 195, + 195, 190, 0, 0, 0, 0, 214, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 208, 208, 0, 0, 0, 238, 238, 238, 238, 238, + 238, 238, 238, 238, 267, 253, 267, 267, 267, 267, + 267, 267, 267, 0, 0, 0, 0, 0, 0, 315, + 315, 316, 316, 316, 316, 0, 0, 0, 315, 305, + 315, 315, 315, 0, 324, 324, 324, 0, 0, 333, + + 333, 334, 334, 334, 334, 0, 333, 333, 333, 336, + 183, 174, 174, 176, 172, 176, 176, 176, 0, 172, + 175, 0, 175, 0, 175, 172, 174, 174, 115, 115, + 115, 0, 113, 0, 125, 125, 125, 0, 123, 124, + 92, 94, 93, 146, 157, 146, 146, 19, 147, 147, + 37, 9, 147, 147, 147, 147, 147, 66, 147, 147, + 147, 147, 147, 147, 147, 147, 147, 147, 147, 31, + 39, 147, 147, 147, 22, 147, 0, 0, 147, 54, + 147, 6, 147, 147, 147, 41, 147, 0, 0, 147, + 34, 139, 65, 147, 147, 147, 147, 147, 147, 147, + + 147, 147, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 147, 10, 147, 23, 147, 69, 147, + 147, 43, 147, 147, 147, 27, 47, 147, 147, 45, + 188, 188, 195, 193, 195, 195, 195, 251, 0, 0, + 0, 0, 0, 204, 0, 0, 0, 0, 208, 206, + 238, 238, 238, 238, 238, 238, 238, 238, 238, 267, + 267, 267, 267, 267, 267, 267, 260, 0, 0, 290, + 0, 0, 0, 0, 285, 0, 0, 0, 0, 296, + 0, 0, 316, 0, 0, 315, 0, 315, 0, 0, + 315, 315, 315, 341, 324, 0, 334, 333, 333, 333, + + 172, 176, 172, 172, 174, 174, 115, 114, 125, 146, + 146, 146, 0, 0, 147, 147, 58, 147, 11, 147, + 147, 17, 147, 147, 147, 2, 147, 68, 147, 147, + 147, 147, 147, 40, 147, 60, 3, 0, 0, 0, + 0, 147, 147, 0, 0, 0, 147, 147, 84, 147, + 0, 0, 0, 147, 0, 0, 147, 21, 147, 0, + 0, 32, 147, 147, 147, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 146, 146, 146, 0, 0, 0, 110, - 146, 146, 189, 189, 0, 0, 0, 0, 0, 0, - 0, 0, 202, 230, 230, 230, 230, 230, 230, 230, - 258, 258, 258, 258, 258, 0, 0, 0, 307, 307, - 0, 0, 0, 0, 0, 0, 307, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 307, 307, 325, - 325, 325, 0, 0, 168, 165, 0, 0, 146, 146, - 146, 146, 0, 0, 0, 50, 146, 146, 146, 146, - 0, 0, 0, 0, 0, 146, 146, 0, 0, 0, - 162, 146, 0, 0, 0, 0, 12, 146, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 147, 24, 82, 147, 147, 26, 4, 147, 46, 147, + + 147, 188, 188, 192, 195, 195, 191, 0, 0, 0, + 0, 224, 0, 0, 0, 221, 0, 208, 238, 238, + 238, 234, 238, 238, 238, 232, 238, 252, 267, 267, + 267, 267, 267, 267, 0, 0, 0, 0, 0, 315, + 0, 0, 0, 0, 0, 315, 315, 0, 315, 0, + 0, 0, 0, 0, 0, 0, 0, 313, 315, 315, + 319, 333, 333, 333, 172, 172, 172, 170, 174, 146, + 146, 146, 0, 0, 0, 33, 147, 35, 147, 147, + 147, 15, 63, 0, 0, 0, 147, 29, 48, 147, + 147, 147, 147, 0, 0, 0, 0, 0, 0, 147, + + 147, 0, 0, 0, 38, 103, 147, 0, 0, 28, + 0, 0, 0, 107, 5, 0, 0, 0, 147, 100, + 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 73, 146, 20, - 0, 0, 0, 146, 67, 189, 189, 0, 0, 209, - 199, 210, 0, 213, 216, 201, 230, 230, 219, 220, - 230, 223, 226, 250, 258, 246, 258, 258, 0, 0, - 0, 307, 307, 0, 0, 0, 0, 0, 0, 307, - 307, 307, 0, 0, 0, 0, 0, 0, 0, 0, - 307, 307, 325, 325, 325, 0, 0, 168, 0, 88, - 146, 146, 146, 0, 0, 0, 159, 36, 146, 146, - - 146, 0, 0, 0, 160, 0, 0, 146, 146, 0, - 0, 0, 0, 57, 0, 0, 0, 0, 142, 0, - 0, 0, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, - 0, 146, 0, 0, 0, 158, 89, 189, 189, 0, - 0, 0, 230, 230, 230, 258, 258, 258, 0, 0, - 0, 307, 307, 0, 295, 0, 0, 0, 0, 0, - 0, 0, 295, 0, 0, 0, 0, 0, 0, 0, - 307, 302, 325, 325, 323, 0, 0, 168, 0, 83, - - 72, 30, 0, 0, 0, 0, 141, 59, 146, 0, - 0, 0, 0, 0, 0, 146, 146, 0, 0, 0, - 0, 134, 0, 0, 0, 161, 0, 0, 0, 0, + 0, 147, 147, 147, 0, 0, 0, 110, 147, 147, + 188, 188, 195, 195, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 208, 238, 238, 238, 238, 238, 238, + 238, 238, 267, 267, 267, 267, 267, 267, 0, 0, + 315, 0, 0, 0, 0, 0, 0, 315, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 315, 315, + 333, 333, 333, 172, 172, 172, 171, 146, 146, 146, + 0, 0, 147, 147, 147, 147, 0, 0, 0, 50, + 147, 147, 147, 147, 0, 0, 0, 0, 0, 147, + 147, 0, 0, 0, 163, 147, 0, 0, 0, 0, + 0, 0, 0, 0, 12, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 128, 0, 0, 0, 0, 0, 146, - 0, 0, 0, 0, 189, 189, 0, 212, 211, 230, - 222, 221, 258, 258, 248, 0, 0, 0, 0, 0, - 307, 301, 295, 0, 0, 0, 0, 0, 0, 307, - 322, 325, 0, 0, 0, 0, 168, 0, 0, 0, - - 0, 0, 146, 0, 0, 0, 0, 0, 0, 146, - 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, + 0, 0, 0, 0, 0, 0, 0, 0, 73, 147, + 20, 0, 0, 0, 147, 67, 188, 188, 195, 195, + + 0, 0, 215, 205, 216, 0, 0, 219, 222, 207, + 238, 238, 226, 227, 238, 238, 230, 233, 259, 267, + 254, 267, 267, 267, 0, 0, 315, 0, 0, 0, + 0, 0, 0, 315, 315, 315, 0, 0, 0, 0, + 0, 0, 0, 0, 315, 315, 333, 333, 333, 172, + 172, 172, 146, 146, 146, 0, 88, 147, 147, 147, + 0, 0, 0, 160, 36, 147, 147, 147, 0, 0, + 0, 161, 0, 0, 147, 147, 0, 0, 0, 0, + 57, 0, 0, 0, 0, 0, 0, 143, 0, 0, + 0, 0, 0, 0, 158, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 120, 0, 70, 0, - 0, 0, 0, 189, 189, 0, 230, 249, 258, 0, + 0, 0, 0, 0, 0, 0, 129, 0, 0, 0, + 0, 0, 0, 0, 147, 0, 0, 0, 159, 89, + 188, 188, 195, 195, 0, 0, 0, 0, 238, 238, + 238, 238, 267, 267, 267, 267, 0, 0, 315, 0, + 304, 0, 0, 0, 0, 0, 0, 0, 304, 0, + 0, 0, 0, 0, 0, 0, 315, 311, 333, 333, + 331, 172, 172, 172, 146, 146, 146, 0, 83, 72, + 30, 0, 0, 0, 0, 142, 59, 147, 0, 0, + 0, 0, 0, 0, 147, 147, 0, 0, 0, 0, + + 135, 0, 0, 0, 0, 162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 295, 307, 325, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 146, 0, 0, 0, 0, - - 146, 62, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 76, 0, 78, - 0, 0, 0, 0, 127, 0, 0, 0, 0, 0, - 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 95, 0, 0, 0, 0, 105, 0, 0, 189, - 189, 0, 230, 247, 0, 0, 0, 0, 0, 0, - 0, 306, 0, 0, 295, 307, 325, 0, 0, 0, - 0, 0, 163, 0, 0, 0, 0, 0, 64, 0, - 0, 0, 146, 162, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, + 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 129, 0, 0, 0, + 0, 0, 0, 0, 147, 0, 0, 0, 0, 188, + 188, 195, 195, 0, 218, 217, 0, 238, 229, 228, + 238, 267, 267, 267, 257, 0, 0, 0, 0, 310, + 304, 0, 0, 0, 0, 0, 0, 315, 330, 333, + 172, 172, 172, 146, 146, 146, 0, 0, 0, 0, + 0, 147, 0, 0, 0, 0, 0, 0, 147, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 81, 0, 0, 0, 0, 0, 101, - 104, 0, 181, 189, 0, 230, 0, 0, 0, 0, - 0, 307, 325, 0, 0, 0, 0, 0, 159, 0, - 160, 0, 0, 0, 143, 0, 0, 0, 0, 0, - 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 119, 0, 0, 0, 0, 0, - 0, 0, 0, 109, 0, 0, 0, 0, 106, 0, - 158, 0, 189, 0, 230, 0, 0, 305, 303, 324, - 0, 0, 0, 0, 0, 0, 0, 161, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 121, 0, 0, 70, 0, 0, 0, 0, 188, 188, + 195, 195, 0, 0, 238, 238, 258, 267, 267, 0, + 0, 0, 0, 0, 0, 304, 315, 333, 172, 172, + 172, 146, 146, 146, 0, 0, 0, 0, 147, 0, + 0, 0, 0, 147, 62, 0, 0, 0, 0, 0, + + 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 76, 0, 78, 0, 0, 0, 0, 0, + 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, + 129, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 95, 0, 0, 0, 0, 0, 105, 0, + 0, 188, 188, 195, 195, 0, 0, 238, 238, 256, + 267, 0, 0, 0, 304, 315, 333, 172, 172, 172, + 146, 146, 146, 0, 0, 0, 64, 0, 0, 0, + 147, 163, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, - 0, 0, 0, 0, 0, 0, 99, 0, 108, 0, - 189, 214, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 80, 0, 0, 121, 0, 87, 0, - 91, 0, 102, 0, 0, 183, 0, 0, 0, 132, - 0, 0, 135, 0, 130, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 80, 0, 129, 0, 0, - 96, 0, 0, 86, 0, 0, 0, 0, 136, 0, - - 0, 0, 0, 0, 0, 80, 0, 76, 0, 0, - 0, 0, 85, 0, 97, 0, 0, 0, 133, 0, + 81, 0, 0, 0, 0, 0, 101, 104, 118, 0, + 188, 188, 187, 195, 0, 0, 238, 238, 267, 0, + 0, 315, 333, 172, 172, 172, 146, 146, 146, 0, + 0, 160, 0, 161, 0, 0, 0, 144, 0, 0, + 0, 0, 0, 0, 0, 158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 120, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 109, 0, 0, 0, 0, 106, 0, 159, + + 0, 188, 188, 195, 0, 0, 238, 238, 255, 0, + 314, 312, 332, 172, 172, 172, 146, 146, 146, 0, + 0, 0, 0, 0, 0, 0, 162, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, + 0, 108, 0, 188, 188, 195, 220, 0, 231, 238, + 0, 172, 172, 172, 146, 146, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 118, 0, 0, 131, 0, 0, - 0, 0, 0, 0, 0, 0, 305, 0, 0, 0, - 0, 0, 140, 79, 0, 0, 0, 0, 79, 0, - 0, 79, 0, 0, 0, 139, 0, 80, 0, 0, - 0, 0, 0, 0, 79, 0 + 0, 0, 0, 0, 0, 80, 165, 0, 0, 0, + 0, 122, 0, 0, 87, 0, 91, 0, 102, 0, + 0, 188, 188, 189, 225, 235, 0, 172, 172, 172, + 146, 146, 146, 133, 0, 0, 136, 167, 0, 131, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 80, 0, 0, 0, 130, 0, 0, 0, 96, 0, + 0, 86, 188, 188, 0, 172, 172, 172, 146, 146, + 147, 0, 137, 0, 0, 0, 0, 0, 0, 80, + 0, 76, 0, 0, 0, 166, 0, 0, 85, 164, + 0, 97, 188, 0, 172, 172, 174, 151, 151, 147, + 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 175, 175, 174, 151, 151, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, + 0, 175, 175, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 119, 0, 0, 132, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 314, 0, 0, + 0, 0, 0, 141, 79, 0, 0, 0, 0, 0, + 0, 79, 0, 0, 0, 0, 79, 0, 0, 0, + 0, 140, 0, 80, 0, 0, 0, 0, 0, 0, + 169, 0, 0, 0, 79, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -653,2595 +673,2684 @@ static yyconst flex_int32_t yy_ec[256] = 1, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 5, 6, 7, 8, 5, 5, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 20, 21, 1, - 22, 1, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 1, 51, 1, 5, 52, 53, 54, 55, 56, 57, - - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 5, 80, 5, 1, 81, 82, 82, - 82, 82, 82, 82, 82, 83, 84, 85, 85, 86, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 87, 87, 87, 87, 87, 88, 89, 89, - 89, 1, 1, 90, 90, 90, 90, 90, 90, 90, - - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 91, 91, 91, 92, 93, 93, 93, - 93, 93, 93, 93, 93, 93, 93, 93, 94, 95, - 95, 95, 95, 95, 1, 1, 1, 1, 1, 1, + 11, 12, 13, 14, 15, 16, 17, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 19, 20, 1, + 21, 1, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 1, 50, 1, 5, 51, 52, 53, 54, 55, 56, + + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 5, 79, 5, 1, 80, 81, 81, + 81, 81, 81, 81, 81, 82, 83, 84, 84, 85, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 87, 88, 88, + 88, 1, 1, 89, 89, 89, 89, 89, 89, 89, + + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 90, 90, 90, 91, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 93, 94, + 94, 94, 94, 94, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[96] = +static yyconst flex_int32_t yy_meta[95] = { 0, 1, 2, 3, 3, 1, 4, 5, 6, 7, 1, - 1, 1, 8, 1, 9, 10, 1, 6, 6, 11, - 1, 1, 1, 1, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 1, 1, 2, 1, 8, 9, 1, 6, 10, 1, + 1, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 12, 6, 13, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 11, + 6, 12, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, - 5, 5, 5, 5, 5 + 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, + 5, 5, 5, 5 } ; -static yyconst flex_int16_t yy_base[2759] = +static yyconst flex_int16_t yy_base[2949] = { 0, - 0, 0, 95, 0, 188, 189, 201, 0, 296, 0, - 391, 0, 485, 489, 502, 506, 0, 0, 600, 0, - 694, 697, 706, 717, 728, 739, 481, 486, 487, 491, - 496, 501, 5821, 5819, 5818, 5787, 833, 0, 509, 510, - 927, 937, 1031, 0, 1126, 0, 516, 518, 1221, 0, - 1315, 1322, 1346, 1356, 489, 517, 5839,17443, 1330, 1336, - 17443, 1340, 1448, 103, 702,17443, 504,17443, 509, 511, - 5795, 687,17443, 1508, 920, 733, 903, 912, 1518, 1309, - 1383, 1527, 722, 1590, 933, 1412, 1598, 1605, 494, 1427, - 1672, 1600, 1665, 1398, 1736, 1601, 669, 1427, 1636, 1665, - - 1730, 1739, 1748,17443,17443, 465,17443, 514, 522, 1693, - 1701, 1771, 1794, 1750, 1802, 1818, 1767, 1817, 1833, 1842, - 1851, 1860,17443,17443, 531,17443, 1948, 2042, 1969, 549, - 1997, 516,17443, 922, 708, 728, 542, 931, 1316, 2089, - 1945, 2080, 2089, 2098, 2107, 2116,17443, 1476, 873, 1863, - 555, 2031, 2058, 1958, 2125, 2134, 2143, 2152, 2161, 2170, - 17443,17443,17443, 0,17443, 559, 0,17443, 0,17443, - 17443, 690, 689, 705, 734, 1949, 5724, 5716,17443,17443, - 17443,17443, 578,17443, 5683, 5675,17443,17443,17443,17443, - 580, 5643, 5635,17443,17443,17443, 915,17443,17443, 754, - - 0,17443, 0, 0, 748, 946, 1357, 1520, 5597, 5571, - 17443,17443, 5577, 5558,17443,17443,17443,17443,17443,17443, - 790, 5558, 5549,17443,17443,17443,17443, 793, 5555, 5546, - 0, 2065, 0, 0, 2258, 0,17443, 1867, 0, 0, - 5570, 0, 5514,17443, 1391, 1522,17443, 2350, 1709,17443, - 17443, 5549,17443, 5519, 2218, 2227, 2234, 2243, 2300,17443, - 2193, 2202, 2259, 2294, 2323, 2332,17443, 943,17443, 1545, - 1574,17443, 0,17443,17443,17443, 5525, 1299, 5414, 5406, - 17443, 1602, 1875,17443, 2445, 1903,17443,17443,17443, 5400, - 2384, 2399, 2456, 2399, 2418, 2427, 2471, 2480, 2489,17443, - - 2003,17443,17443, 2537, 2499, 2508, 2517, 2528, 2537, 2552, - 17443, 1297,17443, 2425, 2640,17443, 2732, 2013,17443, 715, - 17443, 958, 749, 2629,17443,17443, 5389, 2601, 2613, 2621, - 17443, 2578, 2676, 2685, 2705, 2714, 2747,17443, 2686, 2773, - 0, 5397,17443, 1299, 1322, 5300,17443, 2777, 2802, 0, - 5365,17443, 1326, 1355, 5196, 1357, 1363, 1367, 2805, 5162, - 17443, 2294, 2756, 2765, 2774, 2789, 2798, 2817, 0, 2906, - 2850, 2859, 2879, 2888, 2921, 2930, 2211, 2939, 2948, 2957, - 2966, 2975, 2984, 2859,17443, 2993, 3002, 3011, 3020, 3029, - 3038, 811, 2886, 1951,17443, 2018, 3112, 3119, 2636, 3104, - - 2428, 3089, 3128, 3140, 3097, 3150, 3191, 3179, 3223, 3199, - 3207, 3267, 3250, 3261, 3280, 3295, 3301, 3274, 3319, 3350, - 3340, 3380, 3364, 3356, 3401, 3392, 3418, 3436, 3442, 3448, - 3479, 3460, 3504, 3510, 3489, 3516, 3527, 3598, 3588, 3604, - 3430, 3612, 3618, 3629, 3643, 3700, 3667, 3687, 3710, 3747, - 3754, 3658, 3236, 2561, 3083,17443, 3061, 3745, 3769, 3778, - 3787, 3796, 3805, 3814, 3823, 3832, 3841, 3850, 3859, 3868, - 2591, 3877, 3886, 3895, 3904, 3913, 3922, 1005,17443, 1302, - 3994, 3716, 3986, 4000, 4006, 3973, 4015, 3935, 3333, 3964, - 4030, 4039, 3682, 4048, 4057, 1330,17443, 4145, 4151, 4166, - - 17443, 4191, 1523, 1606, 1602, 1669, 4159, 4181, 4190, 4206, - 4215, 4224, 4233, 4242, 1412,17443, 1680, 1598, 1653, 2077, - 3184, 3583, 3530, 3601, 3516, 1517, 2076, 4251, 4260, 4269, - 4278, 4287, 3072, 4296, 4305,17443, 2889, 4314, 4323, 4332, - 4341, 4350, 4359, 3409, 4368, 4377, 4386, 4395, 4404, 4413, - 4494,17443, 4423, 4432, 4441, 4450, 4459, 4468, 1430,17443, - 4157, 4535, 3980,17443, 4481, 4490, 4510, 4519, 4528, 4550, - 4559, 4567, 4576, 4585, 4594, 3316, 4603, 4612, 0, 1467, - 17443, 1383, 1442, 1455, 1471, 1537, 1521, 1697, 1719, 5161, - 5140, 1469,17443, 5144, 5138, 1759,17443, 5142, 5102, 0, - - 1738, 1911, 1763,17443, 1936, 1944, 2104, 2239, 2268, 2344, - 5106, 1360, 5102, 5098, 2006,17443, 5082, 5073, 2142,17443, - 5038, 1282, 0, 3163, 5109,17443, 5100, 5033,17443, 0, - 4700, 4989,17443, 4981, 4860,17443, 3724,17443, 4928, 4918, - 4848,17443, 0,17443, 0,17443, 4616, 4846, 0, 4792, - 4629, 4638, 4647, 4656, 4665, 4674, 3729, 4683, 4692, 4701, - 4736, 4745, 4765, 4703, 3587, 4766, 4817, 4802, 4830, 4845, - 4852, 4867, 4876, 4885, 4894, 4903, 4912, 4921, 4930, 2365, - 4834, 4835, 0, 4928, 2361, 4833, 1295, 5019, 4825, 0, - 5111, 4943, 4952, 4961, 4970, 4979, 4988, 3944, 4997, 5006, - - 5015, 5055, 5064, 5084, 5152, 5084, 5117, 5137, 5133, 5152, - 5164, 5173, 5182, 5191, 5200, 5209, 4773, 5218, 5227, 5236, - 5245, 5254, 5263, 5314, 5273, 5281, 5290, 5302, 5311, 5329, - 5338, 5347, 2624, 5399, 4809, 0, 5491, 5356, 5365, 5374, - 5383, 5392, 5401, 4810, 5435, 5444, 5464, 5473, 5506, 5515, - 1577, 5532, 2681, 3757, 5589, 5550, 3604, 5562, 5570, 5576, - 5544, 5604, 5613, 5622, 5631, 5640, 5649, 5658, 5670, 4808, - 0, 5673, 2630, 2644, 4774, 5746, 4763, 0, 5749, 2743, - 2829, 4754, 2837, 2921, 3110, 4719, 5685, 5528, 5694, 5703, - 5712, 5721, 5730, 5739, 5748, 5672, 5761, 5770, 5779, 5788, - - 5797, 5806, 5814, 5823, 5832, 5840, 5849, 5858, 5867, 5876, - 5885, 5894, 5982, 4718, 3549, 4133, 4214, 1708, 5941, 5015, - 5933, 5951, 5958, 5968, 5975, 5985, 6018, 6027, 6056, 6047, - 6062, 6068, 6079, 6139, 6109, 6126, 6145, 6151, 6158, 6182, - 5902, 6188, 6219, 6225, 6212, 6231, 6258, 6238, 5912, 6269, - 6307, 6313, 6299, 6319, 6342, 6327, 6333, 6282, 6356, 6384, - 6390, 6396, 6414, 6435, 6421, 6407, 6455, 6472, 6480, 6496, - 6503, 6511, 6529, 6519, 6539, 6563, 6571, 6288, 6579, 6555, - 6591, 6599, 6633, 6623, 6647, 6692, 6641, 6681, 6675, 6708, - 5927, 6714, 6743, 6728, 6757, 6772, 6764, 6452, 6103, 6787, - - 6796, 6805, 6094, 6814, 6823, 6350, 6362,17443,17443,17443, - 6832, 6180, 6872, 6894, 6882, 6736, 6888, 6904, 6663, 6838, - 17443,17443, 6859, 6918, 6921, 6992, 6975, 7003, 6934, 7015, - 7021, 7027, 7055, 7039, 7045, 7062, 7073, 7088, 7097, 7105, - 7114, 7123, 7132, 6614, 7141, 7150, 7159, 7167, 7176, 7185, - 7194, 6951, 7203, 7212, 7258, 7267, 7223, 7231, 7240, 7252, - 7282, 6969, 7291, 7300, 7252, 7300, 7315, 3115, 3182, 3182, - 4744, 3203, 3203, 4739, 3281,17443,17443,17443,17443,17443, - 3432, 3473, 3516, 3588, 3594, 3597, 3610, 3690,17443,17443, - 17443,17443,17443,17443,17443,17443,17443,17443, 4615, 4614, - - 6009, 4541,17443, 4612, 4574, 6053, 4501,17443, 4575, 4574, - 6088, 4479, 4478, 7324, 7332, 7341, 7350, 7359, 7368, 7377, - 7386, 7394, 7403, 6122, 4477, 3711, 3759, 3766, 7447, 7455, - 7461, 7468, 7484, 7474, 7409, 7415,17443, 7499, 3992, 6208, - 4199, 3997,17443,17443, 4174, 7508, 7447, 7517, 7526, 7535, - 7431, 7544, 7553, 7561, 7570, 6469, 4173, 7615, 7621, 7608, - 7576, 7582,17443,17443, 7602, 7627, 7633, 7639, 7654, 3988, - 4153, 7663, 7671, 7680, 7689, 7698, 7707, 7716, 7725, 7733, - 7742, 6842, 4150, 4900, 5480, 5167, 1710, 7772, 3983, 4001, - 7786, 7800, 7810, 7742, 7748,17443, 7763, 7569, 4142, 3995, - - 4115, 7854, 4141, 4134, 4151, 4153, 4161, 4154, 7822, 7862, - 7837, 7957, 8052, 7846, 7850, 7897, 7912, 0, 7868, 4139, - 4134, 1839, 1841, 1862, 1872, 1947, 7933, 7927, 7997, 7941, - 8017, 8028, 7793, 8067, 8073, 8091, 8082, 8105, 8114, 8126, - 8144, 8150, 8159, 7987, 8184, 8211, 8177, 8171, 8200, 8097, - 8236, 8220, 8249, 8120, 8229, 8265, 8277, 8290, 8255, 8296, - 8283, 8302, 8335, 8362, 8374, 8381, 8368, 8387, 8320, 8399, - 8450, 8415, 8459, 8466, 8356, 8482, 8406, 8473, 8489, 8508, - 8543, 8559, 8553, 8565, 8583, 8677, 8541, 8592, 8444, 8598, - 8661, 8636, 8670, 8680, 8694, 8686, 8701, 8737, 8746, 8758, - - 8766, 8775, 8781, 8792, 8428, 8805, 8708, 8752, 8811, 8826, - 8833, 8840, 8867, 8877, 8883, 8723, 8861, 8920, 8963, 8926, - 17443, 8970, 9007, 8980, 9013, 9019, 9030, 8992, 8999, 9045, - 9057, 9067, 9054, 9092, 9116, 9100, 9110, 9083, 4768, 4798, - 5090, 5128, 5481, 5501, 5508, 5591, 5577, 0, 5582, 5973, - 4159, 6043, 6044, 6069, 8716, 4129, 8985, 4127, 8009, 4117, - 9211, 9306, 9155, 0, 7894, 4097, 4094, 6059, 6062, 4113, - 9162, 9191, 9243, 9255, 9177, 9283, 6068, 0, 8167, 4082, - 4078, 6140, 9401, 9496, 9279, 0, 8396, 4075, 4069, 9351, - 9261, 9377, 9085,17443, 9591, 9686, 9374, 0, 8419, 4023, - - 4022, 2047, 2059, 2101, 2122, 2253, 6133, 6155, 9447, 9474, - 9467, 0, 8440, 4021, 4002,17443, 6229, 0, 8525, 4001, - 3981,17443,17443,17443,17443,17443, 3961, 9432, 9568, 9663, - 9529, 9541, 9710, 9652, 9718, 9637, 9746, 9731, 9761, 9781, - 9790, 9831, 9840, 9825, 9864, 9893, 9906, 9925, 9900, 9938, - 9958, 9944, 9974,10042, 9967,10003,10023,10020,10077,10070, - 10083,10109,10117,10127,10140,10149,10179, 9340,10104,10155, - 10212,10225,10234,10251,10263,10257,10279,10285,10273,10293, - 10387, 6612, 6227, 6231, 6241, 6313, 6316, 6383, 3960,10311, - 10481,10320,10408,10331,10470,10439,10487,10493,10502,10544, - - 10515,10572,10587,10600,10609,10615,10621,10650,10629,10658, - 9183, 9385,10641,10667,17443,10702,10714, 9558,10721,10753, - 10738,10782,10761,10747,10579, 9336, 6512, 6645, 3784, 6732, - 3783, 6723, 6735, 3761, 6782, 3747, 6776, 6788, 6799, 3746, - 0, 3788, 9861, 3778, 1346, 3692, 3733, 9890, 3732, 1491, - 3659, 3726, 8666, 3725, 751, 3620, 3605, 6887, 6949, 6951, - 10732,10361,10430,10877, 3659,10776,10937,10943,10949,17443, - 3590, 6976, 3589,10928,10962,10977, 3570, 6984, 6992,11007, - 11013,11019, 3569,17443, 3568, 9910,10925,11057,11079,10776, - 11086,11092,11116,11123,11129,11135,11229,11235,11242,11248, - - 11190,11273,11306,11263,11343,11312,11296,11368,11357,11378, - 7009, 7033, 3545,11116,11390,11413, 9813, 3603,11337,11451, - 11428,11438,11463, 7453, 3533,11428,11532,11545,11474,11570, - 11488,11585,11591,11598,11612, 8668, 7470, 7489, 7633, 7823, - 3541, 7864, 3539, 3495, 8295, 7883, 7873, 8053, 7874, 8018, - 8200, 8246, 8292, 8379, 8381, 3485,11569,11605,11628,11643, - 11712,11667,11706,11724,11750,11740,11773,11761, 9460,10371, - 11781, 9535,11821,11767,11861,11867,11050,11901,11853,11696, - 11887,11879, 8456, 8459, 8554, 0, 8964, 8564, 0, 8557, - 0, 8558, 8582, 8576, 8594, 8629, 2321, 2390, 1325, 8676, - - 8681, 8860,11938,11838,11982, 8845, 3484,11996,12010, 0, - 0,12019, 8848,12110,12201,12292,12383,12474,12565, 8945, - 11803,10891,11407,11656,17443,11964,11970,11999, 8937, 8966, - 12005,10899,12013, 8959, 3416,12045,12066,12079,12133,12144, - 12151,12160,12179,12185,11778, 3469,12178,12301,12218,12245, - 12314,12329,12358,12423,11808, 3468,12240, 8964, 9012, 3398, - 12414,12435, 3385, 2302,12269,12340,12442,12456, 9028, 3383, - 12494,12508,12536,12517,12571,12602,12615, 3451,12592, 9091, - 9201, 9212, 9221, 9298, 9316, 9390, 9378, 9491, 9504, 9573, - 9587, 9573, 9669, 9682, 9812, 9811, 9829, 9810, 9823, 9902, - - 9917, 9902, 3381,12656,12683,12699,12398, 3415,12627,12631, - 12729,12716,12672,12049,12744,12690,12784,12752,12797,12815, - 12836,12842,12822, 9903, 3374, 9983, 9984, 9988,10027,10042, - 10060,10053,10080,10096,10171,10212,10217,10232,12790,12828, - 12936,12942,12951,10237, 3344,12958,10239,13049,13140,13231, - 13322,13413,12973,13504,13595,13010, 3321,12645,12929,12979, - 12994,13001,10262,10270,13079,10906,10292, 3303,13095,13109, - 13116,13123, 3302, 2319,13075,12988,13177,13189,13240,13253, - 3301, 2341,13212,10391,10370,13307,13300, 3300, 2345, 2659, - 10568,13358,10371,12575, 3368,13270,13283,13382,10381,10403, - - 10388, 3243, 2436,13348, 3271,10395, 3270,10397,10730,10449, - 10464,10491,10479,10586,10575,10596,10597,10583,10591,10610, - 10712,10710,10729,11213,10749,10752,10753,13366,13460,13436, - 3240, 2451,13397,13534,13488,13352,13472,13523,13541,13159, - 13552,13568,13603,13614,13621,11679, 3260,10941, 0, 0, - 10938, 0, 0, 0,11014, 0, 3259,11011,11013,11013, - 11034,13637,13627,13731,13737,11027,13746,13764,13774,11028, - 0, 0,13865,13794,13804,13813,13832,13888,13850, 3224, - 13819,12912,13879,13844,13912,11080,11090,13896,11081,13957, - 13963,13973,13979, 3206, 2460, 2723,12118,13990,14016,14031, - - 14073, 3183, 2529, 2897,12767,11109,11086,14088,14094,12687, - 12794,11103, 3181,14009,11112, 3180, 2531,13940,14041,11140, - 11168,11196, 3179, 2705, 3321,13722,11200,11200,11207,11218, - 11233,11233,11232, 9195,11323,11310,11358,11347,11383,11536, - 11519,11547, 9381,11551,11536,17443,11590,11706,11711,11764, - 11845,14135, 3171, 2738, 3502,14110,14114,14100,14177,14127, - 14141,14184,11850,11867,11868,11855,11871,11892,11899, 9722, - 3199,14167,14194,14288,17443,14294,14303,14310,14326,14333, - 14340,14370, 0,14385,14401,14407,14437,14446,14453,14468, - 14395,13905,14441,14449,14055,11901,13106,14464,11927,14158, - - 14498,14512,13148,14212,11954, 3145,14519,14544,14561,13272, - 14362,11957, 3135,11971,11977,14571,14577,13556, 3120,12005, - 3112,17443, 3082, 2879, 4160,14367,12006,12023,12002,13651, - 14565,12053, 3074,12120,12151,12157,12142,12157,12167,12224, - 12344, 3071,12306,12357,12385,12376,12425,12430,12429,12420, - 14656, 3070,12457,12465,12498,14722,12514,12511,12526,14643, - 13823,14616,12558, 2877,14649,14630,14710,14537,14600,12551, - 0, 0,12559,12584, 0,12582,13872,14754, 2874,12577, - 14728,14492,14809,14826,14832,14841,14848,14875,14889,14821, - 14679,14858,12608,14695,13464, 2844,14904,12955,14868, 2843, - - 12705, 2832,14917,14871, 2829,12765, 2785,12761,12836,14932, - 14939, 2729,12822,14955,14974,12835, 2703,12830,12847,12893, - 14962, 2655,12914, 2644,12944,12961,13021,13027,13071,12858, - 13379, 2596, 2622,13089, 2618,13106,13420,13123,13149,17443, - 13180,13198,13212, 2576,13218,13219,13235,13477,13300,13459, - 13475,13583,14984,13472,13487,13507,17443,13510,14983,14966, - 2526,13509, 2464,14946,14970,15028,13546, 0,13523,13565, - 15081,13575,13573, 2416, 2389,13618,13688,13840,15005,15096, - 15124,14910,15050,13613,15105,13626, 2341, 2268,14151,14548, - 15081,13633,13644, 2226,13711,15111, 2215,13713,13729,13719, - - 15145,15134,13917,15093, 2074,13726, 2063,13731,13750, 2090, - 2047,13751,13802,13795,13822, 2029,13829,14036, 1998,14173, - 1994,13867,14354,13859,17443,14788, 1954,13870, 1972,13875, - 14003,17443,14136,14167,14216,14234,14245,14250,14277,14276, - 14291,17443,14321,14327,14322,14357,17443, 1941,14390,15127, - 15100,15168,14394, 0,15153,14403, 1962, 1921,14433, 1902, - 15228,17443, 1900,15166,15262,15180,15223,15276,14436, 1887, - 1881,15279,17443, 1826,15218,14457,14454,14597,15284,15289, - 14552,14553,15306,15292, 1802, 1786,14605,14626,14632,14630, - 15319, 1753,15322, 1737,14638,15325, 1701, 1693,14645,15328, - - 1659,14647,14662, 1655,14675,14713,14715,14709,14720,14724, - 14755,14738,14770,17443,14819,14824,14838,14855,14882,17443, - 17443,15333,14977,15295,15348,14899,14906,14947,14967, 1633, - 1606,15312,15337,14980, 1592, 1570,15021,15013,15341, 1568, - 15344, 1535,15061,15072,15354, 1526,15406,15068,15121,15122, - 15448, 1516,15155,15451,15455, 1416,15147,15175,15458, 1406, - 15274, 1359,15315,15327,17443,15320,15355,15363,15391,15392, - 15393,15423,15439,17443,15429,15428,15445,15442,17443,15447, - 15475, 1355,15461,15467,15437,15455,15455,17443,15441,15478, - 15459,15454,15444, 1339, 1328,15457,15452,15504, 1306, 1323, - - 2306,15450, 1291,15454,15542,15469,15448, 1246, 1242,15474, - 15492,15519, 949,15506,15514,15528,15536,17443,15531,15542, - 15532,15550,15549,15539,15534,15542,17443,15546,17443, 939, - 15538,15572, 0,15550,15565,15552,15564,15555,15559,15568, - 935,15565, 924, 920,15574,15583, 940, 938, 900,15586, - 15579,15581,15606,15597,15611,15599,17443,15603,17443,15601, - 17443,15600,17443,15618,15609,15565,15611,15621,15616,17443, - 15634,15637,17443,15640,17443, 887, 886,15647,15638,15641, - 15642,15636,15657,15689,15644,15692, 870,17443,15645,15659, - 17443,15665,15670,17443,15663, 769,15664,15673,17443,15658, - - 734,15666,15673,15678,15682,15716, 756,15719, 725,15680, - 702,15692,17443,15694,17443,15704,15699,15706,17443,15697, - 15704,15700,15719,15720,15721, 688,15718,15709,15711,15706, - 15713,15712,15728,15785,15717,15735,15736,15737,15731,15745, - 17443,15797,15755,15800, 701,15803, 3252, 646, 626,15767, - 660, 650,15769,15782,17443,15761,15789,17443, 505, 494, - 486,15777,15789,15778,15776,15772,17443,15795, 466,15797, - 15788,15790,17443,15756,15801,15781,15793,15796,15831, 452, - 15794,15838,15794,15800, 118,17443,15818,15860,15811,15811, - 15838,15831,15843,15822,15870,17443,15962,15975,15988,16001, - - 16014,16027,16040,16053,16066,16079,16092,16105,16118,16131, - 16144,16157,16167,16173,16182,16184,16187,16196,16201,16208, - 16210,16212,16215,16223,16227,16236,16249,16262,16275,16288, - 16301,16313,16325,16334,16340,16353,16362,16364,16370,16379, - 16385,16398,16408,16414,16427,16436,16438,16441,16450,16455, - 16462,16464,16466,16469,16477,16481,16490,16503,16516,16529, - 16542,16555,16567,16579,16592,16601,16607,16620,16633,16642, - 16644,16650,16663,16672,16678,16691,16704,16717,16726,16728, - 16730,16736,16737,16741,16750,16763,16776,16789,16802,16811, - 16817,16830,16843,16852,16854,16860,16873,16882,16888,16901, - - 16911,16917,16930,16939,16946,16955,16957,16966,16968,16976, - 16978,16981,16983,16991,16995,17004,17017,17030,17043,17056, - 17069,17078,17084,17097,17110,17123,17132,17134,17140,17153, - 17166,17175,17181,17194,17207,17219,17221,17223,17229,17230, - 17234,17243,17256,17269,17282,17291,17297,17310,17319,17325, - 17338,17351,17364,17377,17390,17403,17416,17429 + 0, 0, 94, 0, 186, 187, 199, 0, 293, 0, + 387, 0, 480, 484, 497, 501, 0, 0, 594, 0, + 687, 690, 699, 710, 721, 732, 476, 481, 482, 486, + 491, 496, 6207, 6185, 6184, 6183, 825, 0, 504, 505, + 918, 928, 1021, 0, 1115, 0, 511, 513, 1209, 0, + 1302, 1308, 0, 0, 1323, 1360, 493, 512, 6229,17872, + 1316, 1330,17872, 1336, 1451, 102, 695,17872, 6210,17872, + 503, 6208, 6212, 924,17872, 1511, 1312, 726, 1343, 679, + 912, 668, 1387, 1520, 490, 1527, 717, 1416, 1597, 1583, + 901, 1431, 1664, 927, 1591, 1422, 1672, 1315, 471, 1409, + + 1486, 1679, 1688, 1697, 1706,17872,17872, 872,17872, 500, + 6202, 1708, 1657, 1758, 1752, 1775, 1764, 1781, 1730, 1796, + 1805, 1814, 1823, 1832,17872,17872, 521,17872, 1919, 2012, + 1940, 523, 1967, 497,17872, 721, 919, 928, 498, 1297, + 917, 2059, 1915, 2050, 2059, 2068, 2077, 2086,17872, 1556, + 1737, 1928, 538, 1983, 2028, 1874, 2095, 2104, 2113, 2122, + 2131, 2140,17872,17872,17872, 0,17872, 574, 0,17872, + 0,17872,17872, 666, 683, 696, 707, 2205, 6133, 6107, + 17872,17872,17872,17872, 739,17872, 6113, 6102,17872,17872, + 17872,17872, 782, 6100, 6091,17872,17872,17872, 907,17872, + + 17872, 783, 0,17872, 0, 0, 735, 933, 1668, 1582, + 6096, 6088,17872,17872, 6088, 6080,17872,17872,17872,17872, + 17872,17872, 785, 6055, 6047,17872,17872,17872,17872, 924, + 6053, 6045, 0, 2228, 0, 0, 2245, 0,17872, 2261, + 0, 0, 6078, 0, 6075,17872, 1394, 1587,17872, 2352, + 1954,17872,17872, 6106,17872, 6097, 2000, 2205, 2217, 2223, + 17872, 2197, 2240, 2257, 2296, 2305, 2325,17872, 939,17872, + 1638, 1715,17872, 0,17872,17872,17872, 6074, 1279, 6008, + 5992,17872, 1857, 2327,17872, 2446, 2211,17872,17872,17872, + 6062, 2332, 2396, 2412, 2390, 2427, 2436, 2461, 2470, 2479, + + 17872, 2257,17872,17872, 2527, 2489, 2498, 2507, 2518, 2527, + 2542,17872, 1279,17872, 2392, 2629,17872, 2720, 2545,17872, + 6058,17872, 806, 6057, 2624,17872,17872, 2606, 2615,17872, + 2573, 2602, 2664, 2673, 2693, 2702,17872, 2647, 2671, 0, + 6059,17872, 1300, 1318, 5987,17872, 2674, 2764, 0, 6051, + 17872, 1316, 1329, 5955, 1333, 1347, 1349, 2789, 5951,17872, + 2757, 2735, 2744, 2753, 2776, 2785, 2801, 0, 2889, 2833, + 2842, 2862, 2871, 2904, 2913, 2573, 2922, 2931, 2940, 2949, + 2958, 2967, 2785,17872, 2976, 2985, 2994, 3003, 3012, 3021, + 6012, 2840, 6011, 1427, 1499,17872, 1501, 3094, 3100, 3076, + + 3106, 2843, 3082, 3122, 3147, 3164, 3170, 3206, 3176, 3249, + 3236, 3242, 3280, 3128, 3274, 3286, 3357, 3134, 3322, 3328, + 3336, 3365, 3396, 3371, 3402, 3409, 3429, 3435, 3417, 3450, + 3487, 3495, 3457, 3512, 3501, 3526, 3555, 3579, 3650, 3586, + 3651, 3562, 3573, 3607, 3155, 3637, 3666, 3651, 3690, 3704, + 3735, 3696, 3720, 3728, 2871, 3307,17872, 3051, 3750, 3759, + 3768, 3777, 3786, 3795, 3804, 3813, 3822, 3831, 3840, 3849, + 3858, 3052, 3867, 3876, 3885, 3894, 3903, 3912, 995,17872, + 6009, 3479, 3963, 3975, 3981, 3987, 3969, 3993, 3938, 4007, + 4016, 4025, 4034, 3206, 4043, 4052, 1296,17872, 4139, 4145, + + 4160,17872, 4184, 1377, 1661, 1605, 1593, 4153, 4175, 4184, + 4199, 4208, 4217, 4226, 4235, 1334,17872, 1680, 2053, 1607, + 1676, 1913, 1674, 3095, 4299, 3566, 1520, 3253, 4261, 4290, + 4299, 4308, 4317, 3476, 4326, 4335,17872, 3388, 4344, 4353, + 4362, 4371, 4380, 4389, 3442, 4398, 4407, 4416, 4425, 4434, + 4443, 4523,17872, 4453, 4462, 4471, 4480, 4489, 4498, 1405, + 17872, 4548, 4565, 4273,17872, 4511, 4520, 4540, 4563, 4580, + 4589, 4598, 4251, 4607, 4616, 4625, 3948, 4634, 4643, 0, + 1430,17872, 1368, 1434, 1461, 1523, 1936, 1522, 1628, 1685, + 5936, 5924, 1652,17872, 5927, 5911, 1653,17872, 5913, 5906, + + 0, 1672, 1756, 1822,17872, 1770, 1884, 1904, 1906, 1918, + 2010, 2013, 5909, 1513, 5902, 5899, 1823,17872, 5892, 5886, + 1912,17872, 5804, 487, 0, 3380, 5874,17872, 5844, 5776, + 17872, 0, 4238, 5816,17872, 5809, 5742,17872, 3678,17872, + 5815, 5804, 5738,17872, 0,17872, 0,17872, 3160, 5736, + 0, 4731, 4675, 4684, 4704, 4713, 4746, 4755, 3914, 4764, + 4773, 4782, 4791, 4800, 4809, 3620, 2007, 4854, 4861, 4867, + 4878, 4887, 4826, 4902, 4911, 4920, 4929, 3961, 4938, 4947, + 2067, 4961, 5735, 0, 4971, 2063, 5734, 613, 5034, 5733, + 0, 5125, 4959, 4973, 4983, 4992, 5001, 5010, 4265, 5019, + + 5028, 5069, 5078, 5098, 5107, 5165, 5152, 5158, 5178, 5150, + 5177, 5193, 5202, 5211, 4835, 5220, 5229, 4540, 5238, 5247, + 5256, 5265, 5274, 5283, 5334, 5293, 4692, 5302, 5311, 5322, + 4851, 5331, 5349, 2056, 5418, 5732, 0, 5509, 5358, 5367, + 5376, 5385, 5394, 5403, 4713, 5412, 5453, 5462, 5482, 5491, + 5524, 5763, 5549, 5761, 3098, 2216, 2436, 5597, 5542, 5576, + 5582, 5564, 5575, 5597, 5612, 5621, 5542, 5630, 5639, 5726, + 5698, 0, 5729, 2207, 2229, 5584, 5732, 5562, 0, 5735, + 2221, 2255, 5561, 2369, 2366, 2373, 5559, 5660, 5036, 5669, + 5678, 5687, 5696, 5705, 5714, 5723, 5420, 5747, 5756, 5765, + + 5774, 5783, 5792, 5499, 5801, 5810, 5818, 5827, 5836, 5845, + 5854, 5863, 5872, 5620, 5959, 5557, 3289, 1918, 2095, 3293, + 2238, 5948, 5540, 5921, 5954, 5962, 5968, 5979, 6002, 6048, + 6012, 6062, 6071, 6106, 6092, 6150, 6115, 6157, 6199, 6175, + 6186, 6215, 6206, 6222, 6239, 5992, 6257, 6301, 6287, 6310, + 6323, 6329, 6336, 6267, 6369, 6354, 6382, 6415, 6421, 6408, + 6436, 6462, 6452, 6501, 6474, 6480, 6508, 6533, 6559, 6541, + 6587, 6569, 6598, 6604, 6613, 6627, 6659, 6620, 6651, 6706, + 6692, 6712, 6719, 6738, 6730, 6753, 6761, 6798, 6824, 6833, + 6841, 6883, 6863, 6870, 6854, 6895, 6877, 6942, 6934, 6977, + + 6964, 7006, 6988, 6030, 6451, 6930, 7003, 7021, 5887, 7030, + 7039, 6905, 7043,17872,17872,17872, 7058, 5899, 5536, 6681, + 6971, 5908, 7087, 7102, 7093, 7125, 5527, 5932,17872,17872, + 7067, 7080, 7158, 7174, 7183, 7189, 7204, 7197, 7219, 7268, + 7226, 7283, 7255, 7276, 7244, 7289, 7304, 7313, 7321, 7330, + 7339, 7348, 6130, 7357, 7366, 7375, 7383, 7392, 7401, 7410, + 6254, 7419, 7428, 6791, 7482, 7438, 7446, 7455, 7467, 7476, + 6354, 7497, 7506, 6782, 6812, 7515, 2429, 2652, 2725, 5466, + 2903, 3094, 3085, 5465, 3103,17872,17872,17872,17872,17872, + 3158, 3161, 3208, 3256, 3279, 3281, 3297, 3321, 3335,17872, + + 17872,17872,17872,17872,17872,17872,17872,17872,17872, 5504, + 5391, 6096, 5186,17872, 5246, 5245, 6121, 5160,17872, 5233, + 5222, 6142, 5143, 5142, 7524, 7532, 7541, 7550, 7559, 6680, + 7568, 7577, 7585, 7120, 6167, 5141, 3375, 3357, 7637, 7643, + 7650, 7666, 7625, 7476, 7591,17872, 7606, 3373, 6317, 5140, + 3379,17872,17872, 5121, 7665, 7614, 7681, 7690, 7699, 7150, + 7708, 7717, 7725, 7241, 6485, 5096, 7777, 7783, 7767, 7631, + 7730,17872,17872, 7747, 7789, 7747, 7755, 7804, 3370, 5091, + 7813, 7821, 7830, 7839, 7848, 7857, 7866, 7875, 7883, 7892, + 5115, 6518, 5052, 3734, 2401, 2479, 3581, 3720, 7959, 5111, + + 7965, 7972, 7989, 7978, 7995,17872, 7937, 6734, 5048, 3404, + 3496, 6938, 4971, 3577, 3586, 3696, 3706, 3731, 8001, 8007, + 7952, 8101, 8195, 8045, 8065, 8130, 8060, 5032, 0, 7167, + 4969, 4968, 4156, 4948, 4924, 4923, 4922, 4918, 8145, 8162, + 8213, 8230, 8224, 8292, 8256, 8241, 8309, 8282, 8327, 8320, + 8335, 8344, 8353, 8374, 8380, 8389, 8364, 8434, 8416, 8424, + 8460, 8474, 8445, 8468, 8480, 8539, 8496, 8505, 8565, 8528, + 8575, 8584, 8599, 8591, 8607, 8636, 8647, 8678, 8686, 8693, + 8704, 8654, 8718, 8741, 8747, 8765, 8785, 8774, 8809, 8798, + 8853, 8844, 8829, 8868, 8878, 8899, 8916, 8923, 8939, 9032, + + 8084, 8948, 9002, 9035, 8910, 9044, 9050, 9061, 9074, 9093, + 9133, 9086, 9145, 9157, 9101, 9173, 9180, 9196, 9186, 9203, + 9213, 7952, 8557, 8939, 4908, 8956, 9224, 9021, 8263, 8992, + 8547, 7909, 9237, 9282, 9292, 9320,17872, 9303, 9326, 9332, + 9349, 9411, 9417, 9428, 9151, 9361, 9377, 9311, 9390, 9386, + 9397, 9466, 9440, 9446, 9461, 3731, 3731, 3736, 3746, 3987, + 4122, 4148, 4157, 4163, 4149, 0, 4154, 4180, 4874, 4190, + 4866, 4873, 5115, 7982, 4844, 8491, 4824, 8173, 4823, 9560, + 9654, 9504, 0, 7848, 4822, 4729, 5128, 4757, 9537, 9592, + 9544, 9512, 9606, 5136, 0, 8134, 4702, 4669, 5148, 9748, + + 9842, 9533, 0, 8543, 4659, 4658, 9631, 9621, 9700, 9599, + 17872, 9936,10030, 9692, 4717, 0, 8623, 4654, 4573, 5976, + 4634, 4618, 4617, 4593, 4592, 9788, 9796, 9879, 0, 8701, + 4529, 4508,17872, 5169, 0, 8708, 4507, 4288,17872,17872, + 17872,17872,17872, 4343, 4272, 6131, 9886, 9779, 9984,10038, + 9807, 9900,10048,10067, 9966,10079, 9995,10054,10134,10147, + 10085,10164,10172,10181,10188,10204,10228,10194,10216,10234, + 10252,10274,10313,10283,10296,10319,10390,10273,10363,10353, + 10380,10414,10403,10421,10444,10432,10459, 9915,10459,10513, + 10474,10466,10482,10545,10553,10562,10582,10573,10595,10604, + + 10611,10634, 5489, 5167, 5829, 5953, 5963, 6066, 6081, 4271, + 10627,10727,10652,10731,10501,10755,10652,10748,10742,10763, + 10777,10784,10801,10844,10869,10790,10881,10887,10902,10893, + 4332, 9873,10932, 9638, 9816,10962,10718,17872,10973,10981, + 10913,10994,11002,11017,11033,11023,11062,11053,10627,10532, + 6147, 6202, 4279, 6218, 4277, 6229, 6298, 6316, 4276, 6316, + 4275, 6415, 6430, 6423, 6409, 4197, 0, 4234, 8714, 4218, + 1422, 4146, 4216, 8817, 4215, 1517, 4128, 4199, 9999, 4198, + 1480, 4123, 4122, 6424, 6518,10853,11133,11224, 4186,11081, + 11085,11109,11091,17872, 4091, 6534, 4090,11008,11125,11281, + + 4150, 4085, 8242,11304,11312,11318, 4079,17872, 4077, 4138, + 8596,11324,10096,11124,11330,11383,11103,11409,11339,11418, + 11424,11352,11431,11437,11477,11446,11518,11455,11525,11536, + 11560,11590,11604,11466,11616,11503,11583, 6543, 6541, 4073, + 11581,11622,11639, 9784, 4139,11637,11683,11718,11669,11724, + 6542, 4066,11661,11711,10345,11706,11735,11741,11820,10335, + 11757,11762,11831,11842,11853,11859,10396, 6561, 6565, 6611, + 6605, 4094, 6600, 4093, 3971, 6623, 8225, 6632, 6637, 7180, + 6730, 6751, 6805, 6811, 6807, 6952, 8175, 7020, 3970,11807, + 11889,11790,11869,11882,11912,11899,11983,11938,11922,11961, + + 12003, 4019,11946,11273,11954,11996,11553,12041,12052,12067, + 12090,12033,12132,12098,12084,12113,12138,12144, 7017, 7020, + 7141, 0, 9137, 3982, 7179, 0, 7178, 0, 7196, 7273, + 7279, 7286, 3976, 7287, 1599, 1743, 1982, 7310, 7649,12124, + 12193, 7634, 3936,12237,12243, 0, 0,12252, 8003,12342, + 12432,12522,12612,12702,12792, 8813,12229,12182,12211,12246, + 17872,12281,12287,12274, 3996, 8746,12374,12314,12325, 3995, + 9305,12381, 8034, 3932,12368,12404,12461,12416,12467,12473, + 12558,12453,12495,10811, 3811,12510,12584,12532,12564,12646, + 12621,12655,12629,11375, 3804,12548, 8067, 8160, 3735,12686, + + 12734, 3728, 703,12679,12740,12752,12797, 8192, 3726,12765, + 8212, 3712,12812,12776,12834, 8241, 3688,12821,12847,12823, + 12895,12927, 3755,12887, 8246, 8281, 8315, 8325, 8324, 8344, + 8474, 8462, 8537, 8602, 8658, 8765, 8795, 8801, 8861, 8868, + 8892, 8928, 8955, 9028, 9037, 9133, 9197, 9229, 9216, 9268, + 3684,12919,12933,12949,11587, 3741,12916,12866,12962,12978, + 3733,12989,12293,12995,13005,13012,13018,13042,13097,13076, + 13121,13127,13136,12592, 9271, 3696, 9305, 9307, 9313, 9313, + 9322, 9323, 9381, 9460, 9461, 9467, 9457, 9654, 9641, 9656, + 13082,13178,13229,13235, 9732, 3633,13244, 9760,13334,13424, + + 13514,13604,13694,13272,13784,13874,13251, 3629,13108,13204, + 13219,13275,13240, 3684, 9789,13354,13285, 3673, 9793,13367, + 9758, 3608,13373,13433,13453,13459, 3578, 1437,13322,13465, + 13498,13487,13547,13555, 3555, 1807,13411, 9772, 9827,13614, + 13587, 3554, 1809, 2238,13192,13636, 9836, 9847, 3553,12062, + 3563,13581, 9873, 3494,13524,13667, 9943, 9960, 9944, 3485, + 1850,13631, 3510,10023, 3507,10027,10112,10035,10110,10125, + 10120,10139,10181,10142,10165,10169,10160,10171,10182,10276, + 10274,10309,10355,10454,10398,10397,10395,10452,13642,13731, + 13677, 3475, 1926,13720,13756,13724, 3534,13344,13793,13652, + + 13803,13819,13825,13843,13857,13887,13913,13904,13923,12351, + 3466,10459, 0, 0,10463,10545, 0, 0, 0,10547, + 0, 3464,10552,10564,10591,10604,13395,13984,14016,10605, + 14023,14032,14042,10687, 0, 0,14132,14049,14059,14114, + 14141,14151,14169, 3434,14001,13881,14100,14071,14109, 3448, + 10870,14193, 3435,10871,14210,10702,14163,14224,14235,14248, + 3362, 1928, 2275,13830,14242,14277,14263,14305, 3329, 1960, + 2343,14078,10736,10717,14331,14290,12663,14232,10735, 3313, + 14296,10726,10752, 3312, 1972,14322,10868,14342,10894,10877, + 10883, 3308, 1980, 2483,14409,10881,10882,10885,10952,10975, + + 10980,10974, 9118,10987,10974,10990,10974,10993,11012,11007, + 11078,11078,11103,10677,11167,11274,17872,11296,11297,11282, + 11287,11323,11322,11391,14362, 3280, 1992, 2707,14412,14401, + 3337,14270,14180,14386,14425,14432,14442,14450,11393,11412, + 11423, 3303,11412,11424,11417,11432,11688, 3298,14415,14543, + 17872,14549,14558,14564,14579,14585,14594,14615, 0,14621, + 14657,14676,14690,14707,14716,14723,14663,12479,14693,14701, + 13066, 3292,11546,14731, 3283,11850,14781,11484,14684,14742, + 14750,13027,14758,11518, 3202,14764,14788,14829,13113,14864, + 11519, 3198,11519,11563,14821,14844,13301, 3196,11621, 3155, + + 17872,11694, 3149, 2226, 2880,14894,11708,11699,11728,11707, + 13565,14897,11737, 3130,11742,11788,11793,11820,11828,11829, + 11830,11387, 3127,11847,11898,11913,11893,11935,12004,12014, + 12056,12049,12040,14901, 3102,12049,12063,12080,12096,14967, + 12112,12209,12215,12219,14924,13835,14945,12228, 3081, 3142, + 14873,14953,14889,14959,14968,14978,14984,12219, 0, 0, + 12221,12229,12238,12226, 0,13341,12730, 3067,12231,13445, + 15077,15083,15092,15098,15119,15125,15134,15128,13851,15137, + 3105,12332,15102, 3102,12464,15144,12700,13840, 3037,12241, + 2886,15160,14481, 2860,12286, 2827,12284,12299,15151,15191, + + 2816,12286,12284,14650,15244,12327, 2813,12416,12417,12436, + 12414,14798, 2774,12465, 2773,12479,12579,12636,12639,12696, + 12409,12573, 2772, 2794,12715, 2746,12640,12944,12727,13321, + 12732,12765,17872,12773,12786,12898, 2716,12892,12910,13474, + 12911,12998,12927,13009,13019,13356,15229,13007,13032,13090, + 17872,13148,13176,15169,14848, 2715,13206, 2691, 2746,15206, + 15220,15230,15250,15260,13236,13233, 0,13215,13287,15021, + 13274, 2648, 2647,13285,15330,15356,15236,15285, 2694,13736, + 15352, 2693,13737,15369,13333,13422, 2630,13410,15340, 2623, + 13411,13444,13533,15375,15382,13631,13980,15275, 2622,13584, + + 2621,17872,13586,13601, 2642, 2612,13583,13616,13633,13693, + 2640,13742,14458, 2600,14525, 2599,13771,14826,13793,15416, + 2591,15451, 2589,17872,15446, 2588,13834, 2597,13873,13871, + 17872,15435, 2567,13928,13997,14011,14025,14019,14017,14026, + 14029,14059,17872,14079,14084,14074,14077,14103,17872, 2566, + 14114, 2627,15392,15312,15442,15471,15478,14134,14163, 0, + 14172, 2593, 2516,14195,15488,15464,15484, 2481,14629,15493, + 2473,14671,15523,14209,14206,14881,15501,14904,14223,14224, + 15572,14939, 2404,15594, 2401, 2400,14225,14233,14239,14299, + 14949, 2377,15411, 2366,14304,15304, 2335, 2323,14401,15344, + + 2317,14405,14406, 2279,14400,14453, 2276,14458, 2255,14506, + 14498,14520,14532,14532, 2254,14570,14566,14686,14572,14577, + 17872,14589,14590,14604,14626,14647,17872,17872,17872,15421, + 2315,15511,15517,15552,15603,15609,14663,14694,14780,14778, + 14799,15597,15621, 2314,15621,15651, 2275,15652,15689,14830, + 14825,15628, 2211,15631, 2192,14887,14913,15634, 2186,14930, + 2156,15669,14921,14949,14999,15727, 2043,15008,15731,15734, + 2031,15016,15044,15746, 2029,15051, 2027,15071,15084,15087, + 15083,15125,17872,15110,15130,15130,15135,15158,15247,15295, + 15329,15336,17872,15341,15355,15470,15469,17872,15492,15749, + + 2008, 2047,15700,15706,15742,15757,15481,15594, 0,15595, + 17872,15673,15718, 2045,15758,15810, 2036,15811,15825,15594, + 15583, 1946, 1944,15643,15701,15745,15753, 1906, 1900, 1494, + 15746, 1847,15785,15817,15805,15795, 1725, 1640,15808,15810, + 15828, 1617,15815,15810,15819,15825,15818,15829,15837,17872, + 15824,15837,15833,15834,15850,15850,15839,15848,15856,17872, + 15873,17872, 1519, 1567,15852,15872,15863,15897, 0,15880, + 15898, 1500,15911,15919, 1482,15942,15957,15900,15907,15931, + 15934,15930, 1402,15933, 915, 1336,15936,15955, 1365, 1341, + 1302,15958,15951,15952,15964,15929,17872,15954,15974,15976, + + 15964,17872,15968,15971,17872,15975,17872,15984,17872,16002, + 15992, 1356,15999,15890,16014, 0,16005, 1354,16024,16025, + 1337,16044,16052,17872,16010,16000,17872,17872,16000,17872, + 1248, 1247,16022,16013,16028,16030,16025,16066,16072,16053, + 16075, 1234,16054,16056,17872,16057,16073,16069,17872,16088, + 16093,17872, 1002,16040, 959, 954,16119,16120, 905,16136, + 16137,16094,17872,16083, 730,16119,16126,16131,16132,16083, + 753,16165, 718,16118, 711,17872,16168,16130,17872,17872, + 16135,17872,17872,16137, 747,16164,16179, 745,16180,16187, + 17872,16163,16179,16175,16194,16195,16196, 674,16194,16236, + + 672,16185,16187,16188, 722,16239,16246, 711,16267,16204, + 16287,16191,16231,16248,16255,16247,16248, 627,16251,17872, + 16257, 687,16284, 648,16304, 1550, 513, 502,16265, 536, + 527,16272,16275,16264,17872,16268,16294,17872, 480, 472, + 466,16282,16294,16285,16284,16278,16329,17872,16302, 461, + 16316,16305,16307,17872,16357,16360, 462,16319,16302,16316, + 16321,16363, 454,16329, 447,16328,16385,16328,16328, 117, + 16340,17872,16349,16388,16359,16342,16356,16351,16353,16372, + 17872,16364,16376,16356,16405,17872,16496,16508,16520,16532, + 16544,16556,16568,16580,16592,16604,16616,16628,16640,16652, + + 16664,16676,16685,16691,16699,16701,16704,16712,16717,16723, + 16725,16727,16730,16737,16740,16748,16760,16772,16784,16796, + 16808,16819,16830,16838,16844,16856,16864,16866,16872,16880, + 16886,16898,16907,16913,16925,16933,16935,16938,16946,16951, + 16957,16959,16961,16964,16971,16974,16982,16994,17006,17018, + 17030,17042,17053,17064,17076,17084,17090,17102,17114,17122, + 17124,17130,17142,17150,17156,17168,17180,17192,17200,17205, + 17207,17212,17213,17216,17224,17236,17248,17260,17272,17280, + 17286,17298,17310,17318,17320,17326,17338,17346,17355,17367, + 17376,17382,17394,17402,17409,17417,17422,17430,17432,17439, + + 17441,17444,17446,17453,17456,17464,17476,17488,17500,17512, + 17524,17532,17538,17550,17562,17574,17582,17584,17590,17602, + 17614,17622,17631,17643,17655,17663,17668,17670,17675,17676, + 17679,17687,17699,17711,17723,17731,17737,17749,17757,17763, + 17775,17787,17799,17811,17823,17835,17847,17859 } ; -static yyconst flex_int16_t yy_def[2759] = +static yyconst flex_int16_t yy_def[2949] = { 0, - 2596, 1, 2596, 3, 2597, 2597, 2596, 7, 2596, 9, - 2596, 11, 2598, 2598, 2599, 2599, 2600, 2600, 2596, 19, - 2600, 2600, 2601, 2601, 2602, 2602, 2603, 2603, 2604, 2604, - 2605, 2605, 2606, 2606, 2607, 2607, 2596, 37, 2608, 2608, - 2609, 2609, 2596, 43, 2596, 45, 2610, 2610, 2596, 49, - 2611, 2611, 2612, 2612, 2600, 2600, 2596, 2596, 2596, 2596, - 2596, 2613, 2614, 2615, 2616, 2596, 2596, 2596, 2596, 2596, - 2596, 2615, 2596, 2615, 2615, 2615, 2615, 2615, 2615, 2615, - 2615, 2615, 2615, 2615, 2615, 2615, 2615, 2615, 2615, 2615, - 2615, 88, 2615, 2615, 88, 88, 2617, 2596, 2596, 2596, - - 2596, 2596, 2596, 2596, 2596, 2618, 2596, 2596, 2596, 2618, - 2618, 2618, 2618, 2618, 2618, 2618, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2619, 2619, 2619, 2596, - 2619, 131, 2596, 131, 131, 131, 131, 131, 131, 131, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2620, 2621, 2622, - 2596, 2621, 2621, 2623, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2624, 2596, 2596, 2624, 2596, 2624, 2596, - 2596, 2624, 2624, 2624, 2624, 2624, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2625, 2596, 2596, 2596, - - 2625, 2596, 2625, 2625, 2625, 2625, 2625, 2625, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2626, 2596, 2627, 2628, 2596, 2629, 2596, 2596, 2630, 2631, - 2596, 2632, 2596, 2596, 2596, 2596, 2596, 2633, 2634, 2596, - 2596, 2596, 2596, 2596, 2634, 2634, 2634, 2634, 2634, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2635, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2636, 2637, 2596, 2596, 2596, 2596, - 2637, 2637, 2637, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - - 2638, 2596, 2596, 2638, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2639, 2640, 2596, 2596, - 2596, 2596, 2596, 2640, 2596, 2596, 2596, 2640, 2640, 2640, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2641, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2642, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2643, 2596, 2596, 2596, 2596, 2596, 2596, 2644, 2645, - 2644, 2644, 2644, 2644, 2644, 2644, 2646, 2596, 2596, 2596, - 2596, 2596, 2596, 2647, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2646, 2646, 2646, 2646, - - 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, - 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, - 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, - 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, - 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, 2646, - 2646, 2646, 2646, 2646, 2648, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2649, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2649, 2649, 2649, 2649, 2649, 2649, 2649, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2650, 2650, 2650, - - 2596, 2650, 502, 502, 502, 502, 502, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 502, 502, 502, 502, - 502, 502, 502, 502, 502, 502, 502, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2651, 2596, 2596, 2596, - 2596, 2596, 2596, 2652, 2596, 2596, 2596, 2596, 2596, 2596, - 2653, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2652, 2652, 2654, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2655, 2596, - 2596, 2655, 2655, 2655, 2655, 2655, 2655, 2655, 2655, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2656, - - 2656, 2656, 2596, 2596, 2656, 2656, 2656, 2656, 2656, 2656, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2657, 2596, 2658, 2596, 2596, 2596, 2596, 2659, - 2596, 2660, 2596, 2596, 2596, 2596, 2596, 2596, 2661, 2596, - 2596, 2596, 2662, 2596, 2663, 2596, 2596, 2596, 2664, 2665, - 2664, 2664, 2664, 2664, 2664, 2664, 2666, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2666, 2666, 2666, 2666, 2666, - 2666, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2667, 2596, 2596, 2596, 2596, 2596, 2596, 2668, - 2669, 2668, 2668, 2668, 2668, 2668, 2668, 2670, 2596, 2596, - - 2596, 2596, 2596, 2596, 2596, 2670, 2670, 2670, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2671, 2596, 2596, 2596, - 2596, 2596, 2596, 2671, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2672, 2673, 2672, 2672, 2672, - 2672, 2672, 2672, 2674, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2674, 2674, 2596, 2674, 2674, 2674, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2675, 2596, 2596, 2596, 2596, 2596, 2596, 2676, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2677, 2677, 2677, 2677, 2677, 2677, - - 2677, 2677, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2678, 2596, 2596, 2596, 2596, 2596, 2679, 2679, - 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, - 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, - 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, - 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, - 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, - 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, - 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2679, - 2679, 2679, 2679, 2679, 2679, 2679, 2679, 2596, 2596, 2596, - - 2596, 2596, 2596, 2596, 2596, 2679, 2679, 2596, 2596, 2596, - 2596, 2596, 2680, 2680, 2680, 2680, 2680, 2680, 2680, 2680, - 2596, 2596, 2596, 2596, 2681, 2681, 2681, 2681, 2681, 2681, - 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2682, 2682, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2682, 2682, 2596, 2683, 2683, 2683, - 2683, 2683, 2683, 2683, 2683, 2596, 2596, 2596, 2596, 2596, - 2684, 2684, 2684, 2684, 2684, 2684, 2684, 2684, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2685, 2685, - - 2596, 2596, 2596, 2686, 2686, 2596, 2596, 2596, 2687, 2687, - 2596, 2596, 2596, 2688, 2688, 2688, 2688, 2688, 2688, 2688, - 2688, 2596, 2596, 2689, 2596, 2596, 2596, 2596, 2690, 2690, - 2690, 2690, 2690, 2690, 2690, 2690, 2596, 2596, 2596, 2691, - 2596, 2596, 2596, 2596, 2596, 2692, 2692, 2692, 2692, 2692, - 2692, 2692, 2692, 2596, 2596, 2693, 2596, 2694, 2694, 2694, - 2694, 2694, 2596, 2596, 2596, 2695, 2695, 2695, 2596, 2596, - 2596, 2696, 2696, 2696, 2696, 2696, 2696, 2696, 2696, 2596, - 2596, 2697, 2596, 2596, 2596, 2596, 2596, 2698, 2596, 2596, - 2698, 2698, 2698, 2698, 2698, 2596, 2596, 2699, 2596, 2596, - - 2596, 2700, 2596, 2596, 2596, 2596, 2596, 2596, 2701, 2701, - 2596, 2702, 2702, 2703, 2704, 2704, 2596, 2705, 2705, 2705, - 2596, 2596, 2596, 2596, 2596, 2596, 2706, 2706, 2706, 2706, - 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, - 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, - 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, - 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, - 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, - 2706, 2706, 2706, 2706, 2706, 2596, 2596, 2706, 2706, 2706, - 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2706, - - 2706, 2706, 2706, 2706, 2706, 2706, 2706, 2707, 2707, 2596, - 2708, 2708, 2708, 2708, 2708, 2708, 2709, 2709, 2709, 2709, - 2596, 2709, 2709, 2709, 2709, 2709, 2709, 2710, 2710, 2596, - 2711, 2711, 2596, 2712, 2712, 2713, 2713, 2596, 2714, 2714, - 2714, 2714, 2714, 2714, 2714, 2714, 2715, 2715, 2715, 2715, - 2715, 2715, 2715, 2715, 2716, 2596, 2717, 2596, 2718, 2596, - 2719, 2719, 2720, 2721, 2721, 2721, 2596, 2596, 2596, 2596, - 2722, 2722, 2722, 2722, 2722, 2722, 2596, 2723, 2723, 2723, - 2596, 2596, 2724, 2724, 2725, 2726, 2726, 2726, 2596, 2727, - 2727, 2727, 2728, 2596, 2729, 2729, 2730, 2731, 2731, 2731, - - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2732, 2732, - 2732, 2733, 2733, 2733, 2596, 2596, 2596, 2734, 2734, 2734, - 2596, 2596, 2596, 2596, 2596, 2596, 2735, 2736, 2736, 2736, - 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, - 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, - 2736, 2736, 2736, 2736, 2736, 2736, 2596, 2596, 2736, 2736, - 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2596, 2596, 2736, - 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, - 2736, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, - - 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2737, - 2737, 2737, 2737, 2737, 2596, 2738, 2738, 2738, 2738, 2738, - 2738, 2738, 2738, 2738, 2739, 2739, 2740, 2740, 2740, 2740, - 2740, 2740, 2740, 2740, 2741, 2741, 2741, 2741, 2741, 2741, - 2741, 2742, 2742, 2742, 2742, 2596, 2743, 2743, 2743, 2743, - 2596, 2744, 2744, 2744, 2744, 2596, 2745, 2596, 2596, 2596, - 2746, 2746, 2596, 2596, 2596, 2596, 2746, 2746, 2746, 2596, - 2747, 2596, 2748, 2749, 2749, 2749, 2731, 2596, 2596, 2732, - 2732, 2732, 2733, 2596, 2734, 2596, 2596, 2736, 2736, 2736, - 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, - - 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, - 2596, 2596, 2596, 2596, 2736, 2736, 2596, 2596, 2596, 2736, - 2736, 2736, 2736, 2596, 2596, 2596, 2736, 2736, 2736, 2736, - 2736, 2736, 2736, 2736, 2736, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2736, 2736, 2736, - 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2736, 2737, 2737, - 2737, 2737, 2738, 2738, 2738, 2738, 2738, 2738, 2738, 2738, - 2738, 2739, 2740, 2740, 2740, 2740, 2740, 2740, 2740, 2740, - 2741, 2741, 2741, 2741, 2741, 2741, 2742, 2743, 2744, 2596, - - 2596, 2596, 2746, 2746, 2750, 2596, 2596, 2750, 2750, 1464, - 1464, 2750, 1464, 2750, 2750, 2750, 2750, 2750, 2750, 2596, - 2596, 2746, 2746, 2746, 2596, 2749, 2749, 2749, 2596, 2596, - 2732, 2732, 2732, 2596, 2596, 2596, 2736, 2736, 2736, 2736, - 2736, 2736, 2736, 2736, 2596, 2596, 2596, 2736, 2736, 2736, - 2736, 2736, 2736, 2736, 2596, 2596, 2596, 2596, 2596, 2596, - 2736, 2736, 2596, 2751, 2596, 2736, 2736, 2736, 2596, 2596, - 2736, 2736, 2736, 2736, 2736, 2736, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - - 2596, 2596, 2596, 2736, 2736, 2736, 2596, 2596, 2596, 2736, - 2736, 2736, 2737, 2737, 2738, 2738, 2738, 2738, 2738, 2738, - 2738, 2738, 2739, 2740, 2740, 2740, 2740, 2740, 2740, 2740, - 2741, 2741, 2741, 2741, 2741, 2596, 2596, 2596, 2746, 2746, - 2750, 2750, 2750, 2596, 2596, 2750, 1464, 2750, 2750, 2750, - 2750, 2750, 2750, 2750, 2750, 2752, 2596, 2746, 2746, 2749, - 2749, 2749, 2596, 2596, 2732, 2732, 2596, 2596, 2736, 2736, - 2736, 2736, 2596, 2753, 2596, 2736, 2736, 2736, 2736, 2736, - 2596, 2754, 2596, 2596, 2596, 2736, 2736, 2596, 2751, 2751, - 2596, 2736, 2596, 2596, 2596, 2596, 2736, 2736, 2596, 2596, - - 2596, 2596, 2755, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2736, 2736, 2736, - 2596, 2756, 2596, 2736, 2736, 2737, 2737, 2738, 2738, 2738, - 2738, 2738, 2738, 2738, 2738, 2739, 2740, 2740, 2740, 2740, - 2740, 2740, 2740, 2741, 2741, 2741, 2741, 2741, 2596, 2596, - 2596, 2746, 2746, 2750, 2750, 2596, 2757, 2752, 2750, 1464, - 1464, 1464, 2750, 2752, 2752, 2757, 2752, 2752, 2752, 2596, - 2746, 2746, 2749, 2749, 2749, 2596, 2596, 2732, 2596, 2736, - 2736, 2736, 2736, 2596, 2753, 2753, 2596, 2736, 2736, 2736, - - 2736, 2596, 2754, 2754, 2596, 2596, 2596, 2736, 2736, 2596, - 2596, 2596, 2596, 2736, 2596, 2596, 2758, 2596, 2736, 2596, - 2596, 2596, 2596, 2755, 2755, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2736, 2596, 2756, 2756, 2596, 2736, 2737, 2737, 2738, - 2738, 2738, 2740, 2740, 2740, 2741, 2741, 2741, 2596, 2596, - 2596, 2746, 2746, 2750, 2596, 2757, 2757, 2757, 2757, 2757, - 2757, 2750, 1464, 2752, 2752, 2757, 2757, 2752, 2752, 2752, - 2746, 2746, 2749, 2749, 2749, 2596, 2596, 2732, 2596, 2736, - - 2736, 2736, 2596, 2596, 2596, 2596, 2736, 2736, 2736, 2596, - 2596, 2596, 2596, 2596, 2596, 2736, 2736, 2596, 2596, 2596, - 2596, 2596, 2596, 2758, 2758, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2736, - 2596, 2596, 2596, 2596, 2737, 2737, 2738, 2738, 2738, 2740, - 2740, 2740, 2741, 2741, 2741, 2596, 2596, 2596, 2596, 2596, - 2746, 2746, 2750, 2757, 2757, 2757, 2752, 2757, 2752, 2746, - 2749, 2749, 2596, 2596, 2596, 2596, 2732, 2596, 2596, 2596, - - 2596, 2596, 2736, 2596, 2596, 2596, 2596, 2596, 2596, 2736, - 2736, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2736, 2596, - 2596, 2596, 2596, 2737, 2737, 2738, 2740, 2741, 2741, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2757, - 2752, 2746, 2749, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2736, 2596, 2596, 2596, 2596, - - 2736, 2736, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2737, - 2737, 2738, 2740, 2741, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2757, 2746, 2749, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2736, 2596, - 2596, 2596, 2736, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2737, 2737, 2738, 2740, 2596, 2596, 2596, 2596, - 2596, 2746, 2749, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2736, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2737, 2738, 2740, 2596, 2596, 2596, 2746, 2749, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2737, 2738, 2740, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2737, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 0, 2596, 2596, 2596, 2596, - - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596 + 2786, 1, 2786, 3, 2787, 2787, 2786, 7, 2786, 9, + 2786, 11, 2788, 2788, 2789, 2789, 2790, 2790, 2786, 19, + 2790, 2790, 2791, 2791, 2792, 2792, 2793, 2793, 2794, 2794, + 2795, 2795, 2796, 2796, 2797, 2797, 2786, 37, 2798, 2798, + 2799, 2799, 2786, 43, 2786, 45, 2800, 2800, 2786, 49, + 2801, 2801, 2790, 2790, 2802, 2802, 2790, 2790, 2786, 2786, + 2786, 2786, 2786, 2803, 2804, 2805, 2806, 2786, 2786, 2786, + 2786, 2786, 2786, 2805, 2786, 2805, 2805, 2805, 2805, 2805, + 2805, 2805, 2805, 2805, 2805, 2805, 2805, 2805, 2805, 2805, + 2805, 2805, 2805, 90, 2805, 2805, 90, 90, 2807, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2808, 2786, 2786, + 2786, 2808, 2808, 2808, 2808, 2808, 2808, 2808, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2809, 2809, + 2809, 2786, 2809, 133, 2786, 133, 133, 133, 133, 133, + 133, 133, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2810, + 2811, 2812, 2786, 2811, 2811, 2813, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2814, 2786, 2786, 2814, 2786, + 2814, 2786, 2786, 2814, 2814, 2814, 2814, 2814, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2815, 2786, + + 2786, 2786, 2815, 2786, 2815, 2815, 2815, 2815, 2815, 2815, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2816, 2786, 2817, 2818, 2786, 2819, 2786, 2786, + 2820, 2821, 2786, 2822, 2786, 2786, 2786, 2786, 2786, 2823, + 2824, 2786, 2786, 2786, 2786, 2786, 2824, 2824, 2824, 2824, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2825, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2826, 2827, 2786, 2786, 2786, + 2786, 2827, 2827, 2827, 2786, 2786, 2786, 2786, 2786, 2786, + + 2786, 2828, 2786, 2786, 2828, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2829, 2830, 2786, + 2786, 2786, 2786, 2786, 2830, 2786, 2786, 2830, 2830, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2831, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2832, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2833, 2786, 2786, 2786, 2786, 2786, 2786, 2834, 2835, 2834, + 2834, 2834, 2834, 2834, 2834, 2836, 2786, 2786, 2786, 2786, + 2786, 2786, 2837, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2836, 2836, 2836, + + 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, + 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, + 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, + 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, 410, 410, + 410, 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, 2836, + 2836, 2836, 2836, 2836, 2836, 2838, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2839, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2839, 2839, 2839, 2839, 2839, 2839, 2839, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2840, 2840, + + 2840, 2786, 2840, 503, 503, 503, 503, 503, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 503, 503, 503, + 503, 503, 503, 503, 503, 503, 503, 503, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2841, 2786, 2786, + 2786, 2786, 2786, 2786, 2842, 2786, 2786, 2786, 2786, 2786, + 2786, 2843, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2842, 2842, 2844, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2845, + 2786, 2786, 2845, 2845, 2845, 2845, 2845, 2845, 2845, 2845, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + + 2846, 2846, 2846, 2786, 2786, 2846, 2846, 2846, 2846, 2846, + 2846, 2846, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2847, 2786, 2848, 2786, 2786, 2786, + 2786, 2849, 2786, 2850, 2786, 2786, 2786, 2786, 2786, 2786, + 2851, 2786, 2786, 2786, 2852, 2786, 2853, 2786, 2786, 2786, + 2854, 2855, 2854, 2854, 2854, 2854, 2854, 2854, 2856, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2856, 2856, 2856, + 2856, 2856, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2857, 2786, 2786, 2786, 2786, 2786, 2786, + 2858, 2859, 2858, 2858, 2858, 2858, 2858, 2858, 2860, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2860, 2860, 2860, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2861, 2786, 2786, + 2786, 2786, 2786, 2786, 2861, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2862, 2863, 2862, 2862, + 2862, 2862, 2862, 2862, 2864, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2864, 2864, 2864, + 2864, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2865, 2786, 2786, 2786, 2786, 2786, 2786, 2866, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2867, 2867, 2867, 2867, 2867, + + 2867, 2867, 2867, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2868, 2786, 2786, 2786, 2786, 2786, + 2786, 2869, 2786, 2869, 2869, 2869, 2869, 2869, 2869, 2869, + 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, + 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, + 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, + 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, + 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, + 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, + 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, 2869, + + 2869, 2869, 2869, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2869, 2869, 2786, 2786, 2786, 2786, 2786, 2786, 2870, + 2870, 2870, 2870, 2870, 2870, 2870, 2870, 2870, 2786, 2786, + 2786, 2786, 2871, 2871, 2871, 2871, 2871, 2871, 2871, 2871, + 2871, 2871, 2871, 2871, 2871, 2871, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2872, 2872, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2872, 2872, 2786, 2873, 2873, 2873, 2873, + 2873, 2873, 2873, 2873, 2873, 2786, 2786, 2786, 2786, 2786, + 2874, 2874, 2874, 2874, 2874, 2874, 2874, 2874, 2874, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2875, + 2875, 2786, 2786, 2786, 2876, 2876, 2786, 2786, 2786, 2877, + 2877, 2786, 2786, 2786, 2878, 2878, 2878, 2878, 2878, 2878, + 2878, 2878, 2786, 2786, 2879, 2786, 2786, 2786, 2880, 2880, + 2880, 2880, 2880, 2880, 2880, 2786, 2786, 2786, 2881, 2786, + 2786, 2786, 2786, 2786, 2882, 2882, 2882, 2882, 2882, 2882, + 2882, 2882, 2786, 2786, 2883, 2786, 2884, 2884, 2884, 2884, + 2884, 2786, 2786, 2786, 2885, 2885, 2885, 2786, 2786, 2786, + 2886, 2886, 2886, 2886, 2886, 2886, 2886, 2886, 2786, 2786, + 2786, 2887, 2786, 2786, 2786, 2786, 2786, 2786, 2888, 2786, + + 2888, 2888, 2888, 2888, 2888, 2786, 2786, 2889, 2786, 2786, + 2786, 2890, 2786, 2786, 2786, 2786, 2786, 2786, 2891, 2891, + 2786, 2892, 2892, 2893, 2894, 2894, 2786, 2786, 2895, 2895, + 2895, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2896, 2896, + 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, + 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, + 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, + 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, + 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, + 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2786, + + 2786, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, + 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, 2896, + 2896, 2897, 2897, 2786, 2786, 2898, 2898, 2898, 2898, 2898, + 2898, 2898, 2899, 2899, 2899, 2899, 2786, 2899, 2899, 2899, + 2899, 2899, 2899, 2899, 2900, 2900, 2786, 2901, 2901, 2786, + 2902, 2902, 2903, 2903, 2786, 2904, 2904, 2904, 2904, 2904, + 2904, 2904, 2904, 2904, 2905, 2905, 2905, 2905, 2905, 2905, + 2905, 2905, 2905, 2906, 2786, 2907, 2786, 2908, 2786, 2909, + 2909, 2910, 2911, 2911, 2911, 2786, 2786, 2786, 2912, 2912, + 2912, 2912, 2912, 2786, 2913, 2913, 2913, 2786, 2786, 2914, + + 2914, 2915, 2916, 2916, 2916, 2786, 2917, 2917, 2917, 2918, + 2786, 2919, 2919, 2920, 2786, 2921, 2921, 2921, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2922, 2922, 2922, 2923, 2923, + 2923, 2786, 2786, 2786, 2924, 2924, 2924, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2925, 2786, 2926, 2926, 2926, 2926, + 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, + 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, + 2926, 2926, 2926, 2926, 2926, 2926, 2786, 2786, 2926, 2926, + 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2786, 2786, 2926, + 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, + + 2926, 2926, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2926, 2926, 2926, 2926, 2926, 2926, 2926, + 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, + 2786, 2927, 2927, 2927, 2927, 2927, 2927, 2786, 2928, 2928, + 2928, 2928, 2928, 2928, 2928, 2928, 2928, 2928, 2929, 2929, + 2930, 2930, 2930, 2930, 2930, 2930, 2930, 2930, 2930, 2931, + 2931, 2931, 2931, 2931, 2931, 2931, 2931, 2932, 2932, 2932, + 2932, 2786, 2933, 2933, 2933, 2933, 2786, 2934, 2934, 2934, + 2934, 2786, 2935, 2786, 2786, 2936, 2786, 2786, 2786, 2786, + 2936, 2936, 2936, 2786, 2937, 2786, 2938, 2939, 2939, 2939, + + 2786, 2921, 2786, 2922, 2922, 2922, 2923, 2786, 2924, 2786, + 2786, 2926, 2786, 2786, 2926, 2926, 2926, 2926, 2926, 2926, + 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, + 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2786, 2786, 2786, + 2786, 2926, 2926, 2786, 2786, 2786, 2926, 2926, 2926, 2926, + 2786, 2786, 2786, 2926, 2786, 2786, 2926, 2926, 2926, 2786, + 2786, 2926, 2926, 2926, 2926, 2926, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, 2926, + + 2926, 2786, 2927, 2927, 2927, 2927, 2927, 2928, 2928, 2928, + 2928, 2928, 2928, 2928, 2928, 2928, 2928, 2929, 2930, 2930, + 2930, 2930, 2930, 2930, 2930, 2930, 2930, 2931, 2931, 2931, + 2931, 2931, 2931, 2931, 2932, 2933, 2934, 2786, 2786, 2936, + 2940, 2786, 2786, 2940, 2940, 1488, 1488, 2940, 1488, 2940, + 2940, 2940, 2940, 2940, 2940, 2786, 2786, 2936, 2936, 2936, + 2786, 2939, 2939, 2939, 2786, 2786, 2922, 2922, 2922, 2786, + 2786, 2926, 2786, 2786, 2786, 2926, 2926, 2926, 2926, 2926, + 2926, 2926, 2926, 2786, 2786, 2786, 2926, 2926, 2926, 2926, + 2926, 2926, 2926, 2786, 2786, 2786, 2786, 2786, 2786, 2926, + + 2926, 2786, 2941, 2786, 2926, 2926, 2926, 2786, 2786, 2926, + 2786, 2786, 2786, 2926, 2926, 2786, 2786, 2786, 2926, 2926, + 2926, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2926, 2926, 2926, 2786, 2786, 2786, 2926, 2926, 2926, + 2786, 2927, 2927, 2927, 2928, 2928, 2928, 2928, 2928, 2928, + 2928, 2928, 2928, 2929, 2930, 2930, 2930, 2930, 2930, 2930, + 2930, 2930, 2931, 2931, 2931, 2931, 2931, 2931, 2786, 2786, + 2936, 2940, 2940, 2940, 2786, 2786, 2940, 1488, 2940, 2940, + + 2940, 2940, 2940, 2940, 2940, 2940, 2942, 2786, 2936, 2936, + 2939, 2939, 2939, 2786, 2786, 2922, 2922, 2786, 2786, 2926, + 2786, 2786, 2926, 2926, 2926, 2926, 2786, 2943, 2786, 2926, + 2926, 2926, 2926, 2926, 2786, 2944, 2786, 2786, 2786, 2926, + 2926, 2786, 2941, 2941, 2786, 2926, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2926, 2926, 2786, 2786, 2786, 2786, + 2945, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2926, 2926, + 2926, 2786, 2946, 2786, 2926, 2926, 2786, 2927, 2927, 2927, + + 2928, 2928, 2928, 2928, 2928, 2928, 2928, 2928, 2928, 2929, + 2930, 2930, 2930, 2930, 2930, 2930, 2930, 2930, 2931, 2931, + 2931, 2931, 2931, 2931, 2786, 2786, 2936, 2940, 2940, 2786, + 2947, 2942, 2940, 1488, 1488, 1488, 2940, 2942, 2942, 2947, + 2942, 2942, 2942, 2786, 2936, 2936, 2939, 2939, 2939, 2786, + 2786, 2922, 2786, 2786, 2926, 2786, 2926, 2926, 2926, 2926, + 2786, 2943, 2943, 2786, 2926, 2926, 2926, 2926, 2786, 2944, + 2944, 2786, 2786, 2786, 2926, 2926, 2786, 2786, 2786, 2786, + 2926, 2786, 2786, 2786, 2948, 2786, 2786, 2926, 2786, 2786, + 2786, 2786, 2945, 2945, 2786, 2786, 2786, 2786, 2786, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2926, 2786, 2946, 2946, 2786, 2926, + 2786, 2927, 2927, 2927, 2928, 2928, 2928, 2928, 2930, 2930, + 2930, 2930, 2931, 2931, 2931, 2931, 2786, 2786, 2936, 2940, + 2786, 2947, 2947, 2947, 2947, 2947, 2947, 2940, 1488, 2942, + 2942, 2947, 2947, 2942, 2942, 2942, 2936, 2936, 2939, 2939, + 2939, 2786, 2786, 2922, 2786, 2786, 2926, 2786, 2926, 2926, + 2926, 2786, 2786, 2786, 2786, 2926, 2926, 2926, 2786, 2786, + 2786, 2786, 2786, 2786, 2926, 2926, 2786, 2786, 2786, 2786, + + 2786, 2786, 2786, 2948, 2948, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2926, 2786, 2786, 2786, 2786, 2786, + 2927, 2927, 2927, 2928, 2928, 2928, 2928, 2930, 2930, 2930, + 2930, 2931, 2931, 2931, 2931, 2786, 2786, 2786, 2786, 2936, + 2940, 2947, 2947, 2947, 2942, 2947, 2942, 2936, 2939, 2939, + 2786, 2786, 2922, 2786, 2786, 2926, 2786, 2786, 2786, 2786, + 2786, 2926, 2786, 2786, 2786, 2786, 2786, 2786, 2926, 2926, + + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2926, 2786, 2786, 2786, 2786, 2786, 2927, + 2927, 2927, 2928, 2928, 2930, 2930, 2931, 2931, 2931, 2786, + 2786, 2786, 2786, 2786, 2947, 2942, 2936, 2939, 2786, 2786, + 2922, 2786, 2786, 2926, 2786, 2786, 2786, 2786, 2926, 2786, + 2786, 2786, 2786, 2926, 2926, 2786, 2786, 2786, 2786, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2927, 2927, 2927, 2928, 2928, 2930, 2930, 2931, + 2931, 2786, 2786, 2786, 2947, 2936, 2939, 2786, 2786, 2922, + 2786, 2786, 2926, 2786, 2786, 2786, 2926, 2786, 2786, 2786, + 2926, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2927, 2927, 2927, 2928, 2928, 2930, 2930, 2931, 2786, + 2786, 2936, 2939, 2786, 2786, 2922, 2786, 2786, 2926, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2926, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + + 2786, 2786, 2927, 2927, 2928, 2928, 2930, 2930, 2931, 2786, + 2786, 2936, 2939, 2786, 2786, 2922, 2786, 2786, 2926, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2927, 2927, 2928, 2928, 2930, 2930, + 2786, 2786, 2786, 2922, 2786, 2786, 2926, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2927, 2927, 2928, 2930, 2786, 2786, 2786, 2922, + 2786, 2786, 2926, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2927, 2786, 2786, 2786, 2922, 2786, 2786, + 2926, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2922, 2786, 2786, 2926, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2922, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 0, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786 } ; -static yyconst flex_int16_t yy_nxt[17539] = +static yyconst flex_int16_t yy_nxt[17967] = { 0, - 58, 59, 60, 59, 61, 62, 63, 64, 65, 66, - 66, 61, 67, 68, 69, 70, 71, 72, 72, 61, - 61, 61, 73, 61, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 64, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 64, 64, - 58, 64, 97, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 64, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 64, 64, 58, - 58, 58, 58, 58, 58, 58, 58, 58, 58, 98, - 99, 100, 101, 102, 103, 104, 104, 105, 104, 104, - - 104, 106, 106, 104, 107, 107, 108, 109, 104, 109, - 104, 104, 110, 110, 104, 104, 104, 104, 104, 106, - 106, 106, 106, 106, 111, 106, 106, 112, 106, 106, - 106, 106, 106, 106, 106, 113, 114, 115, 106, 106, - 106, 116, 106, 106, 106, 104, 106, 104, 106, 106, - 106, 106, 106, 111, 106, 106, 112, 106, 106, 106, - 106, 106, 106, 106, 113, 114, 115, 106, 106, 106, - 116, 106, 106, 106, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 117, 118, 119, 120, 121, 122, - 124, 124, 378, 379, 380, 381, 382, 383, 2579, 125, - - 125, 126, 127, 128, 127, 126, 126, 129, 129, 126, - 126, 126, 130, 131, 126, 132, 133, 126, 129, 129, - 126, 126, 126, 126, 126, 129, 129, 129, 134, 135, - 129, 136, 129, 129, 129, 129, 129, 129, 129, 137, - 138, 129, 139, 129, 140, 129, 129, 129, 129, 129, - 129, 126, 129, 126, 129, 129, 129, 134, 135, 129, - 136, 129, 129, 129, 129, 129, 129, 129, 137, 138, - 129, 139, 129, 140, 129, 129, 129, 129, 129, 129, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 141, 142, 143, 144, 145, 146, 147, 147, 105, 147, - - 147, 148, 149, 149, 150, 147, 147, 151, 147, 147, - 147, 147, 147, 149, 149, 147, 147, 147, 147, 147, - 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, - 149, 149, 149, 149, 149, 152, 149, 149, 149, 153, - 149, 149, 149, 149, 149, 149, 147, 149, 154, 149, - 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, - 149, 149, 149, 149, 152, 149, 149, 149, 153, 149, - 149, 149, 149, 149, 149, 147, 147, 147, 147, 147, - 147, 147, 147, 147, 147, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 162, 161, 161, 161, 164, 165, - - 161, 161, 166, 167, 168, 169, 170, 161, 164, 164, - 161, 161, 171, 161, 161, 164, 164, 164, 172, 173, - 164, 174, 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 175, 164, 176, 164, 164, 164, 164, 164, - 164, 161, 164, 161, 164, 164, 164, 172, 173, 164, - 174, 164, 164, 164, 164, 164, 164, 164, 164, 164, - 164, 175, 164, 176, 164, 164, 164, 164, 164, 164, - 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, - 161, 161, 177, 161, 178, 161, 180, 181, 180, 232, - 180, 181, 180, 182, 232, 235, 183, 182, 184, 235, - - 183, 238, 184, 188, 189, 188, 238, 188, 189, 188, - 190, 105, 105, 191, 190, 190, 356, 191, 105, 190, - 105, 392, 392, 393, 357, 478, 392, 392, 394, 394, - 479, 233, 2585, 358, 268, 268, 233, 236, 437, 480, - 480, 236, 496, 499, 356, 356, 239, 497, 312, 2558, - 312, 239, 357, 357, 472, 473, 474, 475, 476, 477, - 515, 358, 358, 268, 268, 516, 559, 437, 2547, 521, - 580, 560, 499, 356, 2546, 581, 185, 312, 186, 312, - 185, 357, 186, 378, 379, 380, 381, 382, 383, 592, - 358, 596, 2569, 192, 593, 193, 597, 192, 521, 193, - - 194, 195, 196, 195, 194, 194, 194, 197, 198, 199, - 199, 200, 201, 202, 203, 194, 194, 204, 204, 194, - 194, 199, 194, 194, 204, 204, 204, 204, 204, 204, - 205, 204, 204, 204, 204, 204, 204, 204, 204, 206, - 204, 204, 207, 208, 204, 204, 204, 204, 204, 204, - 194, 204, 194, 204, 204, 204, 204, 204, 204, 205, - 204, 204, 204, 204, 204, 204, 204, 204, 206, 204, - 204, 207, 208, 204, 204, 204, 204, 204, 204, 199, - 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, - 194, 209, 194, 210, 194, 211, 211, 211, 211, 211, - - 211, 2564, 396, 212, 397, 397, 212, 216, 217, 216, - 385, 2563, 218, 2561, 219, 398, 220, 221, 216, 217, - 216, 456, 582, 218, 583, 219, 2560, 220, 221, 225, - 226, 225, 751, 751, 227, 499, 227, 227, 227, 228, - 225, 226, 225, 519, 398, 227, 584, 227, 227, 227, - 228, 582, 2557, 583, 423, 499, 1454, 406, 457, 458, - 459, 460, 461, 462, 499, 603, 753, 753, 2508, 520, - 604, 407, 519, 585, 408, 584, 378, 379, 380, 381, - 382, 383, 2486, 423, 499, 213, 406, 214, 213, 605, - 214, 386, 387, 388, 389, 390, 391, 222, 520, 223, - - 407, 615, 585, 408, 619, 2526, 616, 2525, 222, 620, - 223, 378, 379, 380, 381, 382, 383, 2475, 605, 229, - 2517, 230, 378, 379, 380, 381, 382, 383, 392, 392, - 229, 1599, 230, 244, 245, 246, 245, 244, 247, 248, - 249, 250, 251, 244, 244, 244, 244, 252, 244, 244, - 249, 249, 244, 253, 244, 244, 254, 255, 249, 249, - 249, 249, 256, 257, 249, 249, 249, 249, 258, 249, - 249, 249, 249, 249, 259, 249, 249, 249, 249, 249, - 249, 249, 249, 244, 249, 260, 255, 249, 249, 249, - 249, 256, 257, 249, 249, 249, 249, 258, 249, 249, - - 249, 249, 249, 259, 249, 249, 249, 249, 249, 249, - 249, 249, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 261, 262, 263, 264, 265, 266, 270, 271, - 270, 409, 272, 273, 2475, 274, 275, 276, 270, 271, - 270, 277, 272, 273, 410, 274, 275, 276, 404, 499, - 2511, 277, 405, 411, 518, 522, 601, 602, 499, 412, - 409, 427, 545, 546, 547, 548, 549, 550, 2443, 278, - 606, 680, 752, 410, 2501, 751, 751, 404, 499, 278, - 2405, 405, 411, 518, 522, 601, 602, 499, 412, 2481, - 427, 2480, 378, 379, 380, 381, 382, 383, 278, 606, - - 680, 378, 379, 380, 381, 382, 383, 2477, 278, 378, - 379, 380, 381, 382, 383, 2398, 478, 2476, 279, 2381, - 280, 479, 378, 379, 380, 381, 382, 383, 279, 2359, - 280, 281, 282, 283, 282, 281, 284, 285, 286, 287, - 288, 289, 281, 281, 281, 290, 281, 281, 286, 286, - 281, 281, 281, 281, 281, 286, 286, 286, 286, 286, - 291, 286, 286, 286, 286, 286, 292, 286, 286, 286, - 286, 286, 293, 286, 286, 286, 286, 286, 286, 286, - 286, 281, 286, 281, 286, 286, 286, 286, 286, 291, - 286, 286, 286, 286, 286, 292, 286, 286, 286, 286, - - 286, 293, 286, 286, 286, 286, 286, 286, 286, 286, - 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - 294, 295, 296, 297, 298, 299, 105, 105, 105, 105, - 105, 300, 301, 301, 302, 105, 105, 105, 105, 105, - 105, 105, 105, 301, 301, 105, 105, 105, 105, 303, - 301, 301, 301, 301, 301, 304, 301, 301, 301, 301, - 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, - 301, 301, 301, 301, 301, 301, 105, 301, 105, 301, - 301, 301, 301, 301, 304, 301, 301, 301, 301, 301, - 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, - - 301, 301, 301, 301, 301, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 105, 305, 306, 307, 308, 309, - 310, 313, 314, 315, 314, 313, 316, 317, 318, 319, - 313, 313, 313, 320, 321, 322, 323, 313, 324, 324, - 313, 325, 326, 313, 327, 328, 318, 318, 318, 318, - 318, 329, 318, 318, 318, 318, 318, 318, 318, 318, - 318, 318, 318, 330, 318, 318, 318, 318, 318, 318, - 318, 313, 318, 331, 328, 318, 318, 318, 318, 318, - 329, 318, 318, 318, 318, 318, 318, 318, 318, 318, - 318, 318, 330, 318, 318, 318, 318, 318, 318, 318, - - 313, 313, 313, 313, 313, 313, 313, 313, 313, 313, - 332, 333, 334, 335, 336, 337, 339, 340, 339, 480, - 480, 341, 2354, 339, 340, 339, 2449, 685, 341, 342, - 1454, 359, 359, 359, 733, 343, 342, 359, 359, 359, - 773, 496, 343, 499, 344, 361, 497, 348, 349, 348, - 416, 344, 350, 774, 1444, 523, 685, 348, 349, 348, - 351, 345, 350, 733, 620, 620, 352, 780, 345, 773, - 351, 2351, 499, 344, 2442, 353, 352, 1043, 1044, 416, - 344, 354, 774, 607, 523, 353, 2441, 781, 608, 783, - 345, 354, 647, 647, 647, 784, 780, 345, 378, 379, - - 380, 381, 382, 383, 353, 1453, 346, 417, 2341, 785, - 354, 418, 607, 346, 353, 419, 781, 608, 783, 2339, - 354, 360, 450, 515, 784, 968, 1597, 360, 516, 363, - 364, 365, 366, 367, 368, 2430, 417, 355, 785, 2300, - 418, 559, 990, 991, 419, 992, 560, 355, 369, 369, - 428, 450, 369, 369, 968, 438, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 439, 969, 369, 369, 369, - 369, 369, 378, 379, 380, 381, 382, 383, 580, 428, - 592, 536, 648, 581, 438, 593, 2413, 378, 379, 380, - 381, 382, 383, 970, 439, 969, 2409, 971, 369, 1449, - - 369, 378, 379, 380, 381, 382, 383, 377, 377, 377, - 377, 377, 377, 377, 377, 377, 378, 379, 380, 381, - 382, 383, 970, 647, 647, 647, 971, 369, 369, 369, - 369, 369, 369, 369, 369, 369, 369, 371, 372, 373, - 374, 375, 376, 399, 609, 400, 681, 681, 681, 499, - 401, 402, 403, 413, 420, 499, 414, 421, 519, 415, - 934, 610, 972, 973, 422, 538, 539, 540, 541, 542, - 543, 1598, 399, 609, 400, 681, 681, 681, 499, 401, - 402, 403, 413, 420, 499, 414, 421, 519, 415, 934, - 610, 972, 973, 422, 751, 751, 2403, 378, 379, 380, - - 381, 382, 383, 688, 688, 688, 2284, 378, 379, 380, - 381, 382, 383, 648, 424, 2395, 378, 379, 380, 381, - 382, 383, 425, 429, 444, 454, 522, 430, 426, 433, - 499, 445, 377, 377, 499, 431, 682, 434, 499, 432, - 926, 446, 377, 424, 377, 377, 435, 520, 2394, 436, - 2272, 425, 429, 444, 454, 522, 430, 426, 433, 499, - 445, 377, 377, 499, 431, 682, 434, 499, 432, 926, - 446, 377, 2189, 377, 377, 435, 520, 927, 436, 378, - 379, 380, 381, 382, 383, 499, 2261, 378, 379, 380, - 381, 382, 383, 689, 378, 379, 380, 381, 382, 383, - - 440, 499, 447, 441, 448, 925, 927, 449, 523, 442, - 481, 481, 499, 2177, 499, 443, 463, 463, 463, 463, - 463, 463, 463, 463, 463, 1126, 1126, 1306, 1306, 440, - 499, 447, 441, 448, 925, 2226, 449, 523, 442, 2362, - 974, 499, 482, 975, 443, 464, 465, 465, 465, 465, - 465, 465, 465, 465, 378, 379, 380, 381, 382, 383, - 451, 378, 379, 380, 381, 382, 383, 452, 453, 974, - 596, 482, 975, 2220, 603, 597, 981, 377, 485, 604, - 377, 2218, 472, 473, 474, 475, 476, 477, 2357, 451, - 472, 473, 474, 475, 476, 477, 452, 453, 658, 659, - - 660, 661, 662, 663, 2353, 981, 377, 485, 483, 377, - 466, 466, 466, 466, 466, 466, 466, 466, 466, 467, - 467, 467, 467, 467, 467, 467, 468, 469, 470, 470, - 470, 470, 470, 470, 470, 470, 470, 483, 484, 472, - 473, 474, 475, 476, 477, 486, 487, 471, 471, 471, - 471, 471, 471, 471, 471, 471, 1123, 1123, 1123, 1123, - 472, 473, 474, 475, 476, 477, 2204, 484, 637, 637, - 637, 552, 638, 639, 486, 487, 688, 688, 688, 1125, - 1125, 640, 2346, 472, 473, 474, 475, 476, 477, 1125, - 1125, 472, 473, 474, 475, 476, 477, 488, 488, 488, - - 488, 488, 488, 488, 488, 488, 2336, 472, 473, 474, - 475, 476, 477, 489, 490, 490, 490, 490, 490, 490, - 490, 490, 491, 491, 491, 491, 491, 491, 491, 491, - 491, 492, 492, 492, 492, 492, 492, 492, 493, 494, - 495, 495, 495, 495, 495, 495, 495, 495, 495, 498, - 498, 498, 553, 554, 555, 556, 557, 558, 641, 982, - 500, 2335, 500, 501, 1126, 1126, 689, 2185, 394, 394, - 2596, 2596, 2596, 586, 983, 502, 503, 587, 504, 815, - 2331, 2596, 2330, 2596, 501, 984, 588, 505, 982, 506, - 589, 507, 699, 700, 701, 702, 703, 704, 2596, 2596, - - 2596, 2171, 586, 983, 502, 503, 587, 504, 815, 2596, - 564, 2596, 501, 2328, 984, 588, 505, 615, 506, 589, - 507, 2160, 616, 2306, 517, 499, 499, 499, 499, 499, - 499, 499, 499, 499, 2304, 816, 816, 508, 509, 510, - 511, 512, 513, 498, 498, 498, 817, 565, 566, 567, - 568, 569, 570, 517, 500, 561, 500, 501, 508, 509, - 514, 511, 512, 513, 1303, 1303, 624, 624, 624, 502, - 503, 625, 504, 626, 2298, 817, 1303, 1303, 2297, 627, - 2295, 505, 562, 506, 561, 507, 508, 509, 514, 511, - 512, 513, 718, 719, 720, 721, 722, 723, 502, 503, - - 935, 504, 745, 746, 747, 748, 749, 750, 499, 499, - 505, 562, 506, 524, 507, 928, 499, 525, 1305, 1305, - 545, 546, 547, 548, 549, 550, 526, 2121, 985, 935, - 527, 508, 509, 510, 511, 512, 513, 499, 499, 1305, - 1305, 2290, 524, 2115, 928, 499, 525, 545, 546, 547, - 548, 549, 550, 619, 2286, 526, 628, 985, 620, 527, - 528, 528, 528, 528, 528, 528, 528, 528, 528, 529, - 530, 530, 530, 530, 530, 530, 530, 530, 531, 531, + 60, 61, 62, 61, 63, 64, 65, 66, 67, 68, + 68, 63, 69, 70, 71, 72, 73, 74, 63, 63, + 63, 75, 63, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 66, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 66, 66, 60, + 66, 99, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 66, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 66, 66, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 100, 101, + 102, 103, 104, 105, 106, 106, 107, 106, 106, 106, + + 108, 108, 106, 109, 109, 110, 111, 106, 111, 106, + 106, 112, 106, 106, 106, 106, 106, 108, 108, 108, + 108, 108, 113, 108, 108, 114, 108, 108, 108, 108, + 108, 108, 108, 115, 116, 117, 108, 108, 108, 118, + 108, 108, 108, 106, 108, 106, 108, 108, 108, 108, + 108, 113, 108, 108, 114, 108, 108, 108, 108, 108, + 108, 108, 115, 116, 117, 108, 108, 108, 118, 108, + 108, 108, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 119, 120, 121, 122, 123, 124, 126, 126, + 377, 378, 379, 380, 381, 382, 2762, 127, 127, 128, + + 129, 130, 129, 128, 128, 131, 131, 128, 128, 128, + 132, 133, 128, 134, 135, 128, 131, 128, 128, 128, + 128, 128, 131, 131, 131, 136, 137, 131, 138, 131, + 131, 131, 131, 131, 131, 131, 139, 140, 131, 141, + 131, 142, 131, 131, 131, 131, 131, 131, 128, 131, + 128, 131, 131, 131, 136, 137, 131, 138, 131, 131, + 131, 131, 131, 131, 131, 139, 140, 131, 141, 131, + 142, 131, 131, 131, 131, 131, 131, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 143, 144, 145, + 146, 147, 148, 149, 149, 107, 149, 149, 150, 151, + + 151, 152, 149, 149, 153, 149, 149, 149, 149, 149, + 151, 149, 149, 149, 149, 149, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, + 151, 154, 151, 151, 151, 155, 151, 151, 151, 151, + 151, 151, 149, 151, 156, 151, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, + 154, 151, 151, 151, 155, 151, 151, 151, 151, 151, + 151, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 164, 163, 163, 163, 166, 167, 163, 163, 168, 169, + + 170, 171, 172, 163, 166, 163, 163, 173, 163, 163, + 166, 166, 166, 174, 175, 166, 176, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 177, 166, 178, + 166, 166, 166, 166, 166, 166, 163, 166, 163, 166, + 166, 166, 174, 175, 166, 176, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 177, 166, 178, 166, + 166, 166, 166, 166, 166, 163, 163, 163, 163, 163, + 163, 163, 163, 163, 163, 163, 163, 179, 163, 180, + 163, 182, 183, 182, 234, 182, 183, 182, 184, 234, + 237, 185, 184, 186, 237, 185, 240, 186, 190, 191, + + 190, 240, 190, 191, 190, 192, 107, 107, 193, 192, + 192, 479, 193, 107, 192, 107, 480, 392, 393, 355, + 394, 424, 457, 500, 522, 235, 2756, 356, 269, 269, + 235, 238, 497, 2770, 516, 238, 357, 498, 355, 517, + 241, 2765, 313, 2738, 313, 241, 356, 2726, 355, 560, + 424, 2725, 500, 522, 561, 357, 356, 269, 269, 458, + 459, 460, 461, 462, 463, 357, 2750, 355, 622, 622, + 187, 313, 188, 313, 187, 356, 188, 2744, 377, 378, + 379, 380, 381, 382, 357, 581, 2743, 194, 2741, 195, + 582, 194, 2740, 195, 196, 197, 198, 197, 196, 196, + + 196, 199, 200, 201, 201, 202, 203, 204, 205, 196, + 196, 206, 196, 196, 201, 196, 196, 206, 206, 206, + 206, 206, 206, 207, 206, 206, 206, 206, 206, 206, + 206, 206, 208, 206, 206, 209, 210, 206, 206, 206, + 206, 206, 206, 196, 206, 196, 206, 206, 206, 206, + 206, 206, 207, 206, 206, 206, 206, 206, 206, 206, + 206, 208, 206, 206, 209, 210, 206, 206, 206, 206, + 206, 206, 201, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 211, 196, 212, 196, 213, 213, + 213, 213, 213, 213, 1052, 1053, 214, 583, 2737, 214, + + 218, 219, 218, 384, 2722, 220, 2700, 221, 417, 222, + 223, 218, 219, 218, 1844, 1845, 220, 584, 221, 412, + 222, 223, 227, 228, 227, 413, 583, 229, 2708, 229, + 229, 229, 230, 227, 228, 227, 585, 417, 229, 2722, + 229, 229, 229, 230, 428, 586, 584, 500, 412, 407, + 593, 2718, 519, 2672, 413, 594, 377, 378, 379, 380, + 381, 382, 2708, 408, 2705, 585, 409, 377, 378, 379, + 380, 381, 382, 428, 586, 606, 500, 215, 407, 216, + 215, 519, 216, 385, 386, 387, 388, 389, 390, 224, + 2641, 225, 408, 597, 604, 409, 617, 2698, 598, 605, + + 224, 618, 225, 2697, 606, 377, 378, 379, 380, 381, + 382, 231, 2630, 232, 377, 378, 379, 380, 381, 382, + 753, 754, 231, 755, 232, 246, 247, 248, 247, 246, + 249, 250, 251, 252, 253, 246, 246, 246, 246, 254, + 246, 246, 251, 246, 255, 246, 246, 256, 251, 251, + 251, 251, 251, 257, 258, 251, 251, 251, 251, 259, + 251, 251, 251, 251, 251, 260, 251, 251, 251, 251, + 251, 251, 251, 251, 246, 251, 261, 251, 251, 251, + 251, 251, 257, 258, 251, 251, 251, 251, 259, 251, + 251, 251, 251, 251, 260, 251, 251, 251, 251, 251, + + 251, 251, 251, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 262, 263, 264, 265, 266, 267, 271, + 272, 271, 2688, 273, 274, 2630, 275, 276, 277, 271, + 272, 271, 278, 273, 274, 621, 275, 276, 277, 397, + 622, 398, 278, 500, 438, 500, 414, 602, 603, 415, + 445, 399, 416, 520, 500, 524, 607, 446, 376, 279, + 473, 474, 475, 476, 477, 478, 681, 447, 521, 279, + 376, 2685, 500, 438, 500, 414, 602, 603, 415, 445, + 399, 416, 520, 500, 524, 607, 446, 376, 279, 377, + 378, 379, 380, 381, 382, 681, 447, 521, 279, 376, + + 377, 378, 379, 380, 381, 382, 479, 2631, 280, 2684, + 281, 480, 377, 378, 379, 380, 381, 382, 280, 2683, + 281, 282, 283, 284, 283, 282, 285, 286, 287, 288, + 289, 290, 282, 282, 282, 291, 282, 282, 287, 282, + 282, 282, 282, 282, 287, 287, 287, 287, 287, 292, + 287, 287, 287, 287, 287, 293, 287, 287, 287, 287, + 287, 294, 287, 287, 287, 287, 287, 287, 287, 287, + 282, 287, 282, 287, 287, 287, 287, 287, 292, 287, + 287, 287, 287, 287, 293, 287, 287, 287, 287, 287, + 294, 287, 287, 287, 287, 287, 287, 287, 287, 282, + + 282, 282, 282, 282, 282, 282, 282, 282, 282, 295, + 296, 297, 298, 299, 300, 107, 107, 107, 107, 107, + 301, 302, 302, 303, 107, 107, 107, 107, 107, 107, + 107, 107, 302, 107, 107, 107, 107, 304, 302, 302, + 302, 302, 302, 305, 302, 302, 302, 302, 302, 302, + 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, + 302, 302, 302, 302, 107, 302, 107, 302, 302, 302, + 302, 302, 305, 302, 302, 302, 302, 302, 302, 302, + 302, 302, 302, 302, 302, 302, 302, 302, 302, 302, + 302, 302, 302, 107, 107, 107, 107, 107, 107, 107, + + 107, 107, 107, 306, 307, 308, 309, 310, 311, 314, + 315, 316, 315, 314, 317, 318, 319, 320, 314, 314, + 314, 321, 322, 323, 324, 314, 325, 314, 326, 327, + 314, 327, 319, 319, 319, 319, 319, 319, 328, 319, + 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + 329, 319, 319, 319, 319, 319, 319, 319, 314, 319, + 330, 319, 319, 319, 319, 319, 319, 328, 319, 319, + 319, 319, 319, 319, 319, 319, 319, 319, 319, 329, + 319, 319, 319, 319, 319, 319, 319, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 331, 332, 333, + + 334, 335, 336, 338, 339, 338, 686, 497, 340, 338, + 339, 338, 498, 2675, 340, 734, 341, 358, 358, 358, + 523, 342, 341, 500, 347, 348, 347, 342, 2585, 349, + 343, 358, 358, 358, 2665, 686, 343, 350, 455, 405, + 774, 360, 351, 406, 734, 516, 376, 344, 775, 523, + 517, 352, 500, 344, 2659, 376, 781, 353, 376, 343, + 782, 347, 348, 347, 784, 343, 349, 455, 405, 774, + 410, 2656, 406, 2653, 350, 376, 344, 775, 785, 351, + 352, 2534, 344, 411, 376, 781, 353, 376, 352, 782, + 786, 2636, 345, 784, 353, 649, 649, 649, 345, 410, + + 377, 378, 379, 380, 381, 382, 359, 785, 500, 977, + 418, 520, 411, 354, 419, 2635, 560, 352, 420, 786, + 359, 561, 2632, 353, 362, 363, 364, 365, 366, 367, + 1470, 377, 378, 379, 380, 381, 382, 500, 977, 418, + 520, 581, 397, 419, 817, 451, 582, 420, 1963, 1964, + 354, 368, 368, 429, 818, 368, 368, 978, 439, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 440, 368, + 368, 368, 368, 368, 451, 377, 378, 379, 380, 381, + 382, 2527, 429, 818, 650, 1480, 978, 439, 376, 376, + 376, 376, 376, 376, 376, 376, 376, 440, 979, 2621, + + 368, 1635, 368, 2585, 377, 378, 379, 380, 381, 382, + 377, 378, 379, 380, 381, 382, 395, 2618, 820, 377, + 378, 379, 380, 381, 382, 1475, 819, 979, 821, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 370, + 371, 372, 373, 374, 375, 400, 421, 401, 980, 422, + 425, 500, 402, 403, 404, 819, 423, 821, 426, 1637, + 2738, 537, 943, 983, 427, 464, 464, 464, 464, 464, + 464, 464, 464, 464, 400, 421, 401, 980, 422, 425, + 500, 402, 403, 404, 2612, 423, 2586, 426, 649, 649, + 649, 943, 983, 427, 1001, 1002, 1636, 1003, 2500, 377, + + 378, 379, 380, 381, 382, 611, 434, 1470, 377, 378, + 379, 380, 381, 382, 435, 377, 378, 379, 380, 381, + 382, 430, 612, 436, 500, 431, 437, 448, 523, 449, + 935, 524, 450, 432, 611, 434, 500, 433, 500, 682, + 682, 682, 2739, 435, 539, 540, 541, 542, 543, 544, + 430, 612, 436, 500, 431, 437, 448, 523, 449, 935, + 524, 450, 432, 593, 597, 500, 433, 500, 594, 598, + 984, 377, 378, 379, 380, 381, 382, 650, 1469, 377, + 378, 379, 380, 381, 382, 377, 378, 379, 380, 381, + 382, 441, 500, 608, 442, 452, 2474, 483, 609, 984, + + 443, 521, 453, 454, 933, 500, 444, 500, 985, 991, + 610, 500, 376, 936, 938, 376, 682, 682, 682, 2469, + 441, 500, 608, 442, 452, 482, 483, 609, 683, 443, + 521, 453, 454, 933, 500, 444, 500, 985, 991, 610, + 500, 376, 936, 938, 376, 473, 474, 475, 476, 477, + 478, 1475, 377, 378, 379, 380, 381, 382, 465, 466, + 466, 466, 466, 466, 466, 466, 466, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 468, 468, 468, 468, + 468, 468, 468, 469, 470, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 484, 485, 473, 474, 475, 476, + + 477, 478, 486, 992, 2591, 683, 487, 993, 488, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 1971, 1972, + 1844, 2786, 1474, 484, 485, 546, 547, 548, 549, 550, + 551, 486, 992, 604, 617, 487, 993, 488, 605, 618, + 473, 474, 475, 476, 477, 478, 473, 474, 475, 476, + 477, 478, 473, 474, 475, 476, 477, 478, 689, 689, + 689, 1994, 1995, 473, 474, 475, 476, 477, 478, 473, + 474, 475, 476, 477, 478, 489, 489, 489, 489, 489, + 489, 489, 489, 489, 490, 491, 491, 491, 491, 491, + 491, 491, 491, 492, 492, 492, 492, 492, 492, 492, + + 492, 492, 493, 493, 493, 493, 493, 493, 493, 494, + 495, 496, 496, 496, 496, 496, 496, 496, 496, 496, + 499, 499, 499, 621, 994, 565, 2466, 995, 622, 996, + 823, 501, 823, 501, 502, 1134, 553, 2028, 2029, 1963, + 2786, 2786, 2786, 2786, 500, 503, 504, 690, 505, 997, + 2584, 937, 2786, 994, 2786, 502, 995, 506, 996, 507, + 981, 508, 566, 567, 568, 569, 570, 571, 2786, 2786, + 2786, 1971, 2786, 500, 503, 504, 982, 505, 997, 2786, + 937, 2786, 502, 2105, 2106, 2583, 506, 1480, 507, 981, + 508, 1994, 2786, 518, 500, 500, 500, 500, 500, 500, + + 500, 500, 500, 2028, 2786, 982, 562, 509, 510, 511, + 512, 513, 514, 499, 499, 499, 554, 555, 556, 557, + 558, 559, 518, 2454, 501, 2452, 501, 502, 509, 510, + 515, 512, 513, 514, 998, 562, 999, 668, 503, 504, + 669, 505, 660, 661, 662, 663, 664, 665, 1037, 1038, + 506, 563, 507, 2575, 508, 509, 510, 515, 512, 513, + 514, 1479, 2572, 998, 2564, 999, 668, 503, 504, 669, + 505, 546, 547, 548, 549, 550, 551, 1037, 1038, 506, + 563, 507, 525, 508, 500, 500, 526, 2563, 660, 661, + 662, 663, 664, 665, 934, 527, 1048, 1051, 1079, 528, + + 509, 510, 511, 512, 513, 514, 2400, 1135, 2542, 1135, + 2538, 525, 1136, 500, 500, 526, 546, 547, 548, 549, + 550, 551, 2532, 934, 527, 1048, 1051, 1079, 528, 529, + 529, 529, 529, 529, 529, 529, 529, 529, 530, 531, 531, 531, 531, 531, 531, 531, 531, 532, 532, 532, - 532, 532, 532, 532, 533, 534, 535, 535, 535, 535, - - 535, 535, 535, 535, 535, 544, 544, 544, 544, 544, - 544, 544, 544, 544, 571, 571, 571, 571, 571, 571, - 571, 571, 571, 572, 573, 573, 573, 573, 573, 573, - 573, 573, 574, 574, 574, 574, 574, 574, 574, 574, - 574, 575, 575, 575, 575, 575, 575, 575, 576, 577, - 578, 578, 578, 578, 578, 578, 578, 578, 578, 631, - 631, 631, 666, 986, 632, 667, 633, 670, 668, 669, - 1306, 1306, 634, 657, 657, 657, 657, 657, 657, 657, - 657, 657, 672, 672, 672, 672, 672, 672, 672, 672, - 672, 666, 986, 987, 667, 2104, 670, 668, 669, 361, - - 378, 379, 380, 381, 382, 383, 2099, 658, 659, 660, - 661, 662, 663, 1790, 1791, 2443, 658, 659, 660, 661, - 662, 663, 987, 658, 659, 660, 661, 662, 663, 1444, - 1896, 1897, 658, 659, 660, 661, 662, 663, 671, 673, - 674, 674, 674, 674, 674, 674, 674, 674, 2094, 635, - 649, 649, 1904, 1905, 649, 649, 1790, 2596, 649, 649, - 649, 649, 649, 649, 649, 649, 649, 671, 988, 649, - 649, 649, 649, 649, 675, 675, 675, 675, 675, 675, - 675, 675, 675, 363, 364, 365, 366, 367, 368, 658, - 659, 660, 661, 662, 663, 1039, 1042, 988, 1449, 2444, - - 649, 1443, 649, 676, 676, 676, 676, 676, 676, 676, - 677, 678, 679, 679, 679, 679, 679, 679, 679, 679, - 679, 2270, 706, 707, 1039, 1042, 734, 734, 734, 649, - 649, 649, 649, 649, 649, 649, 649, 649, 649, 651, - 652, 653, 654, 655, 656, 690, 690, 1925, 1926, 690, - 690, 706, 707, 690, 690, 690, 690, 690, 690, 690, - 690, 690, 1955, 1956, 690, 690, 690, 690, 690, 2077, - 1448, 1896, 2596, 699, 700, 701, 702, 703, 704, 698, - 698, 698, 698, 698, 698, 698, 698, 698, 699, 700, - 701, 702, 703, 704, 708, 690, 2258, 690, 709, 709, - - 709, 709, 709, 709, 709, 709, 709, 710, 711, 711, - 711, 711, 711, 711, 711, 711, 735, 378, 379, 380, - 381, 382, 383, 708, 690, 690, 690, 690, 690, 690, - 690, 690, 690, 690, 692, 693, 694, 695, 696, 697, - 1904, 2596, 2025, 2026, 2062, 699, 700, 701, 702, 703, - 704, 712, 712, 712, 712, 712, 712, 712, 712, 712, - 713, 713, 713, 713, 713, 713, 713, 714, 715, 716, - 716, 716, 716, 716, 716, 716, 716, 716, 724, 717, - 717, 717, 717, 717, 717, 717, 717, 717, 725, 725, - 725, 725, 725, 725, 725, 725, 725, 726, 727, 727, - - 727, 727, 727, 727, 727, 727, 2248, 724, 728, 728, - 728, 728, 728, 728, 728, 728, 728, 729, 729, 729, - 729, 729, 729, 729, 730, 731, 718, 719, 720, 721, - 722, 723, 732, 732, 732, 732, 732, 732, 732, 732, - 732, 734, 734, 734, 754, 758, 755, 755, 759, 760, - 378, 379, 380, 381, 382, 383, 2051, 756, 744, 744, - 744, 744, 744, 744, 744, 744, 744, 1070, 1100, 2224, - 1790, 820, 1101, 2222, 758, 1910, 2041, 759, 760, 821, - 472, 473, 474, 475, 476, 477, 756, 769, 769, 769, - 745, 746, 747, 748, 749, 750, 1070, 1100, 753, 753, - - 820, 1101, 745, 746, 747, 748, 749, 750, 821, 1084, - 745, 746, 747, 748, 749, 750, 1925, 2596, 745, 746, - 747, 748, 749, 750, 2031, 378, 379, 380, 381, 382, - 383, 735, 736, 736, 1896, 2211, 736, 736, 1084, 2003, - 736, 736, 736, 736, 736, 736, 736, 736, 736, 1955, - 2596, 736, 736, 736, 736, 736, 761, 761, 761, 761, - 761, 761, 761, 761, 761, 762, 763, 763, 763, 763, - 763, 763, 763, 763, 769, 769, 769, 770, 776, 776, - 776, 1104, 736, 2207, 736, 764, 764, 764, 764, 764, - 764, 764, 764, 764, 765, 765, 765, 765, 765, 765, - - 765, 766, 767, 776, 776, 776, 359, 359, 359, 2018, - 1104, 736, 736, 736, 736, 736, 736, 736, 736, 736, - 736, 738, 739, 740, 741, 742, 743, 768, 768, 768, - 768, 768, 768, 768, 768, 768, 362, 362, 362, 362, - 362, 362, 362, 362, 362, 787, 787, 787, 787, 787, - 787, 787, 787, 787, 788, 789, 789, 789, 789, 789, - 789, 789, 789, 1105, 770, 2011, 1106, 385, 777, 790, - 790, 790, 790, 790, 790, 790, 790, 790, 791, 791, - 791, 791, 791, 791, 791, 792, 793, 813, 813, 813, - 2025, 2596, 1105, 777, 536, 1106, 360, 794, 794, 794, - - 794, 794, 794, 794, 794, 794, 369, 369, 1904, 2197, - 369, 369, 2004, 2010, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 2194, 2188, 369, 369, 369, 369, 369, - 370, 370, 370, 370, 370, 370, 370, 370, 370, 795, - 795, 795, 795, 795, 795, 795, 795, 795, 386, 387, - 388, 389, 390, 391, 2175, 1107, 369, 2163, 369, 796, - 797, 797, 797, 797, 797, 797, 797, 797, 798, 798, - 798, 798, 798, 798, 798, 798, 798, 814, 538, 539, - 540, 541, 542, 543, 1107, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 371, 372, 373, 374, 375, - - 376, 799, 799, 799, 799, 799, 799, 799, 800, 801, - 802, 802, 802, 802, 802, 802, 802, 802, 802, 377, - 377, 377, 377, 377, 377, 377, 377, 377, 463, 463, - 463, 463, 463, 463, 463, 463, 463, 803, 465, 465, - 465, 465, 465, 465, 465, 465, 466, 466, 466, 466, - 466, 466, 466, 466, 466, 467, 467, 467, 467, 467, - 467, 467, 804, 469, 470, 470, 470, 470, 470, 470, - 470, 470, 470, 384, 384, 384, 384, 384, 384, 384, - 384, 384, 805, 805, 805, 805, 805, 805, 805, 805, - 805, 806, 807, 807, 807, 807, 807, 807, 807, 807, - - 808, 808, 808, 808, 808, 808, 808, 808, 808, 809, - 809, 809, 809, 809, 809, 809, 810, 811, 812, 812, - 812, 812, 812, 812, 812, 812, 812, 396, 822, 397, - 397, 818, 823, 818, 826, 456, 819, 819, 1108, 1239, - 398, 455, 455, 455, 455, 455, 455, 455, 455, 455, - 2144, 2132, 937, 937, 2124, 824, 937, 822, 937, 937, - 937, 823, 1794, 826, 624, 624, 624, 1108, 1239, 398, - 825, 998, 457, 458, 459, 460, 461, 462, 378, 379, - 380, 381, 382, 383, 824, 827, 378, 379, 380, 381, - 382, 383, 1911, 378, 379, 380, 381, 382, 383, 825, - - 2112, 378, 379, 380, 381, 382, 383, 831, 378, 379, - 380, 381, 382, 383, 827, 2107, 499, 378, 379, 380, - 381, 382, 383, 929, 1240, 2102, 1241, 828, 829, 378, - 379, 380, 381, 382, 383, 830, 831, 836, 1243, 378, - 379, 380, 381, 382, 383, 499, 1244, 832, 837, 833, - 2080, 1707, 929, 1240, 628, 1241, 828, 829, 834, 1677, - 2023, 2021, 2558, 1655, 830, 835, 836, 1243, 378, 379, - 380, 381, 382, 383, 840, 1244, 832, 837, 833, 897, - 378, 379, 380, 381, 382, 383, 1645, 834, 378, 379, - 380, 381, 382, 383, 835, 838, 378, 379, 380, 381, - - 382, 383, 841, 840, 1756, 842, 839, 1246, 897, 847, - 1967, 1963, 378, 379, 380, 381, 382, 383, 843, 844, - 1953, 1929, 1927, 1923, 838, 378, 379, 380, 381, 382, - 383, 841, 1925, 845, 842, 839, 1246, 2030, 847, 378, - 379, 380, 381, 382, 383, 2559, 846, 843, 844, 848, - 378, 379, 380, 381, 382, 383, 378, 379, 380, 381, - 382, 383, 845, 378, 379, 380, 381, 382, 383, 378, - 379, 380, 381, 382, 383, 846, 849, 850, 848, 1917, - 1517, 1902, 1894, 1486, 378, 379, 380, 381, 382, 383, - 378, 379, 380, 381, 382, 383, 966, 966, 855, 854, - - 966, 1880, 966, 966, 966, 849, 850, 851, 378, 379, - 380, 381, 382, 383, 919, 919, 919, 919, 919, 919, - 919, 919, 852, 853, 1463, 1848, 1832, 855, 854, 378, - 379, 380, 381, 382, 383, 856, 851, 857, 858, 378, - 379, 380, 381, 382, 383, 378, 379, 380, 381, 382, - 383, 852, 853, 378, 379, 380, 381, 382, 383, 859, - 860, 1391, 1803, 1368, 856, 1788, 857, 858, 881, 378, - 379, 380, 381, 382, 383, 861, 1247, 862, 1357, 1782, - 1774, 378, 379, 380, 381, 382, 383, 864, 859, 860, - 378, 379, 380, 381, 382, 383, 1768, 881, 545, 546, - - 547, 548, 549, 550, 861, 1247, 862, 378, 379, 380, - 381, 382, 383, 1955, 863, 1248, 864, 867, 2061, 378, - 379, 380, 381, 382, 383, 378, 379, 380, 381, 382, - 383, 378, 379, 380, 381, 382, 383, 378, 379, 380, - 381, 382, 383, 863, 1248, 865, 867, 866, 499, 378, - 379, 380, 381, 382, 383, 869, 931, 868, 933, 870, - 1249, 1122, 499, 1122, 1745, 1703, 1123, 1123, 378, 379, - 380, 381, 382, 383, 865, 1186, 866, 499, 378, 379, - 380, 381, 382, 383, 869, 931, 868, 933, 870, 1249, - 1689, 499, 1687, 378, 379, 380, 381, 382, 383, 378, - - 379, 380, 381, 382, 383, 378, 379, 380, 381, 382, - 383, 1026, 1250, 1670, 1664, 499, 378, 379, 380, 381, - 382, 383, 871, 876, 930, 1660, 932, 872, 1089, 1027, - 1028, 1251, 877, 499, 878, 873, 882, 874, 1252, 879, - 1026, 1250, 883, 875, 499, 1253, 1090, 880, 1319, 1313, - 1299, 871, 876, 930, 884, 932, 872, 1089, 1027, 1028, - 1251, 877, 499, 878, 873, 882, 874, 1252, 879, 1287, - 1279, 883, 875, 1620, 1253, 1090, 880, 378, 379, 380, - 381, 382, 383, 884, 885, 1265, 896, 378, 379, 380, - 381, 382, 383, 378, 379, 380, 381, 382, 383, 888, - - 1259, 378, 379, 380, 381, 382, 383, 378, 379, 380, - 381, 382, 383, 885, 889, 896, 1254, 890, 378, 379, - 380, 381, 382, 383, 886, 637, 637, 637, 888, 1008, - 1454, 1454, 378, 379, 380, 381, 382, 383, 891, 1257, - 1449, 1449, 892, 889, 887, 1254, 890, 378, 379, 380, - 381, 382, 383, 886, 913, 1268, 378, 379, 380, 381, - 382, 383, 920, 920, 921, 922, 920, 891, 920, 920, - 920, 892, 1255, 887, 1085, 1085, 378, 379, 380, 381, - 382, 383, 893, 913, 1268, 1086, 1444, 1269, 894, 378, - 379, 380, 381, 382, 383, 895, 1444, 1596, 1592, 378, - - 379, 380, 381, 382, 383, 472, 473, 474, 475, 476, - 477, 893, 1590, 1270, 1086, 641, 1269, 894, 658, 659, - 660, 661, 662, 663, 895, 898, 898, 898, 898, 898, - 898, 898, 898, 898, 1587, 1585, 378, 379, 380, 381, - 382, 383, 1270, 378, 379, 380, 381, 382, 383, 899, - 900, 900, 900, 900, 900, 900, 900, 900, 901, 901, - 901, 901, 901, 901, 901, 901, 901, 902, 902, 902, - 902, 902, 902, 902, 903, 904, 905, 905, 905, 905, - 905, 905, 905, 905, 905, 377, 377, 377, 377, 377, - 377, 377, 377, 377, 359, 906, 906, 906, 906, 906, - - 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, - 906, 906, 377, 377, 377, 377, 377, 377, 377, 377, - 377, 907, 907, 907, 907, 907, 907, 907, 907, 907, - 907, 907, 908, 909, 907, 910, 907, 907, 907, 907, - 907, 907, 907, 907, 907, 907, 907, 907, 911, 911, - 911, 911, 911, 911, 911, 911, 911, 471, 471, 471, - 471, 471, 471, 471, 471, 471, 488, 488, 488, 488, - 488, 488, 488, 488, 488, 489, 490, 490, 490, 490, - 490, 490, 490, 490, 491, 491, 491, 491, 491, 491, + 532, 532, 532, 532, 532, 532, 533, 533, 533, 533, + 533, 533, 533, 534, 535, 536, 536, 536, 536, 536, + 536, 536, 536, 536, 545, 545, 545, 545, 545, 545, + 545, 545, 545, 572, 572, 572, 572, 572, 572, 572, + 572, 572, 573, 574, 574, 574, 574, 574, 574, 574, + + 574, 575, 575, 575, 575, 575, 575, 575, 575, 575, + 576, 576, 576, 576, 576, 576, 576, 577, 578, 579, + 579, 579, 579, 579, 579, 579, 579, 579, 587, 626, + 626, 626, 588, 756, 627, 2384, 628, 2105, 2786, 670, + 671, 589, 629, 1096, 1110, 590, 633, 633, 633, 1844, + 1137, 634, 1137, 635, 1977, 1138, 1111, 587, 1114, 636, + 672, 588, 639, 639, 639, 2382, 640, 641, 670, 671, + 589, 2523, 1096, 1110, 590, 642, 659, 659, 659, 659, + 659, 659, 659, 659, 659, 1111, 1963, 1114, 1115, 672, + 2522, 2082, 2517, 660, 661, 662, 663, 664, 665, 700, + + 701, 702, 703, 704, 705, 660, 661, 662, 663, 664, + 665, 660, 661, 662, 663, 664, 665, 1115, 630, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 689, 689, + 689, 2514, 2502, 2332, 2325, 637, 674, 675, 675, 675, + 675, 675, 675, 675, 675, 719, 720, 721, 722, 723, + 724, 643, 651, 651, 1971, 2322, 651, 651, 2320, 2089, + 651, 651, 651, 651, 651, 651, 651, 651, 651, 707, + 651, 651, 651, 651, 651, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 677, 677, 677, 677, 677, 677, + 677, 678, 679, 735, 735, 735, 2477, 1116, 707, 1117, + + 1118, 651, 2315, 651, 680, 680, 680, 680, 680, 680, + 680, 680, 680, 1100, 2313, 1100, 2472, 690, 1321, 708, + 700, 701, 702, 703, 704, 705, 1116, 2468, 1117, 1118, + 651, 651, 651, 651, 651, 651, 651, 651, 651, 651, + 653, 654, 655, 656, 657, 658, 691, 691, 708, 709, + 691, 691, 1256, 1097, 691, 691, 691, 691, 691, 691, + 691, 691, 691, 1098, 691, 691, 691, 691, 691, 699, + 699, 699, 699, 699, 699, 699, 699, 699, 709, 2298, + 2461, 1256, 736, 2459, 700, 701, 702, 703, 704, 705, + 2447, 1322, 1098, 1322, 1994, 691, 1323, 691, 2444, 2111, + + 700, 701, 702, 703, 704, 705, 710, 710, 710, 710, + 710, 710, 710, 710, 710, 711, 712, 712, 712, 712, + 712, 712, 712, 712, 691, 691, 691, 691, 691, 691, + 691, 691, 691, 691, 693, 694, 695, 696, 697, 698, + 713, 713, 713, 713, 713, 713, 713, 713, 713, 714, + 714, 714, 714, 714, 714, 714, 715, 716, 717, 717, + 717, 717, 717, 717, 717, 717, 717, 725, 718, 718, + 718, 718, 718, 718, 718, 718, 718, 726, 726, 726, + 726, 726, 726, 726, 726, 726, 727, 728, 728, 728, + 728, 728, 728, 728, 728, 2270, 725, 729, 729, 729, + + 729, 729, 729, 729, 729, 729, 730, 730, 730, 730, + 730, 730, 730, 731, 732, 719, 720, 721, 722, 723, + 724, 733, 733, 733, 733, 733, 733, 733, 733, 733, + 735, 735, 735, 746, 747, 748, 749, 750, 751, 757, + 760, 758, 761, 2440, 2431, 2255, 2415, 2411, 770, 770, + 770, 759, 745, 745, 745, 745, 745, 745, 745, 745, + 745, 377, 378, 379, 380, 381, 382, 2409, 2407, 760, + 2404, 761, 770, 770, 770, 777, 777, 777, 2398, 2397, + 759, 762, 762, 762, 762, 762, 762, 762, 762, 762, + 2395, 2212, 2390, 1257, 746, 747, 748, 749, 750, 751, + + 2205, 2386, 2193, 746, 747, 748, 749, 750, 751, 2188, + 2371, 2368, 746, 747, 748, 749, 750, 751, 2028, 736, + 737, 737, 1257, 2146, 737, 737, 2166, 2363, 737, 737, + 737, 737, 737, 737, 737, 737, 737, 771, 737, 737, + 737, 737, 737, 763, 764, 764, 764, 764, 764, 764, + 764, 764, 765, 765, 765, 765, 765, 765, 765, 765, + 765, 771, 360, 2352, 778, 777, 777, 777, 1258, 737, + 2147, 737, 766, 766, 766, 766, 766, 766, 766, 767, + 768, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 358, 358, 358, 384, 2350, 2134, 2319, 1258, 737, 737, + + 737, 737, 737, 737, 737, 737, 737, 737, 739, 740, + 741, 742, 743, 744, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 789, 790, 790, 790, 790, 790, 790, 790, + 790, 815, 815, 815, 2317, 362, 363, 364, 365, 366, + 367, 2122, 2112, 2306, 778, 791, 791, 791, 791, 791, + 791, 791, 791, 791, 792, 792, 792, 792, 792, 792, + 792, 793, 794, 385, 386, 387, 388, 389, 390, 359, + 795, 795, 795, 795, 795, 795, 795, 795, 795, 368, + 368, 2105, 2301, 368, 368, 2097, 2204, 368, 368, 368, + + 368, 368, 368, 368, 368, 368, 2090, 368, 368, 368, + 368, 368, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 796, 796, 796, 796, 796, 796, 796, 796, 796, + 816, 377, 378, 379, 380, 381, 382, 1260, 368, 2290, + 368, 797, 798, 798, 798, 798, 798, 798, 798, 798, + 799, 799, 799, 799, 799, 799, 799, 799, 799, 377, + 378, 379, 380, 381, 382, 2083, 1260, 368, 368, 368, + 368, 368, 368, 368, 368, 368, 368, 370, 371, 372, + 373, 374, 375, 800, 800, 800, 800, 800, 800, 800, + 801, 802, 803, 803, 803, 803, 803, 803, 803, 803, + + 803, 376, 376, 376, 376, 376, 376, 376, 376, 376, + 464, 464, 464, 464, 464, 464, 464, 464, 464, 804, + 466, 466, 466, 466, 466, 466, 466, 466, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 468, 468, 468, + 468, 468, 468, 468, 805, 470, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 806, 806, 806, 806, 806, 806, + 806, 806, 806, 807, 808, 808, 808, 808, 808, 808, + 808, 808, 809, 809, 809, 809, 809, 809, 809, 809, + 809, 810, 810, 810, 810, 810, 810, 810, 811, 812, + + 813, 813, 813, 813, 813, 813, 813, 813, 813, 397, + 825, 822, 823, 757, 823, 1094, 2287, 824, 826, 2282, + 939, 399, 2279, 1261, 828, 1095, 500, 1262, 1264, 827, + 456, 456, 456, 456, 456, 456, 456, 456, 456, 825, + 473, 474, 475, 476, 477, 478, 2273, 826, 829, 939, + 399, 845, 1261, 828, 1095, 500, 1262, 1264, 827, 2259, + 2258, 649, 649, 649, 377, 378, 379, 380, 381, 382, + 377, 378, 379, 380, 381, 382, 830, 829, 851, 890, + 845, 2237, 377, 378, 379, 380, 381, 382, 377, 378, + 379, 380, 381, 382, 377, 378, 379, 380, 381, 382, + + 831, 1265, 1266, 836, 832, 830, 2223, 851, 890, 2215, + 377, 378, 379, 380, 381, 382, 377, 378, 379, 380, + 381, 382, 377, 378, 379, 380, 381, 382, 1850, 831, + 1265, 1266, 836, 832, 1978, 377, 378, 379, 380, 381, + 382, 833, 834, 377, 378, 379, 380, 381, 382, 835, + 650, 1267, 377, 378, 379, 380, 381, 382, 377, 378, + 379, 380, 381, 382, 377, 378, 379, 380, 381, 382, + 833, 834, 837, 841, 838, 2201, 944, 2196, 835, 1268, + 1267, 2191, 842, 839, 500, 928, 928, 929, 930, 928, + 840, 928, 928, 928, 377, 378, 379, 380, 381, 382, + + 2184, 837, 841, 838, 397, 944, 1133, 843, 1268, 2181, + 820, 842, 839, 500, 846, 1269, 818, 847, 844, 840, + 821, 1270, 1271, 848, 377, 378, 379, 380, 381, 382, + 377, 378, 379, 380, 381, 382, 843, 377, 378, 379, + 380, 381, 382, 846, 1269, 818, 847, 844, 2169, 821, + 1270, 1271, 848, 2161, 2150, 1272, 852, 853, 457, 1755, + 1273, 854, 377, 378, 379, 380, 381, 382, 377, 378, + 379, 380, 381, 382, 377, 378, 379, 380, 381, 382, + 849, 626, 626, 626, 1272, 852, 853, 1722, 1009, 1273, + 854, 2103, 2100, 537, 850, 458, 459, 460, 461, 462, + + 463, 855, 1287, 1288, 1294, 859, 1299, 1311, 1694, 849, + 377, 378, 379, 380, 381, 382, 377, 378, 379, 380, + 381, 382, 856, 850, 377, 378, 379, 380, 381, 382, + 855, 1287, 1288, 1294, 859, 1299, 1311, 857, 858, 1333, + 865, 1684, 861, 860, 862, 377, 378, 379, 380, 381, + 382, 856, 2075, 377, 378, 379, 380, 381, 382, 377, + 378, 379, 380, 381, 382, 2072, 857, 858, 1333, 865, + 630, 861, 860, 862, 863, 864, 539, 540, 541, 542, + 543, 544, 866, 869, 377, 378, 379, 380, 381, 382, + 377, 378, 379, 380, 381, 382, 920, 377, 378, 379, + + 380, 381, 382, 863, 864, 377, 378, 379, 380, 381, + 382, 866, 869, 1807, 2044, 867, 2039, 377, 378, 379, + 380, 381, 382, 377, 378, 379, 380, 381, 382, 868, + 546, 547, 548, 549, 550, 551, 1334, 871, 377, 378, + 379, 380, 381, 382, 867, 377, 378, 379, 380, 381, + 382, 2031, 870, 872, 2026, 946, 946, 1998, 868, 946, + 1996, 946, 946, 946, 1992, 1334, 871, 473, 474, 475, + 476, 477, 478, 1560, 1985, 377, 378, 379, 380, 381, + 382, 870, 872, 377, 378, 379, 380, 381, 382, 377, + 378, 379, 380, 381, 382, 873, 888, 500, 1097, 887, + + 377, 378, 379, 380, 381, 382, 874, 942, 1098, 376, + 875, 376, 1339, 1340, 377, 378, 379, 380, 381, 382, + 882, 1035, 1035, 1035, 873, 888, 500, 376, 887, 883, + 889, 884, 1555, 1544, 1969, 874, 942, 1098, 376, 875, + 376, 1339, 1340, 377, 378, 379, 380, 381, 382, 882, + 377, 378, 379, 380, 381, 382, 376, 1961, 883, 889, + 884, 377, 378, 379, 380, 381, 382, 377, 378, 379, + 380, 381, 382, 876, 376, 376, 376, 891, 877, 639, + 639, 639, 894, 1019, 376, 885, 878, 1513, 879, 892, + 1953, 880, 376, 886, 881, 377, 378, 379, 380, 381, + + 382, 1950, 876, 376, 376, 376, 891, 877, 1944, 893, + 1036, 894, 1487, 376, 885, 878, 895, 879, 892, 896, + 880, 376, 886, 881, 1341, 377, 378, 379, 380, 381, + 382, 897, 1324, 1342, 1324, 898, 901, 1325, 893, 377, + 378, 379, 380, 381, 382, 895, 1912, 902, 896, 757, + 1897, 1320, 1893, 1341, 377, 378, 379, 380, 381, 382, + 897, 1095, 1342, 1412, 898, 901, 1861, 1854, 643, 899, + 903, 1343, 1451, 1452, 1453, 900, 902, 1454, 377, 378, + 379, 380, 381, 382, 377, 378, 379, 380, 381, 382, + 1095, 1849, 377, 378, 379, 380, 381, 382, 899, 903, + + 1343, 1451, 1452, 1453, 900, 1388, 1454, 1842, 377, 378, + 379, 380, 381, 382, 1377, 1836, 377, 378, 379, 380, + 381, 382, 1828, 377, 378, 379, 380, 381, 382, 904, + 904, 904, 904, 904, 904, 904, 904, 904, 905, 906, + 906, 906, 906, 906, 906, 906, 906, 907, 907, 907, + 907, 907, 907, 907, 907, 907, 908, 908, 908, 908, + 908, 908, 908, 909, 910, 911, 911, 911, 911, 911, + 911, 911, 911, 911, 376, 376, 376, 376, 376, 376, + 376, 376, 376, 358, 912, 912, 912, 912, 912, 912, + 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, + + 912, 376, 376, 376, 376, 376, 376, 376, 376, 376, + 913, 913, 913, 913, 913, 913, 913, 913, 913, 913, + 913, 914, 915, 913, 916, 913, 913, 913, 913, 913, + 913, 913, 913, 913, 913, 913, 913, 917, 917, 917, + 917, 917, 917, 917, 917, 917, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 489, 489, 489, 489, 489, + 489, 489, 489, 489, 490, 491, 491, 491, 491, 491, 491, 491, 491, 492, 492, 492, 492, 492, 492, 492, + 492, 492, 493, 493, 493, 493, 493, 493, 493, 918, + 495, 496, 496, 496, 496, 496, 496, 496, 496, 496, + + 921, 922, 660, 661, 662, 663, 664, 665, 923, 925, + 924, 1822, 1818, 1814, 1455, 1796, 926, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 1787, 975, 975, 921, + 922, 975, 1780, 975, 975, 975, 1761, 923, 925, 924, + 1045, 1045, 1046, 1455, 1045, 926, 1045, 1045, 1045, 1751, + 1200, 473, 474, 475, 476, 477, 478, 473, 474, 475, + 476, 477, 478, 473, 474, 475, 476, 477, 478, 473, + 474, 475, 476, 477, 478, 473, 474, 475, 476, 477, + 478, 473, 474, 475, 476, 477, 478, 927, 927, 927, + 927, 927, 927, 927, 927, 927, 927, 927, 927, 927, + + 927, 927, 927, 927, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 928, 928, 928, 928, 928, 928, 928, + 928, 928, 928, 928, 928, 928, 928, 928, 928, 928, + 928, 931, 931, 931, 931, 931, 931, 931, 931, 931, + 499, 499, 499, 1734, 1732, 1709, 2786, 2786, 2786, 1456, + 1703, 501, 1699, 501, 502, 1670, 1336, 2786, 1330, 2786, + 502, 2786, 2786, 2786, 1317, 503, 504, 1665, 505, 1304, + 1296, 397, 2786, 1346, 2786, 502, 525, 506, 1456, 507, + 526, 508, 1457, 818, 500, 2786, 2786, 2786, 1458, 527, + 1459, 1460, 1461, 528, 503, 504, 2786, 505, 2786, 502, + + 1656, 1284, 1278, 1480, 1480, 525, 506, 1276, 507, 526, + 508, 1457, 818, 500, 1462, 519, 1464, 1458, 527, 1459, + 1460, 1461, 528, 1475, 1475, 1274, 1470, 509, 510, 511, + 512, 513, 514, 509, 510, 515, 512, 513, 514, 633, + 633, 633, 1470, 1462, 519, 1464, 1014, 1634, 509, 510, + 515, 512, 513, 514, 500, 500, 500, 500, 500, 500, + 500, 500, 500, 529, 529, 529, 529, 529, 529, 529, + 529, 529, 509, 510, 515, 512, 513, 514, 530, 531, + 531, 531, 531, 531, 531, 531, 531, 532, 532, 532, + 532, 532, 532, 532, 532, 532, 533, 533, 533, 533, + + 533, 533, 533, 534, 535, 536, 536, 536, 536, 536, + 536, 536, 536, 536, 932, 531, 531, 531, 531, 531, + 531, 531, 531, 940, 565, 1629, 1627, 1623, 637, 1621, + 500, 974, 974, 974, 974, 974, 974, 974, 974, 941, + 500, 500, 500, 500, 500, 500, 500, 500, 500, 1602, + 1575, 1130, 940, 700, 701, 702, 703, 704, 705, 500, + 1510, 566, 567, 568, 569, 570, 571, 1112, 941, 499, + 945, 945, 945, 945, 945, 945, 945, 945, 945, 945, + 945, 945, 945, 945, 945, 945, 945, 500, 500, 500, + 500, 500, 500, 500, 500, 500, 946, 946, 946, 946, + + 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, + 946, 946, 946, 946, 947, 947, 947, 947, 947, 947, + 947, 947, 947, 538, 538, 538, 538, 538, 538, 538, + 538, 538, 948, 948, 948, 948, 948, 948, 948, 948, + 948, 949, 950, 950, 950, 950, 950, 950, 950, 950, + 951, 951, 951, 951, 951, 951, 951, 951, 951, 952, + 952, 952, 952, 952, 952, 952, 953, 954, 955, 955, + 955, 955, 955, 955, 955, 955, 955, 545, 545, 545, + 545, 545, 545, 545, 545, 545, 572, 572, 572, 572, + 572, 572, 572, 572, 572, 573, 574, 574, 574, 574, - 912, 494, 495, 495, 495, 495, 495, 495, 495, 495, - 495, 481, 481, 914, 917, 471, 471, 471, 471, 471, - 471, 471, 471, 471, 1277, 1282, 1294, 1307, 915, 1308, - 916, 1316, 564, 699, 700, 701, 702, 703, 704, 918, - 1544, 1119, 914, 917, 919, 919, 919, 919, 919, 919, - 919, 919, 919, 1277, 1282, 1294, 1307, 915, 1308, 916, - 1316, 1102, 472, 473, 474, 475, 476, 477, 918, 565, - 566, 567, 568, 569, 570, 472, 473, 474, 475, 476, - 477, 1485, 1098, 472, 473, 474, 475, 476, 477, 472, - 473, 474, 475, 476, 477, 472, 473, 474, 475, 476, - - 477, 1483, 1082, 1477, 472, 473, 474, 475, 476, 477, - 471, 471, 471, 471, 471, 471, 471, 471, 471, 920, - 920, 920, 920, 920, 920, 920, 920, 920, 920, 920, - 920, 920, 920, 920, 920, 920, 920, 923, 923, 923, - 923, 923, 923, 923, 923, 923, 498, 498, 498, 1056, - 816, 816, 2596, 2596, 2596, 1473, 1317, 500, 1040, 500, - 501, 817, 1471, 2596, 1460, 2596, 501, 2596, 2596, 2596, - 1322, 2025, 502, 503, 1024, 504, 2114, 1457, 2596, 1323, - 2596, 501, 1324, 524, 505, 1317, 506, 525, 507, 1325, - 817, 499, 2596, 2596, 2596, 1326, 526, 1456, 955, 1322, - - 527, 502, 503, 2596, 504, 2596, 501, 1451, 1323, 1446, - 1438, 1324, 524, 505, 813, 506, 525, 507, 1325, 1327, - 499, 1321, 1315, 518, 1326, 526, 1124, 955, 1124, 527, - 1301, 1125, 1125, 734, 508, 509, 510, 511, 512, 513, - 508, 509, 514, 511, 512, 513, 545, 546, 547, 548, - 549, 550, 518, 1289, 688, 508, 509, 514, 511, 512, - 513, 499, 499, 499, 499, 499, 499, 499, 499, 499, - 528, 528, 528, 528, 528, 528, 528, 528, 528, 1281, - 508, 509, 514, 511, 512, 513, 529, 530, 530, 530, - 530, 530, 530, 530, 530, 531, 531, 531, 531, 531, - - 531, 531, 531, 531, 532, 532, 532, 532, 532, 532, - 532, 533, 534, 535, 535, 535, 535, 535, 535, 535, - 535, 535, 924, 530, 530, 530, 530, 530, 530, 530, - 530, 499, 499, 499, 499, 499, 499, 499, 499, 499, - 498, 936, 936, 936, 936, 936, 936, 936, 936, 936, - 936, 936, 936, 936, 936, 936, 936, 936, 499, 499, - 499, 499, 499, 499, 499, 499, 499, 937, 937, 937, - 937, 937, 937, 937, 937, 937, 937, 937, 937, 937, - 937, 937, 937, 937, 937, 938, 938, 938, 938, 938, - 938, 938, 938, 938, 537, 537, 537, 537, 537, 537, - - 537, 537, 537, 939, 939, 939, 939, 939, 939, 939, - 939, 939, 940, 941, 941, 941, 941, 941, 941, 941, - 941, 942, 942, 942, 942, 942, 942, 942, 942, 942, - 943, 943, 943, 943, 943, 943, 943, 944, 945, 946, - 946, 946, 946, 946, 946, 946, 946, 946, 544, 544, - 544, 544, 544, 544, 544, 544, 544, 571, 571, 571, - 571, 571, 571, 571, 571, 571, 572, 573, 573, 573, - 573, 573, 573, 573, 573, 574, 574, 574, 574, 574, 574, 574, 574, 574, 575, 575, 575, 575, 575, 575, - 575, 576, 577, 578, 578, 578, 578, 578, 578, 578, - - 578, 578, 552, 551, 551, 551, 551, 551, 551, 551, - 551, 551, 947, 947, 947, 947, 947, 947, 947, 947, - 947, 948, 949, 949, 949, 949, 949, 949, 949, 949, - 950, 950, 950, 950, 950, 950, 950, 950, 950, 951, - 951, 951, 951, 951, 951, 951, 952, 953, 954, 954, - 954, 954, 954, 954, 954, 954, 954, 1267, 647, 637, - 956, 563, 563, 563, 563, 563, 563, 563, 563, 563, - 957, 957, 957, 957, 957, 957, 957, 957, 957, 1010, - 1010, 631, 1005, 553, 554, 555, 556, 557, 558, 956, - 958, 959, 959, 959, 959, 959, 959, 959, 959, 960, - - 960, 960, 960, 960, 960, 960, 960, 960, 961, 961, - 961, 961, 961, 961, 961, 962, 963, 647, 647, 647, - 1005, 624, 1000, 1000, 545, 546, 547, 548, 549, 550, - 964, 964, 964, 964, 964, 964, 964, 964, 964, 544, - 544, 544, 544, 544, 544, 544, 544, 544, 965, 965, - 965, 965, 965, 965, 965, 965, 965, 965, 965, 965, - 965, 965, 965, 965, 965, 544, 544, 544, 544, 544, - 544, 544, 544, 544, 966, 966, 966, 966, 966, 966, - 966, 966, 966, 966, 966, 966, 966, 966, 966, 966, - 966, 966, 967, 967, 967, 967, 967, 967, 967, 967, - - 967, 631, 631, 631, 1024, 1024, 1024, 648, 1003, 650, - 650, 650, 650, 650, 650, 650, 650, 650, 1014, 1014, - 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1015, 1016, 1016, - 1016, 1016, 1016, 1016, 1016, 1016, 1017, 1017, 1017, 1017, - 1017, 1017, 1017, 1017, 1017, 1018, 1018, 1018, 1018, 1018, - 1018, 1018, 1019, 1020, 1021, 1021, 1021, 1021, 1021, 1021, - 1021, 1021, 1021, 657, 657, 657, 657, 657, 657, 657, - 657, 657, 672, 672, 672, 672, 672, 672, 672, 672, - 672, 1022, 674, 674, 674, 674, 674, 674, 674, 674, - 1245, 635, 649, 649, 1025, 1242, 649, 649, 1121, 359, - - 649, 649, 649, 649, 649, 649, 649, 649, 649, 1029, - 1427, 649, 649, 649, 649, 649, 675, 675, 675, 675, - 675, 675, 675, 675, 675, 676, 676, 676, 676, 676, - 676, 676, 1023, 678, 776, 681, 681, 681, 1029, 1427, - 1031, 1428, 649, 782, 649, 679, 679, 679, 679, 679, - 679, 679, 679, 679, 769, 658, 659, 660, 661, 662, - 663, 1030, 718, 719, 720, 721, 722, 723, 1032, 1031, - 1428, 649, 649, 649, 649, 649, 649, 649, 649, 649, - 649, 651, 652, 653, 654, 655, 656, 1033, 775, 1071, - 1030, 658, 659, 660, 661, 662, 663, 1032, 1034, 745, - - 746, 747, 748, 749, 750, 1045, 658, 659, 660, 661, - 662, 663, 1302, 681, 1302, 686, 1033, 1303, 1303, 658, - 659, 660, 661, 662, 663, 682, 1013, 1034, 1012, 1040, - 1040, 1040, 1011, 1010, 658, 659, 660, 661, 662, 663, - 1007, 658, 659, 660, 661, 662, 663, 657, 657, 657, - 657, 657, 657, 657, 657, 657, 647, 1035, 1035, 1035, - 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, 1035, - 1035, 1035, 1035, 1035, 657, 657, 657, 657, 657, 657, - 657, 657, 657, 1036, 1036, 1036, 1036, 1036, 1036, 1036, - 1036, 1036, 1036, 1036, 1037, 1006, 1036, 1005, 1036, 1036, - - 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1041, - 688, 688, 688, 691, 691, 691, 691, 691, 691, 691, - 691, 691, 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1046, - 1046, 1047, 1048, 1048, 1048, 1048, 1048, 1048, 1048, 1048, - 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1050, - 1050, 1050, 1050, 1050, 1050, 1050, 1051, 1052, 1053, 1053, - 1053, 1053, 1053, 1053, 1053, 1053, 1053, 698, 698, 698, - 698, 698, 698, 698, 698, 698, 709, 709, 709, 709, - 709, 709, 709, 709, 709, 1054, 711, 711, 711, 711, - - 711, 711, 711, 711, 378, 379, 380, 381, 382, 383, - 689, 690, 690, 1002, 1001, 690, 690, 1000, 997, 690, - 690, 690, 690, 690, 690, 690, 690, 690, 1058, 1429, - 690, 690, 690, 690, 690, 712, 712, 712, 712, 712, - 712, 712, 712, 712, 713, 713, 713, 713, 713, 713, - 713, 1055, 715, 1056, 1056, 1056, 996, 1058, 1429, 1059, - 1430, 690, 995, 690, 716, 716, 716, 716, 716, 716, - 716, 716, 716, 699, 700, 701, 702, 703, 704, 1304, - 994, 1304, 993, 1060, 1305, 1305, 989, 597, 1059, 1430, - 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, - - 692, 693, 694, 695, 696, 697, 699, 700, 701, 702, - 703, 704, 1060, 698, 698, 698, 698, 698, 698, 698, - 698, 698, 980, 979, 978, 977, 699, 700, 701, 702, - 703, 704, 688, 1061, 1061, 1061, 1061, 1061, 1061, 1061, - 1061, 976, 786, 1057, 1061, 1061, 1061, 1061, 1061, 1061, - 1061, 1061, 1061, 698, 698, 698, 698, 698, 698, 698, - 698, 698, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, - 1062, 1062, 1062, 1063, 1064, 1062, 782, 1062, 1062, 1062, - 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1065, - 1065, 1065, 1065, 1065, 1065, 1065, 1065, 1065, 717, 717, - - 717, 717, 717, 717, 717, 717, 717, 725, 725, 725, - 725, 725, 725, 725, 725, 725, 726, 727, 727, 727, - 727, 727, 727, 727, 727, 728, 728, 728, 728, 728, + 575, 575, 575, 576, 576, 576, 576, 576, 576, 576, + 577, 578, 579, 579, 579, 579, 579, 579, 579, 579, + 579, 553, 552, 552, 552, 552, 552, 552, 552, 552, + 552, 956, 956, 956, 956, 956, 956, 956, 956, 956, + 957, 958, 958, 958, 958, 958, 958, 958, 958, 959, + 959, 959, 959, 959, 959, 959, 959, 959, 960, 960, + 960, 960, 960, 960, 960, 961, 962, 963, 963, 963, + 963, 963, 963, 963, 963, 963, 1509, 1108, 964, 965, + 564, 564, 564, 564, 564, 564, 564, 564, 564, 966, + + 966, 966, 966, 966, 966, 966, 966, 966, 1507, 1325, + 1325, 554, 555, 556, 557, 558, 559, 964, 965, 967, + 968, 968, 968, 968, 968, 968, 968, 968, 719, 720, + 721, 722, 723, 724, 1323, 1323, 546, 547, 548, 549, + 550, 551, 969, 969, 969, 969, 969, 969, 969, 969, + 969, 1321, 1092, 546, 547, 548, 549, 550, 551, 970, + 970, 970, 970, 970, 970, 970, 971, 972, 973, 973, + 973, 973, 973, 973, 973, 973, 973, 545, 545, 545, + 545, 545, 545, 545, 545, 545, 974, 974, 974, 974, + 974, 974, 974, 974, 974, 545, 545, 545, 545, 545, + + 545, 545, 545, 545, 975, 975, 975, 975, 975, 975, + 975, 975, 975, 975, 975, 975, 975, 975, 975, 975, + 975, 975, 976, 976, 976, 976, 976, 976, 976, 976, + 976, 651, 651, 1502, 1501, 651, 651, 1065, 1497, 651, + 651, 651, 651, 651, 651, 651, 651, 651, 1049, 651, + 651, 651, 651, 651, 652, 652, 652, 652, 652, 652, + 652, 652, 652, 1025, 1025, 1025, 1025, 1025, 1025, 1025, + 1025, 1025, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, + 651, 1495, 651, 1026, 1027, 1027, 1027, 1027, 1027, 1027, + 1027, 1027, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, + + 1028, 746, 747, 748, 749, 750, 751, 1485, 1035, 651, + 651, 651, 651, 651, 651, 651, 651, 651, 651, 653, + 654, 655, 656, 657, 658, 1029, 1029, 1029, 1029, 1029, + 1029, 1029, 1030, 1031, 1032, 1032, 1032, 1032, 1032, 1032, + 1032, 1032, 1032, 659, 659, 659, 659, 659, 659, 659, + 659, 659, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 1033, 675, 675, 675, 675, 675, 675, 675, 675, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 677, + 677, 677, 677, 677, 677, 677, 1034, 679, 680, 680, + 680, 680, 680, 680, 680, 680, 680, 1039, 1040, 1465, + + 1466, 1483, 1482, 1477, 1041, 659, 659, 659, 659, 659, + 659, 659, 659, 659, 1071, 1071, 1072, 1073, 1071, 1042, + 1071, 1071, 1071, 1472, 1463, 1431, 1039, 1040, 1465, 1466, + 1077, 1077, 1043, 1041, 1077, 1138, 1077, 1077, 1077, 1138, + 1136, 1136, 660, 661, 662, 663, 664, 665, 1042, 660, + 661, 662, 663, 664, 665, 660, 661, 662, 663, 664, + 665, 1043, 682, 682, 682, 1134, 660, 661, 662, 663, + 664, 665, 1049, 1049, 1049, 660, 661, 662, 663, 664, + 665, 649, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, + 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 659, + + 659, 659, 659, 659, 659, 659, 659, 659, 1045, 1045, + 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 1045, + 1045, 1045, 1045, 1045, 1045, 1045, 1047, 1047, 1047, 1047, + 1047, 1047, 1047, 1047, 1047, 689, 689, 689, 692, 692, + 692, 692, 692, 692, 692, 692, 692, 815, 1345, 1344, + 1338, 683, 1055, 1055, 1055, 1055, 1055, 1055, 1055, 1055, + 1055, 1050, 1056, 1057, 1057, 1057, 1057, 1057, 1057, 1057, + 1057, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, + 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1060, 1061, 1062, + 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 699, 699, + + 699, 699, 699, 699, 699, 699, 699, 710, 710, 710, + 710, 710, 710, 710, 710, 710, 1119, 1119, 1119, 1119, + 1119, 1119, 1119, 1119, 690, 691, 691, 1332, 1321, 691, + 691, 1319, 1315, 691, 691, 691, 691, 691, 691, 691, + 691, 691, 1467, 691, 691, 691, 691, 691, 1063, 712, + 712, 712, 712, 712, 712, 712, 712, 713, 713, 713, + 713, 713, 713, 713, 713, 713, 1065, 1065, 1065, 1484, + 735, 1467, 1494, 1496, 691, 1306, 691, 714, 714, 714, + 714, 714, 714, 714, 1064, 716, 717, 717, 717, 717, + 717, 717, 717, 717, 717, 1067, 1508, 1569, 1484, 1068, + + 689, 1494, 1496, 691, 691, 691, 691, 691, 691, 691, + 691, 691, 691, 693, 694, 695, 696, 697, 698, 1298, + 1286, 649, 639, 1069, 1067, 1508, 1569, 1021, 1068, 699, + 699, 699, 699, 699, 699, 699, 699, 699, 1021, 633, + 700, 701, 702, 703, 704, 705, 700, 701, 702, 703, + 704, 705, 1069, 1016, 1016, 1066, 689, 1070, 1070, 1070, + 1070, 1070, 1070, 1070, 1070, 626, 700, 701, 702, 703, + 704, 705, 1070, 1070, 1070, 1070, 1070, 1070, 1070, 1070, + 1070, 699, 699, 699, 699, 699, 699, 699, 699, 699, + 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1071, + + 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1071, 1074, 1074, + 1074, 1074, 1074, 1074, 1074, 1074, 1074, 718, 718, 718, + 718, 718, 718, 718, 718, 718, 726, 726, 726, 726, + 726, 726, 726, 726, 726, 727, 728, 728, 728, 728, 728, 728, 728, 728, 729, 729, 729, 729, 729, 729, - 729, 730, 731, 732, 732, 732, 732, 732, 732, 732, - 732, 732, 1066, 717, 717, 717, 717, 717, 717, 717, - 717, 717, 1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067, - 1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067, 779, - 775, 1066, 717, 717, 717, 717, 717, 717, 717, 717, - 717, 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1068, - - 734, 734, 734, 718, 719, 720, 721, 722, 723, 1068, - 1068, 772, 757, 1068, 705, 1068, 1068, 1068, 1068, 1068, - 1068, 1068, 1068, 1068, 1068, 1068, 1068, 1069, 1069, 1069, - 1069, 1069, 1069, 1069, 1069, 1069, 737, 737, 737, 737, - 737, 737, 737, 737, 737, 1072, 1072, 1072, 1072, 1072, - 1072, 1072, 1072, 1072, 1073, 1074, 1074, 1074, 1074, 1074, - 1074, 1074, 1074, 1075, 1075, 1075, 1075, 1075, 1075, 1075, - 1075, 1075, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1077, - 1078, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, 1079, - 735, 736, 736, 687, 686, 736, 736, 1085, 1085, 736, - - 736, 736, 736, 736, 736, 736, 736, 736, 1086, 1431, - 736, 736, 736, 736, 736, 744, 744, 744, 744, 744, - 744, 744, 744, 744, 761, 761, 761, 761, 761, 761, - 761, 761, 761, 1082, 1082, 1082, 1432, 1086, 1431, 684, - 1433, 736, 665, 736, 1080, 763, 763, 763, 763, 763, - 763, 763, 763, 764, 764, 764, 764, 764, 764, 764, - 764, 764, 1087, 664, 1087, 1432, 646, 1088, 1088, 1433, - 736, 736, 736, 736, 736, 736, 736, 736, 736, 736, - 738, 739, 740, 741, 742, 743, 765, 765, 765, 765, - 765, 765, 765, 1081, 767, 768, 768, 768, 768, 768, - - 768, 768, 768, 768, 754, 1091, 755, 755, 1092, 1109, - 1109, 1109, 1109, 1109, 1109, 1109, 1109, 756, 1093, 1434, - 1435, 1436, 644, 1083, 744, 744, 744, 744, 744, 744, - 744, 744, 744, 622, 1091, 621, 618, 1092, 617, 745, - 746, 747, 748, 749, 750, 614, 756, 1093, 1434, 1435, - 1436, 745, 746, 747, 748, 749, 750, 613, 612, 745, - 746, 747, 748, 749, 750, 745, 746, 747, 748, 749, - 750, 769, 769, 769, 1098, 1098, 1098, 611, 745, 746, - 747, 748, 749, 750, 734, 1094, 1094, 1094, 1094, 1094, - 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, - - 1094, 1094, 744, 744, 744, 744, 744, 744, 744, 744, - 744, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, - 1095, 1095, 599, 598, 1095, 1096, 1095, 1095, 1095, 1095, - 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1097, 1097, - 1097, 1097, 1097, 1097, 1097, 1097, 1097, 776, 776, 776, - 1102, 1102, 1102, 1112, 1112, 1112, 1112, 1112, 1112, 1112, - 1112, 770, 595, 594, 1099, 362, 362, 362, 362, 362, - 362, 362, 362, 362, 1109, 1109, 1109, 1109, 1109, 1109, - 1109, 1109, 1109, 362, 362, 362, 362, 362, 362, 362, - 362, 362, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, - - 1110, 1110, 1110, 591, 590, 1110, 395, 1110, 1110, 1110, - 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1111, - 1111, 1111, 1111, 1111, 1111, 1111, 1111, 1111, 370, 370, - 370, 370, 370, 370, 370, 370, 370, 777, 2596, 243, - 1103, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, - 370, 370, 370, 370, 370, 370, 370, 370, 370, 1113, - 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, - 243, 241, 1113, 241, 1113, 1113, 1113, 1113, 1113, 1113, - 1113, 1113, 1113, 1113, 1113, 1113, 1114, 1114, 1114, 1114, - 1114, 1114, 1114, 1114, 1114, 906, 906, 906, 906, 906, - - 906, 906, 906, 907, 907, 2596, 2596, 907, 2596, 907, - 907, 907, 384, 384, 384, 384, 384, 384, 384, 384, - 384, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, - 1115, 1115, 1115, 1115, 1115, 1115, 1115, 1115, 384, 384, - 384, 384, 384, 384, 384, 384, 384, 1116, 1116, 1116, - 1116, 1116, 1116, 1116, 1116, 1116, 1116, 1116, 819, 819, - 1116, 1127, 1116, 1116, 1116, 1116, 1116, 1116, 1116, 1116, - 1116, 1116, 1116, 1116, 1117, 1117, 1117, 1117, 1117, 1117, - 1117, 1117, 1117, 1119, 813, 813, 1128, 2596, 2596, 2596, - 1127, 378, 379, 380, 381, 382, 383, 2596, 2596, 1129, - - 1130, 378, 379, 380, 381, 382, 383, 1131, 1437, 1132, - 1255, 1255, 1255, 2596, 2596, 1128, 378, 379, 380, 381, - 382, 383, 378, 379, 380, 381, 382, 383, 1129, 1130, - 378, 379, 380, 381, 382, 383, 1131, 1437, 1132, 2596, - 378, 379, 380, 381, 382, 383, 2596, 378, 379, 380, - 381, 382, 383, 1133, 1257, 1257, 1257, 378, 379, 380, - 381, 382, 383, 1134, 378, 379, 380, 381, 382, 383, - 1439, 2596, 1440, 1120, 378, 379, 380, 381, 382, 383, - 2596, 2596, 1133, 2596, 1137, 2596, 1138, 2596, 2596, 1259, - 1259, 1259, 1134, 1135, 2596, 2596, 2596, 1441, 1136, 1439, - - 1256, 1440, 1458, 1139, 1459, 1470, 2596, 378, 379, 380, - 381, 382, 383, 1137, 1140, 1138, 378, 379, 380, 381, - 382, 383, 1135, 1265, 1024, 1024, 1441, 1136, 2596, 2596, - 2596, 1458, 1139, 1459, 1470, 1143, 378, 379, 380, 381, - 382, 383, 2596, 1140, 1258, 378, 379, 380, 381, 382, - 383, 378, 379, 380, 381, 382, 383, 378, 379, 380, - 381, 382, 383, 1141, 1143, 1144, 1472, 1142, 378, 379, - 380, 381, 382, 383, 1209, 1209, 1478, 1146, 1209, 1260, - 1209, 1209, 1209, 1145, 1208, 1208, 1208, 1208, 1208, 1208, - 1208, 1208, 1141, 1147, 1144, 1472, 1142, 1479, 378, 379, - - 380, 381, 382, 383, 2596, 1478, 1146, 2596, 2596, 1279, - 1040, 1040, 1145, 1266, 2596, 378, 379, 380, 381, 382, - 383, 2596, 1147, 2596, 1148, 1149, 1479, 2596, 378, 379, - 380, 381, 382, 383, 378, 379, 380, 381, 382, 383, - 378, 379, 380, 381, 382, 383, 2596, 378, 379, 380, - 381, 382, 383, 1148, 1149, 1150, 1152, 1484, 1538, 1539, - 920, 920, 1151, 1153, 920, 1540, 920, 920, 920, 1155, - 2596, 378, 379, 380, 381, 382, 383, 378, 379, 380, - 381, 382, 383, 2596, 1150, 1152, 1484, 1538, 1539, 2596, - 2596, 1151, 1153, 2596, 1540, 2596, 2596, 1154, 1155, 1280, - - 2596, 378, 379, 380, 381, 382, 383, 1156, 378, 379, - 380, 381, 382, 383, 378, 379, 380, 381, 382, 383, - 378, 379, 380, 381, 382, 383, 1154, 378, 379, 380, - 381, 382, 383, 1164, 2596, 1157, 1156, 1159, 1541, 1184, - 1542, 1158, 2596, 2596, 2596, 2596, 2596, 378, 379, 380, - 381, 382, 383, 2596, 1160, 1162, 2596, 2596, 378, 379, - 380, 381, 382, 383, 1157, 1163, 1159, 1541, 2596, 1542, - 1158, 378, 379, 380, 381, 382, 383, 378, 379, 380, - 381, 382, 383, 1160, 1162, 1161, 1165, 2596, 378, 379, - 380, 381, 382, 383, 1163, 2596, 378, 379, 380, 381, - - 382, 383, 378, 379, 380, 381, 382, 383, 378, 379, - 380, 381, 382, 383, 1161, 1165, 378, 379, 380, 381, - 382, 383, 378, 379, 380, 381, 382, 383, 1166, 1167, - 1543, 378, 379, 380, 381, 382, 383, 1172, 1168, 378, - 379, 380, 381, 382, 383, 378, 379, 380, 381, 382, - 383, 378, 379, 380, 381, 382, 383, 1166, 1167, 1543, - 2596, 2596, 1169, 1170, 1171, 2596, 1172, 1168, 2596, 2596, - 1287, 1056, 1056, 378, 379, 380, 381, 382, 383, 378, - 379, 380, 381, 382, 383, 378, 379, 380, 381, 382, - 383, 1169, 1170, 1171, 1173, 2596, 378, 379, 380, 381, - - 382, 383, 1174, 378, 379, 380, 381, 382, 383, 2596, - 378, 379, 380, 381, 382, 383, 2596, 2596, 2596, 2596, - 2596, 1175, 1176, 1173, 378, 379, 380, 381, 382, 383, - 1177, 1174, 455, 455, 455, 455, 455, 455, 455, 455, - 455, 2596, 2596, 2596, 378, 379, 380, 381, 382, 383, - 1175, 1176, 1178, 1179, 1180, 1583, 1186, 1186, 1186, 1177, - 1288, 378, 379, 380, 381, 382, 383, 2596, 2596, 378, - 379, 380, 381, 382, 383, 2596, 2596, 1181, 2596, 2596, - 2596, 1178, 1179, 1180, 1583, 378, 379, 380, 381, 382, - 383, 2596, 378, 379, 380, 381, 382, 383, 1182, 2596, - - 378, 379, 380, 381, 382, 383, 1181, 1185, 378, 379, - 380, 381, 382, 383, 1183, 2596, 2596, 2596, 378, 379, - 380, 381, 382, 383, 2596, 2596, 2596, 1182, 378, 379, - 380, 381, 382, 383, 2596, 1536, 1185, 1188, 1189, 2596, - 2596, 2596, 2596, 1183, 378, 379, 1187, 381, 382, 383, - 1537, 2596, 378, 379, 380, 381, 382, 383, 1192, 2596, - 378, 379, 380, 381, 382, 383, 1188, 1189, 378, 379, - 380, 381, 382, 383, 1190, 1193, 1191, 1584, 1196, 1537, - 378, 379, 380, 381, 382, 383, 2596, 1192, 378, 379, - 380, 381, 382, 383, 1229, 1229, 2596, 2596, 1229, 1199, - - 1229, 1229, 1229, 1190, 1193, 1191, 1584, 1196, 2596, 2596, - 2596, 2596, 378, 379, 380, 381, 382, 383, 1194, 1197, - 2596, 1198, 378, 379, 380, 381, 382, 383, 1199, 1195, - 378, 379, 380, 381, 382, 383, 378, 379, 380, 381, - 382, 383, 2596, 2596, 2596, 2596, 2596, 1194, 1197, 1200, - 1198, 1201, 472, 473, 474, 475, 476, 477, 1195, 1586, - 1203, 1588, 1589, 1214, 378, 379, 380, 381, 382, 383, - 378, 379, 380, 381, 382, 383, 2596, 2596, 1200, 2596, - 1201, 378, 379, 380, 381, 382, 383, 1202, 1586, 1203, - 1588, 1589, 1214, 2596, 1204, 1207, 2596, 378, 379, 380, - - 381, 382, 383, 378, 379, 380, 381, 382, 383, 1205, - 1591, 1593, 1594, 1206, 2596, 2596, 1202, 378, 379, 380, - 381, 382, 383, 1204, 1207, 472, 473, 474, 475, 476, - 477, 1595, 378, 379, 380, 381, 382, 383, 1205, 1591, - 1593, 1594, 1206, 1299, 1082, 1082, 378, 379, 380, 381, - 382, 383, 2596, 378, 379, 380, 381, 382, 383, 2596, - 1595, 378, 379, 380, 381, 382, 383, 1208, 1208, 1208, - 1208, 1208, 1208, 1208, 1208, 1208, 455, 455, 455, 455, - 455, 455, 455, 455, 455, 1209, 1209, 1209, 1209, 1209, - 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1209, - - 1209, 1209, 1209, 1210, 1210, 1210, 1210, 1210, 1210, 1210, - 1210, 1210, 377, 377, 377, 377, 377, 377, 377, 377, - 377, 1211, 1212, 1213, 2596, 1600, 1215, 472, 473, 474, - 475, 476, 477, 1300, 2596, 2596, 501, 2596, 1216, 471, - 471, 471, 471, 471, 471, 471, 471, 471, 2596, 501, - 1211, 1212, 1213, 1221, 1600, 1215, 2596, 2596, 2596, 2596, - 1217, 472, 473, 474, 475, 476, 477, 1216, 2596, 2596, - 2596, 472, 473, 474, 475, 476, 477, 472, 473, 474, - 475, 476, 477, 472, 473, 474, 475, 476, 477, 1217, - 501, 1601, 1602, 472, 473, 474, 475, 476, 477, 936, - - 936, 936, 936, 936, 936, 936, 936, 501, 2596, 2596, - 508, 509, 514, 511, 512, 513, 1218, 1219, 501, 1625, - 1601, 1602, 1629, 508, 509, 514, 511, 512, 513, 2596, - 501, 1232, 1232, 2596, 1630, 1232, 501, 1232, 1232, 1232, - 2596, 2596, 501, 2596, 1658, 1218, 1219, 1220, 1625, 1237, - 1237, 1629, 2596, 1237, 501, 1237, 1237, 1237, 1222, 2596, - 501, 2596, 1224, 1630, 508, 509, 514, 511, 512, 513, - 501, 1227, 1223, 1658, 1659, 2596, 1220, 501, 2596, 2596, - 2596, 508, 509, 514, 511, 512, 513, 1222, 501, 2596, - 1226, 1224, 508, 509, 514, 511, 512, 513, 1225, 2596, - - 1227, 2596, 2596, 1659, 508, 509, 514, 511, 512, 513, - 508, 509, 514, 511, 512, 513, 508, 509, 514, 511, - 512, 513, 2596, 2596, 2596, 2596, 2596, 1225, 508, 509, - 514, 511, 512, 513, 508, 509, 514, 511, 512, 513, - 2596, 2596, 2596, 2596, 508, 509, 514, 511, 512, 513, - 2596, 508, 509, 514, 511, 512, 513, 2596, 2596, 2596, - 2596, 2596, 508, 509, 514, 511, 512, 513, 499, 499, - 499, 499, 499, 499, 499, 499, 499, 537, 537, 537, - 537, 537, 537, 537, 537, 537, 1228, 1228, 1228, 1228, - 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, 1228, - - 1228, 1228, 1228, 537, 537, 537, 537, 537, 537, 537, - 537, 537, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, - 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, 1229, - 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1230, 551, - 551, 551, 551, 551, 551, 551, 551, 551, 1231, 1231, - 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, 1231, - 1231, 1231, 1231, 1231, 1231, 551, 551, 551, 551, 551, - 551, 551, 551, 551, 1232, 1232, 1232, 1232, 1232, 1232, - 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232, - 1232, 1232, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, - - 1233, 1234, 1235, 563, 563, 563, 563, 563, 563, 563, - 563, 563, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, - 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 2596, - 1234, 1235, 563, 563, 563, 563, 563, 563, 563, 563, - 563, 545, 546, 547, 548, 549, 550, 545, 546, 547, - 548, 549, 550, 2596, 2596, 2596, 545, 546, 547, 548, - 549, 550, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, - 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, 1237, - 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 545, - 546, 547, 548, 549, 550, 544, 544, 544, 544, 544, - - 544, 544, 544, 544, 650, 650, 650, 650, 650, 650, - 650, 650, 650, 1261, 1261, 1261, 1261, 1261, 1261, 1261, - 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, - 650, 650, 650, 650, 650, 650, 650, 650, 650, 1262, - 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, - 2596, 2596, 1262, 2596, 1262, 1262, 1262, 1262, 1262, 1262, - 1262, 1262, 1262, 1262, 1262, 1262, 1263, 1263, 1263, 1263, - 1263, 1263, 1263, 1263, 1263, 1035, 1035, 1035, 1035, 1035, - 1035, 1035, 1035, 1036, 1036, 1271, 2596, 1036, 2596, 1036, - 1036, 1036, 1272, 1274, 1669, 1683, 2596, 1273, 658, 659, - - 660, 661, 662, 663, 658, 659, 660, 661, 662, 663, - 2596, 1284, 1284, 1684, 1271, 1284, 2596, 1284, 1284, 1284, - 2596, 1272, 1274, 1669, 1683, 1276, 1273, 1275, 1283, 1283, - 1283, 1283, 1283, 1283, 1283, 1283, 658, 659, 660, 661, - 662, 663, 1684, 2596, 658, 659, 660, 661, 662, 663, - 658, 659, 660, 661, 662, 663, 1275, 658, 659, 660, - 661, 662, 663, 658, 659, 660, 661, 662, 663, 2596, - 1313, 1098, 1098, 658, 659, 660, 661, 662, 663, 657, - 657, 657, 657, 657, 657, 657, 657, 657, 691, 691, - 691, 691, 691, 691, 691, 691, 691, 1283, 1283, 1283, - - 1283, 1283, 1283, 1283, 1283, 1283, 691, 691, 691, 691, - 691, 691, 691, 691, 691, 1284, 1284, 1284, 1284, 1284, - 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, - 1284, 1284, 1284, 1285, 1285, 1285, 1285, 1285, 1285, 1285, - 1285, 1285, 1061, 1061, 1061, 1061, 1061, 1061, 1061, 1061, - 1062, 1062, 1290, 2596, 1062, 2596, 1062, 1062, 1062, 1292, - 1314, 2596, 1685, 1293, 1291, 699, 700, 701, 702, 703, - 704, 699, 700, 701, 702, 703, 704, 2596, 2596, 2596, - 2596, 1290, 698, 698, 698, 698, 698, 698, 698, 698, - 698, 1685, 1293, 1291, 2596, 2596, 2596, 699, 700, 701, - - 702, 703, 704, 2596, 699, 700, 701, 702, 703, 704, - 699, 700, 701, 702, 703, 704, 718, 719, 720, 721, - 722, 723, 718, 719, 720, 721, 722, 723, 718, 719, - 720, 721, 722, 723, 717, 717, 717, 717, 717, 717, - 717, 717, 717, 737, 737, 737, 737, 737, 737, 737, - 737, 737, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, - 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 737, - 737, 737, 737, 737, 737, 737, 737, 737, 1296, 1296, - 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1088, - 1088, 1296, 2596, 1296, 1296, 1296, 1296, 1296, 1296, 1296, - - 1296, 1296, 1296, 1296, 1296, 1297, 1297, 1297, 1297, 1297, - 1297, 1297, 1297, 1297, 1094, 1094, 1094, 1094, 1094, 1094, - 1094, 1094, 1095, 1095, 1309, 1310, 1095, 361, 1095, 1095, - 1095, 745, 746, 747, 748, 749, 750, 745, 746, 747, - 748, 749, 750, 744, 744, 744, 744, 744, 744, 744, - 744, 744, 1311, 1309, 1310, 1319, 1102, 1102, 385, 1686, - 2596, 745, 746, 747, 748, 749, 750, 361, 2596, 1119, - 813, 813, 2596, 2596, 2596, 745, 746, 747, 748, 749, - 750, 1311, 378, 379, 380, 381, 382, 383, 1686, 745, - 746, 747, 748, 749, 750, 1265, 1024, 1024, 2596, 745, - - 746, 747, 748, 749, 750, 385, 1688, 1692, 1693, 1696, - 2596, 363, 364, 365, 366, 367, 368, 362, 362, 362, - 362, 362, 362, 362, 362, 362, 370, 370, 370, 370, - 370, 370, 370, 370, 370, 1688, 1692, 1693, 1696, 386, - 387, 388, 389, 390, 391, 1320, 2596, 2596, 2596, 2596, - 2596, 363, 364, 365, 366, 367, 368, 369, 369, 1120, - 2596, 369, 369, 2596, 2596, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 1328, 1329, 369, 369, 369, 369, - 369, 2596, 2596, 2596, 1331, 1266, 386, 387, 388, 389, - 390, 391, 384, 384, 384, 384, 384, 384, 384, 384, - - 384, 2596, 2596, 1328, 1329, 2596, 2596, 369, 2596, 369, - 1453, 1259, 1259, 1331, 1454, 2596, 378, 379, 380, 381, - 382, 383, 378, 379, 380, 381, 382, 383, 2596, 1330, - 378, 379, 380, 381, 382, 383, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 369, 371, 372, 373, 374, - 375, 376, 369, 369, 1332, 1697, 369, 369, 1330, 2596, - 369, 369, 369, 369, 369, 369, 369, 369, 369, 1333, - 2596, 369, 369, 369, 369, 369, 378, 379, 380, 381, - 382, 383, 2596, 1332, 1697, 1694, 378, 379, 380, 381, - 382, 383, 2596, 2596, 2596, 1334, 2596, 1695, 1333, 1335, - - 1455, 1336, 369, 2596, 369, 2596, 378, 379, 380, 381, - 382, 383, 2596, 2596, 1694, 2596, 2596, 378, 379, 380, - 381, 382, 383, 1337, 1334, 1338, 1695, 2596, 1335, 2596, - 1336, 369, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 371, 372, 373, 374, 375, 376, 2596, 1339, 1340, - 1341, 2596, 1337, 2596, 1338, 2596, 378, 379, 380, 381, - 382, 383, 378, 379, 380, 381, 382, 383, 1279, 1040, - 1040, 378, 379, 380, 381, 382, 383, 1339, 1340, 1341, - 378, 379, 380, 381, 382, 383, 378, 379, 380, 381, - 382, 383, 1342, 1343, 378, 379, 380, 381, 382, 383, - - 1344, 1347, 1348, 378, 379, 380, 381, 382, 383, 378, - 379, 380, 381, 382, 383, 378, 379, 380, 381, 382, - 383, 1342, 1343, 2596, 2596, 1345, 2596, 1349, 1698, 1344, - 1347, 1348, 2596, 378, 379, 380, 381, 382, 383, 378, - 379, 380, 381, 382, 383, 2596, 2596, 2596, 378, 379, - 380, 381, 382, 383, 1345, 1346, 1349, 1698, 1280, 1351, - 378, 379, 380, 381, 382, 383, 378, 379, 380, 381, - 382, 383, 2596, 378, 379, 380, 381, 382, 383, 1350, - 1353, 2596, 2596, 2596, 1346, 2596, 1352, 1699, 1351, 378, - 379, 380, 381, 382, 383, 2596, 2596, 1357, 1357, 1357, - - 378, 379, 380, 381, 382, 383, 1354, 2596, 1350, 378, - 379, 380, 381, 382, 383, 1352, 1699, 2596, 378, 379, - 380, 381, 382, 383, 1355, 378, 379, 380, 381, 382, - 383, 1356, 1700, 1690, 1359, 1354, 1691, 2596, 378, 379, - 380, 381, 382, 383, 378, 379, 380, 381, 382, 383, - 2596, 2596, 2596, 1355, 378, 379, 380, 381, 382, 383, - 1356, 1700, 1690, 2596, 2596, 1691, 378, 379, 380, 381, - 382, 383, 378, 379, 380, 381, 382, 383, 1360, 378, - 379, 380, 381, 382, 383, 378, 379, 1358, 381, 382, - 383, 378, 379, 380, 381, 382, 383, 1287, 1056, 1056, - - 2596, 1361, 1362, 1701, 1372, 1702, 1364, 1360, 1363, 378, - 379, 380, 381, 382, 383, 1365, 1368, 1368, 1368, 2596, - 1299, 1082, 1082, 2596, 378, 379, 380, 381, 382, 383, - 1361, 1362, 1701, 1372, 1702, 1364, 2596, 1363, 2596, 2596, - 1366, 1313, 1098, 1098, 1365, 378, 379, 380, 381, 382, - 383, 378, 379, 380, 381, 382, 383, 378, 379, 380, - 381, 382, 383, 378, 379, 380, 381, 382, 383, 1366, - 378, 379, 380, 381, 382, 383, 378, 379, 380, 381, - 382, 383, 1367, 1370, 1724, 1725, 1393, 1288, 378, 379, - 380, 381, 382, 383, 1371, 378, 379, 380, 381, 382, - - 383, 1374, 2596, 2596, 378, 379, 1369, 381, 382, 383, - 1300, 1367, 1370, 1724, 1725, 1393, 1373, 378, 379, 380, - 381, 382, 383, 1371, 2596, 1375, 1319, 1102, 1102, 2596, - 1374, 1314, 1376, 378, 379, 380, 381, 382, 383, 378, - 379, 380, 381, 382, 383, 1373, 2596, 2596, 378, 379, - 380, 381, 382, 383, 1375, 378, 379, 380, 381, 382, - 383, 1376, 378, 379, 380, 381, 382, 383, 2596, 2596, - 2596, 378, 379, 380, 381, 382, 383, 1377, 378, 379, - 380, 381, 382, 383, 1378, 1379, 1726, 2596, 1729, 1730, - 1731, 1380, 2596, 1391, 1391, 1391, 2596, 378, 379, 380, - - 381, 382, 383, 2596, 2596, 2596, 1377, 2596, 2596, 1381, - 1732, 1733, 2596, 1378, 1379, 1726, 1320, 1729, 1730, 1731, - 1380, 1390, 465, 465, 465, 465, 465, 465, 465, 465, - 2596, 1734, 378, 379, 380, 381, 382, 383, 1381, 1732, - 1733, 1394, 378, 379, 380, 381, 382, 383, 378, 379, - 380, 381, 382, 383, 378, 379, 380, 381, 382, 383, - 1734, 2596, 2596, 2596, 1396, 2596, 1735, 1453, 1259, 1259, - 1394, 1454, 378, 379, 380, 381, 382, 383, 1186, 1186, - 1186, 378, 379, 1392, 381, 382, 383, 378, 379, 380, - 381, 382, 383, 1396, 1397, 1735, 2596, 2596, 2596, 2596, - - 1382, 2596, 1736, 1383, 1384, 1395, 1680, 2596, 1398, 2596, - 1681, 1682, 1400, 1737, 1385, 1386, 1387, 1443, 1255, 1255, - 1388, 2596, 2596, 1397, 1444, 378, 379, 380, 381, 382, - 383, 1736, 1383, 1384, 1395, 1680, 1399, 1398, 1401, 1681, - 1682, 1400, 1737, 1385, 1386, 1387, 2596, 2596, 2596, 1388, - 378, 379, 380, 381, 382, 383, 2596, 1455, 2596, 378, - 379, 380, 381, 382, 383, 1399, 2596, 1401, 1389, 378, - 379, 380, 381, 382, 383, 378, 379, 380, 381, 382, - 383, 1402, 1404, 378, 379, 380, 381, 382, 383, 1403, - 378, 379, 380, 381, 382, 383, 1405, 378, 379, 380, - - 381, 382, 383, 1406, 456, 1407, 2596, 1445, 2596, 2596, - 1402, 1404, 472, 473, 474, 475, 476, 477, 1403, 2596, - 2596, 2596, 2596, 2596, 1408, 1405, 378, 379, 380, 381, - 382, 383, 1406, 1409, 1407, 378, 379, 380, 381, 382, - 383, 457, 458, 459, 460, 461, 462, 378, 379, 380, - 381, 382, 383, 1408, 2596, 378, 379, 380, 381, 382, - 383, 1410, 1409, 456, 378, 379, 380, 381, 382, 383, - 378, 379, 380, 381, 382, 383, 501, 2596, 2596, 2596, - 1415, 378, 379, 380, 381, 382, 383, 1411, 1738, 1744, - 1410, 2596, 1747, 2596, 378, 379, 380, 381, 382, 383, - - 457, 458, 459, 460, 461, 462, 455, 455, 455, 455, - 455, 455, 455, 455, 455, 1412, 1411, 1738, 1744, 2596, - 1414, 1747, 472, 473, 474, 475, 476, 477, 1413, 472, - 473, 474, 475, 476, 477, 501, 2596, 2596, 2596, 2596, - 2596, 501, 2596, 2596, 1412, 2596, 1756, 1756, 1756, 1414, - 508, 509, 514, 511, 512, 513, 472, 473, 474, 475, - 476, 477, 1416, 1763, 2596, 1418, 472, 473, 474, 475, - 476, 477, 472, 473, 474, 475, 476, 477, 501, 2596, - 2596, 2596, 2596, 2596, 2596, 501, 1448, 1257, 1257, 2596, - 2596, 1416, 1763, 1449, 1418, 501, 1727, 536, 1764, 2596, - - 1767, 1728, 1784, 2596, 536, 2596, 1417, 2596, 1421, 508, - 509, 514, 511, 512, 513, 508, 509, 514, 511, 512, - 513, 1419, 501, 2596, 2596, 1727, 2596, 1764, 501, 1767, - 1728, 1784, 2596, 2596, 501, 1417, 1757, 1421, 2596, 1420, - 2596, 2596, 2596, 2596, 2596, 501, 2596, 2596, 1422, 2596, - 1785, 1423, 508, 509, 514, 511, 512, 513, 1424, 508, - 509, 514, 511, 512, 513, 552, 1793, 2596, 1420, 508, - 509, 514, 511, 512, 513, 552, 1450, 1422, 2596, 1785, - 1423, 538, 539, 540, 541, 542, 543, 1424, 538, 539, - 540, 541, 542, 543, 2596, 1793, 508, 509, 514, 511, - - 512, 513, 508, 509, 514, 511, 512, 513, 508, 509, - 514, 511, 512, 513, 2596, 2596, 1805, 2596, 2596, 508, - 509, 514, 511, 512, 513, 537, 537, 537, 537, 537, - 537, 537, 537, 537, 551, 551, 551, 551, 551, 551, - 551, 551, 551, 1425, 1426, 1805, 553, 554, 555, 556, - 557, 558, 564, 2596, 2596, 2596, 553, 554, 555, 556, - 557, 558, 564, 563, 563, 563, 563, 563, 563, 563, - 563, 563, 2596, 1426, 718, 719, 720, 721, 722, 723, - 2596, 545, 546, 547, 548, 549, 550, 2596, 1461, 565, - 566, 567, 568, 569, 570, 2596, 2041, 2041, 2041, 565, - - 566, 567, 568, 569, 570, 545, 546, 547, 548, 549, - 550, 649, 649, 2596, 2596, 649, 649, 1461, 1462, 649, - 649, 649, 649, 649, 649, 649, 649, 649, 1468, 1806, - 649, 649, 649, 649, 649, 650, 650, 650, 650, 650, - 650, 650, 650, 650, 1463, 1463, 1463, 1462, 2596, 1464, - 2596, 658, 659, 660, 661, 662, 663, 1465, 1806, 1807, - 1808, 649, 2596, 649, 2596, 2596, 658, 659, 660, 661, - 662, 663, 472, 473, 474, 475, 476, 477, 2596, 1467, - 658, 659, 660, 661, 662, 663, 2042, 2596, 1807, 1808, - 649, 649, 649, 649, 649, 649, 649, 649, 649, 649, - - 651, 652, 653, 654, 655, 656, 649, 649, 1467, 1469, - 649, 649, 1475, 2596, 649, 649, 649, 649, 649, 649, - 649, 649, 649, 2596, 2596, 649, 649, 649, 649, 649, - 2596, 2596, 658, 659, 1466, 661, 662, 663, 1469, 1809, - 1810, 1368, 1368, 1368, 658, 659, 660, 661, 662, 663, - 699, 700, 701, 702, 703, 704, 649, 2596, 649, 691, - 691, 691, 691, 691, 691, 691, 691, 691, 1809, 1810, - 2596, 2596, 658, 659, 660, 661, 662, 663, 1474, 1524, - 2596, 2596, 2051, 2051, 2051, 649, 649, 649, 649, 649, - 649, 649, 649, 649, 649, 651, 652, 653, 654, 655, - - 656, 690, 690, 1476, 2596, 690, 690, 1474, 1524, 690, - 690, 690, 690, 690, 690, 690, 690, 690, 1811, 1812, - 690, 690, 690, 690, 690, 545, 546, 547, 548, 549, - 550, 1525, 1476, 1486, 1486, 1486, 1570, 2596, 2596, 2596, - 699, 700, 701, 702, 703, 704, 2596, 1811, 1812, 2596, - 2596, 690, 2596, 690, 737, 737, 737, 737, 737, 737, - 737, 737, 737, 2596, 2596, 2596, 699, 700, 701, 702, - 703, 704, 2052, 1480, 472, 473, 474, 475, 476, 477, - 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, - 692, 693, 694, 695, 696, 697, 690, 690, 1481, 1482, - - 690, 690, 1480, 2596, 690, 690, 690, 690, 690, 690, - 690, 690, 690, 2596, 2596, 690, 690, 690, 690, 690, - 2596, 378, 379, 1487, 381, 382, 383, 1481, 1482, 2596, - 2596, 2596, 2596, 1813, 2596, 2596, 745, 746, 747, 748, - 749, 750, 2596, 2596, 2596, 1814, 690, 2596, 690, 472, - 473, 474, 475, 476, 477, 2596, 745, 746, 747, 748, - 749, 750, 1813, 745, 746, 747, 748, 749, 750, 2596, - 2596, 2596, 2596, 501, 1814, 690, 690, 690, 690, 690, - 690, 690, 690, 690, 690, 692, 693, 694, 695, 696, - 697, 736, 736, 2596, 2596, 736, 736, 2596, 2596, 736, - - 736, 736, 736, 736, 736, 736, 736, 736, 1815, 1575, - 736, 736, 736, 736, 736, 1816, 1817, 1488, 378, 379, - 380, 381, 382, 383, 472, 473, 474, 475, 476, 477, - 378, 379, 380, 381, 382, 383, 2596, 1815, 2596, 2596, - 2596, 736, 2596, 736, 1816, 1817, 1488, 508, 509, 514, - 511, 512, 513, 2596, 2596, 2596, 2596, 378, 379, 380, - 381, 382, 383, 1493, 2596, 2596, 2596, 2596, 2596, 2596, - 736, 736, 736, 736, 736, 736, 736, 736, 736, 736, - 738, 739, 740, 741, 742, 743, 736, 736, 1489, 1491, - 736, 736, 1493, 1818, 736, 736, 736, 736, 736, 736, - - 736, 736, 736, 2596, 2596, 736, 736, 736, 736, 736, - 1819, 2596, 2596, 2596, 2596, 2596, 2596, 1489, 1491, 2596, - 2596, 2596, 1818, 2077, 2077, 2077, 378, 379, 380, 381, - 382, 383, 2596, 2596, 2596, 2596, 736, 2078, 736, 1819, - 2596, 378, 379, 380, 381, 382, 383, 2596, 2596, 2596, - 2596, 2596, 378, 379, 380, 381, 382, 383, 1490, 2596, - 2596, 1492, 2596, 2596, 2596, 736, 736, 736, 736, 736, - 736, 736, 736, 736, 736, 738, 739, 740, 741, 742, - 743, 2596, 2596, 2596, 2596, 2596, 2596, 1490, 1494, 1495, - 1492, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 378, - - 379, 380, 381, 382, 383, 2596, 2596, 378, 379, 380, - 381, 382, 383, 2079, 1517, 1517, 1517, 1494, 1495, 1496, - 378, 379, 380, 381, 382, 383, 2596, 2596, 2596, 1518, - 2596, 1497, 2596, 2596, 2596, 378, 379, 380, 381, 382, - 383, 2596, 2596, 2596, 2596, 2596, 2596, 1820, 1496, 1821, - 378, 379, 380, 381, 382, 383, 1822, 1500, 1823, 1498, - 1497, 1824, 1443, 1255, 1255, 2596, 2596, 2596, 1499, 1444, - 378, 379, 380, 381, 382, 383, 1820, 2596, 1821, 378, - 379, 380, 381, 382, 383, 1822, 1500, 1823, 1498, 2596, - 1824, 1448, 1257, 1257, 2596, 2596, 2596, 1499, 1449, 2596, - - 2596, 2596, 2596, 2596, 1663, 2596, 1501, 2596, 2596, 2596, - 2596, 1486, 1486, 1486, 378, 379, 380, 381, 382, 383, - 378, 379, 380, 381, 382, 383, 2596, 2596, 2596, 378, - 379, 380, 381, 382, 383, 1501, 1502, 1825, 1503, 2596, - 2596, 2596, 1826, 1827, 1847, 2596, 2596, 2596, 2596, 1634, - 1504, 1505, 1445, 378, 379, 380, 381, 382, 383, 2596, - 2596, 2596, 2596, 2596, 2596, 1502, 1825, 1503, 2596, 2596, - 2596, 1826, 1827, 1847, 1507, 2596, 2596, 2596, 1634, 1504, - 2596, 1450, 378, 379, 380, 381, 382, 383, 2596, 378, - 379, 380, 381, 382, 383, 378, 379, 380, 381, 382, - - 383, 1635, 2596, 1507, 2596, 2596, 2596, 2596, 2596, 1506, - 1849, 1850, 1851, 1508, 378, 379, 380, 381, 382, 383, - 2596, 2596, 2596, 2596, 1357, 1357, 1357, 378, 379, 380, - 381, 382, 383, 378, 379, 380, 381, 382, 383, 1849, - 1850, 1851, 1508, 2596, 2596, 2596, 1510, 378, 379, 380, - 381, 382, 383, 1511, 1852, 2596, 378, 379, 380, 381, - 382, 383, 1512, 378, 379, 380, 381, 382, 383, 1853, - 1509, 2596, 2596, 2596, 2596, 1510, 2596, 2596, 2596, 2596, - 2596, 2596, 1511, 1852, 2596, 2596, 2596, 1854, 1855, 2596, - 2596, 1512, 378, 379, 380, 381, 382, 383, 1853, 1509, - - 1514, 465, 465, 465, 465, 465, 465, 465, 465, 1515, - 1517, 1517, 1517, 2596, 1513, 1856, 1854, 1855, 2596, 2596, - 2596, 2596, 2596, 2596, 1516, 1518, 1857, 2596, 2596, 2596, - 2596, 378, 379, 380, 381, 382, 383, 2596, 1515, 2596, - 2596, 2596, 2596, 2596, 1856, 2596, 2596, 2596, 2596, 1520, - 2596, 2596, 2596, 1516, 2596, 1857, 2596, 2596, 2596, 378, - 379, 380, 381, 382, 383, 1521, 378, 379, 380, 381, - 382, 383, 378, 379, 380, 381, 382, 383, 1520, 2596, - 2596, 2596, 2596, 1522, 1526, 465, 465, 465, 465, 465, - 465, 465, 465, 2596, 1521, 1858, 1527, 2596, 378, 379, - - 1519, 381, 382, 383, 2596, 2596, 378, 379, 380, 381, - 382, 383, 1522, 2596, 2596, 2596, 378, 379, 380, 381, - 382, 383, 1523, 2596, 1858, 1527, 2596, 2596, 2596, 378, - 379, 380, 381, 382, 383, 2596, 2596, 2596, 378, 379, - 380, 381, 382, 383, 378, 379, 380, 381, 382, 383, - 1859, 1523, 2596, 2596, 2596, 1860, 1861, 2596, 2596, 2596, - 2596, 1866, 2596, 1870, 2596, 2596, 2596, 2596, 378, 379, - 380, 381, 382, 383, 2596, 2596, 2596, 2596, 2596, 1859, - 2596, 2596, 2596, 1530, 1860, 1861, 2596, 2596, 2596, 2596, - 1866, 1529, 1870, 1528, 2596, 2596, 2596, 2596, 2596, 2596, - - 1886, 378, 379, 380, 381, 382, 383, 1531, 1887, 1532, - 1533, 2596, 1530, 2596, 378, 379, 380, 381, 382, 383, - 1529, 2596, 1528, 378, 379, 380, 381, 382, 383, 1886, - 1889, 1534, 2596, 2596, 2596, 2596, 1531, 1887, 1532, 1533, - 378, 379, 380, 381, 382, 383, 378, 379, 380, 381, - 382, 383, 378, 379, 380, 381, 382, 383, 2596, 1889, - 1534, 2596, 378, 379, 380, 381, 382, 383, 378, 379, - 380, 381, 382, 383, 378, 379, 380, 381, 382, 383, - 2596, 2596, 378, 379, 380, 381, 382, 383, 2596, 2596, - 2596, 1186, 906, 906, 906, 906, 906, 906, 906, 906, - - 1557, 465, 465, 465, 465, 465, 465, 465, 465, 2596, - 2596, 2596, 1604, 2596, 1713, 2596, 1906, 1907, 1915, 1920, - 378, 379, 380, 381, 382, 383, 2596, 1921, 2596, 1922, - 1535, 1463, 1463, 1463, 2596, 2596, 1605, 1928, 1930, 1558, - 2596, 2596, 2596, 1713, 1465, 1906, 1907, 1915, 1920, 2596, - 658, 659, 660, 661, 662, 663, 1921, 1606, 1922, 1535, - 472, 473, 474, 475, 476, 477, 1928, 1930, 1558, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 378, 379, 380, 381, - 382, 383, 1391, 1391, 1391, 2596, 1606, 2596, 2596, 2596, - 2596, 2596, 2596, 1933, 2596, 2596, 2596, 378, 379, 380, - - 381, 382, 383, 2596, 2596, 2596, 1934, 1545, 1546, 1547, - 1548, 1549, 1559, 1550, 1560, 1551, 2596, 2596, 2596, 1935, - 1552, 1607, 1933, 1553, 1554, 1936, 1561, 1555, 378, 379, - 380, 381, 382, 383, 2596, 1934, 1545, 1546, 1547, 1548, - 1549, 1559, 1550, 1560, 1551, 2596, 2596, 2596, 1935, 1552, - 2596, 2596, 1553, 1554, 1936, 1561, 1555, 2596, 2596, 378, - 379, 380, 381, 382, 383, 2596, 2596, 2596, 1562, 1911, - 1911, 1911, 1556, 2596, 2596, 2596, 378, 379, 380, 381, - 382, 383, 378, 379, 380, 381, 382, 383, 2596, 2596, - 2596, 378, 379, 380, 381, 382, 383, 1562, 2596, 1912, - - 1563, 2596, 2596, 2596, 378, 379, 380, 381, 382, 383, - 2596, 2596, 2596, 1582, 1937, 1564, 2596, 2596, 2596, 1938, - 1939, 1940, 2596, 2596, 2596, 1941, 1942, 1565, 1912, 1563, - 2596, 2596, 2596, 378, 379, 380, 381, 382, 383, 2596, - 2596, 2596, 1582, 1937, 1564, 1943, 1567, 2596, 1938, 1939, - 1940, 2596, 2596, 2596, 1941, 1942, 1565, 1566, 2596, 1913, - 2596, 378, 379, 380, 381, 382, 383, 1571, 545, 546, - 547, 548, 549, 550, 1943, 1567, 378, 379, 380, 381, - 382, 383, 2596, 2596, 2596, 2596, 1566, 1568, 2596, 378, - 379, 380, 381, 382, 383, 1569, 1571, 1572, 378, 379, - - 380, 381, 382, 383, 378, 379, 380, 381, 382, 383, - 378, 379, 380, 381, 382, 383, 1568, 501, 378, 379, - 380, 381, 382, 383, 1569, 2596, 1572, 2596, 2596, 501, - 472, 473, 474, 475, 476, 477, 501, 1944, 1945, 378, - 379, 380, 381, 382, 383, 1573, 1574, 472, 473, 474, - 475, 476, 477, 501, 1931, 1576, 472, 473, 474, 475, - 476, 477, 501, 2596, 2596, 2596, 1944, 1945, 501, 2596, - 1603, 1946, 1932, 1949, 1573, 1574, 501, 2596, 2596, 2596, - 1577, 2596, 2596, 1931, 1576, 2596, 2596, 1950, 1580, 1578, - 1951, 508, 509, 514, 511, 512, 513, 501, 1581, 1603, - - 1946, 1932, 1949, 508, 509, 514, 511, 512, 513, 1577, - 508, 509, 514, 511, 512, 513, 1950, 1580, 2596, 1951, - 1579, 658, 659, 660, 661, 662, 663, 508, 509, 514, - 511, 512, 513, 2596, 2596, 2596, 508, 509, 514, 511, - 512, 513, 508, 509, 514, 511, 512, 513, 2596, 1579, - 508, 509, 514, 511, 512, 513, 1621, 674, 674, 674, - 674, 674, 674, 674, 674, 378, 379, 380, 381, 382, - 383, 508, 509, 514, 511, 512, 513, 1608, 1609, 1463, - 1463, 1608, 1608, 1610, 1611, 1608, 1608, 1608, 1608, 1608, - 1608, 1612, 1608, 1608, 1611, 1611, 1608, 1608, 1608, 1608, - - 1608, 1611, 1611, 1611, 1613, 1611, 1611, 1611, 1611, 1611, - 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, - 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1608, 1611, 1608, - 1611, 1611, 1611, 1613, 1611, 1611, 1611, 1611, 1611, 1611, - 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, - 1611, 1611, 1611, 1611, 1611, 1611, 1608, 1608, 1608, 1608, - 1608, 1608, 1608, 1608, 1608, 1608, 1614, 1615, 1616, 1617, - 1618, 1619, 1622, 1964, 1965, 1623, 2596, 2596, 2596, 1626, - 658, 659, 660, 661, 662, 663, 2596, 1624, 745, 746, - 747, 748, 749, 750, 1627, 745, 746, 747, 748, 749, - - 750, 1622, 1964, 1965, 1623, 1636, 465, 465, 465, 465, - 465, 465, 465, 465, 2596, 1628, 1624, 699, 700, 701, - 702, 703, 704, 1627, 2596, 2596, 658, 659, 660, 661, - 662, 663, 658, 659, 660, 661, 662, 663, 658, 659, - 660, 661, 662, 663, 1628, 1631, 1966, 1968, 1632, 1969, - 1970, 699, 700, 701, 702, 703, 704, 1633, 2596, 2596, - 2596, 1971, 1975, 1983, 2596, 501, 699, 700, 701, 702, - 703, 704, 2596, 2596, 1631, 1966, 1968, 1632, 1969, 1970, - 2596, 2596, 2596, 2596, 2596, 1637, 1633, 2596, 2596, 2596, - 1971, 1975, 1983, 2596, 2596, 2596, 745, 746, 747, 748, - - 749, 750, 745, 746, 747, 748, 749, 750, 745, 746, - 747, 748, 749, 750, 1637, 2596, 1996, 2596, 2596, 2596, - 2596, 2596, 2596, 1638, 2596, 2596, 2596, 1997, 1999, 1639, - 2596, 2596, 2596, 2014, 2015, 2020, 2596, 2596, 2596, 508, - 509, 514, 511, 512, 513, 1996, 378, 379, 380, 381, - 382, 383, 1638, 2596, 2596, 2596, 1997, 1999, 1639, 1640, - 2022, 1642, 2014, 2015, 2020, 2027, 1641, 2596, 378, 379, - 380, 381, 382, 383, 2596, 378, 379, 380, 381, 382, - 383, 378, 379, 380, 381, 382, 383, 2596, 1640, 2022, - 1642, 2596, 2596, 2596, 2027, 1641, 1357, 906, 906, 906, - - 906, 906, 906, 906, 906, 378, 379, 380, 381, 382, - 383, 2028, 378, 379, 380, 381, 382, 383, 378, 379, - 380, 381, 382, 383, 378, 379, 380, 381, 382, 383, - 2596, 2596, 2596, 2596, 2029, 2596, 2596, 2596, 2596, 1947, - 2028, 2034, 2035, 1645, 1645, 1645, 2596, 2596, 2036, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2037, 1643, 1646, 2038, - 1948, 2039, 1644, 2029, 2596, 2596, 2596, 2040, 1947, 2596, - 2034, 2035, 2596, 1648, 2596, 2596, 2596, 2036, 2596, 378, - 379, 380, 381, 382, 383, 2037, 1643, 1651, 2038, 1948, - 2039, 1644, 2596, 2596, 2596, 2596, 2040, 2596, 2596, 2596, - - 2596, 1649, 1648, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 1651, 2596, 378, 379, - 380, 381, 382, 383, 378, 379, 380, 381, 382, 383, - 1649, 378, 379, 1647, 381, 382, 383, 378, 379, 380, - 381, 382, 383, 1650, 2596, 2596, 2596, 2043, 2044, 1653, - 2596, 2596, 378, 379, 380, 381, 382, 383, 2596, 2596, - 2596, 2596, 378, 379, 380, 381, 382, 383, 2596, 2596, - 2596, 2596, 1650, 2596, 2596, 2596, 2043, 2044, 1653, 1655, - 1655, 1655, 2045, 2046, 1652, 378, 379, 380, 381, 382, - 383, 2596, 2596, 2596, 1656, 378, 379, 380, 381, 382, - - 383, 378, 379, 380, 381, 382, 383, 2596, 2596, 1654, - 2596, 2045, 2046, 1652, 2596, 2596, 2596, 1665, 465, 465, - 465, 465, 465, 465, 465, 465, 2047, 1661, 2596, 2596, - 2596, 2596, 378, 379, 380, 381, 382, 383, 1654, 2596, - 2596, 2596, 2596, 2596, 1758, 1662, 378, 379, 380, 381, - 382, 383, 2596, 2596, 2596, 2047, 1661, 378, 379, 380, - 381, 382, 383, 1667, 2596, 2596, 2596, 378, 379, 1657, - 381, 382, 383, 1758, 1662, 2596, 2596, 2596, 2596, 378, - 379, 380, 381, 382, 383, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 1667, 2596, 1666, 1668, 658, 659, 660, 661, - - 662, 663, 378, 379, 380, 381, 382, 383, 1368, 906, - 906, 906, 906, 906, 906, 906, 906, 378, 379, 380, - 381, 382, 383, 1666, 1668, 2596, 2596, 378, 379, 380, - 381, 382, 383, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 378, 379, 380, 381, 382, 383, 2596, 2596, 2596, 2596, - 2596, 2596, 378, 379, 380, 381, 382, 383, 2596, 2596, - 1671, 2048, 2049, 378, 379, 380, 381, 382, 383, 2596, - 2596, 2596, 2596, 2596, 2050, 2053, 1672, 378, 379, 380, - 381, 382, 383, 2054, 2596, 2596, 2596, 2596, 2596, 1671, - 2048, 2049, 2596, 2596, 2596, 2596, 2596, 2596, 1673, 2596, - - 2596, 2596, 2596, 2050, 2053, 1672, 2596, 2596, 2596, 2596, - 2596, 1674, 2054, 1677, 1677, 1677, 2596, 2596, 2055, 1675, - 2596, 378, 379, 380, 381, 382, 383, 1673, 1678, 2596, - 2596, 2596, 2596, 2596, 378, 379, 380, 381, 382, 383, - 1674, 2596, 1676, 1704, 2596, 2596, 2596, 2055, 1675, 1391, - 906, 906, 906, 906, 906, 906, 906, 906, 2596, 378, - 379, 380, 381, 382, 383, 2596, 2596, 2596, 2596, 2596, - 2596, 1676, 1704, 2596, 378, 379, 380, 381, 382, 383, - 378, 379, 380, 381, 382, 383, 2596, 378, 379, 380, - 381, 382, 383, 2596, 378, 379, 380, 381, 382, 383, - - 1759, 378, 379, 1679, 381, 382, 383, 2596, 2596, 2596, - 1706, 501, 2596, 2596, 2596, 2596, 2596, 378, 379, 380, - 381, 382, 383, 2596, 2596, 1707, 1707, 1707, 2596, 1759, - 2596, 2596, 378, 379, 380, 381, 382, 383, 1705, 1706, - 1708, 2596, 2596, 2596, 2596, 658, 659, 660, 661, 662, - 663, 2596, 2596, 2596, 2056, 2057, 378, 379, 380, 381, - 382, 383, 2596, 2596, 2596, 2596, 2596, 1705, 545, 546, - 547, 548, 549, 550, 2596, 2596, 2596, 2596, 1710, 1645, - 1645, 1645, 501, 2056, 2057, 508, 509, 514, 511, 512, - 513, 1712, 2058, 1716, 1646, 378, 379, 380, 381, 382, - - 383, 378, 379, 380, 381, 382, 383, 1710, 1711, 1655, - 1655, 1655, 2596, 378, 379, 1709, 381, 382, 383, 1714, - 1712, 2058, 1716, 2596, 1656, 2596, 2596, 2596, 2596, 378, - 379, 380, 381, 382, 383, 2596, 501, 1711, 2596, 378, - 379, 380, 381, 382, 383, 2596, 2596, 2596, 1714, 1715, - 378, 379, 380, 381, 382, 383, 508, 509, 514, 511, - 512, 513, 378, 379, 380, 381, 382, 383, 501, 1773, - 472, 473, 474, 475, 476, 477, 501, 1721, 1715, 1740, - 2059, 2596, 501, 1463, 1035, 1035, 1035, 1035, 1035, 1035, - 1035, 1035, 2070, 1717, 2071, 1718, 2072, 2073, 2596, 1781, - - 2596, 2596, 501, 2596, 2596, 2074, 1721, 1723, 1740, 2059, - 508, 509, 514, 511, 512, 513, 501, 2596, 2596, 1722, - 2075, 2070, 1717, 2071, 1718, 2072, 2073, 658, 659, 660, - 661, 662, 663, 1719, 2074, 2076, 1723, 2093, 1720, 2596, - 2596, 2596, 508, 509, 514, 511, 512, 513, 1722, 2075, - 508, 509, 514, 511, 512, 513, 508, 509, 514, 511, - 512, 513, 1719, 2596, 2076, 2596, 2093, 1720, 545, 546, - 547, 548, 549, 550, 1739, 2098, 508, 509, 514, 511, - 512, 513, 2596, 1609, 1463, 1463, 2101, 2596, 1741, 2106, - 508, 509, 514, 511, 512, 513, 1612, 1609, 1463, 1463, - - 2596, 2596, 1741, 1739, 2098, 1760, 2108, 1761, 2596, 1742, - 1612, 1609, 1463, 1463, 2596, 2101, 1741, 2596, 2106, 2109, - 1609, 1463, 1463, 1742, 1612, 1741, 2596, 658, 659, 660, - 661, 662, 663, 1746, 1760, 2108, 1761, 1742, 1742, 2596, - 2596, 1765, 2113, 1762, 2596, 2118, 1742, 2119, 2109, 2120, - 1766, 2596, 1742, 699, 700, 701, 702, 703, 704, 699, - 700, 701, 702, 703, 704, 2596, 1742, 2596, 2596, 2596, - 1765, 2113, 1762, 1743, 2118, 1742, 2119, 2596, 2120, 1766, - 2596, 2596, 2596, 2596, 2596, 2123, 1837, 1743, 699, 700, - 701, 702, 703, 704, 745, 746, 747, 748, 749, 750, - - 2596, 1743, 745, 746, 747, 748, 749, 750, 2596, 2596, - 1743, 1609, 1463, 1463, 2123, 1837, 1741, 2596, 2596, 2004, - 2004, 2004, 1769, 2596, 1612, 1486, 906, 906, 906, 906, - 906, 906, 906, 906, 2596, 2596, 2596, 1742, 472, 473, - 474, 475, 476, 477, 2596, 2596, 2596, 2596, 2125, 2005, - 2596, 1769, 2596, 2596, 2596, 378, 379, 380, 381, 382, - 383, 2596, 2596, 2596, 2596, 2596, 1742, 2596, 378, 379, - 380, 381, 382, 383, 2596, 2596, 1770, 2125, 2005, 1771, - 2596, 2596, 2596, 2126, 1772, 2127, 2596, 2596, 2596, 2128, - 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 2596, - - 2129, 1743, 1609, 1463, 1463, 1770, 2596, 1741, 1771, 2006, - 2130, 2596, 2126, 1772, 2127, 1612, 2596, 2596, 2128, 2596, - 2596, 2596, 378, 379, 380, 381, 382, 383, 1742, 2129, - 2596, 2596, 2596, 378, 379, 380, 381, 382, 383, 2130, - 378, 379, 380, 381, 382, 383, 2596, 2596, 2596, 378, - 379, 380, 381, 382, 383, 2596, 2596, 1742, 1775, 465, - 465, 465, 465, 465, 465, 465, 465, 2131, 378, 379, - 380, 381, 382, 383, 378, 379, 380, 381, 382, 383, - 2596, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, - 2596, 2596, 1743, 1609, 1463, 1463, 2131, 2596, 1741, 2596, - - 2596, 2596, 2596, 2596, 2596, 2596, 1612, 378, 379, 380, - 381, 382, 383, 2596, 2596, 2596, 2596, 2596, 2596, 1742, - 1783, 465, 465, 465, 465, 465, 465, 465, 465, 1776, - 2596, 2596, 2596, 2133, 378, 379, 380, 381, 382, 383, - 1777, 2596, 2596, 2596, 2596, 2041, 2041, 2041, 1742, 1517, - 906, 906, 906, 906, 906, 906, 906, 906, 1776, 2596, - 2596, 2596, 2133, 2596, 2596, 2596, 2596, 1778, 2596, 1777, - 2596, 2596, 1749, 1750, 1750, 1750, 1750, 1750, 1750, 1750, - 1750, 2596, 1779, 1743, 1609, 1463, 1463, 2596, 2596, 1741, - 378, 379, 380, 381, 382, 383, 1778, 1612, 2134, 1707, - - 1707, 1707, 2596, 378, 379, 380, 381, 382, 383, 2596, - 1742, 1779, 2135, 2136, 1708, 2596, 2596, 2596, 378, 379, - 380, 381, 382, 383, 2596, 2596, 2596, 2134, 2596, 378, - 379, 380, 381, 382, 383, 2042, 2596, 2596, 2596, 1742, - 2596, 2135, 2136, 2596, 2596, 2596, 2596, 378, 379, 380, - 381, 382, 383, 2137, 2138, 1780, 1786, 2596, 2596, 2596, - 2596, 2139, 2140, 1751, 1751, 1751, 1751, 1751, 1751, 1751, - 1751, 1751, 2596, 1787, 1743, 1609, 1463, 1463, 2596, 2596, - 1741, 2596, 2137, 2138, 1780, 1786, 2596, 2596, 1612, 1831, - 2139, 2140, 2145, 2146, 1792, 2596, 2596, 2596, 2596, 2596, - - 2596, 1742, 1787, 378, 379, 380, 381, 382, 383, 2596, - 2596, 2596, 378, 379, 380, 381, 382, 383, 2596, 2596, - 2596, 2145, 2146, 1792, 378, 379, 380, 381, 382, 383, - 1742, 378, 379, 380, 381, 382, 383, 1794, 1794, 1794, - 2147, 2156, 2596, 2596, 2596, 378, 379, 380, 381, 382, - 383, 1797, 1795, 2157, 1752, 1752, 1752, 1752, 1752, 1752, - 1752, 1753, 1754, 2596, 2158, 1743, 1609, 1463, 1463, 2147, - 2156, 1741, 2596, 2596, 2596, 2596, 1794, 1794, 1794, 1612, - 1797, 2596, 2157, 378, 379, 380, 381, 382, 383, 2596, - 2162, 1795, 1742, 2158, 2167, 2168, 2596, 378, 379, 380, - - 381, 382, 383, 2596, 2596, 2596, 378, 379, 380, 381, - 382, 383, 2169, 2596, 2170, 2176, 1677, 1677, 1677, 2162, - 2596, 1742, 2596, 2167, 2168, 378, 379, 1796, 381, 382, - 383, 1678, 2596, 2596, 2596, 2596, 2596, 2596, 1799, 1798, - 2184, 2169, 1800, 2170, 2176, 1755, 1755, 1755, 1755, 1755, - 1755, 1755, 1755, 1755, 1801, 2596, 1743, 2596, 2596, 2596, - 378, 379, 380, 381, 382, 383, 1916, 2596, 1798, 2184, - 2596, 1800, 1804, 465, 465, 465, 465, 465, 465, 465, - 465, 2596, 2596, 1801, 2596, 2596, 2596, 1881, 2018, 2018, - 2018, 378, 379, 380, 381, 382, 383, 2596, 2596, 1828, - - 2596, 2596, 2596, 1518, 1836, 501, 1802, 1833, 465, 465, - 465, 465, 465, 465, 465, 465, 1881, 2596, 2596, 2596, - 378, 379, 380, 381, 382, 383, 1829, 1830, 1828, 2596, - 2596, 2596, 2596, 1836, 658, 659, 660, 661, 662, 663, - 2596, 1839, 2195, 2596, 2596, 378, 379, 380, 381, 382, - 383, 2596, 2596, 2596, 2596, 1829, 1830, 1834, 1835, 501, - 2596, 472, 473, 474, 475, 476, 477, 501, 2011, 2011, - 2011, 2195, 378, 379, 380, 381, 382, 383, 2019, 508, - 509, 514, 511, 512, 513, 1838, 1834, 1835, 378, 379, - 380, 381, 382, 383, 2596, 1911, 1911, 1911, 2012, 501, - - 1841, 2596, 2198, 2199, 2596, 378, 379, 380, 381, 382, - 383, 1840, 501, 2596, 1838, 2596, 2596, 2596, 378, 379, - 380, 381, 382, 383, 1842, 1912, 1862, 2012, 2596, 1841, - 501, 2198, 2199, 508, 509, 514, 511, 512, 513, 1843, - 1840, 508, 509, 514, 511, 512, 513, 2596, 2596, 2596, - 2596, 501, 2596, 1842, 1912, 1862, 2596, 501, 2013, 2218, - 2218, 2218, 2596, 1844, 2200, 2203, 1863, 2206, 1843, 1845, - 1846, 2208, 2209, 508, 509, 514, 511, 512, 513, 658, - 659, 660, 661, 662, 663, 1913, 508, 509, 514, 511, - 512, 513, 1844, 2200, 2203, 1863, 2206, 2596, 1845, 1846, - - 2208, 2209, 2596, 2596, 508, 509, 514, 511, 512, 513, - 2596, 545, 546, 547, 548, 549, 550, 658, 659, 660, - 661, 662, 663, 2596, 2596, 508, 509, 514, 511, 512, - 513, 508, 509, 514, 511, 512, 513, 1609, 1463, 1463, - 2596, 2210, 1741, 1609, 1463, 1463, 2596, 2596, 1741, 2219, - 1612, 2212, 1609, 1463, 1463, 1992, 1612, 1741, 2596, 1867, - 1868, 1868, 2596, 1742, 1741, 1612, 1882, 2596, 2213, 1742, - 2210, 2596, 1746, 2596, 1609, 1463, 1463, 2596, 1742, 1741, - 2212, 2192, 2596, 2596, 1992, 1742, 1864, 1612, 2596, 2596, - 2596, 2596, 1742, 2596, 2596, 1882, 2193, 2213, 1742, 2214, - - 1742, 658, 659, 660, 661, 662, 663, 1742, 2596, 2596, - 2192, 1875, 1868, 1868, 1742, 1864, 1876, 1883, 658, 659, - 660, 661, 662, 663, 1877, 2193, 2596, 1743, 2214, 1742, - 2596, 1865, 2596, 1743, 2596, 2596, 1884, 1878, 1885, 2596, - 2596, 2596, 1743, 2596, 2596, 2215, 1883, 2596, 2596, 1869, - 1609, 1463, 1463, 1872, 1872, 1741, 2596, 1872, 2596, 1872, - 1872, 1872, 2596, 1612, 1743, 1884, 1878, 1885, 699, 700, - 701, 702, 703, 704, 2215, 2216, 1742, 378, 379, 380, - 381, 382, 383, 699, 700, 701, 702, 703, 704, 2596, - 699, 700, 701, 702, 703, 704, 2596, 2596, 2596, 2217, - - 2596, 1879, 2596, 2596, 2216, 1742, 2596, 2094, 2094, 2094, - 2596, 2596, 2596, 2596, 2596, 1888, 2223, 2596, 2596, 2596, - 2596, 2095, 2596, 1890, 2596, 2596, 2596, 2596, 2217, 1611, - 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 2596, 2596, - 1743, 1609, 1463, 1463, 1888, 2223, 1741, 1891, 2225, 2099, - 2099, 2099, 1890, 1892, 1612, 1645, 906, 906, 906, 906, - 906, 906, 906, 906, 1646, 2228, 1893, 1742, 745, 746, - 747, 748, 749, 750, 501, 2229, 1891, 2225, 2596, 2596, - 2596, 2596, 1892, 2596, 378, 379, 380, 381, 382, 383, - 2596, 2596, 2596, 2596, 2228, 1893, 1742, 2096, 378, 379, - - 380, 381, 382, 383, 2229, 378, 379, 380, 381, 382, - 383, 1898, 378, 379, 380, 381, 382, 383, 1690, 2596, - 1609, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 2596, - 1694, 1743, 1609, 1463, 1463, 1899, 2230, 1741, 2596, 2100, - 1898, 2596, 2596, 2596, 2596, 1612, 2596, 1690, 508, 509, - 514, 511, 512, 513, 2596, 2596, 2596, 2596, 1742, 1694, - 2231, 2232, 2596, 2596, 1899, 2230, 378, 379, 380, 381, - 382, 383, 2596, 2104, 2104, 2104, 1900, 2233, 378, 379, - 380, 381, 382, 383, 2596, 2596, 2596, 1742, 1656, 2231, - 2232, 1901, 1655, 906, 906, 906, 906, 906, 906, 906, - - 906, 2596, 2596, 2596, 2596, 1900, 2233, 2596, 2596, 2596, - 2596, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, 1871, - 1901, 2596, 1743, 1609, 1463, 1463, 2596, 2596, 1741, 378, - 379, 380, 381, 382, 383, 1908, 1612, 2236, 2596, 2596, - 2596, 1909, 378, 379, 380, 381, 382, 383, 2596, 1742, - 1918, 465, 465, 465, 465, 465, 465, 465, 465, 2596, - 2596, 2596, 2596, 2105, 1908, 2596, 2236, 2596, 2596, 2596, - 1909, 2596, 378, 379, 380, 381, 382, 383, 1742, 2596, - 2220, 2220, 2220, 2596, 2596, 2596, 2596, 2596, 1958, 378, - 379, 380, 381, 382, 383, 1914, 378, 379, 380, 381, - - 382, 383, 1611, 1611, 1611, 1611, 1611, 1611, 1611, 1611, - 1611, 2596, 2596, 1743, 1609, 1463, 1463, 1958, 2596, 1741, - 2596, 2226, 2226, 2226, 1914, 1919, 2596, 1612, 1677, 906, - 906, 906, 906, 906, 906, 906, 906, 2596, 2596, 2596, - 1742, 472, 473, 474, 475, 476, 477, 378, 379, 380, - 381, 382, 383, 2596, 1919, 378, 379, 380, 381, 382, - 383, 2596, 2596, 2596, 2596, 2185, 2185, 2185, 2596, 1742, - 2221, 378, 379, 380, 381, 382, 383, 1707, 906, 906, - 906, 906, 906, 906, 906, 906, 2596, 2237, 2186, 2596, - 2596, 2596, 1952, 1872, 1872, 1872, 1872, 1872, 1872, 1872, - - 1872, 1872, 2596, 2238, 1743, 1609, 1463, 1463, 2596, 2596, - 1741, 2227, 2234, 2244, 1959, 2235, 2237, 2186, 1612, 2245, - 2596, 1952, 2596, 2596, 2596, 378, 379, 380, 381, 382, - 383, 1742, 2238, 2596, 2596, 2596, 2596, 2596, 501, 2246, - 2247, 2234, 2244, 1959, 2235, 2596, 2249, 2596, 2245, 378, - 379, 380, 381, 382, 383, 2187, 501, 2018, 2018, 2018, - 1742, 472, 473, 474, 475, 476, 477, 501, 2246, 2247, - 2253, 2254, 1518, 1961, 1960, 2249, 1957, 378, 379, 380, - 381, 382, 383, 501, 1872, 1872, 1872, 1872, 1872, 1872, - 1872, 1872, 1872, 2596, 2596, 1743, 1609, 1463, 1463, 2253, - - 2254, 1741, 1961, 2596, 2596, 1957, 2596, 2596, 2255, 1612, - 2596, 2239, 508, 509, 514, 511, 512, 513, 501, 2256, - 2257, 2240, 1742, 378, 379, 380, 381, 382, 383, 501, - 508, 509, 514, 511, 512, 513, 501, 2255, 2596, 1962, - 2239, 508, 509, 514, 511, 512, 513, 2019, 2256, 2257, - 2240, 1742, 2121, 2121, 2121, 2259, 2268, 508, 509, 514, - 511, 512, 513, 2596, 2596, 2596, 2596, 1678, 1962, 1972, - 2269, 2276, 2277, 1973, 2596, 1873, 1873, 1873, 1873, 1873, - 1873, 1873, 1873, 1873, 2259, 2268, 1743, 2596, 2596, 2177, - 2177, 2177, 508, 509, 514, 511, 512, 513, 1972, 2269, - - 2276, 2277, 1973, 508, 509, 514, 511, 512, 513, 2178, - 508, 509, 514, 511, 512, 513, 658, 659, 660, 661, - 662, 663, 2596, 2031, 2031, 2031, 658, 659, 660, 661, - 662, 663, 1609, 1463, 1463, 2596, 2596, 1741, 1609, 1463, - 1463, 2596, 2122, 1741, 2596, 1612, 2596, 1977, 1868, 1868, - 2596, 1612, 1978, 2032, 2278, 1974, 2280, 2281, 1742, 2596, - 1979, 2282, 2596, 2287, 1742, 1875, 1868, 1868, 2596, 2288, - 1876, 2596, 2596, 1980, 2289, 1609, 1463, 1463, 1877, 2260, - 1741, 2596, 2032, 2278, 1974, 2280, 2281, 1742, 1612, 2596, - 2282, 1878, 2287, 1742, 2291, 1984, 1463, 1463, 2288, 2596, - - 1876, 1742, 1980, 2289, 2596, 1875, 1868, 1868, 1877, 2596, - 1876, 2596, 2596, 2033, 1986, 1463, 1463, 1609, 1877, 1978, - 1878, 1878, 1743, 2291, 2160, 2160, 2160, 1979, 1743, 2292, - 1742, 1878, 2293, 1984, 1463, 1463, 2596, 1981, 1876, 1708, - 1980, 2261, 2261, 2261, 2596, 2596, 1988, 1991, 2596, 2294, - 1878, 1984, 1463, 1463, 1982, 1879, 1876, 2262, 2292, 1878, - 1878, 2293, 2596, 2596, 1877, 1743, 1609, 1463, 1463, 1980, - 2296, 1741, 1994, 2077, 2077, 2077, 1991, 1878, 2294, 1612, - 2596, 2596, 2596, 2596, 2596, 1985, 2596, 2078, 1878, 1984, - 1463, 1463, 1742, 2299, 1876, 1879, 2596, 2302, 2305, 2296, - - 2307, 1994, 1877, 2596, 1987, 2596, 1878, 2596, 658, 659, - 660, 661, 662, 663, 2161, 1878, 2596, 2596, 2284, 2284, - 2284, 1742, 2299, 1985, 2596, 1993, 2302, 2305, 1998, 2307, - 1990, 2263, 1989, 699, 700, 701, 702, 703, 704, 2596, - 2596, 1985, 2596, 2596, 1878, 1611, 1611, 1611, 1611, 1611, - 1611, 1611, 1611, 1611, 1993, 1995, 1743, 1998, 2596, 2596, - 2596, 1989, 2596, 2079, 2596, 2596, 2596, 2596, 699, 700, - 701, 702, 703, 704, 2596, 2596, 2596, 2596, 2596, 1985, - 2596, 2596, 2596, 2596, 1995, 745, 746, 747, 748, 749, - 750, 2596, 2596, 2596, 658, 659, 660, 661, 662, 663, - - 2000, 699, 700, 701, 702, 703, 704, 2002, 2285, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2001, 2596, 2596, 2596, - 1794, 906, 906, 906, 906, 906, 906, 906, 906, 2000, - 2596, 2308, 2596, 2596, 2596, 2596, 2002, 2218, 2218, 2218, - 2596, 2596, 2596, 2596, 2596, 2001, 378, 379, 380, 381, - 382, 383, 378, 379, 380, 381, 382, 383, 2007, 2008, - 2308, 2596, 378, 379, 380, 381, 382, 383, 378, 379, - 380, 381, 382, 383, 2596, 2596, 2596, 2596, 2596, 378, - 379, 380, 381, 382, 383, 2596, 2596, 2007, 2008, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 378, 379, - - 380, 381, 382, 383, 2596, 378, 379, 380, 381, 382, - 383, 2062, 2062, 2062, 2009, 2596, 2596, 2596, 2596, 2596, - 378, 379, 380, 381, 382, 383, 2017, 2219, 2065, 2016, - 378, 379, 380, 381, 382, 383, 2596, 2596, 2596, 2596, - 2596, 2063, 501, 2009, 699, 700, 701, 702, 703, 704, - 2596, 2596, 2189, 2189, 2189, 2017, 501, 2065, 2016, 2596, - 2596, 2596, 378, 379, 380, 381, 382, 383, 2068, 2067, - 2063, 2309, 2190, 2060, 2220, 2220, 2220, 378, 379, 380, - 381, 382, 383, 378, 379, 380, 381, 382, 383, 472, - 473, 474, 475, 476, 477, 2596, 2596, 2068, 2067, 501, - - 2309, 2064, 2060, 378, 379, 380, 381, 382, 383, 2066, - 2081, 2310, 2069, 2004, 2004, 2004, 508, 509, 514, 511, - 512, 513, 2596, 2596, 378, 379, 380, 381, 382, 383, - 508, 509, 514, 511, 512, 513, 2082, 2596, 2066, 2081, - 2310, 2069, 2271, 2005, 2596, 2596, 2596, 378, 379, 380, - 381, 382, 383, 2311, 2596, 2596, 658, 659, 660, 661, - 662, 663, 2596, 2312, 2221, 2082, 472, 473, 474, 475, - 476, 477, 2005, 508, 509, 514, 511, 512, 513, 2596, - 2596, 2313, 2311, 658, 659, 660, 661, 662, 663, 1609, - 1463, 1463, 2312, 2314, 1741, 1986, 1463, 1463, 2596, 2596, - - 1978, 2596, 1612, 2006, 1977, 1868, 1868, 2596, 1979, 1978, - 2313, 1986, 1463, 1463, 2596, 1742, 1978, 1979, 2596, 2315, - 2316, 1980, 2314, 2083, 1979, 2596, 2596, 1986, 1463, 1463, - 1980, 2596, 1978, 2317, 1986, 1463, 1463, 1980, 2596, 1978, - 2084, 1986, 1463, 1463, 1742, 2318, 1978, 1979, 2315, 2316, - 1980, 2319, 2083, 1980, 1979, 2300, 2300, 2300, 2596, 1980, - 1980, 2320, 2317, 2011, 2011, 2011, 1980, 1980, 2115, 2115, - 2115, 1609, 1463, 1463, 2318, 2596, 1741, 2085, 2596, 1743, - 2319, 2596, 1980, 2596, 1612, 1987, 1984, 1463, 1463, 1980, - 2320, 1876, 2596, 2012, 1981, 2596, 1980, 1742, 2116, 1877, - - 2321, 1987, 1984, 1463, 1463, 2596, 2085, 1876, 1986, 1463, - 1463, 2596, 1878, 1978, 2596, 1877, 2596, 1987, 2596, 2596, - 2086, 1979, 2012, 2596, 1987, 2596, 1742, 2116, 1878, 2321, - 2596, 1987, 2596, 2322, 1980, 2596, 2090, 2326, 1986, 1463, - 1463, 1878, 2596, 1978, 2596, 2301, 2327, 1875, 1868, 1868, - 1867, 1979, 1876, 2013, 1984, 1463, 1463, 1878, 2117, 1876, - 1988, 1743, 2322, 1980, 1980, 2090, 2326, 1877, 2329, 1984, - 1463, 1463, 2596, 1878, 1876, 2327, 1985, 2089, 2596, 2334, - 1878, 2087, 1877, 2091, 658, 659, 660, 661, 662, 663, - 2092, 2596, 1985, 1980, 2337, 1878, 2338, 2329, 1987, 2596, - - 2596, 2596, 1878, 2596, 2596, 2596, 2089, 2097, 2334, 1878, - 2596, 2596, 2091, 2596, 2596, 2596, 2596, 2088, 2596, 2092, - 2596, 2596, 2596, 2337, 1878, 2338, 2596, 2596, 1987, 2596, - 699, 700, 701, 702, 703, 704, 2097, 1879, 699, 700, - 701, 702, 703, 704, 1985, 2596, 2596, 2596, 1875, 2272, - 2272, 2272, 501, 745, 746, 747, 748, 749, 750, 1985, - 2596, 2596, 2596, 2596, 2596, 2273, 2031, 2031, 2031, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 658, 659, 660, 661, 662, 663, 378, 379, 380, - 381, 382, 383, 2103, 2343, 2344, 2032, 2596, 2339, 2339, - - 2339, 378, 379, 380, 381, 382, 383, 2596, 378, 379, - 380, 381, 382, 383, 2110, 501, 2596, 2062, 2062, 2062, - 2111, 2596, 2103, 2343, 2344, 2032, 508, 509, 514, 511, - 512, 513, 2596, 378, 379, 380, 381, 382, 383, 2274, - 2596, 2596, 2596, 2110, 2596, 2596, 2596, 2063, 2347, 2111, - 378, 379, 380, 381, 382, 383, 2033, 2051, 2051, 2051, - 378, 379, 380, 381, 382, 383, 378, 379, 380, 381, - 382, 383, 2165, 2348, 2349, 2350, 2063, 2347, 2596, 2358, - 2159, 2596, 2141, 2361, 2363, 2142, 2364, 2164, 2340, 508, - 509, 514, 511, 512, 513, 2596, 2094, 2094, 2094, 2143, - - 2596, 2165, 2348, 2349, 2350, 2596, 2596, 2064, 2358, 2159, - 2095, 2141, 2361, 2363, 2142, 2364, 2164, 2365, 2596, 472, - 473, 474, 475, 476, 477, 501, 2366, 2596, 2143, 2177, - 2177, 2177, 378, 379, 380, 381, 382, 383, 472, 473, - 474, 475, 476, 477, 2596, 2367, 2365, 2052, 2148, 2178, - 2368, 2369, 2370, 2166, 2149, 2171, 2171, 2171, 2150, 2151, - 2596, 2596, 2596, 2152, 2153, 2154, 2371, 2155, 699, 700, - 701, 702, 703, 704, 2367, 2596, 2374, 2148, 2172, 2368, - 2369, 2370, 2166, 2149, 2372, 2373, 2096, 2150, 2151, 2226, - 2226, 2226, 2152, 2153, 2154, 2371, 2155, 2173, 2596, 508, - - 509, 514, 511, 512, 513, 2374, 2596, 2172, 2375, 2596, - 1609, 1463, 1463, 2372, 2373, 1741, 2596, 658, 659, 2179, - 661, 662, 663, 1612, 2596, 2596, 2173, 1977, 1868, 1868, - 2596, 2303, 1978, 1986, 1463, 1463, 1742, 2375, 1978, 2596, - 2084, 2596, 1986, 1463, 1463, 2174, 1979, 1978, 2596, 1984, - 1463, 1463, 2596, 1980, 1876, 1979, 2180, 2376, 2596, 1980, - 2303, 2596, 1877, 2596, 2182, 1742, 2596, 2377, 1980, 2099, - 2099, 2099, 2104, 2104, 2104, 1878, 1986, 1463, 1463, 2227, - 2378, 1978, 1980, 2596, 1646, 2180, 2376, 1656, 1980, 1979, - 1984, 1463, 1463, 2182, 2596, 1876, 2377, 1980, 2379, 2596, - - 1743, 2183, 1980, 1877, 1878, 2189, 2189, 2189, 2380, 2378, - 658, 659, 660, 661, 662, 663, 1878, 1981, 2596, 2596, - 2596, 1977, 2596, 1987, 2181, 2190, 2596, 2379, 1984, 2596, - 2183, 1980, 1987, 2596, 2596, 2596, 2596, 2380, 2596, 1985, - 2596, 2596, 2596, 2385, 2386, 1878, 2596, 699, 700, 701, - 702, 703, 704, 2181, 2596, 1986, 2204, 2204, 2204, 2100, - 2196, 2266, 2105, 2121, 2121, 2121, 1987, 2160, 2160, 2160, - 2596, 1795, 2385, 2386, 2596, 2115, 2115, 2115, 1678, 2596, - 1985, 2596, 1708, 2201, 2596, 2596, 2596, 2202, 2387, 2196, - 2250, 2596, 2596, 745, 746, 2191, 748, 749, 750, 658, - - 659, 660, 661, 662, 663, 2116, 378, 379, 380, 381, - 382, 383, 2241, 2251, 2596, 2388, 2202, 2387, 2391, 2250, - 2242, 378, 379, 380, 381, 382, 383, 2243, 378, 379, - 380, 381, 382, 383, 2116, 472, 473, 474, 475, 476, - 477, 2241, 2251, 501, 2388, 2596, 2205, 2391, 2596, 2242, - 2392, 2393, 2252, 2122, 2596, 2596, 2243, 2161, 2596, 472, - 473, 474, 475, 476, 477, 2117, 472, 473, 474, 475, - 476, 477, 378, 379, 380, 381, 382, 383, 2596, 2392, - 2393, 2252, 2171, 2171, 2171, 2264, 674, 674, 674, 674, - 674, 674, 674, 674, 2204, 2204, 2204, 1986, 1463, 1463, - - 2596, 2267, 1978, 2396, 2397, 2172, 2185, 2185, 2185, 1795, - 1979, 2596, 2596, 2596, 2596, 2596, 2400, 508, 509, 514, - 511, 512, 513, 1980, 2173, 1984, 1463, 1463, 2324, 2186, - 1876, 2265, 2396, 2397, 2172, 2596, 2596, 2596, 1877, 699, - 700, 701, 702, 703, 704, 2400, 2596, 2596, 2596, 2401, - 2402, 1878, 1980, 2173, 2177, 2177, 2177, 2324, 2186, 2279, - 2265, 2275, 763, 763, 763, 763, 763, 763, 763, 763, - 2323, 2596, 2174, 2596, 2178, 2596, 2596, 2283, 2401, 2402, - 1878, 2404, 2596, 501, 2205, 2410, 2596, 1987, 2279, 472, - 473, 474, 475, 476, 477, 2596, 2187, 2596, 2596, 2323, - - 378, 379, 380, 381, 382, 383, 2283, 2596, 2596, 2596, - 2404, 2325, 2332, 2411, 2410, 1985, 472, 473, 474, 475, - 476, 477, 2596, 378, 379, 380, 381, 382, 383, 2261, - 2261, 2261, 2596, 2596, 378, 379, 380, 381, 382, 383, - 2325, 2332, 2411, 2596, 2260, 2262, 2177, 1035, 1035, 1035, - 1035, 1035, 1035, 1035, 1035, 2333, 2596, 508, 509, 514, - 511, 512, 513, 1986, 1463, 1463, 2596, 2596, 1978, 658, - 659, 660, 661, 662, 663, 2596, 1979, 2189, 2189, 2189, - 2272, 2272, 2272, 2596, 2333, 2596, 2596, 2596, 2596, 1980, - 2341, 2341, 2341, 2284, 2284, 2284, 2273, 2190, 2189, 1094, - - 1094, 1094, 1094, 1094, 1094, 1094, 1094, 2596, 2596, 2596, - 2596, 2414, 699, 700, 701, 702, 703, 704, 1980, 2263, - 2351, 2351, 2351, 2354, 2354, 2354, 2359, 2359, 2359, 2300, - 2300, 2300, 2383, 2345, 2381, 2381, 2381, 2355, 2596, 2389, - 2414, 2596, 2339, 2339, 2339, 2341, 2341, 2341, 2596, 2596, - 2415, 2596, 2416, 1987, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2383, 2345, 501, 2390, 2417, 2596, 2271, 2389, 2596, - 2274, 2596, 2596, 378, 379, 380, 381, 382, 383, 2415, - 2342, 2416, 2418, 2285, 472, 473, 474, 475, 476, 477, - 2596, 2419, 2384, 2390, 2417, 378, 379, 380, 381, 382, - - 383, 658, 659, 660, 661, 662, 663, 2398, 2398, 2398, - 2352, 2418, 2596, 2356, 2596, 2596, 2360, 2596, 2596, 2301, - 2419, 2384, 2596, 2596, 2382, 2596, 699, 700, 701, 702, - 703, 704, 2340, 2420, 2421, 2342, 2422, 508, 509, 514, - 511, 512, 513, 378, 379, 380, 381, 382, 383, 2351, - 2351, 2351, 2354, 2354, 2354, 2423, 2405, 2405, 2405, 2359, - 2359, 2359, 2420, 2421, 2596, 2422, 2355, 2424, 2596, 2596, - 2425, 2596, 2426, 2427, 2428, 2429, 2381, 2381, 2381, 2433, - 2596, 2434, 501, 2435, 2423, 2436, 2437, 2431, 2438, 2439, - 2440, 2445, 2446, 2406, 2447, 2448, 2424, 2399, 2407, 2425, - - 2412, 2426, 2427, 2428, 2429, 2398, 2398, 2398, 2433, 2432, - 2434, 2450, 2435, 2596, 2436, 2437, 2431, 2438, 2439, 2440, - 2445, 2446, 2406, 2447, 2448, 2596, 2596, 2407, 2596, 2412, - 658, 659, 660, 661, 662, 663, 2451, 2596, 2432, 2352, - 2450, 2596, 2356, 2405, 2405, 2405, 2408, 2452, 2453, 2360, - 472, 473, 474, 475, 476, 477, 508, 509, 514, 511, - 512, 513, 2454, 2455, 2456, 2451, 2382, 699, 700, 701, - 702, 703, 704, 2457, 2458, 2459, 2452, 2453, 2460, 2461, - 2406, 2462, 2463, 2464, 2465, 2407, 2466, 501, 2467, 2468, - 2469, 2454, 2455, 2456, 2470, 2399, 2471, 2472, 2486, 2486, - - 2486, 2596, 2457, 2458, 2459, 2473, 2474, 2460, 2461, 2406, - 2462, 2463, 2464, 2465, 2407, 2466, 2478, 2467, 2468, 2469, - 2479, 2482, 2483, 2470, 2484, 2471, 2472, 472, 473, 474, - 475, 476, 477, 2408, 2473, 2474, 2596, 2596, 2485, 2488, - 2489, 2490, 2491, 2492, 2493, 2478, 2494, 2495, 2496, 2479, - 2482, 2483, 2497, 2484, 472, 473, 474, 475, 476, 477, - 2498, 508, 509, 514, 511, 512, 513, 2485, 2488, 2489, - 2490, 2491, 2492, 2493, 2499, 2494, 2495, 2496, 2500, 2502, - 2503, 2497, 2504, 2505, 2506, 2507, 2510, 2512, 2487, 2498, - 2508, 2508, 2508, 2486, 2486, 2486, 2513, 2514, 2515, 2516, - - 2518, 2519, 2520, 2499, 2521, 2522, 2523, 2500, 2502, 2503, - 2524, 2504, 2505, 2506, 2507, 2510, 2512, 2486, 2486, 2486, - 2508, 2508, 2508, 2527, 2528, 2513, 2514, 2515, 2516, 2518, - 2519, 2520, 2529, 2521, 2522, 2523, 2530, 2531, 2532, 2524, - 2533, 2534, 2535, 2536, 2537, 2538, 2539, 2540, 2541, 2542, - 2543, 2596, 2527, 2528, 2596, 2544, 2545, 2579, 2579, 2579, - 2550, 2529, 2551, 2552, 2553, 2530, 2531, 2532, 2554, 2533, - 2534, 2535, 2536, 2537, 2538, 2539, 2540, 2541, 2542, 2543, - 2509, 2596, 2555, 2487, 2544, 2545, 2546, 2546, 2546, 2550, - 2556, 2551, 2552, 2553, 2547, 2562, 2565, 2554, 2177, 2177, - - 2177, 2189, 2189, 2189, 2546, 2546, 2546, 2487, 2566, 2567, - 2509, 2555, 2547, 2568, 2570, 2571, 2572, 2573, 2178, 2556, - 2574, 2190, 2575, 2576, 2562, 2565, 2577, 2578, 2581, 2582, - 2583, 2584, 2579, 2579, 2579, 2586, 2587, 2566, 2567, 2579, - 2579, 2579, 2568, 2570, 2571, 2572, 2573, 2580, 2588, 2574, - 2589, 2575, 2576, 2590, 2591, 2577, 2578, 2581, 2582, 2583, - 2584, 2486, 2486, 2486, 2586, 2587, 2592, 2596, 2593, 2594, - 2595, 2579, 2579, 2579, 2596, 2596, 2548, 2588, 2549, 2589, - 2596, 2596, 2590, 2591, 2596, 2596, 2596, 2596, 2260, 2596, - 2596, 2271, 2596, 2596, 2548, 2592, 2549, 2593, 2594, 2595, - - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2580, 2596, 2596, 2596, 2596, 2596, 2596, 2580, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2487, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2580, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 123, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - - 187, 105, 105, 105, 105, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 215, 215, 215, 215, 215, 215, - 215, 215, 215, 215, 215, 215, 215, 224, 224, 224, - 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, - 231, 231, 231, 234, 234, 234, 234, 234, 234, 234, - 234, 234, 234, 234, 234, 234, 237, 237, 237, 237, - 237, 237, 237, 237, 237, 237, 237, 237, 237, 240, - 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, - 240, 240, 242, 242, 242, 242, 242, 242, 242, 242, - - 242, 242, 242, 242, 242, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 269, 269, - 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, - 269, 311, 311, 311, 311, 311, 311, 311, 311, 311, - 311, 311, 311, 311, 338, 338, 338, 338, 338, 338, - 338, 338, 338, 338, 338, 338, 338, 347, 347, 347, - 347, 347, 347, 347, 347, 347, 347, 347, 347, 347, - 362, 362, 362, 370, 370, 2596, 370, 370, 370, 370, - 370, 370, 370, 370, 370, 370, 377, 377, 384, 384, - 384, 455, 455, 2596, 2596, 2596, 2596, 2596, 2596, 455, - - 471, 471, 499, 499, 2596, 499, 499, 2596, 499, 499, - 499, 537, 537, 537, 544, 544, 551, 551, 551, 563, - 563, 2596, 2596, 2596, 2596, 2596, 2596, 563, 579, 2596, - 2596, 579, 600, 2596, 2596, 600, 623, 623, 623, 623, - 623, 623, 2596, 623, 623, 623, 623, 2596, 623, 629, - 629, 629, 629, 629, 629, 629, 629, 629, 629, 629, - 629, 629, 630, 630, 630, 630, 630, 630, 2596, 630, - 630, 630, 630, 2596, 630, 636, 636, 636, 636, 636, - 636, 636, 636, 636, 636, 636, 636, 636, 642, 642, - 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, - - 642, 643, 643, 643, 643, 643, 643, 643, 643, 643, - 643, 643, 643, 645, 645, 645, 645, 645, 645, 645, - 645, 645, 645, 645, 645, 650, 650, 2596, 650, 650, - 650, 650, 650, 650, 650, 650, 650, 650, 657, 657, - 683, 683, 2596, 683, 683, 683, 683, 683, 683, 683, - 683, 683, 683, 691, 691, 2596, 691, 691, 691, 691, - 691, 691, 691, 691, 691, 691, 698, 698, 717, 717, - 737, 737, 2596, 737, 737, 737, 737, 737, 737, 737, - 737, 737, 737, 744, 744, 771, 771, 2596, 771, 771, - 771, 771, 771, 771, 771, 771, 771, 771, 778, 778, - - 2596, 778, 778, 778, 778, 778, 778, 778, 778, 778, - 778, 362, 362, 362, 369, 369, 2596, 369, 369, 369, - 369, 369, 369, 369, 369, 369, 369, 370, 370, 2596, - 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, - 377, 377, 384, 384, 384, 455, 455, 2596, 2596, 2596, - 2596, 2596, 2596, 455, 471, 471, 499, 499, 2596, 499, - 499, 2596, 499, 499, 499, 537, 537, 537, 544, 544, - 551, 551, 551, 563, 563, 2596, 2596, 2596, 2596, 2596, - 2596, 563, 579, 2596, 2596, 579, 600, 2596, 2596, 600, - 623, 623, 623, 623, 623, 623, 2596, 623, 623, 623, - - 623, 2596, 623, 999, 999, 2596, 999, 999, 999, 999, - 999, 999, 999, 999, 999, 999, 630, 630, 630, 630, - 630, 630, 2596, 630, 630, 630, 630, 2596, 630, 1004, - 1004, 2596, 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, - 1004, 1004, 1009, 1009, 2596, 1009, 1009, 1009, 1009, 1009, - 1009, 1009, 1009, 1009, 1009, 643, 643, 643, 643, 643, - 643, 643, 643, 643, 643, 643, 643, 645, 645, 645, - 645, 645, 645, 645, 645, 645, 645, 645, 645, 649, - 649, 2596, 649, 649, 649, 649, 649, 649, 649, 649, - 649, 649, 650, 650, 2596, 650, 650, 650, 650, 650, - - 650, 650, 650, 650, 650, 657, 657, 683, 683, 2596, - 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, - 690, 690, 2596, 690, 690, 690, 690, 690, 690, 690, - 690, 690, 690, 691, 691, 2596, 691, 691, 691, 691, - 691, 691, 691, 691, 691, 691, 698, 698, 717, 717, - 736, 736, 2596, 736, 736, 736, 736, 736, 736, 736, - 736, 736, 736, 737, 737, 2596, 737, 737, 737, 737, - 737, 737, 737, 737, 737, 737, 744, 744, 771, 771, - 2596, 771, 771, 771, 771, 771, 771, 771, 771, 771, - 771, 778, 778, 2596, 778, 778, 778, 778, 778, 778, - - 778, 778, 778, 778, 369, 369, 2596, 369, 369, 369, - 369, 369, 369, 369, 369, 369, 369, 1118, 1118, 1118, - 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, - 377, 377, 471, 471, 499, 499, 2596, 2596, 2596, 499, - 544, 544, 579, 2596, 2596, 579, 600, 2596, 2596, 600, - 999, 999, 2596, 999, 999, 999, 999, 999, 999, 999, - 999, 999, 999, 1004, 1004, 2596, 1004, 1004, 1004, 1004, - 1004, 1004, 1004, 1004, 1004, 1004, 1009, 1009, 2596, 1009, - 1009, 1009, 1009, 1009, 1009, 1009, 1009, 1009, 1009, 649, - 649, 2596, 649, 649, 649, 649, 649, 649, 649, 649, - - 649, 649, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, - 1264, 1264, 1264, 1264, 1264, 657, 657, 1278, 1278, 1278, - 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, - 690, 690, 2596, 690, 690, 690, 690, 690, 690, 690, - 690, 690, 690, 1286, 1286, 1286, 1286, 1286, 1286, 1286, - 1286, 1286, 1286, 1286, 1286, 1286, 698, 698, 717, 717, - 736, 736, 2596, 736, 736, 736, 736, 736, 736, 736, - 736, 736, 736, 1298, 1298, 1298, 1298, 1298, 1298, 1298, - 1298, 1298, 1298, 1298, 1298, 1298, 744, 744, 1312, 1312, - 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, - - 1312, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1318, - 1318, 1318, 1318, 1318, 362, 362, 362, 370, 370, 2596, - 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, - 369, 369, 2596, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 384, 384, 384, 1118, 1118, 2596, 1118, - 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 377, - 377, 455, 455, 2596, 2596, 2596, 2596, 2596, 2596, 455, - 471, 471, 499, 499, 2596, 2596, 2596, 499, 499, 537, - 537, 537, 551, 551, 551, 544, 544, 563, 563, 2596, - 2596, 2596, 2596, 2596, 2596, 563, 579, 2596, 2596, 579, - - 600, 2596, 2596, 600, 1442, 1442, 1442, 1442, 1442, 1442, - 1442, 1442, 1442, 1442, 1442, 1442, 1442, 1447, 1447, 1447, - 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, - 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, - 1452, 1452, 1452, 650, 650, 2596, 650, 650, 650, 650, - 650, 650, 650, 650, 650, 650, 649, 649, 2596, 649, - 649, 649, 649, 649, 649, 649, 649, 649, 649, 1264, - 1264, 2596, 1264, 1264, 1264, 1264, 1264, 1264, 1264, 1264, - 1264, 1264, 657, 657, 1278, 1278, 2596, 1278, 1278, 1278, - 1278, 1278, 1278, 1278, 1278, 1278, 1278, 691, 691, 2596, - + 729, 729, 729, 730, 730, 730, 730, 730, 730, 730, + 731, 732, 733, 733, 733, 733, 733, 733, 733, 733, + 733, 1075, 718, 718, 718, 718, 718, 718, 718, 718, + 718, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1076, + 718, 718, 718, 718, 718, 718, 718, 718, 718, 1011, + + 1075, 1077, 1077, 1077, 1077, 1077, 1077, 1077, 1077, 1077, + 1077, 1077, 1077, 1077, 1077, 1077, 1077, 1077, 1077, 735, + 735, 735, 719, 720, 721, 722, 723, 724, 1078, 1078, + 1078, 1078, 1078, 1078, 1078, 1078, 1078, 738, 738, 738, + 738, 738, 738, 738, 738, 738, 1081, 1081, 1081, 1081, + 1081, 1081, 1081, 1081, 1081, 1082, 1083, 1083, 1083, 1083, + 1083, 1083, 1083, 1083, 1084, 1084, 1084, 1084, 1084, 1084, + 1084, 1084, 1084, 1085, 1085, 1085, 1085, 1085, 1085, 1085, + 1086, 1087, 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, + 1088, 745, 745, 745, 745, 745, 745, 745, 745, 745, + + 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 736, 737, + 737, 1567, 1011, 737, 737, 1263, 1259, 737, 737, 737, + 737, 737, 737, 737, 737, 737, 1568, 737, 737, 737, + 737, 737, 762, 762, 762, 762, 762, 762, 762, 762, + 762, 1089, 764, 764, 764, 764, 764, 764, 764, 764, + 1092, 1092, 1092, 1225, 1100, 1568, 1100, 1134, 737, 1101, + 737, 765, 765, 765, 765, 765, 765, 765, 765, 765, + 766, 766, 766, 766, 766, 766, 766, 1090, 768, 912, + 912, 912, 912, 912, 912, 912, 912, 737, 737, 737, + 737, 737, 737, 737, 737, 737, 737, 739, 740, 741, + + 742, 743, 744, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 757, 1102, 1099, 473, 474, 475, 476, 477, + 478, 1105, 1105, 1103, 759, 1105, 1106, 1105, 1105, 1105, + 746, 747, 748, 749, 750, 751, 1132, 1128, 358, 1093, + 777, 783, 1102, 745, 745, 745, 745, 745, 745, 745, + 745, 745, 1103, 759, 735, 1104, 1104, 1104, 1104, 1104, + 1104, 1104, 1104, 770, 746, 747, 748, 749, 750, 751, + 746, 747, 748, 749, 750, 751, 1104, 1104, 1104, 1104, + 1104, 1104, 1104, 1104, 1104, 746, 747, 748, 749, 750, + 751, 745, 745, 745, 745, 745, 745, 745, 745, 745, + + 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, + 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1105, 1107, 1107, + 1107, 1107, 1107, 1107, 1107, 1107, 1107, 770, 770, 770, + 1108, 1108, 1108, 777, 777, 777, 1112, 1112, 1112, 361, + 361, 361, 361, 361, 361, 361, 361, 361, 1119, 1119, + 1119, 1119, 1119, 1119, 1119, 1119, 1119, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, 1120, 1120, 1120, 1120, 776, 756, 1120, + 1091, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, 1121, 1121, 1121, 1121, 1121, 1121, 1121, + + 1121, 1121, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 1080, 1054, 682, 687, 1024, 771, 1023, 1022, 1109, + 1021, 1018, 778, 1017, 1016, 1113, 1122, 1122, 1122, 1122, + 1122, 1122, 1122, 1122, 1122, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 1123, 1123, 1123, 1123, 1123, 1123, + 1123, 1123, 1123, 1123, 1123, 1013, 1570, 1123, 1012, 1123, + 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + 1123, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, + 913, 913, 1011, 1008, 913, 1570, 913, 913, 913, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 1125, 1125, + + 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, + 1125, 1125, 1125, 1125, 1125, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 1126, 1126, 1126, 1126, 1126, 1126, + 1126, 1126, 1126, 1126, 1126, 1228, 2786, 1126, 824, 1126, + 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, + 1126, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, + 1130, 815, 815, 397, 1228, 1139, 1223, 1223, 1007, 2786, + 1223, 1006, 1223, 1223, 1223, 399, 1571, 2786, 928, 928, + 1005, 1004, 928, 2786, 928, 928, 928, 1572, 1000, 1140, + 598, 757, 990, 1503, 2786, 989, 473, 474, 475, 476, + + 477, 478, 1141, 1095, 399, 1571, 988, 2786, 987, 377, + 378, 379, 380, 381, 382, 986, 1572, 2786, 1140, 1142, + 473, 474, 475, 476, 477, 478, 919, 2786, 395, 814, + 787, 1141, 1095, 1143, 783, 1145, 377, 378, 379, 380, + 381, 382, 377, 378, 379, 380, 381, 382, 1142, 1131, + 377, 378, 379, 380, 381, 382, 377, 378, 379, 380, + 381, 382, 1143, 2786, 1145, 780, 776, 377, 378, 379, + 380, 381, 382, 773, 756, 752, 706, 2786, 688, 1144, + 377, 378, 379, 380, 381, 382, 2786, 687, 685, 1573, + 377, 378, 379, 380, 381, 382, 1146, 1274, 1274, 1274, + + 377, 378, 379, 380, 381, 382, 1147, 2786, 1144, 456, + 456, 456, 456, 456, 456, 456, 456, 456, 1573, 667, + 666, 2786, 1276, 1276, 1276, 1146, 648, 1574, 1150, 646, + 2786, 624, 623, 620, 619, 1147, 377, 378, 379, 380, + 381, 382, 1148, 1278, 1278, 1278, 397, 1149, 1511, 1152, + 377, 378, 379, 380, 381, 382, 1574, 1150, 818, 377, + 378, 379, 380, 381, 382, 2786, 616, 615, 1284, 1035, + 1035, 1148, 2786, 1151, 614, 613, 1149, 600, 1152, 599, + 377, 378, 379, 380, 381, 382, 1275, 818, 596, 1619, + 2786, 1153, 595, 592, 377, 378, 379, 380, 381, 382, + + 1156, 2786, 1151, 377, 378, 379, 380, 381, 382, 1246, + 1246, 1277, 591, 1246, 2786, 1246, 1246, 1246, 1619, 481, + 1153, 2786, 1154, 396, 1157, 395, 1155, 391, 2786, 1156, + 2786, 1159, 1279, 1620, 245, 245, 243, 2786, 377, 378, + 379, 380, 381, 382, 1622, 377, 378, 379, 380, 381, + 382, 1154, 1158, 1157, 2786, 1155, 1160, 1285, 243, 2786, + 1159, 2786, 1620, 377, 378, 379, 380, 381, 382, 2786, + 2786, 1624, 2786, 1622, 377, 378, 379, 380, 381, 382, + 1161, 1158, 2786, 2786, 2786, 1160, 2786, 377, 378, 379, + 380, 381, 382, 1162, 377, 378, 379, 380, 381, 382, + + 1624, 2786, 2786, 377, 378, 379, 380, 381, 382, 1161, + 377, 378, 379, 380, 381, 382, 2786, 2786, 1296, 1049, + 1049, 2786, 1162, 1164, 2786, 2786, 2786, 377, 378, 379, + 380, 381, 382, 1249, 1249, 1625, 1163, 1249, 2786, 1249, + 1249, 1249, 1626, 1628, 2786, 377, 378, 379, 380, 381, + 382, 2786, 1164, 1165, 1166, 377, 378, 379, 380, 381, + 382, 2786, 2786, 2786, 1625, 1163, 1168, 1167, 2786, 2786, + 2786, 1626, 1628, 2786, 2786, 377, 378, 379, 380, 381, + 382, 1170, 1165, 1166, 2786, 2786, 2786, 2786, 2786, 377, + 378, 379, 380, 381, 382, 1168, 1167, 2786, 377, 378, + + 379, 380, 381, 382, 2786, 2786, 1169, 1297, 2786, 1171, + 1170, 377, 378, 379, 380, 381, 382, 377, 378, 379, + 380, 381, 382, 2786, 377, 378, 379, 380, 381, 382, + 2786, 2786, 2786, 1254, 1254, 1169, 2786, 1254, 1171, 1254, + 1254, 1254, 377, 378, 379, 380, 381, 382, 2786, 1630, + 1174, 2786, 1172, 1631, 1632, 1173, 1633, 377, 378, 379, + 380, 381, 382, 1175, 2786, 1638, 2786, 2786, 2786, 2786, + 377, 378, 379, 380, 381, 382, 2786, 2786, 1630, 1174, + 2786, 1172, 1631, 1632, 1173, 1633, 1304, 1065, 1065, 2786, + 2786, 2786, 1175, 1176, 1638, 2786, 377, 378, 379, 380, + + 381, 382, 1177, 377, 378, 379, 380, 381, 382, 377, + 378, 379, 380, 381, 382, 2786, 2786, 1179, 1180, 1317, + 1092, 1092, 1176, 2786, 377, 378, 379, 380, 381, 382, + 1178, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 2786, + 377, 378, 379, 380, 381, 382, 1179, 1180, 2786, 1181, + 377, 378, 379, 380, 381, 382, 2786, 2786, 1639, 1178, + 2786, 2786, 377, 378, 379, 380, 381, 382, 377, 378, + 379, 380, 381, 382, 2786, 1305, 1661, 1697, 1181, 2786, + 1182, 1698, 1708, 1184, 2786, 1728, 1183, 1639, 1729, 377, + 378, 379, 380, 381, 382, 2786, 377, 378, 379, 380, + + 381, 382, 2786, 2786, 2786, 1661, 1697, 1186, 1318, 1182, + 1698, 1708, 1184, 2786, 1728, 1183, 1185, 1729, 2786, 2786, + 2786, 377, 378, 379, 380, 381, 382, 1187, 2786, 377, + 378, 379, 380, 381, 382, 2786, 1186, 2786, 1189, 1730, + 1731, 1733, 2786, 1192, 1188, 1185, 2786, 377, 378, 379, + 380, 381, 382, 1190, 1735, 1738, 1187, 377, 378, 379, + 380, 381, 382, 2786, 2786, 2786, 2786, 1189, 1730, 1731, + 1733, 1739, 1192, 1188, 2786, 377, 378, 379, 380, 381, + 382, 2786, 1190, 1735, 1738, 1193, 377, 378, 379, 380, + 381, 382, 377, 378, 379, 380, 381, 382, 1226, 1191, + + 1739, 377, 378, 379, 380, 381, 382, 2786, 377, 378, + 379, 380, 381, 382, 1193, 377, 378, 379, 380, 381, + 382, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 1191, 1195, + 2786, 2786, 2786, 1194, 2786, 1330, 1108, 1108, 2786, 377, + 378, 379, 380, 381, 382, 2786, 1196, 377, 378, 379, + 380, 381, 382, 2786, 1200, 1200, 1200, 1199, 1195, 1281, + 1281, 1197, 1194, 1281, 1742, 1281, 1281, 1281, 2786, 473, + 474, 475, 476, 477, 478, 1196, 2786, 2786, 2786, 2786, + 377, 378, 379, 380, 381, 382, 1199, 1743, 1198, 2786, + 1197, 2786, 2786, 1742, 377, 378, 379, 380, 381, 382, + + 377, 378, 379, 380, 381, 382, 1202, 377, 378, 379, + 380, 381, 382, 2786, 2786, 2786, 1743, 2786, 377, 378, + 379, 380, 381, 382, 1331, 2786, 377, 378, 379, 380, + 381, 382, 1744, 1251, 1745, 1202, 1203, 2786, 2786, 2786, + 2786, 377, 378, 1201, 380, 381, 382, 1746, 2786, 377, + 378, 379, 380, 381, 382, 2786, 2786, 2786, 2786, 2786, + 2786, 1744, 1251, 1745, 1204, 1203, 1205, 1206, 1207, 2786, + 546, 547, 548, 549, 550, 551, 1746, 1213, 2786, 546, + 547, 548, 549, 550, 551, 2786, 377, 378, 379, 380, + 381, 382, 2786, 1204, 2786, 1205, 1206, 1207, 2786, 1210, + + 546, 547, 548, 549, 550, 551, 1213, 1211, 1208, 1212, + 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, 1209, + 2786, 377, 378, 379, 380, 381, 382, 2786, 1210, 377, + 378, 379, 380, 381, 382, 1214, 1211, 1208, 1212, 1336, + 1112, 1112, 377, 378, 379, 380, 381, 382, 1209, 2786, + 2786, 377, 378, 379, 380, 381, 382, 2786, 377, 378, + 379, 380, 381, 382, 1214, 377, 378, 379, 380, 381, + 382, 377, 378, 379, 380, 381, 382, 1216, 1215, 2786, + 2786, 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, + 2786, 1747, 2786, 377, 378, 379, 380, 381, 382, 2786, + + 1218, 2786, 2786, 2786, 2786, 2786, 1216, 1215, 1217, 1222, + 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1222, 1221, 1227, + 1747, 2786, 377, 378, 379, 380, 381, 382, 1337, 1218, + 377, 378, 379, 380, 381, 382, 2786, 1217, 2786, 2786, + 2786, 2786, 1219, 1750, 1775, 1776, 1220, 1221, 1227, 2786, + 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, 473, + 474, 475, 476, 477, 478, 377, 378, 379, 380, 381, + 382, 1219, 1750, 1775, 1776, 1220, 377, 378, 379, 380, + 381, 382, 456, 456, 456, 456, 456, 456, 456, 456, + 456, 2786, 2786, 2786, 377, 378, 379, 380, 381, 382, + + 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1224, 1224, + 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1229, 1230, 2786, + 1231, 377, 378, 379, 380, 381, 382, 376, 376, 376, + 376, 376, 376, 376, 376, 376, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 2786, 1229, 1230, 1232, 1231, + 945, 945, 945, 945, 945, 945, 945, 945, 1130, 815, + 815, 2786, 1777, 502, 2786, 473, 474, 475, 476, 477, + 478, 473, 474, 475, 476, 477, 478, 1232, 2786, 502, + 473, 474, 475, 476, 477, 478, 1233, 1234, 502, 1045, + + 1045, 1777, 1781, 1045, 502, 1045, 1045, 1045, 2786, 1782, + 2786, 1740, 502, 473, 474, 475, 476, 477, 478, 502, + 2786, 2786, 1237, 1741, 1235, 1233, 1234, 1783, 2786, 1301, + 1301, 1781, 1236, 1301, 502, 1301, 1301, 1301, 1782, 1238, + 1740, 502, 2786, 2786, 2786, 2786, 509, 510, 515, 512, + 513, 514, 1741, 1235, 2786, 1241, 1783, 1131, 2786, 502, + 2786, 1236, 509, 510, 515, 512, 513, 514, 1238, 1239, + 502, 509, 510, 515, 512, 513, 514, 509, 510, 515, + 512, 513, 514, 502, 1241, 509, 510, 515, 512, 513, + 514, 502, 509, 510, 515, 512, 513, 514, 502, 2786, + + 1784, 1244, 1240, 2786, 502, 1243, 2786, 509, 510, 515, + 512, 513, 514, 1785, 509, 510, 515, 512, 513, 514, + 1071, 1071, 1786, 1788, 1071, 1242, 1071, 1071, 1071, 1784, + 1244, 1240, 509, 510, 515, 512, 513, 514, 2786, 2786, + 2786, 1789, 1785, 509, 510, 515, 512, 513, 514, 2786, + 2786, 1786, 1788, 2786, 1242, 2786, 509, 510, 515, 512, + 513, 514, 2786, 2786, 509, 510, 515, 512, 513, 514, + 1789, 509, 510, 515, 512, 513, 514, 509, 510, 515, + 512, 513, 514, 500, 500, 500, 500, 500, 500, 500, + 500, 500, 538, 538, 538, 538, 538, 538, 538, 538, + + 538, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, + 1245, 1245, 1245, 1245, 1245, 1245, 1245, 1245, 538, 538, + 538, 538, 538, 538, 538, 538, 538, 1246, 1246, 1246, + 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, 1246, + 1246, 1246, 1246, 1246, 1246, 1247, 1247, 1247, 1247, 1247, + 1247, 1247, 1247, 1247, 552, 552, 552, 552, 552, 552, + 552, 552, 552, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1248, + 552, 552, 552, 552, 552, 552, 552, 552, 552, 1249, + 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1249, + + 1249, 1249, 1249, 1249, 1249, 1249, 1249, 1250, 1250, 1250, + 1250, 1250, 1250, 1250, 1250, 1250, 1252, 564, 564, 564, + 564, 564, 564, 564, 564, 564, 1253, 1253, 1253, 1253, + 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, 1253, + 1253, 1253, 1253, 2786, 2786, 1252, 564, 564, 564, 564, + 564, 564, 564, 564, 564, 1254, 1254, 1254, 1254, 1254, + 1254, 1254, 1254, 1254, 660, 661, 662, 663, 664, 665, + 546, 547, 548, 549, 550, 551, 1254, 1254, 1254, 1254, + 1254, 1254, 1254, 1254, 1254, 1255, 1255, 1255, 1255, 1255, + 1255, 1255, 1255, 1255, 545, 545, 545, 545, 545, 545, + + 545, 545, 545, 652, 652, 652, 652, 652, 652, 652, + 652, 652, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, + 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 652, + 652, 652, 652, 652, 652, 652, 652, 652, 1281, 1281, + 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, + 1281, 1281, 1281, 1281, 1281, 1281, 1282, 1282, 1282, 1282, + 1282, 1282, 1282, 1282, 1282, 1044, 1044, 1044, 1044, 1044, + 1044, 1044, 1044, 1289, 1291, 1293, 1790, 1795, 1290, 660, + 661, 662, 663, 664, 665, 659, 659, 659, 659, 659, + 659, 659, 659, 659, 1300, 1300, 1300, 1300, 1300, 1300, + + 1300, 1300, 1289, 1291, 2786, 1790, 1795, 1290, 1292, 2786, + 2786, 2786, 2786, 660, 661, 662, 663, 664, 665, 700, + 701, 702, 703, 704, 705, 660, 661, 662, 663, 664, + 665, 660, 661, 662, 663, 664, 665, 1292, 660, 661, + 662, 663, 664, 665, 692, 692, 692, 692, 692, 692, + 692, 692, 692, 2786, 660, 661, 662, 663, 664, 665, + 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 692, + 692, 692, 692, 692, 692, 692, 692, 692, 1301, 1301, + 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, + 1301, 1301, 1301, 1301, 1301, 1301, 1302, 1302, 1302, 1302, + + 1302, 1302, 1302, 1302, 1302, 1070, 1070, 1070, 1070, 1070, + 1070, 1070, 1070, 1307, 2786, 2786, 2786, 1309, 700, 701, + 702, 703, 704, 705, 1310, 1308, 699, 699, 699, 699, + 699, 699, 699, 699, 699, 719, 720, 721, 722, 723, + 724, 2786, 1307, 719, 720, 721, 722, 723, 724, 1284, + 1035, 1035, 2786, 1310, 1308, 700, 701, 702, 703, 704, + 705, 2786, 2786, 2786, 2786, 700, 701, 702, 703, 704, + 705, 700, 701, 702, 703, 704, 705, 719, 720, 721, + 722, 723, 724, 718, 718, 718, 718, 718, 718, 718, + 718, 718, 738, 738, 738, 738, 738, 738, 738, 738, + + 738, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, + 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 738, 738, + 738, 738, 738, 738, 738, 738, 738, 1313, 1313, 1313, + 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1285, 2786, + 1313, 2786, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, + 1313, 1313, 1313, 1313, 1314, 1314, 1314, 1314, 1314, 1314, + 1314, 1314, 1314, 1104, 1104, 1104, 1104, 1104, 1104, 1104, + 1104, 1105, 1105, 2786, 757, 1105, 1326, 1105, 1105, 1105, + 2786, 2786, 1101, 1469, 1274, 1274, 759, 2786, 2786, 2786, + 1470, 2786, 2786, 2786, 2786, 2786, 1327, 473, 474, 475, + + 476, 477, 478, 457, 2786, 2786, 360, 2786, 2786, 2786, + 2786, 2786, 360, 2786, 2786, 759, 745, 745, 745, 745, + 745, 745, 745, 745, 745, 1327, 2786, 2786, 2786, 2786, + 1328, 361, 361, 361, 361, 361, 361, 361, 361, 361, + 458, 459, 460, 461, 462, 463, 1798, 746, 747, 748, + 749, 750, 751, 746, 747, 748, 749, 750, 751, 1328, + 746, 747, 748, 749, 750, 751, 746, 747, 748, 749, + 750, 751, 1471, 384, 1821, 1798, 2786, 746, 747, 748, + 749, 750, 751, 746, 747, 748, 749, 750, 751, 362, + 363, 364, 365, 366, 367, 362, 363, 364, 365, 366, + + 367, 368, 368, 1821, 1838, 368, 368, 2786, 2786, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 2786, 368, + 368, 368, 368, 368, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 1838, 2786, 1296, 1049, 1049, 384, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 2786, 2786, + 368, 2786, 368, 385, 386, 387, 388, 389, 390, 2786, + 397, 2786, 1347, 1411, 466, 466, 466, 466, 466, 466, + 466, 466, 399, 2786, 1479, 1278, 1278, 2786, 1480, 368, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 370, + 371, 372, 373, 374, 375, 368, 368, 1839, 1748, 368, + + 368, 399, 1348, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 1749, 368, 368, 368, 368, 368, 385, 386, + 387, 388, 389, 390, 1297, 2786, 1839, 1748, 2786, 1847, + 2786, 1348, 2786, 377, 378, 379, 380, 381, 382, 2786, + 2786, 1749, 2786, 1848, 368, 2786, 368, 2786, 2786, 2786, + 377, 378, 379, 380, 381, 382, 2786, 757, 1847, 1666, + 1349, 1350, 1736, 1481, 1853, 1737, 1351, 2786, 2786, 1095, + 1863, 2786, 1848, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 368, 370, 371, 372, 373, 374, 375, 1349, + 1350, 1736, 2786, 1853, 1737, 1351, 1353, 2786, 1095, 1863, + + 2786, 377, 378, 379, 380, 381, 382, 2786, 1864, 1356, + 1435, 2786, 377, 378, 379, 380, 381, 382, 377, 378, + 379, 380, 381, 382, 2786, 1353, 2786, 2786, 1352, 377, + 378, 379, 380, 381, 382, 2786, 1354, 1864, 1356, 1435, + 1355, 2786, 2786, 2786, 377, 378, 379, 380, 381, 382, + 2786, 473, 474, 475, 476, 477, 478, 1352, 1357, 2786, + 2786, 1865, 1358, 1866, 1867, 1354, 2786, 1868, 2786, 1355, + 377, 378, 379, 380, 381, 382, 1361, 1359, 1360, 2786, + 377, 378, 379, 380, 381, 382, 2786, 1357, 2786, 2786, + 1865, 1358, 1866, 1867, 2786, 2786, 1868, 377, 378, 379, + + 380, 381, 382, 2786, 2786, 1361, 1359, 1360, 377, 378, + 379, 380, 381, 382, 2786, 377, 378, 379, 380, 381, + 382, 1362, 1363, 377, 378, 379, 380, 381, 382, 1364, + 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, 2786, + 2786, 377, 378, 379, 380, 381, 382, 1367, 2786, 2786, + 1362, 1363, 377, 378, 379, 380, 381, 382, 1364, 1366, + 2786, 2786, 377, 378, 379, 380, 381, 382, 377, 378, + 379, 380, 381, 382, 1365, 2786, 1367, 377, 378, 379, + 380, 381, 382, 2786, 2786, 2786, 2786, 2786, 1366, 2786, + 1368, 2786, 1474, 1276, 1276, 2786, 2786, 2786, 2786, 1475, + + 1369, 1869, 1870, 1365, 377, 378, 379, 380, 381, 382, + 1370, 2786, 377, 378, 379, 380, 381, 382, 1371, 1368, + 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, 1369, + 1869, 1870, 2786, 377, 378, 379, 380, 381, 382, 1370, + 2786, 2786, 2786, 2786, 1304, 1065, 1065, 1371, 377, 378, + 379, 380, 381, 382, 2786, 1373, 377, 378, 379, 380, + 381, 382, 377, 378, 379, 380, 381, 382, 377, 378, + 379, 380, 381, 382, 1375, 1372, 2786, 2786, 1871, 2786, + 2786, 1476, 2786, 1437, 377, 378, 379, 380, 381, 382, + 2786, 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, + + 1377, 1377, 1377, 1375, 1372, 1374, 2786, 1871, 457, 2786, + 2786, 397, 1437, 1671, 2786, 1376, 377, 378, 379, 380, + 381, 382, 2786, 818, 1317, 1092, 1092, 377, 378, 379, + 380, 381, 382, 1305, 1374, 473, 474, 475, 476, 477, + 478, 1379, 1872, 2786, 1376, 458, 459, 460, 461, 462, + 463, 2786, 818, 377, 378, 379, 380, 381, 382, 2786, + 2786, 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, + 2786, 1872, 377, 378, 379, 380, 381, 382, 1380, 377, + 378, 379, 380, 381, 382, 1381, 2786, 377, 378, 1378, + 380, 381, 382, 2786, 1873, 377, 378, 379, 380, 381, + + 382, 2786, 1330, 1108, 1108, 1382, 2786, 1380, 2786, 1336, + 1112, 1112, 1383, 1318, 1381, 1469, 1274, 1274, 2786, 2786, + 2786, 2786, 1470, 1873, 377, 378, 379, 380, 381, 382, + 1384, 1385, 2786, 2786, 1382, 377, 378, 379, 380, 381, + 382, 1383, 377, 378, 379, 380, 381, 382, 1388, 1388, + 1388, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 1386, 1384, + 1385, 757, 2786, 1815, 2786, 2786, 377, 378, 379, 380, + 381, 382, 1387, 1095, 377, 378, 379, 380, 381, 382, + 2786, 377, 378, 379, 380, 381, 382, 1386, 1390, 2786, + 2786, 1331, 377, 378, 379, 380, 381, 382, 1337, 1874, + + 2786, 1387, 1095, 2786, 1471, 2786, 377, 378, 379, 380, + 381, 382, 1391, 2786, 1807, 1807, 1807, 1390, 1474, 1276, + 1276, 1392, 1875, 2786, 2786, 1475, 2786, 2786, 1874, 377, + 378, 379, 380, 381, 382, 377, 378, 1389, 380, 381, + 382, 1391, 1393, 1876, 2786, 2786, 2786, 2786, 2786, 2786, + 1392, 1875, 1396, 377, 378, 379, 380, 381, 382, 2786, + 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, 2786, + 2786, 1393, 1876, 377, 378, 379, 380, 381, 382, 1395, + 1394, 1396, 2786, 2786, 1877, 2786, 377, 378, 379, 380, + 381, 382, 2786, 2786, 2786, 1878, 2786, 377, 378, 379, + + 380, 381, 382, 1808, 2786, 2786, 2786, 1476, 1395, 1394, + 1397, 1398, 2786, 1877, 2786, 2786, 2786, 377, 378, 379, + 380, 381, 382, 1399, 1878, 2786, 1879, 2786, 2786, 2786, + 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, 1397, + 1398, 377, 378, 379, 380, 381, 382, 1400, 1401, 1412, + 1412, 1412, 1399, 1416, 2786, 1879, 377, 378, 379, 380, + 381, 382, 2786, 2786, 1402, 1880, 377, 378, 379, 380, + 381, 382, 2786, 1432, 2786, 2786, 1400, 1401, 2786, 2786, + 2786, 1881, 1416, 2786, 2786, 2786, 2786, 377, 378, 379, + 380, 381, 382, 1402, 1880, 2786, 2786, 2786, 377, 378, + + 379, 380, 381, 382, 377, 378, 379, 380, 381, 382, + 1881, 377, 378, 379, 380, 381, 382, 2786, 456, 456, + 456, 456, 456, 456, 456, 456, 456, 377, 378, 379, + 380, 381, 382, 1200, 1200, 1200, 377, 378, 1413, 380, + 381, 382, 1436, 1414, 473, 474, 475, 476, 477, 478, + 2786, 2786, 2786, 2786, 1403, 2786, 2786, 1404, 1405, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 1434, 1406, 1407, + 1408, 1417, 1414, 1418, 1409, 1882, 2786, 1415, 1883, 2786, + 473, 474, 475, 476, 477, 478, 1404, 1405, 1419, 2786, + 377, 378, 379, 380, 381, 382, 1434, 1406, 1407, 1408, + + 1417, 2786, 1418, 1409, 1882, 2786, 1415, 1883, 2786, 473, + 474, 475, 476, 477, 478, 1420, 2786, 1419, 1421, 2122, + 2122, 2122, 1410, 377, 378, 379, 380, 381, 382, 1423, + 1426, 2786, 377, 378, 379, 380, 381, 382, 377, 378, + 379, 380, 381, 382, 1420, 2786, 2786, 1421, 2786, 377, + 378, 379, 380, 381, 382, 2786, 537, 2786, 1423, 1426, + 2786, 2786, 377, 378, 379, 380, 381, 382, 1778, 1422, + 1884, 2786, 2786, 1779, 377, 378, 379, 380, 381, 382, + 1425, 377, 378, 379, 380, 381, 382, 1424, 2786, 377, + 378, 379, 380, 381, 382, 2786, 2786, 1778, 1422, 1884, + + 1427, 2786, 1779, 1428, 2786, 2786, 2786, 2786, 2123, 1425, + 2786, 2786, 2786, 2786, 2786, 2786, 1424, 2786, 2786, 2786, + 2786, 377, 378, 379, 380, 381, 382, 1429, 2786, 1427, + 1430, 1885, 1428, 377, 378, 379, 380, 381, 382, 539, + 540, 541, 542, 543, 544, 377, 378, 379, 380, 381, + 382, 1433, 502, 1886, 1887, 1438, 1429, 2786, 2786, 1430, + 1885, 377, 378, 379, 380, 381, 382, 2786, 377, 378, + 379, 380, 381, 382, 377, 378, 379, 380, 381, 382, + 1433, 2786, 1886, 1887, 377, 378, 379, 380, 381, 382, + 2786, 377, 378, 379, 380, 381, 382, 502, 2786, 2786, + + 2786, 377, 378, 379, 380, 381, 382, 502, 1888, 2786, + 2786, 1911, 473, 474, 475, 476, 477, 478, 502, 553, + 397, 2786, 1819, 1439, 2786, 509, 510, 515, 512, 513, + 514, 1913, 818, 1914, 1440, 502, 1915, 1888, 2786, 1916, + 1911, 502, 2786, 2786, 2786, 2786, 2786, 502, 1917, 1918, + 2786, 2786, 1439, 1442, 2786, 2786, 2786, 1443, 1441, 1444, + 1913, 818, 1914, 1440, 502, 1915, 537, 2786, 1916, 2786, + 509, 510, 515, 512, 513, 514, 1445, 1917, 1918, 2786, + 509, 510, 515, 512, 513, 514, 1443, 1441, 1444, 2786, + 2786, 509, 510, 515, 512, 513, 514, 2786, 553, 554, + + 555, 556, 557, 558, 559, 1445, 2786, 1919, 509, 510, + 515, 512, 513, 514, 509, 510, 515, 512, 513, 514, + 509, 510, 515, 512, 513, 514, 502, 2786, 2786, 2786, + 2786, 2786, 502, 2786, 2786, 2786, 1919, 509, 510, 515, + 512, 513, 514, 502, 2786, 1446, 2786, 1449, 1447, 539, + 540, 541, 542, 543, 544, 1448, 538, 538, 538, 538, + 538, 538, 538, 538, 538, 552, 552, 552, 552, 552, + 552, 552, 552, 552, 1446, 2786, 2786, 1447, 554, 555, + 556, 557, 558, 559, 1448, 546, 547, 548, 549, 550, + 551, 565, 2786, 1450, 1920, 1921, 1922, 565, 1923, 509, + + 510, 515, 512, 513, 514, 509, 510, 515, 512, 513, + 514, 2786, 2786, 2786, 2786, 2786, 509, 510, 515, 512, + 513, 514, 1450, 1920, 1921, 1922, 2786, 1923, 566, 567, + 568, 569, 570, 571, 566, 567, 568, 569, 570, 571, + 564, 564, 564, 564, 564, 564, 564, 564, 564, 2786, + 2786, 2786, 2786, 2786, 546, 547, 548, 549, 550, 551, + 651, 651, 1492, 1486, 651, 651, 2786, 1491, 651, 651, + 651, 651, 651, 651, 651, 651, 651, 2786, 651, 651, + 651, 651, 651, 652, 652, 652, 652, 652, 652, 652, + 652, 652, 1486, 1487, 1487, 1487, 1491, 2786, 1488, 2786, + + 660, 661, 662, 663, 664, 665, 1489, 2786, 2786, 651, + 2786, 651, 692, 692, 692, 692, 692, 692, 692, 692, + 692, 2786, 2786, 2786, 2786, 660, 661, 662, 663, 664, + 665, 1493, 660, 661, 662, 663, 664, 665, 651, 651, + 651, 651, 651, 651, 651, 651, 651, 651, 653, 654, + 655, 656, 657, 658, 651, 651, 2786, 1498, 651, 651, + 1493, 2786, 651, 651, 651, 651, 651, 651, 651, 651, + 651, 1499, 651, 651, 651, 651, 651, 1924, 1925, 1926, + 660, 661, 1490, 663, 664, 665, 1498, 719, 720, 721, + 722, 723, 724, 2786, 660, 661, 662, 663, 664, 665, + + 2786, 2786, 2786, 651, 2786, 651, 1924, 1925, 1926, 700, + 701, 702, 703, 704, 705, 2786, 2786, 2786, 2786, 700, + 701, 702, 703, 704, 705, 1500, 473, 474, 475, 476, + 477, 478, 651, 651, 651, 651, 651, 651, 651, 651, + 651, 651, 653, 654, 655, 656, 657, 658, 691, 691, + 2786, 2786, 691, 691, 1500, 1930, 691, 691, 691, 691, + 691, 691, 691, 691, 691, 2786, 691, 691, 691, 691, + 691, 738, 738, 738, 738, 738, 738, 738, 738, 738, + 1513, 1513, 1513, 1934, 1930, 1544, 1544, 1544, 700, 701, + 702, 703, 704, 705, 2786, 1956, 1973, 691, 2786, 691, + + 1545, 2786, 2786, 757, 757, 1504, 1951, 2786, 397, 2786, + 1954, 2786, 1934, 2786, 2786, 759, 1095, 2786, 2786, 1505, + 818, 2786, 2786, 2786, 1956, 1973, 691, 691, 691, 691, + 691, 691, 691, 691, 691, 691, 693, 694, 695, 696, + 697, 698, 691, 691, 759, 1095, 691, 691, 1505, 818, + 691, 691, 691, 691, 691, 691, 691, 691, 691, 2786, + 691, 691, 691, 691, 691, 2786, 1605, 377, 378, 1514, + 380, 381, 382, 1974, 1702, 2786, 746, 747, 748, 749, + 750, 751, 1982, 1983, 746, 747, 748, 749, 750, 751, + 1603, 691, 2786, 691, 2786, 377, 378, 379, 380, 381, + + 382, 397, 1974, 1512, 473, 474, 475, 476, 477, 478, + 1506, 1982, 1983, 399, 1987, 2786, 1388, 1388, 1388, 2786, 691, 691, 691, 691, 691, 691, 691, 691, 691, 691, - 690, 690, 2596, 690, 690, 690, 690, 690, 690, 690, - 690, 690, 690, 1286, 1286, 2596, 1286, 1286, 1286, 1286, - 1286, 1286, 1286, 1286, 1286, 1286, 698, 698, 717, 717, - 737, 737, 2596, 737, 737, 737, 737, 737, 737, 737, - 737, 737, 737, 736, 736, 2596, 736, 736, 736, 736, - 736, 736, 736, 736, 736, 736, 1298, 1298, 2596, 1298, - 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1298, 744, - 744, 1312, 1312, 2596, 1312, 1312, 1312, 1312, 1312, 1312, - 1312, 1312, 1312, 1312, 1318, 1318, 2596, 1318, 1318, 1318, - - 1318, 1318, 1318, 1318, 1318, 1318, 1318, 1118, 1118, 2596, - 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, 1118, - 377, 377, 2596, 377, 377, 471, 471, 499, 499, 2596, - 2596, 2596, 499, 544, 544, 579, 2596, 2596, 579, 600, - 2596, 2596, 600, 1442, 1442, 2596, 1442, 1442, 1442, 1442, - 1442, 1442, 1442, 1442, 1442, 1442, 1447, 1447, 2596, 1447, - 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1447, 1452, - 1452, 2596, 1452, 1452, 1452, 1452, 1452, 1452, 1452, 1452, - 1452, 1452, 1264, 1264, 2596, 1264, 1264, 1264, 1264, 1264, - 1264, 1264, 1264, 1264, 1264, 657, 657, 1278, 1278, 2596, - - 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, 1278, - 1286, 1286, 2596, 1286, 1286, 1286, 1286, 1286, 1286, 1286, - 1286, 1286, 1286, 698, 698, 1608, 1608, 1608, 1608, 1608, - 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1608, 1789, 1789, - 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, 1789, - 1789, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, 1874, - 1874, 1874, 1874, 1874, 1895, 1895, 1895, 1895, 1895, 1895, - 1895, 1895, 1895, 1895, 1895, 1895, 1895, 1903, 1903, 1903, - 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, 1903, - 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, 1924, - - 1924, 1924, 1924, 1954, 1954, 1954, 1954, 1954, 1954, 1954, - 1954, 1954, 1954, 1954, 1954, 1954, 1976, 1976, 1976, 1976, - 1976, 1976, 1976, 1976, 1976, 1976, 1976, 1976, 1976, 2024, - 2024, 2024, 2024, 2024, 2024, 2024, 2024, 2024, 2024, 2024, - 2024, 2024, 57, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596 + 693, 694, 695, 696, 697, 698, 737, 737, 2786, 1506, + 737, 737, 399, 1987, 737, 737, 737, 737, 737, 737, + 737, 737, 737, 1551, 737, 737, 737, 737, 737, 2786, + 2786, 473, 474, 475, 476, 477, 478, 746, 747, 748, + 749, 750, 751, 2786, 377, 378, 379, 380, 381, 382, + 1989, 2786, 1551, 1990, 1991, 737, 2786, 737, 377, 378, + 379, 380, 381, 382, 2786, 2786, 2786, 2786, 2786, 2786, + + 1479, 1278, 1278, 2786, 1480, 1552, 2786, 2786, 1519, 1989, + 2786, 2786, 1990, 1991, 737, 737, 737, 737, 737, 737, + 737, 737, 737, 737, 739, 740, 741, 742, 743, 744, + 737, 737, 1515, 2786, 737, 737, 1521, 1519, 737, 737, + 737, 737, 737, 737, 737, 737, 737, 2786, 737, 737, + 737, 737, 737, 2786, 377, 378, 379, 380, 381, 382, + 2786, 1515, 1516, 2786, 1997, 1521, 2786, 1999, 2786, 2786, + 2786, 2786, 377, 378, 379, 380, 381, 382, 2002, 737, + 2786, 737, 2786, 377, 378, 379, 380, 381, 382, 1481, + 2786, 1516, 2786, 1997, 2786, 1517, 1999, 1513, 1513, 1513, + + 2786, 2786, 2786, 1518, 1520, 2786, 2786, 2002, 737, 737, + 737, 737, 737, 737, 737, 737, 737, 737, 739, 740, + 741, 742, 743, 744, 1517, 1524, 377, 378, 379, 380, + 381, 382, 1518, 1520, 1673, 2000, 377, 378, 379, 380, + 381, 382, 377, 378, 379, 380, 381, 382, 2786, 2786, + 2786, 2003, 2004, 2001, 1524, 377, 378, 379, 380, 381, + 382, 1522, 2786, 1673, 2000, 2005, 2006, 377, 378, 379, + 380, 381, 382, 377, 378, 379, 380, 381, 382, 2786, + 2003, 2004, 2001, 2786, 1523, 2009, 1674, 2786, 2010, 2786, + 1522, 1525, 2011, 2786, 2005, 2006, 2786, 2786, 2786, 1526, + + 2786, 2012, 2786, 2786, 2007, 2013, 2786, 2786, 2786, 2786, + 2786, 2786, 1527, 1523, 2009, 2008, 2014, 2010, 1531, 2786, + 1525, 2011, 377, 378, 379, 380, 381, 382, 1526, 1528, + 2012, 2786, 2786, 2007, 2013, 377, 378, 379, 380, 381, + 382, 1527, 2786, 2786, 2008, 2014, 1529, 1531, 2786, 2786, + 2786, 2786, 377, 378, 379, 380, 381, 382, 1528, 1530, + 377, 378, 379, 380, 381, 382, 1532, 2786, 2786, 377, + 378, 379, 380, 381, 382, 1529, 377, 378, 379, 380, + 381, 382, 377, 378, 379, 380, 381, 382, 1530, 2786, + 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, 2786, + + 2015, 2016, 1533, 1534, 377, 378, 379, 380, 381, 382, + 1536, 2786, 2786, 2786, 2786, 2786, 377, 378, 379, 380, + 381, 382, 377, 378, 379, 380, 381, 382, 2786, 2015, + 2016, 2786, 1534, 2786, 2786, 2786, 1560, 1560, 1560, 1536, + 377, 378, 379, 380, 381, 382, 1555, 1555, 1555, 2786, + 2017, 1535, 1541, 466, 466, 466, 466, 466, 466, 466, + 466, 1537, 377, 378, 379, 380, 381, 382, 2786, 1711, + 1716, 377, 378, 379, 380, 381, 382, 2786, 2786, 2017, + 1535, 2786, 2786, 2786, 377, 378, 379, 380, 381, 382, + 1537, 1377, 1377, 1377, 1542, 2786, 2786, 2018, 1711, 1716, + + 2786, 377, 378, 379, 380, 381, 382, 377, 378, 379, + 380, 381, 382, 2786, 2786, 1544, 1544, 1544, 2786, 1538, + 1543, 2021, 2786, 1542, 2786, 1717, 2018, 2786, 1539, 2786, + 1545, 2022, 2023, 1725, 1547, 1712, 2786, 1726, 1727, 2786, + 2786, 377, 378, 379, 380, 381, 382, 2786, 1538, 1543, + 2021, 377, 378, 379, 380, 381, 382, 1539, 1548, 2786, + 2022, 2023, 1725, 1547, 2786, 2786, 1726, 1727, 377, 378, + 379, 380, 381, 382, 2786, 1555, 1555, 1555, 2786, 2019, + 1540, 2786, 2786, 2786, 2786, 2786, 1549, 1548, 2024, 2786, + 2040, 377, 378, 379, 380, 381, 382, 2786, 2041, 2786, + + 2020, 1550, 377, 378, 1546, 380, 381, 382, 2019, 377, + 378, 379, 380, 381, 382, 1549, 2786, 2024, 2786, 2040, + 377, 378, 379, 380, 381, 382, 2786, 2041, 2786, 2020, + 1550, 2786, 377, 378, 379, 380, 381, 382, 1553, 466, + 466, 466, 466, 466, 466, 466, 466, 377, 378, 379, + 380, 381, 382, 1554, 377, 378, 379, 380, 381, 382, + 2786, 2786, 377, 378, 1556, 380, 381, 382, 2786, 2042, + 377, 378, 379, 380, 381, 382, 2786, 2786, 2043, 2045, + 1558, 2786, 1554, 1560, 1560, 1560, 1557, 1559, 2786, 377, + 378, 379, 380, 381, 382, 2786, 2786, 2786, 2042, 2046, + + 1562, 377, 378, 379, 380, 381, 382, 2043, 2045, 1558, + 2786, 2786, 2786, 2786, 2786, 1557, 1559, 2786, 1563, 2786, + 546, 547, 548, 549, 550, 551, 2786, 2047, 2046, 1562, + 2048, 2786, 2786, 377, 378, 379, 380, 381, 382, 2051, + 1564, 377, 378, 379, 380, 381, 382, 1563, 1565, 2786, + 377, 378, 379, 380, 381, 382, 2047, 2786, 2786, 2048, + 1618, 377, 378, 379, 380, 381, 382, 2786, 2051, 1564, + 377, 378, 1561, 380, 381, 382, 1566, 1565, 2134, 2134, + 2134, 2786, 2786, 377, 378, 379, 380, 381, 382, 1618, + 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, 377, + + 378, 379, 380, 381, 382, 1566, 1200, 912, 912, 912, + 912, 912, 912, 912, 912, 546, 547, 548, 549, 550, + 551, 2059, 377, 378, 379, 380, 381, 382, 1412, 1412, + 1412, 1590, 466, 466, 466, 466, 466, 466, 466, 466, + 377, 378, 379, 380, 381, 382, 2786, 1607, 2078, 2786, + 2059, 1576, 1577, 1578, 1579, 1580, 1581, 2786, 1582, 2093, + 1583, 1591, 1584, 2786, 2094, 1585, 2099, 2135, 1586, 1587, + 2786, 2786, 1588, 2101, 1593, 2102, 1607, 2078, 2786, 2786, + 1576, 1577, 1578, 1579, 1580, 1581, 1594, 1582, 2093, 1583, + 1591, 1584, 2786, 2094, 1585, 2099, 1592, 1586, 1587, 2786, + + 1595, 1588, 2101, 1593, 2102, 2786, 473, 474, 475, 476, + 477, 478, 1684, 1684, 1684, 1594, 2786, 1589, 2786, 377, + 378, 379, 380, 381, 382, 1592, 2786, 1685, 1596, 1595, + 377, 378, 379, 380, 381, 382, 377, 378, 379, 380, + 381, 382, 2786, 377, 378, 379, 380, 381, 382, 2786, + 2786, 377, 378, 379, 380, 381, 382, 1596, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 377, 378, 379, 380, 381, + 382, 1597, 377, 378, 379, 380, 381, 382, 377, 378, + 379, 380, 381, 382, 2786, 757, 397, 2073, 2076, 377, + 378, 379, 380, 381, 382, 1598, 2786, 1095, 818, 2786, + + 1597, 1827, 2786, 1640, 2786, 2786, 2786, 2786, 2786, 2786, + 2107, 1600, 2786, 2786, 2786, 2786, 2786, 2786, 2108, 2109, + 2110, 2115, 1599, 2116, 1598, 2117, 1095, 818, 502, 2786, + 2786, 2786, 377, 378, 379, 380, 381, 382, 1601, 2107, + 1600, 660, 661, 662, 663, 664, 665, 2108, 2109, 2110, + 2115, 1599, 2116, 2786, 2117, 2786, 2786, 377, 378, 379, + 380, 381, 382, 1610, 2786, 2786, 2786, 1601, 1604, 377, + 378, 379, 380, 381, 382, 377, 378, 379, 380, 381, + 382, 377, 378, 379, 380, 381, 382, 1606, 502, 2118, + 377, 378, 379, 380, 381, 382, 502, 1604, 2786, 2786, + + 2119, 509, 510, 515, 512, 513, 514, 2120, 2121, 502, + 2124, 2125, 1609, 2126, 2127, 1608, 1606, 502, 2118, 2786, + 473, 474, 475, 476, 477, 478, 2786, 1611, 1612, 2119, + 2128, 2786, 502, 2786, 2786, 2786, 2120, 2121, 502, 2124, + 2125, 1609, 2126, 2127, 1608, 2786, 2786, 2129, 502, 2130, + 473, 474, 475, 476, 477, 478, 1611, 1612, 1662, 2128, + 1615, 509, 510, 515, 512, 513, 514, 1613, 502, 509, + 510, 515, 512, 513, 514, 1614, 2129, 502, 2130, 2786, + 2786, 2786, 509, 510, 515, 512, 513, 514, 1616, 1615, + 509, 510, 515, 512, 513, 514, 700, 701, 702, 703, + + 704, 705, 2131, 1617, 1614, 509, 510, 515, 512, 513, + 514, 509, 510, 515, 512, 513, 514, 1616, 2786, 1658, + 2132, 509, 510, 515, 512, 513, 514, 2786, 1660, 2133, + 2786, 2131, 2786, 2786, 1487, 1487, 1487, 2786, 2786, 1641, + 1659, 509, 510, 515, 512, 513, 514, 1489, 1658, 2132, + 509, 510, 515, 512, 513, 514, 1663, 1660, 2133, 1642, + 1657, 675, 675, 675, 675, 675, 675, 675, 675, 1659, + 2786, 2786, 2786, 660, 661, 662, 663, 664, 665, 660, + 661, 662, 663, 664, 665, 1663, 2786, 2786, 1642, 2786, + 2136, 377, 378, 379, 380, 381, 382, 660, 661, 662, + + 663, 664, 665, 1675, 466, 466, 466, 466, 466, 466, + 466, 466, 2786, 700, 701, 702, 703, 704, 705, 2136, + 2786, 2786, 2786, 1643, 1644, 1645, 1487, 1487, 1644, 1644, + 1646, 1647, 1644, 1644, 1644, 1644, 1644, 1644, 1648, 1644, + 1644, 1647, 1644, 1644, 1644, 1644, 1644, 1647, 1647, 1647, + 1649, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, + 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, + 1647, 1647, 1647, 1644, 1647, 1644, 1647, 1647, 1647, 1649, + 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, + 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, + + 1647, 1647, 1644, 1644, 1644, 1644, 1644, 1644, 1644, 1644, + 1644, 1644, 1650, 1651, 1652, 1653, 1654, 1655, 1664, 757, + 2137, 1667, 2786, 2138, 2139, 2786, 2786, 2786, 2786, 2140, + 2141, 759, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 397, + 2786, 1672, 2786, 2786, 2786, 2786, 1668, 1664, 2786, 2137, + 2142, 399, 2138, 2139, 2786, 1669, 2143, 1676, 2140, 2141, + 759, 473, 474, 475, 476, 477, 478, 2786, 2786, 700, + 701, 702, 703, 704, 705, 1668, 1694, 1694, 1694, 2142, + 399, 2786, 2786, 2786, 1669, 2143, 1676, 2786, 2122, 2122, + 2122, 1695, 746, 747, 748, 749, 750, 751, 2786, 2786, + + 746, 747, 748, 749, 750, 751, 746, 747, 748, 749, + 750, 751, 377, 378, 379, 380, 381, 382, 377, 378, + 379, 380, 381, 382, 2786, 2144, 1677, 377, 378, 379, + 380, 381, 382, 2786, 2158, 2786, 2786, 2786, 2159, 2786, + 377, 378, 379, 380, 381, 382, 2786, 1684, 1684, 1684, + 2160, 1678, 2786, 2162, 2144, 1677, 1681, 2163, 2164, 2165, + 1679, 2786, 1685, 2158, 1682, 1835, 1680, 2159, 2786, 2786, + 2786, 377, 378, 379, 380, 381, 382, 2123, 2786, 2160, + 1678, 2786, 2162, 2786, 2786, 1681, 2163, 2164, 2165, 1679, + 2786, 2786, 2786, 1682, 2786, 1680, 2786, 377, 378, 379, + + 380, 381, 382, 1683, 2786, 2786, 377, 378, 379, 380, + 381, 382, 377, 378, 379, 380, 381, 382, 2786, 377, + 378, 379, 380, 381, 382, 377, 378, 379, 380, 381, + 382, 2187, 1683, 2786, 377, 378, 1686, 380, 381, 382, + 2786, 2786, 1687, 377, 378, 379, 380, 381, 382, 2190, + 2195, 2786, 1688, 2197, 377, 378, 379, 380, 381, 382, + 2187, 757, 2786, 2182, 2786, 377, 378, 379, 380, 381, + 382, 1687, 1689, 1095, 2786, 2786, 2786, 2786, 2190, 2195, + 2786, 1688, 2197, 1690, 1694, 1694, 1694, 2786, 1755, 1755, + 1755, 377, 378, 379, 380, 381, 382, 2786, 2786, 1695, + + 2786, 1689, 1095, 1756, 2198, 2786, 377, 378, 379, 380, + 381, 382, 1690, 377, 378, 379, 380, 381, 382, 2786, + 2786, 2786, 2786, 2786, 377, 378, 379, 380, 381, 382, + 1691, 2786, 2786, 2198, 2786, 2786, 2786, 2786, 2786, 2786, + 1692, 473, 474, 475, 476, 477, 478, 2786, 377, 378, + 379, 380, 381, 382, 2786, 2786, 1693, 2202, 1700, 1691, + 1377, 912, 912, 912, 912, 912, 912, 912, 912, 1692, + 1701, 377, 378, 1696, 380, 381, 382, 1892, 377, 378, + 379, 380, 381, 382, 2786, 1693, 2202, 1700, 2786, 2166, + 2166, 2166, 377, 378, 379, 380, 381, 382, 2786, 1701, + + 2786, 2786, 2786, 2167, 377, 378, 379, 380, 381, 382, + 377, 378, 379, 380, 381, 382, 1704, 466, 466, 466, + 466, 466, 466, 466, 466, 1705, 2786, 377, 378, 379, + 380, 381, 382, 2786, 2203, 2208, 2786, 2209, 1710, 2786, + 1388, 912, 912, 912, 912, 912, 912, 912, 912, 2786, + 2786, 2210, 1706, 2211, 1705, 1707, 2786, 377, 378, 379, + 380, 381, 382, 2203, 2208, 1714, 2209, 1710, 2214, 2216, + 2786, 377, 378, 379, 380, 381, 382, 2786, 2168, 2786, + 2210, 1706, 2211, 2786, 1707, 1713, 466, 466, 466, 466, + 466, 466, 466, 466, 1714, 2786, 2786, 2214, 2216, 377, + + 378, 379, 380, 381, 382, 2786, 377, 378, 379, 380, + 381, 382, 377, 378, 379, 380, 381, 382, 2786, 2217, + 2218, 2786, 2786, 377, 378, 379, 380, 381, 382, 377, + 378, 379, 380, 381, 382, 2786, 1718, 466, 466, 466, + 466, 466, 466, 466, 466, 2786, 2786, 1715, 2217, 2218, + 377, 378, 379, 380, 381, 382, 1719, 2786, 2786, 2786, + 1722, 1722, 1722, 2786, 2786, 397, 2219, 2185, 2786, 1720, + 2220, 2221, 2222, 2224, 2786, 1723, 1715, 818, 377, 378, + 379, 380, 381, 382, 2786, 1719, 1412, 912, 912, 912, + 912, 912, 912, 912, 912, 2219, 1721, 2786, 1720, 2220, + + 2221, 2222, 2224, 2786, 2786, 2786, 818, 1753, 377, 378, + 379, 380, 381, 382, 2786, 2786, 2786, 2786, 2786, 377, + 378, 379, 380, 381, 382, 1721, 1752, 2786, 2786, 2786, + 377, 378, 379, 380, 381, 382, 1753, 2786, 2225, 2226, + 2227, 377, 378, 379, 380, 381, 382, 377, 378, 1724, + 380, 381, 382, 2786, 1754, 1752, 2786, 377, 378, 379, + 380, 381, 382, 1762, 2228, 1758, 2786, 2225, 2226, 2227, + 377, 378, 379, 380, 381, 382, 2786, 377, 378, 379, + 380, 381, 382, 1754, 1755, 1755, 1755, 377, 378, 379, + 380, 381, 382, 2228, 1758, 1759, 1763, 2786, 2786, 1756, + + 377, 378, 379, 380, 381, 382, 2786, 2786, 2786, 2786, + 377, 378, 379, 380, 381, 382, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 1759, 1763, 377, 378, 379, 380, + 381, 382, 1760, 1764, 473, 474, 475, 476, 477, 478, + 2229, 2230, 473, 474, 475, 476, 477, 478, 502, 377, + 378, 379, 380, 381, 382, 2786, 502, 2786, 2786, 2786, + 2786, 1760, 1764, 1850, 1850, 1850, 2786, 502, 1765, 2229, + 2230, 377, 378, 1757, 380, 381, 382, 1766, 1851, 2231, + 2232, 2233, 502, 2238, 473, 474, 475, 476, 477, 478, + 2239, 377, 378, 379, 380, 381, 382, 1765, 1767, 502, + + 2786, 2786, 2786, 2786, 2786, 502, 1766, 1772, 2231, 2232, + 2233, 2786, 2238, 502, 2786, 2786, 2786, 1768, 2786, 2239, + 2240, 509, 510, 515, 512, 513, 514, 1767, 502, 509, + 510, 515, 512, 513, 514, 2786, 1772, 2241, 2250, 2786, + 509, 510, 515, 512, 513, 514, 1768, 502, 1771, 2240, + 2786, 2786, 1984, 502, 2786, 509, 510, 515, 512, 513, + 514, 2786, 2786, 1769, 1791, 2786, 2241, 2250, 1770, 1773, + 2786, 1774, 509, 510, 515, 512, 513, 514, 509, 510, + 515, 512, 513, 514, 2786, 2786, 509, 510, 515, 512, + 513, 514, 1769, 1791, 1645, 1487, 1487, 1770, 1773, 1792, + + 1774, 509, 510, 515, 512, 513, 514, 1648, 2786, 2786, + 2786, 2786, 660, 661, 662, 663, 664, 665, 2786, 1793, + 509, 510, 515, 512, 513, 514, 509, 510, 515, 512, + 513, 514, 546, 547, 548, 549, 550, 551, 1645, 1487, + 1487, 2786, 2786, 1792, 1645, 1487, 1487, 1809, 1793, 1792, + 2251, 1648, 2252, 1645, 1487, 1487, 2253, 1648, 1792, 2257, + 2786, 2265, 2266, 1793, 2267, 2268, 1797, 2269, 2274, 1793, + 660, 661, 662, 663, 664, 665, 1809, 2288, 1793, 2251, + 2786, 2252, 2786, 1794, 2786, 2253, 2786, 2786, 2257, 1810, + 2265, 2266, 1793, 2267, 2268, 2786, 2269, 2274, 1793, 660, + + 661, 662, 663, 664, 665, 2786, 2288, 1793, 1487, 1044, + 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1813, 1810, 2786, + 2786, 1811, 2291, 1812, 1899, 2292, 2293, 1794, 2296, 2786, + 2786, 2297, 2786, 1794, 660, 661, 662, 663, 664, 665, + 2786, 2786, 1794, 1645, 1487, 1487, 1813, 757, 1792, 2280, + 1811, 2291, 1812, 1899, 2292, 2293, 1648, 2296, 2300, 1095, + 2297, 1817, 700, 701, 702, 703, 704, 705, 1793, 700, + 701, 702, 703, 704, 705, 700, 701, 702, 703, 704, + 705, 473, 474, 475, 476, 477, 478, 2300, 1095, 757, + 1817, 1816, 2786, 2786, 2786, 2786, 397, 1793, 1820, 2786, + + 2786, 759, 746, 747, 748, 749, 750, 751, 399, 2786, + 2313, 2313, 2313, 746, 747, 748, 749, 750, 751, 2786, + 2786, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, + 759, 2786, 1794, 1645, 1487, 1487, 2786, 399, 1792, 546, + 547, 548, 549, 550, 551, 2786, 1648, 1513, 912, 912, + 912, 912, 912, 912, 912, 912, 2302, 2303, 1793, 2786, + 2304, 2305, 746, 747, 748, 749, 750, 751, 2786, 377, + 378, 379, 380, 381, 382, 2786, 2786, 2786, 2786, 397, + 2786, 2283, 2786, 2786, 2786, 2302, 2303, 1793, 2786, 2304, + 2305, 818, 377, 378, 379, 380, 381, 382, 1824, 2314, + + 1825, 2307, 2308, 1823, 377, 378, 379, 380, 381, 382, + 2786, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, + 818, 2786, 1794, 1645, 1487, 1487, 2786, 1824, 1792, 1825, + 2307, 2308, 1823, 2786, 2786, 2786, 1648, 2786, 2786, 2786, + 2786, 377, 378, 379, 380, 381, 382, 2786, 1793, 377, + 378, 379, 380, 381, 382, 377, 378, 379, 380, 381, + 382, 377, 378, 379, 380, 381, 382, 660, 661, 662, + 663, 664, 665, 2786, 2315, 2315, 2315, 1793, 2786, 2786, + 2786, 1826, 2786, 377, 378, 379, 380, 381, 382, 1829, + 466, 466, 466, 466, 466, 466, 466, 466, 2786, 2786, + + 2786, 1800, 1801, 1801, 1801, 1801, 1801, 1801, 1801, 1801, + 1826, 1830, 1794, 1645, 1487, 1487, 2309, 2786, 1792, 2786, + 377, 378, 379, 380, 381, 382, 1648, 1837, 466, 466, + 466, 466, 466, 466, 466, 466, 2786, 2786, 1793, 1910, + 1830, 2320, 2320, 2320, 2786, 2309, 377, 378, 379, 380, + 381, 382, 377, 378, 379, 380, 381, 382, 1832, 2310, + 1834, 2786, 2786, 2316, 2097, 2097, 2097, 1793, 1910, 2786, + 2786, 1831, 377, 378, 379, 380, 381, 382, 1833, 1545, + 546, 547, 548, 549, 550, 551, 2311, 1832, 2310, 1834, + 2786, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, 1802, + + 1831, 2786, 1794, 1645, 1487, 1487, 2786, 1833, 1792, 377, + 378, 379, 380, 381, 382, 2311, 1648, 377, 378, 379, + 380, 381, 382, 2312, 2786, 2285, 2786, 1840, 1793, 2786, + 2321, 2270, 2270, 2270, 377, 378, 379, 380, 381, 382, + 2286, 2318, 2786, 377, 378, 379, 380, 381, 382, 2786, + 2786, 2786, 2312, 2098, 2285, 2786, 1840, 1793, 1544, 912, + 912, 912, 912, 912, 912, 912, 912, 2786, 2324, 2286, + 2318, 1841, 2271, 2327, 377, 378, 379, 380, 381, 382, + 2786, 1803, 1803, 1803, 1803, 1803, 1803, 1803, 1804, 1805, + 2328, 2786, 1794, 1645, 1487, 1487, 2786, 2324, 1792, 2786, + + 1841, 2271, 2327, 2786, 2786, 2786, 1648, 2786, 2786, 2786, + 1736, 2786, 2786, 2786, 2786, 2786, 2786, 1740, 1793, 2328, + 2272, 2786, 377, 378, 379, 380, 381, 382, 377, 378, + 379, 380, 381, 382, 1846, 1850, 1850, 1850, 2786, 1736, + 377, 378, 379, 380, 381, 382, 1740, 1793, 2786, 2786, + 1851, 2786, 2786, 377, 378, 379, 380, 381, 382, 2786, + 2786, 2786, 2786, 1846, 377, 378, 379, 380, 381, 382, + 2786, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, 1806, + 1855, 2786, 1794, 2786, 2786, 377, 378, 379, 380, 381, + 382, 1555, 912, 912, 912, 912, 912, 912, 912, 912, + + 1560, 912, 912, 912, 912, 912, 912, 912, 912, 1855, + 2786, 377, 378, 379, 380, 381, 382, 2786, 2786, 2786, + 2786, 2329, 377, 378, 1852, 380, 381, 382, 1722, 1722, + 1722, 1856, 2786, 2330, 2786, 377, 378, 379, 380, 381, + 382, 2786, 2786, 1723, 2786, 2322, 2322, 2322, 2786, 1857, + 2329, 2331, 2334, 1858, 377, 378, 379, 380, 381, 382, + 1856, 1889, 2330, 2337, 2786, 1859, 1862, 466, 466, 466, + 466, 466, 466, 466, 466, 1890, 1891, 2786, 2786, 2786, + 2331, 2334, 1858, 377, 378, 379, 380, 381, 382, 1895, + 1889, 2786, 2337, 2786, 1859, 1894, 466, 466, 466, 466, + + 466, 466, 466, 466, 1890, 1891, 1898, 377, 378, 379, + 380, 381, 382, 2786, 2786, 2786, 2786, 1860, 1895, 1896, + 502, 377, 378, 379, 380, 381, 382, 502, 2188, 2188, + 2188, 1900, 2335, 502, 2323, 2336, 2338, 377, 378, 379, + 380, 381, 382, 1685, 1903, 1901, 2339, 2345, 1896, 2786, + 377, 378, 379, 380, 381, 382, 2786, 502, 2786, 2786, + 1900, 2335, 1902, 2346, 2336, 2338, 377, 378, 379, 380, + 381, 382, 2786, 1903, 1901, 2339, 2345, 473, 474, 475, + 476, 477, 478, 473, 474, 475, 476, 477, 478, 1904, + 2786, 502, 2346, 509, 510, 515, 512, 513, 514, 1906, + + 509, 510, 515, 512, 513, 514, 509, 510, 515, 512, + 513, 514, 502, 2786, 2193, 2193, 2193, 2189, 1904, 1927, + 2786, 2347, 2786, 1905, 2786, 2786, 2786, 2786, 1906, 1695, + 509, 510, 515, 512, 513, 514, 502, 2786, 2786, 2786, + 2786, 2786, 502, 2786, 2786, 2786, 2786, 1907, 1927, 1945, + 2347, 502, 1905, 1908, 700, 701, 702, 703, 704, 705, + 2786, 2786, 1909, 2786, 509, 510, 515, 512, 513, 514, + 660, 661, 662, 663, 664, 665, 1907, 2348, 1945, 1645, + 1487, 1487, 1908, 2786, 1792, 509, 510, 515, 512, 513, + 514, 1909, 1648, 1978, 1978, 1978, 660, 661, 662, 663, + + 664, 665, 2786, 2194, 1793, 2349, 2348, 2786, 2786, 509, + 510, 515, 512, 513, 514, 509, 510, 515, 512, 513, + 514, 2786, 1979, 2786, 509, 510, 515, 512, 513, 514, + 1645, 1487, 1487, 1793, 2349, 1792, 1645, 1487, 1487, 2786, + 1946, 1792, 2351, 1648, 2786, 1931, 1932, 1932, 2786, 1648, + 1792, 1979, 1939, 1932, 1932, 1793, 1947, 1940, 1797, 2358, + 2359, 1793, 2360, 2786, 2786, 1941, 2786, 2786, 1794, 1946, + 1793, 2351, 1928, 1645, 1487, 1487, 1949, 1942, 1792, 2786, + 2786, 2786, 1980, 2786, 1793, 1947, 1648, 2786, 2358, 2359, + 1793, 2360, 660, 661, 662, 663, 664, 665, 1793, 1793, + + 2786, 1928, 2097, 2097, 2097, 1949, 1942, 700, 701, 702, + 703, 704, 705, 2786, 1929, 2786, 1948, 1545, 2361, 1794, + 2362, 2364, 2325, 2325, 2325, 1794, 2786, 1793, 700, 701, + 702, 703, 704, 705, 1933, 1645, 1487, 1487, 2786, 2786, + 1792, 1943, 2166, 2166, 2166, 1948, 2786, 2361, 1648, 2362, + 2364, 1936, 1936, 2786, 2786, 1936, 2167, 1936, 1936, 1936, + 1793, 2032, 1794, 700, 701, 702, 703, 704, 705, 757, + 2374, 1952, 2786, 746, 747, 748, 749, 750, 751, 2786, + 2786, 759, 397, 2340, 1955, 2786, 2786, 2786, 2786, 1793, + 2786, 2098, 2786, 2341, 399, 2786, 2786, 2786, 2786, 2374, + + 1957, 1684, 912, 912, 912, 912, 912, 912, 912, 912, + 759, 2326, 2340, 1647, 1647, 1647, 1647, 1647, 1647, 1647, + 1647, 1647, 2341, 399, 1794, 1645, 1487, 1487, 2786, 1957, + 1792, 2168, 473, 474, 475, 476, 477, 478, 1648, 2786, + 2049, 2786, 746, 747, 748, 749, 750, 751, 2786, 2375, + 1793, 2786, 2376, 2378, 2786, 377, 378, 379, 380, 381, + 382, 377, 378, 379, 380, 381, 382, 2786, 2786, 2049, + 1958, 2379, 2786, 2786, 2786, 2332, 2332, 2332, 2375, 1793, + 2786, 2376, 2378, 660, 661, 662, 663, 664, 665, 1959, + 1694, 912, 912, 912, 912, 912, 912, 912, 912, 1958, + + 2379, 1960, 2786, 1645, 1935, 1935, 1935, 1935, 1935, 1935, + 1935, 1935, 2786, 2786, 1794, 1645, 1487, 1487, 1959, 2786, + 1792, 377, 378, 379, 380, 381, 382, 2786, 1648, 2786, + 1960, 1965, 1966, 660, 661, 662, 663, 664, 665, 2786, + 1793, 377, 378, 379, 380, 381, 382, 377, 378, 379, + 380, 381, 382, 377, 378, 379, 380, 381, 382, 2786, + 1965, 1966, 2786, 2786, 2333, 2786, 2212, 2212, 2212, 1793, + 2786, 2786, 2786, 2786, 2380, 377, 378, 379, 380, 381, + 382, 1723, 1967, 2786, 2786, 2786, 377, 378, 379, 380, + 381, 382, 1968, 1935, 1935, 1935, 1935, 1935, 1935, 1935, + + 1935, 1935, 2786, 2380, 1794, 1645, 1487, 1487, 2786, 2786, + 1792, 1967, 377, 378, 379, 380, 381, 382, 1648, 2786, + 2387, 1968, 2786, 2388, 2389, 2391, 2786, 1976, 2786, 2786, + 1793, 2786, 2382, 2382, 2382, 377, 378, 379, 380, 381, + 382, 1975, 2392, 377, 378, 379, 380, 381, 382, 2387, + 2786, 2786, 2388, 2389, 2391, 2213, 1976, 2786, 2786, 1793, + 1986, 466, 466, 466, 466, 466, 466, 466, 466, 2393, + 1975, 2392, 1981, 2786, 2786, 377, 378, 379, 380, 381, + 382, 2786, 2786, 1647, 1647, 1647, 1647, 1647, 1647, 1647, + 1647, 1647, 2786, 2034, 1794, 1645, 1487, 1487, 2393, 2786, + + 1792, 1981, 377, 378, 379, 380, 381, 382, 1648, 1988, + 1722, 912, 912, 912, 912, 912, 912, 912, 912, 2394, + 1793, 2383, 2034, 2786, 377, 378, 379, 380, 381, 382, + 377, 378, 379, 380, 381, 382, 2786, 2786, 1988, 2786, + 473, 474, 475, 476, 477, 478, 2786, 2786, 2394, 1793, + 2786, 757, 397, 2369, 2372, 377, 378, 379, 380, 381, + 382, 2786, 2025, 1095, 818, 377, 378, 379, 380, 381, + 382, 2786, 2786, 1936, 1936, 1936, 1936, 1936, 1936, 1936, + 1936, 1936, 2396, 2786, 1794, 1645, 1487, 1487, 2786, 2786, + 1792, 2025, 1095, 818, 2786, 2786, 2399, 2030, 1648, 1755, + + 912, 912, 912, 912, 912, 912, 912, 912, 2786, 2786, + 1793, 2396, 377, 378, 379, 380, 381, 382, 502, 377, + 378, 379, 380, 381, 382, 2399, 2030, 2786, 2033, 2786, + 2402, 2083, 2083, 2083, 502, 2786, 2255, 2255, 2255, 1793, + 502, 2188, 2188, 2188, 377, 378, 379, 380, 381, 382, + 2036, 1756, 2786, 2035, 2786, 2786, 1685, 2033, 502, 2402, + 2084, 2410, 2786, 1936, 1936, 1936, 1936, 1936, 1936, 1936, + 1936, 1936, 502, 2786, 1794, 1645, 1487, 1487, 2786, 2036, + 1792, 473, 474, 475, 476, 477, 478, 2786, 1648, 2084, + 2410, 509, 510, 515, 512, 513, 514, 2412, 2413, 2786, + + 1793, 2786, 502, 2786, 2786, 2786, 2786, 509, 510, 515, + 512, 513, 514, 509, 510, 515, 512, 513, 514, 502, + 2085, 2786, 2037, 2068, 2786, 2256, 2412, 2413, 502, 1793, + 2189, 509, 510, 515, 512, 513, 514, 2038, 502, 700, + 701, 702, 703, 704, 705, 509, 510, 515, 512, 513, + 514, 2037, 2068, 1937, 1937, 1937, 1937, 1937, 1937, 1937, + 1937, 1937, 2416, 2786, 1794, 2786, 2038, 2786, 2786, 660, + 661, 662, 663, 664, 665, 509, 510, 515, 512, 513, + 514, 2384, 2384, 2384, 2786, 1645, 1487, 1487, 2786, 2786, + 1792, 2416, 509, 510, 515, 512, 513, 514, 1648, 2786, + + 2786, 509, 510, 515, 512, 513, 514, 2050, 2786, 2786, + 1793, 509, 510, 515, 512, 513, 514, 1645, 1487, 1487, + 2786, 2786, 1792, 2786, 2053, 1932, 1932, 2786, 2067, 2054, + 1648, 2786, 2786, 1939, 1932, 1932, 2050, 2055, 1940, 1793, + 2417, 2786, 1793, 1645, 1487, 1487, 1941, 2418, 1792, 2056, + 2060, 1487, 1487, 2419, 2420, 1940, 1648, 2067, 1942, 2421, + 1939, 1932, 1932, 1941, 2786, 1940, 2786, 2422, 1793, 2417, + 2385, 1793, 2423, 1941, 1794, 1942, 2418, 2786, 2056, 2090, + 2090, 2090, 2419, 2420, 2786, 1942, 2786, 1942, 2421, 660, + 661, 662, 663, 664, 665, 1645, 2422, 1793, 2070, 2786, + + 2424, 2423, 2425, 2786, 1942, 2786, 1794, 2426, 2091, 2786, + 2786, 2786, 2427, 2057, 1942, 2062, 1487, 1487, 2786, 2428, + 2054, 2058, 1943, 2786, 2786, 2786, 2786, 2070, 2055, 2424, + 2786, 2425, 1794, 1645, 1487, 1487, 2426, 2091, 1792, 2061, + 2056, 2427, 2060, 1487, 1487, 2069, 1648, 1940, 2428, 1943, + 2429, 2071, 2060, 1487, 1487, 2064, 2430, 1940, 1793, 700, + 701, 702, 703, 704, 705, 1941, 2786, 1942, 2092, 2056, + 2060, 1487, 1487, 2786, 2069, 1940, 2437, 1942, 2786, 2429, + 2071, 2786, 2786, 1941, 2786, 2430, 2786, 1793, 700, 701, + 702, 703, 704, 705, 2065, 1942, 1942, 700, 701, 702, + + 703, 704, 705, 2438, 2063, 2437, 1942, 2152, 757, 2439, + 2074, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, 1647, + 759, 2786, 1794, 2065, 1942, 397, 2786, 2077, 2786, 2441, + 2786, 2061, 2438, 1978, 1978, 1978, 2152, 399, 2439, 2786, + 2786, 2061, 2786, 2786, 2786, 2450, 2786, 2451, 2066, 759, + 2786, 377, 378, 379, 380, 381, 382, 2786, 2441, 2061, + 2079, 2786, 1979, 2786, 2456, 2457, 399, 2462, 473, 474, + 475, 476, 477, 478, 2450, 2081, 2451, 2080, 2786, 2463, + 2464, 746, 747, 748, 749, 750, 751, 2151, 2786, 2079, + 2087, 1979, 2786, 2456, 2457, 2786, 2462, 2786, 377, 378, + + 379, 380, 381, 382, 2081, 2786, 2080, 2786, 2463, 2464, + 2786, 2786, 377, 378, 379, 380, 381, 382, 2086, 2087, + 2786, 2096, 1980, 377, 378, 379, 380, 381, 382, 2786, + 377, 378, 379, 380, 381, 382, 377, 378, 379, 380, + 381, 382, 2786, 2465, 2473, 2088, 2786, 2086, 2786, 2786, + 2096, 377, 378, 379, 380, 381, 382, 2786, 473, 474, + 475, 476, 477, 478, 2786, 377, 378, 379, 380, 381, + 382, 2095, 2465, 2473, 2088, 2786, 2786, 2786, 377, 378, + 379, 380, 381, 382, 377, 378, 379, 380, 381, 382, + 2786, 2786, 2786, 377, 378, 379, 380, 381, 382, 2145, + + 2095, 1850, 912, 912, 912, 912, 912, 912, 912, 912, + 2112, 2112, 2112, 2147, 2147, 2147, 2786, 2153, 2786, 377, + 378, 379, 380, 381, 382, 2786, 2786, 2786, 2145, 2786, + 377, 378, 379, 380, 381, 382, 2786, 2786, 2476, 2113, + 502, 2478, 2148, 2479, 2480, 2786, 2153, 502, 2786, 2786, + 377, 378, 379, 380, 381, 382, 2170, 502, 2155, 2313, + 2313, 2313, 2786, 2786, 2786, 502, 2154, 2476, 2113, 2156, + 2478, 2148, 2479, 2480, 473, 474, 475, 476, 477, 478, + 2481, 2482, 2193, 2193, 2193, 2170, 2786, 2155, 2786, 377, + 378, 379, 380, 381, 382, 2154, 2786, 1695, 2156, 2114, + + 2157, 2786, 2149, 660, 661, 662, 663, 664, 665, 2481, + 2482, 2786, 2786, 509, 510, 515, 512, 513, 514, 2786, + 509, 510, 515, 512, 513, 514, 2315, 2315, 2315, 2485, + 509, 510, 515, 512, 513, 514, 2786, 2786, 509, 510, + 515, 512, 513, 514, 1645, 1487, 1487, 2483, 2314, 1792, + 2062, 1487, 1487, 2786, 2486, 2054, 2484, 1648, 2485, 2053, + 1932, 1932, 2786, 2055, 2054, 2062, 1487, 1487, 2786, 1793, + 2054, 2194, 2055, 2487, 2488, 2056, 2483, 2171, 2055, 2786, + 2062, 1487, 1487, 2486, 2056, 2054, 2062, 1487, 1487, 2786, + 2056, 2054, 2786, 2172, 2786, 2062, 1487, 1487, 1793, 2055, + + 2054, 2489, 2487, 2488, 2056, 2056, 2171, 2490, 2055, 2493, + 2786, 2056, 2786, 2056, 2494, 2316, 1645, 1487, 1487, 2056, + 2056, 1792, 2060, 1487, 1487, 2786, 2495, 1940, 2173, 1648, + 2489, 2786, 2496, 1794, 2056, 1941, 2490, 2786, 2493, 2063, + 2056, 1793, 2786, 2494, 757, 2497, 2445, 1942, 2057, 2056, + 2786, 2298, 2298, 2298, 2063, 2495, 1095, 2173, 2060, 1487, + 1487, 2496, 2786, 1940, 2786, 2786, 1851, 2786, 2498, 2063, + 1793, 1941, 2499, 2174, 2497, 2063, 1942, 2062, 1487, 1487, + 2786, 2786, 2054, 1942, 2063, 1095, 397, 2786, 2448, 2786, + 2055, 2062, 1487, 1487, 1931, 2786, 2054, 2498, 818, 2786, + + 2786, 2499, 2056, 2178, 2055, 1794, 2507, 2786, 1939, 1932, + 1932, 2061, 1942, 1940, 2491, 2492, 2056, 2060, 1487, 1487, + 2786, 2064, 1940, 2786, 2060, 1487, 1487, 818, 2786, 1940, + 1941, 2056, 2178, 1942, 2179, 2507, 2175, 1941, 2508, 2177, + 2299, 2180, 1942, 2491, 2492, 2056, 757, 2061, 2183, 1942, + 2786, 660, 661, 662, 663, 664, 665, 2786, 759, 2083, + 2083, 2083, 1942, 2179, 2786, 2786, 2063, 2508, 2177, 2176, + 2180, 1942, 377, 378, 379, 380, 381, 382, 1942, 2786, + 2063, 700, 701, 702, 703, 704, 705, 759, 2084, 700, + 701, 702, 703, 704, 705, 2786, 397, 1943, 2186, 2212, + + 2212, 2212, 1939, 2786, 2786, 2786, 2061, 2786, 399, 2786, + 2786, 2786, 2786, 2061, 1723, 2786, 2509, 2084, 2510, 746, + 747, 748, 749, 750, 751, 2786, 2786, 2400, 2400, 2400, + 377, 378, 379, 380, 381, 382, 2786, 399, 377, 378, + 379, 380, 381, 382, 2786, 2509, 2511, 2510, 2085, 2255, + 2255, 2255, 377, 378, 379, 380, 381, 382, 2520, 2786, + 2192, 2786, 2521, 2199, 1756, 2090, 2090, 2090, 2786, 377, + 378, 379, 380, 381, 382, 2511, 377, 378, 379, 380, + 381, 382, 2452, 2452, 2452, 2786, 2200, 2520, 2213, 2192, + 2260, 2521, 2199, 2786, 2091, 2205, 2205, 2205, 2112, 2112, + + 2112, 2786, 2134, 2134, 2134, 2454, 2454, 2454, 2786, 377, + 378, 379, 380, 381, 382, 2200, 2401, 377, 378, 379, + 380, 381, 382, 2091, 2206, 2786, 2234, 2113, 2524, 2235, + 2262, 2786, 377, 378, 379, 380, 381, 382, 2256, 2786, + 2382, 2382, 2382, 2236, 2525, 2786, 2147, 2147, 2147, 2786, + 2466, 2466, 2466, 2206, 2092, 2234, 2113, 2524, 2235, 2262, + 2254, 473, 474, 475, 476, 477, 478, 2526, 2529, 2786, + 2786, 2453, 2236, 2525, 502, 2148, 2530, 473, 474, 475, + 476, 477, 478, 502, 2207, 2786, 2786, 2114, 2786, 2254, + 2261, 2135, 2242, 502, 2455, 2786, 2526, 2529, 2243, 502, + + 2786, 2263, 2244, 2245, 2148, 2530, 2786, 2246, 2247, 2248, + 2786, 2249, 377, 378, 379, 380, 381, 382, 2786, 2261, + 2786, 2242, 2270, 2270, 2270, 2264, 2531, 2243, 2786, 2383, + 2263, 2244, 2245, 2533, 2786, 2149, 2246, 2247, 2248, 2467, + 2249, 473, 474, 475, 476, 477, 478, 509, 510, 515, + 512, 513, 514, 2539, 2264, 2531, 509, 510, 515, 512, + 513, 514, 2533, 2271, 2786, 2786, 509, 510, 515, 512, + 513, 514, 509, 510, 515, 512, 513, 514, 1645, 1487, + 1487, 2540, 2539, 1792, 2053, 1932, 1932, 2543, 2786, 2054, + 2786, 1648, 2271, 2062, 1487, 1487, 2786, 2172, 2054, 2062, + + 1487, 1487, 2786, 1793, 2054, 2544, 2055, 2786, 2786, 2056, + 2540, 2272, 2055, 2545, 2546, 2275, 2543, 757, 2056, 2281, + 2060, 1487, 1487, 2547, 2056, 1940, 2062, 1487, 1487, 759, + 2786, 2054, 1793, 1941, 2544, 2060, 1487, 1487, 2056, 2055, + 1940, 2786, 2545, 2546, 2275, 1942, 2786, 2056, 1941, 2548, + 2786, 2056, 2547, 2056, 2549, 2786, 2550, 2551, 759, 397, + 1942, 2284, 2786, 2786, 2786, 2786, 2786, 1794, 2276, 2786, + 2277, 399, 2786, 2057, 1942, 2786, 2552, 2053, 2548, 2278, + 2056, 2553, 2063, 2549, 2786, 2550, 2551, 2786, 2063, 1942, + 746, 747, 748, 749, 750, 751, 2786, 2276, 2060, 2277, + + 399, 2294, 2289, 2786, 2062, 2552, 2786, 2786, 2278, 2061, + 2553, 2786, 2786, 2786, 2786, 2063, 660, 661, 662, 663, + 664, 665, 2786, 2353, 2061, 700, 701, 702, 703, 704, + 705, 2289, 377, 378, 379, 380, 381, 382, 2295, 377, + 378, 379, 380, 381, 382, 2205, 2205, 2205, 377, 378, + 379, 380, 381, 382, 2786, 2786, 2342, 377, 378, 379, + 380, 381, 382, 2354, 2343, 502, 2786, 2295, 2786, 2786, + 2786, 2344, 2355, 2356, 2206, 502, 2298, 2298, 2298, 377, + 378, 379, 380, 381, 382, 2342, 2366, 2357, 2554, 2786, + 2786, 1851, 2354, 2343, 473, 474, 475, 476, 477, 478, + + 2344, 2355, 2356, 2206, 2786, 2474, 2474, 2474, 473, 474, + 475, 476, 477, 478, 2786, 2786, 2357, 2554, 473, 474, + 475, 476, 477, 478, 660, 661, 662, 663, 664, 665, + 2786, 2062, 1487, 1487, 2207, 2367, 2054, 2555, 509, 510, + 515, 512, 513, 514, 2055, 2400, 2400, 2400, 509, 510, + 515, 512, 513, 514, 2433, 2786, 2056, 2060, 1487, 1487, + 2556, 2786, 1940, 2557, 2365, 2299, 2555, 757, 2786, 2370, + 1941, 2786, 2786, 700, 701, 702, 703, 704, 705, 759, + 2786, 2558, 1942, 2433, 397, 2056, 2373, 2377, 2786, 2556, + 2786, 2786, 2557, 2365, 2475, 2786, 399, 2786, 2559, 2786, + + 473, 474, 475, 476, 477, 478, 2381, 2786, 759, 2432, + 2558, 1942, 2469, 2469, 2469, 2786, 2377, 2320, 2320, 2320, + 2063, 2786, 2500, 2500, 2500, 399, 2470, 2559, 377, 378, + 379, 380, 381, 382, 2401, 2381, 2332, 2332, 2332, 2786, + 746, 747, 748, 749, 750, 751, 2061, 2325, 2325, 2325, + 2403, 2786, 2322, 2322, 2322, 2786, 2786, 377, 378, 379, + 380, 381, 382, 377, 378, 379, 380, 381, 382, 2434, + 377, 378, 379, 380, 381, 382, 2414, 2786, 2405, 2403, + 473, 474, 475, 476, 477, 478, 502, 2786, 2408, 2062, + 1487, 1487, 2406, 502, 2054, 2442, 2786, 2560, 2434, 2786, + + 2561, 2471, 2055, 2786, 2786, 2414, 2321, 2405, 757, 2786, + 2446, 2501, 2786, 2435, 2056, 2443, 2786, 2408, 2436, 2562, + 759, 2406, 2569, 2786, 2442, 2333, 2560, 2786, 2503, 2561, + 473, 474, 475, 476, 477, 478, 2326, 2786, 397, 2786, + 2449, 2323, 2435, 2056, 2443, 2786, 2786, 2436, 2562, 759, + 399, 2569, 660, 661, 662, 663, 664, 665, 2786, 509, + 510, 515, 512, 513, 514, 2786, 509, 510, 515, 512, + 513, 514, 700, 701, 702, 703, 704, 705, 2063, 399, + 2786, 746, 747, 748, 749, 750, 751, 2786, 2504, 377, + 378, 379, 380, 381, 382, 2384, 2384, 2384, 2458, 473, + + 474, 475, 476, 477, 478, 473, 474, 475, 476, 477, + 478, 377, 378, 379, 380, 381, 382, 2504, 502, 2786, + 2786, 2570, 2571, 2512, 502, 2578, 2579, 2458, 2460, 2452, + 2452, 2452, 2454, 2454, 2454, 2786, 757, 2786, 2515, 2786, + 473, 474, 475, 476, 477, 478, 2505, 2513, 1095, 2786, + 2570, 2571, 2512, 2506, 2578, 2579, 2786, 2460, 2786, 2786, + 377, 378, 379, 380, 381, 382, 757, 397, 2516, 2518, + 2527, 2527, 2527, 2786, 2580, 2505, 2513, 1095, 759, 818, + 2786, 2786, 2506, 2786, 2385, 660, 661, 662, 663, 664, + 665, 509, 510, 515, 512, 513, 514, 509, 510, 515, + + 512, 513, 514, 2580, 397, 2786, 2519, 759, 818, 700, + 701, 702, 703, 704, 705, 2786, 399, 2565, 2453, 2786, + 2786, 2455, 377, 378, 379, 380, 381, 382, 2466, 2466, + 2466, 2566, 2469, 2469, 2469, 2534, 2534, 2534, 2581, 746, + 747, 748, 749, 750, 751, 399, 2470, 2474, 2474, 2474, + 2500, 2500, 2500, 2786, 2527, 2527, 2527, 502, 2786, 2528, + 2566, 660, 661, 662, 663, 664, 665, 2581, 2786, 2786, + 2786, 2535, 502, 757, 2582, 2573, 2536, 377, 378, 379, + 380, 381, 382, 2567, 2568, 1095, 2587, 2541, 473, 474, + 475, 476, 477, 478, 473, 474, 475, 476, 477, 478, + + 2535, 2786, 2786, 2582, 2786, 2536, 700, 701, 702, 703, + 704, 705, 2567, 2568, 1095, 2587, 2541, 2467, 2534, 2534, + 2534, 2471, 2588, 2786, 2537, 757, 397, 2574, 2576, 2589, + 509, 510, 515, 512, 513, 514, 2475, 759, 818, 2501, + 397, 2590, 2577, 2528, 2592, 509, 510, 515, 512, 513, + 514, 2588, 399, 2593, 2535, 2594, 2595, 2596, 2589, 2536, + 2597, 2598, 2599, 2600, 2601, 2602, 759, 818, 2603, 2613, + 2590, 2786, 2786, 2592, 2786, 2604, 2605, 2606, 502, 2607, + 2608, 399, 2593, 2535, 2594, 2595, 2596, 2786, 2536, 2597, + 2598, 2599, 2600, 2601, 2602, 2609, 2610, 2603, 746, 747, + + 748, 749, 750, 751, 2604, 2605, 2606, 2537, 2607, 2608, + 2611, 2786, 502, 377, 378, 379, 380, 381, 382, 2614, + 2616, 2617, 2786, 2786, 2609, 2610, 757, 2786, 2619, 2624, + 2641, 2641, 2641, 2786, 757, 2786, 2620, 2615, 1095, 2611, + 473, 474, 475, 476, 477, 478, 759, 2625, 2614, 2616, + 2617, 509, 510, 515, 512, 513, 514, 397, 2624, 2622, + 473, 474, 475, 476, 477, 478, 2615, 1095, 2626, 818, + 2627, 2628, 397, 2629, 2623, 759, 2625, 2633, 473, 474, + 475, 476, 477, 478, 399, 509, 510, 515, 512, 513, + 514, 2634, 2637, 2638, 2639, 2640, 2643, 2626, 818, 2627, + + 2628, 2644, 2629, 2645, 2646, 2647, 2633, 746, 747, 748, + 749, 750, 751, 399, 2648, 2649, 2654, 2786, 2786, 2642, + 2634, 2637, 2638, 2639, 2640, 2643, 2650, 2651, 2652, 502, + 2644, 2655, 2645, 2646, 2647, 2662, 2663, 2664, 2786, 757, + 757, 2657, 2658, 2648, 2649, 377, 378, 379, 380, 381, + 382, 1095, 759, 2666, 2667, 2650, 2651, 2652, 2786, 397, + 2655, 2660, 2786, 2786, 2662, 2663, 2664, 397, 2668, 2661, + 2669, 818, 2670, 2672, 2672, 2672, 2641, 2641, 2641, 399, + 1095, 759, 2666, 2667, 2641, 2641, 2641, 473, 474, 475, + 476, 477, 478, 2671, 2674, 2676, 2677, 2668, 2678, 2669, + + 818, 2670, 509, 510, 515, 512, 513, 514, 399, 2679, + 2680, 2786, 2786, 746, 747, 748, 749, 750, 751, 2681, + 2682, 2691, 2671, 2674, 2676, 2677, 2692, 2678, 473, 474, + 475, 476, 477, 478, 757, 757, 2686, 2687, 2679, 2680, + 377, 378, 379, 380, 381, 382, 1095, 759, 2681, 2682, + 2691, 397, 397, 2689, 2690, 2692, 2693, 2694, 2695, 2696, + 2699, 2702, 2673, 818, 399, 2642, 2672, 2672, 2672, 2700, + 2700, 2700, 2703, 2642, 2704, 1095, 759, 2786, 2786, 757, + 2786, 2706, 2786, 2786, 2786, 2693, 2694, 2695, 2696, 2699, + 2702, 1095, 818, 399, 757, 397, 2707, 2709, 2786, 2786, + + 2786, 2703, 397, 2704, 2690, 2710, 759, 818, 746, 747, + 748, 749, 750, 751, 399, 2711, 2712, 2713, 2714, 2715, + 1095, 2716, 2719, 2720, 2721, 377, 378, 379, 380, 381, + 382, 2724, 2786, 2729, 2710, 759, 818, 2700, 2700, 2700, + 2786, 2786, 2786, 399, 2711, 2712, 2713, 2714, 2715, 2786, + 2716, 2719, 2720, 2721, 757, 2673, 2723, 2730, 2701, 2786, + 2724, 757, 2729, 2707, 2717, 2786, 1095, 746, 747, 748, + 749, 750, 751, 759, 2731, 377, 378, 379, 380, 381, + 382, 2732, 397, 2733, 2709, 2734, 2730, 2735, 2725, 2725, + 2725, 2736, 2742, 2717, 818, 1095, 2726, 2786, 2745, 757, + + 2746, 2723, 759, 2731, 2747, 2725, 2725, 2725, 2786, 2786, + 2732, 1095, 2733, 2726, 2734, 2748, 2735, 2749, 2751, 2752, + 2736, 2742, 2753, 818, 2754, 2755, 2701, 2745, 2758, 2746, + 2756, 2756, 2756, 2747, 746, 747, 748, 749, 750, 751, + 1095, 2759, 2760, 2761, 2748, 2766, 2749, 2751, 2752, 2767, + 2786, 2753, 2768, 2754, 2755, 2769, 2771, 2758, 2762, 2762, + 2762, 2756, 2756, 2756, 2762, 2762, 2762, 2786, 2772, 2773, + 2759, 2760, 2761, 2786, 2766, 2774, 2775, 2727, 2767, 2728, + 2776, 2768, 2777, 2778, 2769, 2771, 2762, 2762, 2762, 2641, + 2641, 2641, 2779, 2780, 2727, 2781, 2728, 2772, 2773, 2782, + + 2783, 2784, 2764, 2785, 2774, 2775, 2762, 2762, 2762, 2776, + 2786, 2777, 2778, 2786, 2786, 2786, 2786, 2786, 2786, 2757, + 2786, 2779, 2780, 2786, 2781, 2786, 2786, 2786, 2782, 2783, + 2784, 2764, 2785, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2763, 2786, 2786, + 2757, 2786, 2786, 2763, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2763, 2786, 2786, 2642, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2763, 125, 125, 125, 125, + + 125, 125, 125, 125, 125, 125, 125, 125, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 217, 217, 217, 217, 217, 217, + 217, 217, 217, 217, 217, 217, 226, 226, 226, 226, + 226, 226, 226, 226, 226, 226, 226, 226, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 239, 239, 239, 239, 239, 239, 239, 239, + + 239, 239, 239, 239, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 244, 244, 244, 244, + 244, 244, 244, 244, 244, 244, 244, 244, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, + 270, 270, 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 337, 337, 337, 337, 337, 337, + 337, 337, 337, 337, 337, 337, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, 361, 361, + 361, 369, 369, 2786, 369, 369, 369, 369, 369, 369, + + 369, 369, 369, 376, 376, 383, 383, 383, 456, 456, + 2786, 2786, 2786, 2786, 2786, 456, 472, 472, 500, 500, + 2786, 500, 500, 2786, 500, 500, 538, 538, 538, 545, + 545, 552, 552, 552, 564, 564, 2786, 2786, 2786, 2786, + 2786, 564, 580, 2786, 580, 601, 2786, 601, 625, 625, + 625, 625, 625, 625, 2786, 625, 625, 625, 2786, 625, + 631, 631, 631, 631, 631, 631, 631, 631, 631, 631, + 631, 631, 632, 632, 632, 632, 632, 632, 2786, 632, + 632, 632, 2786, 632, 638, 638, 638, 638, 638, 638, + 638, 638, 638, 638, 638, 638, 644, 644, 644, 644, + + 644, 644, 644, 644, 644, 644, 644, 644, 645, 645, + 645, 645, 645, 645, 645, 645, 645, 645, 645, 647, + 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, + 652, 652, 2786, 652, 652, 652, 652, 652, 652, 652, + 652, 652, 659, 659, 684, 684, 2786, 684, 684, 684, + 684, 684, 684, 684, 684, 684, 692, 692, 2786, 692, + 692, 692, 692, 692, 692, 692, 692, 692, 699, 699, + 718, 718, 738, 738, 2786, 738, 738, 738, 738, 738, + 738, 738, 738, 738, 745, 745, 772, 772, 2786, 772, + 772, 772, 772, 772, 772, 772, 772, 772, 779, 779, + + 2786, 779, 779, 779, 779, 779, 779, 779, 779, 779, + 361, 361, 361, 368, 368, 2786, 368, 368, 368, 368, + 368, 368, 368, 368, 368, 369, 369, 2786, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 376, 376, 383, + 383, 383, 456, 456, 2786, 2786, 2786, 2786, 2786, 456, + 472, 472, 500, 500, 2786, 500, 500, 2786, 500, 500, + 538, 538, 538, 545, 545, 552, 552, 552, 564, 564, + 2786, 2786, 2786, 2786, 2786, 564, 580, 2786, 580, 601, + 2786, 601, 625, 625, 625, 625, 625, 625, 2786, 625, + 625, 625, 2786, 625, 1010, 1010, 2786, 1010, 1010, 1010, + + 1010, 1010, 1010, 1010, 1010, 1010, 632, 632, 632, 632, + 632, 632, 2786, 632, 632, 632, 2786, 632, 1015, 1015, + 2786, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, + 1020, 1020, 2786, 1020, 1020, 1020, 1020, 1020, 1020, 1020, + 1020, 1020, 645, 645, 645, 645, 645, 645, 645, 645, + 645, 645, 645, 647, 647, 647, 647, 647, 647, 647, + 647, 647, 647, 647, 651, 651, 2786, 651, 651, 651, + 651, 651, 651, 651, 651, 651, 652, 652, 2786, 652, + 652, 652, 652, 652, 652, 652, 652, 652, 659, 659, + 684, 684, 2786, 684, 684, 684, 684, 684, 684, 684, + + 684, 684, 691, 691, 2786, 691, 691, 691, 691, 691, + 691, 691, 691, 691, 692, 692, 2786, 692, 692, 692, + 692, 692, 692, 692, 692, 692, 699, 699, 718, 718, + 737, 737, 2786, 737, 737, 737, 737, 737, 737, 737, + 737, 737, 738, 738, 2786, 738, 738, 738, 738, 738, + 738, 738, 738, 738, 745, 745, 772, 772, 2786, 772, + 772, 772, 772, 772, 772, 772, 772, 772, 779, 779, + 2786, 779, 779, 779, 779, 779, 779, 779, 779, 779, + 368, 368, 2786, 368, 368, 368, 368, 368, 368, 368, + 368, 368, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + + 1129, 1129, 1129, 1129, 376, 376, 2786, 2786, 376, 472, + 472, 500, 500, 2786, 2786, 500, 545, 545, 580, 2786, + 580, 601, 2786, 601, 1010, 1010, 2786, 1010, 1010, 1010, + 1010, 1010, 1010, 1010, 1010, 1010, 1015, 1015, 2786, 1015, + 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1020, 1020, + 2786, 1020, 1020, 1020, 1020, 1020, 1020, 1020, 1020, 1020, + 651, 651, 2786, 651, 651, 651, 651, 651, 651, 651, + 651, 651, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, + 1283, 1283, 1283, 1283, 659, 659, 1295, 1295, 1295, 1295, + 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 691, 691, + + 2786, 691, 691, 691, 691, 691, 691, 691, 691, 691, + 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, + 1303, 1303, 699, 699, 718, 718, 737, 737, 2786, 737, + 737, 737, 737, 737, 737, 737, 737, 737, 1316, 1316, + 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1316, + 745, 745, 2786, 2786, 745, 1329, 1329, 1329, 1329, 1329, + 1329, 1329, 1329, 1329, 1329, 1329, 1329, 1335, 1335, 1335, + 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 1335, 361, + 361, 361, 369, 369, 2786, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 368, 368, 2786, 368, 368, 368, + + 368, 368, 368, 368, 368, 368, 383, 383, 383, 1129, + 1129, 2786, 1129, 1129, 1129, 1129, 1129, 1129, 1129, 1129, + 1129, 376, 376, 2786, 2786, 376, 456, 456, 2786, 2786, + 2786, 2786, 2786, 456, 472, 472, 500, 500, 2786, 2786, + 500, 500, 538, 538, 538, 552, 552, 552, 545, 545, + 564, 564, 2786, 2786, 2786, 2786, 2786, 564, 580, 2786, + 580, 601, 2786, 601, 1468, 1468, 1468, 1468, 1468, 1468, + 1468, 1468, 1468, 1468, 1468, 1468, 1473, 1473, 1473, 1473, + 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1478, 1478, + 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, 1478, + + 652, 652, 2786, 652, 652, 652, 652, 652, 652, 652, + 652, 652, 651, 651, 2786, 651, 651, 651, 651, 651, + 651, 651, 651, 651, 1283, 1283, 2786, 1283, 1283, 1283, + 1283, 1283, 1283, 1283, 1283, 1283, 659, 659, 1295, 1295, + 2786, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, + 692, 692, 2786, 692, 692, 692, 692, 692, 692, 692, + 692, 692, 691, 691, 2786, 691, 691, 691, 691, 691, + 691, 691, 691, 691, 1303, 1303, 2786, 1303, 1303, 1303, + 1303, 1303, 1303, 1303, 1303, 1303, 699, 699, 718, 718, + 738, 738, 2786, 738, 738, 738, 738, 738, 738, 738, + + 738, 738, 737, 737, 2786, 737, 737, 737, 737, 737, + 737, 737, 737, 737, 1316, 1316, 2786, 1316, 1316, 1316, + 1316, 1316, 1316, 1316, 1316, 1316, 745, 745, 2786, 2786, + 745, 1329, 1329, 2786, 1329, 1329, 1329, 1329, 1329, 1329, + 1329, 1329, 1329, 1335, 1335, 2786, 1335, 1335, 1335, 1335, + 1335, 1335, 1335, 1335, 1335, 1129, 1129, 2786, 1129, 1129, + 1129, 1129, 1129, 1129, 1129, 1129, 1129, 376, 376, 2786, + 2786, 376, 472, 472, 500, 500, 2786, 2786, 500, 545, + 545, 580, 2786, 580, 601, 2786, 601, 1468, 1468, 2786, + 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1473, + + 1473, 2786, 1473, 1473, 1473, 1473, 1473, 1473, 1473, 1473, + 1473, 1478, 1478, 2786, 1478, 1478, 1478, 1478, 1478, 1478, + 1478, 1478, 1478, 1283, 1283, 2786, 1283, 1283, 1283, 1283, + 1283, 1283, 1283, 1283, 1283, 659, 659, 1295, 1295, 2786, + 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1303, + 1303, 2786, 1303, 1303, 1303, 1303, 1303, 1303, 1303, 1303, + 1303, 699, 699, 1644, 1644, 1644, 1644, 1644, 1644, 1644, + 1644, 1644, 1644, 1644, 1644, 1843, 1843, 1843, 1843, 1843, + 1843, 1843, 1843, 1843, 1843, 1843, 1843, 1938, 1938, 1938, + 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1938, 1962, + + 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, + 1962, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, 1970, + 1970, 1970, 1970, 1993, 1993, 1993, 1993, 1993, 1993, 1993, + 1993, 1993, 1993, 1993, 1993, 2027, 2027, 2027, 2027, 2027, + 2027, 2027, 2027, 2027, 2027, 2027, 2027, 2052, 2052, 2052, + 2052, 2052, 2052, 2052, 2052, 2052, 2052, 2052, 2052, 2104, + 2104, 2104, 2104, 2104, 2104, 2104, 2104, 2104, 2104, 2104, + 2104, 59, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786 } ; -static yyconst flex_int16_t yy_chk[17539] = +static yyconst flex_int16_t yy_chk[17967] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -3252,7 +3361,7 @@ static yyconst flex_int16_t yy_chk[17539] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, + 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, @@ -3262,10 +3371,9 @@ static yyconst flex_int16_t yy_chk[17539] = 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 5, 6, 64, 64, 64, 64, 64, 64, 2585, 5, + 3, 3, 3, 3, 3, 3, 3, 3, 5, 6, + 66, 66, 66, 66, 66, 66, 2770, 5, 6, 7, - 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, @@ -3274,7 +3382,8 @@ static yyconst flex_int16_t yy_chk[17539] = 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 9, 9, 9, 9, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -3284,8 +3393,8 @@ static yyconst flex_int16_t yy_chk[17539] = 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 9, 9, 9, 9, 9, 9, 9, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, @@ -3295,19 +3404,19 @@ static yyconst flex_int16_t yy_chk[17539] = 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 13, 13, 13, 27, - 14, 14, 14, 13, 28, 29, 13, 14, 13, 30, - - 14, 31, 14, 15, 15, 15, 32, 16, 16, 16, - 15, 39, 40, 15, 16, 15, 55, 16, 47, 16, - 48, 67, 67, 69, 55, 108, 69, 69, 70, 70, - 108, 27, 2580, 55, 39, 40, 28, 29, 89, 109, - 109, 30, 125, 132, 56, 55, 31, 125, 47, 2569, - 48, 32, 56, 55, 106, 106, 106, 106, 106, 106, - 130, 56, 55, 39, 40, 130, 151, 89, 2561, 137, - 166, 151, 132, 56, 2560, 166, 13, 47, 13, 48, - 14, 56, 14, 89, 89, 89, 89, 89, 89, 183, - 56, 191, 2559, 15, 183, 15, 191, 16, 137, 16, + 11, 13, 13, 13, 27, 14, 14, 14, 13, 28, + 29, 13, 14, 13, 30, 14, 31, 14, 15, 15, + + 15, 32, 16, 16, 16, 15, 39, 40, 15, 16, + 15, 110, 16, 47, 16, 48, 110, 71, 71, 57, + 71, 85, 99, 134, 139, 27, 2765, 57, 39, 40, + 28, 29, 127, 2763, 132, 30, 57, 127, 58, 132, + 31, 2757, 47, 2750, 48, 32, 58, 2741, 57, 153, + 85, 2740, 134, 139, 153, 58, 57, 39, 40, 99, + 99, 99, 99, 99, 99, 57, 2739, 58, 624, 624, + 13, 47, 13, 48, 14, 58, 14, 2731, 85, 85, + 85, 85, 85, 85, 58, 168, 2730, 15, 2728, 15, + 168, 16, 2727, 16, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, @@ -3317,45 +3426,44 @@ static yyconst flex_int16_t yy_chk[17539] = 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 21, 21, 21, 22, 22, - - 22, 2552, 72, 21, 72, 72, 22, 23, 23, 23, - 65, 2551, 23, 2549, 23, 72, 23, 23, 24, 24, - 24, 97, 172, 24, 173, 24, 2548, 24, 24, 25, - 25, 25, 320, 320, 25, 135, 25, 25, 25, 25, - 26, 26, 26, 135, 72, 26, 174, 26, 26, 26, - 26, 172, 2545, 173, 83, 136, 1455, 76, 97, 97, - 97, 97, 97, 97, 135, 200, 323, 323, 2526, 136, - 200, 76, 135, 175, 76, 174, 72, 72, 72, 72, - 72, 72, 2511, 83, 136, 21, 76, 21, 22, 205, - 22, 65, 65, 65, 65, 65, 65, 23, 136, 23, - - 76, 221, 175, 76, 228, 2509, 221, 2507, 24, 228, - 24, 83, 83, 83, 83, 83, 83, 2501, 205, 25, - 2496, 25, 76, 76, 76, 76, 76, 76, 392, 392, - 26, 1455, 26, 37, 37, 37, 37, 37, 37, 37, + 19, 19, 19, 19, 19, 19, 19, 19, 21, 21, + 21, 22, 22, 22, 688, 688, 21, 174, 2724, 22, + + 23, 23, 23, 67, 2722, 23, 2718, 23, 82, 23, + 23, 24, 24, 24, 1703, 1703, 24, 175, 24, 80, + 24, 24, 25, 25, 25, 80, 174, 25, 2708, 25, + 25, 25, 25, 26, 26, 26, 176, 82, 26, 2705, + 26, 26, 26, 26, 87, 177, 175, 136, 80, 78, + 185, 2701, 136, 2698, 80, 185, 82, 82, 82, 82, + 82, 82, 2688, 78, 2685, 176, 78, 80, 80, 80, + 80, 80, 80, 87, 177, 207, 136, 21, 78, 21, + 22, 136, 22, 67, 67, 67, 67, 67, 67, 23, + 2675, 23, 78, 193, 202, 78, 223, 2673, 193, 202, + + 24, 223, 24, 2671, 207, 87, 87, 87, 87, 87, + 87, 25, 2665, 25, 78, 78, 78, 78, 78, 78, + 323, 323, 26, 323, 26, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 41, 41, - 41, 77, 41, 41, 2443, 41, 41, 41, 42, 42, - 42, 41, 42, 42, 77, 42, 42, 42, 75, 134, - 2487, 42, 75, 78, 134, 138, 197, 197, 138, 78, - 77, 85, 149, 149, 149, 149, 149, 149, 2477, 41, - 206, 268, 322, 77, 2476, 322, 322, 75, 134, 42, - 2449, 75, 78, 134, 138, 197, 197, 138, 78, 2448, - 85, 2447, 77, 77, 77, 77, 77, 77, 41, 206, - - 268, 78, 78, 78, 78, 78, 78, 2444, 42, 75, - 75, 75, 75, 75, 75, 2441, 478, 2443, 41, 2430, - 41, 478, 85, 85, 85, 85, 85, 85, 42, 2413, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 41, + 41, 41, 2659, 41, 41, 2585, 41, 41, 41, 42, + 42, 42, 41, 42, 42, 230, 42, 42, 42, 74, + 230, 74, 42, 141, 91, 137, 81, 199, 199, 81, + 94, 74, 81, 137, 138, 141, 208, 94, 94, 41, + 108, 108, 108, 108, 108, 108, 269, 94, 138, 42, + 94, 2656, 141, 91, 137, 81, 199, 199, 81, 94, + 74, 81, 137, 138, 141, 208, 94, 94, 41, 91, + 91, 91, 91, 91, 91, 269, 94, 138, 42, 94, + + 81, 81, 81, 81, 81, 81, 479, 2585, 41, 2655, + 41, 479, 74, 74, 74, 74, 74, 74, 42, 2653, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, @@ -3363,21 +3471,20 @@ static yyconst flex_int16_t yy_chk[17539] = 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 43, 43, 45, 45, 45, 45, + 43, 43, 43, 43, 43, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 49, 49, 49, 49, 49, 49, 49, 49, 49, + + 45, 45, 45, 45, 45, 45, 45, 45, 45, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, @@ -3385,1793 +3492,1842 @@ static yyconst flex_int16_t yy_chk[17539] = 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 51, 51, 51, 480, - 480, 51, 2409, 52, 52, 52, 2408, 278, 52, 51, - 1599, 59, 59, 59, 312, 51, 52, 60, 60, 60, - 344, 496, 52, 139, 51, 62, 496, 53, 53, 53, - 80, 52, 53, 345, 1445, 139, 278, 54, 54, 54, - 53, 51, 54, 312, 622, 622, 53, 353, 52, 344, - 54, 2403, 139, 51, 2400, 53, 54, 687, 687, 80, - 52, 53, 345, 207, 139, 54, 2399, 354, 207, 356, - 51, 54, 245, 245, 245, 357, 353, 52, 80, 80, - - 80, 80, 80, 80, 53, 1599, 51, 81, 2395, 358, - 53, 81, 207, 52, 54, 81, 354, 207, 356, 2394, - 54, 59, 94, 515, 357, 582, 1445, 60, 515, 62, - 62, 62, 62, 62, 62, 2382, 81, 53, 358, 2362, - 81, 559, 612, 612, 81, 612, 559, 54, 63, 63, - 86, 94, 63, 63, 582, 90, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 90, 583, 63, 63, 63, - 63, 63, 81, 81, 81, 81, 81, 81, 580, 86, - 592, 148, 245, 580, 90, 592, 2360, 94, 94, 94, - 94, 94, 94, 584, 90, 583, 2356, 585, 63, 1450, - - 63, 86, 86, 86, 86, 86, 86, 98, 98, 98, - 98, 98, 98, 98, 98, 98, 90, 90, 90, 90, - 90, 90, 584, 246, 246, 246, 585, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 74, 208, 74, 270, 270, 270, 526, - 74, 74, 74, 79, 82, 503, 79, 82, 503, 79, - 526, 208, 586, 587, 82, 148, 148, 148, 148, 148, - 148, 1450, 74, 208, 74, 271, 271, 271, 526, 74, - 74, 74, 79, 82, 503, 79, 82, 503, 79, 526, - 208, 586, 587, 82, 751, 751, 2352, 74, 74, 74, - - 74, 74, 74, 282, 282, 282, 2346, 79, 79, 79, - 79, 79, 79, 246, 84, 2342, 82, 82, 82, 82, - 82, 82, 84, 87, 92, 96, 505, 87, 84, 88, - 518, 92, 92, 96, 505, 87, 270, 88, 504, 87, - 518, 92, 96, 84, 92, 96, 88, 504, 2340, 88, - 2336, 84, 87, 92, 96, 505, 87, 84, 88, 518, - 92, 92, 96, 505, 87, 271, 88, 504, 87, 518, - 92, 96, 2335, 92, 96, 88, 504, 519, 88, 84, - 84, 84, 84, 84, 84, 519, 2331, 87, 87, 87, - 87, 87, 87, 282, 88, 88, 88, 88, 88, 88, - - 91, 506, 93, 91, 93, 517, 519, 93, 506, 91, - 110, 110, 517, 2330, 519, 91, 99, 99, 99, 99, - 99, 99, 99, 99, 99, 818, 818, 1087, 1087, 91, - 506, 93, 91, 93, 517, 2304, 93, 506, 91, 2301, - 588, 517, 111, 589, 91, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 93, 93, 93, 93, 93, 93, - 95, 91, 91, 91, 91, 91, 91, 95, 95, 588, - 596, 111, 589, 2298, 603, 596, 601, 95, 114, 603, - 95, 2297, 110, 110, 110, 110, 110, 110, 2294, 95, - 111, 111, 111, 111, 111, 111, 95, 95, 249, 249, - - 249, 249, 249, 249, 2292, 601, 95, 114, 112, 95, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 112, 113, 114, - 114, 114, 114, 114, 114, 115, 116, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 1122, 1122, 1123, 1123, - 112, 112, 112, 112, 112, 112, 2286, 113, 238, 238, - 238, 150, 238, 238, 115, 116, 283, 283, 283, 1124, - 1124, 238, 2285, 113, 113, 113, 113, 113, 113, 1125, - 1125, 115, 115, 115, 115, 115, 115, 118, 118, 118, - - 118, 118, 118, 118, 118, 118, 2274, 116, 116, 116, - 116, 116, 116, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 127, - 127, 127, 150, 150, 150, 150, 150, 150, 238, 602, - 127, 2271, 127, 127, 1126, 1126, 283, 2270, 394, 394, - 129, 129, 129, 176, 605, 127, 127, 176, 127, 394, - 2263, 129, 2260, 129, 129, 606, 176, 127, 602, 127, - 176, 127, 286, 286, 286, 286, 286, 286, 131, 131, - - 131, 2258, 176, 605, 127, 127, 176, 127, 394, 131, - 154, 131, 131, 2257, 606, 176, 127, 615, 127, 176, - 127, 2248, 615, 2229, 131, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 2227, 396, 396, 127, 127, 127, - 127, 127, 127, 128, 128, 128, 396, 154, 154, 154, - 154, 154, 154, 131, 128, 152, 128, 128, 129, 129, - 129, 129, 129, 129, 1302, 1302, 232, 232, 232, 128, - 128, 232, 128, 232, 2221, 396, 1303, 1303, 2219, 232, - 2216, 128, 153, 128, 152, 128, 131, 131, 131, 131, - 131, 131, 301, 301, 301, 301, 301, 301, 128, 128, - - 527, 128, 318, 318, 318, 318, 318, 318, 527, 520, - 128, 153, 128, 140, 128, 520, 140, 140, 1304, 1304, - 152, 152, 152, 152, 152, 152, 140, 2211, 607, 527, - 140, 128, 128, 128, 128, 128, 128, 527, 520, 1305, - 1305, 2210, 140, 2207, 520, 140, 140, 153, 153, 153, - 153, 153, 153, 619, 2205, 140, 232, 607, 619, 140, - 142, 142, 142, 142, 142, 142, 142, 142, 142, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 146, 146, 146, 146, - - 146, 146, 146, 146, 146, 155, 155, 155, 155, 155, - 155, 155, 155, 155, 156, 156, 156, 156, 156, 156, - 156, 156, 156, 157, 157, 157, 157, 157, 157, 157, - 157, 157, 158, 158, 158, 158, 158, 158, 158, 158, - 158, 159, 159, 159, 159, 159, 159, 159, 159, 159, - 160, 160, 160, 160, 160, 160, 160, 160, 160, 235, - 235, 235, 255, 608, 235, 256, 235, 258, 256, 257, - 1306, 1306, 235, 261, 261, 261, 261, 261, 261, 261, - 261, 261, 262, 262, 262, 262, 262, 262, 262, 262, - 262, 255, 608, 609, 256, 2197, 258, 256, 257, 362, - - 377, 377, 377, 377, 377, 377, 2194, 255, 255, 255, - 255, 255, 255, 1664, 1664, 2401, 256, 256, 256, 256, - 256, 256, 609, 257, 257, 257, 257, 257, 257, 1597, - 1774, 1774, 258, 258, 258, 258, 258, 258, 259, 263, - 263, 263, 263, 263, 263, 263, 263, 263, 2188, 235, - 248, 248, 1782, 1782, 248, 248, 1789, 1789, 248, 248, - 248, 248, 248, 248, 248, 248, 248, 259, 610, 248, - 248, 248, 248, 248, 264, 264, 264, 264, 264, 264, - 264, 264, 264, 362, 362, 362, 362, 362, 362, 259, - 259, 259, 259, 259, 259, 680, 685, 610, 1598, 2401, - - 248, 1597, 248, 265, 265, 265, 265, 265, 265, 265, - 265, 265, 266, 266, 266, 266, 266, 266, 266, 266, - 266, 2187, 291, 292, 680, 685, 314, 314, 314, 248, - 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 285, 285, 1803, 1803, 285, - 285, 291, 292, 285, 285, 285, 285, 285, 285, 285, - 285, 285, 1832, 1832, 285, 285, 285, 285, 285, 2175, - 1598, 1895, 1895, 291, 291, 291, 291, 291, 291, 294, - 294, 294, 294, 294, 294, 294, 294, 294, 292, 292, - 292, 292, 292, 292, 293, 285, 2174, 285, 295, 295, - - 295, 295, 295, 295, 295, 295, 295, 296, 296, 296, - 296, 296, 296, 296, 296, 296, 314, 401, 401, 401, - 401, 401, 401, 293, 285, 285, 285, 285, 285, 285, - 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, - 1903, 1903, 1917, 1917, 2163, 293, 293, 293, 293, 293, - 293, 297, 297, 297, 297, 297, 297, 297, 297, 297, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + + 49, 49, 49, 51, 51, 51, 279, 497, 51, 52, + 52, 52, 497, 2642, 52, 313, 51, 61, 61, 61, + 140, 51, 52, 140, 55, 55, 55, 52, 2632, 55, + 51, 62, 62, 62, 2631, 279, 52, 55, 98, 77, + 343, 64, 55, 77, 313, 516, 98, 51, 344, 140, + 516, 55, 140, 52, 2621, 98, 352, 55, 98, 51, + 353, 56, 56, 56, 355, 52, 56, 98, 77, 343, + 79, 2618, 77, 2612, 56, 98, 51, 344, 356, 56, + 55, 2591, 52, 79, 98, 352, 55, 98, 56, 353, + 357, 2590, 51, 355, 56, 247, 247, 247, 52, 79, + + 77, 77, 77, 77, 77, 77, 61, 356, 504, 583, + 83, 504, 79, 55, 83, 2589, 560, 56, 83, 357, + 62, 560, 2586, 56, 64, 64, 64, 64, 64, 64, + 1471, 79, 79, 79, 79, 79, 79, 504, 583, 83, + 504, 581, 394, 83, 394, 96, 581, 83, 1828, 1828, + 56, 65, 65, 88, 394, 65, 65, 584, 92, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 92, 65, + 65, 65, 65, 65, 96, 83, 83, 83, 83, 83, + 83, 2583, 88, 394, 247, 1481, 584, 92, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 92, 585, 2575, + + 65, 1471, 65, 2530, 88, 88, 88, 88, 88, 88, + 96, 96, 96, 96, 96, 96, 395, 2572, 397, 92, + 92, 92, 92, 92, 92, 1476, 395, 585, 397, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 76, 84, 76, 586, 84, + 86, 527, 76, 76, 76, 395, 84, 397, 86, 1481, + 2726, 150, 527, 588, 86, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 76, 84, 76, 586, 84, 86, + 527, 76, 76, 76, 2564, 84, 2530, 86, 248, 248, + 248, 527, 588, 86, 614, 614, 1476, 614, 2563, 76, + + 76, 76, 76, 76, 76, 210, 90, 1635, 84, 84, + 84, 84, 84, 84, 90, 86, 86, 86, 86, 86, + 86, 89, 210, 90, 507, 89, 90, 95, 506, 95, + 520, 507, 95, 89, 210, 90, 506, 89, 520, 271, + 271, 271, 2726, 90, 150, 150, 150, 150, 150, 150, + 89, 210, 90, 507, 89, 90, 95, 506, 95, 520, + 507, 95, 89, 593, 597, 506, 89, 520, 593, 597, + 589, 90, 90, 90, 90, 90, 90, 248, 1635, 95, + 95, 95, 95, 95, 95, 89, 89, 89, 89, 89, + 89, 93, 505, 209, 93, 97, 2542, 113, 209, 589, + + 93, 505, 97, 97, 518, 523, 93, 521, 590, 602, + 209, 518, 97, 521, 523, 97, 272, 272, 272, 2538, + 93, 505, 209, 93, 97, 112, 113, 209, 271, 93, + 505, 97, 97, 518, 523, 93, 521, 590, 602, 209, + 518, 97, 521, 523, 97, 113, 113, 113, 113, 113, + 113, 1636, 93, 93, 93, 93, 93, 93, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 114, 115, 112, 112, 112, 112, + + 112, 112, 116, 603, 2537, 272, 117, 606, 118, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 1836, 1836, + 1843, 1843, 1636, 114, 115, 151, 151, 151, 151, 151, + 151, 116, 603, 604, 617, 117, 606, 118, 604, 617, + 115, 115, 115, 115, 115, 115, 114, 114, 114, 114, + 114, 114, 117, 117, 117, 117, 117, 117, 283, 283, + 283, 1861, 1861, 116, 116, 116, 116, 116, 116, 118, + 118, 118, 118, 118, 118, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 122, 122, 122, 122, 122, 122, 122, + + 122, 122, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 129, 129, 129, 621, 607, 156, 2532, 608, 621, 609, + 818, 129, 818, 129, 129, 818, 152, 1893, 1893, 1962, + 1962, 131, 131, 131, 522, 129, 129, 283, 129, 610, + 2529, 522, 131, 607, 131, 131, 608, 129, 609, 129, + 587, 129, 156, 156, 156, 156, 156, 156, 133, 133, + 133, 1970, 1970, 522, 129, 129, 587, 129, 610, 133, + 522, 133, 133, 1985, 1985, 2528, 129, 1637, 129, 587, + 129, 1993, 1993, 133, 143, 143, 143, 143, 143, 143, + + 143, 143, 143, 2027, 2027, 587, 154, 129, 129, 129, + 129, 129, 129, 130, 130, 130, 152, 152, 152, 152, + 152, 152, 133, 2523, 130, 2522, 130, 130, 131, 131, + 131, 131, 131, 131, 611, 154, 612, 257, 130, 130, + 257, 130, 251, 251, 251, 251, 251, 251, 667, 667, + 130, 155, 130, 2517, 130, 133, 133, 133, 133, 133, + 133, 1637, 2514, 611, 2502, 612, 257, 130, 130, 257, + 130, 154, 154, 154, 154, 154, 154, 667, 667, 130, + 155, 130, 142, 130, 519, 142, 142, 2501, 257, 257, + 257, 257, 257, 257, 519, 142, 681, 686, 734, 142, + + 130, 130, 130, 130, 130, 130, 2477, 819, 2475, 819, + 2471, 142, 819, 519, 142, 142, 155, 155, 155, 155, + 155, 155, 2467, 519, 142, 681, 686, 734, 142, 144, + 144, 144, 144, 144, 144, 144, 144, 144, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 147, 147, 147, 147, + 147, 147, 147, 147, 147, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 159, 159, 159, 159, 159, 159, 159, 159, + + 159, 160, 160, 160, 160, 160, 160, 160, 160, 160, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 162, + 162, 162, 162, 162, 162, 162, 162, 162, 178, 234, + 234, 234, 178, 756, 234, 2461, 234, 2104, 2104, 258, + 259, 178, 234, 756, 774, 178, 237, 237, 237, 1844, + 821, 237, 821, 237, 1844, 821, 775, 178, 781, 237, + 260, 178, 240, 240, 240, 2459, 240, 240, 258, 259, + 178, 2455, 756, 774, 178, 240, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 775, 1963, 781, 782, 260, + 2453, 1963, 2447, 258, 258, 258, 258, 258, 258, 287, + + 287, 287, 287, 287, 287, 259, 259, 259, 259, 259, + 259, 260, 260, 260, 260, 260, 260, 782, 234, 263, + 263, 263, 263, 263, 263, 263, 263, 263, 284, 284, + 284, 2444, 2431, 2415, 2409, 237, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 302, 302, 302, 302, 302, + 302, 240, 250, 250, 1971, 2407, 250, 250, 2404, 1971, + 250, 250, 250, 250, 250, 250, 250, 250, 250, 292, + 250, 250, 250, 250, 250, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 266, 266, 266, 266, 266, 266, + 266, 266, 266, 315, 315, 315, 2401, 784, 292, 785, + + 786, 250, 2398, 250, 267, 267, 267, 267, 267, 267, + 267, 267, 267, 1095, 2397, 1095, 2394, 284, 1095, 293, + 292, 292, 292, 292, 292, 292, 784, 2392, 785, 786, + 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, + 250, 250, 250, 250, 250, 250, 286, 286, 293, 294, + 286, 286, 977, 757, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 757, 286, 286, 286, 286, 286, 295, + 295, 295, 295, 295, 295, 295, 295, 295, 294, 2386, + 2385, 977, 315, 2383, 293, 293, 293, 293, 293, 293, + 2371, 1096, 757, 1096, 1994, 286, 1096, 286, 2368, 1994, + + 294, 294, 294, 294, 294, 294, 296, 296, 296, 296, + 296, 296, 296, 296, 296, 297, 297, 297, 297, 297, + 297, 297, 297, 297, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 298, 298, 298, 298, 298, 298, 298, 298, 298, 299, - 299, 299, 299, 299, 299, 299, 299, 299, 304, 305, - 305, 305, 305, 305, 305, 305, 305, 305, 306, 306, + 299, 299, 299, 299, 299, 299, 299, 299, 300, 300, + 300, 300, 300, 300, 300, 300, 300, 305, 306, 306, 306, 306, 306, 306, 306, 306, 306, 307, 307, 307, - - 307, 307, 307, 307, 307, 307, 2161, 304, 308, 308, - 308, 308, 308, 308, 308, 308, 308, 309, 309, 309, - 309, 309, 309, 309, 309, 309, 304, 304, 304, 304, - 304, 304, 310, 310, 310, 310, 310, 310, 310, 310, - 310, 315, 315, 315, 324, 328, 324, 324, 329, 330, - 454, 454, 454, 454, 454, 454, 2144, 324, 332, 332, - 332, 332, 332, 332, 332, 332, 332, 733, 773, 2135, - 1790, 399, 774, 2133, 328, 1790, 2132, 329, 330, 399, - 471, 471, 471, 471, 471, 471, 324, 339, 339, 339, - 328, 328, 328, 328, 328, 328, 733, 773, 753, 753, - - 399, 774, 329, 329, 329, 329, 329, 329, 399, 753, - 330, 330, 330, 330, 330, 330, 1924, 1924, 324, 324, - 324, 324, 324, 324, 2124, 399, 399, 399, 399, 399, - 399, 315, 317, 317, 1896, 2122, 317, 317, 753, 1896, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 1954, - 1954, 317, 317, 317, 317, 317, 333, 333, 333, 333, - 333, 333, 333, 333, 333, 334, 334, 334, 334, 334, - 334, 334, 334, 334, 340, 340, 340, 339, 348, 348, - 348, 780, 317, 2117, 317, 335, 335, 335, 335, 335, - 335, 335, 335, 335, 336, 336, 336, 336, 336, 336, - - 336, 336, 336, 349, 349, 349, 359, 359, 359, 2112, - 780, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 337, 337, 337, - 337, 337, 337, 337, 337, 337, 363, 363, 363, 363, - 363, 363, 363, 363, 363, 364, 364, 364, 364, 364, - 364, 364, 364, 364, 365, 365, 365, 365, 365, 365, - 365, 365, 365, 781, 340, 2107, 783, 384, 348, 366, - 366, 366, 366, 366, 366, 366, 366, 366, 367, 367, - 367, 367, 367, 367, 367, 367, 367, 393, 393, 393, - 2024, 2024, 781, 349, 537, 783, 359, 368, 368, 368, - - 368, 368, 368, 368, 368, 368, 370, 370, 1904, 2105, - 370, 370, 2102, 1904, 370, 370, 370, 370, 370, 370, - 370, 370, 370, 2100, 2096, 370, 370, 370, 370, 370, - 371, 371, 371, 371, 371, 371, 371, 371, 371, 372, - 372, 372, 372, 372, 372, 372, 372, 372, 384, 384, - 384, 384, 384, 384, 2079, 784, 370, 2064, 370, 373, - 373, 373, 373, 373, 373, 373, 373, 373, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 393, 537, 537, - 537, 537, 537, 537, 784, 370, 370, 370, 370, 370, - 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, - - 370, 375, 375, 375, 375, 375, 375, 375, 375, 375, - 376, 376, 376, 376, 376, 376, 376, 376, 376, 378, - 378, 378, 378, 378, 378, 378, 378, 378, 379, 379, - 379, 379, 379, 379, 379, 379, 379, 380, 380, 380, - 380, 380, 380, 380, 380, 380, 381, 381, 381, 381, - 381, 381, 381, 381, 381, 382, 382, 382, 382, 382, - 382, 382, 382, 382, 383, 383, 383, 383, 383, 383, - 383, 383, 383, 386, 386, 386, 386, 386, 386, 386, - 386, 386, 387, 387, 387, 387, 387, 387, 387, 387, - 387, 388, 388, 388, 388, 388, 388, 388, 388, 388, - - 389, 389, 389, 389, 389, 389, 389, 389, 389, 390, - 390, 390, 390, 390, 390, 390, 390, 390, 391, 391, - 391, 391, 391, 391, 391, 391, 391, 397, 400, 397, - 397, 398, 402, 398, 405, 455, 398, 398, 785, 968, - 397, 457, 457, 457, 457, 457, 457, 457, 457, 457, - 2052, 2042, 533, 533, 2033, 403, 533, 400, 533, 533, - 533, 402, 2023, 405, 624, 624, 624, 785, 968, 397, - 404, 624, 455, 455, 455, 455, 455, 455, 402, 402, - 402, 402, 402, 402, 403, 406, 405, 405, 405, 405, - 405, 405, 2021, 400, 400, 400, 400, 400, 400, 404, - - 2019, 397, 397, 397, 397, 397, 397, 408, 398, 398, - 398, 398, 398, 398, 406, 2013, 521, 403, 403, 403, - 403, 403, 403, 521, 969, 2006, 970, 407, 407, 404, - 404, 404, 404, 404, 404, 407, 408, 410, 972, 406, - 406, 406, 406, 406, 406, 521, 973, 409, 411, 409, - 1971, 1953, 521, 969, 624, 970, 407, 407, 409, 1923, - 1916, 1913, 2547, 1902, 407, 409, 410, 972, 408, 408, - 408, 408, 408, 408, 413, 973, 409, 411, 409, 453, - 407, 407, 407, 407, 407, 407, 1894, 409, 410, 410, - 410, 410, 410, 410, 409, 412, 411, 411, 411, 411, - - 411, 411, 414, 413, 1880, 414, 412, 975, 453, 418, - 1857, 1847, 409, 409, 409, 409, 409, 409, 415, 416, - 1831, 1807, 1805, 1802, 412, 453, 453, 453, 453, 453, - 453, 414, 1925, 416, 414, 412, 975, 1925, 418, 413, - 413, 413, 413, 413, 413, 2547, 417, 415, 416, 419, - 414, 414, 414, 414, 414, 414, 412, 412, 412, 412, - 412, 412, 416, 418, 418, 418, 418, 418, 418, 415, - 415, 415, 415, 415, 415, 417, 420, 421, 419, 1795, - 1788, 1781, 1773, 1768, 416, 416, 416, 416, 416, 416, - 417, 417, 417, 417, 417, 417, 576, 576, 424, 423, - - 576, 1757, 576, 576, 576, 420, 421, 422, 419, 419, - 419, 419, 419, 419, 489, 489, 489, 489, 489, 489, - 489, 489, 422, 422, 1745, 1725, 1708, 424, 423, 421, - 421, 421, 421, 421, 421, 425, 422, 425, 426, 420, - 420, 420, 420, 420, 420, 424, 424, 424, 424, 424, - 424, 422, 422, 423, 423, 423, 423, 423, 423, 427, - 428, 1703, 1678, 1670, 425, 1663, 425, 426, 441, 422, - 422, 422, 422, 422, 422, 429, 981, 430, 1660, 1656, - 1646, 426, 426, 426, 426, 426, 426, 432, 427, 428, - 425, 425, 425, 425, 425, 425, 1635, 441, 544, 544, - - 544, 544, 544, 544, 429, 981, 430, 427, 427, 427, - 427, 427, 427, 1955, 431, 982, 432, 435, 1955, 441, - 441, 441, 441, 441, 441, 428, 428, 428, 428, 428, - 428, 429, 429, 429, 429, 429, 429, 430, 430, 430, - 430, 430, 430, 431, 982, 433, 435, 434, 525, 432, - 432, 432, 432, 432, 432, 437, 523, 436, 525, 437, - 983, 815, 523, 815, 1607, 1556, 815, 815, 431, 431, - 431, 431, 431, 431, 433, 1544, 434, 525, 435, 435, - 435, 435, 435, 435, 437, 523, 436, 525, 437, 983, - 1543, 523, 1541, 433, 433, 433, 433, 433, 433, 434, - - 434, 434, 434, 434, 434, 436, 436, 436, 436, 436, - 436, 665, 984, 1525, 1518, 522, 437, 437, 437, 437, - 437, 437, 438, 439, 522, 1513, 524, 438, 757, 665, - 665, 985, 439, 524, 439, 438, 442, 438, 986, 440, - 665, 984, 443, 438, 522, 987, 757, 440, 1485, 1483, - 1477, 438, 439, 522, 444, 524, 438, 757, 665, 665, - 985, 439, 524, 439, 438, 442, 438, 986, 440, 1473, - 1471, 443, 438, 1465, 987, 757, 440, 439, 439, 439, - 439, 439, 439, 444, 445, 1457, 452, 438, 438, 438, - 438, 438, 438, 440, 440, 440, 440, 440, 440, 447, - - 1456, 442, 442, 442, 442, 442, 442, 443, 443, 443, - 443, 443, 443, 445, 448, 452, 988, 448, 444, 444, - 444, 444, 444, 444, 446, 637, 637, 637, 447, 637, - 1454, 1452, 445, 445, 445, 445, 445, 445, 449, 1451, - 1449, 1447, 449, 448, 446, 988, 448, 452, 452, 452, - 452, 452, 452, 446, 482, 1026, 447, 447, 447, 447, - 447, 447, 493, 493, 493, 493, 493, 449, 493, 493, - 493, 449, 1446, 446, 754, 754, 448, 448, 448, 448, - 448, 448, 450, 482, 1026, 754, 1444, 1027, 450, 446, - 446, 446, 446, 446, 446, 451, 1442, 1440, 1436, 449, - - 449, 449, 449, 449, 449, 482, 482, 482, 482, 482, - 482, 450, 1434, 1028, 754, 637, 1027, 450, 657, 657, - 657, 657, 657, 657, 451, 458, 458, 458, 458, 458, - 458, 458, 458, 458, 1431, 1429, 450, 450, 450, 450, - 450, 450, 1028, 451, 451, 451, 451, 451, 451, 459, + 307, 307, 307, 307, 307, 307, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 2363, 305, 309, 309, 309, + + 309, 309, 309, 309, 309, 309, 310, 310, 310, 310, + 310, 310, 310, 310, 310, 305, 305, 305, 305, 305, + 305, 311, 311, 311, 311, 311, 311, 311, 311, 311, + 316, 316, 316, 319, 319, 319, 319, 319, 319, 325, + 328, 325, 329, 2362, 2352, 2350, 2333, 2328, 338, 338, + 338, 325, 331, 331, 331, 331, 331, 331, 331, 331, + 331, 376, 376, 376, 376, 376, 376, 2326, 2323, 328, + 2321, 329, 339, 339, 339, 347, 347, 347, 2316, 2314, + 325, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 2311, 2306, 2305, 978, 328, 328, 328, 328, 328, 328, + + 2301, 2299, 2290, 329, 329, 329, 329, 329, 329, 2287, + 2282, 2279, 325, 325, 325, 325, 325, 325, 2028, 316, + 318, 318, 978, 2028, 318, 318, 2273, 2272, 318, 318, + 318, 318, 318, 318, 318, 318, 318, 338, 318, 318, + 318, 318, 318, 333, 333, 333, 333, 333, 333, 333, + 333, 333, 334, 334, 334, 334, 334, 334, 334, 334, + 334, 339, 361, 2259, 347, 348, 348, 348, 979, 318, + 2258, 318, 335, 335, 335, 335, 335, 335, 335, 335, + 335, 336, 336, 336, 336, 336, 336, 336, 336, 336, + 358, 358, 358, 383, 2256, 2237, 2226, 979, 318, 318, + + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 318, 362, 362, 362, 362, 362, 362, + 362, 362, 362, 363, 363, 363, 363, 363, 363, 363, + 363, 363, 364, 364, 364, 364, 364, 364, 364, 364, + 364, 392, 392, 392, 2224, 361, 361, 361, 361, 361, + 361, 2223, 2215, 2213, 348, 365, 365, 365, 365, 365, + 365, 365, 365, 365, 366, 366, 366, 366, 366, 366, + 366, 366, 366, 383, 383, 383, 383, 383, 383, 358, + 367, 367, 367, 367, 367, 367, 367, 367, 367, 369, + 369, 2105, 2207, 369, 369, 2201, 2105, 369, 369, 369, + + 369, 369, 369, 369, 369, 369, 2196, 369, 369, 369, + 369, 369, 370, 370, 370, 370, 370, 370, 370, 370, + 370, 371, 371, 371, 371, 371, 371, 371, 371, 371, + 392, 402, 402, 402, 402, 402, 402, 981, 369, 2194, + 369, 372, 372, 372, 372, 372, 372, 372, 372, 372, + 373, 373, 373, 373, 373, 373, 373, 373, 373, 455, + 455, 455, 455, 455, 455, 2191, 981, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, 369, 369, 369, + 369, 369, 369, 374, 374, 374, 374, 374, 374, 374, + 374, 374, 375, 375, 375, 375, 375, 375, 375, 375, + + 375, 377, 377, 377, 377, 377, 377, 377, 377, 377, + 378, 378, 378, 378, 378, 378, 378, 378, 378, 379, + 379, 379, 379, 379, 379, 379, 379, 379, 380, 380, + 380, 380, 380, 380, 380, 380, 380, 381, 381, 381, + 381, 381, 381, 381, 381, 381, 382, 382, 382, 382, + 382, 382, 382, 382, 382, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 386, 386, 386, 386, 386, 386, + 386, 386, 386, 387, 387, 387, 387, 387, 387, 387, + 387, 387, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 389, 389, 389, 389, 389, 389, 389, 389, 389, + + 390, 390, 390, 390, 390, 390, 390, 390, 390, 398, + 400, 398, 399, 755, 399, 755, 2189, 399, 400, 2184, + 524, 398, 2181, 982, 403, 755, 524, 983, 985, 401, + 458, 458, 458, 458, 458, 458, 458, 458, 458, 400, + 472, 472, 472, 472, 472, 472, 2168, 400, 404, 524, + 398, 414, 982, 403, 755, 524, 983, 985, 401, 2150, + 2149, 649, 649, 649, 400, 400, 400, 400, 400, 400, + 403, 403, 403, 403, 403, 403, 405, 404, 418, 445, + 414, 2135, 398, 398, 398, 398, 398, 398, 399, 399, + 399, 399, 399, 399, 401, 401, 401, 401, 401, 401, + + 406, 991, 992, 409, 407, 405, 2123, 418, 445, 2114, + 404, 404, 404, 404, 404, 404, 414, 414, 414, 414, + 414, 414, 418, 418, 418, 418, 418, 418, 2103, 406, + 991, 992, 409, 407, 2100, 405, 405, 405, 405, 405, + 405, 408, 408, 445, 445, 445, 445, 445, 445, 408, + 649, 993, 406, 406, 406, 406, 406, 406, 407, 407, + 407, 407, 407, 407, 409, 409, 409, 409, 409, 409, + 408, 408, 410, 411, 410, 2098, 528, 2092, 408, 994, + 993, 2085, 412, 410, 528, 494, 494, 494, 494, 494, + 410, 494, 494, 494, 408, 408, 408, 408, 408, 408, + + 2075, 410, 411, 410, 817, 528, 817, 413, 994, 2072, + 820, 412, 410, 528, 415, 995, 817, 415, 413, 410, + 820, 996, 997, 416, 411, 411, 411, 411, 411, 411, + 412, 412, 412, 412, 412, 412, 413, 410, 410, 410, + 410, 410, 410, 415, 995, 817, 415, 413, 2048, 820, + 996, 997, 416, 2042, 2031, 998, 419, 420, 456, 2026, + 999, 421, 415, 415, 415, 415, 415, 415, 413, 413, + 413, 413, 413, 413, 416, 416, 416, 416, 416, 416, + 417, 626, 626, 626, 998, 419, 420, 1992, 626, 999, + 421, 1984, 1980, 538, 417, 456, 456, 456, 456, 456, + + 456, 422, 1037, 1038, 1048, 424, 1051, 1079, 1969, 417, + 419, 419, 419, 419, 419, 419, 420, 420, 420, 420, + 420, 420, 423, 417, 421, 421, 421, 421, 421, 421, + 422, 1037, 1038, 1048, 424, 1051, 1079, 423, 423, 1110, + 429, 1961, 426, 425, 426, 417, 417, 417, 417, 417, + 417, 423, 1953, 422, 422, 422, 422, 422, 422, 424, + 424, 424, 424, 424, 424, 1950, 423, 423, 1110, 429, + 626, 426, 425, 426, 427, 428, 538, 538, 538, 538, + 538, 538, 430, 433, 423, 423, 423, 423, 423, 423, + 425, 425, 425, 425, 425, 425, 482, 426, 426, 426, + + 426, 426, 426, 427, 428, 429, 429, 429, 429, 429, + 429, 430, 433, 1944, 1922, 431, 1911, 427, 427, 427, + 427, 427, 427, 428, 428, 428, 428, 428, 428, 432, + 545, 545, 545, 545, 545, 545, 1111, 435, 430, 430, + 430, 430, 430, 430, 431, 433, 433, 433, 433, 433, + 433, 1897, 434, 436, 1892, 534, 534, 1865, 432, 534, + 1863, 534, 534, 534, 1860, 1111, 435, 482, 482, 482, + 482, 482, 482, 1854, 1851, 431, 431, 431, 431, 431, + 431, 434, 436, 432, 432, 432, 432, 432, 432, 435, + 435, 435, 435, 435, 435, 437, 443, 526, 1097, 442, + + 434, 434, 434, 434, 434, 434, 438, 526, 1097, 440, + 438, 440, 1114, 1115, 436, 436, 436, 436, 436, 436, + 440, 666, 666, 666, 437, 443, 526, 440, 442, 440, + 444, 440, 1849, 1842, 1835, 438, 526, 1097, 440, 438, + 440, 1114, 1115, 437, 437, 437, 437, 437, 437, 440, + 442, 442, 442, 442, 442, 442, 440, 1827, 440, 444, + 440, 443, 443, 443, 443, 443, 443, 438, 438, 438, + 438, 438, 438, 439, 441, 439, 441, 446, 439, 639, + 639, 639, 448, 639, 439, 441, 439, 1822, 439, 447, + 1818, 439, 441, 441, 439, 444, 444, 444, 444, 444, + + 444, 1814, 439, 441, 439, 441, 446, 439, 1808, 447, + 666, 448, 1796, 439, 441, 439, 449, 439, 447, 449, + 439, 441, 441, 439, 1116, 446, 446, 446, 446, 446, + 446, 450, 1098, 1117, 1098, 450, 452, 1098, 447, 448, + 448, 448, 448, 448, 448, 449, 1776, 453, 449, 1094, + 1761, 1094, 1756, 1116, 447, 447, 447, 447, 447, 447, + 450, 1094, 1117, 1751, 450, 452, 1723, 1717, 639, 451, + 454, 1118, 1256, 1257, 1258, 451, 453, 1259, 449, 449, + 449, 449, 449, 449, 452, 452, 452, 452, 452, 452, + 1094, 1712, 450, 450, 450, 450, 450, 450, 451, 454, + + 1118, 1256, 1257, 1258, 451, 1709, 1259, 1702, 453, 453, + 453, 453, 453, 453, 1699, 1695, 454, 454, 454, 454, + 454, 454, 1685, 451, 451, 451, 451, 451, 451, 459, 459, 459, 459, 459, 459, 459, 459, 459, 460, 460, 460, 460, 460, 460, 460, 460, 460, 461, 461, 461, 461, 461, 461, 461, 461, 461, 462, 462, 462, 462, 462, 462, 462, 462, 462, 463, 463, 463, 463, 463, 463, 463, 463, 463, 464, 464, 464, 464, 464, 464, - 464, 464, 464, 465, 465, 465, 465, 465, 465, 465, 465, 465, 466, 466, 466, 466, 466, 466, 466, 466, + 466, 467, 467, 467, 467, 467, 467, 467, 467, 467, 468, 468, 468, 468, 468, 468, 468, 468, 468, 469, 469, 469, 469, 469, 469, 469, 469, 469, 470, 470, - 470, 470, 470, 470, 470, 470, 470, 472, 472, 472, - 472, 472, 472, 472, 472, 472, 473, 473, 473, 473, + 470, 470, 470, 470, 470, 470, 470, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 473, 473, 473, 473, 473, 473, 473, 473, 473, 474, 474, 474, 474, 474, 474, 474, 474, 474, 475, 475, 475, 475, 475, 475, 475, 475, 475, 476, 476, 476, 476, 476, 476, 476, - 476, 476, 477, 477, 477, 477, 477, 477, 477, 477, - 477, 481, 481, 483, 486, 488, 488, 488, 488, 488, - 488, 488, 488, 488, 1039, 1042, 1070, 1089, 484, 1090, - 485, 1100, 563, 698, 698, 698, 698, 698, 698, 487, - 1389, 1327, 483, 486, 490, 490, 490, 490, 490, 490, - 490, 490, 490, 1039, 1042, 1070, 1089, 484, 1090, 485, - 1100, 1321, 486, 486, 486, 486, 486, 486, 487, 563, - 563, 563, 563, 563, 563, 483, 483, 483, 483, 483, - 483, 1320, 1315, 481, 481, 481, 481, 481, 481, 484, - 484, 484, 484, 484, 484, 485, 485, 485, 485, 485, - - 485, 1314, 1301, 1300, 487, 487, 487, 487, 487, 487, - 491, 491, 491, 491, 491, 491, 491, 491, 491, 492, - 492, 492, 492, 492, 492, 492, 492, 492, 494, 494, - 494, 494, 494, 494, 494, 494, 494, 495, 495, 495, - 495, 495, 495, 495, 495, 495, 498, 498, 498, 1289, - 816, 816, 499, 499, 499, 1288, 1101, 498, 1281, 498, - 498, 816, 1280, 499, 1270, 499, 499, 500, 500, 500, - 1104, 2025, 498, 498, 1267, 498, 2025, 1266, 500, 1105, - 500, 500, 1106, 507, 498, 1101, 498, 507, 498, 1107, - 816, 507, 502, 502, 502, 1108, 507, 1260, 561, 1104, - - 507, 498, 498, 502, 498, 502, 502, 1258, 1105, 1256, - 1251, 1106, 507, 498, 1121, 498, 507, 498, 1107, 1120, - 507, 1103, 1099, 502, 1108, 507, 817, 561, 817, 507, - 1083, 817, 817, 1071, 498, 498, 498, 498, 498, 498, - 499, 499, 499, 499, 499, 499, 561, 561, 561, 561, - 561, 561, 502, 1057, 1045, 500, 500, 500, 500, 500, - 500, 508, 508, 508, 508, 508, 508, 508, 508, 508, - 509, 509, 509, 509, 509, 509, 509, 509, 509, 1041, - 502, 502, 502, 502, 502, 502, 510, 510, 510, 510, - 510, 510, 510, 510, 510, 511, 511, 511, 511, 511, - - 511, 511, 511, 511, 512, 512, 512, 512, 512, 512, - 512, 512, 512, 513, 513, 513, 513, 513, 513, 513, - 513, 513, 514, 514, 514, 514, 514, 514, 514, 514, - 514, 528, 528, 528, 528, 528, 528, 528, 528, 528, - 529, 529, 529, 529, 529, 529, 529, 529, 529, 530, + 477, 478, 478, 478, 478, 478, 478, 478, 478, 478, + + 483, 484, 659, 659, 659, 659, 659, 659, 485, 487, + 486, 1674, 1670, 1665, 1260, 1643, 488, 489, 489, 489, + 489, 489, 489, 489, 489, 489, 1633, 577, 577, 483, + 484, 577, 1624, 577, 577, 577, 1602, 485, 487, 486, + 678, 678, 678, 1260, 678, 488, 678, 678, 678, 1589, + 1575, 483, 483, 483, 483, 483, 483, 487, 487, 487, + 487, 487, 487, 484, 484, 484, 484, 484, 484, 485, + 485, 485, 485, 485, 485, 486, 486, 486, 486, 486, + 486, 488, 488, 488, 488, 488, 488, 490, 490, 490, + 490, 490, 490, 490, 490, 491, 491, 491, 491, 491, + + 491, 491, 491, 491, 492, 492, 492, 492, 492, 492, + 492, 492, 492, 493, 493, 493, 493, 493, 493, 493, + 493, 493, 495, 495, 495, 495, 495, 495, 495, 495, + 495, 496, 496, 496, 496, 496, 496, 496, 496, 496, + 499, 499, 499, 1574, 1572, 1552, 500, 500, 500, 1261, + 1545, 499, 1540, 499, 499, 1510, 1509, 500, 1507, 500, + 500, 501, 501, 501, 1502, 499, 499, 1501, 499, 1497, + 1495, 1133, 501, 1133, 501, 501, 508, 499, 1261, 499, + 508, 499, 1262, 1133, 508, 503, 503, 503, 1263, 508, + 1264, 1265, 1267, 508, 499, 499, 503, 499, 503, 503, + + 1489, 1483, 1482, 1480, 1478, 508, 499, 1477, 499, 508, + 499, 1262, 1133, 508, 1268, 503, 1270, 1263, 508, 1264, + 1265, 1267, 508, 1475, 1473, 1472, 1470, 499, 499, 499, + 499, 499, 499, 500, 500, 500, 500, 500, 500, 633, + 633, 633, 1468, 1268, 503, 1270, 633, 1466, 501, 501, + 501, 501, 501, 501, 509, 509, 509, 509, 509, 509, + 509, 509, 509, 510, 510, 510, 510, 510, 510, 510, + 510, 510, 503, 503, 503, 503, 503, 503, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 512, 512, 512, + 512, 512, 512, 512, 512, 512, 513, 513, 513, 513, + + 513, 513, 513, 513, 513, 514, 514, 514, 514, 514, + 514, 514, 514, 514, 515, 515, 515, 515, 515, 515, + 515, 515, 515, 525, 564, 1461, 1459, 1455, 633, 1453, + 525, 573, 573, 573, 573, 573, 573, 573, 573, 525, + 529, 529, 529, 529, 529, 529, 529, 529, 529, 1431, + 1410, 1345, 525, 699, 699, 699, 699, 699, 699, 525, + 1344, 564, 564, 564, 564, 564, 564, 1338, 525, 530, 530, 530, 530, 530, 530, 530, 530, 530, 531, 531, 531, 531, 531, 531, 531, 531, 531, 532, 532, 532, - 532, 532, 532, 532, 532, 532, 534, 534, 534, 534, - 534, 534, 534, 534, 534, 535, 535, 535, 535, 535, - 535, 535, 535, 535, 538, 538, 538, 538, 538, 538, + 532, 532, 532, 532, 532, 532, 533, 533, 533, 533, - 538, 538, 538, 539, 539, 539, 539, 539, 539, 539, + 533, 533, 533, 533, 533, 535, 535, 535, 535, 535, + 535, 535, 535, 535, 536, 536, 536, 536, 536, 536, + 536, 536, 536, 539, 539, 539, 539, 539, 539, 539, 539, 539, 540, 540, 540, 540, 540, 540, 540, 540, 540, 541, 541, 541, 541, 541, 541, 541, 541, 541, 542, 542, 542, 542, 542, 542, 542, 542, 542, 543, - 543, 543, 543, 543, 543, 543, 543, 543, 545, 545, - 545, 545, 545, 545, 545, 545, 545, 546, 546, 546, + 543, 543, 543, 543, 543, 543, 543, 543, 544, 544, + 544, 544, 544, 544, 544, 544, 544, 546, 546, 546, 546, 546, 546, 546, 546, 546, 547, 547, 547, 547, 547, 547, 547, 547, 547, 548, 548, 548, 548, 548, + 548, 548, 548, 548, 549, 549, 549, 549, 549, 549, 549, 549, 549, 550, 550, 550, 550, 550, 550, 550, - - 550, 550, 551, 553, 553, 553, 553, 553, 553, 553, - 553, 553, 554, 554, 554, 554, 554, 554, 554, 554, + 550, 550, 551, 551, 551, 551, 551, 551, 551, 551, + 551, 552, 554, 554, 554, 554, 554, 554, 554, 554, 554, 555, 555, 555, 555, 555, 555, 555, 555, 555, 556, 556, 556, 556, 556, 556, 556, 556, 556, 557, 557, 557, 557, 557, 557, 557, 557, 557, 558, 558, - 558, 558, 558, 558, 558, 558, 558, 1025, 1013, 1012, - 562, 565, 565, 565, 565, 565, 565, 565, 565, 565, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 1010, - 1009, 1007, 1005, 551, 551, 551, 551, 551, 551, 562, - 567, 567, 567, 567, 567, 567, 567, 567, 567, 568, - - 568, 568, 568, 568, 568, 568, 568, 568, 569, 569, - 569, 569, 569, 569, 569, 569, 569, 647, 647, 647, - 1004, 1002, 1000, 999, 562, 562, 562, 562, 562, 562, - 570, 570, 570, 570, 570, 570, 570, 570, 570, 571, - 571, 571, 571, 571, 571, 571, 571, 571, 572, 572, - 572, 572, 572, 572, 572, 572, 573, 573, 573, 573, - 573, 573, 573, 573, 573, 574, 574, 574, 574, 574, - 574, 574, 574, 574, 575, 575, 575, 575, 575, 575, - 575, 575, 575, 577, 577, 577, 577, 577, 577, 577, - 577, 577, 578, 578, 578, 578, 578, 578, 578, 578, - - 578, 631, 631, 631, 664, 664, 664, 647, 631, 651, - 651, 651, 651, 651, 651, 651, 651, 651, 652, 652, - 652, 652, 652, 652, 652, 652, 652, 653, 653, 653, - 653, 653, 653, 653, 653, 653, 654, 654, 654, 654, - 654, 654, 654, 654, 654, 655, 655, 655, 655, 655, - 655, 655, 655, 655, 656, 656, 656, 656, 656, 656, - 656, 656, 656, 658, 658, 658, 658, 658, 658, 658, - 658, 658, 659, 659, 659, 659, 659, 659, 659, 659, - 659, 660, 660, 660, 660, 660, 660, 660, 660, 660, - 974, 631, 650, 650, 664, 971, 650, 650, 814, 786, - - 650, 650, 650, 650, 650, 650, 650, 650, 650, 666, - 1239, 650, 650, 650, 650, 650, 661, 661, 661, 661, - 661, 661, 661, 661, 661, 662, 662, 662, 662, 662, - 662, 662, 662, 662, 782, 681, 681, 681, 666, 1239, - 668, 1240, 650, 777, 650, 663, 663, 663, 663, 663, - 663, 663, 663, 663, 775, 666, 666, 666, 666, 666, - 666, 667, 717, 717, 717, 717, 717, 717, 669, 668, - 1240, 650, 650, 650, 650, 650, 650, 650, 650, 650, - 650, 650, 650, 650, 650, 650, 650, 670, 770, 735, - 667, 668, 668, 668, 668, 668, 668, 669, 671, 744, - - 744, 744, 744, 744, 744, 689, 667, 667, 667, 667, - 667, 667, 1084, 686, 1084, 682, 670, 1084, 1084, 669, - 669, 669, 669, 669, 669, 681, 648, 671, 641, 684, - 684, 684, 640, 639, 670, 670, 670, 670, 670, 670, - 635, 671, 671, 671, 671, 671, 671, 672, 672, 672, - 672, 672, 672, 672, 672, 672, 673, 673, 673, 673, - 673, 673, 673, 673, 673, 674, 674, 674, 674, 674, - 674, 674, 674, 674, 675, 675, 675, 675, 675, 675, - 675, 675, 675, 676, 676, 676, 676, 676, 676, 676, - 676, 676, 677, 677, 677, 634, 677, 632, 677, 677, - - 677, 678, 678, 678, 678, 678, 678, 678, 678, 678, - 679, 679, 679, 679, 679, 679, 679, 679, 679, 684, - 688, 688, 688, 692, 692, 692, 692, 692, 692, 692, - 692, 692, 693, 693, 693, 693, 693, 693, 693, 693, - 693, 694, 694, 694, 694, 694, 694, 694, 694, 694, - 695, 695, 695, 695, 695, 695, 695, 695, 695, 696, - 696, 696, 696, 696, 696, 696, 696, 696, 697, 697, - 697, 697, 697, 697, 697, 697, 697, 699, 699, 699, - 699, 699, 699, 699, 699, 699, 700, 700, 700, 700, - 700, 700, 700, 700, 700, 701, 701, 701, 701, 701, - - 701, 701, 701, 701, 820, 820, 820, 820, 820, 820, - 688, 691, 691, 628, 627, 691, 691, 625, 621, 691, - 691, 691, 691, 691, 691, 691, 691, 691, 706, 1241, - 691, 691, 691, 691, 691, 702, 702, 702, 702, 702, - 702, 702, 702, 702, 703, 703, 703, 703, 703, 703, - 703, 703, 703, 705, 705, 705, 618, 706, 1241, 707, - 1242, 691, 617, 691, 704, 704, 704, 704, 704, 704, - 704, 704, 704, 706, 706, 706, 706, 706, 706, 1086, - 614, 1086, 613, 708, 1086, 1086, 611, 599, 707, 1242, - 691, 691, 691, 691, 691, 691, 691, 691, 691, 691, - - 691, 691, 691, 691, 691, 691, 707, 707, 707, 707, - 707, 707, 708, 709, 709, 709, 709, 709, 709, 709, - 709, 709, 598, 595, 594, 591, 708, 708, 708, 708, - 708, 708, 710, 710, 710, 710, 710, 710, 710, 710, - 710, 590, 360, 705, 711, 711, 711, 711, 711, 711, - 711, 711, 711, 712, 712, 712, 712, 712, 712, 712, - 712, 712, 713, 713, 713, 713, 713, 713, 713, 713, - 713, 714, 714, 714, 714, 714, 355, 714, 714, 714, - 715, 715, 715, 715, 715, 715, 715, 715, 715, 716, - 716, 716, 716, 716, 716, 716, 716, 716, 718, 718, - - 718, 718, 718, 718, 718, 718, 718, 719, 719, 719, + 558, 558, 558, 558, 558, 558, 558, 559, 559, 559, + 559, 559, 559, 559, 559, 559, 1337, 1332, 562, 563, + 566, 566, 566, 566, 566, 566, 566, 566, 566, 567, + + 567, 567, 567, 567, 567, 567, 567, 567, 1331, 1325, + 1324, 552, 552, 552, 552, 552, 552, 562, 563, 568, + 568, 568, 568, 568, 568, 568, 568, 568, 718, 718, + 718, 718, 718, 718, 1323, 1322, 562, 562, 562, 562, + 562, 562, 569, 569, 569, 569, 569, 569, 569, 569, + 569, 1321, 1319, 563, 563, 563, 563, 563, 563, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 571, 571, + 571, 571, 571, 571, 571, 571, 571, 572, 572, 572, + 572, 572, 572, 572, 572, 572, 574, 574, 574, 574, + 574, 574, 574, 574, 574, 575, 575, 575, 575, 575, + + 575, 575, 575, 575, 576, 576, 576, 576, 576, 576, + 576, 576, 576, 578, 578, 578, 578, 578, 578, 578, + 578, 578, 579, 579, 579, 579, 579, 579, 579, 579, + 579, 652, 652, 1318, 1315, 652, 652, 1306, 1305, 652, + 652, 652, 652, 652, 652, 652, 652, 652, 1298, 652, + 652, 652, 652, 652, 653, 653, 653, 653, 653, 653, + 653, 653, 653, 654, 654, 654, 654, 654, 654, 654, + 654, 654, 727, 727, 727, 727, 727, 727, 727, 727, + 652, 1297, 652, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 656, 656, 656, 656, 656, 656, 656, 656, + + 656, 745, 745, 745, 745, 745, 745, 1288, 1286, 652, + 652, 652, 652, 652, 652, 652, 652, 652, 652, 652, + 652, 652, 652, 652, 652, 657, 657, 657, 657, 657, + 657, 657, 657, 657, 658, 658, 658, 658, 658, 658, + 658, 658, 658, 660, 660, 660, 660, 660, 660, 660, + 660, 660, 661, 661, 661, 661, 661, 661, 661, 661, + 661, 662, 662, 662, 662, 662, 662, 662, 662, 662, + 663, 663, 663, 663, 663, 663, 663, 663, 663, 664, + 664, 664, 664, 664, 664, 664, 664, 664, 665, 665, + 665, 665, 665, 665, 665, 665, 665, 668, 669, 1271, + + 1272, 1285, 1279, 1277, 670, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 715, 715, 715, 715, 715, 671, + 715, 715, 715, 1275, 1269, 1225, 668, 669, 1271, 1272, + 731, 731, 672, 670, 731, 1138, 731, 731, 731, 1137, + 1136, 1135, 668, 668, 668, 668, 668, 668, 671, 669, + 669, 669, 669, 669, 669, 670, 670, 670, 670, 670, + 670, 672, 682, 682, 682, 1134, 671, 671, 671, 671, + 671, 671, 685, 685, 685, 672, 672, 672, 672, 672, + 672, 674, 674, 674, 674, 674, 674, 674, 674, 674, + 675, 675, 675, 675, 675, 675, 675, 675, 675, 676, + + 676, 676, 676, 676, 676, 676, 676, 676, 677, 677, + 677, 677, 677, 677, 677, 677, 677, 679, 679, 679, + 679, 679, 679, 679, 679, 679, 680, 680, 680, 680, + 680, 680, 680, 680, 680, 689, 689, 689, 693, 693, + 693, 693, 693, 693, 693, 693, 693, 1132, 1131, 1128, + 1113, 682, 694, 694, 694, 694, 694, 694, 694, 694, + 694, 685, 695, 695, 695, 695, 695, 695, 695, 695, + 695, 696, 696, 696, 696, 696, 696, 696, 696, 696, + 697, 697, 697, 697, 697, 697, 697, 697, 697, 698, + 698, 698, 698, 698, 698, 698, 698, 698, 700, 700, + + 700, 700, 700, 700, 700, 700, 700, 701, 701, 701, + 701, 701, 701, 701, 701, 701, 789, 789, 789, 789, + 789, 789, 789, 789, 689, 692, 692, 1109, 1100, 692, + 692, 1093, 1091, 692, 692, 692, 692, 692, 692, 692, + 692, 692, 1273, 692, 692, 692, 692, 692, 702, 702, + 702, 702, 702, 702, 702, 702, 702, 703, 703, 703, + 703, 703, 703, 703, 703, 703, 706, 706, 706, 1287, + 1080, 1273, 1294, 1299, 692, 1066, 692, 704, 704, 704, + 704, 704, 704, 704, 704, 704, 705, 705, 705, 705, + 705, 705, 705, 705, 705, 707, 1334, 1404, 1287, 708, + + 1054, 1294, 1299, 692, 692, 692, 692, 692, 692, 692, + 692, 692, 692, 692, 692, 692, 692, 692, 692, 1050, + 1036, 1024, 1023, 709, 707, 1334, 1404, 1021, 708, 710, + 710, 710, 710, 710, 710, 710, 710, 710, 1020, 1018, + 707, 707, 707, 707, 707, 707, 708, 708, 708, 708, + 708, 708, 709, 1016, 1015, 706, 711, 711, 711, 711, + 711, 711, 711, 711, 711, 1013, 709, 709, 709, 709, + 709, 709, 712, 712, 712, 712, 712, 712, 712, 712, + 712, 713, 713, 713, 713, 713, 713, 713, 713, 713, + 714, 714, 714, 714, 714, 714, 714, 714, 714, 716, + + 716, 716, 716, 716, 716, 716, 716, 716, 717, 717, + 717, 717, 717, 717, 717, 717, 717, 719, 719, 719, 719, 719, 719, 719, 719, 719, 720, 720, 720, 720, 720, 720, 720, 720, 720, 721, 721, 721, 721, 721, 721, 721, 721, 721, 722, 722, 722, 722, 722, 722, 722, 722, 722, 723, 723, 723, 723, 723, 723, 723, - 723, 723, 724, 725, 725, 725, 725, 725, 725, 725, - 725, 725, 726, 726, 726, 726, 726, 726, 726, 726, - 727, 727, 727, 727, 727, 727, 727, 727, 727, 351, - 346, 724, 728, 728, 728, 728, 728, 728, 728, 728, - 728, 729, 729, 729, 729, 729, 729, 729, 729, 729, - - 734, 734, 734, 724, 724, 724, 724, 724, 724, 730, - 730, 342, 327, 730, 290, 730, 730, 730, 731, 731, - 731, 731, 731, 731, 731, 731, 731, 732, 732, 732, - 732, 732, 732, 732, 732, 732, 738, 738, 738, 738, - 738, 738, 738, 738, 738, 739, 739, 739, 739, 739, - 739, 739, 739, 739, 740, 740, 740, 740, 740, 740, - 740, 740, 740, 741, 741, 741, 741, 741, 741, 741, - 741, 741, 742, 742, 742, 742, 742, 742, 742, 742, - 742, 743, 743, 743, 743, 743, 743, 743, 743, 743, - 734, 737, 737, 280, 279, 737, 737, 1085, 1085, 737, - - 737, 737, 737, 737, 737, 737, 737, 737, 1085, 1243, - 737, 737, 737, 737, 737, 745, 745, 745, 745, 745, - 745, 745, 745, 745, 746, 746, 746, 746, 746, 746, - 746, 746, 746, 752, 752, 752, 1244, 1085, 1243, 277, - 1245, 737, 254, 737, 747, 747, 747, 747, 747, 747, - 747, 747, 747, 748, 748, 748, 748, 748, 748, 748, - 748, 748, 756, 252, 756, 1244, 243, 756, 756, 1245, - 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, - 737, 737, 737, 737, 737, 737, 749, 749, 749, 749, - 749, 749, 749, 749, 749, 750, 750, 750, 750, 750, - - 750, 750, 750, 750, 755, 758, 755, 755, 759, 788, - 788, 788, 788, 788, 788, 788, 788, 755, 760, 1246, - 1247, 1249, 241, 752, 761, 761, 761, 761, 761, 761, - 761, 761, 761, 230, 758, 229, 223, 759, 222, 756, - 756, 756, 756, 756, 756, 214, 755, 760, 1246, 1247, - 1249, 758, 758, 758, 758, 758, 758, 213, 210, 759, - 759, 759, 759, 759, 759, 760, 760, 760, 760, 760, - 760, 769, 769, 769, 772, 772, 772, 209, 755, 755, - 755, 755, 755, 755, 762, 762, 762, 762, 762, 762, - 762, 762, 762, 763, 763, 763, 763, 763, 763, 763, - - 763, 763, 764, 764, 764, 764, 764, 764, 764, 764, - 764, 765, 765, 765, 765, 765, 765, 765, 765, 765, - 766, 766, 193, 192, 766, 766, 766, 766, 766, 767, - 767, 767, 767, 767, 767, 767, 767, 767, 768, 768, - 768, 768, 768, 768, 768, 768, 768, 776, 776, 776, - 779, 779, 779, 796, 796, 796, 796, 796, 796, 796, - 796, 769, 186, 185, 772, 787, 787, 787, 787, 787, - 787, 787, 787, 787, 789, 789, 789, 789, 789, 789, - 789, 789, 789, 790, 790, 790, 790, 790, 790, 790, - 790, 790, 791, 791, 791, 791, 791, 791, 791, 791, - - 791, 792, 792, 178, 177, 792, 71, 792, 792, 792, - 793, 793, 793, 793, 793, 793, 793, 793, 793, 794, - 794, 794, 794, 794, 794, 794, 794, 794, 795, 795, - 795, 795, 795, 795, 795, 795, 795, 776, 57, 36, - 779, 797, 797, 797, 797, 797, 797, 797, 797, 797, - 798, 798, 798, 798, 798, 798, 798, 798, 798, 799, - 799, 799, 799, 799, 799, 799, 799, 799, 800, 800, - 35, 34, 800, 33, 800, 800, 800, 801, 801, 801, - 801, 801, 801, 801, 801, 801, 802, 802, 802, 802, - 802, 802, 802, 802, 802, 803, 803, 803, 803, 803, - - 803, 803, 803, 804, 804, 0, 0, 804, 0, 804, - 804, 804, 805, 805, 805, 805, 805, 805, 805, 805, - 805, 806, 806, 806, 806, 806, 806, 806, 806, 807, - 807, 807, 807, 807, 807, 807, 807, 807, 808, 808, - 808, 808, 808, 808, 808, 808, 808, 809, 809, 809, - 809, 809, 809, 809, 809, 809, 810, 810, 819, 819, - 810, 821, 810, 810, 810, 811, 811, 811, 811, 811, - 811, 811, 811, 811, 812, 812, 812, 812, 812, 812, - 812, 812, 812, 813, 813, 813, 822, 0, 0, 0, - 821, 841, 841, 841, 841, 841, 841, 0, 0, 823, - - 824, 849, 849, 849, 849, 849, 849, 825, 1250, 826, - 1001, 1001, 1001, 0, 0, 822, 891, 891, 891, 891, - 891, 891, 821, 821, 821, 821, 821, 821, 823, 824, - 819, 819, 819, 819, 819, 819, 825, 1250, 826, 0, - 822, 822, 822, 822, 822, 822, 0, 823, 823, 823, - 823, 823, 823, 827, 1006, 1006, 1006, 824, 824, 824, - 824, 824, 824, 828, 825, 825, 825, 825, 825, 825, - 1252, 0, 1253, 813, 826, 826, 826, 826, 826, 826, - 0, 0, 827, 0, 830, 0, 831, 0, 0, 1011, - 1011, 1011, 828, 829, 0, 0, 0, 1254, 829, 1252, - - 1001, 1253, 1268, 832, 1269, 1277, 0, 827, 827, 827, - 827, 827, 827, 830, 833, 831, 828, 828, 828, 828, - 828, 828, 829, 1024, 1024, 1024, 1254, 829, 0, 0, - 0, 1268, 832, 1269, 1277, 835, 830, 830, 830, 830, - 830, 830, 0, 833, 1006, 829, 829, 829, 829, 829, - 829, 831, 831, 831, 831, 831, 831, 832, 832, 832, - 832, 832, 832, 834, 835, 836, 1282, 834, 833, 833, - 833, 833, 833, 833, 903, 903, 1307, 838, 903, 1011, - 903, 903, 903, 837, 899, 899, 899, 899, 899, 899, - 899, 899, 834, 839, 836, 1282, 834, 1308, 835, 835, - - 835, 835, 835, 835, 0, 1307, 838, 0, 0, 1040, - 1040, 1040, 837, 1024, 0, 836, 836, 836, 836, 836, - 836, 0, 839, 0, 840, 842, 1308, 0, 834, 834, - 834, 834, 834, 834, 837, 837, 837, 837, 837, 837, - 838, 838, 838, 838, 838, 838, 0, 839, 839, 839, - 839, 839, 839, 840, 842, 843, 845, 1317, 1383, 1384, - 912, 912, 844, 846, 912, 1385, 912, 912, 912, 848, - 0, 840, 840, 840, 840, 840, 840, 842, 842, 842, - 842, 842, 842, 0, 843, 845, 1317, 1383, 1384, 0, - 0, 844, 846, 0, 1385, 0, 0, 847, 848, 1040, - - 0, 845, 845, 845, 845, 845, 845, 850, 843, 843, - 843, 843, 843, 843, 844, 844, 844, 844, 844, 844, - 846, 846, 846, 846, 846, 846, 847, 848, 848, 848, - 848, 848, 848, 858, 0, 851, 850, 853, 1386, 878, - 1387, 852, 0, 0, 0, 0, 0, 847, 847, 847, - 847, 847, 847, 0, 854, 856, 0, 0, 850, 850, - 850, 850, 850, 850, 851, 857, 853, 1386, 0, 1387, - 852, 858, 858, 858, 858, 858, 858, 878, 878, 878, - 878, 878, 878, 854, 856, 855, 859, 0, 853, 853, - 853, 853, 853, 853, 857, 0, 851, 851, 851, 851, - - 851, 851, 852, 852, 852, 852, 852, 852, 854, 854, - 854, 854, 854, 854, 855, 859, 856, 856, 856, 856, - 856, 856, 857, 857, 857, 857, 857, 857, 860, 861, - 1388, 855, 855, 855, 855, 855, 855, 866, 862, 906, - 906, 906, 906, 906, 906, 859, 859, 859, 859, 859, - 859, 907, 907, 907, 907, 907, 907, 860, 861, 1388, - 0, 0, 863, 864, 865, 0, 866, 862, 0, 0, - 1056, 1056, 1056, 860, 860, 860, 860, 860, 860, 861, - 861, 861, 861, 861, 861, 862, 862, 862, 862, 862, - 862, 863, 864, 865, 867, 0, 866, 866, 866, 866, - - 866, 866, 868, 863, 863, 863, 863, 863, 863, 0, - 865, 865, 865, 865, 865, 865, 0, 0, 0, 0, - 0, 869, 870, 867, 864, 864, 864, 864, 864, 864, - 871, 868, 898, 898, 898, 898, 898, 898, 898, 898, - 898, 0, 0, 0, 867, 867, 867, 867, 867, 867, - 869, 870, 872, 873, 874, 1427, 880, 880, 880, 871, - 1056, 868, 868, 868, 868, 868, 868, 0, 0, 869, - 869, 869, 869, 869, 869, 0, 0, 875, 0, 0, - 0, 872, 873, 874, 1427, 870, 870, 870, 870, 870, - 870, 0, 871, 871, 871, 871, 871, 871, 876, 0, - - 872, 872, 872, 872, 872, 872, 875, 879, 874, 874, - 874, 874, 874, 874, 877, 0, 0, 0, 873, 873, - 873, 873, 873, 873, 0, 0, 0, 876, 875, 875, - 875, 875, 875, 875, 0, 1382, 879, 881, 882, 0, - 0, 0, 0, 877, 880, 880, 880, 880, 880, 880, - 1382, 0, 876, 876, 876, 876, 876, 876, 884, 0, - 877, 877, 877, 877, 877, 877, 881, 882, 879, 879, - 879, 879, 879, 879, 883, 885, 883, 1428, 887, 1382, - 881, 881, 881, 881, 881, 881, 0, 884, 882, 882, - 882, 882, 882, 882, 944, 944, 0, 0, 944, 889, - - 944, 944, 944, 883, 885, 883, 1428, 887, 0, 0, - 0, 0, 884, 884, 884, 884, 884, 884, 886, 888, - 0, 888, 883, 883, 883, 883, 883, 883, 889, 886, - 887, 887, 887, 887, 887, 887, 885, 885, 885, 885, - 885, 885, 0, 0, 0, 0, 0, 886, 888, 890, - 888, 892, 919, 919, 919, 919, 919, 919, 886, 1430, - 894, 1432, 1433, 916, 889, 889, 889, 889, 889, 889, - 888, 888, 888, 888, 888, 888, 0, 0, 890, 0, - 892, 886, 886, 886, 886, 886, 886, 893, 1430, 894, - 1432, 1433, 916, 0, 895, 897, 0, 890, 890, 890, - - 890, 890, 890, 892, 892, 892, 892, 892, 892, 896, - 1435, 1437, 1438, 896, 0, 0, 893, 894, 894, 894, - 894, 894, 894, 895, 897, 916, 916, 916, 916, 916, - 916, 1439, 893, 893, 893, 893, 893, 893, 896, 1435, - 1437, 1438, 896, 1082, 1082, 1082, 895, 895, 895, 895, - 895, 895, 0, 897, 897, 897, 897, 897, 897, 0, - 1439, 896, 896, 896, 896, 896, 896, 900, 900, 900, - 900, 900, 900, 900, 900, 900, 901, 901, 901, 901, - 901, 901, 901, 901, 901, 902, 902, 902, 902, 902, - 902, 902, 902, 902, 904, 904, 904, 904, 904, 904, - - 904, 904, 904, 905, 905, 905, 905, 905, 905, 905, - 905, 905, 911, 911, 911, 911, 911, 911, 911, 911, - 911, 913, 914, 915, 0, 1458, 917, 920, 920, 920, - 920, 920, 920, 1082, 0, 0, 925, 0, 918, 923, - 923, 923, 923, 923, 923, 923, 923, 923, 0, 929, - 913, 914, 915, 929, 1458, 917, 0, 0, 0, 0, - 925, 913, 913, 913, 913, 913, 913, 918, 0, 0, - 0, 915, 915, 915, 915, 915, 915, 917, 917, 917, - 917, 917, 917, 914, 914, 914, 914, 914, 914, 925, - 927, 1459, 1460, 918, 918, 918, 918, 918, 918, 924, - - 924, 924, 924, 924, 924, 924, 924, 926, 0, 0, - 925, 925, 925, 925, 925, 925, 926, 927, 928, 1472, - 1459, 1460, 1478, 929, 929, 929, 929, 929, 929, 0, - 930, 952, 952, 0, 1479, 952, 931, 952, 952, 952, - 0, 0, 932, 0, 1511, 926, 927, 928, 1472, 962, - 962, 1478, 0, 962, 934, 962, 962, 962, 930, 0, - 935, 0, 932, 1479, 927, 927, 927, 927, 927, 927, - 933, 935, 931, 1511, 1512, 0, 928, 936, 0, 0, - 0, 926, 926, 926, 926, 926, 926, 930, 937, 0, - 934, 932, 928, 928, 928, 928, 928, 928, 933, 0, - - 935, 0, 0, 1512, 930, 930, 930, 930, 930, 930, - 931, 931, 931, 931, 931, 931, 932, 932, 932, 932, - 932, 932, 0, 0, 0, 0, 0, 933, 934, 934, - 934, 934, 934, 934, 935, 935, 935, 935, 935, 935, - 0, 0, 0, 0, 933, 933, 933, 933, 933, 933, - 0, 936, 936, 936, 936, 936, 936, 0, 0, 0, - 0, 0, 937, 937, 937, 937, 937, 937, 938, 938, - 938, 938, 938, 938, 938, 938, 938, 939, 939, 939, - 939, 939, 939, 939, 939, 939, 940, 940, 940, 940, - 940, 940, 940, 940, 941, 941, 941, 941, 941, 941, - - 941, 941, 941, 942, 942, 942, 942, 942, 942, 942, - 942, 942, 943, 943, 943, 943, 943, 943, 943, 943, - 943, 945, 945, 945, 945, 945, 945, 945, 945, 945, - 946, 946, 946, 946, 946, 946, 946, 946, 946, 947, - 947, 947, 947, 947, 947, 947, 947, 947, 948, 948, - 948, 948, 948, 948, 948, 948, 949, 949, 949, 949, - 949, 949, 949, 949, 949, 950, 950, 950, 950, 950, - 950, 950, 950, 950, 951, 951, 951, 951, 951, 951, - 951, 951, 951, 953, 953, 953, 953, 953, 953, 953, - 953, 953, 954, 954, 954, 954, 954, 954, 954, 954, - - 954, 955, 956, 957, 957, 957, 957, 957, 957, 957, - 957, 957, 958, 958, 958, 958, 958, 958, 958, 958, - 959, 959, 959, 959, 959, 959, 959, 959, 959, 0, - 955, 956, 960, 960, 960, 960, 960, 960, 960, 960, - 960, 965, 965, 965, 965, 965, 965, 955, 955, 955, - 955, 955, 955, 0, 0, 0, 956, 956, 956, 956, - 956, 956, 961, 961, 961, 961, 961, 961, 961, 961, - 961, 963, 963, 963, 963, 963, 963, 963, 963, 963, - 964, 964, 964, 964, 964, 964, 964, 964, 964, 966, - 966, 966, 966, 966, 966, 967, 967, 967, 967, 967, - - 967, 967, 967, 967, 1014, 1014, 1014, 1014, 1014, 1014, - 1014, 1014, 1014, 1015, 1015, 1015, 1015, 1015, 1015, 1015, - 1015, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, 1016, - 1017, 1017, 1017, 1017, 1017, 1017, 1017, 1017, 1017, 1018, - 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1018, 1019, 1019, - 0, 0, 1019, 0, 1019, 1019, 1019, 1020, 1020, 1020, - 1020, 1020, 1020, 1020, 1020, 1020, 1021, 1021, 1021, 1021, - 1021, 1021, 1021, 1021, 1021, 1022, 1022, 1022, 1022, 1022, - 1022, 1022, 1022, 1023, 1023, 1029, 0, 1023, 0, 1023, - 1023, 1023, 1030, 1032, 1524, 1537, 0, 1031, 1035, 1035, - - 1035, 1035, 1035, 1035, 1036, 1036, 1036, 1036, 1036, 1036, - 0, 1051, 1051, 1538, 1029, 1051, 0, 1051, 1051, 1051, - 0, 1030, 1032, 1524, 1537, 1034, 1031, 1033, 1047, 1047, - 1047, 1047, 1047, 1047, 1047, 1047, 1029, 1029, 1029, 1029, - 1029, 1029, 1538, 0, 1030, 1030, 1030, 1030, 1030, 1030, - 1031, 1031, 1031, 1031, 1031, 1031, 1033, 1032, 1032, 1032, - 1032, 1032, 1032, 1034, 1034, 1034, 1034, 1034, 1034, 0, - 1098, 1098, 1098, 1033, 1033, 1033, 1033, 1033, 1033, 1038, - 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1038, 1046, 1046, - 1046, 1046, 1046, 1046, 1046, 1046, 1046, 1048, 1048, 1048, - - 1048, 1048, 1048, 1048, 1048, 1048, 1049, 1049, 1049, 1049, - 1049, 1049, 1049, 1049, 1049, 1050, 1050, 1050, 1050, 1050, - 1050, 1050, 1050, 1050, 1052, 1052, 1052, 1052, 1052, 1052, - 1052, 1052, 1052, 1053, 1053, 1053, 1053, 1053, 1053, 1053, - 1053, 1053, 1054, 1054, 1054, 1054, 1054, 1054, 1054, 1054, - 1055, 1055, 1058, 0, 1055, 0, 1055, 1055, 1055, 1060, - 1098, 0, 1539, 1066, 1059, 1061, 1061, 1061, 1061, 1061, - 1061, 1062, 1062, 1062, 1062, 1062, 1062, 0, 0, 0, - 0, 1058, 1065, 1065, 1065, 1065, 1065, 1065, 1065, 1065, - 1065, 1539, 1066, 1059, 0, 0, 0, 1060, 1060, 1060, - - 1060, 1060, 1060, 0, 1058, 1058, 1058, 1058, 1058, 1058, - 1059, 1059, 1059, 1059, 1059, 1059, 1066, 1066, 1066, 1066, - 1066, 1066, 1067, 1067, 1067, 1067, 1067, 1067, 1068, 1068, - 1068, 1068, 1068, 1068, 1069, 1069, 1069, 1069, 1069, 1069, - 1069, 1069, 1069, 1072, 1072, 1072, 1072, 1072, 1072, 1072, - 1072, 1072, 1073, 1073, 1073, 1073, 1073, 1073, 1073, 1073, - 1074, 1074, 1074, 1074, 1074, 1074, 1074, 1074, 1074, 1075, - 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1076, 1076, - 1076, 1076, 1076, 1076, 1076, 1076, 1076, 1077, 1077, 1088, - 1088, 1077, 0, 1077, 1077, 1077, 1078, 1078, 1078, 1078, - - 1078, 1078, 1078, 1078, 1078, 1079, 1079, 1079, 1079, 1079, - 1079, 1079, 1079, 1079, 1080, 1080, 1080, 1080, 1080, 1080, - 1080, 1080, 1081, 1081, 1091, 1092, 1081, 1109, 1081, 1081, - 1081, 1094, 1094, 1094, 1094, 1094, 1094, 1095, 1095, 1095, - 1095, 1095, 1095, 1097, 1097, 1097, 1097, 1097, 1097, 1097, - 1097, 1097, 1093, 1091, 1092, 1102, 1102, 1102, 1115, 1540, - 0, 1088, 1088, 1088, 1088, 1088, 1088, 1110, 0, 1119, - 1119, 1119, 0, 0, 0, 1091, 1091, 1091, 1091, 1091, - 1091, 1093, 1133, 1133, 1133, 1133, 1133, 1133, 1540, 1092, - 1092, 1092, 1092, 1092, 1092, 1265, 1265, 1265, 0, 1093, - - 1093, 1093, 1093, 1093, 1093, 1116, 1542, 1546, 1547, 1549, - 0, 1109, 1109, 1109, 1109, 1109, 1109, 1111, 1111, 1111, - 1111, 1111, 1111, 1111, 1111, 1111, 1114, 1114, 1114, 1114, - 1114, 1114, 1114, 1114, 1114, 1542, 1546, 1547, 1549, 1115, - 1115, 1115, 1115, 1115, 1115, 1102, 0, 0, 0, 0, - 0, 1110, 1110, 1110, 1110, 1110, 1110, 1112, 1112, 1119, - 0, 1112, 1112, 0, 0, 1112, 1112, 1112, 1112, 1112, - 1112, 1112, 1112, 1112, 1127, 1128, 1112, 1112, 1112, 1112, - 1112, 0, 0, 0, 1130, 1265, 1116, 1116, 1116, 1116, - 1116, 1116, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, - - 1117, 0, 0, 1127, 1128, 0, 0, 1112, 0, 1112, - 1259, 1259, 1259, 1130, 1259, 0, 1128, 1128, 1128, 1128, - 1128, 1128, 1127, 1127, 1127, 1127, 1127, 1127, 0, 1129, - 1130, 1130, 1130, 1130, 1130, 1130, 1112, 1112, 1112, 1112, - 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, 1112, - 1112, 1112, 1113, 1113, 1131, 1550, 1113, 1113, 1129, 0, - 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1132, - 0, 1113, 1113, 1113, 1113, 1113, 1144, 1144, 1144, 1144, - 1144, 1144, 0, 1131, 1550, 1548, 1129, 1129, 1129, 1129, - 1129, 1129, 0, 0, 0, 1134, 0, 1548, 1132, 1134, - - 1259, 1135, 1113, 0, 1113, 0, 1131, 1131, 1131, 1131, - 1131, 1131, 0, 0, 1548, 0, 0, 1132, 1132, 1132, - 1132, 1132, 1132, 1136, 1134, 1137, 1548, 0, 1134, 0, - 1135, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, - 1113, 1113, 1113, 1113, 1113, 1113, 1113, 0, 1138, 1139, - 1140, 0, 1136, 0, 1137, 0, 1134, 1134, 1134, 1134, - 1134, 1134, 1135, 1135, 1135, 1135, 1135, 1135, 1279, 1279, - 1279, 1137, 1137, 1137, 1137, 1137, 1137, 1138, 1139, 1140, - 1136, 1136, 1136, 1136, 1136, 1136, 1150, 1150, 1150, 1150, - 1150, 1150, 1141, 1142, 1138, 1138, 1138, 1138, 1138, 1138, - - 1143, 1147, 1148, 1139, 1139, 1139, 1139, 1139, 1139, 1154, - 1154, 1154, 1154, 1154, 1154, 1140, 1140, 1140, 1140, 1140, - 1140, 1141, 1142, 0, 0, 1145, 0, 1149, 1551, 1143, - 1147, 1148, 0, 1141, 1141, 1141, 1141, 1141, 1141, 1142, - 1142, 1142, 1142, 1142, 1142, 0, 0, 0, 1143, 1143, - 1143, 1143, 1143, 1143, 1145, 1146, 1149, 1551, 1279, 1152, - 1148, 1148, 1148, 1148, 1148, 1148, 1147, 1147, 1147, 1147, - 1147, 1147, 0, 1145, 1145, 1145, 1145, 1145, 1145, 1151, - 1155, 0, 0, 0, 1146, 0, 1153, 1552, 1152, 1149, - 1149, 1149, 1149, 1149, 1149, 0, 0, 1160, 1160, 1160, - - 1146, 1146, 1146, 1146, 1146, 1146, 1156, 0, 1151, 1152, - 1152, 1152, 1152, 1152, 1152, 1153, 1552, 0, 1155, 1155, - 1155, 1155, 1155, 1155, 1157, 1151, 1151, 1151, 1151, 1151, - 1151, 1158, 1553, 1545, 1161, 1156, 1545, 0, 1153, 1153, - 1153, 1153, 1153, 1153, 1159, 1159, 1159, 1159, 1159, 1159, - 0, 0, 0, 1157, 1156, 1156, 1156, 1156, 1156, 1156, - 1158, 1553, 1545, 0, 0, 1545, 1157, 1157, 1157, 1157, - 1157, 1157, 1161, 1161, 1161, 1161, 1161, 1161, 1163, 1158, - 1158, 1158, 1158, 1158, 1158, 1160, 1160, 1160, 1160, 1160, - 1160, 1162, 1162, 1162, 1162, 1162, 1162, 1287, 1287, 1287, - - 0, 1164, 1165, 1554, 1175, 1555, 1167, 1163, 1166, 1169, - 1169, 1169, 1169, 1169, 1169, 1168, 1172, 1172, 1172, 0, - 1299, 1299, 1299, 0, 1163, 1163, 1163, 1163, 1163, 1163, - 1164, 1165, 1554, 1175, 1555, 1167, 0, 1166, 0, 0, - 1170, 1313, 1313, 1313, 1168, 1175, 1175, 1175, 1175, 1175, - 1175, 1164, 1164, 1164, 1164, 1164, 1164, 1167, 1167, 1167, - 1167, 1167, 1167, 1165, 1165, 1165, 1165, 1165, 1165, 1170, - 1166, 1166, 1166, 1166, 1166, 1166, 1168, 1168, 1168, 1168, - 1168, 1168, 1171, 1173, 1583, 1584, 1189, 1287, 1170, 1170, - 1170, 1170, 1170, 1170, 1174, 1177, 1177, 1177, 1177, 1177, - - 1177, 1178, 0, 0, 1172, 1172, 1172, 1172, 1172, 1172, - 1299, 1171, 1173, 1583, 1584, 1189, 1176, 1205, 1205, 1205, - 1205, 1205, 1205, 1174, 0, 1179, 1319, 1319, 1319, 0, - 1178, 1313, 1180, 1189, 1189, 1189, 1189, 1189, 1189, 1171, - 1171, 1171, 1171, 1171, 1171, 1176, 0, 0, 1173, 1173, - 1173, 1173, 1173, 1173, 1179, 1174, 1174, 1174, 1174, 1174, - 1174, 1180, 1178, 1178, 1178, 1178, 1178, 1178, 0, 0, - 0, 1176, 1176, 1176, 1176, 1176, 1176, 1181, 1179, 1179, - 1179, 1179, 1179, 1179, 1182, 1183, 1585, 0, 1588, 1590, - 1592, 1184, 0, 1188, 1188, 1188, 0, 1180, 1180, 1180, - - 1180, 1180, 1180, 0, 0, 0, 1181, 0, 0, 1185, - 1593, 1594, 0, 1182, 1183, 1585, 1319, 1588, 1590, 1592, - 1184, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, 1187, - 0, 1595, 1181, 1181, 1181, 1181, 1181, 1181, 1185, 1593, - 1594, 1190, 1183, 1183, 1183, 1183, 1183, 1183, 1182, 1182, - 1182, 1182, 1182, 1182, 1184, 1184, 1184, 1184, 1184, 1184, - 1595, 0, 0, 0, 1192, 0, 1596, 1453, 1453, 1453, - 1190, 1453, 1185, 1185, 1185, 1185, 1185, 1185, 1186, 1186, - 1186, 1188, 1188, 1188, 1188, 1188, 1188, 1190, 1190, 1190, - 1190, 1190, 1190, 1192, 1193, 1596, 0, 0, 0, 0, - - 1186, 0, 1600, 1186, 1186, 1191, 1536, 0, 1194, 0, - 1536, 1536, 1196, 1601, 1186, 1186, 1186, 1255, 1255, 1255, - 1186, 0, 0, 1193, 1255, 1192, 1192, 1192, 1192, 1192, - 1192, 1600, 1186, 1186, 1191, 1536, 1195, 1194, 1197, 1536, - 1536, 1196, 1601, 1186, 1186, 1186, 0, 0, 0, 1186, - 1191, 1191, 1191, 1191, 1191, 1191, 0, 1453, 0, 1193, - 1193, 1193, 1193, 1193, 1193, 1195, 0, 1197, 1186, 1194, - 1194, 1194, 1194, 1194, 1194, 1196, 1196, 1196, 1196, 1196, - 1196, 1198, 1200, 1195, 1195, 1195, 1195, 1195, 1195, 1199, - 1197, 1197, 1197, 1197, 1197, 1197, 1201, 1207, 1207, 1207, - - 1207, 1207, 1207, 1202, 1208, 1203, 0, 1255, 0, 0, - 1198, 1200, 1216, 1216, 1216, 1216, 1216, 1216, 1199, 0, - 0, 0, 0, 0, 1204, 1201, 1198, 1198, 1198, 1198, - 1198, 1198, 1202, 1206, 1203, 1199, 1199, 1199, 1199, 1199, - 1199, 1208, 1208, 1208, 1208, 1208, 1208, 1200, 1200, 1200, - 1200, 1200, 1200, 1204, 0, 1201, 1201, 1201, 1201, 1201, - 1201, 1211, 1206, 1209, 1202, 1202, 1202, 1202, 1202, 1202, - 1203, 1203, 1203, 1203, 1203, 1203, 1217, 0, 0, 0, - 1217, 1204, 1204, 1204, 1204, 1204, 1204, 1212, 1602, 1606, - 1211, 0, 1613, 0, 1206, 1206, 1206, 1206, 1206, 1206, - - 1209, 1209, 1209, 1209, 1209, 1209, 1210, 1210, 1210, 1210, - 1210, 1210, 1210, 1210, 1210, 1213, 1212, 1602, 1606, 0, - 1215, 1613, 1211, 1211, 1211, 1211, 1211, 1211, 1214, 1212, - 1212, 1212, 1212, 1212, 1212, 1218, 0, 0, 0, 1218, - 0, 1220, 0, 0, 1213, 1220, 1620, 1620, 1620, 1215, - 1217, 1217, 1217, 1217, 1217, 1217, 1213, 1213, 1213, 1213, - 1213, 1213, 1218, 1629, 0, 1220, 1214, 1214, 1214, 1214, - 1214, 1214, 1215, 1215, 1215, 1215, 1215, 1215, 1219, 0, - 0, 0, 1219, 0, 0, 1222, 1257, 1257, 1257, 1222, - 0, 1218, 1629, 1257, 1220, 1224, 1587, 1228, 1630, 1224, - - 1634, 1587, 1658, 0, 1229, 0, 1219, 0, 1224, 1218, - 1218, 1218, 1218, 1218, 1218, 1220, 1220, 1220, 1220, 1220, - 1220, 1222, 1223, 0, 0, 1587, 1223, 1630, 1225, 1634, - 1587, 1658, 1225, 0, 1226, 1219, 1620, 1224, 1226, 1223, - 0, 0, 0, 0, 0, 1227, 0, 0, 1225, 1227, - 1659, 1226, 1219, 1219, 1219, 1219, 1219, 1219, 1227, 1222, - 1222, 1222, 1222, 1222, 1222, 1231, 1669, 0, 1223, 1224, - 1224, 1224, 1224, 1224, 1224, 1232, 1257, 1225, 0, 1659, - 1226, 1228, 1228, 1228, 1228, 1228, 1228, 1227, 1229, 1229, - 1229, 1229, 1229, 1229, 0, 1669, 1223, 1223, 1223, 1223, - - 1223, 1223, 1225, 1225, 1225, 1225, 1225, 1225, 1226, 1226, - 1226, 1226, 1226, 1226, 0, 0, 1680, 0, 0, 1227, - 1227, 1227, 1227, 1227, 1227, 1230, 1230, 1230, 1230, 1230, - 1230, 1230, 1230, 1230, 1233, 1233, 1233, 1233, 1233, 1233, - 1233, 1233, 1233, 1234, 1235, 1680, 1231, 1231, 1231, 1231, - 1231, 1231, 1236, 0, 0, 0, 1232, 1232, 1232, 1232, - 1232, 1232, 1237, 1238, 1238, 1238, 1238, 1238, 1238, 1238, - 1238, 1238, 0, 1235, 1293, 1293, 1293, 1293, 1293, 1293, - 0, 1234, 1234, 1234, 1234, 1234, 1234, 0, 1271, 1236, - 1236, 1236, 1236, 1236, 1236, 0, 1934, 1934, 1934, 1237, - - 1237, 1237, 1237, 1237, 1237, 1235, 1235, 1235, 1235, 1235, - 1235, 1261, 1261, 0, 0, 1261, 1261, 1271, 1272, 1261, - 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1275, 1681, - 1261, 1261, 1261, 1261, 1261, 1263, 1263, 1263, 1263, 1263, - 1263, 1263, 1263, 1263, 1273, 1273, 1273, 1272, 0, 1273, - 0, 1271, 1271, 1271, 1271, 1271, 1271, 1273, 1681, 1682, - 1683, 1261, 0, 1261, 0, 0, 1275, 1275, 1275, 1275, - 1275, 1275, 1411, 1411, 1411, 1411, 1411, 1411, 0, 1274, - 1272, 1272, 1272, 1272, 1272, 1272, 1934, 0, 1682, 1683, - 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, 1261, - - 1261, 1261, 1261, 1261, 1261, 1261, 1262, 1262, 1274, 1276, - 1262, 1262, 1291, 0, 1262, 1262, 1262, 1262, 1262, 1262, - 1262, 1262, 1262, 0, 0, 1262, 1262, 1262, 1262, 1262, - 0, 0, 1273, 1273, 1273, 1273, 1273, 1273, 1276, 1684, - 1685, 1368, 1368, 1368, 1274, 1274, 1274, 1274, 1274, 1274, - 1291, 1291, 1291, 1291, 1291, 1291, 1262, 0, 1262, 1285, - 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1285, 1684, 1685, - 0, 0, 1276, 1276, 1276, 1276, 1276, 1276, 1290, 1368, - 0, 0, 1943, 1943, 1943, 1262, 1262, 1262, 1262, 1262, - 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, 1262, - - 1262, 1283, 1283, 1292, 0, 1283, 1283, 1290, 1368, 1283, - 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1686, 1687, - 1283, 1283, 1283, 1283, 1283, 1426, 1426, 1426, 1426, 1426, - 1426, 1368, 1292, 1328, 1328, 1328, 1412, 0, 0, 0, - 1290, 1290, 1290, 1290, 1290, 1290, 0, 1686, 1687, 0, - 0, 1283, 0, 1283, 1297, 1297, 1297, 1297, 1297, 1297, - 1297, 1297, 1297, 0, 0, 0, 1292, 1292, 1292, 1292, - 1292, 1292, 1943, 1309, 1412, 1412, 1412, 1412, 1412, 1412, - 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, - 1283, 1283, 1283, 1283, 1283, 1283, 1284, 1284, 1310, 1311, - - 1284, 1284, 1309, 0, 1284, 1284, 1284, 1284, 1284, 1284, - 1284, 1284, 1284, 0, 0, 1284, 1284, 1284, 1284, 1284, - 0, 1328, 1328, 1328, 1328, 1328, 1328, 1310, 1311, 0, - 1331, 1331, 1331, 1688, 0, 0, 1309, 1309, 1309, 1309, - 1309, 1309, 1332, 1332, 1332, 1689, 1284, 0, 1284, 1569, - 1569, 1569, 1569, 1569, 1569, 0, 1311, 1311, 1311, 1311, - 1311, 1311, 1688, 1310, 1310, 1310, 1310, 1310, 1310, 1329, - 1329, 1329, 0, 1418, 1689, 1284, 1284, 1284, 1284, 1284, - 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, - 1284, 1295, 1295, 0, 0, 1295, 1295, 0, 0, 1295, - - 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1690, 1418, - 1295, 1295, 1295, 1295, 1295, 1691, 1692, 1329, 1331, 1331, - 1331, 1331, 1331, 1331, 1572, 1572, 1572, 1572, 1572, 1572, - 1332, 1332, 1332, 1332, 1332, 1332, 0, 1690, 1336, 1336, - 1336, 1295, 0, 1295, 1691, 1692, 1329, 1418, 1418, 1418, - 1418, 1418, 1418, 1334, 1334, 1334, 0, 1329, 1329, 1329, - 1329, 1329, 1329, 1336, 1330, 1330, 1330, 0, 0, 0, - 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, 1295, - 1295, 1295, 1295, 1295, 1295, 1295, 1296, 1296, 1330, 1334, - 1296, 1296, 1336, 1693, 1296, 1296, 1296, 1296, 1296, 1296, - - 1296, 1296, 1296, 0, 0, 1296, 1296, 1296, 1296, 1296, - 1694, 1333, 1333, 1333, 0, 0, 0, 1330, 1334, 1335, - 1335, 1335, 1693, 1970, 1970, 1970, 1336, 1336, 1336, 1336, - 1336, 1336, 1338, 1338, 1338, 0, 1296, 1970, 1296, 1694, - 0, 1334, 1334, 1334, 1334, 1334, 1334, 1337, 1337, 1337, - 0, 0, 1330, 1330, 1330, 1330, 1330, 1330, 1333, 0, - 0, 1335, 1339, 1339, 1339, 1296, 1296, 1296, 1296, 1296, - 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, 1296, - 1296, 0, 1340, 1340, 1340, 0, 0, 1333, 1337, 1339, - 1335, 1341, 1341, 1341, 0, 0, 0, 0, 0, 1333, - - 1333, 1333, 1333, 1333, 1333, 0, 0, 1335, 1335, 1335, - 1335, 1335, 1335, 1970, 1517, 1517, 1517, 1337, 1339, 1340, - 1338, 1338, 1338, 1338, 1338, 1338, 1344, 1344, 1344, 1517, - 0, 1341, 1342, 1342, 1342, 1337, 1337, 1337, 1337, 1337, - 1337, 1343, 1343, 1343, 0, 0, 0, 1695, 1340, 1696, - 1339, 1339, 1339, 1339, 1339, 1339, 1697, 1344, 1698, 1342, - 1341, 1699, 1443, 1443, 1443, 1345, 1345, 1345, 1343, 1443, - 1340, 1340, 1340, 1340, 1340, 1340, 1695, 0, 1696, 1341, - 1341, 1341, 1341, 1341, 1341, 1697, 1344, 1698, 1342, 0, - 1699, 1448, 1448, 1448, 1346, 1346, 1346, 1343, 1448, 0, - - 0, 1349, 1349, 1349, 1517, 0, 1345, 1347, 1347, 1347, - 0, 1486, 1486, 1486, 1344, 1344, 1344, 1344, 1344, 1344, - 1342, 1342, 1342, 1342, 1342, 1342, 1348, 1348, 1348, 1343, - 1343, 1343, 1343, 1343, 1343, 1345, 1346, 1700, 1347, 1350, - 1350, 1350, 1701, 1702, 1724, 1352, 1352, 1352, 0, 1486, - 1348, 1349, 1443, 1345, 1345, 1345, 1345, 1345, 1345, 1351, - 1351, 1351, 0, 0, 0, 1346, 1700, 1347, 1355, 1355, - 1355, 1701, 1702, 1724, 1352, 1353, 1353, 1353, 1486, 1348, - 0, 1448, 1346, 1346, 1346, 1346, 1346, 1346, 0, 1349, - 1349, 1349, 1349, 1349, 1349, 1347, 1347, 1347, 1347, 1347, - - 1347, 1486, 0, 1352, 1356, 1356, 1356, 0, 0, 1351, - 1726, 1727, 1728, 1353, 1348, 1348, 1348, 1348, 1348, 1348, - 0, 0, 0, 0, 1357, 1357, 1357, 1350, 1350, 1350, - 1350, 1350, 1350, 1352, 1352, 1352, 1352, 1352, 1352, 1726, - 1727, 1728, 1353, 1354, 1354, 1354, 1356, 1351, 1351, 1351, - 1351, 1351, 1351, 1357, 1729, 0, 1355, 1355, 1355, 1355, - 1355, 1355, 1357, 1353, 1353, 1353, 1353, 1353, 1353, 1730, - 1354, 1360, 1360, 1360, 0, 1356, 0, 0, 1359, 1359, - 1359, 0, 1357, 1729, 1361, 1361, 1361, 1731, 1732, 0, - 0, 1357, 1356, 1356, 1356, 1356, 1356, 1356, 1730, 1354, - - 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1358, 1359, - 1362, 1362, 1362, 0, 1357, 1733, 1731, 1732, 1363, 1363, - 1363, 0, 0, 0, 1361, 1362, 1734, 0, 1364, 1364, - 1364, 1354, 1354, 1354, 1354, 1354, 1354, 0, 1359, 0, - 0, 1365, 1365, 1365, 1733, 0, 0, 0, 0, 1363, - 1366, 1366, 1366, 1361, 0, 1734, 1370, 1370, 1370, 1360, - 1360, 1360, 1360, 1360, 1360, 1364, 1359, 1359, 1359, 1359, - 1359, 1359, 1361, 1361, 1361, 1361, 1361, 1361, 1363, 0, - 1367, 1367, 1367, 1365, 1369, 1369, 1369, 1369, 1369, 1369, - 1369, 1369, 1369, 0, 1364, 1735, 1370, 0, 1362, 1362, - - 1362, 1362, 1362, 1362, 0, 0, 1363, 1363, 1363, 1363, - 1363, 1363, 1365, 1371, 1371, 1371, 1364, 1364, 1364, 1364, - 1364, 1364, 1367, 0, 1735, 1370, 1372, 1372, 1372, 1365, - 1365, 1365, 1365, 1365, 1365, 1373, 1373, 1373, 1366, 1366, - 1366, 1366, 1366, 1366, 1370, 1370, 1370, 1370, 1370, 1370, - 1736, 1367, 1374, 1374, 1374, 1737, 1738, 0, 1376, 1376, - 1376, 1744, 0, 1747, 1375, 1375, 1375, 0, 1367, 1367, - 1367, 1367, 1367, 1367, 1379, 1379, 1379, 0, 0, 1736, - 1377, 1377, 1377, 1376, 1737, 1738, 1378, 1378, 1378, 0, - 1744, 1375, 1747, 1374, 1380, 1380, 1380, 0, 0, 0, - - 1763, 1371, 1371, 1371, 1371, 1371, 1371, 1377, 1764, 1378, - 1379, 0, 1376, 0, 1372, 1372, 1372, 1372, 1372, 1372, - 1375, 0, 1374, 1373, 1373, 1373, 1373, 1373, 1373, 1763, - 1767, 1380, 1394, 1394, 1394, 0, 1377, 1764, 1378, 1379, - 1374, 1374, 1374, 1374, 1374, 1374, 1376, 1376, 1376, 1376, - 1376, 1376, 1375, 1375, 1375, 1375, 1375, 1375, 0, 1767, - 1380, 0, 1379, 1379, 1379, 1379, 1379, 1379, 1377, 1377, - 1377, 1377, 1377, 1377, 1378, 1378, 1378, 1378, 1378, 1378, - 0, 0, 1380, 1380, 1380, 1380, 1380, 1380, 1381, 1381, - 1381, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 1390, - - 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1392, 1393, - 1393, 1393, 1462, 0, 1570, 0, 1784, 1785, 1793, 1799, - 1394, 1394, 1394, 1394, 1394, 1394, 0, 1800, 0, 1801, - 1381, 1463, 1463, 1463, 0, 0, 1463, 1806, 1808, 1393, - 1396, 1396, 1396, 1570, 1463, 1784, 1785, 1793, 1799, 0, - 1462, 1462, 1462, 1462, 1462, 1462, 1800, 1463, 1801, 1381, - 1570, 1570, 1570, 1570, 1570, 1570, 1806, 1808, 1393, 0, - 0, 1395, 1395, 1395, 0, 0, 1381, 1381, 1381, 1381, - 1381, 1381, 1391, 1391, 1391, 0, 1463, 0, 1397, 1397, - 1397, 0, 0, 1810, 1398, 1398, 1398, 1393, 1393, 1393, - - 1393, 1393, 1393, 1399, 1399, 1399, 1811, 1391, 1391, 1391, - 1391, 1391, 1395, 1391, 1397, 1391, 1401, 1401, 1401, 1812, - 1391, 1463, 1810, 1391, 1391, 1813, 1399, 1391, 1396, 1396, - 1396, 1396, 1396, 1396, 0, 1811, 1391, 1391, 1391, 1391, - 1391, 1395, 1391, 1397, 1391, 1400, 1400, 1400, 1812, 1391, - 0, 0, 1391, 1391, 1813, 1399, 1391, 0, 0, 1395, - 1395, 1395, 1395, 1395, 1395, 0, 0, 0, 1400, 1791, - 1791, 1791, 1391, 1402, 1402, 1402, 1397, 1397, 1397, 1397, - 1397, 1397, 1398, 1398, 1398, 1398, 1398, 1398, 1403, 1403, - 1403, 1399, 1399, 1399, 1399, 1399, 1399, 1400, 0, 1791, - - 1402, 1404, 1404, 1404, 1401, 1401, 1401, 1401, 1401, 1401, - 1405, 1405, 1405, 1425, 1814, 1403, 1406, 1406, 1406, 1815, - 1816, 1817, 1407, 1407, 1407, 1818, 1819, 1404, 1791, 1402, - 1409, 1409, 1409, 1400, 1400, 1400, 1400, 1400, 1400, 0, - 0, 0, 1425, 1814, 1403, 1820, 1407, 0, 1815, 1816, - 1817, 1408, 1408, 1408, 1818, 1819, 1404, 1406, 0, 1791, - 0, 1402, 1402, 1402, 1402, 1402, 1402, 1413, 1425, 1425, - 1425, 1425, 1425, 1425, 1820, 1407, 1403, 1403, 1403, 1403, - 1403, 1403, 0, 0, 0, 0, 1406, 1408, 0, 1404, - 1404, 1404, 1404, 1404, 1404, 1410, 1413, 1414, 1405, 1405, - - 1405, 1405, 1405, 1405, 1406, 1406, 1406, 1406, 1406, 1406, - 1407, 1407, 1407, 1407, 1407, 1407, 1408, 1416, 1409, 1409, - 1409, 1409, 1409, 1409, 1410, 0, 1414, 0, 0, 1417, - 1413, 1413, 1413, 1413, 1413, 1413, 1419, 1821, 1822, 1408, - 1408, 1408, 1408, 1408, 1408, 1416, 1417, 1410, 1410, 1410, - 1410, 1410, 1410, 1421, 1809, 1419, 1414, 1414, 1414, 1414, - 1414, 1414, 1424, 0, 0, 0, 1821, 1822, 1420, 0, - 1461, 1823, 1809, 1825, 1416, 1417, 1423, 1490, 1490, 1490, - 1420, 0, 0, 1809, 1419, 0, 0, 1826, 1423, 1421, - 1827, 1416, 1416, 1416, 1416, 1416, 1416, 1422, 1424, 1461, - - 1823, 1809, 1825, 1417, 1417, 1417, 1417, 1417, 1417, 1420, - 1419, 1419, 1419, 1419, 1419, 1419, 1826, 1423, 0, 1827, - 1422, 1461, 1461, 1461, 1461, 1461, 1461, 1421, 1421, 1421, - 1421, 1421, 1421, 0, 0, 0, 1424, 1424, 1424, 1424, - 1424, 1424, 1420, 1420, 1420, 1420, 1420, 1420, 0, 1422, - 1423, 1423, 1423, 1423, 1423, 1423, 1466, 1466, 1466, 1466, - 1466, 1466, 1466, 1466, 1466, 1490, 1490, 1490, 1490, 1490, - 1490, 1422, 1422, 1422, 1422, 1422, 1422, 1464, 1464, 1464, - 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, - 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, - - 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, - 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, - 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, - 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, - 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, - 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, - 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, 1464, - 1464, 1464, 1467, 1848, 1851, 1468, 0, 0, 0, 1474, - 1622, 1622, 1622, 1622, 1622, 1622, 0, 1469, 1632, 1632, - 1632, 1632, 1632, 1632, 1475, 1766, 1766, 1766, 1766, 1766, - - 1766, 1467, 1848, 1851, 1468, 1487, 1487, 1487, 1487, 1487, - 1487, 1487, 1487, 1487, 0, 1476, 1469, 1474, 1474, 1474, - 1474, 1474, 1474, 1475, 0, 0, 1467, 1467, 1467, 1467, - 1467, 1467, 1468, 1468, 1468, 1468, 1468, 1468, 1469, 1469, - 1469, 1469, 1469, 1469, 1476, 1480, 1855, 1858, 1481, 1859, - 1860, 1475, 1475, 1475, 1475, 1475, 1475, 1482, 1488, 1488, - 1488, 1861, 1866, 1870, 0, 1577, 1476, 1476, 1476, 1476, - 1476, 1476, 0, 0, 1480, 1855, 1858, 1481, 1859, 1860, - 1489, 1489, 1489, 0, 0, 1488, 1482, 1491, 1491, 1491, - 1861, 1866, 1870, 1492, 1492, 1492, 1480, 1480, 1480, 1480, - - 1480, 1480, 1481, 1481, 1481, 1481, 1481, 1481, 1482, 1482, - 1482, 1482, 1482, 1482, 1488, 0, 1886, 1493, 1493, 1493, - 0, 0, 0, 1489, 1494, 1494, 1494, 1887, 1889, 1491, - 1495, 1495, 1495, 1906, 1907, 1912, 1496, 1496, 1496, 1577, - 1577, 1577, 1577, 1577, 1577, 1886, 1488, 1488, 1488, 1488, - 1488, 1488, 1489, 0, 0, 0, 1887, 1889, 1491, 1493, - 1915, 1496, 1906, 1907, 1912, 1920, 1494, 0, 1489, 1489, - 1489, 1489, 1489, 1489, 0, 1491, 1491, 1491, 1491, 1491, - 1491, 1492, 1492, 1492, 1492, 1492, 1492, 0, 1493, 1915, - 1496, 1501, 1501, 1501, 1920, 1494, 1514, 1514, 1514, 1514, - - 1514, 1514, 1514, 1514, 1514, 1493, 1493, 1493, 1493, 1493, - 1493, 1921, 1494, 1494, 1494, 1494, 1494, 1494, 1495, 1495, - 1495, 1495, 1495, 1495, 1496, 1496, 1496, 1496, 1496, 1496, - 1497, 1497, 1497, 0, 1922, 0, 1498, 1498, 1498, 1824, - 1921, 1927, 1928, 1499, 1499, 1499, 0, 0, 1929, 1500, - 1500, 1500, 0, 0, 0, 0, 1930, 1497, 1499, 1931, - 1824, 1932, 1498, 1922, 1504, 1504, 1504, 1933, 1824, 0, - 1927, 1928, 0, 1500, 1502, 1502, 1502, 1929, 0, 1501, - 1501, 1501, 1501, 1501, 1501, 1930, 1497, 1504, 1931, 1824, - 1932, 1498, 0, 0, 0, 0, 1933, 1507, 1507, 1507, - - 0, 1502, 1500, 0, 0, 0, 0, 1503, 1503, 1503, - 0, 0, 0, 1506, 1506, 1506, 1504, 0, 1497, 1497, - 1497, 1497, 1497, 1497, 1498, 1498, 1498, 1498, 1498, 1498, - 1502, 1499, 1499, 1499, 1499, 1499, 1499, 1500, 1500, 1500, - 1500, 1500, 1500, 1503, 1505, 1505, 1505, 1935, 1936, 1506, - 0, 0, 1504, 1504, 1504, 1504, 1504, 1504, 1509, 1509, - 1509, 0, 1502, 1502, 1502, 1502, 1502, 1502, 0, 1508, - 1508, 1508, 1503, 0, 0, 0, 1935, 1936, 1506, 1510, - 1510, 1510, 1937, 1938, 1505, 1507, 1507, 1507, 1507, 1507, - 1507, 1515, 1515, 1515, 1510, 1503, 1503, 1503, 1503, 1503, - - 1503, 1506, 1506, 1506, 1506, 1506, 1506, 0, 0, 1508, - 0, 1937, 1938, 1505, 1516, 1516, 1516, 1519, 1519, 1519, - 1519, 1519, 1519, 1519, 1519, 1519, 1939, 1515, 0, 1521, - 1521, 1521, 1505, 1505, 1505, 1505, 1505, 1505, 1508, 1522, - 1522, 1522, 0, 0, 1623, 1516, 1509, 1509, 1509, 1509, - 1509, 1509, 1520, 1520, 1520, 1939, 1515, 1508, 1508, 1508, - 1508, 1508, 1508, 1521, 1523, 1523, 1523, 1510, 1510, 1510, - 1510, 1510, 1510, 1623, 1516, 1529, 1529, 1529, 0, 1515, - 1515, 1515, 1515, 1515, 1515, 0, 0, 0, 0, 1531, - 1531, 1531, 1521, 0, 1520, 1523, 1623, 1623, 1623, 1623, - - 1623, 1623, 1516, 1516, 1516, 1516, 1516, 1516, 1526, 1526, - 1526, 1526, 1526, 1526, 1526, 1526, 1526, 1521, 1521, 1521, - 1521, 1521, 1521, 1520, 1523, 0, 0, 1522, 1522, 1522, - 1522, 1522, 1522, 1527, 1527, 1527, 0, 0, 0, 0, - 1520, 1520, 1520, 1520, 1520, 1520, 1528, 1528, 1528, 0, - 0, 0, 1523, 1523, 1523, 1523, 1523, 1523, 0, 0, - 1527, 1940, 1941, 1529, 1529, 1529, 1529, 1529, 1529, 0, - 0, 1530, 1530, 1530, 1942, 1944, 1528, 1531, 1531, 1531, - 1531, 1531, 1531, 1945, 0, 0, 1532, 1532, 1532, 1527, - 1940, 1941, 1533, 1533, 1533, 0, 0, 0, 1530, 1534, - - 1534, 1534, 0, 1942, 1944, 1528, 1558, 1558, 1558, 0, - 0, 1532, 1945, 1535, 1535, 1535, 0, 0, 1947, 1533, - 0, 1527, 1527, 1527, 1527, 1527, 1527, 1530, 1535, 1559, - 1559, 1559, 0, 0, 1528, 1528, 1528, 1528, 1528, 1528, - 1532, 0, 1534, 1558, 1560, 1560, 1560, 1947, 1533, 1557, - 1557, 1557, 1557, 1557, 1557, 1557, 1557, 1557, 0, 1530, - 1530, 1530, 1530, 1530, 1530, 0, 0, 0, 1562, 1562, - 1562, 1534, 1558, 0, 1532, 1532, 1532, 1532, 1532, 1532, - 1533, 1533, 1533, 1533, 1533, 1533, 0, 1534, 1534, 1534, - 1534, 1534, 1534, 0, 1558, 1558, 1558, 1558, 1558, 1558, - - 1624, 1535, 1535, 1535, 1535, 1535, 1535, 1563, 1563, 1563, - 1562, 1580, 0, 1561, 1561, 1561, 0, 1559, 1559, 1559, - 1559, 1559, 1559, 0, 0, 1564, 1564, 1564, 0, 1624, - 0, 0, 1560, 1560, 1560, 1560, 1560, 1560, 1561, 1562, - 1564, 1566, 1566, 1566, 0, 1624, 1624, 1624, 1624, 1624, - 1624, 1565, 1565, 1565, 1948, 1949, 1562, 1562, 1562, 1562, - 1562, 1562, 1568, 1568, 1568, 0, 0, 1561, 1846, 1846, - 1846, 1846, 1846, 1846, 1567, 1567, 1567, 0, 1565, 1645, - 1645, 1645, 1574, 1948, 1949, 1580, 1580, 1580, 1580, 1580, - 1580, 1568, 1950, 1574, 1645, 1563, 1563, 1563, 1563, 1563, - - 1563, 1561, 1561, 1561, 1561, 1561, 1561, 1565, 1567, 1655, - 1655, 1655, 0, 1564, 1564, 1564, 1564, 1564, 1564, 1571, - 1568, 1950, 1574, 0, 1655, 0, 0, 0, 0, 1566, - 1566, 1566, 1566, 1566, 1566, 0, 1573, 1567, 0, 1565, - 1565, 1565, 1565, 1565, 1565, 0, 0, 0, 1571, 1573, - 1568, 1568, 1568, 1568, 1568, 1568, 1574, 1574, 1574, 1574, - 1574, 1574, 1567, 1567, 1567, 1567, 1567, 1567, 1579, 1645, - 1571, 1571, 1571, 1571, 1571, 1571, 1575, 1579, 1573, 1604, - 1951, 0, 1576, 1621, 1621, 1621, 1621, 1621, 1621, 1621, - 1621, 1621, 1963, 1575, 1964, 1576, 1965, 1966, 0, 1655, - - 0, 0, 1581, 0, 0, 1967, 1579, 1582, 1604, 1951, - 1573, 1573, 1573, 1573, 1573, 1573, 1578, 0, 0, 1581, - 1968, 1963, 1575, 1964, 1576, 1965, 1966, 1604, 1604, 1604, - 1604, 1604, 1604, 1578, 1967, 1969, 1582, 1996, 1578, 0, - 0, 0, 1579, 1579, 1579, 1579, 1579, 1579, 1581, 1968, - 1575, 1575, 1575, 1575, 1575, 1575, 1576, 1576, 1576, 1576, - 1576, 1576, 1578, 0, 1969, 0, 1996, 1578, 1582, 1582, - 1582, 1582, 1582, 1582, 1603, 1999, 1581, 1581, 1581, 1581, - 1581, 1581, 0, 1605, 1605, 1605, 2005, 0, 1605, 2012, - 1578, 1578, 1578, 1578, 1578, 1578, 1605, 1608, 1608, 1608, - - 0, 0, 1608, 1603, 1999, 1626, 2014, 1627, 0, 1605, - 1608, 1609, 1609, 1609, 0, 2005, 1609, 0, 2012, 2015, - 1612, 1612, 1612, 1608, 1609, 1612, 0, 1603, 1603, 1603, - 1603, 1603, 1603, 1612, 1626, 2014, 1627, 1609, 1605, 0, - 0, 1631, 2020, 1628, 0, 2027, 1612, 2028, 2015, 2029, - 1633, 0, 1608, 1626, 1626, 1626, 1626, 1626, 1626, 1627, - 1627, 1627, 1627, 1627, 1627, 0, 1609, 1637, 1637, 1637, - 1631, 2020, 1628, 1605, 2027, 1612, 2028, 0, 2029, 1633, - 1638, 1638, 1638, 0, 0, 2032, 1714, 1608, 1628, 1628, - 1628, 1628, 1628, 1628, 1631, 1631, 1631, 1631, 1631, 1631, - - 0, 1609, 1633, 1633, 1633, 1633, 1633, 1633, 0, 0, - 1612, 1614, 1614, 1614, 2032, 1714, 1614, 0, 0, 1897, - 1897, 1897, 1638, 0, 1614, 1636, 1636, 1636, 1636, 1636, - 1636, 1636, 1636, 1636, 1639, 1639, 1639, 1614, 1714, 1714, - 1714, 1714, 1714, 1714, 0, 1640, 1640, 1640, 2034, 1897, - 0, 1638, 1641, 1641, 1641, 1637, 1637, 1637, 1637, 1637, - 1637, 1642, 1642, 1642, 0, 0, 1614, 0, 1638, 1638, - 1638, 1638, 1638, 1638, 0, 0, 1640, 2034, 1897, 1641, - 1643, 1643, 1643, 2035, 1642, 2036, 1644, 1644, 1644, 2037, - 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 1614, 0, - - 2038, 1614, 1615, 1615, 1615, 1640, 0, 1615, 1641, 1897, - 2039, 0, 2035, 1642, 2036, 1615, 0, 0, 2037, 1649, - 1649, 1649, 1639, 1639, 1639, 1639, 1639, 1639, 1615, 2038, - 0, 0, 0, 1640, 1640, 1640, 1640, 1640, 1640, 2039, - 1641, 1641, 1641, 1641, 1641, 1641, 1650, 1650, 1650, 1642, - 1642, 1642, 1642, 1642, 1642, 0, 0, 1615, 1647, 1647, - 1647, 1647, 1647, 1647, 1647, 1647, 1647, 2040, 1643, 1643, - 1643, 1643, 1643, 1643, 1644, 1644, 1644, 1644, 1644, 1644, - 0, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, 1615, - 0, 0, 1615, 1616, 1616, 1616, 2040, 0, 1616, 0, - - 0, 0, 1648, 1648, 1648, 0, 1616, 1649, 1649, 1649, - 1649, 1649, 1649, 0, 0, 1651, 1651, 1651, 0, 1616, - 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1648, - 1652, 1652, 1652, 2043, 1650, 1650, 1650, 1650, 1650, 1650, - 1651, 1666, 1666, 1666, 0, 2041, 2041, 2041, 1616, 1665, - 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1665, 1648, 1653, - 1653, 1653, 2043, 0, 0, 0, 0, 1652, 0, 1651, - 0, 0, 1616, 1616, 1616, 1616, 1616, 1616, 1616, 1616, - 1616, 0, 1653, 1616, 1617, 1617, 1617, 0, 0, 1617, - 1648, 1648, 1648, 1648, 1648, 1648, 1652, 1617, 2044, 1707, - - 1707, 1707, 0, 1651, 1651, 1651, 1651, 1651, 1651, 0, - 1617, 1653, 2045, 2046, 1707, 1661, 1661, 1661, 1652, 1652, - 1652, 1652, 1652, 1652, 1654, 1654, 1654, 2044, 0, 1666, - 1666, 1666, 1666, 1666, 1666, 2041, 1662, 1662, 1662, 1617, - 0, 2045, 2046, 1667, 1667, 1667, 0, 1653, 1653, 1653, - 1653, 1653, 1653, 2047, 2048, 1654, 1661, 1668, 1668, 1668, - 0, 2049, 2050, 1617, 1617, 1617, 1617, 1617, 1617, 1617, - 1617, 1617, 0, 1662, 1617, 1618, 1618, 1618, 0, 0, - 1618, 0, 2047, 2048, 1654, 1661, 0, 0, 1618, 1707, - 2049, 2050, 2053, 2054, 1668, 1671, 1671, 1671, 0, 0, - - 0, 1618, 1662, 1661, 1661, 1661, 1661, 1661, 1661, 1672, - 1672, 1672, 1654, 1654, 1654, 1654, 1654, 1654, 1674, 1674, - 1674, 2053, 2054, 1668, 1662, 1662, 1662, 1662, 1662, 1662, - 1618, 1667, 1667, 1667, 1667, 1667, 1667, 1673, 1673, 1673, - 2055, 2057, 0, 0, 0, 1668, 1668, 1668, 1668, 1668, - 1668, 1674, 1673, 2058, 1618, 1618, 1618, 1618, 1618, 1618, - 1618, 1618, 1618, 0, 2059, 1618, 1619, 1619, 1619, 2055, - 2057, 1619, 1675, 1675, 1675, 0, 1794, 1794, 1794, 1619, - 1674, 0, 2058, 1671, 1671, 1671, 1671, 1671, 1671, 0, - 2063, 1794, 1619, 2059, 2070, 2073, 0, 1672, 1672, 1672, - - 1672, 1672, 1672, 1676, 1676, 1676, 1674, 1674, 1674, 1674, - 1674, 1674, 2074, 0, 2076, 2080, 1677, 1677, 1677, 2063, - 0, 1619, 0, 2070, 2073, 1673, 1673, 1673, 1673, 1673, - 1673, 1677, 1710, 1710, 1710, 0, 0, 0, 1677, 1676, - 2093, 2074, 1677, 2076, 2080, 1619, 1619, 1619, 1619, 1619, - 1619, 1619, 1619, 1619, 1677, 0, 1619, 1704, 1704, 1704, - 1675, 1675, 1675, 1675, 1675, 1675, 1794, 0, 1676, 2093, - 0, 1677, 1679, 1679, 1679, 1679, 1679, 1679, 1679, 1679, - 1679, 0, 0, 1677, 1705, 1705, 1705, 1758, 1910, 1910, - 1910, 1676, 1676, 1676, 1676, 1676, 1676, 0, 0, 1704, - - 1706, 1706, 1706, 1910, 1713, 1716, 1677, 1709, 1709, 1709, - 1709, 1709, 1709, 1709, 1709, 1709, 1758, 1712, 1712, 1712, - 1710, 1710, 1710, 1710, 1710, 1710, 1705, 1706, 1704, 0, - 1711, 1711, 1711, 1713, 1758, 1758, 1758, 1758, 1758, 1758, - 0, 1716, 2101, 0, 0, 1704, 1704, 1704, 1704, 1704, - 1704, 0, 0, 0, 0, 1705, 1706, 1711, 1712, 1715, - 0, 1713, 1713, 1713, 1713, 1713, 1713, 1718, 1905, 1905, - 1905, 2101, 1705, 1705, 1705, 1705, 1705, 1705, 1910, 1716, - 1716, 1716, 1716, 1716, 1716, 1715, 1711, 1712, 1706, 1706, - 1706, 1706, 1706, 1706, 0, 1911, 1911, 1911, 1905, 1717, - - 1718, 0, 2106, 2108, 0, 1712, 1712, 1712, 1712, 1712, - 1712, 1717, 1719, 0, 1715, 0, 0, 0, 1711, 1711, - 1711, 1711, 1711, 1711, 1719, 1911, 1739, 1905, 0, 1718, - 1720, 2106, 2108, 1715, 1715, 1715, 1715, 1715, 1715, 1720, - 1717, 1718, 1718, 1718, 1718, 1718, 1718, 0, 0, 0, - 0, 1721, 0, 1719, 1911, 1739, 0, 1722, 1905, 2130, - 2130, 2130, 0, 1721, 2109, 2113, 1740, 2116, 1720, 1722, - 1723, 2118, 2119, 1717, 1717, 1717, 1717, 1717, 1717, 1739, - 1739, 1739, 1739, 1739, 1739, 1911, 1719, 1719, 1719, 1719, - 1719, 1719, 1721, 2109, 2113, 1740, 2116, 0, 1722, 1723, - - 2118, 2119, 0, 0, 1720, 1720, 1720, 1720, 1720, 1720, - 0, 1723, 1723, 1723, 1723, 1723, 1723, 1740, 1740, 1740, - 1740, 1740, 1740, 0, 0, 1721, 1721, 1721, 1721, 1721, - 1721, 1722, 1722, 1722, 1722, 1722, 1722, 1741, 1741, 1741, - 0, 2120, 1741, 1742, 1742, 1742, 0, 0, 1742, 2130, - 1741, 2123, 1743, 1743, 1743, 1882, 1742, 1743, 0, 1746, - 1746, 1746, 0, 1741, 1746, 1743, 1759, 0, 2125, 1742, - 2120, 0, 1746, 0, 1753, 1753, 1753, 0, 1743, 1753, - 2123, 2098, 0, 0, 1882, 1746, 1742, 1753, 0, 1776, - 1776, 1776, 1741, 0, 0, 1759, 2098, 2125, 1742, 2126, - - 1753, 1882, 1882, 1882, 1882, 1882, 1882, 1743, 0, 0, - 2098, 1756, 1756, 1756, 1746, 1742, 1756, 1760, 1759, 1759, - 1759, 1759, 1759, 1759, 1756, 2098, 0, 1741, 2126, 1753, - 0, 1743, 0, 1742, 0, 0, 1761, 1756, 1762, 0, - 0, 0, 1743, 0, 0, 2127, 1760, 0, 0, 1746, - 1748, 1748, 1748, 1753, 1753, 1748, 0, 1753, 0, 1753, - 1753, 1753, 0, 1748, 1753, 1761, 1756, 1762, 1760, 1760, - 1760, 1760, 1760, 1760, 2127, 2128, 1748, 1776, 1776, 1776, - 1776, 1776, 1776, 1761, 1761, 1761, 1761, 1761, 1761, 0, - 1762, 1762, 1762, 1762, 1762, 1762, 1769, 1769, 1769, 2129, - - 0, 1756, 0, 0, 2128, 1748, 0, 1997, 1997, 1997, - 1770, 1770, 1770, 0, 0, 1765, 2134, 1771, 1771, 1771, - 0, 1997, 0, 1769, 1772, 1772, 1772, 0, 2129, 1748, - 1748, 1748, 1748, 1748, 1748, 1748, 1748, 1748, 0, 0, - 1748, 1749, 1749, 1749, 1765, 2134, 1749, 1770, 2136, 2003, - 2003, 2003, 1769, 1771, 1749, 1775, 1775, 1775, 1775, 1775, - 1775, 1775, 1775, 1775, 2003, 2138, 1772, 1749, 1765, 1765, - 1765, 1765, 1765, 1765, 1840, 2139, 1770, 2136, 1777, 1777, - 1777, 0, 1771, 0, 1769, 1769, 1769, 1769, 1769, 1769, - 1778, 1778, 1778, 0, 2138, 1772, 1749, 1997, 1770, 1770, - - 1770, 1770, 1770, 1770, 2139, 1771, 1771, 1771, 1771, 1771, - 1771, 1777, 1772, 1772, 1772, 1772, 1772, 1772, 2141, 0, - 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 1749, 0, - 2142, 1749, 1750, 1750, 1750, 1778, 2143, 1750, 0, 2003, - 1777, 1779, 1779, 1779, 0, 1750, 0, 2141, 1840, 1840, - 1840, 1840, 1840, 1840, 1780, 1780, 1780, 0, 1750, 2142, - 2145, 2146, 0, 0, 1778, 2143, 1777, 1777, 1777, 1777, - 1777, 1777, 0, 2010, 2010, 2010, 1779, 2147, 1778, 1778, - 1778, 1778, 1778, 1778, 1797, 1797, 1797, 1750, 2010, 2145, - 2146, 1780, 1783, 1783, 1783, 1783, 1783, 1783, 1783, 1783, - - 1783, 1787, 1787, 1787, 0, 1779, 2147, 0, 1786, 1786, - 1786, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750, - 1780, 0, 1750, 1751, 1751, 1751, 0, 0, 1751, 1779, - 1779, 1779, 1779, 1779, 1779, 1786, 1751, 2149, 0, 0, - 0, 1787, 1780, 1780, 1780, 1780, 1780, 1780, 0, 1751, - 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1796, 1792, - 1792, 1792, 0, 2010, 1786, 0, 2149, 1828, 1828, 1828, - 1787, 0, 1797, 1797, 1797, 1797, 1797, 1797, 1751, 0, - 2131, 2131, 2131, 1798, 1798, 1798, 0, 0, 1836, 1787, - 1787, 1787, 1787, 1787, 1787, 1792, 1786, 1786, 1786, 1786, - - 1786, 1786, 1751, 1751, 1751, 1751, 1751, 1751, 1751, 1751, - 1751, 0, 0, 1751, 1752, 1752, 1752, 1836, 0, 1752, - 0, 2137, 2137, 2137, 1792, 1798, 0, 1752, 1804, 1804, - 1804, 1804, 1804, 1804, 1804, 1804, 1804, 1830, 1830, 1830, - 1752, 1836, 1836, 1836, 1836, 1836, 1836, 1792, 1792, 1792, - 1792, 1792, 1792, 0, 1798, 1828, 1828, 1828, 1828, 1828, - 1828, 1829, 1829, 1829, 0, 2095, 2095, 2095, 0, 1752, - 2131, 1798, 1798, 1798, 1798, 1798, 1798, 1833, 1833, 1833, - 1833, 1833, 1833, 1833, 1833, 1833, 0, 2150, 2095, 1835, - 1835, 1835, 1829, 1752, 1752, 1752, 1752, 1752, 1752, 1752, - - 1752, 1752, 0, 2151, 1752, 1754, 1754, 1754, 0, 0, - 1754, 2137, 2148, 2154, 1837, 2148, 2150, 2095, 1754, 2155, - 0, 1829, 0, 0, 0, 1830, 1830, 1830, 1830, 1830, - 1830, 1754, 2151, 0, 0, 1834, 1834, 1834, 1838, 2156, - 2158, 2148, 2154, 1837, 2148, 0, 2162, 0, 2155, 1829, - 1829, 1829, 1829, 1829, 1829, 2095, 1839, 2018, 2018, 2018, - 1754, 1837, 1837, 1837, 1837, 1837, 1837, 1841, 2156, 2158, - 2167, 2169, 2018, 1839, 1838, 2162, 1834, 1835, 1835, 1835, - 1835, 1835, 1835, 1842, 1754, 1754, 1754, 1754, 1754, 1754, - 1754, 1754, 1754, 0, 0, 1754, 1755, 1755, 1755, 2167, - - 2169, 1755, 1839, 0, 0, 1834, 0, 0, 2170, 1755, - 0, 2152, 1838, 1838, 1838, 1838, 1838, 1838, 1843, 2172, - 2173, 2152, 1755, 1834, 1834, 1834, 1834, 1834, 1834, 1844, - 1839, 1839, 1839, 1839, 1839, 1839, 1845, 2170, 0, 1843, - 2152, 1841, 1841, 1841, 1841, 1841, 1841, 2018, 2172, 2173, - 2152, 1755, 2030, 2030, 2030, 2176, 2184, 1842, 1842, 1842, - 1842, 1842, 1842, 0, 0, 0, 0, 2030, 1843, 1862, - 2186, 2192, 2193, 1863, 0, 1755, 1755, 1755, 1755, 1755, - 1755, 1755, 1755, 1755, 2176, 2184, 1755, 0, 0, 2177, - 2177, 2177, 1843, 1843, 1843, 1843, 1843, 1843, 1862, 2186, - - 2192, 2193, 1863, 1844, 1844, 1844, 1844, 1844, 1844, 2177, - 1845, 1845, 1845, 1845, 1845, 1845, 1863, 1863, 1863, 1863, - 1863, 1863, 0, 1926, 1926, 1926, 1862, 1862, 1862, 1862, - 1862, 1862, 1864, 1864, 1864, 0, 0, 1864, 1865, 1865, - 1865, 0, 2030, 1865, 0, 1864, 0, 1867, 1867, 1867, - 0, 1865, 1867, 1926, 2195, 1864, 2198, 2199, 1864, 0, - 1867, 2200, 0, 2206, 1865, 1868, 1868, 1868, 0, 2208, - 1868, 0, 0, 1867, 2209, 1869, 1869, 1869, 1868, 2177, - 1869, 0, 1926, 2195, 1864, 2198, 2199, 1864, 1869, 0, - 2200, 1868, 2206, 1865, 2212, 1874, 1874, 1874, 2208, 0, - - 1874, 1869, 1867, 2209, 0, 1875, 1875, 1875, 1874, 0, - 1875, 0, 0, 1926, 1876, 1876, 1876, 1865, 1875, 1876, - 1868, 1874, 1864, 2212, 2061, 2061, 2061, 1876, 1865, 2213, - 1869, 1875, 2214, 1877, 1877, 1877, 0, 1867, 1877, 2061, - 1876, 2178, 2178, 2178, 0, 0, 1877, 1881, 0, 2215, - 1874, 1879, 1879, 1879, 1869, 1868, 1879, 2178, 2213, 1877, - 1875, 2214, 0, 0, 1879, 1869, 1873, 1873, 1873, 1876, - 2217, 1873, 1884, 2077, 2077, 2077, 1881, 1879, 2215, 1873, - 0, 0, 0, 0, 0, 1874, 0, 2077, 1877, 1878, - 1878, 1878, 1873, 2222, 1878, 1875, 0, 2224, 2228, 2217, - - 2230, 1884, 1878, 0, 1876, 0, 1879, 0, 1881, 1881, - 1881, 1881, 1881, 1881, 2061, 1878, 0, 0, 2203, 2203, - 2203, 1873, 2222, 1877, 0, 1883, 2224, 2228, 1888, 2230, - 1879, 2178, 1878, 1884, 1884, 1884, 1884, 1884, 1884, 0, - 0, 1879, 0, 0, 1878, 1873, 1873, 1873, 1873, 1873, - 1873, 1873, 1873, 1873, 1883, 1885, 1873, 1888, 1890, 1890, - 1890, 1878, 0, 2077, 1891, 1891, 1891, 0, 1883, 1883, - 1883, 1883, 1883, 1883, 1892, 1892, 1892, 0, 0, 1878, - 1893, 1893, 1893, 0, 1885, 1888, 1888, 1888, 1888, 1888, - 1888, 1898, 1898, 1898, 1992, 1992, 1992, 1992, 1992, 1992, - - 1891, 1885, 1885, 1885, 1885, 1885, 1885, 1893, 2203, 0, - 1914, 1914, 1914, 0, 0, 0, 1892, 1899, 1899, 1899, - 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1918, 1891, - 0, 2231, 1900, 1900, 1900, 0, 1893, 2218, 2218, 2218, - 0, 0, 1919, 1919, 1919, 1892, 1890, 1890, 1890, 1890, - 1890, 1890, 1891, 1891, 1891, 1891, 1891, 1891, 1899, 1900, - 2231, 0, 1892, 1892, 1892, 1892, 1892, 1892, 1893, 1893, - 1893, 1893, 1893, 1893, 1901, 1901, 1901, 0, 0, 1898, - 1898, 1898, 1898, 1898, 1898, 0, 0, 1899, 1900, 1908, - 1908, 1908, 0, 0, 0, 1909, 1909, 1909, 1914, 1914, - - 1914, 1914, 1914, 1914, 0, 1899, 1899, 1899, 1899, 1899, - 1899, 1956, 1956, 1956, 1901, 1957, 1957, 1957, 0, 0, - 1900, 1900, 1900, 1900, 1900, 1900, 1909, 2218, 1958, 1908, - 1919, 1919, 1919, 1919, 1919, 1919, 1952, 1952, 1952, 0, - 0, 1956, 1960, 1901, 1995, 1995, 1995, 1995, 1995, 1995, - 0, 0, 2189, 2189, 2189, 1909, 1961, 1958, 1908, 2000, - 2000, 2000, 1901, 1901, 1901, 1901, 1901, 1901, 1961, 1960, - 1956, 2233, 2189, 1952, 2220, 2220, 2220, 1908, 1908, 1908, - 1908, 1908, 1908, 1909, 1909, 1909, 1909, 1909, 1909, 1958, - 1958, 1958, 1958, 1958, 1958, 0, 0, 1961, 1960, 1962, - - 2233, 1956, 1952, 1957, 1957, 1957, 1957, 1957, 1957, 1959, - 1972, 2234, 1962, 2004, 2004, 2004, 1960, 1960, 1960, 1960, - 1960, 1960, 0, 0, 1952, 1952, 1952, 1952, 1952, 1952, - 1961, 1961, 1961, 1961, 1961, 1961, 1973, 0, 1959, 1972, - 2234, 1962, 2189, 2004, 0, 0, 0, 2000, 2000, 2000, - 2000, 2000, 2000, 2235, 0, 0, 1972, 1972, 1972, 1972, - 1972, 1972, 0, 2236, 2220, 1973, 1959, 1959, 1959, 1959, - 1959, 1959, 2004, 1962, 1962, 1962, 1962, 1962, 1962, 0, - 0, 2237, 2235, 1973, 1973, 1973, 1973, 1973, 1973, 1974, - 1974, 1974, 2236, 2238, 1974, 1976, 1976, 1976, 0, 0, - - 1976, 0, 1974, 2004, 1977, 1977, 1977, 0, 1976, 1977, - 2237, 1978, 1978, 1978, 0, 1974, 1978, 1977, 0, 2239, - 2240, 1976, 2238, 1974, 1978, 0, 0, 1979, 1979, 1979, - 1977, 0, 1979, 2241, 1980, 1980, 1980, 1978, 0, 1980, - 1979, 1981, 1981, 1981, 1974, 2243, 1981, 1980, 2239, 2240, - 1976, 2244, 1974, 1979, 1981, 2223, 2223, 2223, 0, 1977, - 1980, 2245, 2241, 2011, 2011, 2011, 1978, 1981, 2026, 2026, - 2026, 1982, 1982, 1982, 2243, 0, 1982, 1980, 0, 1974, - 2244, 0, 1979, 0, 1982, 1976, 1984, 1984, 1984, 1980, - 2245, 1984, 0, 2011, 1977, 0, 1981, 1982, 2026, 1984, - - 2246, 1978, 1985, 1985, 1985, 0, 1980, 1985, 1986, 1986, - 1986, 0, 1984, 1986, 0, 1985, 0, 1979, 0, 0, - 1981, 1986, 2011, 0, 1980, 0, 1982, 2026, 1985, 2246, - 0, 1981, 0, 2249, 1986, 0, 1991, 2253, 1987, 1987, - 1987, 1984, 0, 1987, 0, 2223, 2256, 1988, 1988, 1988, - 1982, 1987, 1988, 2011, 1989, 1989, 1989, 1985, 2026, 1989, - 1988, 1982, 2249, 1986, 1987, 1991, 2253, 1989, 2259, 1990, - 1990, 1990, 0, 1988, 1990, 2256, 1984, 1989, 0, 2269, - 1989, 1985, 1990, 1993, 1991, 1991, 1991, 1991, 1991, 1991, - 1994, 0, 1985, 1987, 2276, 1990, 2277, 2259, 1986, 2001, - - 2001, 2001, 1988, 0, 0, 0, 1989, 1998, 2269, 1989, - 0, 0, 1993, 2002, 2002, 2002, 0, 1987, 0, 1994, - 2007, 2007, 2007, 2276, 1990, 2277, 0, 0, 1987, 0, - 1993, 1993, 1993, 1993, 1993, 1993, 1998, 1988, 1994, 1994, - 1994, 1994, 1994, 1994, 1989, 2008, 2008, 2008, 1990, 2190, - 2190, 2190, 2068, 1998, 1998, 1998, 1998, 1998, 1998, 1990, - 0, 0, 2009, 2009, 2009, 2190, 2031, 2031, 2031, 0, - 0, 0, 2016, 2016, 2016, 0, 0, 0, 2017, 2017, - 2017, 2082, 2082, 2082, 2082, 2082, 2082, 2001, 2001, 2001, - 2001, 2001, 2001, 2009, 2281, 2282, 2031, 0, 2278, 2278, - - 2278, 2002, 2002, 2002, 2002, 2002, 2002, 0, 2007, 2007, - 2007, 2007, 2007, 2007, 2016, 2069, 0, 2062, 2062, 2062, - 2017, 0, 2009, 2281, 2282, 2031, 2068, 2068, 2068, 2068, - 2068, 2068, 0, 2008, 2008, 2008, 2008, 2008, 2008, 2190, - 0, 0, 0, 2016, 2060, 2060, 2060, 2062, 2287, 2017, - 2009, 2009, 2009, 2009, 2009, 2009, 2031, 2051, 2051, 2051, - 2016, 2016, 2016, 2016, 2016, 2016, 2017, 2017, 2017, 2017, - 2017, 2017, 2066, 2288, 2289, 2290, 2062, 2287, 0, 2295, - 2060, 0, 2051, 2299, 2302, 2051, 2303, 2065, 2278, 2069, - 2069, 2069, 2069, 2069, 2069, 0, 2094, 2094, 2094, 2051, - - 0, 2066, 2288, 2289, 2290, 0, 0, 2062, 2295, 2060, - 2094, 2051, 2299, 2302, 2051, 2303, 2065, 2305, 0, 2066, - 2066, 2066, 2066, 2066, 2066, 2067, 2305, 0, 2051, 2081, - 2081, 2081, 2060, 2060, 2060, 2060, 2060, 2060, 2065, 2065, - 2065, 2065, 2065, 2065, 0, 2306, 2305, 2051, 2056, 2081, - 2307, 2308, 2309, 2067, 2056, 2078, 2078, 2078, 2056, 2056, - 0, 0, 0, 2056, 2056, 2056, 2310, 2056, 2091, 2091, - 2091, 2091, 2091, 2091, 2306, 0, 2312, 2056, 2078, 2307, - 2308, 2309, 2067, 2056, 2311, 2311, 2094, 2056, 2056, 2226, - 2226, 2226, 2056, 2056, 2056, 2310, 2056, 2078, 0, 2067, - - 2067, 2067, 2067, 2067, 2067, 2312, 0, 2078, 2313, 0, - 2083, 2083, 2083, 2311, 2311, 2083, 0, 2081, 2081, 2081, - 2081, 2081, 2081, 2083, 0, 0, 2078, 2084, 2084, 2084, - 0, 2226, 2084, 2085, 2085, 2085, 2083, 2313, 2085, 0, - 2084, 0, 2086, 2086, 2086, 2078, 2085, 2086, 0, 2087, - 2087, 2087, 0, 2084, 2087, 2086, 2085, 2315, 0, 2085, - 2226, 0, 2087, 0, 2090, 2083, 0, 2316, 2086, 2099, - 2099, 2099, 2104, 2104, 2104, 2087, 2088, 2088, 2088, 2226, - 2317, 2088, 2084, 0, 2099, 2085, 2315, 2104, 2085, 2088, - 2089, 2089, 2089, 2090, 0, 2089, 2316, 2086, 2318, 0, - - 2083, 2092, 2088, 2089, 2087, 2097, 2097, 2097, 2319, 2317, - 2090, 2090, 2090, 2090, 2090, 2090, 2089, 2084, 2103, 2103, - 2103, 2086, 0, 2085, 2089, 2097, 0, 2318, 2087, 0, - 2092, 2088, 2086, 2110, 2110, 2110, 0, 2319, 0, 2087, - 2111, 2111, 2111, 2326, 2327, 2089, 0, 2092, 2092, 2092, - 2092, 2092, 2092, 2089, 0, 2088, 2114, 2114, 2114, 2099, - 2103, 2182, 2104, 2121, 2121, 2121, 2088, 2160, 2160, 2160, - 0, 2114, 2326, 2327, 0, 2115, 2115, 2115, 2121, 0, - 2089, 0, 2160, 2110, 2159, 2159, 2159, 2111, 2328, 2103, - 2164, 0, 0, 2097, 2097, 2097, 2097, 2097, 2097, 2182, - - 2182, 2182, 2182, 2182, 2182, 2115, 2103, 2103, 2103, 2103, - 2103, 2103, 2153, 2165, 0, 2329, 2111, 2328, 2334, 2164, - 2153, 2110, 2110, 2110, 2110, 2110, 2110, 2153, 2111, 2111, - 2111, 2111, 2111, 2111, 2115, 2164, 2164, 2164, 2164, 2164, - 2164, 2153, 2165, 2166, 2329, 0, 2114, 2334, 0, 2153, - 2337, 2338, 2166, 2121, 0, 0, 2153, 2160, 0, 2165, - 2165, 2165, 2165, 2165, 2165, 2115, 2323, 2323, 2323, 2323, - 2323, 2323, 2159, 2159, 2159, 2159, 2159, 2159, 0, 2337, - 2338, 2166, 2171, 2171, 2171, 2179, 2179, 2179, 2179, 2179, - 2179, 2179, 2179, 2179, 2204, 2204, 2204, 2180, 2180, 2180, - - 0, 2183, 2180, 2343, 2344, 2171, 2185, 2185, 2185, 2204, - 2180, 0, 2196, 2196, 2196, 0, 2348, 2166, 2166, 2166, - 2166, 2166, 2166, 2180, 2171, 2181, 2181, 2181, 2251, 2185, - 2181, 2180, 2343, 2344, 2171, 2202, 2202, 2202, 2181, 2183, - 2183, 2183, 2183, 2183, 2183, 2348, 2201, 2201, 2201, 2349, - 2350, 2181, 2180, 2171, 2255, 2255, 2255, 2251, 2185, 2196, - 2180, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, 2191, - 2250, 0, 2171, 0, 2255, 0, 0, 2201, 2349, 2350, - 2181, 2353, 0, 2252, 2204, 2357, 0, 2180, 2196, 2251, - 2251, 2251, 2251, 2251, 2251, 0, 2185, 0, 0, 2250, - - 2196, 2196, 2196, 2196, 2196, 2196, 2201, 0, 0, 0, - 2353, 2252, 2266, 2358, 2357, 2181, 2250, 2250, 2250, 2250, - 2250, 2250, 0, 2202, 2202, 2202, 2202, 2202, 2202, 2261, - 2261, 2261, 0, 0, 2201, 2201, 2201, 2201, 2201, 2201, - 2252, 2266, 2358, 0, 2255, 2261, 2264, 2264, 2264, 2264, - 2264, 2264, 2264, 2264, 2264, 2267, 0, 2252, 2252, 2252, - 2252, 2252, 2252, 2265, 2265, 2265, 0, 0, 2265, 2266, - 2266, 2266, 2266, 2266, 2266, 0, 2265, 2268, 2268, 2268, - 2272, 2272, 2272, 0, 2267, 2279, 2279, 2279, 0, 2265, - 2280, 2280, 2280, 2284, 2284, 2284, 2272, 2268, 2275, 2275, - - 2275, 2275, 2275, 2275, 2275, 2275, 2275, 2283, 2283, 2283, - 0, 2361, 2267, 2267, 2267, 2267, 2267, 2267, 2265, 2261, - 2291, 2291, 2291, 2293, 2293, 2293, 2296, 2296, 2296, 2300, - 2300, 2300, 2324, 2283, 2322, 2322, 2322, 2293, 0, 2332, - 2361, 0, 2339, 2339, 2339, 2341, 2341, 2341, 0, 0, - 2363, 0, 2364, 2265, 0, 2345, 2345, 2345, 0, 0, - 0, 2324, 2283, 2325, 2333, 2366, 0, 2268, 2332, 0, - 2272, 0, 0, 2279, 2279, 2279, 2279, 2279, 2279, 2363, - 2280, 2364, 2367, 2284, 2324, 2324, 2324, 2324, 2324, 2324, - 0, 2368, 2325, 2333, 2366, 2283, 2283, 2283, 2283, 2283, - - 2283, 2332, 2332, 2332, 2332, 2332, 2332, 2347, 2347, 2347, - 2291, 2367, 0, 2293, 0, 0, 2296, 0, 0, 2300, - 2368, 2325, 0, 0, 2322, 0, 2333, 2333, 2333, 2333, - 2333, 2333, 2339, 2369, 2370, 2341, 2371, 2325, 2325, 2325, - 2325, 2325, 2325, 2345, 2345, 2345, 2345, 2345, 2345, 2351, - 2351, 2351, 2354, 2354, 2354, 2372, 2355, 2355, 2355, 2359, - 2359, 2359, 2369, 2370, 0, 2371, 2354, 2373, 0, 0, - 2375, 0, 2376, 2377, 2378, 2380, 2381, 2381, 2381, 2385, - 0, 2386, 2384, 2387, 2372, 2391, 2392, 2383, 2393, 2396, - 2397, 2402, 2404, 2355, 2406, 2407, 2373, 2347, 2355, 2375, - - 2359, 2376, 2377, 2378, 2380, 2398, 2398, 2398, 2385, 2384, - 2386, 2410, 2387, 0, 2391, 2392, 2383, 2393, 2396, 2397, - 2402, 2404, 2355, 2406, 2407, 0, 0, 2355, 0, 2359, - 2389, 2389, 2389, 2389, 2389, 2389, 2411, 0, 2384, 2351, - 2410, 0, 2354, 2405, 2405, 2405, 2355, 2412, 2414, 2359, - 2383, 2383, 2383, 2383, 2383, 2383, 2384, 2384, 2384, 2384, - 2384, 2384, 2415, 2416, 2417, 2411, 2381, 2390, 2390, 2390, - 2390, 2390, 2390, 2419, 2420, 2421, 2412, 2414, 2422, 2423, - 2405, 2424, 2425, 2426, 2428, 2405, 2431, 2432, 2434, 2435, - 2436, 2415, 2416, 2417, 2437, 2398, 2438, 2439, 2454, 2454, - - 2454, 0, 2419, 2420, 2421, 2440, 2442, 2422, 2423, 2405, - 2424, 2425, 2426, 2428, 2405, 2431, 2445, 2434, 2435, 2436, - 2446, 2450, 2451, 2437, 2452, 2438, 2439, 2431, 2431, 2431, - 2431, 2431, 2431, 2405, 2440, 2442, 0, 0, 2453, 2455, - 2456, 2458, 2460, 2462, 2464, 2445, 2465, 2467, 2468, 2446, - 2450, 2451, 2469, 2452, 2466, 2466, 2466, 2466, 2466, 2466, - 2471, 2432, 2432, 2432, 2432, 2432, 2432, 2453, 2455, 2456, - 2458, 2460, 2462, 2464, 2472, 2465, 2467, 2468, 2474, 2478, - 2479, 2469, 2480, 2481, 2482, 2483, 2485, 2489, 2454, 2471, - 2484, 2484, 2484, 2486, 2486, 2486, 2490, 2492, 2493, 2495, - - 2497, 2498, 2500, 2472, 2502, 2503, 2504, 2474, 2478, 2479, - 2505, 2480, 2481, 2482, 2483, 2485, 2489, 2506, 2506, 2506, - 2508, 2508, 2508, 2510, 2512, 2490, 2492, 2493, 2495, 2497, - 2498, 2500, 2514, 2502, 2503, 2504, 2516, 2517, 2518, 2505, - 2520, 2521, 2522, 2523, 2524, 2525, 2527, 2528, 2529, 2530, - 2531, 0, 2510, 2512, 0, 2532, 2533, 2574, 2574, 2574, - 2535, 2514, 2536, 2537, 2538, 2516, 2517, 2518, 2539, 2520, - 2521, 2522, 2523, 2524, 2525, 2527, 2528, 2529, 2530, 2531, - 2484, 0, 2540, 2486, 2532, 2533, 2534, 2534, 2534, 2535, - 2543, 2536, 2537, 2538, 2534, 2550, 2553, 2539, 2542, 2542, - - 2542, 2544, 2544, 2544, 2546, 2546, 2546, 2506, 2554, 2556, - 2508, 2540, 2546, 2557, 2562, 2563, 2564, 2565, 2542, 2543, - 2566, 2544, 2568, 2570, 2550, 2553, 2571, 2572, 2575, 2576, - 2577, 2578, 2579, 2579, 2579, 2581, 2583, 2554, 2556, 2582, - 2582, 2582, 2557, 2562, 2563, 2564, 2565, 2574, 2584, 2566, - 2587, 2568, 2570, 2589, 2590, 2571, 2572, 2575, 2576, 2577, - 2578, 2588, 2588, 2588, 2581, 2583, 2591, 0, 2592, 2593, - 2594, 2595, 2595, 2595, 0, 0, 2534, 2584, 2534, 2587, - 0, 0, 2589, 2590, 0, 0, 0, 0, 2542, 0, - 0, 2544, 0, 0, 2546, 2591, 2546, 2592, 2593, 2594, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2579, 0, 0, 0, 0, 0, 0, 2582, + 723, 723, 724, 724, 724, 724, 724, 724, 724, 724, + 724, 725, 726, 726, 726, 726, 726, 726, 726, 726, + 726, 728, 728, 728, 728, 728, 728, 728, 728, 728, + 729, 729, 729, 729, 729, 729, 729, 729, 729, 1011, + + 725, 730, 730, 730, 730, 730, 730, 730, 730, 730, + 732, 732, 732, 732, 732, 732, 732, 732, 732, 735, + 735, 735, 725, 725, 725, 725, 725, 725, 733, 733, + 733, 733, 733, 733, 733, 733, 733, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 740, 740, 740, 740, + 740, 740, 740, 740, 740, 741, 741, 741, 741, 741, + 741, 741, 741, 741, 742, 742, 742, 742, 742, 742, + 742, 742, 742, 743, 743, 743, 743, 743, 743, 743, + 743, 743, 744, 744, 744, 744, 744, 744, 744, 744, + 744, 746, 746, 746, 746, 746, 746, 746, 746, 746, + + 797, 797, 797, 797, 797, 797, 797, 797, 735, 738, + 738, 1403, 1010, 738, 738, 984, 980, 738, 738, 738, + 738, 738, 738, 738, 738, 738, 1403, 738, 738, 738, + 738, 738, 747, 747, 747, 747, 747, 747, 747, 747, + 747, 748, 748, 748, 748, 748, 748, 748, 748, 748, + 753, 753, 753, 919, 759, 1403, 759, 823, 738, 759, + 738, 749, 749, 749, 749, 749, 749, 749, 749, 749, + 750, 750, 750, 750, 750, 750, 750, 750, 750, 804, + 804, 804, 804, 804, 804, 804, 804, 738, 738, 738, + 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, + + 738, 738, 738, 751, 751, 751, 751, 751, 751, 751, + 751, 751, 758, 760, 758, 927, 927, 927, 927, 927, + 927, 767, 767, 761, 758, 767, 767, 767, 767, 767, + 759, 759, 759, 759, 759, 759, 816, 814, 787, 753, + 783, 778, 760, 762, 762, 762, 762, 762, 762, 762, + 762, 762, 761, 758, 763, 763, 763, 763, 763, 763, + 763, 763, 763, 776, 760, 760, 760, 760, 760, 760, + 761, 761, 761, 761, 761, 761, 764, 764, 764, 764, + 764, 764, 764, 764, 764, 758, 758, 758, 758, 758, + 758, 765, 765, 765, 765, 765, 765, 765, 765, 765, + + 766, 766, 766, 766, 766, 766, 766, 766, 766, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 770, 770, 770, + 773, 773, 773, 777, 777, 777, 780, 780, 780, 788, + 788, 788, 788, 788, 788, 788, 788, 788, 790, 790, + 790, 790, 790, 790, 790, 790, 790, 791, 791, 791, + 791, 791, 791, 791, 791, 791, 792, 792, 792, 792, + 792, 792, 792, 792, 792, 793, 793, 771, 754, 793, + 752, 793, 793, 793, 794, 794, 794, 794, 794, 794, + 794, 794, 794, 795, 795, 795, 795, 795, 795, 795, + + 795, 795, 796, 796, 796, 796, 796, 796, 796, 796, + 796, 736, 690, 687, 683, 650, 770, 643, 642, 773, + 641, 637, 777, 636, 634, 780, 798, 798, 798, 798, + 798, 798, 798, 798, 798, 799, 799, 799, 799, 799, + 799, 799, 799, 799, 800, 800, 800, 800, 800, 800, + 800, 800, 800, 801, 801, 630, 1405, 801, 629, 801, + 801, 801, 802, 802, 802, 802, 802, 802, 802, 802, + 802, 803, 803, 803, 803, 803, 803, 803, 803, 803, + 805, 805, 627, 623, 805, 1405, 805, 805, 805, 806, + 806, 806, 806, 806, 806, 806, 806, 806, 807, 807, + + 807, 807, 807, 807, 807, 807, 808, 808, 808, 808, + 808, 808, 808, 808, 808, 809, 809, 809, 809, 809, + 809, 809, 809, 809, 810, 810, 810, 810, 810, 810, + 810, 810, 810, 811, 811, 922, 824, 811, 824, 811, + 811, 811, 812, 812, 812, 812, 812, 812, 812, 812, + 812, 813, 813, 813, 813, 813, 813, 813, 813, 813, + 815, 815, 815, 822, 922, 822, 909, 909, 620, 825, + 909, 619, 909, 909, 909, 822, 1406, 826, 918, 918, + 616, 615, 918, 827, 918, 918, 918, 1407, 613, 826, + 600, 1320, 599, 1320, 828, 596, 922, 922, 922, 922, + + 922, 922, 827, 1320, 822, 1406, 595, 846, 592, 824, + 824, 824, 824, 824, 824, 591, 1407, 829, 826, 828, + 928, 928, 928, 928, 928, 928, 481, 831, 393, 391, + 359, 827, 1320, 829, 354, 831, 822, 822, 822, 822, + 822, 822, 825, 825, 825, 825, 825, 825, 828, 815, + 826, 826, 826, 826, 826, 826, 827, 827, 827, 827, + 827, 827, 829, 830, 831, 350, 345, 828, 828, 828, + 828, 828, 828, 341, 324, 321, 291, 832, 281, 830, + 846, 846, 846, 846, 846, 846, 833, 280, 278, 1408, + 829, 829, 829, 829, 829, 829, 832, 1012, 1012, 1012, + + 831, 831, 831, 831, 831, 831, 833, 835, 830, 904, + 904, 904, 904, 904, 904, 904, 904, 904, 1408, 256, + 254, 834, 1017, 1017, 1017, 832, 245, 1409, 835, 243, + 837, 232, 231, 225, 224, 833, 830, 830, 830, 830, + 830, 830, 834, 1022, 1022, 1022, 1346, 834, 1346, 837, + 832, 832, 832, 832, 832, 832, 1409, 835, 1346, 833, + 833, 833, 833, 833, 833, 836, 216, 215, 1035, 1035, + 1035, 834, 838, 836, 212, 211, 834, 195, 837, 194, + 835, 835, 835, 835, 835, 835, 1012, 1346, 188, 1451, + 840, 838, 187, 180, 834, 834, 834, 834, 834, 834, + + 840, 841, 836, 837, 837, 837, 837, 837, 837, 953, + 953, 1017, 179, 953, 839, 953, 953, 953, 1451, 111, + 838, 843, 839, 73, 841, 72, 839, 69, 59, 840, + 842, 843, 1022, 1452, 36, 35, 34, 844, 836, 836, + 836, 836, 836, 836, 1454, 838, 838, 838, 838, 838, + 838, 839, 842, 841, 845, 839, 844, 1035, 33, 0, + 843, 0, 1452, 840, 840, 840, 840, 840, 840, 0, + 0, 1456, 847, 1454, 841, 841, 841, 841, 841, 841, + 845, 842, 854, 0, 0, 844, 0, 839, 839, 839, + 839, 839, 839, 847, 843, 843, 843, 843, 843, 843, + + 1456, 0, 849, 842, 842, 842, 842, 842, 842, 845, + 844, 844, 844, 844, 844, 844, 848, 0, 1049, 1049, + 1049, 0, 847, 849, 0, 850, 0, 845, 845, 845, + 845, 845, 845, 961, 961, 1457, 848, 961, 851, 961, + 961, 961, 1458, 1460, 852, 847, 847, 847, 847, 847, + 847, 853, 849, 850, 851, 854, 854, 854, 854, 854, + 854, 0, 0, 0, 1457, 848, 853, 852, 0, 856, + 0, 1458, 1460, 0, 0, 849, 849, 849, 849, 849, + 849, 856, 850, 851, 855, 0, 0, 0, 0, 848, + 848, 848, 848, 848, 848, 853, 852, 857, 850, 850, + + 850, 850, 850, 850, 0, 0, 855, 1049, 0, 857, + 856, 851, 851, 851, 851, 851, 851, 852, 852, 852, + 852, 852, 852, 860, 853, 853, 853, 853, 853, 853, + 858, 0, 0, 971, 971, 855, 859, 971, 857, 971, + 971, 971, 856, 856, 856, 856, 856, 856, 0, 1462, + 860, 861, 858, 1463, 1464, 859, 1465, 855, 855, 855, + 855, 855, 855, 861, 0, 1484, 0, 863, 0, 0, + 857, 857, 857, 857, 857, 857, 0, 862, 1462, 860, + 0, 858, 1463, 1464, 859, 1465, 1065, 1065, 1065, 865, + 0, 0, 861, 862, 1484, 866, 860, 860, 860, 860, + + 860, 860, 863, 858, 858, 858, 858, 858, 858, 859, + 859, 859, 859, 859, 859, 0, 864, 865, 866, 1092, + 1092, 1092, 862, 867, 861, 861, 861, 861, 861, 861, + 864, 905, 905, 905, 905, 905, 905, 905, 905, 0, + 863, 863, 863, 863, 863, 863, 865, 866, 868, 867, + 862, 862, 862, 862, 862, 862, 870, 0, 1485, 864, + 0, 0, 865, 865, 865, 865, 865, 865, 866, 866, + 866, 866, 866, 866, 869, 1065, 1496, 1538, 867, 0, + 868, 1539, 1551, 870, 872, 1568, 869, 1485, 1569, 864, + 864, 864, 864, 864, 864, 0, 867, 867, 867, 867, + + 867, 867, 871, 0, 0, 1496, 1538, 872, 1092, 868, + 1539, 1551, 870, 873, 1568, 869, 871, 1569, 0, 874, + 0, 868, 868, 868, 868, 868, 868, 873, 875, 870, + 870, 870, 870, 870, 870, 878, 872, 0, 875, 1570, + 1571, 1573, 876, 878, 874, 871, 0, 869, 869, 869, + 869, 869, 869, 876, 1576, 1578, 873, 872, 872, 872, + 872, 872, 872, 0, 0, 0, 879, 875, 1570, 1571, + 1573, 1579, 878, 874, 877, 871, 871, 871, 871, 871, + 871, 0, 876, 1576, 1578, 879, 873, 873, 873, 873, + 873, 873, 874, 874, 874, 874, 874, 874, 920, 877, + + 1579, 875, 875, 875, 875, 875, 875, 881, 878, 878, + 878, 878, 878, 878, 879, 876, 876, 876, 876, 876, + 876, 880, 0, 0, 0, 0, 0, 882, 877, 881, + 0, 0, 0, 880, 883, 1108, 1108, 1108, 0, 879, + 879, 879, 879, 879, 879, 885, 882, 877, 877, 877, + 877, 877, 877, 884, 886, 886, 886, 885, 881, 1030, + 1030, 883, 880, 1030, 1581, 1030, 1030, 1030, 886, 920, + 920, 920, 920, 920, 920, 882, 887, 0, 0, 0, + 881, 881, 881, 881, 881, 881, 885, 1582, 884, 0, + 883, 0, 0, 1581, 880, 880, 880, 880, 880, 880, + + 882, 882, 882, 882, 882, 882, 887, 883, 883, 883, + 883, 883, 883, 888, 0, 0, 1582, 0, 885, 885, + 885, 885, 885, 885, 1108, 0, 884, 884, 884, 884, + 884, 884, 1583, 964, 1584, 887, 888, 0, 0, 889, + 0, 886, 886, 886, 886, 886, 886, 1585, 890, 887, + 887, 887, 887, 887, 887, 0, 891, 0, 0, 0, + 0, 1583, 964, 1584, 889, 888, 889, 890, 891, 895, + 974, 974, 974, 974, 974, 974, 1585, 895, 893, 964, + 964, 964, 964, 964, 964, 894, 888, 888, 888, 888, + 888, 888, 897, 889, 0, 889, 890, 891, 892, 893, + + 975, 975, 975, 975, 975, 975, 895, 894, 892, 894, + 896, 0, 889, 889, 889, 889, 889, 889, 0, 892, + 912, 890, 890, 890, 890, 890, 890, 0, 893, 891, + 891, 891, 891, 891, 891, 896, 894, 892, 894, 1112, + 1112, 1112, 895, 895, 895, 895, 895, 895, 892, 899, + 0, 893, 893, 893, 893, 893, 893, 898, 894, 894, + 894, 894, 894, 894, 896, 897, 897, 897, 897, 897, + 897, 892, 892, 892, 892, 892, 892, 899, 898, 901, + 0, 0, 0, 896, 896, 896, 896, 896, 896, 0, + 0, 1586, 900, 912, 912, 912, 912, 912, 912, 0, + + 901, 0, 0, 903, 0, 0, 899, 898, 900, 906, + 906, 906, 906, 906, 906, 906, 906, 906, 903, 921, + 1586, 902, 899, 899, 899, 899, 899, 899, 1112, 901, + 898, 898, 898, 898, 898, 898, 0, 900, 0, 0, + 0, 0, 902, 1588, 1619, 1620, 902, 903, 921, 0, + 0, 0, 901, 901, 901, 901, 901, 901, 913, 921, + 921, 921, 921, 921, 921, 900, 900, 900, 900, 900, + 900, 902, 1588, 1619, 1620, 902, 903, 903, 903, 903, + 903, 903, 907, 907, 907, 907, 907, 907, 907, 907, + 907, 0, 0, 0, 902, 902, 902, 902, 902, 902, + + 908, 908, 908, 908, 908, 908, 908, 908, 908, 910, + 910, 910, 910, 910, 910, 910, 910, 910, 911, 911, + 911, 911, 911, 911, 911, 911, 911, 923, 924, 0, + 925, 913, 913, 913, 913, 913, 913, 917, 917, 917, + 917, 917, 917, 917, 917, 917, 931, 931, 931, 931, + 931, 931, 931, 931, 931, 0, 923, 924, 926, 925, + 932, 932, 932, 932, 932, 932, 932, 932, 1130, 1130, + 1130, 0, 1621, 933, 0, 923, 923, 923, 923, 923, + 923, 925, 925, 925, 925, 925, 925, 926, 0, 934, + 924, 924, 924, 924, 924, 924, 933, 934, 935, 1034, + + 1034, 1621, 1625, 1034, 936, 1034, 1034, 1034, 0, 1627, + 0, 1580, 938, 926, 926, 926, 926, 926, 926, 937, + 0, 0, 937, 1580, 935, 933, 934, 1629, 0, 1060, + 1060, 1625, 936, 1060, 939, 1060, 1060, 1060, 1627, 938, + 1580, 941, 0, 0, 0, 0, 933, 933, 933, 933, + 933, 933, 1580, 935, 0, 941, 1629, 1130, 0, 945, + 0, 936, 934, 934, 934, 934, 934, 934, 938, 939, + 943, 935, 935, 935, 935, 935, 935, 936, 936, 936, + 936, 936, 936, 940, 941, 938, 938, 938, 938, 938, + 938, 944, 937, 937, 937, 937, 937, 937, 942, 0, + + 1630, 944, 940, 0, 946, 943, 0, 939, 939, 939, + 939, 939, 939, 1631, 941, 941, 941, 941, 941, 941, + 1064, 1064, 1632, 1634, 1064, 942, 1064, 1064, 1064, 1630, + 944, 940, 945, 945, 945, 945, 945, 945, 0, 0, + 0, 1638, 1631, 943, 943, 943, 943, 943, 943, 0, + 0, 1632, 1634, 0, 942, 0, 940, 940, 940, 940, + 940, 940, 0, 0, 944, 944, 944, 944, 944, 944, + 1638, 942, 942, 942, 942, 942, 942, 946, 946, 946, + 946, 946, 946, 947, 947, 947, 947, 947, 947, 947, + 947, 947, 948, 948, 948, 948, 948, 948, 948, 948, + + 948, 949, 949, 949, 949, 949, 949, 949, 949, 950, + 950, 950, 950, 950, 950, 950, 950, 950, 951, 951, + 951, 951, 951, 951, 951, 951, 951, 952, 952, 952, + 952, 952, 952, 952, 952, 952, 954, 954, 954, 954, + 954, 954, 954, 954, 954, 955, 955, 955, 955, 955, + 955, 955, 955, 955, 956, 956, 956, 956, 956, 956, + 956, 956, 956, 957, 957, 957, 957, 957, 957, 957, + 957, 958, 958, 958, 958, 958, 958, 958, 958, 958, + 959, 959, 959, 959, 959, 959, 959, 959, 959, 960, + 960, 960, 960, 960, 960, 960, 960, 960, 962, 962, + + 962, 962, 962, 962, 962, 962, 962, 963, 963, 963, + 963, 963, 963, 963, 963, 963, 965, 966, 966, 966, + 966, 966, 966, 966, 966, 966, 967, 967, 967, 967, + 967, 967, 967, 967, 968, 968, 968, 968, 968, 968, + 968, 968, 968, 0, 0, 965, 969, 969, 969, 969, + 969, 969, 969, 969, 969, 970, 970, 970, 970, 970, + 970, 970, 970, 970, 1044, 1044, 1044, 1044, 1044, 1044, + 965, 965, 965, 965, 965, 965, 972, 972, 972, 972, + 972, 972, 972, 972, 972, 973, 973, 973, 973, 973, + 973, 973, 973, 973, 976, 976, 976, 976, 976, 976, + + 976, 976, 976, 1025, 1025, 1025, 1025, 1025, 1025, 1025, + 1025, 1025, 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1026, + 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1028, + 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1028, 1029, 1029, + 1029, 1029, 1029, 1029, 1029, 1029, 1029, 1031, 1031, 1031, + 1031, 1031, 1031, 1031, 1031, 1031, 1032, 1032, 1032, 1032, + 1032, 1032, 1032, 1032, 1032, 1033, 1033, 1033, 1033, 1033, + 1033, 1033, 1033, 1039, 1041, 1043, 1639, 1642, 1040, 1045, + 1045, 1045, 1045, 1045, 1045, 1047, 1047, 1047, 1047, 1047, + 1047, 1047, 1047, 1047, 1056, 1056, 1056, 1056, 1056, 1056, + + 1056, 1056, 1039, 1041, 0, 1639, 1642, 1040, 1042, 0, + 0, 0, 0, 1043, 1043, 1043, 1043, 1043, 1043, 1070, + 1070, 1070, 1070, 1070, 1070, 1039, 1039, 1039, 1039, 1039, + 1039, 1040, 1040, 1040, 1040, 1040, 1040, 1042, 1041, 1041, + 1041, 1041, 1041, 1041, 1055, 1055, 1055, 1055, 1055, 1055, + 1055, 1055, 1055, 0, 1042, 1042, 1042, 1042, 1042, 1042, + 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1057, 1058, + 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1059, 1059, + 1059, 1059, 1059, 1059, 1059, 1059, 1059, 1061, 1061, 1061, + 1061, 1061, 1061, 1061, 1061, 1061, 1062, 1062, 1062, 1062, + + 1062, 1062, 1062, 1062, 1062, 1063, 1063, 1063, 1063, 1063, + 1063, 1063, 1063, 1067, 0, 0, 0, 1069, 1071, 1071, + 1071, 1071, 1071, 1071, 1075, 1068, 1074, 1074, 1074, 1074, + 1074, 1074, 1074, 1074, 1074, 1076, 1076, 1076, 1076, 1076, + 1076, 0, 1067, 1077, 1077, 1077, 1077, 1077, 1077, 1284, + 1284, 1284, 0, 1075, 1068, 1069, 1069, 1069, 1069, 1069, + 1069, 0, 0, 0, 0, 1067, 1067, 1067, 1067, 1067, + 1067, 1068, 1068, 1068, 1068, 1068, 1068, 1075, 1075, 1075, + 1075, 1075, 1075, 1078, 1078, 1078, 1078, 1078, 1078, 1078, + 1078, 1078, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, + + 1081, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1082, 1083, + 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1083, 1084, 1084, + 1084, 1084, 1084, 1084, 1084, 1084, 1084, 1085, 1085, 1085, + 1085, 1085, 1085, 1085, 1085, 1085, 1086, 1086, 1284, 0, + 1086, 0, 1086, 1086, 1086, 1087, 1087, 1087, 1087, 1087, + 1087, 1087, 1087, 1087, 1088, 1088, 1088, 1088, 1088, 1088, + 1088, 1088, 1088, 1089, 1089, 1089, 1089, 1089, 1089, 1089, + 1089, 1090, 1090, 0, 1099, 1090, 1099, 1090, 1090, 1090, + 1101, 0, 1101, 1274, 1274, 1274, 1099, 1102, 0, 0, + 1274, 0, 0, 1104, 0, 0, 1102, 1232, 1232, 1232, + + 1232, 1232, 1232, 1222, 1103, 0, 1119, 0, 0, 0, + 1105, 0, 1120, 0, 0, 1099, 1107, 1107, 1107, 1107, + 1107, 1107, 1107, 1107, 1107, 1102, 0, 0, 0, 0, + 1103, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, + 1222, 1222, 1222, 1222, 1222, 1222, 1649, 1099, 1099, 1099, + 1099, 1099, 1099, 1101, 1101, 1101, 1101, 1101, 1101, 1103, + 1102, 1102, 1102, 1102, 1102, 1102, 1104, 1104, 1104, 1104, + 1104, 1104, 1274, 1125, 1673, 1649, 0, 1103, 1103, 1103, + 1103, 1103, 1103, 1105, 1105, 1105, 1105, 1105, 1105, 1119, + 1119, 1119, 1119, 1119, 1119, 1120, 1120, 1120, 1120, 1120, + + 1120, 1122, 1122, 1673, 1697, 1122, 1122, 0, 0, 1122, + 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 0, 1122, + 1122, 1122, 1122, 1122, 1124, 1124, 1124, 1124, 1124, 1124, + 1124, 1124, 1124, 1697, 0, 1296, 1296, 1296, 1126, 1127, + 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1127, 0, 0, + 1122, 0, 1122, 1125, 1125, 1125, 1125, 1125, 1125, 0, + 1139, 0, 1139, 1201, 1201, 1201, 1201, 1201, 1201, 1201, + 1201, 1201, 1139, 0, 1278, 1278, 1278, 1140, 1278, 1122, + 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, + 1122, 1122, 1122, 1122, 1122, 1123, 1123, 1698, 1587, 1123, + + 1123, 1139, 1140, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + 1123, 1123, 1587, 1123, 1123, 1123, 1123, 1123, 1126, 1126, + 1126, 1126, 1126, 1126, 1296, 0, 1698, 1587, 1141, 1708, + 0, 1140, 0, 1139, 1139, 1139, 1139, 1139, 1139, 1143, + 0, 1587, 0, 1711, 1123, 1142, 1123, 0, 0, 0, + 1140, 1140, 1140, 1140, 1140, 1140, 1146, 1503, 1708, 1503, + 1141, 1142, 1577, 1278, 1716, 1577, 1143, 0, 0, 1503, + 1725, 1145, 1711, 1123, 1123, 1123, 1123, 1123, 1123, 1123, + 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1141, + 1142, 1577, 0, 1716, 1577, 1143, 1145, 1148, 1503, 1725, + + 0, 1141, 1141, 1141, 1141, 1141, 1141, 1144, 1726, 1148, + 1229, 0, 1143, 1143, 1143, 1143, 1143, 1143, 1142, 1142, + 1142, 1142, 1142, 1142, 1147, 1145, 0, 0, 1144, 1146, + 1146, 1146, 1146, 1146, 1146, 1150, 1147, 1726, 1148, 1229, + 1147, 0, 1149, 0, 1145, 1145, 1145, 1145, 1145, 1145, + 1151, 1229, 1229, 1229, 1229, 1229, 1229, 1144, 1149, 1152, + 0, 1727, 1150, 1728, 1729, 1147, 0, 1730, 1153, 1147, + 1148, 1148, 1148, 1148, 1148, 1148, 1153, 1151, 1152, 1157, + 1144, 1144, 1144, 1144, 1144, 1144, 0, 1149, 0, 1154, + 1727, 1150, 1728, 1729, 0, 1155, 1730, 1147, 1147, 1147, + + 1147, 1147, 1147, 0, 1156, 1153, 1151, 1152, 1150, 1150, + 1150, 1150, 1150, 1150, 0, 1149, 1149, 1149, 1149, 1149, + 1149, 1154, 1155, 1151, 1151, 1151, 1151, 1151, 1151, 1156, + 0, 1159, 1152, 1152, 1152, 1152, 1152, 1152, 0, 1160, + 0, 1153, 1153, 1153, 1153, 1153, 1153, 1160, 0, 1158, + 1154, 1155, 1157, 1157, 1157, 1157, 1157, 1157, 1156, 1159, + 1163, 0, 1154, 1154, 1154, 1154, 1154, 1154, 1155, 1155, + 1155, 1155, 1155, 1155, 1158, 1161, 1160, 1156, 1156, 1156, + 1156, 1156, 1156, 1164, 0, 0, 0, 0, 1159, 1162, + 1161, 0, 1276, 1276, 1276, 1165, 0, 0, 0, 1276, + + 1162, 1731, 1732, 1158, 1159, 1159, 1159, 1159, 1159, 1159, + 1164, 1167, 1160, 1160, 1160, 1160, 1160, 1160, 1165, 1161, + 1168, 0, 1158, 1158, 1158, 1158, 1158, 1158, 0, 1162, + 1731, 1732, 0, 1163, 1163, 1163, 1163, 1163, 1163, 1164, + 0, 0, 0, 1170, 1304, 1304, 1304, 1165, 1161, 1161, + 1161, 1161, 1161, 1161, 1166, 1168, 1164, 1164, 1164, 1164, + 1164, 1164, 1162, 1162, 1162, 1162, 1162, 1162, 1165, 1165, + 1165, 1165, 1165, 1165, 1170, 1166, 0, 0, 1733, 0, + 1169, 1276, 0, 1231, 1167, 1167, 1167, 1167, 1167, 1167, + 1171, 0, 0, 1168, 1168, 1168, 1168, 1168, 1168, 1172, + + 1173, 1173, 1173, 1170, 1166, 1169, 1174, 1733, 1223, 0, + 0, 1511, 1231, 1511, 1173, 1171, 1170, 1170, 1170, 1170, + 1170, 1170, 1175, 1511, 1317, 1317, 1317, 1166, 1166, 1166, + 1166, 1166, 1166, 1304, 1169, 1231, 1231, 1231, 1231, 1231, + 1231, 1174, 1734, 0, 1171, 1223, 1223, 1223, 1223, 1223, + 1223, 1176, 1511, 1169, 1169, 1169, 1169, 1169, 1169, 0, + 0, 0, 1177, 1171, 1171, 1171, 1171, 1171, 1171, 1182, + 0, 1734, 1172, 1172, 1172, 1172, 1172, 1172, 1176, 1174, + 1174, 1174, 1174, 1174, 1174, 1177, 0, 1173, 1173, 1173, + 1173, 1173, 1173, 1178, 1735, 1175, 1175, 1175, 1175, 1175, + + 1175, 1179, 1330, 1330, 1330, 1178, 0, 1176, 1180, 1336, + 1336, 1336, 1179, 1317, 1177, 1469, 1469, 1469, 0, 1181, + 0, 0, 1469, 1735, 1176, 1176, 1176, 1176, 1176, 1176, + 1180, 1181, 0, 1183, 1178, 1177, 1177, 1177, 1177, 1177, + 1177, 1179, 1182, 1182, 1182, 1182, 1182, 1182, 1185, 1185, + 1185, 0, 0, 0, 0, 0, 1184, 0, 1183, 1180, + 1181, 1666, 1185, 1666, 0, 0, 1178, 1178, 1178, 1178, + 1178, 1178, 1184, 1666, 1179, 1179, 1179, 1179, 1179, 1179, + 1186, 1180, 1180, 1180, 1180, 1180, 1180, 1183, 1186, 1188, + 0, 1330, 1181, 1181, 1181, 1181, 1181, 1181, 1336, 1736, + + 1187, 1184, 1666, 0, 1469, 0, 1183, 1183, 1183, 1183, + 1183, 1183, 1187, 1190, 1656, 1656, 1656, 1186, 1474, 1474, + 1474, 1188, 1737, 0, 1189, 1474, 0, 0, 1736, 1184, + 1184, 1184, 1184, 1184, 1184, 1185, 1185, 1185, 1185, 1185, + 1185, 1187, 1189, 1738, 1193, 0, 0, 0, 0, 0, + 1188, 1737, 1193, 1186, 1186, 1186, 1186, 1186, 1186, 1192, + 0, 0, 1188, 1188, 1188, 1188, 1188, 1188, 1191, 0, + 0, 1189, 1738, 1187, 1187, 1187, 1187, 1187, 1187, 1192, + 1191, 1193, 0, 1194, 1739, 0, 1190, 1190, 1190, 1190, + 1190, 1190, 0, 1195, 0, 1740, 0, 1189, 1189, 1189, + + 1189, 1189, 1189, 1656, 0, 0, 0, 1474, 1192, 1191, + 1194, 1195, 0, 1739, 1196, 0, 0, 1193, 1193, 1193, + 1193, 1193, 1193, 1196, 1740, 1205, 1741, 0, 0, 0, + 0, 1197, 1192, 1192, 1192, 1192, 1192, 1192, 1198, 1194, + 1195, 1191, 1191, 1191, 1191, 1191, 1191, 1197, 1198, 1202, + 1202, 1202, 1196, 1205, 1199, 1741, 1194, 1194, 1194, 1194, + 1194, 1194, 0, 1202, 1199, 1742, 1195, 1195, 1195, 1195, + 1195, 1195, 0, 1226, 0, 0, 1197, 1198, 0, 0, + 0, 1743, 1205, 0, 0, 0, 0, 1196, 1196, 1196, + 1196, 1196, 1196, 1199, 1742, 0, 0, 0, 1205, 1205, + + 1205, 1205, 1205, 1205, 1197, 1197, 1197, 1197, 1197, 1197, + 1743, 1198, 1198, 1198, 1198, 1198, 1198, 1203, 1224, 1224, + 1224, 1224, 1224, 1224, 1224, 1224, 1224, 1199, 1199, 1199, + 1199, 1199, 1199, 1200, 1200, 1200, 1202, 1202, 1202, 1202, + 1202, 1202, 1230, 1203, 1226, 1226, 1226, 1226, 1226, 1226, + 1204, 0, 0, 0, 1200, 0, 0, 1200, 1200, 1206, + 0, 0, 0, 0, 0, 1207, 0, 1228, 1200, 1200, + 1200, 1206, 1203, 1207, 1200, 1744, 1208, 1204, 1745, 0, + 1230, 1230, 1230, 1230, 1230, 1230, 1200, 1200, 1208, 1209, + 1203, 1203, 1203, 1203, 1203, 1203, 1228, 1200, 1200, 1200, + + 1206, 1212, 1207, 1200, 1744, 0, 1204, 1745, 1210, 1228, + 1228, 1228, 1228, 1228, 1228, 1209, 1215, 1208, 1210, 2003, + 2003, 2003, 1200, 1204, 1204, 1204, 1204, 1204, 1204, 1212, + 1215, 0, 1206, 1206, 1206, 1206, 1206, 1206, 1207, 1207, + 1207, 1207, 1207, 1207, 1209, 0, 0, 1210, 1211, 1208, + 1208, 1208, 1208, 1208, 1208, 0, 1245, 0, 1212, 1215, + 1213, 0, 1209, 1209, 1209, 1209, 1209, 1209, 1623, 1211, + 1746, 0, 1214, 1623, 1212, 1212, 1212, 1212, 1212, 1212, + 1214, 1210, 1210, 1210, 1210, 1210, 1210, 1213, 1216, 1215, + 1215, 1215, 1215, 1215, 1215, 1217, 0, 1623, 1211, 1746, + + 1216, 1219, 1623, 1217, 0, 0, 0, 0, 2003, 1214, + 0, 1218, 0, 0, 0, 0, 1213, 0, 1220, 0, + 0, 1211, 1211, 1211, 1211, 1211, 1211, 1218, 1221, 1216, + 1220, 1747, 1217, 1213, 1213, 1213, 1213, 1213, 1213, 1245, + 1245, 1245, 1245, 1245, 1245, 1214, 1214, 1214, 1214, 1214, + 1214, 1227, 1233, 1748, 1749, 1233, 1218, 0, 0, 1220, + 1747, 1216, 1216, 1216, 1216, 1216, 1216, 0, 1217, 1217, + 1217, 1217, 1217, 1217, 1219, 1219, 1219, 1219, 1219, 1219, + 1227, 0, 1748, 1749, 1218, 1218, 1218, 1218, 1218, 1218, + 0, 1220, 1220, 1220, 1220, 1220, 1220, 1234, 0, 0, + + 1234, 1221, 1221, 1221, 1221, 1221, 1221, 1235, 1750, 0, + 1235, 1775, 1227, 1227, 1227, 1227, 1227, 1227, 1238, 1248, + 1671, 1238, 1671, 1234, 0, 1233, 1233, 1233, 1233, 1233, + 1233, 1777, 1671, 1778, 1235, 1236, 1779, 1750, 1236, 1780, + 1775, 1239, 0, 0, 1239, 0, 0, 1240, 1781, 1782, + 1240, 0, 1234, 1238, 0, 0, 0, 1239, 1236, 1240, + 1777, 1671, 1778, 1235, 1241, 1779, 1246, 1241, 1780, 0, + 1234, 1234, 1234, 1234, 1234, 1234, 1241, 1781, 1782, 0, + 1235, 1235, 1235, 1235, 1235, 1235, 1239, 1236, 1240, 0, + 0, 1238, 1238, 1238, 1238, 1238, 1238, 0, 1249, 1248, + + 1248, 1248, 1248, 1248, 1248, 1241, 0, 1783, 1236, 1236, + 1236, 1236, 1236, 1236, 1239, 1239, 1239, 1239, 1239, 1239, + 1240, 1240, 1240, 1240, 1240, 1240, 1242, 0, 0, 1242, + 0, 0, 1243, 0, 0, 1243, 1783, 1241, 1241, 1241, + 1241, 1241, 1241, 1244, 0, 1242, 1244, 1251, 1243, 1246, + 1246, 1246, 1246, 1246, 1246, 1244, 1247, 1247, 1247, 1247, + 1247, 1247, 1247, 1247, 1247, 1250, 1250, 1250, 1250, 1250, + 1250, 1250, 1250, 1250, 1242, 0, 0, 1243, 1249, 1249, + 1249, 1249, 1249, 1249, 1244, 1251, 1251, 1251, 1251, 1251, + 1251, 1253, 0, 1252, 1784, 1785, 1786, 1254, 1787, 1242, + + 1242, 1242, 1242, 1242, 1242, 1243, 1243, 1243, 1243, 1243, + 1243, 0, 0, 0, 0, 0, 1244, 1244, 1244, 1244, + 1244, 1244, 1252, 1784, 1785, 1786, 0, 1787, 1253, 1253, + 1253, 1253, 1253, 1253, 1254, 1254, 1254, 1254, 1254, 1254, + 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 1255, 0, + 0, 0, 0, 0, 1252, 1252, 1252, 1252, 1252, 1252, + 1280, 1280, 1292, 1289, 1280, 1280, 0, 1291, 1280, 1280, + 1280, 1280, 1280, 1280, 1280, 1280, 1280, 0, 1280, 1280, + 1280, 1280, 1280, 1282, 1282, 1282, 1282, 1282, 1282, 1282, + 1282, 1282, 1289, 1290, 1290, 1290, 1291, 0, 1290, 0, + + 1292, 1292, 1292, 1292, 1292, 1292, 1290, 0, 0, 1280, + 0, 1280, 1302, 1302, 1302, 1302, 1302, 1302, 1302, 1302, + 1302, 0, 0, 0, 0, 1289, 1289, 1289, 1289, 1289, + 1289, 1293, 1291, 1291, 1291, 1291, 1291, 1291, 1280, 1280, + 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, + 1280, 1280, 1280, 1280, 1281, 1281, 0, 1307, 1281, 1281, + 1293, 0, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, + 1281, 1308, 1281, 1281, 1281, 1281, 1281, 1788, 1789, 1790, + 1290, 1290, 1290, 1290, 1290, 1290, 1307, 1310, 1310, 1310, + 1310, 1310, 1310, 0, 1293, 1293, 1293, 1293, 1293, 1293, + + 0, 0, 0, 1281, 0, 1281, 1788, 1789, 1790, 1308, + 1308, 1308, 1308, 1308, 1308, 0, 0, 0, 0, 1307, + 1307, 1307, 1307, 1307, 1307, 1309, 1434, 1434, 1434, 1434, + 1434, 1434, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, + 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1300, 1300, + 0, 0, 1300, 1300, 1309, 1795, 1300, 1300, 1300, 1300, + 1300, 1300, 1300, 1300, 1300, 0, 1300, 1300, 1300, 1300, + 1300, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, 1314, + 1348, 1348, 1348, 1798, 1795, 1544, 1544, 1544, 1309, 1309, + 1309, 1309, 1309, 1309, 1348, 1821, 1838, 1300, 0, 1300, + + 1544, 0, 0, 1326, 1815, 1326, 1815, 0, 1819, 0, + 1819, 1327, 1798, 0, 0, 1326, 1815, 0, 0, 1327, + 1819, 0, 1351, 0, 1821, 1838, 1300, 1300, 1300, 1300, + 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, 1300, + 1300, 1300, 1301, 1301, 1326, 1815, 1301, 1301, 1327, 1819, + 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 0, + 1301, 1301, 1301, 1301, 1301, 0, 1435, 1348, 1348, 1348, + 1348, 1348, 1348, 1839, 1544, 0, 1326, 1326, 1326, 1326, + 1326, 1326, 1847, 1848, 1327, 1327, 1327, 1327, 1327, 1327, + 1432, 1301, 0, 1301, 1328, 1351, 1351, 1351, 1351, 1351, + + 1351, 1347, 1839, 1347, 1435, 1435, 1435, 1435, 1435, 1435, + 1328, 1847, 1848, 1347, 1853, 1352, 1388, 1388, 1388, 0, + 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, 1301, + 1301, 1301, 1301, 1301, 1301, 1301, 1312, 1312, 0, 1328, + 1312, 1312, 1347, 1853, 1312, 1312, 1312, 1312, 1312, 1312, + 1312, 1312, 1312, 1388, 1312, 1312, 1312, 1312, 1312, 0, + 0, 1432, 1432, 1432, 1432, 1432, 1432, 1328, 1328, 1328, + 1328, 1328, 1328, 0, 1347, 1347, 1347, 1347, 1347, 1347, + 1857, 1355, 1388, 1858, 1859, 1312, 0, 1312, 1352, 1352, + 1352, 1352, 1352, 1352, 0, 0, 0, 0, 0, 1349, + + 1479, 1479, 1479, 0, 1479, 1388, 0, 0, 1355, 1857, + 1357, 0, 1858, 1859, 1312, 1312, 1312, 1312, 1312, 1312, + 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, 1312, + 1313, 1313, 1349, 0, 1313, 1313, 1357, 1355, 1313, 1313, + 1313, 1313, 1313, 1313, 1313, 1313, 1313, 0, 1313, 1313, + 1313, 1313, 1313, 1350, 1355, 1355, 1355, 1355, 1355, 1355, + 0, 1349, 1350, 1353, 1864, 1357, 0, 1866, 0, 1358, + 0, 0, 1349, 1349, 1349, 1349, 1349, 1349, 1868, 1313, + 0, 1313, 1354, 1357, 1357, 1357, 1357, 1357, 1357, 1479, + 0, 1350, 0, 1864, 1356, 1353, 1866, 1513, 1513, 1513, + + 1361, 0, 0, 1354, 1356, 0, 0, 1868, 1313, 1313, + 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, 1313, + 1313, 1313, 1313, 1313, 1353, 1361, 1350, 1350, 1350, 1350, + 1350, 1350, 1354, 1356, 1513, 1867, 1353, 1353, 1353, 1353, + 1353, 1353, 1358, 1358, 1358, 1358, 1358, 1358, 0, 1359, + 0, 1869, 1870, 1867, 1361, 1354, 1354, 1354, 1354, 1354, + 1354, 1359, 1360, 1513, 1867, 1871, 1872, 1356, 1356, 1356, + 1356, 1356, 1356, 1361, 1361, 1361, 1361, 1361, 1361, 1362, + 1869, 1870, 1867, 0, 1360, 1874, 1513, 1363, 1875, 0, + 1359, 1362, 1876, 0, 1871, 1872, 1364, 0, 0, 1363, + + 0, 1877, 0, 1365, 1873, 1878, 0, 0, 0, 1368, + 0, 0, 1364, 1360, 1874, 1873, 1879, 1875, 1368, 1366, + 1362, 1876, 1359, 1359, 1359, 1359, 1359, 1359, 1363, 1365, + 1877, 1369, 0, 1873, 1878, 1360, 1360, 1360, 1360, 1360, + 1360, 1364, 0, 1367, 1873, 1879, 1366, 1368, 0, 1370, + 0, 0, 1362, 1362, 1362, 1362, 1362, 1362, 1365, 1367, + 1363, 1363, 1363, 1363, 1363, 1363, 1369, 1371, 0, 1364, + 1364, 1364, 1364, 1364, 1364, 1366, 1365, 1365, 1365, 1365, + 1365, 1365, 1368, 1368, 1368, 1368, 1368, 1368, 1367, 1372, + 0, 0, 1366, 1366, 1366, 1366, 1366, 1366, 1374, 0, + + 1880, 1881, 1371, 1372, 1369, 1369, 1369, 1369, 1369, 1369, + 1374, 1375, 0, 0, 0, 0, 1367, 1367, 1367, 1367, + 1367, 1367, 1370, 1370, 1370, 1370, 1370, 1370, 1373, 1880, + 1881, 0, 1372, 0, 1376, 0, 1560, 1560, 1560, 1374, + 1371, 1371, 1371, 1371, 1371, 1371, 1555, 1555, 1555, 0, + 1882, 1373, 1378, 1378, 1378, 1378, 1378, 1378, 1378, 1378, + 1378, 1376, 1372, 1372, 1372, 1372, 1372, 1372, 1380, 1555, + 1560, 1374, 1374, 1374, 1374, 1374, 1374, 0, 1379, 1882, + 1373, 0, 0, 0, 1375, 1375, 1375, 1375, 1375, 1375, + 1376, 1377, 1377, 1377, 1379, 1381, 0, 1883, 1555, 1560, + + 0, 1373, 1373, 1373, 1373, 1373, 1373, 1376, 1376, 1376, + 1376, 1376, 1376, 0, 0, 1382, 1382, 1382, 1383, 1377, + 1381, 1885, 0, 1379, 0, 1560, 1883, 0, 1377, 1382, + 1382, 1886, 1887, 1567, 1383, 1555, 1384, 1567, 1567, 0, + 0, 1380, 1380, 1380, 1380, 1380, 1380, 1386, 1377, 1381, + 1885, 1379, 1379, 1379, 1379, 1379, 1379, 1377, 1384, 1385, + 1886, 1887, 1567, 1383, 0, 0, 1567, 1567, 1381, 1381, + 1381, 1381, 1381, 1381, 1387, 1391, 1391, 1391, 0, 1884, + 1377, 1392, 0, 0, 0, 0, 1385, 1384, 1888, 1391, + 1912, 1383, 1383, 1383, 1383, 1383, 1383, 1393, 1915, 0, + + 1884, 1387, 1382, 1382, 1382, 1382, 1382, 1382, 1884, 1384, + 1384, 1384, 1384, 1384, 1384, 1385, 1415, 1888, 0, 1912, + 1386, 1386, 1386, 1386, 1386, 1386, 0, 1915, 1390, 1884, + 1387, 0, 1385, 1385, 1385, 1385, 1385, 1385, 1389, 1389, + 1389, 1389, 1389, 1389, 1389, 1389, 1389, 1387, 1387, 1387, + 1387, 1387, 1387, 1390, 1392, 1392, 1392, 1392, 1392, 1392, + 1394, 0, 1391, 1391, 1391, 1391, 1391, 1391, 1395, 1916, + 1393, 1393, 1393, 1393, 1393, 1393, 0, 1396, 1920, 1923, + 1395, 0, 1390, 1397, 1397, 1397, 1394, 1396, 1398, 1415, + 1415, 1415, 1415, 1415, 1415, 0, 0, 1397, 1916, 1924, + + 1398, 1390, 1390, 1390, 1390, 1390, 1390, 1920, 1923, 1395, + 1399, 0, 0, 0, 0, 1394, 1396, 0, 1399, 1400, + 1450, 1450, 1450, 1450, 1450, 1450, 1401, 1925, 1924, 1398, + 1926, 0, 0, 1394, 1394, 1394, 1394, 1394, 1394, 1930, + 1400, 1395, 1395, 1395, 1395, 1395, 1395, 1399, 1401, 1402, + 1396, 1396, 1396, 1396, 1396, 1396, 1925, 0, 0, 1926, + 1449, 1398, 1398, 1398, 1398, 1398, 1398, 1417, 1930, 1400, + 1397, 1397, 1397, 1397, 1397, 1397, 1402, 1401, 2014, 2014, + 2014, 0, 0, 1399, 1399, 1399, 1399, 1399, 1399, 1449, + 0, 0, 1400, 1400, 1400, 1400, 1400, 1400, 0, 1401, + + 1401, 1401, 1401, 1401, 1401, 1402, 1411, 1411, 1411, 1411, + 1411, 1411, 1411, 1411, 1411, 1449, 1449, 1449, 1449, 1449, + 1449, 1934, 1402, 1402, 1402, 1402, 1402, 1402, 1412, 1412, + 1412, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, 1413, + 1417, 1417, 1417, 1417, 1417, 1417, 1414, 1437, 1956, 0, + 1934, 1412, 1412, 1412, 1412, 1412, 1412, 1419, 1412, 1973, + 1412, 1414, 1412, 1418, 1974, 1412, 1979, 2014, 1412, 1412, + 1416, 0, 1412, 1982, 1418, 1983, 1437, 1956, 1420, 0, + 1412, 1412, 1412, 1412, 1412, 1412, 1420, 1412, 1973, 1412, + 1414, 1412, 1421, 1974, 1412, 1979, 1416, 1412, 1412, 1422, + + 1421, 1412, 1982, 1418, 1983, 1426, 1437, 1437, 1437, 1437, + 1437, 1437, 1684, 1684, 1684, 1420, 1423, 1412, 0, 1414, + 1414, 1414, 1414, 1414, 1414, 1416, 0, 1684, 1423, 1421, + 1419, 1419, 1419, 1419, 1419, 1419, 1418, 1418, 1418, 1418, + 1418, 1418, 0, 1416, 1416, 1416, 1416, 1416, 1416, 0, + 0, 1420, 1420, 1420, 1420, 1420, 1420, 1423, 0, 1424, + 0, 0, 0, 0, 0, 1421, 1421, 1421, 1421, 1421, + 1421, 1424, 1422, 1422, 1422, 1422, 1422, 1422, 1426, 1426, + 1426, 1426, 1426, 1426, 1425, 1951, 1954, 1951, 1954, 1423, + 1423, 1423, 1423, 1423, 1423, 1425, 1427, 1951, 1954, 0, + + 1424, 1684, 1428, 1486, 0, 0, 0, 0, 1430, 0, + 1987, 1428, 0, 0, 0, 0, 0, 1429, 1989, 1990, + 1991, 1996, 1427, 1997, 1425, 1998, 1951, 1954, 1441, 0, + 0, 0, 1424, 1424, 1424, 1424, 1424, 1424, 1429, 1987, + 1428, 1486, 1486, 1486, 1486, 1486, 1486, 1989, 1990, 1991, + 1996, 1427, 1997, 0, 1998, 0, 0, 1425, 1425, 1425, + 1425, 1425, 1425, 1441, 0, 0, 0, 1429, 1433, 1427, + 1427, 1427, 1427, 1427, 1427, 1428, 1428, 1428, 1428, 1428, + 1428, 1430, 1430, 1430, 1430, 1430, 1430, 1436, 1439, 1999, + 1429, 1429, 1429, 1429, 1429, 1429, 1440, 1433, 0, 0, + + 2000, 1441, 1441, 1441, 1441, 1441, 1441, 2001, 2002, 1442, + 2004, 2005, 1440, 2006, 2007, 1439, 1436, 1443, 1999, 0, + 1433, 1433, 1433, 1433, 1433, 1433, 0, 1442, 1443, 2000, + 2008, 0, 1444, 0, 0, 0, 2001, 2002, 1446, 2004, + 2005, 1440, 2006, 2007, 1439, 0, 0, 2009, 1445, 2010, + 1436, 1436, 1436, 1436, 1436, 1436, 1442, 1443, 1498, 2008, + 1446, 1439, 1439, 1439, 1439, 1439, 1439, 1444, 1448, 1440, + 1440, 1440, 1440, 1440, 1440, 1445, 2009, 1447, 2010, 0, + 0, 0, 1442, 1442, 1442, 1442, 1442, 1442, 1447, 1446, + 1443, 1443, 1443, 1443, 1443, 1443, 1498, 1498, 1498, 1498, + + 1498, 1498, 2011, 1448, 1445, 1444, 1444, 1444, 1444, 1444, + 1444, 1446, 1446, 1446, 1446, 1446, 1446, 1447, 1517, 1491, + 2012, 1445, 1445, 1445, 1445, 1445, 1445, 0, 1493, 2013, + 0, 2011, 0, 0, 1487, 1487, 1487, 0, 0, 1487, + 1492, 1448, 1448, 1448, 1448, 1448, 1448, 1487, 1491, 2012, + 1447, 1447, 1447, 1447, 1447, 1447, 1499, 1493, 2013, 1487, + 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1490, 1492, + 0, 0, 0, 1491, 1491, 1491, 1491, 1491, 1491, 1493, + 1493, 1493, 1493, 1493, 1493, 1499, 0, 0, 1487, 0, + 2015, 1517, 1517, 1517, 1517, 1517, 1517, 1492, 1492, 1492, + + 1492, 1492, 1492, 1514, 1514, 1514, 1514, 1514, 1514, 1514, + 1514, 1514, 0, 1499, 1499, 1499, 1499, 1499, 1499, 2015, + 0, 0, 0, 1487, 1488, 1488, 1488, 1488, 1488, 1488, + 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, + 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, + 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, + 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, + 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, + 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, + 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, + + 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, + 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1488, 1500, 1504, + 2016, 1504, 0, 2018, 2019, 0, 0, 1505, 0, 2020, + 2021, 1504, 0, 1506, 0, 0, 0, 0, 0, 1512, + 0, 1512, 0, 0, 0, 1515, 1505, 1500, 0, 2016, + 2022, 1512, 2018, 2019, 1519, 1506, 2023, 1515, 2020, 2021, + 1504, 1604, 1604, 1604, 1604, 1604, 1604, 1522, 0, 1500, + 1500, 1500, 1500, 1500, 1500, 1505, 1694, 1694, 1694, 2022, + 1512, 0, 0, 0, 1506, 2023, 1515, 0, 2122, 2122, + 2122, 1694, 1504, 1504, 1504, 1504, 1504, 1504, 1516, 0, + + 1505, 1505, 1505, 1505, 1505, 1505, 1506, 1506, 1506, 1506, + 1506, 1506, 1512, 1512, 1512, 1512, 1512, 1512, 1515, 1515, + 1515, 1515, 1515, 1515, 1518, 2024, 1516, 1519, 1519, 1519, + 1519, 1519, 1519, 1520, 2039, 0, 0, 0, 2040, 1521, + 1522, 1522, 1522, 1522, 1522, 1522, 1523, 1526, 1526, 1526, + 2041, 1518, 1524, 2043, 2024, 1516, 1523, 2044, 2045, 2046, + 1520, 1526, 1526, 2039, 1524, 1694, 1521, 2040, 0, 0, + 1528, 1516, 1516, 1516, 1516, 1516, 1516, 2122, 0, 2041, + 1518, 1534, 2043, 0, 0, 1523, 2044, 2045, 2046, 1520, + 0, 0, 1525, 1524, 0, 1521, 0, 1518, 1518, 1518, + + 1518, 1518, 1518, 1525, 0, 0, 1520, 1520, 1520, 1520, + 1520, 1520, 1521, 1521, 1521, 1521, 1521, 1521, 1536, 1523, + 1523, 1523, 1523, 1523, 1523, 1524, 1524, 1524, 1524, 1524, + 1524, 2078, 1525, 1527, 1526, 1526, 1526, 1526, 1526, 1526, + 1529, 0, 1527, 1528, 1528, 1528, 1528, 1528, 1528, 2084, + 2091, 1530, 1529, 2093, 1534, 1534, 1534, 1534, 1534, 1534, + 2078, 2073, 0, 2073, 0, 1525, 1525, 1525, 1525, 1525, + 1525, 1527, 1530, 2073, 0, 1531, 0, 0, 2084, 2091, + 0, 1529, 2093, 1531, 1537, 1537, 1537, 0, 1755, 1755, + 1755, 1536, 1536, 1536, 1536, 1536, 1536, 0, 1537, 1537, + + 0, 1530, 2073, 1755, 2094, 1532, 1527, 1527, 1527, 1527, + 1527, 1527, 1531, 1529, 1529, 1529, 1529, 1529, 1529, 1533, + 0, 0, 0, 0, 1530, 1530, 1530, 1530, 1530, 1530, + 1532, 1535, 0, 2094, 0, 0, 0, 1542, 0, 0, + 1533, 1607, 1607, 1607, 1607, 1607, 1607, 0, 1531, 1531, + 1531, 1531, 1531, 1531, 1543, 0, 1535, 2099, 1542, 1532, + 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1541, 1533, + 1543, 1537, 1537, 1537, 1537, 1537, 1537, 1755, 1532, 1532, + 1532, 1532, 1532, 1532, 1549, 1535, 2099, 1542, 0, 2047, + 2047, 2047, 1533, 1533, 1533, 1533, 1533, 1533, 1547, 1543, + + 0, 0, 0, 2047, 1535, 1535, 1535, 1535, 1535, 1535, + 1542, 1542, 1542, 1542, 1542, 1542, 1546, 1546, 1546, 1546, + 1546, 1546, 1546, 1546, 1546, 1547, 1554, 1543, 1543, 1543, + 1543, 1543, 1543, 1548, 2102, 2107, 0, 2108, 1554, 1550, + 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 1553, 0, + 1557, 2109, 1548, 2110, 1547, 1550, 1558, 1549, 1549, 1549, + 1549, 1549, 1549, 2102, 2107, 1557, 2108, 1554, 2113, 2115, + 0, 1547, 1547, 1547, 1547, 1547, 1547, 1562, 2047, 0, + 2109, 1548, 2110, 0, 1550, 1556, 1556, 1556, 1556, 1556, + 1556, 1556, 1556, 1556, 1557, 0, 0, 2113, 2115, 1554, + + 1554, 1554, 1554, 1554, 1554, 1592, 1548, 1548, 1548, 1548, + 1548, 1548, 1550, 1550, 1550, 1550, 1550, 1550, 0, 2116, + 2117, 0, 0, 1557, 1557, 1557, 1557, 1557, 1557, 1558, + 1558, 1558, 1558, 1558, 1558, 1559, 1561, 1561, 1561, 1561, + 1561, 1561, 1561, 1561, 1561, 0, 1563, 1559, 2116, 2117, + 1562, 1562, 1562, 1562, 1562, 1562, 1563, 1564, 0, 0, + 1566, 1566, 1566, 0, 0, 2076, 2118, 2076, 1565, 1564, + 2119, 2120, 2121, 2124, 1566, 1566, 1559, 2076, 1592, 1592, + 1592, 1592, 1592, 1592, 1593, 1563, 1590, 1590, 1590, 1590, + 1590, 1590, 1590, 1590, 1590, 2118, 1565, 1594, 1564, 2119, + + 2120, 2121, 2124, 0, 1591, 0, 2076, 1594, 1559, 1559, + 1559, 1559, 1559, 1559, 1596, 0, 0, 0, 0, 1563, + 1563, 1563, 1563, 1563, 1563, 1565, 1591, 1595, 0, 0, + 1564, 1564, 1564, 1564, 1564, 1564, 1594, 1599, 2125, 2126, + 2127, 1565, 1565, 1565, 1565, 1565, 1565, 1566, 1566, 1566, + 1566, 1566, 1566, 1598, 1595, 1591, 0, 1593, 1593, 1593, + 1593, 1593, 1593, 1603, 2128, 1598, 0, 2125, 2126, 2127, + 1594, 1594, 1594, 1594, 1594, 1594, 1600, 1591, 1591, 1591, + 1591, 1591, 1591, 1595, 1597, 1597, 1597, 1596, 1596, 1596, + 1596, 1596, 1596, 2128, 1598, 1600, 1605, 0, 1597, 1597, + + 1595, 1595, 1595, 1595, 1595, 1595, 0, 0, 0, 0, + 1599, 1599, 1599, 1599, 1599, 1599, 0, 0, 1601, 0, + 0, 0, 0, 0, 1600, 1605, 1598, 1598, 1598, 1598, + 1598, 1598, 1601, 1606, 1603, 1603, 1603, 1603, 1603, 1603, + 2129, 2130, 1605, 1605, 1605, 1605, 1605, 1605, 1612, 1600, + 1600, 1600, 1600, 1600, 1600, 0, 1608, 0, 0, 0, + 0, 1601, 1606, 1850, 1850, 1850, 0, 1609, 1608, 2129, + 2130, 1597, 1597, 1597, 1597, 1597, 1597, 1609, 1850, 2131, + 2132, 2133, 1610, 2136, 1606, 1606, 1606, 1606, 1606, 1606, + 2137, 1601, 1601, 1601, 1601, 1601, 1601, 1608, 1610, 1615, + + 0, 0, 0, 0, 0, 1611, 1609, 1615, 2131, 2132, + 2133, 0, 2136, 1614, 0, 0, 0, 1611, 0, 2137, + 2138, 1612, 1612, 1612, 1612, 1612, 1612, 1610, 1616, 1608, + 1608, 1608, 1608, 1608, 1608, 0, 1615, 2139, 2141, 0, + 1609, 1609, 1609, 1609, 1609, 1609, 1611, 1613, 1614, 2138, + 0, 0, 1850, 1617, 0, 1610, 1610, 1610, 1610, 1610, + 1610, 0, 0, 1613, 1640, 0, 2139, 2141, 1613, 1617, + 0, 1618, 1615, 1615, 1615, 1615, 1615, 1615, 1611, 1611, + 1611, 1611, 1611, 1611, 0, 0, 1614, 1614, 1614, 1614, + 1614, 1614, 1613, 1640, 1641, 1641, 1641, 1613, 1617, 1641, + + 1618, 1616, 1616, 1616, 1616, 1616, 1616, 1641, 0, 0, + 0, 0, 1640, 1640, 1640, 1640, 1640, 1640, 0, 1641, + 1613, 1613, 1613, 1613, 1613, 1613, 1617, 1617, 1617, 1617, + 1617, 1617, 1618, 1618, 1618, 1618, 1618, 1618, 1644, 1644, + 1644, 0, 0, 1644, 1645, 1645, 1645, 1659, 1641, 1645, + 2142, 1644, 2143, 1648, 1648, 1648, 2144, 1645, 1648, 2148, + 0, 2158, 2161, 1644, 2162, 2163, 1648, 2164, 2169, 1645, + 1658, 1658, 1658, 1658, 1658, 1658, 1659, 2190, 1648, 2142, + 0, 2143, 0, 1641, 0, 2144, 0, 0, 2148, 1660, + 2158, 2161, 1644, 2162, 2163, 0, 2164, 2169, 1645, 1659, + + 1659, 1659, 1659, 1659, 1659, 0, 2190, 1648, 1657, 1657, + 1657, 1657, 1657, 1657, 1657, 1657, 1657, 1664, 1660, 0, + 0, 1662, 2195, 1663, 1763, 2197, 2198, 1644, 2202, 1668, + 0, 2203, 0, 1645, 1660, 1660, 1660, 1660, 1660, 1660, + 1669, 0, 1648, 1650, 1650, 1650, 1664, 2182, 1650, 2182, + 1662, 2195, 1663, 1763, 2197, 2198, 1650, 2202, 2206, 2182, + 2203, 1669, 1664, 1664, 1664, 1664, 1664, 1664, 1650, 1662, + 1662, 1662, 1662, 1662, 1662, 1663, 1663, 1663, 1663, 1663, + 1663, 1763, 1763, 1763, 1763, 1763, 1763, 2206, 2182, 1667, + 1669, 1667, 0, 0, 0, 0, 1672, 1650, 1672, 0, + + 0, 1667, 1668, 1668, 1668, 1668, 1668, 1668, 1672, 0, + 2221, 2221, 2221, 1669, 1669, 1669, 1669, 1669, 1669, 1676, + 0, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, 1650, + 1667, 1678, 1650, 1651, 1651, 1651, 0, 1672, 1651, 1910, + 1910, 1910, 1910, 1910, 1910, 0, 1651, 1675, 1675, 1675, + 1675, 1675, 1675, 1675, 1675, 1675, 2208, 2209, 1651, 0, + 2210, 2211, 1667, 1667, 1667, 1667, 1667, 1667, 1682, 1672, + 1672, 1672, 1672, 1672, 1672, 0, 1677, 0, 0, 2185, + 0, 2185, 1679, 0, 0, 2208, 2209, 1651, 1680, 2210, + 2211, 2185, 1676, 1676, 1676, 1676, 1676, 1676, 1679, 2221, + + 1680, 2214, 2216, 1677, 1678, 1678, 1678, 1678, 1678, 1678, + 1683, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, 1651, + 2185, 0, 1651, 1652, 1652, 1652, 0, 1679, 1652, 1680, + 2214, 2216, 1677, 0, 0, 0, 1652, 0, 0, 0, + 0, 1682, 1682, 1682, 1682, 1682, 1682, 1688, 1652, 1677, + 1677, 1677, 1677, 1677, 1677, 1679, 1679, 1679, 1679, 1679, + 1679, 1680, 1680, 1680, 1680, 1680, 1680, 2068, 2068, 2068, + 2068, 2068, 2068, 1681, 2222, 2222, 2222, 1652, 0, 1689, + 0, 1681, 0, 1683, 1683, 1683, 1683, 1683, 1683, 1686, + 1686, 1686, 1686, 1686, 1686, 1686, 1686, 1686, 0, 1687, + + 0, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, 1652, + 1681, 1687, 1652, 1653, 1653, 1653, 2217, 0, 1653, 0, + 1688, 1688, 1688, 1688, 1688, 1688, 1653, 1696, 1696, 1696, + 1696, 1696, 1696, 1696, 1696, 1696, 1691, 0, 1653, 1774, + 1687, 2227, 2227, 2227, 1693, 2217, 1681, 1681, 1681, 1681, + 1681, 1681, 1689, 1689, 1689, 1689, 1689, 1689, 1691, 2218, + 1693, 1690, 0, 2222, 1977, 1977, 1977, 1653, 1774, 0, + 1692, 1690, 1687, 1687, 1687, 1687, 1687, 1687, 1692, 1977, + 1774, 1774, 1774, 1774, 1774, 1774, 2219, 1691, 2218, 1693, + 0, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, 1653, + + 1690, 1700, 1653, 1654, 1654, 1654, 0, 1692, 1654, 1691, + 1691, 1691, 1691, 1691, 1691, 2219, 1654, 1693, 1693, 1693, + 1693, 1693, 1693, 2220, 0, 2187, 0, 1700, 1654, 0, + 2227, 2167, 2167, 2167, 1690, 1690, 1690, 1690, 1690, 1690, + 2187, 2225, 0, 1692, 1692, 1692, 1692, 1692, 1692, 1701, + 0, 0, 2220, 1977, 2187, 1705, 1700, 1654, 1704, 1704, + 1704, 1704, 1704, 1704, 1704, 1704, 1704, 1706, 2229, 2187, + 2225, 1701, 2167, 2231, 1700, 1700, 1700, 1700, 1700, 1700, + 1710, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, 1654, + 2232, 1714, 1654, 1655, 1655, 1655, 0, 2229, 1655, 0, + + 1701, 2167, 2231, 0, 0, 0, 1655, 0, 0, 0, + 2234, 0, 1707, 0, 0, 0, 0, 2235, 1655, 2232, + 2167, 0, 1701, 1701, 1701, 1701, 1701, 1701, 1705, 1705, + 1705, 1705, 1705, 1705, 1707, 1715, 1715, 1715, 1720, 2234, + 1706, 1706, 1706, 1706, 1706, 1706, 2235, 1655, 0, 1715, + 1715, 0, 0, 1710, 1710, 1710, 1710, 1710, 1710, 0, + 0, 0, 1719, 1707, 1714, 1714, 1714, 1714, 1714, 1714, + 0, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, 1655, + 1719, 1758, 1655, 0, 0, 1707, 1707, 1707, 1707, 1707, + 1707, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, 1713, + + 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1718, 1719, + 1721, 1720, 1720, 1720, 1720, 1720, 1720, 0, 0, 0, + 0, 2236, 1715, 1715, 1715, 1715, 1715, 1715, 1722, 1722, + 1722, 1721, 0, 2238, 1752, 1719, 1719, 1719, 1719, 1719, + 1719, 0, 0, 1722, 0, 2228, 2228, 2228, 1753, 1722, + 2236, 2239, 2241, 1722, 1758, 1758, 1758, 1758, 1758, 1758, + 1721, 1752, 2238, 2243, 1754, 1722, 1724, 1724, 1724, 1724, + 1724, 1724, 1724, 1724, 1724, 1753, 1754, 1759, 0, 0, + 2239, 2241, 1722, 1721, 1721, 1721, 1721, 1721, 1721, 1759, + 1752, 0, 2243, 1760, 1722, 1757, 1757, 1757, 1757, 1757, + + 1757, 1757, 1757, 1757, 1753, 1754, 1762, 1752, 1752, 1752, + 1752, 1752, 1752, 0, 0, 0, 0, 1722, 1759, 1760, + 1765, 1753, 1753, 1753, 1753, 1753, 1753, 1766, 2082, 2082, + 2082, 1764, 2242, 1767, 2228, 2242, 2244, 1754, 1754, 1754, + 1754, 1754, 1754, 2082, 1767, 1765, 2245, 2248, 1760, 0, + 1759, 1759, 1759, 1759, 1759, 1759, 0, 1768, 0, 0, + 1764, 2242, 1766, 2249, 2242, 2244, 1760, 1760, 1760, 1760, + 1760, 1760, 0, 1767, 1765, 2245, 2248, 1762, 1762, 1762, + 1762, 1762, 1762, 1764, 1764, 1764, 1764, 1764, 1764, 1768, + 0, 1770, 2249, 1765, 1765, 1765, 1765, 1765, 1765, 1770, + + 1766, 1766, 1766, 1766, 1766, 1766, 1767, 1767, 1767, 1767, + 1767, 1767, 1769, 0, 2089, 2089, 2089, 2082, 1768, 1791, + 0, 2250, 0, 1769, 0, 0, 0, 0, 1770, 2089, + 1768, 1768, 1768, 1768, 1768, 1768, 1771, 0, 0, 0, + 0, 0, 1772, 0, 0, 0, 0, 1771, 1791, 1809, + 2250, 1773, 1769, 1772, 2071, 2071, 2071, 2071, 2071, 2071, + 0, 0, 1773, 0, 1770, 1770, 1770, 1770, 1770, 1770, + 1791, 1791, 1791, 1791, 1791, 1791, 1771, 2252, 1809, 1792, + 1792, 1792, 1772, 0, 1792, 1769, 1769, 1769, 1769, 1769, + 1769, 1773, 1792, 1845, 1845, 1845, 1809, 1809, 1809, 1809, + + 1809, 1809, 0, 2089, 1792, 2253, 2252, 0, 0, 1771, + 1771, 1771, 1771, 1771, 1771, 1772, 1772, 1772, 1772, 1772, + 1772, 0, 1845, 0, 1773, 1773, 1773, 1773, 1773, 1773, + 1793, 1793, 1793, 1792, 2253, 1793, 1794, 1794, 1794, 0, + 1810, 1794, 2257, 1793, 0, 1797, 1797, 1797, 0, 1794, + 1797, 1845, 1807, 1807, 1807, 1793, 1811, 1807, 1797, 2265, + 2266, 1794, 2268, 0, 0, 1807, 0, 0, 1792, 1810, + 1797, 2257, 1793, 1804, 1804, 1804, 1813, 1807, 1804, 0, + 0, 0, 1845, 0, 1793, 1811, 1804, 0, 2265, 2266, + 1794, 2268, 1810, 1810, 1810, 1810, 1810, 1810, 1804, 1797, + + 1817, 1793, 2097, 2097, 2097, 1813, 1807, 1811, 1811, 1811, + 1811, 1811, 1811, 0, 1794, 0, 1812, 2097, 2269, 1793, + 2271, 2274, 2230, 2230, 2230, 1794, 0, 1804, 1813, 1813, + 1813, 1813, 1813, 1813, 1797, 1799, 1799, 1799, 0, 0, + 1799, 1807, 2166, 2166, 2166, 1812, 0, 2269, 1799, 2271, + 2274, 1804, 1804, 0, 0, 1804, 2166, 1804, 1804, 1804, + 1799, 1898, 1804, 1812, 1812, 1812, 1812, 1812, 1812, 1816, + 2285, 1816, 0, 1817, 1817, 1817, 1817, 1817, 1817, 0, + 0, 1816, 1820, 2246, 1820, 0, 0, 0, 1823, 1799, + 0, 2097, 0, 2246, 1820, 0, 0, 0, 0, 2285, + + 1823, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, 1829, + 1816, 2230, 2246, 1799, 1799, 1799, 1799, 1799, 1799, 1799, + 1799, 1799, 2246, 1820, 1799, 1800, 1800, 1800, 0, 1823, + 1800, 2166, 1898, 1898, 1898, 1898, 1898, 1898, 1800, 0, + 1927, 0, 1816, 1816, 1816, 1816, 1816, 1816, 1824, 2286, + 1800, 0, 2288, 2291, 0, 1820, 1820, 1820, 1820, 1820, + 1820, 1823, 1823, 1823, 1823, 1823, 1823, 0, 1825, 1927, + 1824, 2292, 0, 0, 1826, 2240, 2240, 2240, 2286, 1800, + 1830, 2288, 2291, 1927, 1927, 1927, 1927, 1927, 1927, 1825, + 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1824, + + 2292, 1826, 1832, 1800, 1800, 1800, 1800, 1800, 1800, 1800, + 1800, 1800, 0, 1831, 1800, 1801, 1801, 1801, 1825, 0, + 1801, 1824, 1824, 1824, 1824, 1824, 1824, 0, 1801, 0, + 1826, 1831, 1832, 2170, 2170, 2170, 2170, 2170, 2170, 1855, + 1801, 1825, 1825, 1825, 1825, 1825, 1825, 1826, 1826, 1826, + 1826, 1826, 1826, 1830, 1830, 1830, 1830, 1830, 1830, 0, + 1831, 1832, 1833, 0, 2240, 0, 2111, 2111, 2111, 1801, + 1834, 0, 0, 0, 2293, 1832, 1832, 1832, 1832, 1832, + 1832, 2111, 1833, 0, 0, 0, 1831, 1831, 1831, 1831, + 1831, 1831, 1834, 1801, 1801, 1801, 1801, 1801, 1801, 1801, + + 1801, 1801, 1841, 2293, 1801, 1802, 1802, 1802, 0, 0, + 1802, 1833, 1855, 1855, 1855, 1855, 1855, 1855, 1802, 0, + 2300, 1834, 0, 2303, 2304, 2307, 0, 1841, 0, 1840, + 1802, 0, 2296, 2296, 2296, 1833, 1833, 1833, 1833, 1833, + 1833, 1840, 2308, 1834, 1834, 1834, 1834, 1834, 1834, 2300, + 0, 1846, 2303, 2304, 2307, 2111, 1841, 1889, 0, 1802, + 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 1852, 2309, + 1840, 2308, 1846, 0, 0, 1841, 1841, 1841, 1841, 1841, + 1841, 0, 1856, 1802, 1802, 1802, 1802, 1802, 1802, 1802, + 1802, 1802, 1891, 1900, 1802, 1803, 1803, 1803, 2309, 0, + + 1803, 1846, 1840, 1840, 1840, 1840, 1840, 1840, 1803, 1856, + 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 1862, 2310, + 1803, 2296, 1900, 0, 1846, 1846, 1846, 1846, 1846, 1846, + 1889, 1889, 1889, 1889, 1889, 1889, 0, 0, 1856, 1896, + 1900, 1900, 1900, 1900, 1900, 1900, 1890, 0, 2310, 1803, + 0, 2280, 2283, 2280, 2283, 1856, 1856, 1856, 1856, 1856, + 1856, 0, 1890, 2280, 2283, 1891, 1891, 1891, 1891, 1891, + 1891, 1895, 0, 1803, 1803, 1803, 1803, 1803, 1803, 1803, + 1803, 1803, 2312, 0, 1803, 1805, 1805, 1805, 0, 0, + 1805, 1890, 2280, 2283, 0, 0, 2317, 1895, 1805, 1894, + + 1894, 1894, 1894, 1894, 1894, 1894, 1894, 1894, 0, 0, + 1805, 2312, 1896, 1896, 1896, 1896, 1896, 1896, 1901, 1890, + 1890, 1890, 1890, 1890, 1890, 2317, 1895, 0, 1899, 0, + 2319, 1964, 1964, 1964, 1902, 0, 2146, 2146, 2146, 1805, + 1903, 2188, 2188, 2188, 1895, 1895, 1895, 1895, 1895, 1895, + 1902, 2146, 0, 1901, 0, 0, 2188, 1899, 1904, 2319, + 1964, 2327, 0, 1805, 1805, 1805, 1805, 1805, 1805, 1805, + 1805, 1805, 1905, 0, 1805, 1806, 1806, 1806, 0, 1902, + 1806, 1899, 1899, 1899, 1899, 1899, 1899, 0, 1806, 1964, + 2327, 1901, 1901, 1901, 1901, 1901, 1901, 2329, 2330, 0, + + 1806, 0, 1906, 0, 0, 0, 0, 1902, 1902, 1902, + 1902, 1902, 1902, 1903, 1903, 1903, 1903, 1903, 1903, 1908, + 1964, 0, 1906, 1946, 0, 2146, 2329, 2330, 1907, 1806, + 2188, 1904, 1904, 1904, 1904, 1904, 1904, 1907, 1909, 2179, + 2179, 2179, 2179, 2179, 2179, 1905, 1905, 1905, 1905, 1905, + 1905, 1906, 1946, 1806, 1806, 1806, 1806, 1806, 1806, 1806, + 1806, 1806, 2334, 0, 1806, 0, 1907, 0, 0, 1946, + 1946, 1946, 1946, 1946, 1946, 1906, 1906, 1906, 1906, 1906, + 1906, 2297, 2297, 2297, 0, 1928, 1928, 1928, 0, 0, + 1928, 2334, 1908, 1908, 1908, 1908, 1908, 1908, 1928, 0, + + 0, 1907, 1907, 1907, 1907, 1907, 1907, 1928, 0, 0, + 1928, 1909, 1909, 1909, 1909, 1909, 1909, 1929, 1929, 1929, + 0, 0, 1929, 0, 1931, 1931, 1931, 0, 1945, 1931, + 1929, 0, 0, 1932, 1932, 1932, 1928, 1931, 1932, 1928, + 2335, 0, 1929, 1933, 1933, 1933, 1932, 2336, 1933, 1931, + 1938, 1938, 1938, 2337, 2338, 1938, 1933, 1945, 1932, 2339, + 1939, 1939, 1939, 1938, 0, 1939, 0, 2340, 1933, 2335, + 2297, 1929, 2341, 1939, 1928, 1938, 2336, 0, 1931, 1972, + 1972, 1972, 2337, 2338, 0, 1939, 0, 1932, 2339, 1945, + 1945, 1945, 1945, 1945, 1945, 1929, 2340, 1933, 1948, 0, + + 2342, 2341, 2344, 0, 1938, 0, 1929, 2345, 1972, 0, + 0, 0, 2346, 1931, 1939, 1940, 1940, 1940, 0, 2347, + 1940, 1933, 1932, 0, 0, 0, 0, 1948, 1940, 2342, + 0, 2344, 1933, 1937, 1937, 1937, 2345, 1972, 1937, 1938, + 1940, 2346, 1941, 1941, 1941, 1947, 1937, 1941, 2347, 1939, + 2348, 1949, 1942, 1942, 1942, 1941, 2351, 1942, 1937, 1948, + 1948, 1948, 1948, 1948, 1948, 1942, 0, 1941, 1972, 1940, + 1943, 1943, 1943, 0, 1947, 1943, 2358, 1942, 1957, 2348, + 1949, 0, 0, 1943, 0, 2351, 0, 1937, 1947, 1947, + 1947, 1947, 1947, 1947, 1942, 1943, 1941, 1949, 1949, 1949, + + 1949, 1949, 1949, 2359, 1940, 2358, 1942, 2033, 1952, 2361, + 1952, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, 1937, + 1952, 0, 1937, 1942, 1943, 1955, 0, 1955, 0, 2364, + 0, 1941, 2359, 1978, 1978, 1978, 2033, 1955, 2361, 1958, + 0, 1942, 0, 0, 0, 2374, 0, 2375, 1943, 1952, + 1959, 1957, 1957, 1957, 1957, 1957, 1957, 1965, 2364, 1943, + 1958, 0, 1978, 1960, 2379, 2380, 1955, 2387, 2033, 2033, + 2033, 2033, 2033, 2033, 2374, 1960, 2375, 1959, 1967, 2388, + 2389, 1952, 1952, 1952, 1952, 1952, 1952, 2032, 0, 1958, + 1967, 1978, 1966, 2379, 2380, 0, 2387, 0, 1955, 1955, + + 1955, 1955, 1955, 1955, 1960, 1976, 1959, 0, 2388, 2389, + 0, 1981, 1958, 1958, 1958, 1958, 1958, 1958, 1966, 1967, + 1968, 1976, 1978, 1959, 1959, 1959, 1959, 1959, 1959, 0, + 1965, 1965, 1965, 1965, 1965, 1965, 1960, 1960, 1960, 1960, + 1960, 1960, 0, 2390, 2395, 1968, 1975, 1966, 0, 0, + 1976, 1967, 1967, 1967, 1967, 1967, 1967, 1988, 2032, 2032, + 2032, 2032, 2032, 2032, 0, 1966, 1966, 1966, 1966, 1966, + 1966, 1975, 2390, 2395, 1968, 0, 0, 2025, 1976, 1976, + 1976, 1976, 1976, 1976, 1981, 1981, 1981, 1981, 1981, 1981, + 0, 0, 0, 1968, 1968, 1968, 1968, 1968, 1968, 2025, + + 1975, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, 1986, + 1995, 1995, 1995, 2029, 2029, 2029, 2030, 2034, 0, 1975, + 1975, 1975, 1975, 1975, 1975, 0, 0, 0, 2025, 0, + 1988, 1988, 1988, 1988, 1988, 1988, 0, 0, 2399, 1995, + 2035, 2402, 2029, 2403, 2405, 0, 2034, 2036, 0, 0, + 2025, 2025, 2025, 2025, 2025, 2025, 2049, 2037, 2036, 2313, + 2313, 2313, 0, 0, 0, 2038, 2035, 2399, 1995, 2037, + 2402, 2029, 2403, 2405, 2034, 2034, 2034, 2034, 2034, 2034, + 2406, 2408, 2193, 2193, 2193, 2049, 0, 2036, 0, 2030, + 2030, 2030, 2030, 2030, 2030, 2035, 0, 2193, 2037, 1995, + + 2038, 0, 2029, 2049, 2049, 2049, 2049, 2049, 2049, 2406, + 2408, 0, 0, 2035, 2035, 2035, 2035, 2035, 2035, 0, + 2036, 2036, 2036, 2036, 2036, 2036, 2315, 2315, 2315, 2411, + 2037, 2037, 2037, 2037, 2037, 2037, 0, 0, 2038, 2038, + 2038, 2038, 2038, 2038, 2050, 2050, 2050, 2410, 2313, 2050, + 2052, 2052, 2052, 0, 2412, 2052, 2410, 2050, 2411, 2053, + 2053, 2053, 0, 2052, 2053, 2054, 2054, 2054, 0, 2050, + 2054, 2193, 2053, 2413, 2414, 2052, 2410, 2050, 2054, 0, + 2055, 2055, 2055, 2412, 2053, 2055, 2056, 2056, 2056, 0, + 2054, 2056, 0, 2055, 0, 2057, 2057, 2057, 2050, 2056, + + 2057, 2416, 2413, 2414, 2052, 2055, 2050, 2417, 2057, 2419, + 0, 2056, 0, 2053, 2420, 2315, 2058, 2058, 2058, 2054, + 2057, 2058, 2060, 2060, 2060, 0, 2422, 2060, 2056, 2058, + 2416, 0, 2423, 2050, 2055, 2060, 2417, 0, 2419, 2052, + 2056, 2058, 0, 2420, 2369, 2424, 2369, 2060, 2053, 2057, + 0, 2204, 2204, 2204, 2054, 2422, 2369, 2056, 2061, 2061, + 2061, 2423, 0, 2061, 0, 0, 2204, 0, 2425, 2055, + 2058, 2061, 2426, 2057, 2424, 2056, 2060, 2062, 2062, 2062, + 0, 0, 2062, 2061, 2057, 2369, 2372, 0, 2372, 0, + 2062, 2063, 2063, 2063, 2058, 0, 2063, 2425, 2372, 2079, + + 0, 2426, 2062, 2067, 2063, 2058, 2437, 0, 2064, 2064, + 2064, 2060, 2061, 2064, 2418, 2418, 2063, 2065, 2065, 2065, + 0, 2064, 2065, 0, 2066, 2066, 2066, 2372, 0, 2066, + 2065, 2062, 2067, 2064, 2069, 2437, 2061, 2066, 2438, 2065, + 2204, 2070, 2065, 2418, 2418, 2063, 2074, 2061, 2074, 2066, + 0, 2067, 2067, 2067, 2067, 2067, 2067, 2080, 2074, 2083, + 2083, 2083, 2064, 2069, 0, 2081, 2062, 2438, 2065, 2063, + 2070, 2065, 2079, 2079, 2079, 2079, 2079, 2079, 2066, 2086, + 2063, 2069, 2069, 2069, 2069, 2069, 2069, 2074, 2083, 2070, + 2070, 2070, 2070, 2070, 2070, 0, 2077, 2064, 2077, 2212, + + 2212, 2212, 2066, 2087, 0, 0, 2065, 0, 2077, 0, + 0, 0, 0, 2066, 2212, 0, 2439, 2083, 2440, 2074, + 2074, 2074, 2074, 2074, 2074, 0, 0, 2318, 2318, 2318, + 2080, 2080, 2080, 2080, 2080, 2080, 2095, 2077, 2081, 2081, + 2081, 2081, 2081, 2081, 2088, 2439, 2441, 2440, 2083, 2255, + 2255, 2255, 2086, 2086, 2086, 2086, 2086, 2086, 2450, 2096, + 2088, 0, 2451, 2095, 2255, 2090, 2090, 2090, 0, 2077, + 2077, 2077, 2077, 2077, 2077, 2441, 2087, 2087, 2087, 2087, + 2087, 2087, 2376, 2376, 2376, 0, 2096, 2450, 2212, 2088, + 2151, 2451, 2095, 0, 2090, 2106, 2106, 2106, 2112, 2112, + + 2112, 0, 2134, 2134, 2134, 2378, 2378, 2378, 0, 2095, + 2095, 2095, 2095, 2095, 2095, 2096, 2318, 2088, 2088, 2088, + 2088, 2088, 2088, 2090, 2106, 0, 2134, 2112, 2456, 2134, + 2153, 0, 2096, 2096, 2096, 2096, 2096, 2096, 2255, 2145, + 2382, 2382, 2382, 2134, 2457, 0, 2147, 2147, 2147, 0, + 2391, 2391, 2391, 2106, 2090, 2134, 2112, 2456, 2134, 2153, + 2145, 2151, 2151, 2151, 2151, 2151, 2151, 2460, 2463, 0, + 0, 2376, 2134, 2457, 2154, 2147, 2464, 2153, 2153, 2153, + 2153, 2153, 2153, 2155, 2106, 0, 0, 2112, 0, 2145, + 2152, 2134, 2140, 2156, 2378, 0, 2460, 2463, 2140, 2157, + + 0, 2154, 2140, 2140, 2147, 2464, 0, 2140, 2140, 2140, + 0, 2140, 2145, 2145, 2145, 2145, 2145, 2145, 0, 2152, + 0, 2140, 2270, 2270, 2270, 2157, 2465, 2140, 0, 2382, + 2154, 2140, 2140, 2468, 0, 2147, 2140, 2140, 2140, 2391, + 2140, 2152, 2152, 2152, 2152, 2152, 2152, 2154, 2154, 2154, + 2154, 2154, 2154, 2472, 2157, 2465, 2155, 2155, 2155, 2155, + 2155, 2155, 2468, 2270, 0, 0, 2156, 2156, 2156, 2156, + 2156, 2156, 2157, 2157, 2157, 2157, 2157, 2157, 2171, 2171, + 2171, 2473, 2472, 2171, 2172, 2172, 2172, 2476, 0, 2172, + 0, 2171, 2270, 2173, 2173, 2173, 0, 2172, 2173, 2174, + + 2174, 2174, 0, 2171, 2174, 2478, 2173, 0, 0, 2172, + 2473, 2270, 2174, 2479, 2480, 2173, 2476, 2183, 2173, 2183, + 2175, 2175, 2175, 2481, 2174, 2175, 2176, 2176, 2176, 2183, + 0, 2176, 2171, 2175, 2478, 2177, 2177, 2177, 2172, 2176, + 2177, 0, 2479, 2480, 2173, 2175, 0, 2173, 2177, 2482, + 0, 2176, 2481, 2174, 2484, 0, 2485, 2486, 2183, 2186, + 2177, 2186, 0, 0, 0, 0, 2199, 2171, 2177, 0, + 2178, 2186, 0, 2172, 2175, 2192, 2487, 2174, 2482, 2180, + 2176, 2488, 2173, 2484, 2254, 2485, 2486, 0, 2174, 2177, + 2183, 2183, 2183, 2183, 2183, 2183, 0, 2177, 2175, 2178, + + 2186, 2199, 2192, 0, 2176, 2487, 2200, 0, 2180, 2175, + 2488, 0, 0, 0, 0, 2176, 2178, 2178, 2178, 2178, + 2178, 2178, 0, 2260, 2177, 2180, 2180, 2180, 2180, 2180, + 2180, 2192, 2186, 2186, 2186, 2186, 2186, 2186, 2200, 2199, + 2199, 2199, 2199, 2199, 2199, 2205, 2205, 2205, 2192, 2192, + 2192, 2192, 2192, 2192, 0, 0, 2247, 2254, 2254, 2254, + 2254, 2254, 2254, 2261, 2247, 2263, 0, 2200, 0, 0, + 0, 2247, 2262, 2263, 2205, 2264, 2298, 2298, 2298, 2200, + 2200, 2200, 2200, 2200, 2200, 2247, 2277, 2264, 2489, 0, + 0, 2298, 2261, 2247, 2260, 2260, 2260, 2260, 2260, 2260, + + 2247, 2262, 2263, 2205, 0, 2396, 2396, 2396, 2261, 2261, + 2261, 2261, 2261, 2261, 0, 0, 2264, 2489, 2262, 2262, + 2262, 2262, 2262, 2262, 2277, 2277, 2277, 2277, 2277, 2277, + 0, 2275, 2275, 2275, 2205, 2278, 2275, 2490, 2263, 2263, + 2263, 2263, 2263, 2263, 2275, 2400, 2400, 2400, 2264, 2264, + 2264, 2264, 2264, 2264, 2354, 2289, 2275, 2276, 2276, 2276, + 2491, 0, 2276, 2492, 2275, 2298, 2490, 2281, 0, 2281, + 2276, 0, 0, 2278, 2278, 2278, 2278, 2278, 2278, 2281, + 0, 2494, 2276, 2354, 2284, 2275, 2284, 2289, 0, 2491, + 2294, 0, 2492, 2275, 2396, 0, 2284, 2295, 2495, 0, + + 2354, 2354, 2354, 2354, 2354, 2354, 2294, 0, 2281, 2353, + 2494, 2276, 2393, 2393, 2393, 0, 2289, 2320, 2320, 2320, + 2275, 0, 2430, 2430, 2430, 2284, 2393, 2495, 2289, 2289, + 2289, 2289, 2289, 2289, 2400, 2294, 2332, 2332, 2332, 0, + 2281, 2281, 2281, 2281, 2281, 2281, 2276, 2325, 2325, 2325, + 2320, 0, 2322, 2322, 2322, 0, 0, 2284, 2284, 2284, + 2284, 2284, 2284, 2294, 2294, 2294, 2294, 2294, 2294, 2355, + 2295, 2295, 2295, 2295, 2295, 2295, 2332, 0, 2322, 2320, + 2353, 2353, 2353, 2353, 2353, 2353, 2356, 0, 2325, 2365, + 2365, 2365, 2322, 2357, 2365, 2366, 0, 2496, 2355, 0, + + 2497, 2393, 2365, 0, 0, 2332, 2320, 2322, 2370, 0, + 2370, 2430, 0, 2356, 2365, 2367, 2377, 2325, 2357, 2499, + 2370, 2322, 2507, 0, 2366, 2332, 2496, 0, 2432, 2497, + 2355, 2355, 2355, 2355, 2355, 2355, 2325, 0, 2373, 0, + 2373, 2322, 2356, 2365, 2367, 0, 0, 2357, 2499, 2370, + 2373, 2507, 2366, 2366, 2366, 2366, 2366, 2366, 0, 2356, + 2356, 2356, 2356, 2356, 2356, 0, 2357, 2357, 2357, 2357, + 2357, 2357, 2367, 2367, 2367, 2367, 2367, 2367, 2365, 2373, + 0, 2370, 2370, 2370, 2370, 2370, 2370, 2381, 2434, 2377, + 2377, 2377, 2377, 2377, 2377, 2384, 2384, 2384, 2381, 2432, + + 2432, 2432, 2432, 2432, 2432, 2433, 2433, 2433, 2433, 2433, + 2433, 2373, 2373, 2373, 2373, 2373, 2373, 2434, 2435, 0, + 0, 2508, 2510, 2442, 2436, 2520, 2521, 2381, 2384, 2452, + 2452, 2452, 2454, 2454, 2454, 0, 2445, 0, 2445, 0, + 2434, 2434, 2434, 2434, 2434, 2434, 2435, 2443, 2445, 2458, + 2508, 2510, 2442, 2436, 2520, 2521, 0, 2384, 0, 0, + 2381, 2381, 2381, 2381, 2381, 2381, 2446, 2448, 2446, 2448, + 2462, 2462, 2462, 0, 2524, 2435, 2443, 2445, 2446, 2448, + 0, 0, 2436, 0, 2384, 2442, 2442, 2442, 2442, 2442, + 2442, 2435, 2435, 2435, 2435, 2435, 2435, 2436, 2436, 2436, + + 2436, 2436, 2436, 2524, 2449, 0, 2449, 2446, 2448, 2443, + 2443, 2443, 2443, 2443, 2443, 0, 2449, 2503, 2452, 0, + 0, 2454, 2458, 2458, 2458, 2458, 2458, 2458, 2466, 2466, + 2466, 2504, 2469, 2469, 2469, 2470, 2470, 2470, 2525, 2446, + 2446, 2446, 2446, 2446, 2446, 2449, 2469, 2474, 2474, 2474, + 2500, 2500, 2500, 0, 2527, 2527, 2527, 2505, 0, 2462, + 2504, 2512, 2512, 2512, 2512, 2512, 2512, 2525, 0, 0, + 0, 2470, 2506, 2515, 2526, 2515, 2470, 2449, 2449, 2449, + 2449, 2449, 2449, 2505, 2506, 2515, 2531, 2474, 2503, 2503, + 2503, 2503, 2503, 2503, 2504, 2504, 2504, 2504, 2504, 2504, + + 2470, 0, 0, 2526, 0, 2470, 2513, 2513, 2513, 2513, + 2513, 2513, 2505, 2506, 2515, 2531, 2474, 2466, 2534, 2534, + 2534, 2469, 2533, 0, 2470, 2516, 2518, 2516, 2518, 2535, + 2505, 2505, 2505, 2505, 2505, 2505, 2474, 2516, 2518, 2500, + 2519, 2536, 2519, 2527, 2539, 2506, 2506, 2506, 2506, 2506, + 2506, 2533, 2519, 2540, 2534, 2541, 2543, 2544, 2535, 2534, + 2545, 2546, 2547, 2548, 2549, 2551, 2516, 2518, 2552, 2565, + 2536, 0, 0, 2539, 0, 2553, 2554, 2555, 2567, 2556, + 2557, 2519, 2540, 2534, 2541, 2543, 2544, 0, 2534, 2545, + 2546, 2547, 2548, 2549, 2551, 2558, 2559, 2552, 2516, 2516, + + 2516, 2516, 2516, 2516, 2553, 2554, 2555, 2534, 2556, 2557, + 2561, 0, 2568, 2519, 2519, 2519, 2519, 2519, 2519, 2566, + 2570, 2571, 0, 0, 2558, 2559, 2573, 0, 2573, 2578, + 2596, 2596, 2596, 0, 2574, 0, 2574, 2568, 2573, 2561, + 2565, 2565, 2565, 2565, 2565, 2565, 2574, 2579, 2566, 2570, + 2571, 2567, 2567, 2567, 2567, 2567, 2567, 2576, 2578, 2576, + 2566, 2566, 2566, 2566, 2566, 2566, 2568, 2573, 2580, 2576, + 2581, 2582, 2577, 2584, 2577, 2574, 2579, 2587, 2614, 2614, + 2614, 2614, 2614, 2614, 2577, 2568, 2568, 2568, 2568, 2568, + 2568, 2588, 2592, 2593, 2594, 2595, 2598, 2580, 2576, 2581, + + 2582, 2599, 2584, 2600, 2601, 2603, 2587, 2574, 2574, 2574, + 2574, 2574, 2574, 2577, 2604, 2606, 2613, 0, 0, 2596, + 2588, 2592, 2593, 2594, 2595, 2598, 2608, 2610, 2611, 2615, + 2599, 2617, 2600, 2601, 2603, 2625, 2626, 2629, 0, 2619, + 2620, 2619, 2620, 2604, 2606, 2577, 2577, 2577, 2577, 2577, + 2577, 2619, 2620, 2633, 2634, 2608, 2610, 2611, 0, 2622, + 2617, 2622, 0, 0, 2625, 2626, 2629, 2623, 2635, 2623, + 2636, 2622, 2637, 2639, 2639, 2639, 2641, 2641, 2641, 2623, + 2619, 2620, 2633, 2634, 2670, 2670, 2670, 2613, 2613, 2613, + 2613, 2613, 2613, 2638, 2640, 2643, 2644, 2635, 2646, 2636, + + 2622, 2637, 2615, 2615, 2615, 2615, 2615, 2615, 2623, 2647, + 2648, 0, 0, 2620, 2620, 2620, 2620, 2620, 2620, 2650, + 2651, 2662, 2638, 2640, 2643, 2644, 2664, 2646, 2654, 2654, + 2654, 2654, 2654, 2654, 2657, 2658, 2657, 2658, 2647, 2648, + 2623, 2623, 2623, 2623, 2623, 2623, 2657, 2658, 2650, 2651, + 2662, 2660, 2661, 2660, 2661, 2664, 2666, 2667, 2668, 2669, + 2674, 2678, 2639, 2660, 2661, 2641, 2672, 2672, 2672, 2677, + 2677, 2677, 2681, 2670, 2684, 2657, 2658, 0, 0, 2686, + 0, 2686, 0, 0, 0, 2666, 2667, 2668, 2669, 2674, + 2678, 2686, 2660, 2661, 2687, 2689, 2687, 2689, 0, 0, + + 0, 2681, 2690, 2684, 2690, 2692, 2687, 2689, 2658, 2658, + 2658, 2658, 2658, 2658, 2690, 2693, 2694, 2695, 2696, 2697, + 2686, 2699, 2702, 2703, 2704, 2661, 2661, 2661, 2661, 2661, + 2661, 2710, 0, 2712, 2692, 2687, 2689, 2700, 2700, 2700, + 0, 0, 0, 2690, 2693, 2694, 2695, 2696, 2697, 0, + 2699, 2702, 2703, 2704, 2706, 2672, 2706, 2713, 2677, 0, + 2710, 2707, 2712, 2707, 2700, 0, 2706, 2687, 2687, 2687, + 2687, 2687, 2687, 2707, 2714, 2690, 2690, 2690, 2690, 2690, + 2690, 2715, 2709, 2716, 2709, 2717, 2713, 2719, 2711, 2711, + 2711, 2721, 2729, 2700, 2709, 2706, 2711, 0, 2732, 2723, + + 2733, 2723, 2707, 2714, 2734, 2725, 2725, 2725, 0, 0, + 2715, 2723, 2716, 2725, 2717, 2736, 2719, 2737, 2742, 2743, + 2721, 2729, 2744, 2709, 2745, 2746, 2700, 2732, 2749, 2733, + 2747, 2747, 2747, 2734, 2707, 2707, 2707, 2707, 2707, 2707, + 2723, 2751, 2752, 2753, 2736, 2758, 2737, 2742, 2743, 2759, + 0, 2744, 2760, 2745, 2746, 2761, 2764, 2749, 2755, 2755, + 2755, 2756, 2756, 2756, 2762, 2762, 2762, 0, 2766, 2768, + 2751, 2752, 2753, 0, 2758, 2769, 2771, 2711, 2759, 2711, + 2773, 2760, 2775, 2776, 2761, 2764, 2767, 2767, 2767, 2774, + 2774, 2774, 2777, 2778, 2725, 2779, 2725, 2766, 2768, 2780, + + 2782, 2783, 2756, 2784, 2769, 2771, 2785, 2785, 2785, 2773, + 0, 2775, 2776, 0, 0, 0, 0, 0, 0, 2747, + 0, 2777, 2778, 0, 2779, 0, 0, 0, 2780, 2782, + 2783, 2756, 2784, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2755, 0, 0, + 2756, 0, 0, 2762, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2767, 0, 0, 2774, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2588, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2595, 2597, 2597, 2597, 2597, 2597, 2597, 2597, 2597, - 2597, 2597, 2597, 2597, 2597, 2598, 2598, 2598, 2598, 2598, - 2598, 2598, 2598, 2598, 2598, 2598, 2598, 2598, 2599, 2599, - 2599, 2599, 2599, 2599, 2599, 2599, 2599, 2599, 2599, 2599, - - 2599, 2600, 2600, 2600, 2600, 2600, 2600, 2600, 2600, 2600, - 2600, 2600, 2600, 2600, 2601, 2601, 2601, 2601, 2601, 2601, - 2601, 2601, 2601, 2601, 2601, 2601, 2601, 2602, 2602, 2602, - 2602, 2602, 2602, 2602, 2602, 2602, 2602, 2602, 2602, 2602, - 2603, 2603, 2603, 2603, 2603, 2603, 2603, 2603, 2603, 2603, - 2603, 2603, 2603, 2604, 2604, 2604, 2604, 2604, 2604, 2604, - 2604, 2604, 2604, 2604, 2604, 2604, 2605, 2605, 2605, 2605, - 2605, 2605, 2605, 2605, 2605, 2605, 2605, 2605, 2605, 2606, - 2606, 2606, 2606, 2606, 2606, 2606, 2606, 2606, 2606, 2606, - 2606, 2606, 2607, 2607, 2607, 2607, 2607, 2607, 2607, 2607, - - 2607, 2607, 2607, 2607, 2607, 2608, 2608, 2608, 2608, 2608, - 2608, 2608, 2608, 2608, 2608, 2608, 2608, 2608, 2609, 2609, - 2609, 2609, 2609, 2609, 2609, 2609, 2609, 2609, 2609, 2609, - 2609, 2610, 2610, 2610, 2610, 2610, 2610, 2610, 2610, 2610, - 2610, 2610, 2610, 2610, 2611, 2611, 2611, 2611, 2611, 2611, - 2611, 2611, 2611, 2611, 2611, 2611, 2611, 2612, 2612, 2612, - 2612, 2612, 2612, 2612, 2612, 2612, 2612, 2612, 2612, 2612, - 2613, 2613, 2613, 2614, 2614, 0, 2614, 2614, 2614, 2614, - 2614, 2614, 2614, 2614, 2614, 2614, 2615, 2615, 2616, 2616, - 2616, 2617, 2617, 0, 0, 0, 0, 0, 0, 2617, - - 2618, 2618, 2619, 2619, 0, 2619, 2619, 0, 2619, 2619, - 2619, 2620, 2620, 2620, 2621, 2621, 2622, 2622, 2622, 2623, - 2623, 0, 0, 0, 0, 0, 0, 2623, 2624, 0, - 0, 2624, 2625, 0, 0, 2625, 2626, 2626, 2626, 2626, - 2626, 2626, 0, 2626, 2626, 2626, 2626, 0, 2626, 2627, - 2627, 2627, 2627, 2627, 2627, 2627, 2627, 2627, 2627, 2627, - 2627, 2627, 2628, 2628, 2628, 2628, 2628, 2628, 0, 2628, - 2628, 2628, 2628, 0, 2628, 2629, 2629, 2629, 2629, 2629, - 2629, 2629, 2629, 2629, 2629, 2629, 2629, 2629, 2630, 2630, - 2630, 2630, 2630, 2630, 2630, 2630, 2630, 2630, 2630, 2630, - - 2630, 2631, 2631, 2631, 2631, 2631, 2631, 2631, 2631, 2631, - 2631, 2631, 2631, 2632, 2632, 2632, 2632, 2632, 2632, 2632, - 2632, 2632, 2632, 2632, 2632, 2633, 2633, 0, 2633, 2633, - 2633, 2633, 2633, 2633, 2633, 2633, 2633, 2633, 2634, 2634, - 2635, 2635, 0, 2635, 2635, 2635, 2635, 2635, 2635, 2635, - 2635, 2635, 2635, 2636, 2636, 0, 2636, 2636, 2636, 2636, - 2636, 2636, 2636, 2636, 2636, 2636, 2637, 2637, 2638, 2638, - 2639, 2639, 0, 2639, 2639, 2639, 2639, 2639, 2639, 2639, - 2639, 2639, 2639, 2640, 2640, 2641, 2641, 0, 2641, 2641, - 2641, 2641, 2641, 2641, 2641, 2641, 2641, 2641, 2642, 2642, - - 0, 2642, 2642, 2642, 2642, 2642, 2642, 2642, 2642, 2642, - 2642, 2643, 2643, 2643, 2644, 2644, 0, 2644, 2644, 2644, - 2644, 2644, 2644, 2644, 2644, 2644, 2644, 2645, 2645, 0, - 2645, 2645, 2645, 2645, 2645, 2645, 2645, 2645, 2645, 2645, - 2646, 2646, 2647, 2647, 2647, 2648, 2648, 0, 0, 0, - 0, 0, 0, 2648, 2649, 2649, 2650, 2650, 0, 2650, - 2650, 0, 2650, 2650, 2650, 2651, 2651, 2651, 2652, 2652, - 2653, 2653, 2653, 2654, 2654, 0, 0, 0, 0, 0, - 0, 2654, 2655, 0, 0, 2655, 2656, 0, 0, 2656, - 2657, 2657, 2657, 2657, 2657, 2657, 0, 2657, 2657, 2657, - - 2657, 0, 2657, 2658, 2658, 0, 2658, 2658, 2658, 2658, - 2658, 2658, 2658, 2658, 2658, 2658, 2659, 2659, 2659, 2659, - 2659, 2659, 0, 2659, 2659, 2659, 2659, 0, 2659, 2660, - 2660, 0, 2660, 2660, 2660, 2660, 2660, 2660, 2660, 2660, - 2660, 2660, 2661, 2661, 0, 2661, 2661, 2661, 2661, 2661, - 2661, 2661, 2661, 2661, 2661, 2662, 2662, 2662, 2662, 2662, - 2662, 2662, 2662, 2662, 2662, 2662, 2662, 2663, 2663, 2663, - 2663, 2663, 2663, 2663, 2663, 2663, 2663, 2663, 2663, 2664, - 2664, 0, 2664, 2664, 2664, 2664, 2664, 2664, 2664, 2664, - 2664, 2664, 2665, 2665, 0, 2665, 2665, 2665, 2665, 2665, - - 2665, 2665, 2665, 2665, 2665, 2666, 2666, 2667, 2667, 0, - 2667, 2667, 2667, 2667, 2667, 2667, 2667, 2667, 2667, 2667, - 2668, 2668, 0, 2668, 2668, 2668, 2668, 2668, 2668, 2668, - 2668, 2668, 2668, 2669, 2669, 0, 2669, 2669, 2669, 2669, - 2669, 2669, 2669, 2669, 2669, 2669, 2670, 2670, 2671, 2671, - 2672, 2672, 0, 2672, 2672, 2672, 2672, 2672, 2672, 2672, - 2672, 2672, 2672, 2673, 2673, 0, 2673, 2673, 2673, 2673, - 2673, 2673, 2673, 2673, 2673, 2673, 2674, 2674, 2675, 2675, - 0, 2675, 2675, 2675, 2675, 2675, 2675, 2675, 2675, 2675, - 2675, 2676, 2676, 0, 2676, 2676, 2676, 2676, 2676, 2676, - - 2676, 2676, 2676, 2676, 2677, 2677, 0, 2677, 2677, 2677, - 2677, 2677, 2677, 2677, 2677, 2677, 2677, 2678, 2678, 2678, - 2678, 2678, 2678, 2678, 2678, 2678, 2678, 2678, 2678, 2678, - 2679, 2679, 2680, 2680, 2681, 2681, 0, 0, 0, 2681, - 2682, 2682, 2683, 0, 0, 2683, 2684, 0, 0, 2684, - 2685, 2685, 0, 2685, 2685, 2685, 2685, 2685, 2685, 2685, - 2685, 2685, 2685, 2686, 2686, 0, 2686, 2686, 2686, 2686, - 2686, 2686, 2686, 2686, 2686, 2686, 2687, 2687, 0, 2687, - 2687, 2687, 2687, 2687, 2687, 2687, 2687, 2687, 2687, 2688, - 2688, 0, 2688, 2688, 2688, 2688, 2688, 2688, 2688, 2688, - - 2688, 2688, 2689, 2689, 2689, 2689, 2689, 2689, 2689, 2689, - 2689, 2689, 2689, 2689, 2689, 2690, 2690, 2691, 2691, 2691, - 2691, 2691, 2691, 2691, 2691, 2691, 2691, 2691, 2691, 2691, - 2692, 2692, 0, 2692, 2692, 2692, 2692, 2692, 2692, 2692, - 2692, 2692, 2692, 2693, 2693, 2693, 2693, 2693, 2693, 2693, - 2693, 2693, 2693, 2693, 2693, 2693, 2694, 2694, 2695, 2695, - 2696, 2696, 0, 2696, 2696, 2696, 2696, 2696, 2696, 2696, - 2696, 2696, 2696, 2697, 2697, 2697, 2697, 2697, 2697, 2697, - 2697, 2697, 2697, 2697, 2697, 2697, 2698, 2698, 2699, 2699, - 2699, 2699, 2699, 2699, 2699, 2699, 2699, 2699, 2699, 2699, - - 2699, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, - 2700, 2700, 2700, 2700, 2701, 2701, 2701, 2702, 2702, 0, - 2702, 2702, 2702, 2702, 2702, 2702, 2702, 2702, 2702, 2702, - 2703, 2703, 0, 2703, 2703, 2703, 2703, 2703, 2703, 2703, - 2703, 2703, 2703, 2704, 2704, 2704, 2705, 2705, 0, 2705, - 2705, 2705, 2705, 2705, 2705, 2705, 2705, 2705, 2705, 2706, - 2706, 2707, 2707, 0, 0, 0, 0, 0, 0, 2707, - 2708, 2708, 2709, 2709, 0, 0, 0, 2709, 2709, 2710, - 2710, 2710, 2711, 2711, 2711, 2712, 2712, 2713, 2713, 0, - 0, 0, 0, 0, 0, 2713, 2714, 0, 0, 2714, - - 2715, 0, 0, 2715, 2716, 2716, 2716, 2716, 2716, 2716, - 2716, 2716, 2716, 2716, 2716, 2716, 2716, 2717, 2717, 2717, - 2717, 2717, 2717, 2717, 2717, 2717, 2717, 2717, 2717, 2717, - 2718, 2718, 2718, 2718, 2718, 2718, 2718, 2718, 2718, 2718, - 2718, 2718, 2718, 2719, 2719, 0, 2719, 2719, 2719, 2719, - 2719, 2719, 2719, 2719, 2719, 2719, 2720, 2720, 0, 2720, - 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2720, 2721, - 2721, 0, 2721, 2721, 2721, 2721, 2721, 2721, 2721, 2721, - 2721, 2721, 2722, 2722, 2723, 2723, 0, 2723, 2723, 2723, - 2723, 2723, 2723, 2723, 2723, 2723, 2723, 2724, 2724, 0, - - 2724, 2724, 2724, 2724, 2724, 2724, 2724, 2724, 2724, 2724, - 2725, 2725, 0, 2725, 2725, 2725, 2725, 2725, 2725, 2725, - 2725, 2725, 2725, 2726, 2726, 0, 2726, 2726, 2726, 2726, - 2726, 2726, 2726, 2726, 2726, 2726, 2727, 2727, 2728, 2728, - 2729, 2729, 0, 2729, 2729, 2729, 2729, 2729, 2729, 2729, - 2729, 2729, 2729, 2730, 2730, 0, 2730, 2730, 2730, 2730, - 2730, 2730, 2730, 2730, 2730, 2730, 2731, 2731, 0, 2731, - 2731, 2731, 2731, 2731, 2731, 2731, 2731, 2731, 2731, 2732, - 2732, 2733, 2733, 0, 2733, 2733, 2733, 2733, 2733, 2733, - 2733, 2733, 2733, 2733, 2734, 2734, 0, 2734, 2734, 2734, - - 2734, 2734, 2734, 2734, 2734, 2734, 2734, 2735, 2735, 0, - 2735, 2735, 2735, 2735, 2735, 2735, 2735, 2735, 2735, 2735, - 2736, 2736, 0, 2736, 2736, 2737, 2737, 2738, 2738, 0, - 0, 0, 2738, 2739, 2739, 2740, 0, 0, 2740, 2741, - 0, 0, 2741, 2742, 2742, 0, 2742, 2742, 2742, 2742, - 2742, 2742, 2742, 2742, 2742, 2742, 2743, 2743, 0, 2743, - 2743, 2743, 2743, 2743, 2743, 2743, 2743, 2743, 2743, 2744, - 2744, 0, 2744, 2744, 2744, 2744, 2744, 2744, 2744, 2744, - 2744, 2744, 2745, 2745, 0, 2745, 2745, 2745, 2745, 2745, - 2745, 2745, 2745, 2745, 2745, 2746, 2746, 2747, 2747, 0, - - 2747, 2747, 2747, 2747, 2747, 2747, 2747, 2747, 2747, 2747, - 2748, 2748, 0, 2748, 2748, 2748, 2748, 2748, 2748, 2748, - 2748, 2748, 2748, 2749, 2749, 2750, 2750, 2750, 2750, 2750, - 2750, 2750, 2750, 2750, 2750, 2750, 2750, 2750, 2751, 2751, - 2751, 2751, 2751, 2751, 2751, 2751, 2751, 2751, 2751, 2751, - 2751, 2752, 2752, 2752, 2752, 2752, 2752, 2752, 2752, 2752, - 2752, 2752, 2752, 2752, 2753, 2753, 2753, 2753, 2753, 2753, - 2753, 2753, 2753, 2753, 2753, 2753, 2753, 2754, 2754, 2754, - 2754, 2754, 2754, 2754, 2754, 2754, 2754, 2754, 2754, 2754, - 2755, 2755, 2755, 2755, 2755, 2755, 2755, 2755, 2755, 2755, - - 2755, 2755, 2755, 2756, 2756, 2756, 2756, 2756, 2756, 2756, - 2756, 2756, 2756, 2756, 2756, 2756, 2757, 2757, 2757, 2757, - 2757, 2757, 2757, 2757, 2757, 2757, 2757, 2757, 2757, 2758, - 2758, 2758, 2758, 2758, 2758, 2758, 2758, 2758, 2758, 2758, - 2758, 2758, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, - 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596 + 0, 0, 0, 0, 0, 2785, 2787, 2787, 2787, 2787, + + 2787, 2787, 2787, 2787, 2787, 2787, 2787, 2787, 2788, 2788, + 2788, 2788, 2788, 2788, 2788, 2788, 2788, 2788, 2788, 2788, + 2789, 2789, 2789, 2789, 2789, 2789, 2789, 2789, 2789, 2789, + 2789, 2789, 2790, 2790, 2790, 2790, 2790, 2790, 2790, 2790, + 2790, 2790, 2790, 2790, 2791, 2791, 2791, 2791, 2791, 2791, + 2791, 2791, 2791, 2791, 2791, 2791, 2792, 2792, 2792, 2792, + 2792, 2792, 2792, 2792, 2792, 2792, 2792, 2792, 2793, 2793, + 2793, 2793, 2793, 2793, 2793, 2793, 2793, 2793, 2793, 2793, + 2794, 2794, 2794, 2794, 2794, 2794, 2794, 2794, 2794, 2794, + 2794, 2794, 2795, 2795, 2795, 2795, 2795, 2795, 2795, 2795, + + 2795, 2795, 2795, 2795, 2796, 2796, 2796, 2796, 2796, 2796, + 2796, 2796, 2796, 2796, 2796, 2796, 2797, 2797, 2797, 2797, + 2797, 2797, 2797, 2797, 2797, 2797, 2797, 2797, 2798, 2798, + 2798, 2798, 2798, 2798, 2798, 2798, 2798, 2798, 2798, 2798, + 2799, 2799, 2799, 2799, 2799, 2799, 2799, 2799, 2799, 2799, + 2799, 2799, 2800, 2800, 2800, 2800, 2800, 2800, 2800, 2800, + 2800, 2800, 2800, 2800, 2801, 2801, 2801, 2801, 2801, 2801, + 2801, 2801, 2801, 2801, 2801, 2801, 2802, 2802, 2802, 2802, + 2802, 2802, 2802, 2802, 2802, 2802, 2802, 2802, 2803, 2803, + 2803, 2804, 2804, 0, 2804, 2804, 2804, 2804, 2804, 2804, + + 2804, 2804, 2804, 2805, 2805, 2806, 2806, 2806, 2807, 2807, + 0, 0, 0, 0, 0, 2807, 2808, 2808, 2809, 2809, + 0, 2809, 2809, 0, 2809, 2809, 2810, 2810, 2810, 2811, + 2811, 2812, 2812, 2812, 2813, 2813, 0, 0, 0, 0, + 0, 2813, 2814, 0, 2814, 2815, 0, 2815, 2816, 2816, + 2816, 2816, 2816, 2816, 0, 2816, 2816, 2816, 0, 2816, + 2817, 2817, 2817, 2817, 2817, 2817, 2817, 2817, 2817, 2817, + 2817, 2817, 2818, 2818, 2818, 2818, 2818, 2818, 0, 2818, + 2818, 2818, 0, 2818, 2819, 2819, 2819, 2819, 2819, 2819, + 2819, 2819, 2819, 2819, 2819, 2819, 2820, 2820, 2820, 2820, + + 2820, 2820, 2820, 2820, 2820, 2820, 2820, 2820, 2821, 2821, + 2821, 2821, 2821, 2821, 2821, 2821, 2821, 2821, 2821, 2822, + 2822, 2822, 2822, 2822, 2822, 2822, 2822, 2822, 2822, 2822, + 2823, 2823, 0, 2823, 2823, 2823, 2823, 2823, 2823, 2823, + 2823, 2823, 2824, 2824, 2825, 2825, 0, 2825, 2825, 2825, + 2825, 2825, 2825, 2825, 2825, 2825, 2826, 2826, 0, 2826, + 2826, 2826, 2826, 2826, 2826, 2826, 2826, 2826, 2827, 2827, + 2828, 2828, 2829, 2829, 0, 2829, 2829, 2829, 2829, 2829, + 2829, 2829, 2829, 2829, 2830, 2830, 2831, 2831, 0, 2831, + 2831, 2831, 2831, 2831, 2831, 2831, 2831, 2831, 2832, 2832, + + 0, 2832, 2832, 2832, 2832, 2832, 2832, 2832, 2832, 2832, + 2833, 2833, 2833, 2834, 2834, 0, 2834, 2834, 2834, 2834, + 2834, 2834, 2834, 2834, 2834, 2835, 2835, 0, 2835, 2835, + 2835, 2835, 2835, 2835, 2835, 2835, 2835, 2836, 2836, 2837, + 2837, 2837, 2838, 2838, 0, 0, 0, 0, 0, 2838, + 2839, 2839, 2840, 2840, 0, 2840, 2840, 0, 2840, 2840, + 2841, 2841, 2841, 2842, 2842, 2843, 2843, 2843, 2844, 2844, + 0, 0, 0, 0, 0, 2844, 2845, 0, 2845, 2846, + 0, 2846, 2847, 2847, 2847, 2847, 2847, 2847, 0, 2847, + 2847, 2847, 0, 2847, 2848, 2848, 0, 2848, 2848, 2848, + + 2848, 2848, 2848, 2848, 2848, 2848, 2849, 2849, 2849, 2849, + 2849, 2849, 0, 2849, 2849, 2849, 0, 2849, 2850, 2850, + 0, 2850, 2850, 2850, 2850, 2850, 2850, 2850, 2850, 2850, + 2851, 2851, 0, 2851, 2851, 2851, 2851, 2851, 2851, 2851, + 2851, 2851, 2852, 2852, 2852, 2852, 2852, 2852, 2852, 2852, + 2852, 2852, 2852, 2853, 2853, 2853, 2853, 2853, 2853, 2853, + 2853, 2853, 2853, 2853, 2854, 2854, 0, 2854, 2854, 2854, + 2854, 2854, 2854, 2854, 2854, 2854, 2855, 2855, 0, 2855, + 2855, 2855, 2855, 2855, 2855, 2855, 2855, 2855, 2856, 2856, + 2857, 2857, 0, 2857, 2857, 2857, 2857, 2857, 2857, 2857, + + 2857, 2857, 2858, 2858, 0, 2858, 2858, 2858, 2858, 2858, + 2858, 2858, 2858, 2858, 2859, 2859, 0, 2859, 2859, 2859, + 2859, 2859, 2859, 2859, 2859, 2859, 2860, 2860, 2861, 2861, + 2862, 2862, 0, 2862, 2862, 2862, 2862, 2862, 2862, 2862, + 2862, 2862, 2863, 2863, 0, 2863, 2863, 2863, 2863, 2863, + 2863, 2863, 2863, 2863, 2864, 2864, 2865, 2865, 0, 2865, + 2865, 2865, 2865, 2865, 2865, 2865, 2865, 2865, 2866, 2866, + 0, 2866, 2866, 2866, 2866, 2866, 2866, 2866, 2866, 2866, + 2867, 2867, 0, 2867, 2867, 2867, 2867, 2867, 2867, 2867, + 2867, 2867, 2868, 2868, 2868, 2868, 2868, 2868, 2868, 2868, + + 2868, 2868, 2868, 2868, 2869, 2869, 0, 0, 2869, 2870, + 2870, 2871, 2871, 0, 0, 2871, 2872, 2872, 2873, 0, + 2873, 2874, 0, 2874, 2875, 2875, 0, 2875, 2875, 2875, + 2875, 2875, 2875, 2875, 2875, 2875, 2876, 2876, 0, 2876, + 2876, 2876, 2876, 2876, 2876, 2876, 2876, 2876, 2877, 2877, + 0, 2877, 2877, 2877, 2877, 2877, 2877, 2877, 2877, 2877, + 2878, 2878, 0, 2878, 2878, 2878, 2878, 2878, 2878, 2878, + 2878, 2878, 2879, 2879, 2879, 2879, 2879, 2879, 2879, 2879, + 2879, 2879, 2879, 2879, 2880, 2880, 2881, 2881, 2881, 2881, + 2881, 2881, 2881, 2881, 2881, 2881, 2881, 2881, 2882, 2882, + + 0, 2882, 2882, 2882, 2882, 2882, 2882, 2882, 2882, 2882, + 2883, 2883, 2883, 2883, 2883, 2883, 2883, 2883, 2883, 2883, + 2883, 2883, 2884, 2884, 2885, 2885, 2886, 2886, 0, 2886, + 2886, 2886, 2886, 2886, 2886, 2886, 2886, 2886, 2887, 2887, + 2887, 2887, 2887, 2887, 2887, 2887, 2887, 2887, 2887, 2887, + 2888, 2888, 0, 0, 2888, 2889, 2889, 2889, 2889, 2889, + 2889, 2889, 2889, 2889, 2889, 2889, 2889, 2890, 2890, 2890, + 2890, 2890, 2890, 2890, 2890, 2890, 2890, 2890, 2890, 2891, + 2891, 2891, 2892, 2892, 0, 2892, 2892, 2892, 2892, 2892, + 2892, 2892, 2892, 2892, 2893, 2893, 0, 2893, 2893, 2893, + + 2893, 2893, 2893, 2893, 2893, 2893, 2894, 2894, 2894, 2895, + 2895, 0, 2895, 2895, 2895, 2895, 2895, 2895, 2895, 2895, + 2895, 2896, 2896, 0, 0, 2896, 2897, 2897, 0, 0, + 0, 0, 0, 2897, 2898, 2898, 2899, 2899, 0, 0, + 2899, 2899, 2900, 2900, 2900, 2901, 2901, 2901, 2902, 2902, + 2903, 2903, 0, 0, 0, 0, 0, 2903, 2904, 0, + 2904, 2905, 0, 2905, 2906, 2906, 2906, 2906, 2906, 2906, + 2906, 2906, 2906, 2906, 2906, 2906, 2907, 2907, 2907, 2907, + 2907, 2907, 2907, 2907, 2907, 2907, 2907, 2907, 2908, 2908, + 2908, 2908, 2908, 2908, 2908, 2908, 2908, 2908, 2908, 2908, + + 2909, 2909, 0, 2909, 2909, 2909, 2909, 2909, 2909, 2909, + 2909, 2909, 2910, 2910, 0, 2910, 2910, 2910, 2910, 2910, + 2910, 2910, 2910, 2910, 2911, 2911, 0, 2911, 2911, 2911, + 2911, 2911, 2911, 2911, 2911, 2911, 2912, 2912, 2913, 2913, + 0, 2913, 2913, 2913, 2913, 2913, 2913, 2913, 2913, 2913, + 2914, 2914, 0, 2914, 2914, 2914, 2914, 2914, 2914, 2914, + 2914, 2914, 2915, 2915, 0, 2915, 2915, 2915, 2915, 2915, + 2915, 2915, 2915, 2915, 2916, 2916, 0, 2916, 2916, 2916, + 2916, 2916, 2916, 2916, 2916, 2916, 2917, 2917, 2918, 2918, + 2919, 2919, 0, 2919, 2919, 2919, 2919, 2919, 2919, 2919, + + 2919, 2919, 2920, 2920, 0, 2920, 2920, 2920, 2920, 2920, + 2920, 2920, 2920, 2920, 2921, 2921, 0, 2921, 2921, 2921, + 2921, 2921, 2921, 2921, 2921, 2921, 2922, 2922, 0, 0, + 2922, 2923, 2923, 0, 2923, 2923, 2923, 2923, 2923, 2923, + 2923, 2923, 2923, 2924, 2924, 0, 2924, 2924, 2924, 2924, + 2924, 2924, 2924, 2924, 2924, 2925, 2925, 0, 2925, 2925, + 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2926, 2926, 0, + 0, 2926, 2927, 2927, 2928, 2928, 0, 0, 2928, 2929, + 2929, 2930, 0, 2930, 2931, 0, 2931, 2932, 2932, 0, + 2932, 2932, 2932, 2932, 2932, 2932, 2932, 2932, 2932, 2933, + + 2933, 0, 2933, 2933, 2933, 2933, 2933, 2933, 2933, 2933, + 2933, 2934, 2934, 0, 2934, 2934, 2934, 2934, 2934, 2934, + 2934, 2934, 2934, 2935, 2935, 0, 2935, 2935, 2935, 2935, + 2935, 2935, 2935, 2935, 2935, 2936, 2936, 2937, 2937, 0, + 2937, 2937, 2937, 2937, 2937, 2937, 2937, 2937, 2937, 2938, + 2938, 0, 2938, 2938, 2938, 2938, 2938, 2938, 2938, 2938, + 2938, 2939, 2939, 2940, 2940, 2940, 2940, 2940, 2940, 2940, + 2940, 2940, 2940, 2940, 2940, 2941, 2941, 2941, 2941, 2941, + 2941, 2941, 2941, 2941, 2941, 2941, 2941, 2942, 2942, 2942, + 2942, 2942, 2942, 2942, 2942, 2942, 2942, 2942, 2942, 2943, + + 2943, 2943, 2943, 2943, 2943, 2943, 2943, 2943, 2943, 2943, + 2943, 2944, 2944, 2944, 2944, 2944, 2944, 2944, 2944, 2944, + 2944, 2944, 2944, 2945, 2945, 2945, 2945, 2945, 2945, 2945, + 2945, 2945, 2945, 2945, 2945, 2946, 2946, 2946, 2946, 2946, + 2946, 2946, 2946, 2946, 2946, 2946, 2946, 2947, 2947, 2947, + 2947, 2947, 2947, 2947, 2947, 2947, 2947, 2947, 2947, 2948, + 2948, 2948, 2948, 2948, 2948, 2948, 2948, 2948, 2948, 2948, + 2948, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, 2786, + 2786, 2786, 2786, 2786, 2786, 2786 } ; /* The intent behind this definition is that it'll catch @@ -5447,10 +5603,13 @@ do {\ + -#line 5455 "ob_proxy_parser_utf8_lex.c" +/* limit the length of int_num from 1 to 17 in case of int64_t out of bound, 17 -> [ ( length of 2^64 ) - 2 ]*/ +/* binlog relate SQL */ +#line 5614 "ob_proxy_parser_utf8_lex.c" #define INITIAL 0 #define hint 1 @@ -5477,9 +5636,10 @@ do {\ #define prepare 22 #define insert_all_expr 23 #define set_expr 24 -#define show_topology 25 -#define show_tables 26 -#define proxy_icmd_state 27 +#define show_elastic_id 25 +#define show_topology 26 +#define show_tables 27 +#define proxy_icmd_state 28 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way @@ -5721,11 +5881,11 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 388 "ob_proxy_parser_utf8.l" +#line 400 "ob_proxy_parser_utf8.l" /* basic dml stmt: */ -#line 5731 "ob_proxy_parser_utf8_lex.c" +#line 5891 "ob_proxy_parser_utf8_lex.c" yylval = yylval_param; @@ -5782,13 +5942,13 @@ YY_DECL while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 2597 ) + if ( yy_current_state >= 2787 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 17443 ); + while ( yy_base[yy_current_state] != 17872 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -5814,86 +5974,86 @@ YY_DECL case 1: YY_RULE_SETUP -#line 391 "ob_proxy_parser_utf8.l" +#line 403 "ob_proxy_parser_utf8.l" { SET_DML_STMT(OBPROXY_T_SELECT); PUSH_STATE(in_expr); return SELECT; } YY_BREAK case 2: YY_RULE_SETUP -#line 392 "ob_proxy_parser_utf8.l" +#line 404 "ob_proxy_parser_utf8.l" { SET_DML_STMT(OBPROXY_T_DELETE); PUSH_STATE_IF_NOT_ICMD(in_expr); return DELETE; } YY_BREAK case 3: YY_RULE_SETUP -#line 393 "ob_proxy_parser_utf8.l" +#line 405 "ob_proxy_parser_utf8.l" { SET_DML_STMT(OBPROXY_T_INSERT); return INSERT; } YY_BREAK case 4: YY_RULE_SETUP -#line 394 "ob_proxy_parser_utf8.l" +#line 406 "ob_proxy_parser_utf8.l" { SET_DML_STMT(OBPROXY_T_UPDATE); return UPDATE; } YY_BREAK case 5: YY_RULE_SETUP -#line 395 "ob_proxy_parser_utf8.l" +#line 407 "ob_proxy_parser_utf8.l" { SET_DML_STMT(OBPROXY_T_REPLACE); return REPLACE; } YY_BREAK case 6: YY_RULE_SETUP -#line 396 "ob_proxy_parser_utf8.l" +#line 408 "ob_proxy_parser_utf8.l" { SET_DML_STMT(OBPROXY_T_MERGE); return MERGE; } YY_BREAK case 7: YY_RULE_SETUP -#line 397 "ob_proxy_parser_utf8.l" +#line 409 "ob_proxy_parser_utf8.l" { SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW; } YY_BREAK case 8: YY_RULE_SETUP -#line 398 "ob_proxy_parser_utf8.l" +#line 410 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(XA); } YY_BREAK /* if begin is for starting transaction, will set has_anonymous_block = false in yacc */ case 9: YY_RULE_SETUP -#line 400 "ob_proxy_parser_utf8.l" +#line 412 "ob_proxy_parser_utf8.l" { SET_HAS_ANONYMOUS_BLOCK(); RETURN_NON_RESERVED_KEYWORD(BEGI); } YY_BREAK case 10: YY_RULE_SETUP -#line 401 "ob_proxy_parser_utf8.l" +#line 413 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(START); } YY_BREAK case 11: YY_RULE_SETUP -#line 402 "ob_proxy_parser_utf8.l" +#line 414 "ob_proxy_parser_utf8.l" { SET_BASIC_STMT(OBPROXY_T_COMMIT); RETURN_IGNORED_WORD(); } YY_BREAK case 12: YY_RULE_SETUP -#line 403 "ob_proxy_parser_utf8.l" +#line 415 "ob_proxy_parser_utf8.l" { SET_BASIC_STMT(OBPROXY_T_ROLLBACK); RETURN_IGNORED_WORD(); } YY_BREAK case 13: YY_RULE_SETUP -#line 404 "ob_proxy_parser_utf8.l" +#line 416 "ob_proxy_parser_utf8.l" { SET_BASIC_STMT(OBPROXY_T_SET); PUSH_STATE_IF_NOT_ICMD(set_expr); return SET; } YY_BREAK case 14: YY_RULE_SETUP -#line 405 "ob_proxy_parser_utf8.l" +#line 417 "ob_proxy_parser_utf8.l" { SET_BASIC_STMT(OBPROXY_T_CALL); return CALL; } YY_BREAK case 15: YY_RULE_SETUP -#line 406 "ob_proxy_parser_utf8.l" +#line 418 "ob_proxy_parser_utf8.l" { SET_HAS_ANONYMOUS_BLOCK(); PUSH_STATE(in_anonymous_block); } YY_BREAK case 16: YY_RULE_SETUP -#line 407 "ob_proxy_parser_utf8.l" +#line 419 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = ob_proxy_parser_utf8_yyget_extra(yyscanner); if (OB_NOTNULL(p)) { - if (OBPROXY_T_INSERT == p->cur_stmt_type_) + if (OBPROXY_T_INSERT == p->cur_stmt_type_) PUSH_STATE(insert_all_expr); } return WHEN; } @@ -5901,338 +6061,338 @@ YY_RULE_SETUP /* basic ddl stmt */ case 17: YY_RULE_SETUP -#line 415 "ob_proxy_parser_utf8.l" +#line 427 "ob_proxy_parser_utf8.l" { return CREATE; } YY_BREAK case 18: YY_RULE_SETUP -#line 416 "ob_proxy_parser_utf8.l" +#line 428 "ob_proxy_parser_utf8.l" { return DROP; } YY_BREAK case 19: YY_RULE_SETUP -#line 417 "ob_proxy_parser_utf8.l" +#line 429 "ob_proxy_parser_utf8.l" { return ALTER; } YY_BREAK case 20: YY_RULE_SETUP -#line 418 "ob_proxy_parser_utf8.l" +#line 430 "ob_proxy_parser_utf8.l" { return TRUNCATE; } YY_BREAK case 21: YY_RULE_SETUP -#line 419 "ob_proxy_parser_utf8.l" +#line 431 "ob_proxy_parser_utf8.l" { return RENAME; } YY_BREAK case 22: YY_RULE_SETUP -#line 420 "ob_proxy_parser_utf8.l" +#line 432 "ob_proxy_parser_utf8.l" { return INDEX; } YY_BREAK case 23: YY_RULE_SETUP -#line 421 "ob_proxy_parser_utf8.l" +#line 433 "ob_proxy_parser_utf8.l" { return TABLE; } YY_BREAK case 24: YY_RULE_SETUP -#line 422 "ob_proxy_parser_utf8.l" +#line 434 "ob_proxy_parser_utf8.l" { return STATUS; } YY_BREAK case 25: YY_RULE_SETUP -#line 423 "ob_proxy_parser_utf8.l" +#line 435 "ob_proxy_parser_utf8.l" { return FROM; } YY_BREAK case 26: YY_RULE_SETUP -#line 424 "ob_proxy_parser_utf8.l" +#line 436 "ob_proxy_parser_utf8.l" { return UNIQUE; } YY_BREAK /* ps stmt */ case 27: YY_RULE_SETUP -#line 427 "ob_proxy_parser_utf8.l" +#line 439 "ob_proxy_parser_utf8.l" { return USING; } YY_BREAK case 28: YY_RULE_SETUP -#line 428 "ob_proxy_parser_utf8.l" +#line 440 "ob_proxy_parser_utf8.l" { PUSH_STATE(prepare); return PREPARE; } YY_BREAK case 29: YY_RULE_SETUP -#line 429 "ob_proxy_parser_utf8.l" +#line 441 "ob_proxy_parser_utf8.l" { return EXECUTE; } YY_BREAK case 30: YY_RULE_SETUP -#line 430 "ob_proxy_parser_utf8.l" -{ return DEALLOCATE; } +#line 442 "ob_proxy_parser_utf8.l" +{ return DEALLOCATE; } YY_BREAK /* oracle ddl stmt */ case 31: YY_RULE_SETUP -#line 434 "ob_proxy_parser_utf8.l" +#line 446 "ob_proxy_parser_utf8.l" { return GRANT; } YY_BREAK case 32: YY_RULE_SETUP -#line 435 "ob_proxy_parser_utf8.l" +#line 447 "ob_proxy_parser_utf8.l" { return REVOKE; } YY_BREAK case 33: YY_RULE_SETUP -#line 436 "ob_proxy_parser_utf8.l" +#line 448 "ob_proxy_parser_utf8.l" { return ANALYZE; } YY_BREAK case 34: YY_RULE_SETUP -#line 437 "ob_proxy_parser_utf8.l" +#line 449 "ob_proxy_parser_utf8.l" { return PURGE; } YY_BREAK case 35: YY_RULE_SETUP -#line 438 "ob_proxy_parser_utf8.l" +#line 450 "ob_proxy_parser_utf8.l" { return COMMENT; } YY_BREAK case 36: YY_RULE_SETUP -#line 439 "ob_proxy_parser_utf8.l" +#line 451 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(FLASHBACK); } YY_BREAK case 37: YY_RULE_SETUP -#line 440 "ob_proxy_parser_utf8.l" +#line 452 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(AUDIT); } YY_BREAK case 38: YY_RULE_SETUP -#line 441 "ob_proxy_parser_utf8.l" +#line 453 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(NOAUDIT); } YY_BREAK case 39: YY_RULE_SETUP -#line 443 "ob_proxy_parser_utf8.l" +#line 455 "ob_proxy_parser_utf8.l" { return GROUP;} YY_BREAK case 40: YY_RULE_SETUP -#line 444 "ob_proxy_parser_utf8.l" +#line 456 "ob_proxy_parser_utf8.l" { return HAVING;} YY_BREAK case 41: YY_RULE_SETUP -#line 445 "ob_proxy_parser_utf8.l" +#line 457 "ob_proxy_parser_utf8.l" { return ORDER;} YY_BREAK case 42: YY_RULE_SETUP -#line 446 "ob_proxy_parser_utf8.l" +#line 458 "ob_proxy_parser_utf8.l" { return FOR;} YY_BREAK case 43: YY_RULE_SETUP -#line 447 "ob_proxy_parser_utf8.l" +#line 459 "ob_proxy_parser_utf8.l" { return UNION;} YY_BREAK case 44: YY_RULE_SETUP -#line 448 "ob_proxy_parser_utf8.l" +#line 460 "ob_proxy_parser_utf8.l" { return AS; } YY_BREAK case 45: YY_RULE_SETUP -#line 449 "ob_proxy_parser_utf8.l" +#line 461 "ob_proxy_parser_utf8.l" { return WHERE; } YY_BREAK case 46: YY_RULE_SETUP -#line 450 "ob_proxy_parser_utf8.l" +#line 462 "ob_proxy_parser_utf8.l" { return VALUES; } YY_BREAK case 47: YY_RULE_SETUP -#line 451 "ob_proxy_parser_utf8.l" +#line 463 "ob_proxy_parser_utf8.l" { return VALUES; } YY_BREAK case 48: YY_RULE_SETUP -#line 452 "ob_proxy_parser_utf8.l" +#line 464 "ob_proxy_parser_utf8.l" { SET_HAS_EXPLAIN(); return EXPLAIN; } YY_BREAK case 49: YY_RULE_SETUP -#line 453 "ob_proxy_parser_utf8.l" +#line 465 "ob_proxy_parser_utf8.l" { SET_HAS_EXPLAIN(); return DESC; } YY_BREAK case 50: YY_RULE_SETUP -#line 454 "ob_proxy_parser_utf8.l" +#line 466 "ob_proxy_parser_utf8.l" { SET_HAS_EXPLAIN(); return DESCRIBE; } YY_BREAK /*change from non_reserved to reserved according https://dev.mysql.com/doc/refman/5.6/en/keywords.html*/ case 51: YY_RULE_SETUP -#line 456 "ob_proxy_parser_utf8.l" +#line 468 "ob_proxy_parser_utf8.l" { return READ; } YY_BREAK case 52: YY_RULE_SETUP -#line 457 "ob_proxy_parser_utf8.l" +#line 469 "ob_proxy_parser_utf8.l" { return WITH; } YY_BREAK case 53: YY_RULE_SETUP -#line 458 "ob_proxy_parser_utf8.l" +#line 470 "ob_proxy_parser_utf8.l" { return USE; } YY_BREAK case 54: YY_RULE_SETUP -#line 459 "ob_proxy_parser_utf8.l" +#line 471 "ob_proxy_parser_utf8.l" { return LIMIT; } YY_BREAK case 55: YY_RULE_SETUP -#line 460 "ob_proxy_parser_utf8.l" +#line 472 "ob_proxy_parser_utf8.l" { return ALL; } YY_BREAK case 56: YY_RULE_SETUP -#line 461 "ob_proxy_parser_utf8.l" +#line 473 "ob_proxy_parser_utf8.l" { return LIKE; } YY_BREAK case 57: YY_RULE_SETUP -#line 462 "ob_proxy_parser_utf8.l" +#line 474 "ob_proxy_parser_utf8.l" { return PARTITION; } YY_BREAK case 58: YY_RULE_SETUP -#line 463 "ob_proxy_parser_utf8.l" +#line 475 "ob_proxy_parser_utf8.l" { return BINARY; } YY_BREAK case 59: YY_RULE_SETUP -#line 464 "ob_proxy_parser_utf8.l" -{ return GROUP_NAME; } +#line 476 "ob_proxy_parser_utf8.l" +{ RETURN_NON_RESERVED_KEYWORD(GROUP_NAME); } YY_BREAK /* to make bison easy, do not return these reserved keyword in non strict mode */ case 60: YY_RULE_SETUP -#line 467 "ob_proxy_parser_utf8.l" +#line 479 "ob_proxy_parser_utf8.l" { RETURN_IGNORED_WORD(); } YY_BREAK case 61: YY_RULE_SETUP -#line 468 "ob_proxy_parser_utf8.l" +#line 480 "ob_proxy_parser_utf8.l" { RETURN_IGNORED_WORD(); } YY_BREAK case 62: YY_RULE_SETUP -#line 469 "ob_proxy_parser_utf8.l" +#line 481 "ob_proxy_parser_utf8.l" { RETURN_IGNORED_WORD(); } YY_BREAK case 63: YY_RULE_SETUP -#line 470 "ob_proxy_parser_utf8.l" +#line 482 "ob_proxy_parser_utf8.l" { RETURN_IGNORED_WORD(); } YY_BREAK case 64: YY_RULE_SETUP -#line 471 "ob_proxy_parser_utf8.l" +#line 483 "ob_proxy_parser_utf8.l" { RETURN_IGNORED_WORD(); } YY_BREAK /* no reserved keyword , don't forget to add these keyword in .y */ /*refer: https://dev.mysql.com/doc/refman/5.6/en/keywords.html*/ case 65: YY_RULE_SETUP -#line 475 "ob_proxy_parser_utf8.l" +#line 487 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(QUICK); } YY_BREAK case 66: YY_RULE_SETUP -#line 476 "ob_proxy_parser_utf8.l" +#line 488 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(COUNT); } YY_BREAK case 67: YY_RULE_SETUP -#line 477 "ob_proxy_parser_utf8.l" +#line 489 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(WARNINGS); } YY_BREAK case 68: YY_RULE_SETUP -#line 478 "ob_proxy_parser_utf8.l" +#line 490 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(ERRORS); } YY_BREAK case 69: YY_RULE_SETUP -#line 479 "ob_proxy_parser_utf8.l" +#line 491 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(TRACE); } YY_BREAK case 70: YY_RULE_SETUP -#line 480 "ob_proxy_parser_utf8.l" +#line 492 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(TRANSACTION); } YY_BREAK case 71: YY_RULE_SETUP -#line 482 "ob_proxy_parser_utf8.l" +#line 494 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(ONLY); } YY_BREAK case 72: YY_RULE_SETUP -#line 484 "ob_proxy_parser_utf8.l" +#line 496 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(CONSISTENT); } YY_BREAK case 73: YY_RULE_SETUP -#line 485 "ob_proxy_parser_utf8.l" +#line 497 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(SNAPSHOT); } YY_BREAK case 74: YY_RULE_SETUP -#line 487 "ob_proxy_parser_utf8.l" +#line 499 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(HELP); } YY_BREAK /*set names*/ case 75: /* rule 75 can match eol */ YY_RULE_SETUP -#line 491 "ob_proxy_parser_utf8.l" +#line 503 "ob_proxy_parser_utf8.l" { SET_BASIC_STMT(OBPROXY_T_SET_NAMES); return SET_NAMES; } YY_BREAK /*set charset*/ case 76: /* rule 76 can match eol */ YY_RULE_SETUP -#line 493 "ob_proxy_parser_utf8.l" +#line 505 "ob_proxy_parser_utf8.l" { SET_BASIC_STMT(OBPROXY_T_SET_CHARSET); return SET_CHARSET; } YY_BREAK /*set passwd*/ case 77: /* rule 77 can match eol */ YY_RULE_SETUP -#line 495 "ob_proxy_parser_utf8.l" +#line 507 "ob_proxy_parser_utf8.l" { SET_BASIC_STMT(OBPROXY_T_SET_PASSWORD); return SET_PASSWORD; } YY_BREAK /*set default*/ case 78: /* rule 78 can match eol */ YY_RULE_SETUP -#line 497 "ob_proxy_parser_utf8.l" +#line 509 "ob_proxy_parser_utf8.l" { SET_BASIC_STMT(OBPROXY_T_SET_DEFAULT); return SET_DEFAULT; } YY_BREAK case 79: /* rule 79 can match eol */ YY_RULE_SETUP -#line 499 "ob_proxy_parser_utf8.l" +#line 511 "ob_proxy_parser_utf8.l" { SET_BASIC_STMT(OBPROXY_T_SET_OB_READ_CONSISTENCY); return SET_OB_READ_CONSISTENCY; } YY_BREAK case 80: /* rule 80 can match eol */ YY_RULE_SETUP -#line 500 "ob_proxy_parser_utf8.l" +#line 512 "ob_proxy_parser_utf8.l" { SET_BASIC_STMT(OBPROXY_T_SET_TX_READ_ONLY); return SET_TX_READ_ONLY; } YY_BREAK /*internal cmd*/ @@ -6240,453 +6400,459 @@ YY_RULE_SETUP case 81: /* rule 81 can match eol */ YY_RULE_SETUP -#line 504 "ob_proxy_parser_utf8.l" +#line 516 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_NET); return SHOW_PROXYNET; } YY_BREAK case 82: YY_RULE_SETUP -#line 505 "ob_proxy_parser_utf8.l" +#line 517 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(THREAD); } YY_BREAK case 83: YY_RULE_SETUP -#line 506 "ob_proxy_parser_utf8.l" +#line 518 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(CONNECTION); } YY_BREAK case 84: YY_RULE_SETUP -#line 508 "ob_proxy_parser_utf8.l" +#line 520 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(OFFSET); } YY_BREAK /*show session*/ case 85: /* rule 85 can match eol */ YY_RULE_SETUP -#line 511 "ob_proxy_parser_utf8.l" +#line 523 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_GLOBAL_SESSION); return SHOW_GLOBALSESSION; } YY_BREAK case 86: /* rule 86 can match eol */ YY_RULE_SETUP -#line 512 "ob_proxy_parser_utf8.l" +#line 524 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_SESSION); return SHOW_PROXYSESSION; } YY_BREAK case 87: /* rule 87 can match eol */ YY_RULE_SETUP -#line 513 "ob_proxy_parser_utf8.l" +#line 525 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_PROCESSLIST); return SHOW_PROCESSLIST; } YY_BREAK case 88: YY_RULE_SETUP -#line 514 "ob_proxy_parser_utf8.l" +#line 526 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(ATTRIBUTE); } YY_BREAK case 89: YY_RULE_SETUP -#line 515 "ob_proxy_parser_utf8.l" +#line 527 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(VARIABLES); } YY_BREAK case 90: YY_RULE_SETUP -#line 517 "ob_proxy_parser_utf8.l" +#line 529 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(STAT); } YY_BREAK /*show config*/ case 91: /* rule 91 can match eol */ YY_RULE_SETUP -#line 520 "ob_proxy_parser_utf8.l" +#line 532 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_CONFIG); PUSH_STATE(proxy_icmd_state); return SHOW_PROXYCONFIG; } YY_BREAK case 92: YY_RULE_SETUP -#line 522 "ob_proxy_parser_utf8.l" +#line 534 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(DIFF); } YY_BREAK case 93: YY_RULE_SETUP -#line 523 "ob_proxy_parser_utf8.l" +#line 535 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(USER); } YY_BREAK case 94: YY_RULE_SETUP -#line 524 "ob_proxy_parser_utf8.l" +#line 536 "ob_proxy_parser_utf8.l" { POP_STATE(); return LIKE; } YY_BREAK /*show sm*/ case 95: /* rule 95 can match eol */ YY_RULE_SETUP -#line 527 "ob_proxy_parser_utf8.l" +#line 539 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_SM); return SHOW_PROXYSM; } YY_BREAK /*show cluster*/ case 96: /* rule 96 can match eol */ YY_RULE_SETUP -#line 530 "ob_proxy_parser_utf8.l" +#line 542 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_CLUSTER); return SHOW_PROXYCLUSTER; } YY_BREAK /*show resource*/ case 97: /* rule 97 can match eol */ YY_RULE_SETUP -#line 533 "ob_proxy_parser_utf8.l" +#line 545 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_RESOURCE); return SHOW_PROXYRESOURCE; } YY_BREAK /*show congestion*/ case 98: /* rule 98 can match eol */ YY_RULE_SETUP -#line 536 "ob_proxy_parser_utf8.l" +#line 548 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_CONGESTION); return SHOW_PROXYCONGESTION; } YY_BREAK /*show route*/ case 99: /* rule 99 can match eol */ YY_RULE_SETUP -#line 539 "ob_proxy_parser_utf8.l" +#line 551 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_ROUTE); return SHOW_PROXYROUTE; } YY_BREAK case 100: YY_RULE_SETUP -#line 541 "ob_proxy_parser_utf8.l" +#line 553 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(ROUTINE); } YY_BREAK /*show vip*/ case 101: /* rule 101 can match eol */ YY_RULE_SETUP -#line 544 "ob_proxy_parser_utf8.l" +#line 556 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_VIP); return SHOW_PROXYVIP; } YY_BREAK /*show memory*/ case 102: /* rule 102 can match eol */ YY_RULE_SETUP -#line 547 "ob_proxy_parser_utf8.l" +#line 559 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_MEMORY); return SHOW_PROXYMEMORY; } YY_BREAK case 103: YY_RULE_SETUP -#line 548 "ob_proxy_parser_utf8.l" +#line 560 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(OBJPOOL); } YY_BREAK /*show sqlaudit*/ case 104: /* rule 104 can match eol */ YY_RULE_SETUP -#line 551 "ob_proxy_parser_utf8.l" +#line 563 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_SQLAUDIT); return SHOW_SQLAUDIT; } YY_BREAK /*show warnlog*/ case 105: /* rule 105 can match eol */ YY_RULE_SETUP -#line 554 "ob_proxy_parser_utf8.l" +#line 566 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_WARNLOG); return SHOW_WARNLOG; } YY_BREAK /*show stat*/ case 106: /* rule 106 can match eol */ YY_RULE_SETUP -#line 557 "ob_proxy_parser_utf8.l" +#line 569 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_STAT); return SHOW_PROXYSTAT; } YY_BREAK case 107: YY_RULE_SETUP -#line 558 "ob_proxy_parser_utf8.l" +#line 570 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(REFRESH); } YY_BREAK /*show trace*/ case 108: /* rule 108 can match eol */ YY_RULE_SETUP -#line 561 "ob_proxy_parser_utf8.l" +#line 573 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_TRACE); return SHOW_PROXYTRACE; } YY_BREAK /*show info*/ case 109: /* rule 109 can match eol */ YY_RULE_SETUP -#line 564 "ob_proxy_parser_utf8.l" +#line 576 "ob_proxy_parser_utf8.l" { SET_ICMD_STMT(OBPROXY_T_ICMD_SHOW_INFO); return SHOW_PROXYINFO; } YY_BREAK case 110: YY_RULE_SETUP -#line 565 "ob_proxy_parser_utf8.l" +#line 577 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(UPGRADE); } YY_BREAK case 111: YY_RULE_SETUP -#line 566 "ob_proxy_parser_utf8.l" +#line 578 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(IDC); } YY_BREAK case 112: /* rule 112 can match eol */ YY_RULE_SETUP -#line 568 "ob_proxy_parser_utf8.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_topology); return SHOW_TOPOLOGY; } +#line 580 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_elastic_id ); return SHOW_ELASTIC_ID; } YY_BREAK case 113: YY_RULE_SETUP -#line 569 "ob_proxy_parser_utf8.l" +#line 581 "ob_proxy_parser_utf8.l" { POP_STATE(); PUSH_STATE(INITIAL); return FROM; } YY_BREAK case 114: YY_RULE_SETUP -#line 570 "ob_proxy_parser_utf8.l" +#line 582 "ob_proxy_parser_utf8.l" { POP_STATE(); PUSH_STATE(INITIAL); return WHERE; } YY_BREAK -case YY_STATE_EOF(show_topology): -#line 571 "ob_proxy_parser_utf8.l" +case YY_STATE_EOF(show_elastic_id): +#line 583 "ob_proxy_parser_utf8.l" { return END_P; } YY_BREAK case 115: /* rule 115 can match eol */ YY_RULE_SETUP -#line 572 "ob_proxy_parser_utf8.l" +#line 584 "ob_proxy_parser_utf8.l" { } YY_BREAK case 116: YY_RULE_SETUP -#line 573 "ob_proxy_parser_utf8.l" +#line 585 "ob_proxy_parser_utf8.l" { POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } YY_BREAK case 117: YY_RULE_SETUP -#line 574 "ob_proxy_parser_utf8.l" +#line 586 "ob_proxy_parser_utf8.l" { return ERROR; } YY_BREAK case 118: /* rule 118 can match eol */ YY_RULE_SETUP -#line 576 "ob_proxy_parser_utf8.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_DB_VERSION; } +#line 588 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_TOPOLOGY; } YY_BREAK case 119: /* rule 119 can match eol */ YY_RULE_SETUP -#line 577 "ob_proxy_parser_utf8.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_DATABASES; } +#line 590 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_DB_VERSION; } YY_BREAK case 120: /* rule 120 can match eol */ YY_RULE_SETUP -#line 579 "ob_proxy_parser_utf8.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_tables); return SHOW_TABLES; } +#line 591 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_DATABASES; } YY_BREAK case 121: /* rule 121 can match eol */ YY_RULE_SETUP -#line 580 "ob_proxy_parser_utf8.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_tables); return SHOW_FULL_TABLES; } +#line 593 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_tables); return SHOW_TABLES; } YY_BREAK case 122: +/* rule 122 can match eol */ YY_RULE_SETUP -#line 582 "ob_proxy_parser_utf8.l" -{ POP_STATE(); PUSH_STATE(INITIAL); return FROM; } +#line 594 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); PUSH_STATE(show_tables); return SHOW_FULL_TABLES; } YY_BREAK case 123: YY_RULE_SETUP -#line 583 "ob_proxy_parser_utf8.l" +#line 596 "ob_proxy_parser_utf8.l" +{ POP_STATE(); PUSH_STATE(INITIAL); return FROM; } + YY_BREAK +case 124: +YY_RULE_SETUP +#line 597 "ob_proxy_parser_utf8.l" { POP_STATE(); PUSH_STATE(INITIAL); return LIKE; } YY_BREAK case YY_STATE_EOF(show_tables): -#line 584 "ob_proxy_parser_utf8.l" +#line 598 "ob_proxy_parser_utf8.l" { return END_P; } YY_BREAK -case 124: -/* rule 124 can match eol */ -YY_RULE_SETUP -#line 585 "ob_proxy_parser_utf8.l" -{ } - YY_BREAK case 125: +/* rule 125 can match eol */ YY_RULE_SETUP -#line 586 "ob_proxy_parser_utf8.l" -{ POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } +#line 599 "ob_proxy_parser_utf8.l" +{ } YY_BREAK case 126: YY_RULE_SETUP -#line 587 "ob_proxy_parser_utf8.l" -{ return ERROR; } +#line 600 "ob_proxy_parser_utf8.l" +{ POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } YY_BREAK case 127: -/* rule 127 can match eol */ YY_RULE_SETUP -#line 588 "ob_proxy_parser_utf8.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_COLUMNS; } +#line 601 "ob_proxy_parser_utf8.l" +{ return ERROR; } YY_BREAK case 128: /* rule 128 can match eol */ YY_RULE_SETUP -#line 589 "ob_proxy_parser_utf8.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_INDEX; } +#line 602 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_COLUMNS; } YY_BREAK case 129: /* rule 129 can match eol */ YY_RULE_SETUP -#line 591 "ob_proxy_parser_utf8.l" -{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_CREATE_TABLE; } +#line 603 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_INDEX; } YY_BREAK case 130: /* rule 130 can match eol */ YY_RULE_SETUP -#line 592 "ob_proxy_parser_utf8.l" -{ SET_DML_STMT(OBPROXY_T_SELECT); return SELECT_DATABASE; } +#line 605 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW); return SHOW_CREATE_TABLE; } YY_BREAK case 131: /* rule 131 can match eol */ YY_RULE_SETUP -#line 593 "ob_proxy_parser_utf8.l" -{ SET_DML_STMT(OBPROXY_T_SELECT_PROXY_VERSION); return SELECT_PROXY_VERSION; } +#line 606 "ob_proxy_parser_utf8.l" +{ SET_DML_STMT(OBPROXY_T_SELECT); return SELECT_DATABASE; } YY_BREAK -/*alter config*/ case 132: /* rule 132 can match eol */ YY_RULE_SETUP -#line 596 "ob_proxy_parser_utf8.l" -{ SET_ICMD_STMT(OBPROXY_T_ICMD_ALTER_CONFIG); return ALTER_PROXYCONFIG; } +#line 607 "ob_proxy_parser_utf8.l" +{ SET_DML_STMT(OBPROXY_T_SELECT_PROXY_VERSION); return SELECT_PROXY_VERSION; } YY_BREAK -/*alter resource*/ +/*alter config*/ case 133: /* rule 133 can match eol */ YY_RULE_SETUP -#line 599 "ob_proxy_parser_utf8.l" -{ SET_ICMD_STMT(OBPROXY_T_ICMD_ALTER_RESOURCE); return ALTER_PROXYRESOURCE; } +#line 610 "ob_proxy_parser_utf8.l" +{ SET_ICMD_STMT(OBPROXY_T_ICMD_ALTER_CONFIG); return ALTER_PROXYCONFIG; } YY_BREAK -/*ping proxy*/ +/*alter resource*/ case 134: /* rule 134 can match eol */ YY_RULE_SETUP -#line 602 "ob_proxy_parser_utf8.l" -{ SET_ICMD_STMT(OBPROXY_T_PING_PROXY); return PING_PROXY; } +#line 613 "ob_proxy_parser_utf8.l" +{ SET_ICMD_STMT(OBPROXY_T_ICMD_ALTER_RESOURCE); return ALTER_PROXYRESOURCE; } YY_BREAK -/*kill*/ +/*ping proxy*/ case 135: /* rule 135 can match eol */ YY_RULE_SETUP -#line 605 "ob_proxy_parser_utf8.l" -{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_SESSION); return KILL_PROXYSESSION; } +#line 616 "ob_proxy_parser_utf8.l" +{ SET_ICMD_STMT(OBPROXY_T_PING_PROXY); return PING_PROXY; } YY_BREAK +/*kill*/ case 136: /* rule 136 can match eol */ YY_RULE_SETUP -#line 606 "ob_proxy_parser_utf8.l" -{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_GLOBAL_SESSION); return KILL_GLOBALSESSION; } +#line 619 "ob_proxy_parser_utf8.l" +{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_SESSION); return KILL_PROXYSESSION; } YY_BREAK case 137: +/* rule 137 can match eol */ YY_RULE_SETUP -#line 607 "ob_proxy_parser_utf8.l" -{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_MYSQL); return KILL; } +#line 620 "ob_proxy_parser_utf8.l" +{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_GLOBAL_SESSION); return KILL_GLOBALSESSION; } YY_BREAK case 138: YY_RULE_SETUP -#line 608 "ob_proxy_parser_utf8.l" -{ RETURN_NON_RESERVED_KEYWORD(QUERY); } +#line 621 "ob_proxy_parser_utf8.l" +{ SET_ICMD_STMT(OBPROXY_T_ICMD_KILL_MYSQL); return KILL; } YY_BREAK -/* obproxy_route_addr */ case 139: -/* rule 139 can match eol */ YY_RULE_SETUP -#line 611 "ob_proxy_parser_utf8.l" -{ return SELECT_OBPROXY_ROUTE_ADDR; } +#line 622 "ob_proxy_parser_utf8.l" +{ RETURN_NON_RESERVED_KEYWORD(QUERY); } YY_BREAK +/* obproxy_route_addr */ case 140: /* rule 140 can match eol */ YY_RULE_SETUP -#line 612 "ob_proxy_parser_utf8.l" +#line 625 "ob_proxy_parser_utf8.l" +{ return SELECT_OBPROXY_ROUTE_ADDR; } + YY_BREAK +case 141: +/* rule 141 can match eol */ +YY_RULE_SETUP +#line 626 "ob_proxy_parser_utf8.l" { return SET_OBPROXY_ROUTE_ADDR; } YY_BREAK /* identifer */ -case 141: +case 142: YY_RULE_SETUP -#line 615 "ob_proxy_parser_utf8.l" +#line 629 "ob_proxy_parser_utf8.l" { SET_FOUND_ROWS(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 142: +case 143: YY_RULE_SETUP -#line 616 "ob_proxy_parser_utf8.l" +#line 630 "ob_proxy_parser_utf8.l" { SET_ROW_COUNT(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 143: +case 144: YY_RULE_SETUP -#line 617 "ob_proxy_parser_utf8.l" +#line 631 "ob_proxy_parser_utf8.l" { SET_LAST_INSERT_ID(); RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 144: +case 145: YY_RULE_SETUP -#line 618 "ob_proxy_parser_utf8.l" +#line 632 "ob_proxy_parser_utf8.l" { return ','; } YY_BREAK -case 145: +case 146: YY_RULE_SETUP -#line 619 "ob_proxy_parser_utf8.l" +#line 633 "ob_proxy_parser_utf8.l" { RETURN_INT_NUM(); } YY_BREAK -case 146: +case 147: YY_RULE_SETUP -#line 620 "ob_proxy_parser_utf8.l" +#line 634 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 147: +case 148: YY_RULE_SETUP -#line 621 "ob_proxy_parser_utf8.l" +#line 635 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_SINGLE); } YY_BREAK -case 148: +case 149: YY_RULE_SETUP -#line 622 "ob_proxy_parser_utf8.l" +#line 636 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_DOUBLE); } YY_BREAK -case 149: +case 150: YY_RULE_SETUP -#line 623 "ob_proxy_parser_utf8.l" +#line 637 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_BACK); } YY_BREAK -case 150: +case 151: YY_RULE_SETUP -#line 624 "ob_proxy_parser_utf8.l" +#line 638 "ob_proxy_parser_utf8.l" { RETURN_NUMBER_VAL(); } YY_BREAK -case 151: +case 152: YY_RULE_SETUP -#line 625 "ob_proxy_parser_utf8.l" +#line 639 "ob_proxy_parser_utf8.l" { return PLACE_HOLDER; } YY_BREAK -case 152: +case 153: YY_RULE_SETUP -#line 626 "ob_proxy_parser_utf8.l" +#line 640 "ob_proxy_parser_utf8.l" { return yytext[0]; } YY_BREAK -case 153: +case 154: YY_RULE_SETUP -#line 627 "ob_proxy_parser_utf8.l" +#line 641 "ob_proxy_parser_utf8.l" { RETURN_WITH_CALL_CHECK(yytext[0]); } YY_BREAK -case 154: +case 155: YY_RULE_SETUP -#line 628 "ob_proxy_parser_utf8.l" +#line 642 "ob_proxy_parser_utf8.l" { RETURN_WITH_CALL_CHECK('('); } YY_BREAK -case 155: +case 156: YY_RULE_SETUP -#line 629 "ob_proxy_parser_utf8.l" +#line 643 "ob_proxy_parser_utf8.l" { RETURN_WITH_CALL_CHECK(')'); } YY_BREAK -case 156: -/* rule 156 can match eol */ +case 157: +/* rule 157 can match eol */ YY_RULE_SETUP -#line 630 "ob_proxy_parser_utf8.l" +#line 644 "ob_proxy_parser_utf8.l" { } YY_BREAK /* hint option */ -case 157: -/* rule 157 can match eol */ +case 158: +/* rule 158 can match eol */ YY_RULE_SETUP -#line 633 "ob_proxy_parser_utf8.l" +#line 647 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_expr); PUSH_STATE(hint); @@ -6694,20 +6860,20 @@ YY_RULE_SETUP return SELECT_HINT_BEGIN; } YY_BREAK -case 158: -/* rule 158 can match eol */ +case 159: +/* rule 159 can match eol */ YY_RULE_SETUP -#line 639 "ob_proxy_parser_utf8.l" +#line 653 "ob_proxy_parser_utf8.l" { PUSH_STATE(hint); SET_BASIC_STMT(OBPROXY_T_UPDATE); return UPDATE_HINT_BEGIN; } YY_BREAK -case 159: -/* rule 159 can match eol */ +case 160: +/* rule 160 can match eol */ YY_RULE_SETUP -#line 644 "ob_proxy_parser_utf8.l" +#line 658 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_expr); PUSH_STATE(hint); @@ -6715,95 +6881,125 @@ YY_RULE_SETUP return DELETE_HINT_BEGIN; } YY_BREAK -case 160: -/* rule 160 can match eol */ +case 161: +/* rule 161 can match eol */ YY_RULE_SETUP -#line 650 "ob_proxy_parser_utf8.l" +#line 664 "ob_proxy_parser_utf8.l" { PUSH_STATE(hint); SET_BASIC_STMT(OBPROXY_T_INSERT); return INSERT_HINT_BEGIN; } YY_BREAK -case 161: -/* rule 161 can match eol */ +case 162: +/* rule 162 can match eol */ YY_RULE_SETUP -#line 655 "ob_proxy_parser_utf8.l" +#line 669 "ob_proxy_parser_utf8.l" { PUSH_STATE(hint); SET_BASIC_STMT(OBPROXY_T_REPLACE); return REPLACE_HINT_BEGIN; } YY_BREAK -case 162: -/* rule 162 can match eol */ +case 163: +/* rule 163 can match eol */ YY_RULE_SETUP -#line 660 "ob_proxy_parser_utf8.l" +#line 674 "ob_proxy_parser_utf8.l" { PUSH_STATE(hint); SET_BASIC_STMT(OBPROXY_T_MERGE); return MERGE_HINT_BEGIN; } YY_BREAK -case 163: -/* rule 163 can match eol */ +case 164: +/* rule 164 can match eol */ YY_RULE_SETUP -#line 666 "ob_proxy_parser_utf8.l" -{ return AUTOCOMMIT_0; } +#line 680 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW_MASTER_STATUS); return SHOW_MASTER_STATUS; } YY_BREAK -case 164: +case 165: +/* rule 165 can match eol */ +YY_RULE_SETUP +#line 681 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW_BINARY_LOGS); return SHOW_BINARY_LOGS; } + YY_BREAK +case 166: +/* rule 166 can match eol */ +YY_RULE_SETUP +#line 682 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW_BINLOG_EVENTS); return SHOW_BINLOG_EVENTS; } + YY_BREAK +case 167: +/* rule 167 can match eol */ +YY_RULE_SETUP +#line 683 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_PURGE_BINARY_LOGS); return PURGE_BINARY_LOGS; } + YY_BREAK +case 168: +/* rule 168 can match eol */ YY_RULE_SETUP -#line 667 "ob_proxy_parser_utf8.l" +#line 684 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_RESET_MASTER); return RESET_MASTER; } + YY_BREAK +case 169: +/* rule 169 can match eol */ +YY_RULE_SETUP +#line 685 "ob_proxy_parser_utf8.l" +{ SET_BASIC_STMT(OBPROXY_T_SHOW_BINLOG_SERVER_FOR_TENANT); return SHOW_BINLOG_SERVER_FOR_TENANT; } + YY_BREAK +case 170: +YY_RULE_SETUP +#line 687 "ob_proxy_parser_utf8.l" { return GLOBAL; } YY_BREAK -case 165: +case 171: YY_RULE_SETUP -#line 668 "ob_proxy_parser_utf8.l" +#line 688 "ob_proxy_parser_utf8.l" { return SESSION; } YY_BREAK -case 166: +case 172: YY_RULE_SETUP -#line 669 "ob_proxy_parser_utf8.l" +#line 689 "ob_proxy_parser_utf8.l" { RETURN_INT_NUM(); } YY_BREAK -case 167: +case 173: YY_RULE_SETUP -#line 670 "ob_proxy_parser_utf8.l" +#line 690 "ob_proxy_parser_utf8.l" { return ','; } YY_BREAK -case 168: +case 174: YY_RULE_SETUP -#line 671 "ob_proxy_parser_utf8.l" +#line 691 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 169: +case 175: YY_RULE_SETUP -#line 672 "ob_proxy_parser_utf8.l" +#line 692 "ob_proxy_parser_utf8.l" { RETURN_NUMBER_VAL(); } YY_BREAK -case 170: -/* rule 170 can match eol */ +case 176: +/* rule 176 can match eol */ YY_RULE_SETUP -#line 673 "ob_proxy_parser_utf8.l" +#line 693 "ob_proxy_parser_utf8.l" { } YY_BREAK -case 171: +case 177: YY_RULE_SETUP -#line 674 "ob_proxy_parser_utf8.l" +#line 694 "ob_proxy_parser_utf8.l" { return yytext[0]; } YY_BREAK case YY_STATE_EOF(set_expr): -#line 675 "ob_proxy_parser_utf8.l" +#line 695 "ob_proxy_parser_utf8.l" { return END_P; } YY_BREAK -case 172: +case 178: YY_RULE_SETUP -#line 676 "ob_proxy_parser_utf8.l" +#line 696 "ob_proxy_parser_utf8.l" { POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } YY_BREAK -case 173: +case 179: YY_RULE_SETUP -#line 678 "ob_proxy_parser_utf8.l" +#line 698 "ob_proxy_parser_utf8.l" { PUSH_STATE(sq); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6814,9 +7010,9 @@ YY_RULE_SETUP } } YY_BREAK -case 174: +case 180: YY_RULE_SETUP -#line 688 "ob_proxy_parser_utf8.l" +#line 708 "ob_proxy_parser_utf8.l" { PUSH_STATE(dq); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6827,9 +7023,9 @@ YY_RULE_SETUP } } YY_BREAK -case 175: +case 181: YY_RULE_SETUP -#line 698 "ob_proxy_parser_utf8.l" +#line 718 "ob_proxy_parser_utf8.l" { PUSH_STATE(bt); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6840,90 +7036,90 @@ YY_RULE_SETUP } } YY_BREAK -case 176: +case 182: YY_RULE_SETUP -#line 707 "ob_proxy_parser_utf8.l" +#line 727 "ob_proxy_parser_utf8.l" { return ERROR; } YY_BREAK -case 177: +case 183: YY_RULE_SETUP -#line 709 "ob_proxy_parser_utf8.l" +#line 729 "ob_proxy_parser_utf8.l" { POP_STATE(); RETURN_IGNORED_WORD(); } YY_BREAK -case 178: +case 184: YY_RULE_SETUP -#line 710 "ob_proxy_parser_utf8.l" +#line 730 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 179: +case 185: YY_RULE_SETUP -#line 712 "ob_proxy_parser_utf8.l" +#line 732 "ob_proxy_parser_utf8.l" { return '('; } YY_BREAK -case 180: +case 186: YY_RULE_SETUP -#line 713 "ob_proxy_parser_utf8.l" +#line 733 "ob_proxy_parser_utf8.l" { return ')'; } YY_BREAK -case 181: +case 187: YY_RULE_SETUP -#line 714 "ob_proxy_parser_utf8.l" +#line 734 "ob_proxy_parser_utf8.l" { return QUERY_TIMEOUT; } YY_BREAK -case 182: +case 188: YY_RULE_SETUP -#line 715 "ob_proxy_parser_utf8.l" +#line 735 "ob_proxy_parser_utf8.l" { RETURN_INT_NUM(); } YY_BREAK -case 183: +case 189: YY_RULE_SETUP -#line 716 "ob_proxy_parser_utf8.l" +#line 736 "ob_proxy_parser_utf8.l" { return READ_CONSISTENCY; } YY_BREAK -case 184: +case 190: YY_RULE_SETUP -#line 717 "ob_proxy_parser_utf8.l" +#line 737 "ob_proxy_parser_utf8.l" { return WEAK; } YY_BREAK -case 185: +case 191: YY_RULE_SETUP -#line 718 "ob_proxy_parser_utf8.l" +#line 738 "ob_proxy_parser_utf8.l" { return STRONG; } YY_BREAK -case 186: +case 192: YY_RULE_SETUP -#line 719 "ob_proxy_parser_utf8.l" +#line 739 "ob_proxy_parser_utf8.l" { return FROZEN; } YY_BREAK -case 187: +case 193: YY_RULE_SETUP -#line 720 "ob_proxy_parser_utf8.l" +#line 740 "ob_proxy_parser_utf8.l" { return INDEX; } YY_BREAK -case 188: +case 194: YY_RULE_SETUP -#line 721 "ob_proxy_parser_utf8.l" +#line 741 "ob_proxy_parser_utf8.l" { return yytext[0]; } YY_BREAK -case 189: +case 195: YY_RULE_SETUP -#line 722 "ob_proxy_parser_utf8.l" +#line 742 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 190: +case 196: YY_RULE_SETUP -#line 723 "ob_proxy_parser_utf8.l" +#line 743 "ob_proxy_parser_utf8.l" { POP_STATE(); return HINT_END; } YY_BREAK -case 191: +case 197: YY_RULE_SETUP -#line 724 "ob_proxy_parser_utf8.l" +#line 744 "ob_proxy_parser_utf8.l" {} YY_BREAK /* comment */ -case 192: +case 198: YY_RULE_SETUP -#line 727 "ob_proxy_parser_utf8.l" +#line 747 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_c_comment); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6938,25 +7134,25 @@ YY_RULE_SETUP } } YY_BREAK -case 193: +case 199: YY_RULE_SETUP -#line 741 "ob_proxy_parser_utf8.l" +#line 761 "ob_proxy_parser_utf8.l" { POP_STATE(); } YY_BREAK -case 194: -/* rule 194 can match eol */ +case 200: +/* rule 200 can match eol */ YY_RULE_SETUP -#line 742 "ob_proxy_parser_utf8.l" +#line 762 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 195: +case 201: YY_RULE_SETUP -#line 743 "ob_proxy_parser_utf8.l" +#line 763 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 196: +case 202: YY_RULE_SETUP -#line 745 "ob_proxy_parser_utf8.l" +#line 765 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -6967,15 +7163,15 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 197: +case 203: YY_RULE_SETUP -#line 755 "ob_proxy_parser_utf8.l" +#line 775 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_old_comment_expr); } YY_BREAK -case 198: -/* rule 198 can match eol */ +case 204: +/* rule 204 can match eol */ YY_RULE_SETUP -#line 756 "ob_proxy_parser_utf8.l" +#line 776 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_old_comment_expr); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -6985,10 +7181,10 @@ YY_RULE_SETUP } } YY_BREAK -case 199: -/* rule 199 can match eol */ +case 205: +/* rule 205 can match eol */ YY_RULE_SETUP -#line 765 "ob_proxy_parser_utf8.l" +#line 785 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_old_comment_expr); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7000,9 +7196,9 @@ YY_RULE_SETUP } } YY_BREAK -case 200: +case 206: YY_RULE_SETUP -#line 776 "ob_proxy_parser_utf8.l" +#line 796 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7011,9 +7207,9 @@ YY_RULE_SETUP } } YY_BREAK -case 201: +case 207: YY_RULE_SETUP -#line 784 "ob_proxy_parser_utf8.l" +#line 804 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7024,29 +7220,29 @@ YY_RULE_SETUP } } YY_BREAK -case 202: +case 208: YY_RULE_SETUP -#line 794 "ob_proxy_parser_utf8.l" +#line 814 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 203: +case 209: YY_RULE_SETUP -#line 795 "ob_proxy_parser_utf8.l" +#line 815 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_SINGLE); } YY_BREAK -case 204: +case 210: YY_RULE_SETUP -#line 796 "ob_proxy_parser_utf8.l" +#line 816 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_DOUBLE); } YY_BREAK -case 205: +case 211: YY_RULE_SETUP -#line 797 "ob_proxy_parser_utf8.l" +#line 817 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD_WITH_QUOTE(NAME_OB, OBPROXY_QUOTE_T_BACK); } YY_BREAK -case 206: +case 212: YY_RULE_SETUP -#line 798 "ob_proxy_parser_utf8.l" +#line 818 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7058,160 +7254,171 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 207: +case 213: YY_RULE_SETUP -#line 808 "ob_proxy_parser_utf8.l" +#line 828 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 208: +case 214: YY_RULE_SETUP -#line 810 "ob_proxy_parser_utf8.l" +#line 830 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(ODP_COMMENT); } YY_BREAK -case 209: -/* rule 209 can match eol */ +case 215: +/* rule 215 can match eol */ YY_RULE_SETUP -#line 811 "ob_proxy_parser_utf8.l" +#line 831 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(GROUP_ID); } YY_BREAK -case 210: -/* rule 210 can match eol */ +case 216: +/* rule 216 can match eol */ YY_RULE_SETUP -#line 812 "ob_proxy_parser_utf8.l" +#line 832 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(TABLE_ID); } YY_BREAK -case 211: -/* rule 211 can match eol */ +case 217: +/* rule 217 can match eol */ YY_RULE_SETUP -#line 813 "ob_proxy_parser_utf8.l" +#line 833 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(TABLE_NAME); } YY_BREAK -case 212: -/* rule 212 can match eol */ +case 218: +/* rule 218 can match eol */ YY_RULE_SETUP -#line 814 "ob_proxy_parser_utf8.l" +#line 834 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(ELASTIC_ID); } YY_BREAK -case 213: -/* rule 213 can match eol */ +case 219: +/* rule 219 can match eol */ YY_RULE_SETUP -#line 815 "ob_proxy_parser_utf8.l" +#line 835 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(TESTLOAD); } YY_BREAK -case 214: -/* rule 214 can match eol */ +case 220: +/* rule 220 can match eol */ YY_RULE_SETUP -#line 816 "ob_proxy_parser_utf8.l" +#line 836 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(DISASTER_STATUS); } YY_BREAK -case 215: -/* rule 215 can match eol */ +case 221: +/* rule 221 can match eol */ YY_RULE_SETUP -#line 817 "ob_proxy_parser_utf8.l" +#line 837 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(TNT_ID); } YY_BREAK -case 216: -/* rule 216 can match eol */ +case 222: +/* rule 222 can match eol */ YY_RULE_SETUP -#line 818 "ob_proxy_parser_utf8.l" +#line 838 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(TRACE_ID); } YY_BREAK -case 217: -/* rule 217 can match eol */ +case 223: +/* rule 223 can match eol */ YY_RULE_SETUP -#line 819 "ob_proxy_parser_utf8.l" +#line 839 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT_NAME_OB_DOT(NAME_OB_DOT); } YY_BREAK -case 218: -/* rule 218 can match eol */ +case 224: +/* rule 224 can match eol */ YY_RULE_SETUP -#line 820 "ob_proxy_parser_utf8.l" +#line 840 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_expr); RETURN_SHARD_COMMENT(RPC_ID); } YY_BREAK -case 219: +case 225: +/* rule 225 can match eol */ YY_RULE_SETUP -#line 822 "ob_proxy_parser_utf8.l" +#line 841 "ob_proxy_parser_utf8.l" +{ PUSH_STATE(in_odp_comment_expr); return TARGET_DB_SERVER; } + YY_BREAK +case 226: +YY_RULE_SETUP +#line 843 "ob_proxy_parser_utf8.l" { return GROUP_ID; } YY_BREAK -case 220: +case 227: YY_RULE_SETUP -#line 823 "ob_proxy_parser_utf8.l" +#line 844 "ob_proxy_parser_utf8.l" { return TABLE_ID; } YY_BREAK -case 221: +case 228: YY_RULE_SETUP -#line 824 "ob_proxy_parser_utf8.l" +#line 845 "ob_proxy_parser_utf8.l" { return TABLE_NAME; } YY_BREAK -case 222: +case 229: YY_RULE_SETUP -#line 825 "ob_proxy_parser_utf8.l" +#line 846 "ob_proxy_parser_utf8.l" { return ELASTIC_ID; } YY_BREAK -case 223: +case 230: YY_RULE_SETUP -#line 826 "ob_proxy_parser_utf8.l" +#line 847 "ob_proxy_parser_utf8.l" { return TESTLOAD; } YY_BREAK -case 224: +case 231: YY_RULE_SETUP -#line 827 "ob_proxy_parser_utf8.l" +#line 848 "ob_proxy_parser_utf8.l" { return DISASTER_STATUS; } YY_BREAK -case 225: +case 232: YY_RULE_SETUP -#line 828 "ob_proxy_parser_utf8.l" +#line 849 "ob_proxy_parser_utf8.l" { return TNT_ID; } YY_BREAK -case 226: +case 233: YY_RULE_SETUP -#line 829 "ob_proxy_parser_utf8.l" +#line 850 "ob_proxy_parser_utf8.l" { return TRACE_ID; } YY_BREAK -case 227: +case 234: YY_RULE_SETUP -#line 830 "ob_proxy_parser_utf8.l" +#line 851 "ob_proxy_parser_utf8.l" { return RPC_ID; } YY_BREAK -case 228: +case 235: YY_RULE_SETUP -#line 831 "ob_proxy_parser_utf8.l" +#line 852 "ob_proxy_parser_utf8.l" +{ return TARGET_DB_SERVER; } + YY_BREAK +case 236: +YY_RULE_SETUP +#line 853 "ob_proxy_parser_utf8.l" { ENTER_QUOTE_STATE(comment_sq); } YY_BREAK -case 229: +case 237: YY_RULE_SETUP -#line 832 "ob_proxy_parser_utf8.l" +#line 854 "ob_proxy_parser_utf8.l" { return ','; } YY_BREAK -case 230: +case 238: YY_RULE_SETUP -#line 833 "ob_proxy_parser_utf8.l" +#line 855 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 231: +case 239: YY_RULE_SETUP -#line 834 "ob_proxy_parser_utf8.l" +#line 856 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_odp_comment_value_expr); return yytext[0]; } YY_BREAK -case 232: +case 240: YY_RULE_SETUP -#line 835 "ob_proxy_parser_utf8.l" +#line 857 "ob_proxy_parser_utf8.l" { return yytext[0]; } YY_BREAK -case 233: -/* rule 233 can match eol */ +case 241: +/* rule 241 can match eol */ YY_RULE_SETUP -#line 836 "ob_proxy_parser_utf8.l" +#line 858 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 234: +case 242: YY_RULE_SETUP -#line 837 "ob_proxy_parser_utf8.l" +#line 859 "ob_proxy_parser_utf8.l" { return ERROR; } YY_BREAK -case 235: +case 243: YY_RULE_SETUP -#line 838 "ob_proxy_parser_utf8.l" +#line 860 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7223,22 +7430,22 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 236: +case 244: YY_RULE_SETUP -#line 849 "ob_proxy_parser_utf8.l" +#line 871 "ob_proxy_parser_utf8.l" { ENTER_QUOTE_STATE(comment_sq); } YY_BREAK -case 237: +case 245: YY_RULE_SETUP -#line 850 "ob_proxy_parser_utf8.l" +#line 872 "ob_proxy_parser_utf8.l" { POP_STATE(); return ','; } YY_BREAK -case 238: +case 246: YY_RULE_SETUP -#line 854 "ob_proxy_parser_utf8.l" +#line 876 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7251,15 +7458,15 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 239: -/* rule 239 can match eol */ +case 247: +/* rule 247 can match eol */ YY_RULE_SETUP -#line 865 "ob_proxy_parser_utf8.l" +#line 887 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 240: +case 248: YY_RULE_SETUP -#line 866 "ob_proxy_parser_utf8.l" +#line 888 "ob_proxy_parser_utf8.l" { do { PUSH_STATE(in_odp_comment_value_expr_calc) @@ -7272,10 +7479,10 @@ YY_RULE_SETUP } while (0); } YY_BREAK -case 241: -/* rule 241 can match eol */ +case 249: +/* rule 249 can match eol */ YY_RULE_SETUP -#line 878 "ob_proxy_parser_utf8.l" +#line 900 "ob_proxy_parser_utf8.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7288,9 +7495,9 @@ YY_RULE_SETUP } } YY_BREAK -case 242: +case 250: YY_RULE_SETUP -#line 890 "ob_proxy_parser_utf8.l" +#line 912 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7298,90 +7505,95 @@ YY_RULE_SETUP } } YY_BREAK -case 243: +case 251: YY_RULE_SETUP -#line 897 "ob_proxy_parser_utf8.l" +#line 919 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_dbp_comment_expr); RETURN_SHARD_COMMENT(DBP_COMMENT); } YY_BREAK -case 244: +case 252: YY_RULE_SETUP -#line 898 "ob_proxy_parser_utf8.l" +#line 920 "ob_proxy_parser_utf8.l" { return ROUTE_TAG; } YY_BREAK -case 245: +case 253: YY_RULE_SETUP -#line 899 "ob_proxy_parser_utf8.l" +#line 921 "ob_proxy_parser_utf8.l" { return SYS_TAG; } YY_BREAK -case 246: +case 254: YY_RULE_SETUP -#line 900 "ob_proxy_parser_utf8.l" +#line 922 "ob_proxy_parser_utf8.l" { return SCAN_ALL; } YY_BREAK -case 247: +case 255: YY_RULE_SETUP -#line 901 "ob_proxy_parser_utf8.l" +#line 923 "ob_proxy_parser_utf8.l" +{ return STICKY_SESSION; } + YY_BREAK +case 256: +YY_RULE_SETUP +#line 924 "ob_proxy_parser_utf8.l" { return SHARD_KEY; } YY_BREAK -case 248: +case 257: YY_RULE_SETUP -#line 902 "ob_proxy_parser_utf8.l" +#line 925 "ob_proxy_parser_utf8.l" { return TABLE_NAME;} YY_BREAK -case 249: +case 258: YY_RULE_SETUP -#line 903 "ob_proxy_parser_utf8.l" +#line 926 "ob_proxy_parser_utf8.l" { return PARALL; } YY_BREAK -case 250: +case 259: YY_RULE_SETUP -#line 904 "ob_proxy_parser_utf8.l" +#line 927 "ob_proxy_parser_utf8.l" { return GROUP_ID; } YY_BREAK -case 251: +case 260: YY_RULE_SETUP -#line 905 "ob_proxy_parser_utf8.l" +#line 928 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_dbp_comment_trace_expr); return TRACE; } YY_BREAK -case 252: +case 261: YY_RULE_SETUP -#line 906 "ob_proxy_parser_utf8.l" +#line 929 "ob_proxy_parser_utf8.l" { ENTER_QUOTE_STATE(comment_sq); } YY_BREAK -case 253: +case 262: YY_RULE_SETUP -#line 907 "ob_proxy_parser_utf8.l" +#line 930 "ob_proxy_parser_utf8.l" { return yytext[0]; } YY_BREAK -case 254: +case 263: YY_RULE_SETUP -#line 908 "ob_proxy_parser_utf8.l" +#line 931 "ob_proxy_parser_utf8.l" { return '('; } YY_BREAK -case 255: +case 264: YY_RULE_SETUP -#line 909 "ob_proxy_parser_utf8.l" +#line 932 "ob_proxy_parser_utf8.l" { return ')'; } YY_BREAK -case 256: +case 265: YY_RULE_SETUP -#line 910 "ob_proxy_parser_utf8.l" +#line 933 "ob_proxy_parser_utf8.l" { return ','; } YY_BREAK -case 257: -/* rule 257 can match eol */ +case 266: +/* rule 266 can match eol */ YY_RULE_SETUP -#line 911 "ob_proxy_parser_utf8.l" +#line 934 "ob_proxy_parser_utf8.l" { } YY_BREAK -case 258: +case 267: YY_RULE_SETUP -#line 912 "ob_proxy_parser_utf8.l" +#line 935 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 259: +case 268: YY_RULE_SETUP -#line 914 "ob_proxy_parser_utf8.l" +#line 937 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7393,39 +7605,39 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 260: +case 269: YY_RULE_SETUP -#line 924 "ob_proxy_parser_utf8.l" +#line 947 "ob_proxy_parser_utf8.l" {return yytext[0];} YY_BREAK -case 261: +case 270: YY_RULE_SETUP -#line 925 "ob_proxy_parser_utf8.l" +#line 948 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_dbp_comment_trace_value_expr); return '('; } YY_BREAK -case 262: -/* rule 262 can match eol */ +case 271: +/* rule 271 can match eol */ YY_RULE_SETUP -#line 926 "ob_proxy_parser_utf8.l" +#line 949 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 263: +case 272: YY_RULE_SETUP -#line 928 "ob_proxy_parser_utf8.l" +#line 951 "ob_proxy_parser_utf8.l" { ENTER_QUOTE_STATE(comment_sq); } YY_BREAK -case 264: +case 273: YY_RULE_SETUP -#line 929 "ob_proxy_parser_utf8.l" +#line 952 "ob_proxy_parser_utf8.l" { POP_STATE(); POP_STATE(); return ')'; } YY_BREAK -case 265: +case 274: YY_RULE_SETUP -#line 934 "ob_proxy_parser_utf8.l" +#line 957 "ob_proxy_parser_utf8.l" { do { PUSH_STATE(in_dbp_comment_trace_value_expr_calc) @@ -7439,9 +7651,9 @@ YY_RULE_SETUP } while (0); } YY_BREAK -case 266: +case 275: YY_RULE_SETUP -#line 946 "ob_proxy_parser_utf8.l" +#line 969 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7455,15 +7667,15 @@ YY_RULE_SETUP return COMMENT_END; } YY_BREAK -case 267: -/* rule 267 can match eol */ +case 276: +/* rule 276 can match eol */ YY_RULE_SETUP -#line 958 "ob_proxy_parser_utf8.l" +#line 981 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 268: +case 277: YY_RULE_SETUP -#line 959 "ob_proxy_parser_utf8.l" +#line 982 "ob_proxy_parser_utf8.l" { do { PUSH_STATE(in_dbp_comment_trace_value_expr_calc) @@ -7476,10 +7688,10 @@ YY_RULE_SETUP } while (0); } YY_BREAK -case 269: -/* rule 269 can match eol */ +case 278: +/* rule 278 can match eol */ YY_RULE_SETUP -#line 971 "ob_proxy_parser_utf8.l" +#line 994 "ob_proxy_parser_utf8.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7492,9 +7704,9 @@ YY_RULE_SETUP } } YY_BREAK -case 270: +case 279: YY_RULE_SETUP -#line 983 "ob_proxy_parser_utf8.l" +#line 1006 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7503,9 +7715,9 @@ YY_RULE_SETUP } YY_BREAK /* quote */ -case 271: +case 280: YY_RULE_SETUP -#line 991 "ob_proxy_parser_utf8.l" +#line 1014 "ob_proxy_parser_utf8.l" { PUSH_STATE(sq); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7516,10 +7728,10 @@ YY_RULE_SETUP } } YY_BREAK -case 272: -/* rule 272 can match eol */ +case 281: +/* rule 281 can match eol */ YY_RULE_SETUP -#line 1001 "ob_proxy_parser_utf8.l" +#line 1024 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7527,9 +7739,9 @@ YY_RULE_SETUP } } YY_BREAK -case 273: +case 282: YY_RULE_SETUP -#line 1008 "ob_proxy_parser_utf8.l" +#line 1031 "ob_proxy_parser_utf8.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7547,32 +7759,32 @@ YY_RULE_SETUP } } YY_BREAK -case 274: +case 283: YY_RULE_SETUP -#line 1025 "ob_proxy_parser_utf8.l" +#line 1048 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 275: -/* rule 275 can match eol */ +case 284: +/* rule 284 can match eol */ YY_RULE_SETUP -#line 1026 "ob_proxy_parser_utf8.l" +#line 1049 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 276: -/* rule 276 can match eol */ +case 285: +/* rule 285 can match eol */ YY_RULE_SETUP -#line 1027 "ob_proxy_parser_utf8.l" +#line 1050 "ob_proxy_parser_utf8.l" {} YY_BREAK case YY_STATE_EOF(sq): -#line 1028 "ob_proxy_parser_utf8.l" +#line 1051 "ob_proxy_parser_utf8.l" { return ERROR; } YY_BREAK /* comment sq return name_str */ -case 277: -/* rule 277 can match eol */ +case 286: +/* rule 286 can match eol */ YY_RULE_SETUP -#line 1031 "ob_proxy_parser_utf8.l" +#line 1054 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7580,9 +7792,9 @@ YY_RULE_SETUP } } YY_BREAK -case 278: +case 287: YY_RULE_SETUP -#line 1038 "ob_proxy_parser_utf8.l" +#line 1061 "ob_proxy_parser_utf8.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7594,31 +7806,31 @@ YY_RULE_SETUP } } YY_BREAK -case 279: +case 288: YY_RULE_SETUP -#line 1049 "ob_proxy_parser_utf8.l" +#line 1072 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 280: -/* rule 280 can match eol */ +case 289: +/* rule 289 can match eol */ YY_RULE_SETUP -#line 1050 "ob_proxy_parser_utf8.l" +#line 1073 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 281: -/* rule 281 can match eol */ +case 290: +/* rule 290 can match eol */ YY_RULE_SETUP -#line 1051 "ob_proxy_parser_utf8.l" +#line 1074 "ob_proxy_parser_utf8.l" {} YY_BREAK case YY_STATE_EOF(comment_sq): -#line 1052 "ob_proxy_parser_utf8.l" +#line 1075 "ob_proxy_parser_utf8.l" { return ERROR; } YY_BREAK /* dquote */ -case 282: +case 291: YY_RULE_SETUP -#line 1055 "ob_proxy_parser_utf8.l" +#line 1078 "ob_proxy_parser_utf8.l" { PUSH_STATE(dq); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7629,10 +7841,10 @@ YY_RULE_SETUP } } YY_BREAK -case 283: -/* rule 283 can match eol */ +case 292: +/* rule 292 can match eol */ YY_RULE_SETUP -#line 1065 "ob_proxy_parser_utf8.l" +#line 1088 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (OB_NOTNULL(p)) { @@ -7640,9 +7852,9 @@ YY_RULE_SETUP } } YY_BREAK -case 284: +case 293: YY_RULE_SETUP -#line 1072 "ob_proxy_parser_utf8.l" +#line 1095 "ob_proxy_parser_utf8.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7660,31 +7872,31 @@ YY_RULE_SETUP } } YY_BREAK -case 285: +case 294: YY_RULE_SETUP -#line 1089 "ob_proxy_parser_utf8.l" +#line 1112 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 286: -/* rule 286 can match eol */ +case 295: +/* rule 295 can match eol */ YY_RULE_SETUP -#line 1090 "ob_proxy_parser_utf8.l" +#line 1113 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 287: -/* rule 287 can match eol */ +case 296: +/* rule 296 can match eol */ YY_RULE_SETUP -#line 1091 "ob_proxy_parser_utf8.l" +#line 1114 "ob_proxy_parser_utf8.l" {} YY_BREAK case YY_STATE_EOF(dq): -#line 1092 "ob_proxy_parser_utf8.l" +#line 1115 "ob_proxy_parser_utf8.l" { return ERROR; } YY_BREAK /* backtick */ -case 288: +case 297: YY_RULE_SETUP -#line 1096 "ob_proxy_parser_utf8.l" +#line 1119 "ob_proxy_parser_utf8.l" { PUSH_STATE(bt); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7695,9 +7907,9 @@ YY_RULE_SETUP } } YY_BREAK -case 289: +case 298: YY_RULE_SETUP -#line 1106 "ob_proxy_parser_utf8.l" +#line 1129 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (NULL != p && NULL != p->tmp_buf_ && p->tmp_len_ + 1 < OBPROXY_MAX_NAME_LENGTH) { @@ -7705,10 +7917,10 @@ YY_RULE_SETUP } } YY_BREAK -case 290: -/* rule 290 can match eol */ +case 299: +/* rule 299 can match eol */ YY_RULE_SETUP -#line 1113 "ob_proxy_parser_utf8.l" +#line 1136 "ob_proxy_parser_utf8.l" { ObProxyParseResult *p = (ObProxyParseResult *)yyextra; if (NULL != p && NULL != p->tmp_buf_ && p->tmp_len_ + yyleng < OBPROXY_MAX_NAME_LENGTH) { @@ -7717,9 +7929,9 @@ YY_RULE_SETUP } } YY_BREAK -case 291: +case 300: YY_RULE_SETUP -#line 1121 "ob_proxy_parser_utf8.l" +#line 1144 "ob_proxy_parser_utf8.l" { POP_STATE(); ObProxyParseResult *p = (ObProxyParseResult *)yyextra; @@ -7733,248 +7945,242 @@ YY_RULE_SETUP } YY_BREAK case YY_STATE_EOF(bt): -#line 1133 "ob_proxy_parser_utf8.l" +#line 1156 "ob_proxy_parser_utf8.l" { return ERROR; } YY_BREAK -case 292: +case 301: YY_RULE_SETUP -#line 1137 "ob_proxy_parser_utf8.l" +#line 1160 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 293: -/* rule 293 can match eol */ +case 302: +/* rule 302 can match eol */ YY_RULE_SETUP -#line 1138 "ob_proxy_parser_utf8.l" +#line 1161 "ob_proxy_parser_utf8.l" {} YY_BREAK -case 294: +case 303: YY_RULE_SETUP -#line 1139 "ob_proxy_parser_utf8.l" +#line 1162 "ob_proxy_parser_utf8.l" { POP_STATE(); RETURN_IGNORED_WORD(); } YY_BREAK case YY_STATE_EOF(bt_in_expr): -#line 1140 "ob_proxy_parser_utf8.l" +#line 1163 "ob_proxy_parser_utf8.l" { return ERROR; } YY_BREAK /* some useful keyword */ -case 295: -/* rule 295 can match eol */ +case 304: +/* rule 304 can match eol */ YY_RULE_SETUP -#line 1143 "ob_proxy_parser_utf8.l" +#line 1166 "ob_proxy_parser_utf8.l" { RETURN_IGNORED_WORD_FOR_DUAL(); } YY_BREAK -case 296: +case 305: YY_RULE_SETUP -#line 1144 "ob_proxy_parser_utf8.l" +#line 1167 "ob_proxy_parser_utf8.l" { POP_STATE(); PUSH_STATE(INITIAL); return FROM; } YY_BREAK -case 297: +case 306: YY_RULE_SETUP -#line 1145 "ob_proxy_parser_utf8.l" +#line 1168 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_subquery); return '('; } YY_BREAK -case 298: +case 307: YY_RULE_SETUP -#line 1146 "ob_proxy_parser_utf8.l" +#line 1169 "ob_proxy_parser_utf8.l" { PUSH_STATE(dq); } YY_BREAK -case 299: +case 308: YY_RULE_SETUP -#line 1147 "ob_proxy_parser_utf8.l" +#line 1170 "ob_proxy_parser_utf8.l" { PUSH_STATE(sq); } YY_BREAK -case 300: +case 309: YY_RULE_SETUP -#line 1148 "ob_proxy_parser_utf8.l" +#line 1171 "ob_proxy_parser_utf8.l" { PUSH_STATE(bt_in_expr); } YY_BREAK -case 301: +case 310: YY_RULE_SETUP -#line 1149 "ob_proxy_parser_utf8.l" +#line 1172 "ob_proxy_parser_utf8.l" { SET_FOUND_ROWS(); RETURN_IGNORED_WORD(); } YY_BREAK -case 302: +case 311: YY_RULE_SETUP -#line 1150 "ob_proxy_parser_utf8.l" +#line 1173 "ob_proxy_parser_utf8.l" { SET_ROW_COUNT(); RETURN_IGNORED_WORD(); } YY_BREAK -case 303: +case 312: YY_RULE_SETUP -#line 1151 "ob_proxy_parser_utf8.l" +#line 1174 "ob_proxy_parser_utf8.l" { SET_LAST_INSERT_ID(); RETURN_IGNORED_WORD(); } YY_BREAK -case 304: +case 313: YY_RULE_SETUP -#line 1152 "ob_proxy_parser_utf8.l" +#line 1175 "ob_proxy_parser_utf8.l" { SET_GLOBAL_SET_STMT(); RETURN_IGNORED_WORD(); } YY_BREAK -case 305: -/* rule 305 can match eol */ +case 314: +/* rule 314 can match eol */ YY_RULE_SETUP -#line 1153 "ob_proxy_parser_utf8.l" +#line 1176 "ob_proxy_parser_utf8.l" { RETURN_COL_NAME(TX_READ_ONLY); } YY_BREAK -case 306: -/* rule 306 can match eol */ -YY_RULE_SETUP -#line 1154 "ob_proxy_parser_utf8.l" -{ return AUTOCOMMIT_0; } - YY_BREAK -case 307: +case 315: YY_RULE_SETUP -#line 1155 "ob_proxy_parser_utf8.l" +#line 1177 "ob_proxy_parser_utf8.l" { RETURN_IGNORED_WORD(); } YY_BREAK case YY_STATE_EOF(in_expr): -#line 1156 "ob_proxy_parser_utf8.l" +#line 1178 "ob_proxy_parser_utf8.l" { return END_P; } YY_BREAK -case 308: -/* rule 308 can match eol */ +case 316: +/* rule 316 can match eol */ YY_RULE_SETUP -#line 1157 "ob_proxy_parser_utf8.l" +#line 1179 "ob_proxy_parser_utf8.l" { } YY_BREAK -case 309: +case 317: YY_RULE_SETUP -#line 1158 "ob_proxy_parser_utf8.l" +#line 1180 "ob_proxy_parser_utf8.l" { POP_STATE(); PUSH_STATE(INITIAL); return yytext[0]; } YY_BREAK -case 310: +case 318: YY_RULE_SETUP -#line 1159 "ob_proxy_parser_utf8.l" +#line 1181 "ob_proxy_parser_utf8.l" { RETURN_IGNORED_WORD(); } YY_BREAK -case 311: +case 319: YY_RULE_SETUP -#line 1161 "ob_proxy_parser_utf8.l" +#line 1183 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_expr); return SELECT; } YY_BREAK -case 312: +case 320: YY_RULE_SETUP -#line 1162 "ob_proxy_parser_utf8.l" +#line 1184 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_subquery); return '('; } YY_BREAK -case 313: +case 321: YY_RULE_SETUP -#line 1163 "ob_proxy_parser_utf8.l" +#line 1185 "ob_proxy_parser_utf8.l" { POP_STATE(); return ')'; } YY_BREAK -case 314: +case 322: YY_RULE_SETUP -#line 1164 "ob_proxy_parser_utf8.l" +#line 1186 "ob_proxy_parser_utf8.l" { PUSH_STATE(dq); } YY_BREAK -case 315: +case 323: YY_RULE_SETUP -#line 1165 "ob_proxy_parser_utf8.l" +#line 1187 "ob_proxy_parser_utf8.l" { PUSH_STATE(sq); } YY_BREAK case YY_STATE_EOF(in_subquery): -#line 1166 "ob_proxy_parser_utf8.l" +#line 1188 "ob_proxy_parser_utf8.l" { return END_P; } YY_BREAK -case 316: -/* rule 316 can match eol */ +case 324: +/* rule 324 can match eol */ YY_RULE_SETUP -#line 1167 "ob_proxy_parser_utf8.l" +#line 1189 "ob_proxy_parser_utf8.l" { } YY_BREAK -case 317: +case 325: YY_RULE_SETUP -#line 1168 "ob_proxy_parser_utf8.l" +#line 1190 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_no_select_query); RETURN_IGNORED_WORD(); } YY_BREAK -case 318: +case 326: YY_RULE_SETUP -#line 1170 "ob_proxy_parser_utf8.l" +#line 1192 "ob_proxy_parser_utf8.l" { PUSH_STATE(in_subquery); return '('; } YY_BREAK -case 319: +case 327: YY_RULE_SETUP -#line 1171 "ob_proxy_parser_utf8.l" +#line 1193 "ob_proxy_parser_utf8.l" { POP_STATE(); POP_STATE(); return ')'; } YY_BREAK -case 320: +case 328: YY_RULE_SETUP -#line 1172 "ob_proxy_parser_utf8.l" +#line 1194 "ob_proxy_parser_utf8.l" { PUSH_STATE(dq); } YY_BREAK -case 321: +case 329: YY_RULE_SETUP -#line 1173 "ob_proxy_parser_utf8.l" +#line 1195 "ob_proxy_parser_utf8.l" { PUSH_STATE(sq); } YY_BREAK -case 322: +case 330: YY_RULE_SETUP -#line 1174 "ob_proxy_parser_utf8.l" +#line 1196 "ob_proxy_parser_utf8.l" { SET_FOUND_ROWS(); RETURN_IGNORED_WORD(); } YY_BREAK -case 323: +case 331: YY_RULE_SETUP -#line 1175 "ob_proxy_parser_utf8.l" +#line 1197 "ob_proxy_parser_utf8.l" { SET_ROW_COUNT(); RETURN_IGNORED_WORD(); } YY_BREAK -case 324: +case 332: YY_RULE_SETUP -#line 1176 "ob_proxy_parser_utf8.l" +#line 1198 "ob_proxy_parser_utf8.l" { SET_LAST_INSERT_ID(); RETURN_IGNORED_WORD(); } YY_BREAK -case 325: +case 333: YY_RULE_SETUP -#line 1177 "ob_proxy_parser_utf8.l" +#line 1199 "ob_proxy_parser_utf8.l" { RETURN_IGNORED_WORD(); } YY_BREAK case YY_STATE_EOF(in_no_select_query): -#line 1178 "ob_proxy_parser_utf8.l" +#line 1200 "ob_proxy_parser_utf8.l" { return END_P; } YY_BREAK -case 326: -/* rule 326 can match eol */ +case 334: +/* rule 334 can match eol */ YY_RULE_SETUP -#line 1179 "ob_proxy_parser_utf8.l" +#line 1201 "ob_proxy_parser_utf8.l" { } YY_BREAK -case 327: +case 335: YY_RULE_SETUP -#line 1180 "ob_proxy_parser_utf8.l" +#line 1202 "ob_proxy_parser_utf8.l" { RETURN_IGNORED_WORD(); } YY_BREAK -case 328: +case 336: YY_RULE_SETUP -#line 1182 "ob_proxy_parser_utf8.l" +#line 1204 "ob_proxy_parser_utf8.l" { return FROM; } YY_BREAK -case 329: +case 337: YY_RULE_SETUP -#line 1183 "ob_proxy_parser_utf8.l" +#line 1205 "ob_proxy_parser_utf8.l" { return yytext[0]; } YY_BREAK -case 330: +case 338: YY_RULE_SETUP -#line 1184 "ob_proxy_parser_utf8.l" +#line 1206 "ob_proxy_parser_utf8.l" { RETURN_NON_RESERVED_KEYWORD(NAME_OB); } YY_BREAK -case 331: +case 339: YY_RULE_SETUP -#line 1185 "ob_proxy_parser_utf8.l" +#line 1207 "ob_proxy_parser_utf8.l" { POP_STATE(); } YY_BREAK -case 332: +case 340: YY_RULE_SETUP -#line 1186 "ob_proxy_parser_utf8.l" +#line 1208 "ob_proxy_parser_utf8.l" { POP_STATE(); } YY_BREAK -case 333: +case 341: YY_RULE_SETUP -#line 1188 "ob_proxy_parser_utf8.l" -{ POP_STATE(); return BEGI;} +#line 1210 "ob_proxy_parser_utf8.l" +{ POP_STATE(); RETURN_NON_RESERVED_KEYWORD(BEGI);} YY_BREAK -case 334: +case 342: YY_RULE_SETUP -#line 1189 "ob_proxy_parser_utf8.l" +#line 1211 "ob_proxy_parser_utf8.l" {} YY_BREAK case YY_STATE_EOF(INITIAL): @@ -7993,21 +8199,22 @@ case YY_STATE_EOF(in_dbp_comment_trace_value_expr_calc): case YY_STATE_EOF(in_anonymous_block): case YY_STATE_EOF(prepare): case YY_STATE_EOF(insert_all_expr): +case YY_STATE_EOF(show_topology): case YY_STATE_EOF(proxy_icmd_state): -#line 1191 "ob_proxy_parser_utf8.l" +#line 1213 "ob_proxy_parser_utf8.l" { return END_P; } YY_BREAK -case 335: +case 343: YY_RULE_SETUP -#line 1192 "ob_proxy_parser_utf8.l" +#line 1214 "ob_proxy_parser_utf8.l" { RETURN_IGNORED_WORD(); } YY_BREAK -case 336: +case 344: YY_RULE_SETUP -#line 1193 "ob_proxy_parser_utf8.l" +#line 1215 "ob_proxy_parser_utf8.l" ECHO; YY_BREAK -#line 8013 "ob_proxy_parser_utf8_lex.c" +#line 8220 "ob_proxy_parser_utf8_lex.c" case YY_END_OF_BUFFER: { @@ -8299,7 +8506,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 2597 ) + if ( yy_current_state >= 2787 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -8328,11 +8535,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 2597 ) + if ( yy_current_state >= 2787 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 2596); + yy_is_jam = (yy_current_state == 2786); return yy_is_jam ? 0 : yy_current_state; } @@ -9157,7 +9364,7 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 1193 "ob_proxy_parser_utf8.l" +#line 1215 "ob_proxy_parser_utf8.l" inline void *ob_proxy_parser_utf8_yyalloc(size_t bytes,void *yyscanner) @@ -9367,96 +9574,104 @@ extern int ob_proxy_parser_utf8_yydebug; UNION = 333, FOR = 334, TX_READ_ONLY = 335, - AUTOCOMMIT_0 = 336, - SELECT_OBPROXY_ROUTE_ADDR = 337, - SET_OBPROXY_ROUTE_ADDR = 338, - NAME_OB_DOT = 339, - NAME_OB = 340, - EXPLAIN = 341, - DESC = 342, - DESCRIBE = 343, - NAME_STR = 344, - USE = 345, - HELP = 346, - SET_NAMES = 347, - SET_CHARSET = 348, - SET_PASSWORD = 349, - SET_DEFAULT = 350, - SET_OB_READ_CONSISTENCY = 351, - SET_TX_READ_ONLY = 352, - GLOBAL = 353, - SESSION = 354, - NUMBER_VAL = 355, - GROUP_ID = 356, - TABLE_ID = 357, - ELASTIC_ID = 358, - TESTLOAD = 359, - ODP_COMMENT = 360, - TNT_ID = 361, - DISASTER_STATUS = 362, - TRACE_ID = 363, - RPC_ID = 364, + SELECT_OBPROXY_ROUTE_ADDR = 336, + SET_OBPROXY_ROUTE_ADDR = 337, + NAME_OB_DOT = 338, + NAME_OB = 339, + EXPLAIN = 340, + DESC = 341, + DESCRIBE = 342, + NAME_STR = 343, + USE = 344, + HELP = 345, + SET_NAMES = 346, + SET_CHARSET = 347, + SET_PASSWORD = 348, + SET_DEFAULT = 349, + SET_OB_READ_CONSISTENCY = 350, + SET_TX_READ_ONLY = 351, + GLOBAL = 352, + SESSION = 353, + NUMBER_VAL = 354, + GROUP_ID = 355, + TABLE_ID = 356, + ELASTIC_ID = 357, + TESTLOAD = 358, + ODP_COMMENT = 359, + TNT_ID = 360, + DISASTER_STATUS = 361, + TRACE_ID = 362, + RPC_ID = 363, + TARGET_DB_SERVER = 364, DBP_COMMENT = 365, ROUTE_TAG = 366, SYS_TAG = 367, TABLE_NAME = 368, SCAN_ALL = 369, - PARALL = 370, - SHARD_KEY = 371, - INT_NUM = 372, - SHOW_PROXYNET = 373, - THREAD = 374, - CONNECTION = 375, - LIMIT = 376, - OFFSET = 377, - SHOW_PROCESSLIST = 378, - SHOW_PROXYSESSION = 379, - SHOW_GLOBALSESSION = 380, - ATTRIBUTE = 381, - VARIABLES = 382, - ALL = 383, - STAT = 384, - SHOW_PROXYCONFIG = 385, - DIFF = 386, - USER = 387, - LIKE = 388, - SHOW_PROXYSM = 389, - SHOW_PROXYCLUSTER = 390, - SHOW_PROXYRESOURCE = 391, - SHOW_PROXYCONGESTION = 392, - SHOW_PROXYROUTE = 393, - PARTITION = 394, - ROUTINE = 395, - SHOW_PROXYVIP = 396, - SHOW_PROXYMEMORY = 397, - OBJPOOL = 398, - SHOW_SQLAUDIT = 399, - SHOW_WARNLOG = 400, - SHOW_PROXYSTAT = 401, - REFRESH = 402, - SHOW_PROXYTRACE = 403, - SHOW_PROXYINFO = 404, - BINARY = 405, - UPGRADE = 406, - IDC = 407, - SHOW_TOPOLOGY = 408, - GROUP_NAME = 409, - SHOW_DB_VERSION = 410, - SHOW_DATABASES = 411, - SHOW_TABLES = 412, - SHOW_FULL_TABLES = 413, - SELECT_DATABASE = 414, - SHOW_CREATE_TABLE = 415, - SELECT_PROXY_VERSION = 416, - SHOW_COLUMNS = 417, - SHOW_INDEX = 418, - ALTER_PROXYCONFIG = 419, - ALTER_PROXYRESOURCE = 420, - PING_PROXY = 421, - KILL_PROXYSESSION = 422, - KILL_GLOBALSESSION = 423, - KILL = 424, - QUERY = 425 + STICKY_SESSION = 370, + PARALL = 371, + SHARD_KEY = 372, + INT_NUM = 373, + SHOW_PROXYNET = 374, + THREAD = 375, + CONNECTION = 376, + LIMIT = 377, + OFFSET = 378, + SHOW_PROCESSLIST = 379, + SHOW_PROXYSESSION = 380, + SHOW_GLOBALSESSION = 381, + ATTRIBUTE = 382, + VARIABLES = 383, + ALL = 384, + STAT = 385, + SHOW_PROXYCONFIG = 386, + DIFF = 387, + USER = 388, + LIKE = 389, + SHOW_PROXYSM = 390, + SHOW_PROXYCLUSTER = 391, + SHOW_PROXYRESOURCE = 392, + SHOW_PROXYCONGESTION = 393, + SHOW_PROXYROUTE = 394, + PARTITION = 395, + ROUTINE = 396, + SHOW_PROXYVIP = 397, + SHOW_PROXYMEMORY = 398, + OBJPOOL = 399, + SHOW_SQLAUDIT = 400, + SHOW_WARNLOG = 401, + SHOW_PROXYSTAT = 402, + REFRESH = 403, + SHOW_PROXYTRACE = 404, + SHOW_PROXYINFO = 405, + BINARY = 406, + UPGRADE = 407, + IDC = 408, + SHOW_ELASTIC_ID = 409, + SHOW_TOPOLOGY = 410, + GROUP_NAME = 411, + SHOW_DB_VERSION = 412, + SHOW_DATABASES = 413, + SHOW_TABLES = 414, + SHOW_FULL_TABLES = 415, + SELECT_DATABASE = 416, + SHOW_CREATE_TABLE = 417, + SELECT_PROXY_VERSION = 418, + SHOW_COLUMNS = 419, + SHOW_INDEX = 420, + ALTER_PROXYCONFIG = 421, + ALTER_PROXYRESOURCE = 422, + PING_PROXY = 423, + KILL_PROXYSESSION = 424, + KILL_GLOBALSESSION = 425, + KILL = 426, + QUERY = 427, + SHOW_MASTER_STATUS = 428, + SHOW_BINARY_LOGS = 429, + SHOW_BINLOG_EVENTS = 430, + PURGE_BINARY_LOGS = 431, + RESET_MASTER = 432, + SHOW_BINLOG_SERVER_FOR_TENANT = 433 }; #endif diff --git a/src/obproxy/opsql/parser/ob_proxy_parser_utf8_lex.h b/src/obproxy/opsql/parser/ob_proxy_parser_utf8_lex.h index 486cb751d..4cb2afb95 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parser_utf8_lex.h +++ b/src/obproxy/opsql/parser/ob_proxy_parser_utf8_lex.h @@ -244,9 +244,10 @@ void ob_proxy_parser_utf8_yyfree (void * ,yyscan_t yyscanner ); #define prepare 22 #define insert_all_expr 23 #define set_expr 24 -#define show_topology 25 -#define show_tables 26 -#define proxy_icmd_state 27 +#define show_elastic_id 25 +#define show_topology 26 +#define show_tables 27 +#define proxy_icmd_state 28 #endif @@ -364,9 +365,9 @@ extern int ob_proxy_parser_utf8_yylex \ #undef YY_DECL #endif -#line 1193 "ob_proxy_parser_utf8.l" +#line 1215 "ob_proxy_parser_utf8.l" -#line 371 "ob_proxy_parser_utf8_lex.h" +#line 372 "ob_proxy_parser_utf8_lex.h" #undef ob_proxy_parser_utf8_yyIN_HEADER #endif /* ob_proxy_parser_utf8_yyHEADER_H */ diff --git a/src/obproxy/opsql/parser/ob_proxy_parser_utf8_tab.c b/src/obproxy/opsql/parser/ob_proxy_parser_utf8_tab.c index 48704e9f9..0ae9f5266 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parser_utf8_tab.c +++ b/src/obproxy/opsql/parser/ob_proxy_parser_utf8_tab.c @@ -112,9 +112,6 @@ static inline void handle_stmt_end(ObProxyParseResult* result) case OBPROXY_T_SELECT_TX_RO: result->stmt_type_ = OBPROXY_T_SELECT; break; - case OBPROXY_T_SET_AC_0: - result->stmt_type_ = OBPROXY_T_OTHERS; - break; case OBPROXY_T_BEGIN: result->stmt_type_ = OBPROXY_T_OTHERS; break; @@ -133,7 +130,7 @@ static inline void handle_stmt_end(ObProxyParseResult* result) } } else { result->stmt_type_ = result->cur_stmt_type_; - } + } if (OBPROXY_T_TEXT_PS_PREPARE == result->text_ps_inner_stmt_type_) { ObProxyBasicStmtType tmp_type = result->cur_stmt_type_; @@ -459,96 +456,104 @@ extern int ob_proxy_parser_utf8_yydebug; UNION = 333, FOR = 334, TX_READ_ONLY = 335, - AUTOCOMMIT_0 = 336, - SELECT_OBPROXY_ROUTE_ADDR = 337, - SET_OBPROXY_ROUTE_ADDR = 338, - NAME_OB_DOT = 339, - NAME_OB = 340, - EXPLAIN = 341, - DESC = 342, - DESCRIBE = 343, - NAME_STR = 344, - USE = 345, - HELP = 346, - SET_NAMES = 347, - SET_CHARSET = 348, - SET_PASSWORD = 349, - SET_DEFAULT = 350, - SET_OB_READ_CONSISTENCY = 351, - SET_TX_READ_ONLY = 352, - GLOBAL = 353, - SESSION = 354, - NUMBER_VAL = 355, - GROUP_ID = 356, - TABLE_ID = 357, - ELASTIC_ID = 358, - TESTLOAD = 359, - ODP_COMMENT = 360, - TNT_ID = 361, - DISASTER_STATUS = 362, - TRACE_ID = 363, - RPC_ID = 364, + SELECT_OBPROXY_ROUTE_ADDR = 336, + SET_OBPROXY_ROUTE_ADDR = 337, + NAME_OB_DOT = 338, + NAME_OB = 339, + EXPLAIN = 340, + DESC = 341, + DESCRIBE = 342, + NAME_STR = 343, + USE = 344, + HELP = 345, + SET_NAMES = 346, + SET_CHARSET = 347, + SET_PASSWORD = 348, + SET_DEFAULT = 349, + SET_OB_READ_CONSISTENCY = 350, + SET_TX_READ_ONLY = 351, + GLOBAL = 352, + SESSION = 353, + NUMBER_VAL = 354, + GROUP_ID = 355, + TABLE_ID = 356, + ELASTIC_ID = 357, + TESTLOAD = 358, + ODP_COMMENT = 359, + TNT_ID = 360, + DISASTER_STATUS = 361, + TRACE_ID = 362, + RPC_ID = 363, + TARGET_DB_SERVER = 364, DBP_COMMENT = 365, ROUTE_TAG = 366, SYS_TAG = 367, TABLE_NAME = 368, SCAN_ALL = 369, - PARALL = 370, - SHARD_KEY = 371, - INT_NUM = 372, - SHOW_PROXYNET = 373, - THREAD = 374, - CONNECTION = 375, - LIMIT = 376, - OFFSET = 377, - SHOW_PROCESSLIST = 378, - SHOW_PROXYSESSION = 379, - SHOW_GLOBALSESSION = 380, - ATTRIBUTE = 381, - VARIABLES = 382, - ALL = 383, - STAT = 384, - SHOW_PROXYCONFIG = 385, - DIFF = 386, - USER = 387, - LIKE = 388, - SHOW_PROXYSM = 389, - SHOW_PROXYCLUSTER = 390, - SHOW_PROXYRESOURCE = 391, - SHOW_PROXYCONGESTION = 392, - SHOW_PROXYROUTE = 393, - PARTITION = 394, - ROUTINE = 395, - SHOW_PROXYVIP = 396, - SHOW_PROXYMEMORY = 397, - OBJPOOL = 398, - SHOW_SQLAUDIT = 399, - SHOW_WARNLOG = 400, - SHOW_PROXYSTAT = 401, - REFRESH = 402, - SHOW_PROXYTRACE = 403, - SHOW_PROXYINFO = 404, - BINARY = 405, - UPGRADE = 406, - IDC = 407, - SHOW_TOPOLOGY = 408, - GROUP_NAME = 409, - SHOW_DB_VERSION = 410, - SHOW_DATABASES = 411, - SHOW_TABLES = 412, - SHOW_FULL_TABLES = 413, - SELECT_DATABASE = 414, - SHOW_CREATE_TABLE = 415, - SELECT_PROXY_VERSION = 416, - SHOW_COLUMNS = 417, - SHOW_INDEX = 418, - ALTER_PROXYCONFIG = 419, - ALTER_PROXYRESOURCE = 420, - PING_PROXY = 421, - KILL_PROXYSESSION = 422, - KILL_GLOBALSESSION = 423, - KILL = 424, - QUERY = 425 + STICKY_SESSION = 370, + PARALL = 371, + SHARD_KEY = 372, + INT_NUM = 373, + SHOW_PROXYNET = 374, + THREAD = 375, + CONNECTION = 376, + LIMIT = 377, + OFFSET = 378, + SHOW_PROCESSLIST = 379, + SHOW_PROXYSESSION = 380, + SHOW_GLOBALSESSION = 381, + ATTRIBUTE = 382, + VARIABLES = 383, + ALL = 384, + STAT = 385, + SHOW_PROXYCONFIG = 386, + DIFF = 387, + USER = 388, + LIKE = 389, + SHOW_PROXYSM = 390, + SHOW_PROXYCLUSTER = 391, + SHOW_PROXYRESOURCE = 392, + SHOW_PROXYCONGESTION = 393, + SHOW_PROXYROUTE = 394, + PARTITION = 395, + ROUTINE = 396, + SHOW_PROXYVIP = 397, + SHOW_PROXYMEMORY = 398, + OBJPOOL = 399, + SHOW_SQLAUDIT = 400, + SHOW_WARNLOG = 401, + SHOW_PROXYSTAT = 402, + REFRESH = 403, + SHOW_PROXYTRACE = 404, + SHOW_PROXYINFO = 405, + BINARY = 406, + UPGRADE = 407, + IDC = 408, + SHOW_ELASTIC_ID = 409, + SHOW_TOPOLOGY = 410, + GROUP_NAME = 411, + SHOW_DB_VERSION = 412, + SHOW_DATABASES = 413, + SHOW_TABLES = 414, + SHOW_FULL_TABLES = 415, + SELECT_DATABASE = 416, + SHOW_CREATE_TABLE = 417, + SELECT_PROXY_VERSION = 418, + SHOW_COLUMNS = 419, + SHOW_INDEX = 420, + ALTER_PROXYCONFIG = 421, + ALTER_PROXYRESOURCE = 422, + PING_PROXY = 423, + KILL_PROXYSESSION = 424, + KILL_GLOBALSESSION = 425, + KILL = 426, + QUERY = 427, + SHOW_MASTER_STATUS = 428, + SHOW_BINARY_LOGS = 429, + SHOW_BINLOG_EVENTS = 430, + PURGE_BINARY_LOGS = 431, + RESET_MASTER = 432, + SHOW_BINLOG_SERVER_FOR_TENANT = 433 }; #endif @@ -811,22 +816,22 @@ union yyalloc #endif /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 322 +#define YYFINAL 314 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 1614 +#define YYLAST 1384 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 182 +#define YYNTOKENS 190 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 137 +#define YYNNTS 138 /* YYNRULES -- Number of rules. */ -#define YYNRULES 442 +#define YYNRULES 435 /* YYNRULES -- Number of states. */ -#define YYNSTATES 713 +#define YYNSTATES 715 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 425 +#define YYMAXUTOK 433 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -837,16 +842,16 @@ static const yytype_uint8 yytranslate[] = 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 180, 2, 2, 2, 2, - 175, 176, 181, 2, 173, 2, 177, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 171, - 2, 174, 2, 2, 172, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 188, 2, 2, 2, 2, + 183, 184, 189, 2, 181, 2, 185, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 179, + 2, 182, 2, 2, 180, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 178, 2, 179, 2, 2, 2, 2, + 2, 2, 2, 186, 2, 187, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -876,7 +881,8 @@ static const yytype_uint8 yytranslate[] = 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 170 + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178 }; #if YYDEBUG @@ -887,234 +893,231 @@ static const yytype_uint16 yyprhs[] = 0, 0, 3, 5, 7, 9, 12, 15, 18, 22, 24, 27, 31, 33, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, - 68, 70, 72, 74, 76, 78, 80, 82, 84, 88, - 91, 94, 97, 100, 103, 106, 108, 110, 113, 115, - 117, 119, 121, 122, 124, 126, 129, 131, 133, 135, - 137, 139, 141, 143, 145, 148, 153, 156, 158, 160, - 164, 167, 171, 174, 177, 181, 185, 187, 189, 191, - 193, 195, 197, 199, 201, 203, 206, 208, 210, 212, - 213, 216, 217, 219, 222, 228, 232, 234, 238, 241, - 245, 247, 249, 251, 253, 255, 257, 259, 261, 263, - 265, 267, 269, 271, 273, 276, 279, 283, 289, 293, - 299, 300, 303, 304, 307, 311, 315, 321, 323, 325, - 329, 335, 343, 345, 349, 351, 353, 355, 357, 359, - 361, 367, 369, 373, 379, 380, 382, 386, 388, 390, - 392, 395, 399, 401, 403, 406, 408, 411, 415, 419, - 421, 423, 425, 426, 430, 432, 436, 440, 446, 449, - 452, 457, 460, 463, 467, 469, 474, 481, 486, 492, - 499, 504, 508, 510, 512, 514, 516, 519, 523, 529, - 536, 543, 550, 557, 564, 572, 579, 586, 593, 600, - 609, 618, 619, 622, 625, 628, 630, 634, 636, 641, - 646, 650, 657, 662, 667, 674, 678, 680, 684, 685, - 689, 693, 697, 701, 705, 709, 713, 717, 721, 725, - 731, 735, 736, 738, 739, 741, 743, 745, 747, 750, - 752, 755, 757, 760, 763, 767, 768, 770, 773, 775, - 778, 780, 783, 786, 787, 790, 795, 797, 802, 808, - 810, 815, 820, 826, 827, 829, 831, 833, 834, 836, - 840, 844, 847, 849, 851, 853, 855, 857, 859, 861, - 863, 865, 867, 869, 871, 873, 875, 877, 879, 881, - 883, 885, 887, 889, 891, 893, 894, 897, 902, 907, - 908, 911, 912, 915, 918, 920, 922, 926, 929, 933, - 938, 940, 943, 944, 947, 951, 954, 957, 960, 961, - 964, 968, 971, 975, 978, 982, 986, 991, 993, 996, - 999, 1003, 1006, 1009, 1010, 1012, 1014, 1017, 1020, 1024, - 1027, 1029, 1032, 1034, 1037, 1040, 1043, 1046, 1047, 1049, - 1053, 1059, 1062, 1066, 1069, 1070, 1072, 1075, 1078, 1081, - 1084, 1089, 1095, 1101, 1105, 1107, 1110, 1114, 1118, 1121, - 1124, 1128, 1132, 1133, 1136, 1138, 1142, 1146, 1150, 1151, - 1153, 1155, 1159, 1162, 1166, 1169, 1172, 1174, 1175, 1178, - 1183, 1186, 1188, 1192, 1195, 1200, 1204, 1210, 1212, 1214, - 1216, 1218, 1220, 1222, 1224, 1226, 1228, 1230, 1232, 1234, - 1236, 1238, 1240, 1242, 1244, 1246, 1248, 1250, 1252, 1254, - 1256, 1258, 1260, 1262, 1264, 1266, 1268, 1270, 1272, 1274, - 1276, 1278, 1280, 1282, 1284, 1286, 1288, 1290, 1292, 1294, - 1296, 1298, 1300 + 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, + 90, 93, 96, 99, 102, 105, 108, 110, 112, 115, + 117, 119, 121, 123, 124, 126, 128, 131, 133, 135, + 137, 139, 141, 143, 145, 147, 150, 155, 158, 160, + 162, 166, 169, 173, 176, 179, 183, 187, 189, 191, + 193, 195, 197, 199, 201, 203, 205, 208, 210, 212, + 214, 215, 218, 219, 221, 224, 230, 234, 236, 240, + 242, 244, 246, 248, 250, 252, 254, 256, 258, 260, + 262, 264, 266, 268, 271, 274, 278, 284, 288, 294, + 295, 298, 299, 302, 306, 310, 316, 318, 320, 324, + 330, 338, 340, 344, 346, 350, 352, 354, 356, 358, + 360, 362, 368, 370, 374, 380, 381, 383, 387, 389, + 391, 393, 396, 400, 402, 404, 407, 409, 412, 416, + 420, 422, 424, 426, 427, 431, 433, 437, 441, 447, + 450, 453, 458, 461, 464, 468, 470, 475, 482, 487, + 493, 500, 505, 509, 511, 513, 515, 517, 520, 524, + 530, 537, 544, 551, 558, 565, 573, 580, 587, 594, + 601, 610, 619, 626, 627, 630, 633, 636, 638, 642, + 644, 649, 654, 658, 665, 669, 674, 679, 686, 690, + 692, 696, 697, 701, 705, 709, 713, 717, 721, 725, + 729, 733, 737, 741, 747, 751, 752, 754, 755, 757, + 759, 761, 763, 766, 768, 771, 773, 776, 779, 783, + 784, 786, 789, 791, 794, 796, 799, 802, 803, 806, + 811, 813, 818, 824, 826, 831, 836, 842, 843, 845, + 847, 849, 850, 852, 856, 860, 863, 865, 867, 869, + 871, 873, 875, 877, 879, 881, 883, 885, 887, 889, + 891, 893, 895, 897, 899, 901, 903, 905, 907, 909, + 911, 913, 915, 917, 919, 921, 922, 925, 930, 935, + 936, 939, 940, 943, 946, 948, 950, 954, 957, 961, + 966, 968, 971, 972, 975, 979, 982, 985, 988, 989, + 992, 996, 999, 1003, 1006, 1010, 1014, 1019, 1021, 1024, + 1027, 1031, 1034, 1037, 1038, 1040, 1042, 1045, 1048, 1052, + 1055, 1057, 1060, 1062, 1065, 1068, 1071, 1074, 1075, 1077, + 1081, 1087, 1090, 1094, 1097, 1098, 1100, 1103, 1106, 1109, + 1112, 1117, 1123, 1129, 1133, 1135, 1138, 1142, 1146, 1149, + 1152, 1156, 1160, 1161, 1164, 1166, 1170, 1174, 1178, 1179, + 1181, 1183, 1187, 1190, 1194, 1197, 1200, 1202, 1203, 1206, + 1211, 1214, 1216, 1220, 1223, 1228, 1232, 1238, 1240, 1242, + 1244, 1246, 1248, 1250, 1252, 1254, 1256, 1258, 1260, 1262, + 1264, 1266, 1268, 1270, 1272, 1274, 1276, 1278, 1280, 1282, + 1284, 1286, 1288, 1290, 1292, 1294 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int16 yyrhs[] = { - 183, 0, -1, 184, -1, 1, -1, 185, -1, 184, - 185, -1, 186, 50, -1, 186, 171, -1, 186, 171, - 50, -1, 171, -1, 171, 50, -1, 56, 186, 171, - -1, 187, -1, 246, 187, -1, 188, -1, 237, -1, - 242, -1, 238, -1, 239, -1, 240, -1, 189, -1, - 307, -1, 272, -1, 208, -1, 273, -1, 311, -1, - 312, -1, 220, -1, 221, -1, 222, -1, 223, -1, - 224, -1, 225, -1, 226, -1, 190, -1, 199, -1, - 241, -1, 313, -1, 260, 204, 203, -1, 201, 188, - -1, 201, 237, -1, 201, 239, -1, 201, 240, -1, - 201, 238, -1, 201, 241, -1, 191, -1, 200, -1, - 14, 192, -1, 15, -1, 16, -1, 17, -1, 18, - -1, -1, 19, -1, 64, -1, 21, 64, -1, 188, - -1, 237, -1, 238, -1, 240, -1, 239, -1, 313, - -1, 226, -1, 241, -1, 172, 85, -1, 194, 173, - 172, 85, -1, 172, 85, -1, 195, -1, 193, -1, - 29, 318, 27, -1, 30, 318, -1, 30, 318, 31, - -1, 197, 196, -1, 198, 194, -1, 15, 29, 318, - -1, 32, 29, 318, -1, 22, -1, 23, -1, 24, - -1, 25, -1, 53, -1, 26, -1, 54, -1, 55, - -1, 202, -1, 202, 85, -1, 86, -1, 87, -1, - 88, -1, -1, 27, 233, -1, -1, 230, -1, 5, - 80, -1, 5, 80, 204, 27, 233, -1, 5, 80, - 230, -1, 161, -1, 161, 71, 318, -1, 12, 81, - -1, 12, 81, 230, -1, 205, -1, 206, -1, 207, - -1, 218, -1, 219, -1, 209, -1, 217, -1, 216, - -1, 159, -1, 156, -1, 214, -1, 215, -1, 210, - -1, 211, -1, 160, 227, -1, 202, 227, -1, 162, - 27, 85, -1, 162, 27, 85, 27, 85, -1, 163, - 27, 85, -1, 163, 27, 85, 27, 85, -1, -1, - 133, 85, -1, -1, 27, 85, -1, 157, 213, 212, - -1, 158, 213, 212, -1, 11, 19, 20, 213, 212, - -1, 155, -1, 153, -1, 153, 27, 85, -1, 153, - 72, 154, 174, 85, -1, 153, 27, 85, 72, 154, - 174, 85, -1, 82, -1, 83, 174, 117, -1, 92, - -1, 93, -1, 94, -1, 95, -1, 96, -1, 97, - -1, 13, 227, 175, 228, 176, -1, 318, -1, 318, - 177, 318, -1, 318, 177, 318, 177, 318, -1, -1, - 229, -1, 228, 173, 229, -1, 85, -1, 117, -1, - 100, -1, 172, 85, -1, 172, 172, 85, -1, 49, - -1, 231, -1, 230, 231, -1, 232, -1, 175, 176, - -1, 175, 188, 176, -1, 175, 230, 176, -1, 315, - -1, 234, -1, 188, -1, -1, 175, 236, 176, -1, - 85, -1, 236, 173, 85, -1, 263, 316, 314, -1, - 263, 316, 314, 235, 234, -1, 265, 233, -1, 261, - 233, -1, 262, 271, 27, 233, -1, 266, 316, -1, - 12, 243, -1, 244, 173, 243, -1, 244, -1, 172, - 85, 174, 245, -1, 172, 172, 98, 85, 174, 245, - -1, 98, 85, 174, 245, -1, 172, 172, 85, 174, - 245, -1, 172, 172, 99, 85, 174, 245, -1, 99, - 85, 174, 245, -1, 85, 174, 245, -1, 85, -1, - 117, -1, 100, -1, 247, -1, 247, 246, -1, 40, - 248, 41, -1, 40, 105, 256, 255, 41, -1, 40, - 102, 174, 259, 255, 41, -1, 40, 113, 174, 259, - 255, 41, -1, 40, 101, 174, 259, 255, 41, -1, - 40, 103, 174, 259, 255, 41, -1, 40, 104, 174, - 259, 255, 41, -1, 40, 84, 85, 174, 258, 255, - 41, -1, 40, 108, 174, 257, 255, 41, -1, 40, - 109, 174, 257, 255, 41, -1, 40, 106, 174, 259, - 255, 41, -1, 40, 107, 174, 259, 255, 41, -1, - 40, 110, 111, 174, 178, 250, 179, 41, -1, 40, - 110, 112, 174, 178, 252, 179, 41, -1, -1, 248, - 249, -1, 42, 85, -1, 43, 85, -1, 85, -1, - 251, 173, 250, -1, 251, -1, 101, 175, 259, 176, - -1, 113, 175, 259, 176, -1, 114, 175, 176, -1, - 114, 175, 115, 174, 259, 176, -1, 116, 175, 253, - 176, -1, 68, 175, 257, 176, -1, 68, 175, 257, - 180, 257, 176, -1, 254, 173, 253, -1, 254, -1, - 85, 174, 259, -1, -1, 255, 173, 256, -1, 101, - 174, 259, -1, 102, 174, 259, -1, 113, 174, 259, - -1, 103, 174, 259, -1, 104, 174, 259, -1, 108, - 174, 257, -1, 109, 174, 257, -1, 106, 174, 259, - -1, 107, 174, 259, -1, 85, 177, 85, 174, 258, - -1, 85, 174, 258, -1, -1, 259, -1, -1, 259, - -1, 85, -1, 89, -1, 5, -1, 33, 267, -1, - 8, -1, 34, 267, -1, 6, -1, 35, 267, -1, - 7, 264, -1, 36, 267, 264, -1, -1, 128, -1, - 128, 52, -1, 9, -1, 37, 267, -1, 10, -1, - 38, 267, -1, 268, 39, -1, -1, 269, 268, -1, - 44, 175, 117, 176, -1, 117, -1, 45, 175, 270, - 176, -1, 64, 175, 85, 85, 176, -1, 85, -1, - 85, 175, 117, 176, -1, 85, 175, 85, 176, -1, - 85, 175, 85, 85, 176, -1, -1, 46, -1, 47, - -1, 48, -1, -1, 69, -1, 11, 306, 66, -1, - 11, 306, 67, -1, 11, 68, -1, 277, -1, 279, - -1, 280, -1, 283, -1, 281, -1, 285, -1, 286, - -1, 287, -1, 288, -1, 290, -1, 291, -1, 292, - -1, 293, -1, 294, -1, 296, -1, 297, -1, 299, - -1, 300, -1, 301, -1, 302, -1, 303, -1, 304, - -1, 305, -1, -1, 121, 117, -1, 121, 117, 173, - 117, -1, 121, 117, 122, 117, -1, -1, 133, 85, - -1, -1, 133, 85, -1, 118, 278, -1, 119, -1, - 120, -1, 120, 117, 274, -1, 130, 275, -1, 130, - 131, 275, -1, 130, 131, 132, 275, -1, 123, -1, - 125, 282, -1, -1, 126, 85, -1, 126, 133, 85, - -1, 126, 128, -1, 133, 85, -1, 124, 284, -1, - -1, 126, 275, -1, 126, 117, 275, -1, 129, 275, - -1, 129, 117, 275, -1, 127, 275, -1, 127, 117, - 275, -1, 127, 128, 275, -1, 127, 128, 117, 275, - -1, 134, -1, 134, 117, -1, 135, 275, -1, 135, - 152, 275, -1, 136, 275, -1, 137, 289, -1, -1, - 85, -1, 128, -1, 128, 85, -1, 138, 276, -1, - 138, 140, 276, -1, 138, 139, -1, 141, -1, 141, - 85, -1, 142, -1, 142, 143, -1, 144, 274, -1, - 144, 117, -1, 145, 295, -1, -1, 117, -1, 117, - 173, 117, -1, 117, 173, 117, 173, 85, -1, 146, - 275, -1, 146, 147, 275, -1, 148, 298, -1, -1, - 117, -1, 117, 117, -1, 149, 150, -1, 149, 151, - -1, 149, 152, -1, 164, 12, 85, 174, -1, 164, - 12, 85, 174, 85, -1, 164, 12, 85, 174, 117, - -1, 165, 6, 85, -1, 166, -1, 167, 117, -1, - 167, 117, 117, -1, 168, 85, 117, -1, 168, 85, - -1, 169, 117, -1, 169, 120, 117, -1, 169, 170, - 117, -1, -1, 70, 181, -1, 56, -1, 57, 58, - 308, -1, 65, 56, 85, -1, 65, 57, 85, -1, - -1, 309, -1, 310, -1, 309, 173, 310, -1, 59, - 60, -1, 61, 62, 63, -1, 90, 85, -1, 91, - 85, -1, 85, -1, -1, 139, 85, -1, 139, 175, - 85, 176, -1, 316, 314, -1, 318, -1, 318, 177, - 318, -1, 318, 318, -1, 318, 177, 318, 318, -1, - 318, 71, 318, -1, 318, 177, 318, 71, 318, -1, - 57, -1, 65, -1, 56, -1, 58, -1, 62, -1, - 67, -1, 66, -1, 70, -1, 69, -1, 68, -1, - 119, -1, 120, -1, 122, -1, 126, -1, 127, -1, - 129, -1, 131, -1, 132, -1, 143, -1, 147, -1, - 151, -1, 152, -1, 170, -1, 101, -1, 102, -1, - 103, -1, 104, -1, 154, -1, 105, -1, 106, -1, - 107, -1, 108, -1, 109, -1, 110, -1, 111, -1, - 112, -1, 113, -1, 115, -1, 114, -1, 116, -1, - 64, -1, 53, -1, 54, -1, 55, -1, 85, -1, - 317, -1 + 191, 0, -1, 192, -1, 1, -1, 193, -1, 192, + 193, -1, 194, 50, -1, 194, 179, -1, 194, 179, + 50, -1, 179, -1, 179, 50, -1, 56, 194, 179, + -1, 195, -1, 254, 195, -1, 196, -1, 245, -1, + 250, -1, 246, -1, 247, -1, 248, -1, 197, -1, + 316, -1, 280, -1, 215, -1, 281, -1, 320, -1, + 321, -1, 228, -1, 229, -1, 230, -1, 231, -1, + 232, -1, 233, -1, 234, -1, 198, -1, 207, -1, + 249, -1, 282, -1, 322, -1, 268, 212, 211, -1, + 209, 196, -1, 209, 245, -1, 209, 247, -1, 209, + 248, -1, 209, 246, -1, 209, 249, -1, 199, -1, + 208, -1, 14, 200, -1, 15, -1, 16, -1, 17, + -1, 18, -1, -1, 19, -1, 64, -1, 21, 64, + -1, 196, -1, 245, -1, 246, -1, 248, -1, 247, + -1, 322, -1, 234, -1, 249, -1, 180, 84, -1, + 202, 181, 180, 84, -1, 180, 84, -1, 203, -1, + 201, -1, 29, 327, 27, -1, 30, 327, -1, 30, + 327, 31, -1, 205, 204, -1, 206, 202, -1, 15, + 29, 327, -1, 32, 29, 327, -1, 22, -1, 23, + -1, 24, -1, 25, -1, 53, -1, 26, -1, 54, + -1, 55, -1, 210, -1, 210, 84, -1, 85, -1, + 86, -1, 87, -1, -1, 27, 241, -1, -1, 238, + -1, 5, 80, -1, 5, 80, 212, 27, 241, -1, + 5, 80, 238, -1, 163, -1, 163, 71, 327, -1, + 213, -1, 214, -1, 226, -1, 227, -1, 216, -1, + 224, -1, 225, -1, 223, -1, 161, -1, 158, -1, + 221, -1, 222, -1, 217, -1, 218, -1, 162, 235, + -1, 210, 327, -1, 164, 27, 84, -1, 164, 27, + 84, 27, 84, -1, 165, 27, 84, -1, 165, 27, + 84, 27, 84, -1, -1, 134, 84, -1, -1, 27, + 84, -1, 159, 220, 219, -1, 160, 220, 219, -1, + 11, 19, 20, 220, 219, -1, 157, -1, 154, -1, + 154, 27, 84, -1, 154, 72, 156, 182, 84, -1, + 154, 27, 84, 72, 156, 182, 84, -1, 155, -1, + 155, 27, 84, -1, 81, -1, 82, 182, 118, -1, + 91, -1, 92, -1, 93, -1, 94, -1, 95, -1, + 96, -1, 13, 235, 183, 236, 184, -1, 327, -1, + 327, 185, 327, -1, 327, 185, 327, 185, 327, -1, + -1, 237, -1, 236, 181, 237, -1, 84, -1, 118, + -1, 99, -1, 180, 84, -1, 180, 180, 84, -1, + 49, -1, 239, -1, 238, 239, -1, 240, -1, 183, + 184, -1, 183, 196, 184, -1, 183, 238, 184, -1, + 324, -1, 242, -1, 196, -1, -1, 183, 244, 184, + -1, 84, -1, 244, 181, 84, -1, 271, 325, 323, + -1, 271, 325, 323, 243, 242, -1, 273, 241, -1, + 269, 241, -1, 270, 279, 27, 241, -1, 274, 325, + -1, 12, 251, -1, 252, 181, 251, -1, 252, -1, + 180, 84, 182, 253, -1, 180, 180, 97, 84, 182, + 253, -1, 97, 84, 182, 253, -1, 180, 180, 84, + 182, 253, -1, 180, 180, 98, 84, 182, 253, -1, + 98, 84, 182, 253, -1, 84, 182, 253, -1, 84, + -1, 118, -1, 99, -1, 255, -1, 255, 254, -1, + 40, 256, 41, -1, 40, 104, 264, 263, 41, -1, + 40, 101, 182, 267, 263, 41, -1, 40, 113, 182, + 267, 263, 41, -1, 40, 100, 182, 267, 263, 41, + -1, 40, 102, 182, 267, 263, 41, -1, 40, 103, + 182, 267, 263, 41, -1, 40, 83, 84, 182, 266, + 263, 41, -1, 40, 107, 182, 265, 263, 41, -1, + 40, 108, 182, 265, 263, 41, -1, 40, 105, 182, + 267, 263, 41, -1, 40, 106, 182, 267, 263, 41, + -1, 40, 110, 111, 182, 186, 258, 187, 41, -1, + 40, 110, 112, 182, 186, 260, 187, 41, -1, 40, + 109, 182, 267, 263, 41, -1, -1, 256, 257, -1, + 42, 84, -1, 43, 84, -1, 84, -1, 259, 181, + 258, -1, 259, -1, 100, 183, 267, 184, -1, 113, + 183, 267, 184, -1, 114, 183, 184, -1, 114, 183, + 116, 182, 267, 184, -1, 115, 183, 184, -1, 117, + 183, 261, 184, -1, 68, 183, 265, 184, -1, 68, + 183, 265, 188, 265, 184, -1, 262, 181, 261, -1, + 262, -1, 84, 182, 267, -1, -1, 263, 181, 264, + -1, 100, 182, 267, -1, 101, 182, 267, -1, 113, + 182, 267, -1, 102, 182, 267, -1, 103, 182, 267, + -1, 107, 182, 265, -1, 108, 182, 265, -1, 105, + 182, 267, -1, 106, 182, 267, -1, 109, 182, 267, + -1, 84, 185, 84, 182, 266, -1, 84, 182, 266, + -1, -1, 267, -1, -1, 267, -1, 84, -1, 88, + -1, 5, -1, 33, 275, -1, 8, -1, 34, 275, + -1, 6, -1, 35, 275, -1, 7, 272, -1, 36, + 275, 272, -1, -1, 129, -1, 129, 52, -1, 9, + -1, 37, 275, -1, 10, -1, 38, 275, -1, 276, + 39, -1, -1, 277, 276, -1, 44, 183, 118, 184, + -1, 118, -1, 45, 183, 278, 184, -1, 64, 183, + 84, 84, 184, -1, 84, -1, 84, 183, 118, 184, + -1, 84, 183, 84, 184, -1, 84, 183, 84, 84, + 184, -1, -1, 46, -1, 47, -1, 48, -1, -1, + 69, -1, 11, 315, 66, -1, 11, 315, 67, -1, + 11, 68, -1, 286, -1, 288, -1, 289, -1, 292, + -1, 290, -1, 294, -1, 295, -1, 296, -1, 297, + -1, 299, -1, 300, -1, 301, -1, 302, -1, 303, + -1, 305, -1, 306, -1, 308, -1, 309, -1, 310, + -1, 311, -1, 312, -1, 313, -1, 314, -1, 173, + -1, 174, -1, 175, -1, 176, -1, 177, -1, 178, + -1, -1, 122, 118, -1, 122, 118, 181, 118, -1, + 122, 118, 123, 118, -1, -1, 134, 84, -1, -1, + 134, 84, -1, 119, 287, -1, 120, -1, 121, -1, + 121, 118, 283, -1, 131, 284, -1, 131, 132, 284, + -1, 131, 132, 133, 284, -1, 124, -1, 126, 291, + -1, -1, 127, 84, -1, 127, 134, 84, -1, 127, + 129, -1, 134, 84, -1, 125, 293, -1, -1, 127, + 284, -1, 127, 118, 284, -1, 130, 284, -1, 130, + 118, 284, -1, 128, 284, -1, 128, 118, 284, -1, + 128, 129, 284, -1, 128, 129, 118, 284, -1, 135, + -1, 135, 118, -1, 136, 284, -1, 136, 153, 284, + -1, 137, 284, -1, 138, 298, -1, -1, 84, -1, + 129, -1, 129, 84, -1, 139, 285, -1, 139, 141, + 285, -1, 139, 140, -1, 142, -1, 142, 84, -1, + 143, -1, 143, 144, -1, 145, 283, -1, 145, 118, + -1, 146, 304, -1, -1, 118, -1, 118, 181, 118, + -1, 118, 181, 118, 181, 84, -1, 147, 284, -1, + 147, 148, 284, -1, 149, 307, -1, -1, 118, -1, + 118, 118, -1, 150, 151, -1, 150, 152, -1, 150, + 153, -1, 166, 12, 84, 182, -1, 166, 12, 84, + 182, 84, -1, 166, 12, 84, 182, 118, -1, 167, + 6, 84, -1, 168, -1, 169, 118, -1, 169, 118, + 118, -1, 170, 84, 118, -1, 170, 84, -1, 171, + 118, -1, 171, 121, 118, -1, 171, 172, 118, -1, + -1, 70, 189, -1, 56, -1, 57, 58, 317, -1, + 65, 56, 84, -1, 65, 57, 84, -1, -1, 318, + -1, 319, -1, 318, 181, 319, -1, 59, 60, -1, + 61, 62, 63, -1, 89, 84, -1, 90, 84, -1, + 84, -1, -1, 140, 84, -1, 140, 183, 84, 184, + -1, 325, 323, -1, 327, -1, 327, 185, 327, -1, + 327, 327, -1, 327, 185, 327, 327, -1, 327, 71, + 327, -1, 327, 185, 327, 71, 327, -1, 57, -1, + 65, -1, 56, -1, 58, -1, 62, -1, 67, -1, + 66, -1, 70, -1, 69, -1, 68, -1, 120, -1, + 121, -1, 123, -1, 127, -1, 128, -1, 130, -1, + 132, -1, 133, -1, 144, -1, 148, -1, 152, -1, + 153, -1, 172, -1, 156, -1, 53, -1, 54, -1, + 55, -1, 84, -1, 326, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 336, 336, 337, 339, 340, 342, 343, 344, 345, - 346, 347, 349, 350, 352, 353, 354, 355, 356, 357, - 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, - 368, 369, 370, 371, 372, 373, 374, 375, 377, 379, - 380, 381, 382, 383, 384, 386, 387, 389, 390, 391, - 392, 393, 395, 396, 397, 398, 400, 401, 402, 403, - 404, 405, 406, 407, 409, 416, 424, 432, 433, 436, - 442, 447, 453, 456, 459, 464, 470, 471, 472, 473, - 474, 475, 476, 477, 479, 480, 482, 483, 484, 486, - 487, 489, 490, 492, 493, 494, 496, 497, 499, 500, - 502, 503, 504, 505, 506, 507, 509, 510, 511, 512, - 513, 514, 515, 516, 517, 518, 524, 529, 536, 541, - 548, 549, 551, 552, 554, 558, 563, 568, 570, 571, - 576, 581, 588, 591, 597, 598, 599, 600, 601, 602, - 605, 607, 611, 616, 624, 627, 632, 637, 642, 647, - 652, 657, 662, 670, 671, 673, 675, 676, 677, 679, - 680, 682, 684, 685, 687, 688, 690, 694, 695, 696, - 697, 698, 703, 705, 706, 708, 712, 716, 720, 724, - 728, 732, 736, 741, 746, 752, 753, 755, 756, 757, - 758, 759, 760, 761, 762, 768, 769, 770, 771, 772, - 773, 775, 776, 778, 779, 780, 782, 783, 785, 790, - 795, 796, 797, 799, 800, 802, 803, 805, 813, 814, - 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, - 831, 833, 834, 836, 837, 839, 840, 842, 843, 844, - 845, 846, 847, 848, 849, 851, 852, 853, 855, 856, - 857, 858, 859, 860, 861, 863, 864, 865, 866, 871, - 872, 873, 874, 876, 877, 878, 879, 881, 882, 885, - 886, 887, 890, 891, 892, 893, 894, 895, 896, 897, - 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, - 908, 909, 910, 911, 912, 917, 919, 923, 928, 936, - 937, 941, 942, 945, 947, 948, 949, 953, 954, 955, - 959, 961, 963, 964, 965, 966, 967, 970, 972, 973, - 974, 975, 976, 977, 978, 979, 980, 984, 985, 989, - 990, 995, 998, 1000, 1001, 1002, 1003, 1007, 1008, 1009, - 1013, 1014, 1018, 1019, 1023, 1024, 1027, 1029, 1030, 1031, - 1032, 1036, 1037, 1040, 1042, 1043, 1044, 1048, 1049, 1050, - 1054, 1055, 1056, 1060, 1064, 1068, 1069, 1073, 1074, 1078, - 1079, 1080, 1083, 1084, 1087, 1091, 1092, 1093, 1095, 1096, - 1098, 1099, 1102, 1103, 1106, 1112, 1115, 1117, 1118, 1119, - 1121, 1126, 1129, 1133, 1137, 1142, 1146, 1152, 1153, 1154, - 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, - 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, - 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, - 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, - 1195, 1197, 1198 + 0, 334, 334, 335, 337, 338, 340, 341, 342, 343, + 344, 345, 347, 348, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, + 366, 367, 368, 369, 370, 371, 372, 373, 374, 376, + 378, 379, 380, 381, 382, 383, 385, 386, 388, 389, + 390, 391, 392, 394, 395, 396, 397, 399, 400, 401, + 402, 403, 404, 405, 406, 408, 415, 423, 431, 432, + 435, 441, 446, 452, 455, 458, 463, 469, 470, 471, + 472, 473, 474, 475, 476, 478, 479, 481, 482, 483, + 485, 486, 488, 489, 491, 492, 493, 495, 496, 498, + 499, 500, 501, 502, 504, 505, 506, 507, 508, 509, + 510, 511, 512, 513, 514, 521, 526, 533, 538, 545, + 546, 548, 549, 551, 555, 560, 565, 567, 568, 573, + 578, 585, 586, 592, 595, 601, 602, 603, 604, 605, + 606, 609, 611, 615, 620, 628, 631, 636, 641, 646, + 651, 656, 661, 666, 674, 675, 677, 679, 680, 681, + 683, 684, 686, 688, 689, 691, 692, 694, 698, 699, + 700, 701, 702, 707, 709, 710, 712, 716, 720, 724, + 728, 732, 736, 740, 745, 750, 756, 757, 759, 760, + 761, 762, 763, 764, 765, 766, 772, 773, 774, 775, + 776, 777, 778, 779, 780, 782, 783, 784, 786, 787, + 789, 794, 799, 800, 801, 802, 804, 805, 807, 808, + 810, 818, 819, 821, 822, 823, 824, 825, 826, 827, + 828, 829, 830, 831, 837, 839, 840, 842, 843, 845, + 846, 848, 849, 850, 851, 852, 853, 854, 855, 857, + 858, 859, 861, 862, 863, 864, 865, 866, 867, 869, + 870, 871, 872, 877, 878, 879, 880, 882, 883, 884, + 885, 887, 888, 891, 892, 893, 896, 897, 898, 899, + 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, + 910, 911, 912, 913, 914, 915, 916, 917, 918, 920, + 921, 922, 923, 924, 925, 930, 932, 936, 941, 949, + 950, 954, 955, 958, 960, 961, 962, 966, 967, 968, + 972, 974, 976, 977, 978, 979, 980, 983, 985, 986, + 987, 988, 989, 990, 991, 992, 993, 997, 998, 1002, + 1003, 1008, 1011, 1013, 1014, 1015, 1016, 1020, 1021, 1022, + 1026, 1027, 1031, 1032, 1036, 1037, 1040, 1042, 1043, 1044, + 1045, 1049, 1050, 1053, 1055, 1056, 1057, 1061, 1062, 1063, + 1067, 1068, 1069, 1073, 1077, 1081, 1082, 1086, 1087, 1091, + 1092, 1093, 1096, 1097, 1100, 1104, 1105, 1106, 1108, 1109, + 1111, 1112, 1115, 1116, 1119, 1125, 1128, 1130, 1131, 1132, + 1134, 1139, 1142, 1146, 1150, 1155, 1159, 1165, 1166, 1167, + 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, + 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, + 1188, 1189, 1190, 1191, 1193, 1194 }; #endif @@ -1137,26 +1140,29 @@ static const char *const yytname[] = "ONLY", "WITH", "CONSISTENT", "SNAPSHOT", "INDEX", "XA", "WARNINGS", "ERRORS", "TRACE", "QUICK", "COUNT", "AS", "WHERE", "VALUES", "ORDER", "GROUP", "HAVING", "INTO", "UNION", "FOR", "TX_READ_ONLY", - "AUTOCOMMIT_0", "SELECT_OBPROXY_ROUTE_ADDR", "SET_OBPROXY_ROUTE_ADDR", - "NAME_OB_DOT", "NAME_OB", "EXPLAIN", "DESC", "DESCRIBE", "NAME_STR", - "USE", "HELP", "SET_NAMES", "SET_CHARSET", "SET_PASSWORD", "SET_DEFAULT", + "SELECT_OBPROXY_ROUTE_ADDR", "SET_OBPROXY_ROUTE_ADDR", "NAME_OB_DOT", + "NAME_OB", "EXPLAIN", "DESC", "DESCRIBE", "NAME_STR", "USE", "HELP", + "SET_NAMES", "SET_CHARSET", "SET_PASSWORD", "SET_DEFAULT", "SET_OB_READ_CONSISTENCY", "SET_TX_READ_ONLY", "GLOBAL", "SESSION", "NUMBER_VAL", "GROUP_ID", "TABLE_ID", "ELASTIC_ID", "TESTLOAD", "ODP_COMMENT", "TNT_ID", "DISASTER_STATUS", "TRACE_ID", "RPC_ID", - "DBP_COMMENT", "ROUTE_TAG", "SYS_TAG", "TABLE_NAME", "SCAN_ALL", - "PARALL", "SHARD_KEY", "INT_NUM", "SHOW_PROXYNET", "THREAD", - "CONNECTION", "LIMIT", "OFFSET", "SHOW_PROCESSLIST", "SHOW_PROXYSESSION", - "SHOW_GLOBALSESSION", "ATTRIBUTE", "VARIABLES", "ALL", "STAT", - "SHOW_PROXYCONFIG", "DIFF", "USER", "LIKE", "SHOW_PROXYSM", - "SHOW_PROXYCLUSTER", "SHOW_PROXYRESOURCE", "SHOW_PROXYCONGESTION", - "SHOW_PROXYROUTE", "PARTITION", "ROUTINE", "SHOW_PROXYVIP", - "SHOW_PROXYMEMORY", "OBJPOOL", "SHOW_SQLAUDIT", "SHOW_WARNLOG", - "SHOW_PROXYSTAT", "REFRESH", "SHOW_PROXYTRACE", "SHOW_PROXYINFO", - "BINARY", "UPGRADE", "IDC", "SHOW_TOPOLOGY", "GROUP_NAME", - "SHOW_DB_VERSION", "SHOW_DATABASES", "SHOW_TABLES", "SHOW_FULL_TABLES", - "SELECT_DATABASE", "SHOW_CREATE_TABLE", "SELECT_PROXY_VERSION", - "SHOW_COLUMNS", "SHOW_INDEX", "ALTER_PROXYCONFIG", "ALTER_PROXYRESOURCE", - "PING_PROXY", "KILL_PROXYSESSION", "KILL_GLOBALSESSION", "KILL", "QUERY", + "TARGET_DB_SERVER", "DBP_COMMENT", "ROUTE_TAG", "SYS_TAG", "TABLE_NAME", + "SCAN_ALL", "STICKY_SESSION", "PARALL", "SHARD_KEY", "INT_NUM", + "SHOW_PROXYNET", "THREAD", "CONNECTION", "LIMIT", "OFFSET", + "SHOW_PROCESSLIST", "SHOW_PROXYSESSION", "SHOW_GLOBALSESSION", + "ATTRIBUTE", "VARIABLES", "ALL", "STAT", "SHOW_PROXYCONFIG", "DIFF", + "USER", "LIKE", "SHOW_PROXYSM", "SHOW_PROXYCLUSTER", + "SHOW_PROXYRESOURCE", "SHOW_PROXYCONGESTION", "SHOW_PROXYROUTE", + "PARTITION", "ROUTINE", "SHOW_PROXYVIP", "SHOW_PROXYMEMORY", "OBJPOOL", + "SHOW_SQLAUDIT", "SHOW_WARNLOG", "SHOW_PROXYSTAT", "REFRESH", + "SHOW_PROXYTRACE", "SHOW_PROXYINFO", "BINARY", "UPGRADE", "IDC", + "SHOW_ELASTIC_ID", "SHOW_TOPOLOGY", "GROUP_NAME", "SHOW_DB_VERSION", + "SHOW_DATABASES", "SHOW_TABLES", "SHOW_FULL_TABLES", "SELECT_DATABASE", + "SHOW_CREATE_TABLE", "SELECT_PROXY_VERSION", "SHOW_COLUMNS", + "SHOW_INDEX", "ALTER_PROXYCONFIG", "ALTER_PROXYRESOURCE", "PING_PROXY", + "KILL_PROXYSESSION", "KILL_GLOBALSESSION", "KILL", "QUERY", + "SHOW_MASTER_STATUS", "SHOW_BINARY_LOGS", "SHOW_BINLOG_EVENTS", + "PURGE_BINARY_LOGS", "RESET_MASTER", "SHOW_BINLOG_SERVER_FOR_TENANT", "';'", "'@'", "','", "'='", "'('", "')'", "'.'", "'{'", "'}'", "'#'", "'*'", "$accept", "root", "sql_stmts", "sql_stmt", "comment_stmt", "stmt", "select_stmt", "explain_stmt", "ddl_stmt", "mysql_ddl_stmt", @@ -1165,10 +1171,10 @@ static const char *const yytname[] = "text_ps_prepare_stmt", "text_ps_execute_stmt", "text_ps_stmt", "oracle_ddl_stmt", "explain_or_desc_stmt", "explain_or_desc", "opt_from", "select_expr_list", "select_tx_read_only_stmt", - "select_proxy_version_stmt", "set_autocommit_0_stmt", "hooked_stmt", - "shard_special_stmt", "show_columns_stmt", "show_index_stmt", - "opt_show_like", "opt_show_from", "show_tables_stmt", - "show_table_status_stmt", "show_db_version_stmt", "show_es_id_stmt", + "select_proxy_version_stmt", "hooked_stmt", "shard_special_stmt", + "show_columns_stmt", "show_index_stmt", "opt_show_like", "opt_show_from", + "show_tables_stmt", "show_table_status_stmt", "show_db_version_stmt", + "show_es_id_stmt", "show_topology_stmt", "select_obproxy_route_addr_stmt", "set_obproxy_route_addr_stmt", "set_names_stmt", "set_charset_stmt", "set_password_stmt", "set_default_stmt", "set_ob_read_consistency_stmt", @@ -1185,8 +1191,8 @@ static const char *const yytname[] = "insert_with_opt_hint", "insert_all_when", "replace_with_opt_hint", "merge_with_opt_hint", "hint_list_with_end", "hint_list", "hint", "opt_read_consistency", "opt_quick", "show_stmt", "icmd_stmt", - "opt_limit", "opt_like", "opt_large_like", "show_proxynet", - "opt_show_net", "show_proxyconfig", "show_processlist", + "binlog_stmt", "opt_limit", "opt_like", "opt_large_like", + "show_proxynet", "opt_show_net", "show_proxyconfig", "show_processlist", "show_globalsession", "opt_show_global_session", "show_proxysession", "opt_show_session", "show_proxysm", "show_proxycluster", "show_proxyresource", "show_proxycongestion", "opt_show_congestion", @@ -1224,59 +1230,58 @@ static const yytype_uint16 yytoknum[] = 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, - 425, 59, 64, 44, 61, 40, 41, 46, 123, 125, - 35, 42 + 425, 426, 427, 428, 429, 430, 431, 432, 433, 59, + 64, 44, 61, 40, 41, 46, 123, 125, 35, 42 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint16 yyr1[] = { - 0, 182, 183, 183, 184, 184, 185, 185, 185, 185, - 185, 185, 186, 186, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 188, 189, - 189, 189, 189, 189, 189, 190, 190, 191, 191, 191, - 191, 191, 192, 192, 192, 192, 193, 193, 193, 193, - 193, 193, 193, 193, 194, 194, 195, 196, 196, 197, - 198, 198, 199, 199, 199, 199, 200, 200, 200, 200, - 200, 200, 200, 200, 201, 201, 202, 202, 202, 203, - 203, 204, 204, 205, 205, 205, 206, 206, 207, 207, - 208, 208, 208, 208, 208, 208, 209, 209, 209, 209, - 209, 209, 209, 209, 209, 209, 210, 210, 211, 211, - 212, 212, 213, 213, 214, 214, 215, 216, 217, 217, - 217, 217, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 227, 227, 228, 228, 228, 229, 229, 229, - 229, 229, 229, 230, 230, 231, 232, 232, 232, 233, - 233, 234, 235, 235, 236, 236, 237, 237, 238, 239, - 240, 241, 242, 243, 243, 244, 244, 244, 244, 244, - 244, 244, 245, 245, 245, 246, 246, 247, 247, 247, - 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, - 247, 248, 248, 249, 249, 249, 250, 250, 251, 251, - 251, 251, 251, 252, 252, 253, 253, 254, 255, 255, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 257, 257, 258, 258, 259, 259, 260, 260, 261, - 261, 262, 262, 263, 263, 264, 264, 264, 265, 265, - 266, 266, 267, 268, 268, 269, 269, 269, 269, 269, - 269, 269, 269, 270, 270, 270, 270, 271, 271, 272, - 272, 272, 273, 273, 273, 273, 273, 273, 273, 273, - 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, - 273, 273, 273, 273, 273, 274, 274, 274, 274, 275, - 275, 276, 276, 277, 278, 278, 278, 279, 279, 279, - 280, 281, 282, 282, 282, 282, 282, 283, 284, 284, - 284, 284, 284, 284, 284, 284, 284, 285, 285, 286, - 286, 287, 288, 289, 289, 289, 289, 290, 290, 290, - 291, 291, 292, 292, 293, 293, 294, 295, 295, 295, - 295, 296, 296, 297, 298, 298, 298, 299, 299, 299, - 300, 300, 300, 301, 302, 303, 303, 304, 304, 305, - 305, 305, 306, 306, 307, 307, 307, 307, 308, 308, - 309, 309, 310, 310, 311, 312, 313, 314, 314, 314, - 315, 316, 316, 316, 316, 316, 316, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - 317, 318, 318 + 0, 190, 191, 191, 192, 192, 193, 193, 193, 193, + 193, 193, 194, 194, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 196, + 197, 197, 197, 197, 197, 197, 198, 198, 199, 199, + 199, 199, 199, 200, 200, 200, 200, 201, 201, 201, + 201, 201, 201, 201, 201, 202, 202, 203, 204, 204, + 205, 206, 206, 207, 207, 207, 207, 208, 208, 208, + 208, 208, 208, 208, 208, 209, 209, 210, 210, 210, + 211, 211, 212, 212, 213, 213, 213, 214, 214, 215, + 215, 215, 215, 215, 216, 216, 216, 216, 216, 216, + 216, 216, 216, 216, 216, 217, 217, 218, 218, 219, + 219, 220, 220, 221, 221, 222, 223, 224, 224, 224, + 224, 225, 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 235, 235, 236, 236, 236, 237, 237, + 237, 237, 237, 237, 238, 238, 239, 240, 240, 240, + 241, 241, 242, 243, 243, 244, 244, 245, 245, 246, + 247, 248, 249, 250, 251, 251, 252, 252, 252, 252, + 252, 252, 252, 253, 253, 253, 254, 254, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 256, 256, 257, 257, 257, 258, 258, + 259, 259, 259, 259, 259, 259, 260, 260, 261, 261, + 262, 263, 263, 264, 264, 264, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 265, 265, 266, 266, 267, + 267, 268, 268, 269, 269, 270, 270, 271, 271, 272, + 272, 272, 273, 273, 274, 274, 275, 276, 276, 277, + 277, 277, 277, 277, 277, 277, 277, 278, 278, 278, + 278, 279, 279, 280, 280, 280, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 282, + 282, 282, 282, 282, 282, 283, 283, 283, 283, 284, + 284, 285, 285, 286, 287, 287, 287, 288, 288, 288, + 289, 290, 291, 291, 291, 291, 291, 292, 293, 293, + 293, 293, 293, 293, 293, 293, 293, 294, 294, 295, + 295, 296, 297, 298, 298, 298, 298, 299, 299, 299, + 300, 300, 301, 301, 302, 302, 303, 304, 304, 304, + 304, 305, 305, 306, 307, 307, 307, 308, 308, 308, + 309, 309, 309, 310, 311, 312, 312, 313, 313, 314, + 314, 314, 315, 315, 316, 316, 316, 316, 317, 317, + 318, 318, 319, 319, 320, 321, 322, 323, 323, 323, + 324, 325, 325, 325, 325, 325, 325, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 327, 327 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -1285,31 +1290,32 @@ static const yytype_uint8 yyr2[] = 0, 2, 1, 1, 1, 2, 2, 2, 3, 1, 2, 3, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, - 2, 2, 2, 2, 2, 1, 1, 2, 1, 1, - 1, 1, 0, 1, 1, 2, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 4, 2, 1, 1, 3, - 2, 3, 2, 2, 3, 3, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 1, 1, 1, 0, - 2, 0, 1, 2, 5, 3, 1, 3, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, + 2, 2, 2, 2, 2, 2, 1, 1, 2, 1, + 1, 1, 1, 0, 1, 1, 2, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 4, 2, 1, 1, + 3, 2, 3, 2, 2, 3, 3, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, + 0, 2, 0, 1, 2, 5, 3, 1, 3, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 2, 3, 5, 3, 5, 0, + 2, 0, 2, 3, 3, 5, 1, 1, 3, 5, + 7, 1, 3, 1, 3, 1, 1, 1, 1, 1, + 1, 5, 1, 3, 5, 0, 1, 3, 1, 1, + 1, 2, 3, 1, 1, 2, 1, 2, 3, 3, + 1, 1, 1, 0, 3, 1, 3, 3, 5, 2, + 2, 4, 2, 2, 3, 1, 4, 6, 4, 5, + 6, 4, 3, 1, 1, 1, 1, 2, 3, 5, + 6, 6, 6, 6, 6, 7, 6, 6, 6, 6, + 8, 8, 6, 0, 2, 2, 2, 1, 3, 1, + 4, 4, 3, 6, 3, 4, 4, 6, 3, 1, + 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 5, 3, 0, 1, 0, 1, 1, + 1, 1, 2, 1, 2, 1, 2, 2, 3, 0, + 1, 2, 1, 2, 1, 2, 2, 0, 2, 4, + 1, 4, 5, 1, 4, 4, 5, 0, 1, 1, + 1, 0, 1, 3, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 2, 3, 5, 3, 5, - 0, 2, 0, 2, 3, 3, 5, 1, 1, 3, - 5, 7, 1, 3, 1, 1, 1, 1, 1, 1, - 5, 1, 3, 5, 0, 1, 3, 1, 1, 1, - 2, 3, 1, 1, 2, 1, 2, 3, 3, 1, - 1, 1, 0, 3, 1, 3, 3, 5, 2, 2, - 4, 2, 2, 3, 1, 4, 6, 4, 5, 6, - 4, 3, 1, 1, 1, 1, 2, 3, 5, 6, - 6, 6, 6, 6, 7, 6, 6, 6, 6, 8, - 8, 0, 2, 2, 2, 1, 3, 1, 4, 4, - 3, 6, 4, 4, 6, 3, 1, 3, 0, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, - 3, 0, 1, 0, 1, 1, 1, 1, 2, 1, - 2, 1, 2, 2, 3, 0, 1, 2, 1, 2, - 1, 2, 2, 0, 2, 4, 1, 4, 5, 1, - 4, 4, 5, 0, 1, 1, 1, 0, 1, 3, - 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 4, 4, 0, 2, 0, 2, 2, 1, 1, 3, 2, 3, 4, @@ -1324,9 +1330,7 @@ static const yytype_uint8 yyr2[] = 2, 1, 3, 2, 4, 3, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1 + 1, 1, 1, 1, 1, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -1334,532 +1338,486 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint16 yydefact[] = { - 0, 3, 237, 241, 245, 239, 248, 250, 372, 0, - 0, 52, 48, 49, 50, 51, 76, 77, 78, 79, - 81, 0, 0, 0, 253, 253, 253, 253, 253, 253, - 201, 80, 82, 83, 374, 0, 0, 132, 0, 386, - 86, 87, 88, 0, 0, 134, 135, 136, 137, 138, - 139, 0, 310, 318, 312, 299, 327, 299, 299, 333, - 301, 340, 342, 295, 347, 299, 354, 0, 128, 127, - 109, 122, 122, 108, 0, 96, 0, 0, 0, 0, - 364, 0, 0, 0, 9, 0, 2, 4, 0, 12, - 14, 20, 34, 45, 0, 0, 35, 46, 0, 84, - 100, 101, 102, 23, 105, 112, 113, 110, 111, 107, - 106, 103, 104, 27, 28, 29, 30, 31, 32, 33, - 15, 17, 18, 19, 36, 16, 0, 185, 91, 0, - 267, 0, 0, 0, 22, 24, 272, 273, 274, 276, - 275, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 21, - 25, 26, 37, 93, 246, 243, 0, 271, 0, 0, - 98, 0, 0, 0, 0, 172, 174, 438, 439, 440, - 399, 397, 400, 401, 437, 398, 403, 402, 406, 405, - 404, 441, 420, 421, 422, 423, 425, 426, 427, 428, - 429, 430, 431, 432, 433, 435, 434, 436, 407, 408, - 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, - 424, 419, 0, 442, 141, 53, 0, 54, 47, 0, - 0, 70, 0, 0, 0, 0, 259, 256, 238, 0, - 253, 240, 242, 245, 249, 251, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 374, - 0, 378, 0, 0, 0, 384, 385, 304, 305, 303, - 299, 299, 299, 317, 0, 0, 311, 299, 0, 307, - 328, 299, 329, 331, 334, 335, 332, 0, 339, 301, - 337, 341, 343, 345, 0, 344, 348, 346, 299, 351, - 355, 353, 357, 358, 359, 0, 0, 0, 120, 120, - 114, 0, 0, 0, 0, 0, 365, 368, 369, 0, - 0, 10, 1, 5, 6, 7, 237, 0, 56, 68, - 67, 72, 62, 57, 58, 60, 59, 63, 61, 0, - 73, 39, 40, 43, 41, 42, 44, 85, 115, 13, - 186, 0, 89, 92, 153, 155, 161, 169, 160, 159, - 387, 391, 268, 0, 387, 168, 171, 0, 95, 247, - 122, 373, 269, 270, 99, 0, 0, 0, 0, 0, - 0, 144, 0, 55, 74, 69, 71, 75, 0, 263, - 0, 0, 252, 254, 244, 0, 0, 0, 0, 0, + 0, 3, 241, 245, 249, 243, 252, 254, 382, 0, + 0, 53, 49, 50, 51, 52, 77, 78, 79, 80, + 82, 0, 0, 0, 257, 257, 257, 257, 257, 257, + 203, 81, 83, 84, 384, 0, 0, 133, 0, 396, + 87, 88, 89, 0, 0, 135, 136, 137, 138, 139, + 140, 0, 320, 328, 322, 309, 337, 309, 309, 343, + 311, 350, 352, 305, 357, 309, 364, 0, 127, 131, + 126, 108, 121, 121, 107, 0, 97, 0, 0, 0, + 0, 374, 0, 0, 0, 299, 300, 301, 302, 303, + 304, 9, 0, 2, 4, 0, 12, 14, 20, 34, + 46, 0, 0, 35, 47, 0, 85, 99, 100, 23, + 103, 111, 112, 109, 110, 106, 104, 105, 101, 102, + 27, 28, 29, 30, 31, 32, 33, 15, 17, 18, + 19, 36, 16, 0, 186, 92, 0, 271, 0, 0, + 0, 22, 24, 37, 276, 277, 278, 280, 279, 281, + 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + 292, 293, 294, 295, 296, 297, 298, 21, 25, 26, + 38, 94, 250, 247, 0, 275, 0, 0, 0, 0, + 0, 0, 173, 175, 431, 432, 433, 409, 407, 410, + 411, 408, 413, 412, 416, 415, 414, 434, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, + 430, 429, 0, 435, 142, 54, 0, 55, 48, 0, + 0, 71, 0, 0, 0, 0, 263, 260, 242, 0, + 257, 244, 246, 249, 253, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 218, 0, 0, 231, 231, 0, 0, 0, 187, 0, - 0, 205, 202, 11, 0, 0, 375, 379, 380, 376, - 377, 133, 295, 299, 319, 299, 299, 323, 299, 321, - 313, 315, 0, 316, 299, 308, 300, 330, 336, 302, - 338, 296, 0, 352, 356, 129, 0, 123, 0, 124, - 125, 97, 116, 118, 0, 363, 366, 367, 370, 371, - 8, 66, 64, 0, 156, 0, 0, 0, 38, 154, - 0, 390, 0, 0, 393, 0, 162, 0, 120, 182, - 184, 183, 181, 0, 0, 0, 0, 0, 0, 173, - 152, 147, 149, 148, 0, 0, 145, 142, 0, 264, - 265, 266, 0, 0, 0, 0, 233, 235, 236, 218, - 218, 218, 218, 233, 0, 0, 0, 0, 0, 0, - 0, 231, 231, 0, 0, 218, 218, 218, 232, 218, - 0, 0, 218, 203, 204, 382, 0, 0, 306, 320, - 324, 299, 325, 322, 314, 309, 0, 0, 349, 0, - 0, 121, 0, 0, 360, 0, 157, 158, 90, 388, - 0, 395, 392, 170, 0, 0, 94, 126, 177, 180, - 175, 0, 0, 0, 150, 0, 0, 140, 0, 255, - 257, 0, 0, 261, 260, 218, 234, 0, 0, 0, - 0, 230, 0, 220, 221, 223, 224, 227, 228, 225, - 226, 222, 188, 0, 0, 0, 0, 0, 0, 0, - 0, 383, 381, 326, 298, 297, 0, 0, 130, 117, - 119, 361, 362, 65, 0, 0, 394, 164, 0, 167, - 178, 0, 0, 151, 146, 143, 258, 262, 0, 191, - 189, 192, 193, 233, 219, 197, 198, 195, 196, 0, - 0, 0, 0, 0, 207, 0, 0, 190, 350, 0, - 389, 396, 0, 163, 176, 179, 194, 229, 0, 0, - 0, 0, 0, 0, 231, 0, 131, 165, 0, 0, - 0, 210, 0, 0, 216, 199, 206, 0, 200, 208, - 209, 0, 0, 212, 0, 213, 231, 0, 217, 215, - 0, 211, 214 + 384, 0, 388, 0, 0, 0, 394, 395, 314, 315, + 313, 309, 309, 309, 327, 0, 0, 321, 309, 0, + 317, 338, 309, 339, 341, 344, 345, 342, 0, 349, + 311, 347, 351, 353, 355, 0, 354, 358, 356, 309, + 361, 365, 363, 367, 368, 369, 0, 0, 0, 0, + 119, 119, 113, 0, 0, 0, 0, 0, 375, 378, + 379, 0, 0, 10, 1, 5, 6, 7, 241, 0, + 57, 69, 68, 73, 63, 58, 59, 61, 60, 64, + 62, 0, 74, 40, 41, 44, 42, 43, 45, 86, + 114, 13, 187, 0, 90, 93, 154, 156, 162, 170, + 161, 160, 397, 401, 272, 0, 397, 169, 172, 0, + 96, 251, 121, 383, 273, 274, 0, 0, 0, 0, + 0, 0, 145, 0, 56, 75, 70, 72, 76, 0, + 267, 0, 0, 256, 258, 248, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 221, 0, 0, 235, 235, 0, 0, 0, + 0, 188, 0, 0, 207, 204, 11, 0, 0, 385, + 389, 390, 386, 387, 134, 305, 309, 329, 309, 309, + 333, 309, 331, 323, 325, 0, 326, 309, 318, 310, + 340, 346, 312, 348, 306, 0, 362, 366, 128, 0, + 132, 122, 0, 123, 124, 98, 115, 117, 0, 373, + 376, 377, 380, 381, 8, 67, 65, 0, 157, 0, + 0, 0, 39, 155, 0, 400, 0, 0, 403, 0, + 163, 0, 119, 183, 185, 184, 182, 0, 0, 0, + 0, 0, 0, 174, 153, 148, 150, 149, 0, 0, + 146, 143, 0, 268, 269, 270, 0, 0, 0, 0, + 237, 239, 240, 221, 221, 221, 221, 237, 0, 0, + 0, 0, 0, 0, 0, 235, 235, 0, 0, 0, + 221, 221, 221, 236, 221, 221, 0, 0, 221, 205, + 206, 392, 0, 0, 316, 330, 334, 309, 335, 332, + 324, 319, 0, 0, 359, 0, 0, 120, 0, 0, + 370, 0, 158, 159, 91, 398, 0, 405, 402, 171, + 0, 0, 95, 125, 178, 181, 176, 0, 0, 0, + 151, 0, 0, 141, 0, 259, 261, 0, 0, 265, + 264, 221, 238, 0, 0, 0, 0, 234, 0, 223, + 224, 226, 227, 230, 231, 228, 229, 232, 225, 189, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 393, + 391, 336, 308, 307, 0, 0, 129, 116, 118, 371, + 372, 66, 0, 0, 404, 165, 0, 168, 179, 0, + 0, 152, 147, 144, 262, 266, 0, 192, 190, 193, + 194, 237, 222, 198, 199, 196, 197, 202, 0, 0, + 0, 0, 0, 0, 209, 0, 0, 191, 360, 0, + 399, 406, 0, 164, 177, 180, 195, 233, 0, 0, + 0, 0, 0, 0, 0, 235, 0, 130, 166, 0, + 0, 0, 212, 214, 0, 0, 219, 200, 208, 0, + 201, 210, 211, 0, 0, 215, 0, 216, 235, 0, + 220, 218, 0, 213, 217 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 85, 86, 87, 88, 89, 356, 91, 92, 93, - 228, 329, 340, 330, 331, 94, 95, 96, 97, 98, - 99, 478, 352, 100, 101, 102, 103, 104, 105, 106, - 459, 308, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 222, 505, 506, 353, 354, - 355, 357, 358, 575, 638, 120, 121, 122, 123, 124, - 125, 175, 176, 492, 126, 127, 258, 422, 663, 664, - 666, 693, 694, 534, 410, 537, 595, 538, 128, 129, - 130, 131, 165, 132, 133, 238, 239, 240, 512, 363, - 134, 135, 295, 279, 290, 136, 269, 137, 138, 139, - 276, 140, 273, 141, 142, 143, 144, 286, 145, 146, - 147, 148, 149, 297, 150, 151, 301, 152, 153, 154, - 155, 156, 157, 158, 169, 159, 426, 427, 428, 160, - 161, 162, 481, 359, 360, 223, 361 + -1, 92, 93, 94, 95, 96, 348, 98, 99, 100, + 218, 321, 332, 322, 323, 101, 102, 103, 104, 105, + 106, 472, 344, 107, 108, 109, 110, 111, 112, 453, + 300, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 212, 499, 500, 345, 346, + 347, 349, 350, 571, 636, 127, 128, 129, 130, 131, + 132, 182, 183, 486, 133, 134, 249, 415, 663, 664, + 666, 695, 696, 529, 402, 532, 591, 533, 135, 136, + 137, 138, 173, 139, 140, 228, 229, 230, 506, 355, + 141, 142, 143, 286, 270, 281, 144, 260, 145, 146, + 147, 267, 148, 264, 149, 150, 151, 152, 277, 153, + 154, 155, 156, 157, 288, 158, 159, 292, 160, 161, + 162, 163, 164, 165, 166, 177, 167, 419, 420, 421, + 168, 169, 170, 475, 351, 352, 213, 353 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -485 +#define YYPACT_NINF -479 static const yytype_int16 yypact[] = { - 392, -485, 32, -485, 42, -485, -485, -485, 49, -12, - 1337, 63, 91, -485, -485, -485, -485, -485, -485, -485, - -485, 1337, 1337, 172, 31, 31, 31, 31, 31, 31, - 145, -485, -485, -485, 830, 151, 161, -485, 102, -485, - -485, -485, -485, 138, 210, -485, -485, -485, -485, -485, - -485, 124, -485, 105, -33, 169, 190, -45, 176, -5, - 57, 231, 174, 34, 203, 35, 204, 56, 50, -485, - -485, 291, 291, -485, 1337, 251, 296, 297, 313, 320, - -485, 211, 242, -65, 279, 330, 559, -485, 17, -485, - -485, -485, -485, -485, 23, 159, -485, -485, 230, 1444, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, 995, 292, 158, 680, - 265, 1337, 680, 1337, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -8, 283, -485, 316, -485, 156, 193, - 158, 164, 254, 255, -31, -485, 168, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, 167, -485, 166, -485, 280, -485, -485, 1337, - 318, 315, 1337, 175, 177, 178, 179, -485, -485, 308, - 31, -485, -485, 42, -485, -485, 272, 185, 186, 188, - 189, 171, 191, 192, 194, 195, 201, 196, 68, -485, - 202, 244, 276, 282, 232, -485, -485, -485, 247, -485, - 26, -36, 30, -485, -32, 286, -485, 150, 289, -485, - -485, 176, -485, -485, -485, 290, -485, 293, -485, 243, - -485, -485, -485, -485, 266, -485, 208, -485, 176, -485, - 267, -485, -485, -485, -485, 300, 233, 301, 256, 256, - -485, 1337, 305, 306, 307, 309, 278, 294, -485, 295, - 302, -485, -485, -485, -485, 346, -485, 328, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, 335, - 250, -485, -485, -485, -485, -485, -485, 12, -485, -485, - -485, 9, 404, 158, -485, -485, -485, -485, -485, -485, - 298, 1112, -485, 406, 298, -485, -485, 407, -4, -485, - 291, -485, -485, -485, 158, 33, 261, 262, 268, 106, - -20, 14, 1337, -485, -485, -485, -485, -485, 321, 223, - 354, -14, -485, -485, -485, 269, 39, 39, 39, 39, - -83, 270, 277, 281, 284, 285, 287, 288, 317, 319, - -485, 39, 39, 39, 39, 322, 323, 39, -485, 355, - 356, -485, -485, -485, 390, 391, -485, 303, -485, -485, - -485, -485, 331, 176, -485, 176, 60, -485, 176, -485, - -485, -485, 369, -485, 176, -485, -485, -485, -485, -485, - -485, -52, 339, -485, -485, 388, 324, -485, 378, -485, - -485, -485, 437, 438, 325, -485, -485, -485, -485, -485, - -485, -485, -485, 299, -485, 314, 139, 680, -485, -485, - -35, -485, 1337, 1337, -485, 680, -13, 680, 256, -485, - -485, -485, -485, 33, 33, 33, 326, 381, 382, -485, - -485, -485, -485, -485, -11, -27, -485, 304, 327, -485, - -485, -485, 329, 383, -50, 332, 39, -485, -485, -485, - -485, -485, -485, 39, 384, 39, 39, 39, 39, 39, - 39, 39, 39, 39, -17, -485, -485, -485, -485, -485, - 333, 334, -485, -485, -485, -485, 429, 244, -485, -485, - -485, 176, -485, -485, -485, -485, 353, 377, 336, 347, - 417, -485, 419, 421, -2, 422, -485, -485, -485, -485, - 428, -485, 1230, -485, 433, 80, -485, -485, -485, -485, - -485, 33, 340, 345, -485, 435, 14, -485, 1337, -485, - -485, 348, 349, -485, -485, -485, -485, -16, -7, -1, - 0, -485, 357, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, 171, 2, 3, 5, 6, 86, 453, - 7, -485, -485, -485, -485, -485, 447, 361, -485, -485, - -485, -485, -485, -485, 363, 1337, -485, -485, 123, -485, - -485, 33, 33, -485, -485, -485, -485, -485, 8, -485, - -485, -485, -485, 39, -485, -485, -485, -485, -485, 367, - 368, 371, 405, 344, 413, 412, 365, -485, -485, 494, - -485, -485, 505, -485, -485, -485, -485, -485, 39, 39, - -70, 513, 560, 86, 39, 561, -485, -485, 424, 427, - 430, -485, 431, 432, 434, -485, -485, 18, -485, -485, - -485, 39, 39, -485, 513, -485, 39, 441, -485, -485, - 442, -485, -485 + 418, -479, 36, -479, -62, -479, -479, -479, 47, -14, + 1104, 50, 68, -479, -479, -479, -479, -479, -479, -479, + -479, 1104, 1104, 116, 8, 8, 8, 8, 8, 8, + 300, -479, -479, -479, 770, 109, 51, -479, 29, -479, + -479, -479, -479, 137, 157, -479, -479, -479, -479, -479, + -479, 129, -479, 221, 54, 71, 210, -54, 124, -2, + -36, 182, 172, 92, 217, -15, 224, 148, 49, 297, + -479, -479, 319, 319, -479, 1104, 285, 328, 330, 348, + 355, -479, 254, 291, -40, -479, -479, -479, -479, -479, + -479, 327, 379, 595, -479, -8, -479, -479, -479, -479, + -479, 11, 200, -479, -479, 360, 1212, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, 944, 341, 201, 95, 316, 1104, 95, + 1104, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, 0, 334, -479, 367, -479, 199, 218, 208, 305, + 308, -11, -479, 230, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, 216, -479, 227, -479, 350, -479, -479, 1104, + 388, 385, 1104, 234, 235, 237, 238, -479, -479, 383, + 8, -479, -479, -62, -479, -479, 353, 256, 257, 263, + 264, 212, 267, 275, 277, 278, 279, 198, 280, 46, + -479, 286, 76, 380, 384, 345, -479, -479, -479, 351, + -479, -25, -44, 38, -479, -16, 386, -479, 207, 392, + -479, -479, 124, -479, -479, -479, 393, -479, 394, -479, + 346, -479, -479, -479, -479, 361, -479, 301, -479, 124, + -479, 363, -479, -479, -479, -479, 400, 329, 402, 403, + 354, 354, -479, 1104, 405, 406, 407, 409, 376, 377, + -479, 378, 397, -479, -479, -479, -479, 447, -479, 414, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, 417, 325, -479, -479, -479, -479, -479, -479, 13, + -479, -479, -479, 10, 489, 201, -479, -479, -479, -479, + -479, -479, 381, 206, -479, 490, 381, -479, -479, 491, + 3, -479, 319, -479, -479, -479, 120, 337, 338, 340, + 147, -14, 2, 1104, -479, -479, -479, -479, -479, 408, + 284, 439, -7, -479, -479, -479, 342, 136, 136, 136, + 136, -27, 343, 347, 349, 352, 356, 357, 358, 359, + 364, 365, -479, 136, 136, 136, 136, 136, 366, 368, + 136, -479, 443, 444, -479, -479, -479, 470, 471, -479, + 370, -479, -479, -479, -479, 410, 124, -479, 124, 41, + -479, 124, -479, -479, -479, 451, -479, 124, -479, -479, + -479, -479, -479, -479, -69, 427, -479, -479, 464, 387, + -479, -479, 468, -479, -479, -479, 532, 535, 389, -479, + -479, -479, -479, -479, -479, -479, -479, 390, -479, 382, + 169, 95, -479, -479, -29, -479, 1104, 1104, -479, 95, + -9, 95, 354, -479, -479, -479, -479, 120, 120, 120, + 416, 506, 515, -479, -479, -479, -479, -479, 7, 110, + -479, 429, 431, -479, -479, -479, 432, 538, -53, 442, + 136, -479, -479, -479, -479, -479, -479, 136, 550, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, -13, + -479, -479, -479, -479, -479, -479, 450, 452, -479, -479, + -479, -479, 574, 76, -479, -479, -479, 124, -479, -479, + -479, -479, 521, 522, 460, 486, 559, -479, 560, 561, + 26, 562, -479, -479, -479, -479, 563, -479, 1070, -479, + 569, 70, -479, -479, -479, -479, -479, 120, 472, 473, + -479, 572, 2, -479, 1104, -479, -479, 474, 475, -479, + -479, -479, -479, -5, -4, -3, -1, -479, 479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + 212, 9, 15, 17, 18, 19, 140, 589, 20, -479, + -479, -479, -479, -479, 578, 481, -479, -479, -479, -479, + -479, -479, 480, 1104, -479, -479, 111, -479, -479, 120, + 120, -479, -479, -479, -479, -479, 21, -479, -479, -479, + -479, 136, -479, -479, -479, -479, -479, -479, 482, 483, + 484, 485, 487, 488, 492, 495, 496, -479, -479, 585, + -479, -479, 587, -479, -479, -479, -479, -479, 136, 136, + -59, 508, 588, 633, 140, 136, 652, -479, -479, 510, + 511, 514, -479, -479, 516, 513, 518, -479, -479, 42, + -479, -479, -479, 136, 136, -479, 588, -479, 136, 517, + -479, -479, 519, -479, -479 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -485, -485, -485, 520, 575, 484, 4, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, 448, -485, -485, -485, -485, -485, -485, -485, - -296, -62, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, 525, 55, -485, 36, -148, -302, - -485, -129, 45, -485, -485, 126, 147, 163, 187, 200, - -485, 241, -485, -477, 496, -485, -485, -485, -57, -485, - -485, -77, -485, -309, 15, -387, -484, -391, -485, -485, - -485, -485, 386, -485, -485, 264, 393, -485, -485, -485, - -485, -485, 198, -56, 342, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, - -485, -485, -485, -485, -485, -485, -485, -485, 85, -485, - -485, 540, 271, -485, 173, -485, -10 + -479, -479, -479, 607, 668, 571, 1, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, 534, -479, -479, -479, -479, -479, -479, -287, + -60, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, 605, 632, -479, 126, -146, -281, + -479, -134, 138, -479, -479, 128, 131, 141, 151, 164, + -479, 339, -479, -455, 577, -479, -479, -479, 28, -479, + -479, 12, -479, -227, 103, -402, -478, -381, -479, -479, + -479, -479, 494, -479, -479, 253, 493, -479, -479, -479, + -479, -479, -479, 290, -55, 436, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, 174, + -479, -479, 621, 369, -479, 97, -479, -10 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -442 +#define YYTABLE_NINF -435 static const yytype_int16 yytable[] = { - 224, 282, 283, 365, 90, 519, 520, 521, 522, 299, - 309, 230, 231, 460, 326, 368, 578, 579, 580, -91, - 535, 536, 374, -92, 612, 649, 542, 539, 326, 3, - 4, 5, 6, 7, 650, 592, 10, -166, 90, 601, - 651, 652, 24, 655, 656, 690, 657, 658, 667, 676, - 569, 479, 318, 440, 378, 319, 24, 25, 26, 27, - 28, 29, -441, 500, 224, 171, 479, 324, 166, 170, - 556, 514, 479, 171, 584, 233, 234, 305, 172, 173, - 284, 435, 225, 631, 226, 326, 172, 173, 278, 224, - 90, 523, 436, 274, 524, 235, 441, 278, 328, 501, - 275, 442, 341, 515, 640, 320, 691, 281, 39, 418, - 419, 420, 163, 24, 502, 632, 236, 167, 489, 168, - 229, 557, 306, 285, 517, 596, 593, 227, 518, 310, - 90, 503, 596, 490, 603, 604, 605, 606, 607, 608, - 570, 379, 611, 433, 609, 610, 586, 438, 237, 587, - 491, 293, 174, 421, 348, 294, 613, 613, -166, 278, - 174, 585, 574, 278, 674, 675, 613, 351, 278, 677, - 164, 351, 613, 613, 479, 613, 613, 551, 613, 613, - 613, 613, 298, -441, 351, 474, 504, 659, 325, -441, - 287, 496, 577, 278, 705, 327, 288, 289, 706, 660, - 661, 232, 662, 476, 497, 498, 302, 303, 304, 261, - 597, 598, 599, 600, 434, 437, 439, 262, 263, 384, - 333, 445, 387, 265, 342, 447, 614, 615, 616, 246, - 617, 270, 271, 620, 272, 326, 3, 4, 5, 6, - 7, 334, 453, 267, 268, 343, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 400, 335, 257, 372, - 373, 344, 596, 24, 25, 26, 27, 28, 29, 509, - 510, 511, 401, 402, 403, 404, 264, 405, 406, 407, - 408, 336, 444, 278, 409, 345, 648, 688, 689, 241, - 242, 243, 244, 245, 337, 266, 672, 697, 346, 673, - 277, 461, 278, 424, 364, 425, 366, 280, 488, 278, - 707, 708, 415, 416, 351, 567, 291, 292, 307, 710, - 296, 300, 311, 312, 313, 314, 315, 317, 316, 321, - 322, 339, 30, 351, 362, 369, 370, 371, 375, 376, - 377, 380, 381, 382, 383, 385, 386, 392, 568, 431, - 388, 484, 389, 390, 391, 475, 573, 395, 576, 396, - 397, 429, 398, 399, 432, 411, 412, 430, 413, 414, - 417, 443, 507, 423, 446, 448, 287, 549, 449, 550, - 552, 452, 553, 451, 454, 455, 457, 456, 555, 458, - 462, 463, 464, 1, 465, 466, 470, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 467, 468, 471, 16, 17, 18, 19, 20, 469, - 472, 21, 22, 473, 23, 24, 25, 26, 27, 28, - 29, 477, 30, 485, 487, 493, 494, 480, 508, 513, - 543, 544, 495, 516, 525, 31, 32, 33, 34, 35, - 545, 526, 294, 546, 554, 527, 558, 36, 528, 529, - 559, 530, 531, 561, 562, 563, 582, 583, 591, 602, - 624, 565, 571, 572, 37, 38, 547, 39, 40, 41, - 42, 588, 43, 44, 45, 46, 47, 48, 49, 50, - 566, 532, 621, 533, 625, 623, 540, 541, 560, 564, - 581, 627, 628, 589, 629, 590, 630, 633, 594, 626, - 51, 618, 619, 634, 641, 52, 53, 54, 637, 642, - 643, 665, 55, 682, 646, 647, 56, 57, 58, 59, - 60, 653, 668, 61, 62, 669, 63, 64, 65, 670, - 66, 67, 678, 679, 685, 68, 680, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 636, 84, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 645, 686, - 681, 16, 17, 18, 19, 20, 683, 684, 21, 22, - 687, 23, 24, 25, 26, 27, 28, 29, 692, 30, - 699, 695, 698, 700, 701, 702, 323, 704, 703, 260, - 349, 367, 31, 32, 33, 34, 35, 711, 712, 332, - 639, 499, 644, 350, 36, 671, 696, 709, 654, 394, - 548, 450, 622, 393, 338, 486, 0, 0, 0, 0, - 0, 37, 38, 0, 39, 40, 41, 42, 0, 43, - 44, 45, 46, 47, 48, 49, 50, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, - 0, 0, 52, 53, 54, 326, 0, 0, 0, 55, - 0, 0, 0, 56, 57, 58, 59, 60, 0, 0, - 61, 62, 0, 63, 64, 65, 0, 66, 67, 0, - 0, 0, 68, 24, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 0, - 84, 0, 0, 177, 178, 179, 180, 181, 182, 0, - 0, 0, 183, 0, 184, 185, 186, 187, 188, 189, - 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 191, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 0, 0, 208, - 209, 0, 210, 0, 0, 0, 211, 212, 0, 213, - 0, 214, 215, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 216, 0, 0, 0, 217, 0, 0, - 0, 218, 219, 0, 220, 2, 3, 4, 5, 6, + 214, 97, 273, 274, 534, 357, 513, 514, 515, 516, + 290, 220, 221, 301, 454, 318, 318, 3, 4, 5, + 6, 7, 530, 531, 10, 360, 535, -92, 609, 538, + -93, 588, 574, 575, 576, 97, 647, 648, 649, 597, + 650, -167, 316, 24, 24, 25, 26, 27, 28, 29, + 653, 494, 223, 224, 552, 565, 654, 691, 655, 656, + 657, 667, 676, -434, 473, 214, 174, 172, 433, 215, + 178, 216, 225, 369, 428, 318, 296, 508, 310, 473, + 269, 311, 275, 179, 180, 429, 495, 411, 412, 413, + 269, 580, 226, 426, 97, 39, 340, 219, 278, 272, + 318, 496, 320, 24, 279, 280, 333, 253, 254, 269, + 629, 509, 553, 434, 217, 175, 171, 176, 435, 269, + 497, 297, 638, 605, 606, 692, 227, 276, 24, 592, + 414, 589, 312, 289, 97, 417, 592, 418, 599, 600, + 601, 602, 603, 604, 630, 222, 607, 608, 184, 185, + 186, 187, 188, 189, 566, 517, 431, 190, 518, 547, + 191, 192, 193, 194, 195, 196, 181, 252, 610, 370, + -167, 317, 269, 677, 570, 269, 610, 610, 610, 197, + 610, 265, 498, 343, 674, 675, 343, 581, 266, 473, + 610, 319, -434, 343, 468, 573, 610, 470, 610, 610, + 610, 610, 610, 268, 483, 269, 427, 430, 432, 375, + 284, 255, 378, 438, 285, 198, 199, 440, 200, 484, + 511, 256, 201, 202, 512, 203, 707, 204, 205, 325, + 708, 490, 326, 334, 446, 356, 335, 358, 485, 206, + 658, 257, 327, 207, 491, 492, 336, 208, 209, 258, + 259, 210, 328, 659, 660, 661, 337, 662, 269, 184, + 185, 186, 187, 188, 189, 329, 282, 211, 190, 338, + 592, 191, 192, 193, 194, 195, 196, 476, 231, 232, + 233, 234, 235, 699, 364, 365, 593, 594, 595, 596, + 197, 582, 672, 455, 583, 673, 391, 689, 690, 293, + 294, 295, 482, 611, 612, 613, 712, 614, 615, 408, + 409, 618, 392, 393, 394, 395, 283, 396, 397, 398, + 399, 400, 709, 710, 298, 401, 198, 199, 271, 200, + 503, 504, 505, 201, 202, 287, 203, 564, 204, 205, + 437, 269, 291, 478, 469, 569, 299, 572, 261, 262, + 206, 263, 343, 563, 207, 304, 303, 305, 208, 209, + 306, 307, 210, 501, 646, 318, 3, 4, 5, 6, + 7, 545, 308, 546, 548, 309, 549, 313, 211, 314, + 331, 30, 551, 236, 343, 354, 361, 362, 363, 367, + 366, 477, 368, 24, 25, 26, 27, 28, 29, 372, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 371, 373, 248, 374, 376, 377, 379, 380, 1, + 381, 382, 383, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 386, 387, 388, + 16, 17, 18, 19, 20, 389, 390, 21, 22, 403, + 23, 24, 25, 26, 27, 28, 29, 404, 30, 405, + 406, 407, 410, 424, 422, 416, 567, 568, 423, 425, + 436, 31, 32, 33, 34, 35, 439, 441, 442, 444, + 278, 447, 445, 36, 448, 449, 450, 451, 452, 456, + 457, 458, 621, 459, 460, 461, 462, 464, 465, 37, + 38, 466, 39, 40, 41, 42, 467, 43, 44, 45, + 46, 47, 48, 49, 50, 463, 471, 479, 481, 487, + 488, 474, 489, 507, 510, 519, 502, 539, 540, 520, + 541, 521, 285, 542, 522, 550, 555, 51, 523, 524, + 525, 526, 52, 53, 54, 554, 527, 528, 536, 55, + 537, 543, 557, 56, 57, 58, 59, 60, 634, 558, + 61, 62, 559, 63, 64, 65, 562, 66, 67, 556, + 561, 560, 68, 69, 643, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 578, 85, 86, 87, 88, 89, 90, 91, 577, 579, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 584, 585, 586, 16, 17, 18, + 19, 20, 587, 671, 21, 22, 590, 23, 24, 25, + 26, 27, 28, 29, 598, 30, 616, 619, 617, 622, + 623, 624, 625, 626, 627, 628, 631, 632, 31, 32, + 33, 34, 35, 635, 639, 640, 641, 665, 644, 645, + 36, 651, 668, 669, 670, 678, 679, 680, 681, 687, + 682, 688, 694, 684, 697, 683, 37, 38, 685, 39, + 40, 41, 42, 686, 43, 44, 45, 46, 47, 48, + 49, 50, 693, 700, 701, 702, 703, 705, 704, 706, + 315, 713, 251, 714, 341, 359, 324, 302, 642, 637, + 493, 342, 698, 652, 51, 544, 443, 620, 711, 52, + 53, 54, 330, 384, 0, 480, 55, 385, 0, 0, + 56, 57, 58, 59, 60, 0, 0, 61, 62, 0, + 63, 64, 65, 0, 66, 67, 0, 0, 0, 68, + 69, 0, 70, 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, 0, 85, 86, + 87, 88, 89, 90, 91, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, - 221, 0, 16, 17, 18, 19, 20, 0, 0, 21, + 0, 0, 16, 17, 18, 19, 20, 0, 0, 21, 22, 0, 23, 24, 25, 26, 27, 28, 29, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 31, 32, 33, 259, 35, 0, 0, + 0, 0, 0, 31, 32, 33, 250, 35, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 37, 38, 0, 39, 40, 41, 42, 0, - 43, 44, 45, 46, 47, 48, 49, 50, 0, 0, + 0, 37, 38, 0, 39, 40, 41, 42, 0, 43, + 44, 45, 46, 47, 48, 49, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, - 0, 0, 0, 52, 53, 54, 0, 0, 0, 0, - 55, 0, 0, 0, 56, 57, 58, 59, 60, 0, - 0, 61, 62, 0, 63, 64, 65, 0, 66, 67, - 0, 0, 0, 68, 0, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 0, 0, 0, 16, 17, 18, - 19, 20, 0, 0, 21, 22, 0, 23, 24, 25, - 26, 27, 28, 29, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 31, 32, - 33, 259, 35, 0, 0, 0, 0, 0, 0, 0, - 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 37, 38, 0, - 39, 40, 41, 42, 0, 43, 44, 45, 46, 47, - 48, 49, 50, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, + 0, 0, 0, 0, 52, 53, 54, 0, 0, 0, + 0, 55, 0, 0, 0, 56, 57, 58, 59, 60, + 0, 0, 61, 62, 0, 63, 64, 65, 0, 66, + 67, 0, 0, 0, 68, 69, 0, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 0, 85, 86, 87, 88, 89, 90, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 0, 0, 0, 16, 17, 18, 19, + 20, 0, 0, 21, 22, 0, 23, 24, 25, 26, + 27, 28, 29, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 31, 32, 33, + 250, 35, 0, 0, 0, 0, 0, 0, 0, 36, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 37, 38, 0, 39, 40, + 41, 42, 0, 43, 44, 45, 46, 47, 48, 49, + 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 52, 53, 54, 0, 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 59, 60, 0, 0, 61, 62, 0, 63, - 64, 65, 0, 66, 67, 0, 0, 0, 68, 0, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 177, 178, 179, 180, 181, - 182, 0, 0, 0, 183, 0, 184, 185, 186, 187, - 188, 189, 190, 482, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 191, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 0, - 0, 208, 209, 0, 210, 0, 0, 0, 211, 212, - 0, 213, 0, 214, 215, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 216, 0, 0, 0, 217, - 0, 0, 0, 218, 219, 0, 220, 0, 0, 0, + 64, 65, 0, 66, 67, 0, 0, 0, 68, 69, + 0, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 0, 85, 86, 87, + 88, 89, 90, 184, 185, 186, 187, 188, 189, 0, + 0, 0, 190, 0, 0, 191, 192, 193, 194, 195, + 196, 633, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 197, 0, 0, 184, 185, 186, + 187, 188, 189, 0, 0, 0, 190, 0, 0, 191, + 192, 193, 194, 195, 196, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, + 198, 199, 0, 200, 0, 0, 0, 201, 202, 0, + 203, 0, 204, 205, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 206, 0, 0, 0, 207, 0, + 0, 0, 208, 209, 198, 199, 210, 200, 0, 0, + 0, 201, 202, 0, 203, 0, 204, 205, 0, 0, + 0, 0, 211, 0, 0, 0, 0, 0, 206, 0, + 0, 0, 207, 0, 0, 0, 208, 209, 0, 0, + 210, 0, 0, 0, 0, 184, 185, 186, 187, 188, + 189, 0, 0, 0, 190, 0, 211, 191, 192, 193, + 194, 195, 196, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 221, 177, 178, 179, 180, 181, 182, 483, - 0, 0, 183, 0, 184, 185, 186, 187, 188, 189, - 190, 635, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 0, 0, 208, - 209, 0, 210, 0, 0, 0, 211, 212, 0, 213, - 0, 214, 215, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 216, 0, 0, 0, 217, 0, 0, - 0, 218, 219, 0, 220, 0, 0, 0, 0, 0, - 177, 178, 179, 180, 181, 182, 0, 0, 0, 183, - 221, 184, 185, 186, 187, 188, 189, 190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 191, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 192, 193, - 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 207, 0, 0, 208, 209, 0, 210, - 0, 0, 0, 211, 212, 0, 213, 0, 214, 215, + 0, 0, 198, 199, 0, 200, 0, 0, 0, 201, + 202, 0, 203, 0, 204, 205, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 206, 0, 0, 0, + 207, 0, 0, 0, 208, 209, 0, 0, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 216, 0, 0, 0, 217, 0, 0, 0, 218, 219, - 0, 220, 0, 0, 0, 0, 0, 177, 178, 179, - 180, 181, 182, 0, 0, 0, 183, 221, 184, 185, - 186, 187, 188, 189, 190, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 347, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 0, 0, 208, 209, 0, 210, 0, 0, 0, - 211, 212, 0, 213, 0, 214, 215, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 216, 0, 0, - 0, 217, 0, 0, 0, 218, 219, 0, 220, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 221 + 0, 0, 0, 0, 211 }; static const yytype_int16 yycheck[] = { - 10, 57, 58, 132, 0, 396, 397, 398, 399, 65, - 72, 21, 22, 309, 5, 163, 493, 494, 495, 27, - 411, 412, 170, 27, 41, 41, 417, 414, 5, 6, - 7, 8, 9, 10, 41, 85, 13, 50, 34, 523, - 41, 41, 33, 41, 41, 115, 41, 41, 41, 41, - 85, 353, 117, 85, 85, 120, 33, 34, 35, 36, - 37, 38, 50, 49, 74, 85, 368, 50, 19, 81, - 122, 85, 374, 85, 85, 44, 45, 27, 98, 99, - 85, 117, 19, 85, 21, 5, 98, 99, 133, 99, - 86, 174, 128, 126, 177, 64, 128, 133, 94, 85, - 133, 133, 98, 117, 581, 170, 176, 152, 85, 41, - 42, 43, 80, 33, 100, 117, 85, 68, 85, 70, - 29, 173, 72, 128, 85, 516, 176, 64, 89, 74, - 126, 117, 523, 100, 525, 526, 527, 528, 529, 530, - 175, 172, 533, 117, 531, 532, 173, 117, 117, 176, - 117, 117, 172, 85, 99, 121, 173, 173, 171, 133, - 172, 172, 175, 133, 641, 642, 173, 175, 133, 653, - 128, 175, 173, 173, 476, 173, 173, 117, 173, 173, - 173, 173, 147, 171, 175, 176, 172, 101, 171, 177, - 133, 85, 488, 133, 176, 172, 139, 140, 180, 113, - 114, 29, 116, 351, 98, 99, 150, 151, 152, 58, - 519, 520, 521, 522, 270, 271, 272, 56, 57, 229, - 94, 277, 232, 85, 98, 281, 535, 536, 537, 84, - 539, 126, 127, 542, 129, 5, 6, 7, 8, 9, - 10, 94, 298, 119, 120, 98, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 85, 94, 113, 66, - 67, 98, 653, 33, 34, 35, 36, 37, 38, 46, - 47, 48, 101, 102, 103, 104, 174, 106, 107, 108, - 109, 94, 132, 133, 113, 98, 595, 678, 679, 25, - 26, 27, 28, 29, 94, 85, 173, 684, 98, 176, - 131, 311, 133, 59, 131, 61, 133, 117, 370, 133, - 701, 702, 111, 112, 175, 176, 85, 143, 27, 706, - 117, 117, 71, 27, 27, 12, 6, 85, 117, 50, - 0, 172, 40, 175, 69, 52, 20, 181, 174, 85, - 85, 173, 175, 177, 64, 27, 31, 39, 477, 117, - 175, 361, 175, 175, 175, 351, 485, 85, 487, 174, - 174, 85, 174, 174, 117, 174, 174, 85, 174, 174, - 174, 85, 382, 171, 85, 85, 133, 433, 85, 435, - 436, 173, 438, 117, 117, 85, 85, 154, 444, 133, - 85, 85, 85, 1, 85, 117, 50, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 117, 117, 85, 22, 23, 24, 25, 26, 117, - 85, 29, 30, 173, 32, 33, 34, 35, 36, 37, - 38, 27, 40, 27, 27, 174, 174, 139, 117, 85, - 85, 85, 174, 174, 174, 53, 54, 55, 56, 57, - 60, 174, 121, 62, 85, 174, 117, 65, 174, 174, - 72, 174, 174, 85, 27, 27, 85, 85, 85, 85, - 117, 172, 482, 483, 82, 83, 173, 85, 86, 87, - 88, 177, 90, 91, 92, 93, 94, 95, 96, 97, - 176, 174, 63, 174, 117, 551, 174, 174, 174, 174, - 174, 154, 85, 176, 85, 176, 85, 85, 176, 173, - 118, 178, 178, 85, 174, 123, 124, 125, 85, 174, - 85, 68, 130, 179, 176, 176, 134, 135, 136, 137, - 138, 174, 85, 141, 142, 174, 144, 145, 146, 176, - 148, 149, 175, 175, 179, 153, 175, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 572, 171, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 588, 85, - 175, 22, 23, 24, 25, 26, 173, 175, 29, 30, - 85, 32, 33, 34, 35, 36, 37, 38, 85, 40, - 176, 41, 41, 176, 174, 174, 86, 173, 176, 34, - 126, 163, 53, 54, 55, 56, 57, 176, 176, 94, - 575, 380, 586, 127, 65, 635, 683, 704, 613, 243, - 432, 289, 547, 240, 94, 364, -1, -1, -1, -1, - -1, 82, 83, -1, 85, 86, 87, 88, -1, 90, - 91, 92, 93, 94, 95, 96, 97, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 118, -1, -1, - -1, -1, 123, 124, 125, 5, -1, -1, -1, 130, - -1, -1, -1, 134, 135, 136, 137, 138, -1, -1, - 141, 142, -1, 144, 145, 146, -1, 148, 149, -1, - -1, -1, 153, 33, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, 169, -1, - 171, -1, -1, 53, 54, 55, 56, 57, 58, -1, - -1, -1, 62, -1, 64, 65, 66, 67, 68, 69, - 70, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 85, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, -1, -1, 119, - 120, -1, 122, -1, -1, -1, 126, 127, -1, 129, - -1, 131, 132, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 143, -1, -1, -1, 147, -1, -1, - -1, 151, 152, -1, 154, 5, 6, 7, 8, 9, + 10, 0, 57, 58, 406, 139, 387, 388, 389, 390, + 65, 21, 22, 73, 301, 5, 5, 6, 7, 8, + 9, 10, 403, 404, 13, 171, 407, 27, 41, 410, + 27, 84, 487, 488, 489, 34, 41, 41, 41, 517, + 41, 50, 50, 33, 33, 34, 35, 36, 37, 38, + 41, 49, 44, 45, 123, 84, 41, 116, 41, 41, + 41, 41, 41, 50, 345, 75, 19, 129, 84, 19, + 84, 21, 64, 84, 118, 5, 27, 84, 118, 360, + 134, 121, 84, 97, 98, 129, 84, 41, 42, 43, + 134, 84, 84, 118, 93, 84, 106, 29, 134, 153, + 5, 99, 101, 33, 140, 141, 105, 56, 57, 134, + 84, 118, 181, 129, 64, 68, 80, 70, 134, 134, + 118, 72, 577, 525, 526, 184, 118, 129, 33, 510, + 84, 184, 172, 148, 133, 59, 517, 61, 519, 520, + 521, 522, 523, 524, 118, 29, 527, 528, 53, 54, + 55, 56, 57, 58, 183, 182, 118, 62, 185, 118, + 65, 66, 67, 68, 69, 70, 180, 58, 181, 180, + 179, 179, 134, 651, 183, 134, 181, 181, 181, 84, + 181, 127, 180, 183, 639, 640, 183, 180, 134, 470, + 181, 180, 179, 183, 184, 482, 181, 343, 181, 181, + 181, 181, 181, 132, 84, 134, 261, 262, 263, 219, + 118, 182, 222, 268, 122, 120, 121, 272, 123, 99, + 84, 84, 127, 128, 88, 130, 184, 132, 133, 101, + 188, 84, 101, 105, 289, 138, 105, 140, 118, 144, + 100, 84, 101, 148, 97, 98, 105, 152, 153, 120, + 121, 156, 101, 113, 114, 115, 105, 117, 134, 53, + 54, 55, 56, 57, 58, 101, 84, 172, 62, 105, + 651, 65, 66, 67, 68, 69, 70, 71, 25, 26, + 27, 28, 29, 685, 66, 67, 513, 514, 515, 516, + 84, 181, 181, 303, 184, 184, 84, 678, 679, 151, + 152, 153, 362, 530, 531, 532, 708, 534, 535, 111, + 112, 538, 100, 101, 102, 103, 144, 105, 106, 107, + 108, 109, 703, 704, 27, 113, 120, 121, 118, 123, + 46, 47, 48, 127, 128, 118, 130, 471, 132, 133, + 133, 134, 118, 353, 343, 479, 27, 481, 127, 128, + 144, 130, 183, 184, 148, 27, 71, 27, 152, 153, + 12, 6, 156, 373, 591, 5, 6, 7, 8, 9, + 10, 426, 118, 428, 429, 84, 431, 50, 172, 0, + 180, 40, 437, 83, 183, 69, 52, 20, 189, 84, + 182, 185, 84, 33, 34, 35, 36, 37, 38, 183, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 181, 185, 113, 64, 27, 31, 183, 183, 1, + 183, 183, 39, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 84, 182, 182, + 22, 23, 24, 25, 26, 182, 182, 29, 30, 182, + 32, 33, 34, 35, 36, 37, 38, 182, 40, 182, + 182, 182, 182, 118, 84, 179, 476, 477, 84, 118, + 84, 53, 54, 55, 56, 57, 84, 84, 84, 118, + 134, 118, 181, 65, 84, 156, 84, 84, 134, 84, + 84, 84, 547, 84, 118, 118, 118, 50, 84, 81, + 82, 84, 84, 85, 86, 87, 181, 89, 90, 91, + 92, 93, 94, 95, 96, 118, 27, 27, 27, 182, + 182, 140, 182, 84, 182, 182, 118, 84, 84, 182, + 60, 182, 122, 62, 182, 84, 72, 119, 182, 182, + 182, 182, 124, 125, 126, 118, 182, 182, 182, 131, + 182, 181, 84, 135, 136, 137, 138, 139, 568, 27, + 142, 143, 27, 145, 146, 147, 184, 149, 150, 182, + 180, 182, 154, 155, 584, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, + 84, 173, 174, 175, 176, 177, 178, 179, 182, 84, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 185, 184, 184, 22, 23, 24, + 25, 26, 84, 633, 29, 30, 184, 32, 33, 34, + 35, 36, 37, 38, 84, 40, 186, 63, 186, 118, + 118, 181, 156, 84, 84, 84, 84, 84, 53, 54, + 55, 56, 57, 84, 182, 182, 84, 68, 184, 184, + 65, 182, 84, 182, 184, 183, 183, 183, 183, 84, + 183, 84, 84, 181, 41, 187, 81, 82, 183, 84, + 85, 86, 87, 187, 89, 90, 91, 92, 93, 94, + 95, 96, 184, 41, 184, 184, 182, 184, 182, 181, + 93, 184, 34, 184, 133, 171, 101, 75, 582, 571, + 371, 134, 684, 610, 119, 425, 280, 543, 706, 124, + 125, 126, 101, 230, -1, 356, 131, 233, -1, -1, + 135, 136, 137, 138, 139, -1, -1, 142, 143, -1, + 145, 146, 147, -1, 149, 150, -1, -1, -1, 154, + 155, -1, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, -1, 173, 174, + 175, 176, 177, 178, 179, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, -1, - 170, -1, 22, 23, 24, 25, 26, -1, -1, 29, + -1, -1, 22, 23, 24, 25, 26, -1, -1, 29, 30, -1, 32, 33, 34, 35, 36, 37, 38, -1, 40, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1, -1, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 82, 83, -1, 85, 86, 87, 88, -1, - 90, 91, 92, 93, 94, 95, 96, 97, -1, -1, + -1, 81, 82, -1, 84, 85, 86, 87, -1, 89, + 90, 91, 92, 93, 94, 95, 96, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 118, -1, - -1, -1, -1, 123, 124, 125, -1, -1, -1, -1, - 130, -1, -1, -1, 134, 135, 136, 137, 138, -1, - -1, 141, 142, -1, 144, 145, 146, -1, 148, 149, - -1, -1, -1, 153, -1, 155, 156, 157, 158, 159, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 119, + -1, -1, -1, -1, 124, 125, 126, -1, -1, -1, + -1, 131, -1, -1, -1, 135, 136, 137, 138, 139, + -1, -1, 142, 143, -1, 145, 146, 147, -1, 149, + 150, -1, -1, -1, 154, 155, -1, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, -1, -1, -1, 22, 23, 24, - 25, 26, -1, -1, 29, 30, -1, 32, 33, 34, - 35, 36, 37, 38, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 53, 54, - 55, 56, 57, -1, -1, -1, -1, -1, -1, -1, - 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 82, 83, -1, - 85, 86, 87, 88, -1, 90, 91, 92, 93, 94, - 95, 96, 97, -1, -1, -1, -1, -1, -1, -1, + 170, 171, -1, 173, 174, 175, 176, 177, 178, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, -1, -1, -1, 22, 23, 24, 25, + 26, -1, -1, 29, 30, -1, 32, 33, 34, 35, + 36, 37, 38, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 53, 54, 55, + 56, 57, -1, -1, -1, -1, -1, -1, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 118, -1, -1, -1, -1, 123, 124, - 125, -1, -1, -1, -1, 130, -1, -1, -1, 134, - 135, 136, 137, 138, -1, -1, 141, 142, -1, 144, - 145, 146, -1, 148, 149, -1, -1, -1, 153, -1, - 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 53, 54, 55, 56, 57, - 58, -1, -1, -1, 62, -1, 64, 65, 66, 67, - 68, 69, 70, 71, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 85, -1, -1, + -1, -1, -1, -1, -1, 81, 82, -1, 84, 85, + 86, 87, -1, 89, 90, 91, 92, 93, 94, 95, + 96, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, -1, - -1, 119, 120, -1, 122, -1, -1, -1, 126, 127, - -1, 129, -1, 131, 132, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 143, -1, -1, -1, 147, - -1, -1, -1, 151, 152, -1, 154, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 170, 53, 54, 55, 56, 57, 58, 177, - -1, -1, 62, -1, 64, 65, 66, 67, 68, 69, + -1, -1, -1, 119, -1, -1, -1, -1, 124, 125, + 126, -1, -1, -1, -1, 131, -1, -1, -1, 135, + 136, 137, 138, 139, -1, -1, 142, 143, -1, 145, + 146, 147, -1, 149, 150, -1, -1, -1, 154, 155, + -1, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, -1, 173, 174, 175, + 176, 177, 178, 53, 54, 55, 56, 57, 58, -1, + -1, -1, 62, -1, -1, 65, 66, 67, 68, 69, 70, 71, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 85, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, -1, -1, 119, - 120, -1, 122, -1, -1, -1, 126, 127, -1, 129, - -1, 131, 132, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 143, -1, -1, -1, 147, -1, -1, - -1, 151, 152, -1, 154, -1, -1, -1, -1, -1, - 53, 54, 55, 56, 57, 58, -1, -1, -1, 62, - 170, 64, 65, 66, 67, 68, 69, 70, -1, -1, + -1, -1, -1, -1, 84, -1, -1, 53, 54, 55, + 56, 57, 58, -1, -1, -1, 62, -1, -1, 65, + 66, 67, 68, 69, 70, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 84, -1, + 120, 121, -1, 123, -1, -1, -1, 127, 128, -1, + 130, -1, 132, 133, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 144, -1, -1, -1, 148, -1, + -1, -1, 152, 153, 120, 121, 156, 123, -1, -1, + -1, 127, 128, -1, 130, -1, 132, 133, -1, -1, + -1, -1, 172, -1, -1, -1, -1, -1, 144, -1, + -1, -1, 148, -1, -1, -1, 152, 153, -1, -1, + 156, -1, -1, -1, -1, 53, 54, 55, 56, 57, + 58, -1, -1, -1, 62, -1, 172, 65, 66, 67, + 68, 69, 70, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 84, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 85, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, -1, -1, 119, 120, -1, 122, - -1, -1, -1, 126, 127, -1, 129, -1, 131, 132, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 143, -1, -1, -1, 147, -1, -1, -1, 151, 152, - -1, 154, -1, -1, -1, -1, -1, 53, 54, 55, - 56, 57, 58, -1, -1, -1, 62, 170, 64, 65, - 66, 67, 68, 69, 70, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 85, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, -1, 119, 120, -1, 122, -1, -1, -1, - 126, 127, -1, 129, -1, 131, 132, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 143, -1, -1, - -1, 147, -1, -1, -1, 151, 152, -1, 154, -1, + -1, -1, 120, 121, -1, 123, -1, -1, -1, 127, + 128, -1, 130, -1, 132, 133, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 144, -1, -1, -1, + 148, -1, -1, -1, 152, 153, -1, -1, 156, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 170 + -1, -1, -1, -1, 172 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -1869,75 +1827,75 @@ static const yytype_uint16 yystos[] = 0, 1, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 22, 23, 24, 25, 26, 29, 30, 32, 33, 34, 35, 36, 37, 38, - 40, 53, 54, 55, 56, 57, 65, 82, 83, 85, - 86, 87, 88, 90, 91, 92, 93, 94, 95, 96, - 97, 118, 123, 124, 125, 130, 134, 135, 136, 137, - 138, 141, 142, 144, 145, 146, 148, 149, 153, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 171, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 197, 198, 199, 200, 201, 202, - 205, 206, 207, 208, 209, 210, 211, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 237, 238, 239, 240, 241, 242, 246, 247, 260, 261, - 262, 263, 265, 266, 272, 273, 277, 279, 280, 281, - 283, 285, 286, 287, 288, 290, 291, 292, 293, 294, - 296, 297, 299, 300, 301, 302, 303, 304, 305, 307, - 311, 312, 313, 80, 128, 264, 19, 68, 70, 306, - 81, 85, 98, 99, 172, 243, 244, 53, 54, 55, - 56, 57, 58, 62, 64, 65, 66, 67, 68, 69, - 70, 85, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 119, 120, - 122, 126, 127, 129, 131, 132, 143, 147, 151, 152, - 154, 170, 227, 317, 318, 19, 21, 64, 192, 29, - 318, 318, 29, 44, 45, 64, 85, 117, 267, 268, - 269, 267, 267, 267, 267, 267, 84, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 113, 248, 56, - 186, 58, 56, 57, 174, 85, 85, 119, 120, 278, - 126, 127, 129, 284, 126, 133, 282, 131, 133, 275, - 117, 152, 275, 275, 85, 128, 289, 133, 139, 140, - 276, 85, 143, 117, 121, 274, 117, 295, 147, 275, - 117, 298, 150, 151, 152, 27, 72, 27, 213, 213, - 227, 71, 27, 27, 12, 6, 117, 85, 117, 120, - 170, 50, 0, 185, 50, 171, 5, 172, 188, 193, - 195, 196, 226, 237, 238, 239, 240, 241, 313, 172, - 194, 188, 237, 238, 239, 240, 241, 85, 227, 187, - 246, 175, 204, 230, 231, 232, 188, 233, 234, 315, - 316, 318, 69, 271, 316, 233, 316, 204, 230, 52, - 20, 181, 66, 67, 230, 174, 85, 85, 85, 172, - 173, 175, 177, 64, 318, 27, 31, 318, 175, 175, - 175, 175, 39, 268, 264, 85, 174, 174, 174, 174, - 85, 101, 102, 103, 104, 106, 107, 108, 109, 113, - 256, 174, 174, 174, 174, 111, 112, 174, 41, 42, - 43, 85, 249, 171, 59, 61, 308, 309, 310, 85, - 85, 117, 117, 117, 275, 117, 128, 275, 117, 275, - 85, 128, 133, 85, 132, 275, 85, 275, 85, 85, - 276, 117, 173, 275, 117, 85, 154, 85, 133, 212, - 212, 318, 85, 85, 85, 85, 117, 117, 117, 117, - 50, 85, 85, 173, 176, 188, 230, 27, 203, 231, - 139, 314, 71, 177, 318, 27, 314, 27, 213, 85, - 100, 117, 245, 174, 174, 174, 85, 98, 99, 243, - 49, 85, 100, 117, 172, 228, 229, 318, 117, 46, - 47, 48, 270, 85, 85, 117, 174, 85, 89, 259, - 259, 259, 259, 174, 177, 174, 174, 174, 174, 174, - 174, 174, 174, 174, 255, 259, 259, 257, 259, 257, - 174, 174, 259, 85, 85, 60, 62, 173, 274, 275, - 275, 117, 275, 275, 85, 275, 122, 173, 117, 72, - 174, 85, 27, 27, 174, 172, 176, 176, 233, 85, - 175, 318, 318, 233, 175, 235, 233, 212, 245, 245, - 245, 174, 85, 85, 85, 172, 173, 176, 177, 176, - 176, 85, 85, 176, 176, 258, 259, 255, 255, 255, - 255, 258, 85, 259, 259, 259, 259, 259, 259, 257, - 257, 259, 41, 173, 255, 255, 255, 255, 178, 178, - 255, 63, 310, 275, 117, 117, 173, 154, 85, 85, - 85, 85, 117, 85, 85, 71, 318, 85, 236, 234, - 245, 174, 174, 85, 229, 318, 176, 176, 255, 41, - 41, 41, 41, 174, 256, 41, 41, 41, 41, 101, - 113, 114, 116, 250, 251, 68, 252, 41, 85, 174, - 176, 318, 173, 176, 245, 245, 41, 258, 175, 175, - 175, 175, 179, 173, 175, 179, 85, 85, 259, 259, - 115, 176, 85, 253, 254, 41, 250, 257, 41, 176, - 176, 174, 174, 176, 173, 176, 180, 259, 259, 253, - 257, 176, 176 + 40, 53, 54, 55, 56, 57, 65, 81, 82, 84, + 85, 86, 87, 89, 90, 91, 92, 93, 94, 95, + 96, 119, 124, 125, 126, 131, 135, 136, 137, 138, + 139, 142, 143, 145, 146, 147, 149, 150, 154, 155, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 173, 174, 175, 176, 177, + 178, 179, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 205, 206, 207, 208, 209, 210, 213, 214, 215, + 216, 217, 218, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 245, 246, 247, + 248, 249, 250, 254, 255, 268, 269, 270, 271, 273, + 274, 280, 281, 282, 286, 288, 289, 290, 292, 294, + 295, 296, 297, 299, 300, 301, 302, 303, 305, 306, + 308, 309, 310, 311, 312, 313, 314, 316, 320, 321, + 322, 80, 129, 272, 19, 68, 70, 315, 84, 97, + 98, 180, 251, 252, 53, 54, 55, 56, 57, 58, + 62, 65, 66, 67, 68, 69, 70, 84, 120, 121, + 123, 127, 128, 130, 132, 133, 144, 148, 152, 153, + 156, 172, 235, 326, 327, 19, 21, 64, 200, 29, + 327, 327, 29, 44, 45, 64, 84, 118, 275, 276, + 277, 275, 275, 275, 275, 275, 83, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 113, 256, + 56, 194, 58, 56, 57, 182, 84, 84, 120, 121, + 287, 127, 128, 130, 293, 127, 134, 291, 132, 134, + 284, 118, 153, 284, 284, 84, 129, 298, 134, 140, + 141, 285, 84, 144, 118, 122, 283, 118, 304, 148, + 284, 118, 307, 151, 152, 153, 27, 72, 27, 27, + 220, 220, 235, 71, 27, 27, 12, 6, 118, 84, + 118, 121, 172, 50, 0, 193, 50, 179, 5, 180, + 196, 201, 203, 204, 234, 245, 246, 247, 248, 249, + 322, 180, 202, 196, 245, 246, 247, 248, 249, 84, + 327, 195, 254, 183, 212, 238, 239, 240, 196, 241, + 242, 324, 325, 327, 69, 279, 325, 241, 325, 212, + 238, 52, 20, 189, 66, 67, 182, 84, 84, 84, + 180, 181, 183, 185, 64, 327, 27, 31, 327, 183, + 183, 183, 183, 39, 276, 272, 84, 182, 182, 182, + 182, 84, 100, 101, 102, 103, 105, 106, 107, 108, + 109, 113, 264, 182, 182, 182, 182, 182, 111, 112, + 182, 41, 42, 43, 84, 257, 179, 59, 61, 317, + 318, 319, 84, 84, 118, 118, 118, 284, 118, 129, + 284, 118, 284, 84, 129, 134, 84, 133, 284, 84, + 284, 84, 84, 285, 118, 181, 284, 118, 84, 156, + 84, 84, 134, 219, 219, 327, 84, 84, 84, 84, + 118, 118, 118, 118, 50, 84, 84, 181, 184, 196, + 238, 27, 211, 239, 140, 323, 71, 185, 327, 27, + 323, 27, 220, 84, 99, 118, 253, 182, 182, 182, + 84, 97, 98, 251, 49, 84, 99, 118, 180, 236, + 237, 327, 118, 46, 47, 48, 278, 84, 84, 118, + 182, 84, 88, 267, 267, 267, 267, 182, 185, 182, + 182, 182, 182, 182, 182, 182, 182, 182, 182, 263, + 267, 267, 265, 267, 265, 267, 182, 182, 267, 84, + 84, 60, 62, 181, 283, 284, 284, 118, 284, 284, + 84, 284, 123, 181, 118, 72, 182, 84, 27, 27, + 182, 180, 184, 184, 241, 84, 183, 327, 327, 241, + 183, 243, 241, 219, 253, 253, 253, 182, 84, 84, + 84, 180, 181, 184, 185, 184, 184, 84, 84, 184, + 184, 266, 267, 263, 263, 263, 263, 266, 84, 267, + 267, 267, 267, 267, 267, 265, 265, 267, 267, 41, + 181, 263, 263, 263, 263, 263, 186, 186, 263, 63, + 319, 284, 118, 118, 181, 156, 84, 84, 84, 84, + 118, 84, 84, 71, 327, 84, 244, 242, 253, 182, + 182, 84, 237, 327, 184, 184, 263, 41, 41, 41, + 41, 182, 264, 41, 41, 41, 41, 41, 100, 113, + 114, 115, 117, 258, 259, 68, 260, 41, 84, 182, + 184, 327, 181, 184, 253, 253, 41, 266, 183, 183, + 183, 183, 183, 187, 181, 183, 187, 84, 84, 267, + 267, 116, 184, 184, 84, 261, 262, 41, 258, 265, + 41, 184, 184, 182, 182, 184, 181, 184, 188, 267, + 267, 261, 265, 184, 184 }; #define yyerrok (yyerrstatus = 0) @@ -2945,42 +2903,42 @@ YYLTYPE yylloc; case 37: - { result->cur_stmt_type_ = OBPROXY_T_OTHERS; ;} + {;} break; - case 47: + case 38: - { result->cur_stmt_type_ = OBPROXY_T_CREATE; ;} + { result->cur_stmt_type_ = OBPROXY_T_OTHERS; ;} break; case 48: - { result->cur_stmt_type_ = OBPROXY_T_DROP; ;} + { result->cur_stmt_type_ = OBPROXY_T_CREATE; ;} break; case 49: - { result->cur_stmt_type_ = OBPROXY_T_ALTER; ;} + { result->cur_stmt_type_ = OBPROXY_T_DROP; ;} break; case 50: - { result->cur_stmt_type_ = OBPROXY_T_TRUNCATE; ;} + { result->cur_stmt_type_ = OBPROXY_T_ALTER; ;} break; case 51: - { result->cur_stmt_type_ = OBPROXY_T_RENAME; ;} + { result->cur_stmt_type_ = OBPROXY_T_TRUNCATE; ;} break; - case 53: + case 52: - { result->sub_stmt_type_ = OBPROXY_T_SUB_CREATE_TABLE; ;} + { result->cur_stmt_type_ = OBPROXY_T_RENAME; ;} break; case 54: - { result->sub_stmt_type_ = OBPROXY_T_SUB_CREATE_INDEX; ;} + { result->sub_stmt_type_ = OBPROXY_T_SUB_CREATE_TABLE; ;} break; case 55: @@ -2990,7 +2948,7 @@ YYLTYPE yylloc; case 56: - {;} + { result->sub_stmt_type_ = OBPROXY_T_SUB_CREATE_INDEX; ;} break; case 57: @@ -3030,6 +2988,11 @@ YYLTYPE yylloc; case 64: + {;} + break; + + case 65: + { ObProxyTextPsParseNode *node = NULL; malloc_parse_node(node); @@ -3038,7 +3001,7 @@ YYLTYPE yylloc; ;} break; - case 65: + case 66: { ObProxyTextPsParseNode *node = NULL; @@ -3048,7 +3011,7 @@ YYLTYPE yylloc; ;} break; - case 66: + case 67: { ObProxyTextPsParseNode *node = NULL; @@ -3058,7 +3021,7 @@ YYLTYPE yylloc; ;} break; - case 69: + case 70: { result->text_ps_inner_stmt_type_ = OBPROXY_T_TEXT_PS_PREPARE; @@ -3066,7 +3029,7 @@ YYLTYPE yylloc; ;} break; - case 70: + case 71: { result->cur_stmt_type_ = OBPROXY_T_TEXT_PS_EXECUTE; @@ -3074,7 +3037,7 @@ YYLTYPE yylloc; ;} break; - case 71: + case 72: { result->cur_stmt_type_ = OBPROXY_T_TEXT_PS_EXECUTE; @@ -3082,19 +3045,19 @@ YYLTYPE yylloc; ;} break; - case 72: + case 73: { ;} break; - case 73: + case 74: { ;} break; - case 74: + case 75: { result->cur_stmt_type_ = OBPROXY_T_TEXT_PS_DROP; @@ -3102,7 +3065,7 @@ YYLTYPE yylloc; ;} break; - case 75: + case 76: { result->cur_stmt_type_ = OBPROXY_T_TEXT_PS_DROP; @@ -3110,74 +3073,74 @@ YYLTYPE yylloc; ;} break; - case 76: + case 77: { result->cur_stmt_type_ = OBPROXY_T_GRANT; ;} break; - case 77: + case 78: { result->cur_stmt_type_ = OBPROXY_T_REVOKE; ;} break; - case 78: + case 79: { result->cur_stmt_type_ = OBPROXY_T_ANALYZE; ;} break; - case 79: + case 80: { result->cur_stmt_type_ = OBPROXY_T_PURGE; ;} break; - case 80: + case 81: { result->cur_stmt_type_ = OBPROXY_T_FLASHBACK; ;} break; - case 81: + case 82: { result->cur_stmt_type_ = OBPROXY_T_COMMENT; ;} break; - case 82: + case 83: { result->cur_stmt_type_ = OBPROXY_T_AUDIT; ;} break; - case 83: + case 84: { result->cur_stmt_type_ = OBPROXY_T_NOAUDIT; ;} break; - case 86: + case 87: {;} break; - case 87: + case 88: {;} break; - case 88: + case 89: {;} break; - case 93: + case 94: { result->cur_stmt_type_ = OBPROXY_T_SELECT_TX_RO; ;} break; - case 97: + case 98: { result->col_name_ = (yyvsp[(3) - (3)].str); ;} break; - case 98: + case 99: - { result->cur_stmt_type_ = OBPROXY_T_SET_AC_0; ;} + {;} break; case 100: @@ -3217,17 +3180,17 @@ YYLTYPE yylloc; case 107: - {;} + { result->sub_stmt_type_ = OBPROXY_T_SUB_SELECT_DATABASE; ;} break; case 108: - { result->sub_stmt_type_ = OBPROXY_T_SUB_SELECT_DATABASE; ;} + { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_DATABASES; ;} break; case 109: - { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_DATABASES; ;} + {;} break; case 110: @@ -3247,23 +3210,19 @@ YYLTYPE yylloc; case 113: - {;} - break; - - case 114: - { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_CREATE_TABLE; ;} break; - case 115: + case 114: { + result->table_info_.table_name_ = (yyvsp[(2) - (2)].str); result->cur_stmt_type_ = OBPROXY_T_DESC; result->sub_stmt_type_ = OBPROXY_T_SUB_DESC_TABLE; ;} break; - case 116: + case 115: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_COLUMNS; @@ -3271,7 +3230,7 @@ YYLTYPE yylloc; ;} break; - case 117: + case 116: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_COLUMNS; @@ -3280,7 +3239,7 @@ YYLTYPE yylloc; ;} break; - case 118: + case 117: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_INDEX; @@ -3288,7 +3247,7 @@ YYLTYPE yylloc; ;} break; - case 119: + case 118: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_INDEX; @@ -3297,98 +3256,106 @@ YYLTYPE yylloc; ;} break; - case 120: + case 119: {;} break; - case 121: + case 120: { result->table_info_.table_name_ = (yyvsp[(2) - (2)].str); ;} break; - case 122: + case 121: {;} break; - case 123: + case 122: { result->table_info_.database_name_ = (yyvsp[(2) - (2)].str); ;} break; - case 124: + case 123: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TABLES; ;} break; - case 125: + case 124: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_FULL_TABLES; ;} break; - case 126: + case 125: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TABLE_STATUS; ;} break; - case 127: + case 126: { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_DB_VERSION; ;} break; - case 128: + case 127: - { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; ;} + { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; ;} break; - case 129: + case 128: { SET_ICMD_ONE_STRING((yyvsp[(3) - (3)].str)); - result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; + result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; ;} break; - case 130: + case 129: { SET_ICMD_SECOND_STRING((yyvsp[(5) - (5)].str)); - result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; + result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; ;} break; - case 131: + case 130: { SET_ICMD_ONE_STRING((yyvsp[(3) - (7)].str)); SET_ICMD_SECOND_STRING((yyvsp[(7) - (7)].str)); - result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; + result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_ELASTIC_ID; ;} break; + case 131: + + { result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; ;} + break; + case 132: - { result->cur_stmt_type_ = OBPROXY_T_SELECT_ROUTE_ADDR; ;} + { + result->table_info_.table_name_ = (yyvsp[(3) - (3)].str); + result->sub_stmt_type_ = OBPROXY_T_SUB_SHOW_TOPOLOGY; + ;} break; case 133: - { - result->cur_stmt_type_ = OBPROXY_T_SET_ROUTE_ADDR; - result->cmd_info_.integer_[0] = (yyvsp[(3) - (3)].num); - ;} + { result->cur_stmt_type_ = OBPROXY_T_SELECT_ROUTE_ADDR; ;} break; case 134: - {;} + { + result->cur_stmt_type_ = OBPROXY_T_SET_ROUTE_ADDR; + result->cmd_info_.integer_[0] = (yyvsp[(3) - (3)].num); + ;} break; case 135: @@ -3416,14 +3383,19 @@ YYLTYPE yylloc; {;} break; - case 141: + case 140: + + {;} + break; + + case 142: { result->table_info_.table_name_ = (yyvsp[(1) - (1)].str); ;} break; - case 142: + case 143: { result->table_info_.package_name_ = (yyvsp[(1) - (3)].str); @@ -3431,7 +3403,7 @@ YYLTYPE yylloc; ;} break; - case 143: + case 144: { result->table_info_.database_name_ = (yyvsp[(1) - (5)].str); @@ -3440,14 +3412,14 @@ YYLTYPE yylloc; ;} break; - case 144: + case 145: { result->call_parse_info_.node_count_ = 0; ;} break; - case 145: + case 146: { result->call_parse_info_.node_count_ = 0; @@ -3455,14 +3427,14 @@ YYLTYPE yylloc; ;} break; - case 146: + case 147: { add_call_node(result->call_parse_info_, (yyvsp[(3) - (3)].node)); ;} break; - case 147: + case 148: { malloc_call_node((yyval.node), CALL_TOKEN_STR_VAL); @@ -3470,7 +3442,7 @@ YYLTYPE yylloc; ;} break; - case 148: + case 149: { malloc_call_node((yyval.node), CALL_TOKEN_INT_VAL); @@ -3478,7 +3450,7 @@ YYLTYPE yylloc; ;} break; - case 149: + case 150: { malloc_call_node((yyval.node), CALL_TOKEN_NUMBER_VAL); @@ -3486,7 +3458,7 @@ YYLTYPE yylloc; ;} break; - case 150: + case 151: { malloc_call_node((yyval.node), CALL_TOKEN_USER_VAR); @@ -3494,7 +3466,7 @@ YYLTYPE yylloc; ;} break; - case 151: + case 152: { malloc_call_node((yyval.node), CALL_TOKEN_SYS_VAR); @@ -3502,7 +3474,7 @@ YYLTYPE yylloc; ;} break; - case 152: + case 153: { result->placeholder_list_idx_++; @@ -3511,7 +3483,7 @@ YYLTYPE yylloc; ;} break; - case 166: + case 167: { handle_stmt_end(result); @@ -3519,7 +3491,7 @@ YYLTYPE yylloc; ;} break; - case 171: + case 172: { handle_stmt_end(result); @@ -3527,56 +3499,56 @@ YYLTYPE yylloc; ;} break; - case 175: + case 176: { add_set_var_node(result->set_parse_info_, (yyvsp[(4) - (4)].var_node), (yyvsp[(2) - (4)].str), SET_VAR_USER); ;} break; - case 176: + case 177: { add_set_var_node(result->set_parse_info_, (yyvsp[(6) - (6)].var_node), (yyvsp[(4) - (6)].str), SET_VAR_SYS); ;} break; - case 177: + case 178: { add_set_var_node(result->set_parse_info_, (yyvsp[(4) - (4)].var_node), (yyvsp[(2) - (4)].str), SET_VAR_SYS); ;} break; - case 178: + case 179: { add_set_var_node(result->set_parse_info_, (yyvsp[(5) - (5)].var_node), (yyvsp[(3) - (5)].str), SET_VAR_SYS); ;} break; - case 179: + case 180: { add_set_var_node(result->set_parse_info_, (yyvsp[(6) - (6)].var_node), (yyvsp[(4) - (6)].str), SET_VAR_SYS); ;} break; - case 180: + case 181: { add_set_var_node(result->set_parse_info_, (yyvsp[(4) - (4)].var_node), (yyvsp[(2) - (4)].str), SET_VAR_SYS); ;} break; - case 181: + case 182: { add_set_var_node(result->set_parse_info_, (yyvsp[(3) - (3)].var_node), (yyvsp[(1) - (3)].str), SET_VAR_SYS); ;} break; - case 182: + case 183: { malloc_set_var_node((yyval.var_node), SET_VALUE_TYPE_STR); @@ -3584,7 +3556,7 @@ YYLTYPE yylloc; ;} break; - case 183: + case 184: { malloc_set_var_node((yyval.var_node), SET_VALUE_TYPE_INT); @@ -3592,7 +3564,7 @@ YYLTYPE yylloc; ;} break; - case 184: + case 185: { malloc_set_var_node((yyval.var_node), SET_VALUE_TYPE_NUMBER); @@ -3600,42 +3572,42 @@ YYLTYPE yylloc; ;} break; - case 187: + case 188: {;} break; - case 188: + case 189: {;} break; - case 189: + case 190: { result->dbmesh_route_info_.tb_idx_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 190: + case 191: { result->dbmesh_route_info_.table_name_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 191: + case 192: { result->dbmesh_route_info_.group_idx_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 192: + case 193: { result->dbmesh_route_info_.es_idx_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 193: + case 194: { result->dbmesh_route_info_.testload_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 194: + case 195: { malloc_shard_column_node((yyval.shard_node), (yyvsp[(2) - (7)].str), (yyvsp[(3) - (7)].str), DBMESH_TOKEN_STR_VAL); @@ -3644,52 +3616,57 @@ YYLTYPE yylloc; ;} break; - case 195: + case 196: { result->trace_id_ = (yyvsp[(4) - (6)].str); ;} break; - case 196: + case 197: { result->rpc_id_ = (yyvsp[(4) - (6)].str); ;} break; - case 197: + case 198: { result->dbmesh_route_info_.tnt_id_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 198: + case 199: { result->dbmesh_route_info_.disaster_status_str_ = (yyvsp[(4) - (6)].str); ;} break; - case 199: + case 200: {;} break; - case 200: + case 201: {;} break; - case 201: + case 202: - {;} + { result->target_db_server_ = (yyvsp[(4) - (6)].str); ;} break; case 203: + {;} + break; + + case 205: + { result->has_simple_route_info_ = true; result->simple_route_info_.table_name_ = (yyvsp[(2) - (2)].str); ;} break; - case 204: + case 206: { result->simple_route_info_.part_key_ = (yyvsp[(2) - (2)].str); ;} break; - case 208: + case 210: { result->dbp_route_info_.has_group_info_ = true; @@ -3697,7 +3674,7 @@ YYLTYPE yylloc; ;} break; - case 209: + case 211: { result->dbp_route_info_.has_group_info_ = true; @@ -3705,37 +3682,42 @@ YYLTYPE yylloc; ;} break; - case 210: + case 212: { result->dbp_route_info_.scan_all_ = true; ;} break; - case 211: + case 213: { result->dbp_route_info_.scan_all_ = true; ;} break; - case 212: + case 214: + + { result->dbp_route_info_.sticky_session_ = true; ;} + break; + + case 215: {result->dbp_route_info_.has_shard_key_ = true;;} break; - case 213: + case 216: { result->trace_id_ = (yyvsp[(3) - (4)].str); ;} break; - case 214: + case 217: { result->trace_id_ = (yyvsp[(3) - (6)].str); result->rpc_id_ = (yyvsp[(5) - (6)].str); ;} break; - case 215: + case 218: {;} break; - case 217: + case 220: { if (result->dbp_route_info_.shard_key_count_ < OBPROXY_MAX_DBP_SHARD_KEY_NUM) { @@ -3746,52 +3728,57 @@ YYLTYPE yylloc; ;} break; - case 220: + case 223: { result->dbmesh_route_info_.group_idx_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 221: + case 224: { result->dbmesh_route_info_.tb_idx_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 222: + case 225: { result->dbmesh_route_info_.table_name_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 223: + case 226: { result->dbmesh_route_info_.es_idx_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 224: + case 227: { result->dbmesh_route_info_.testload_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 225: + case 228: { result->trace_id_ = (yyvsp[(3) - (3)].str); ;} break; - case 226: + case 229: { result->rpc_id_ = (yyvsp[(3) - (3)].str); ;} break; - case 227: + case 230: { result->dbmesh_route_info_.tnt_id_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 228: + case 231: { result->dbmesh_route_info_.disaster_status_str_ = (yyvsp[(3) - (3)].str); ;} break; - case 229: + case 232: + + { result->target_db_server_ = (yyvsp[(3) - (3)].str); ;} + break; + + case 233: { malloc_shard_column_node((yyval.shard_node), (yyvsp[(1) - (5)].str), (yyvsp[(3) - (5)].str), DBMESH_TOKEN_STR_VAL); @@ -3800,32 +3787,32 @@ YYLTYPE yylloc; ;} break; - case 230: + case 234: {;} break; - case 231: + case 235: { (yyval.str).str_ = NULL; (yyval.str).str_len_ = 0; ;} break; - case 233: + case 237: { (yyval.str).str_ = NULL; (yyval.str).str_len_ = 0; ;} break; - case 255: + case 259: { result->query_timeout_ = (yyvsp[(3) - (4)].num); ;} break; - case 256: + case 260: {;} break; - case 258: + case 262: { add_hint_index(result->dbmesh_route_info_, (yyvsp[(3) - (5)].str)); @@ -3833,75 +3820,105 @@ YYLTYPE yylloc; ;} break; - case 259: + case 263: {;} break; - case 260: + case 264: {;} break; - case 261: + case 265: {;} break; - case 262: + case 266: {;} break; - case 263: + case 267: {;} break; - case 264: + case 268: { SET_READ_CONSISTENCY(OBPROXY_READ_CONSISTENCY_WEAK); ;} break; - case 265: + case 269: { SET_READ_CONSISTENCY(OBPROXY_READ_CONSISTENCY_STRONG); ;} break; - case 266: + case 270: { SET_READ_CONSISTENCY(OBPROXY_READ_CONSISTENCY_FROZEN); ;} break; - case 269: + case 273: { result->cur_stmt_type_ = OBPROXY_T_SHOW_WARNINGS; ;} break; - case 270: + case 274: { result->cur_stmt_type_ = OBPROXY_T_SHOW_ERRORS; ;} break; - case 271: + case 275: { result->cur_stmt_type_ = OBPROXY_T_SHOW_TRACE; ;} break; - case 295: + case 299: + + {;} + break; + + case 300: + + {;} + break; + + case 301: + + {;} + break; + + case 302: + + {;} + break; + + case 303: + + {;} + break; + + case 304: + + {;} + break; + + case 305: { ;} break; - case 296: + case 306: { result->cmd_info_.integer_[2] = (yyvsp[(2) - (2)].num);/*row*/ ;} break; - case 297: + case 307: { result->cmd_info_.integer_[1] = (yyvsp[(2) - (4)].num);/*offset*/ @@ -3909,7 +3926,7 @@ YYLTYPE yylloc; ;} break; - case 298: + case 308: { result->cmd_info_.integer_[1] = (yyvsp[(4) - (4)].num);/*offset*/ @@ -3917,342 +3934,342 @@ YYLTYPE yylloc; ;} break; - case 299: + case 309: {;} break; - case 300: + case 310: { result->cmd_info_.string_[0] = (yyvsp[(2) - (2)].str);;} break; - case 301: + case 311: {;} break; - case 302: + case 312: { result->cmd_info_.string_[1] = (yyvsp[(2) - (2)].str);;} break; - case 304: + case 314: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_NET_THREAD); ;} break; - case 305: + case 315: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_NET_CONNECTION); ;} break; - case 306: + case 316: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_NET_CONNECTION, (yyvsp[(2) - (3)].num)); ;} break; - case 307: + case 317: {;} break; - case 308: + case 318: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_CONFIG_DIFF); ;} break; - case 309: + case 319: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_CONFIG_DIFF_USER); ;} break; - case 310: + case 320: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_LIST); ;} break; - case 312: + case 322: {SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_GLOBAL_SESSION_LIST);;} break; - case 313: + case 323: {SET_ICMD_SUB_AND_ONE_STRING(OBPROXY_T_SUB_GLOBAL_SESSION_LIST_INFO, (yyvsp[(2) - (2)].str));;} break; - case 314: + case 324: {SET_ICMD_SUB_AND_ONE_STRING(OBPROXY_T_SUB_GLOBAL_SESSION_LIST_LIKE, (yyvsp[(3) - (3)].str));;} break; - case 315: + case 325: {SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_GLOBAL_SESSION_LIST_INFO_ALL);;} break; - case 316: + case 326: {result->cmd_info_.string_[0] = (yyvsp[(2) - (2)].str);;} break; - case 318: + case 328: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_LIST_INTERNAL); ;} break; - case 319: + case 329: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_ATTRIBUTE); ;} break; - case 320: + case 330: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_SESSION_ATTRIBUTE, (yyvsp[(2) - (3)].num)); ;} break; - case 321: + case 331: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_STAT); ;} break; - case 322: + case 332: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_SESSION_STAT, (yyvsp[(2) - (3)].num)); ;} break; - case 323: + case 333: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_VARIABLES_LOCAL); ;} break; - case 324: + case 334: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_SESSION_VARIABLES_LOCAL, (yyvsp[(2) - (3)].num)); ;} break; - case 325: + case 335: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SESSION_VARIABLES_ALL); ;} break; - case 326: + case 336: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_SESSION_VARIABLES_ALL, (yyvsp[(3) - (4)].num)); ;} break; - case 327: + case 337: {;} break; - case 328: + case 338: { SET_ICMD_ONE_ID((yyvsp[(2) - (2)].num)); ;} break; - case 329: + case 339: {;} break; - case 330: + case 340: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_INFO_IDC); ;} break; - case 331: + case 341: {;} break; - case 333: + case 343: {;} break; - case 334: + case 344: { SET_ICMD_ONE_STRING((yyvsp[(1) - (1)].str)); ;} break; - case 335: + case 345: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_CONGEST_ALL);;} break; - case 336: + case 346: { SET_ICMD_SUB_AND_ONE_STRING(OBPROXY_T_SUB_CONGEST_ALL, (yyvsp[(2) - (2)].str));;} break; - case 337: + case 347: {;} break; - case 338: + case 348: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_ROUTE_ROUTINE); ;} break; - case 339: + case 349: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_ROUTE_PARTITION); ;} break; - case 340: + case 350: {;} break; - case 341: + case 351: { SET_ICMD_ONE_STRING((yyvsp[(2) - (2)].str)); ;} break; - case 342: + case 352: {;} break; - case 343: + case 353: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_MEMORY_OBJPOOL); ;} break; - case 344: + case 354: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_SQLAUDIT_AUDIT_ID); ;} break; - case 345: + case 355: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_SQLAUDIT_SM_ID, (yyvsp[(2) - (2)].num)); ;} break; - case 347: + case 357: {;} break; - case 348: + case 358: { SET_ICMD_SECOND_ID((yyvsp[(1) - (1)].num)); ;} break; - case 349: + case 359: { SET_ICMD_TWO_ID((yyvsp[(3) - (3)].num), (yyvsp[(1) - (3)].num)); ;} break; - case 350: + case 360: { SET_ICMD_TWO_ID((yyvsp[(3) - (5)].num), (yyvsp[(1) - (5)].num)); SET_ICMD_ONE_STRING((yyvsp[(5) - (5)].str)); ;} break; - case 351: + case 361: {;} break; - case 352: + case 362: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_STAT_REFRESH); ;} break; - case 354: + case 364: {;} break; - case 355: + case 365: { SET_ICMD_ONE_ID((yyvsp[(1) - (1)].num)); ;} break; - case 356: + case 366: { SET_ICMD_SUB_AND_TWO_ID(OBPROXY_T_SUB_TRACE_LIMIT, (yyvsp[(1) - (2)].num),(yyvsp[(2) - (2)].num)); ;} break; - case 357: + case 367: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_INFO_BINARY); ;} break; - case 358: + case 368: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_INFO_UPGRADE); ;} break; - case 359: + case 369: { SET_ICMD_SUB_TYPE(OBPROXY_T_SUB_INFO_IDC); ;} break; - case 360: + case 370: { SET_ICMD_ONE_STRING((yyvsp[(3) - (4)].str)); ;} break; - case 361: + case 371: { SET_ICMD_TWO_STRING((yyvsp[(3) - (5)].str), (yyvsp[(5) - (5)].str)); ;} break; - case 362: + case 372: { SET_ICMD_CONFIG_INT_VALUE((yyvsp[(3) - (5)].str), (yyvsp[(5) - (5)].num)); ;} break; - case 363: + case 373: { SET_ICMD_ONE_STRING((yyvsp[(3) - (3)].str)); ;} break; - case 364: + case 374: {;} break; - case 365: + case 375: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_KILL_CS, (yyvsp[(2) - (2)].num)); ;} break; - case 366: + case 376: { SET_ICMD_SUB_AND_TWO_ID(OBPROXY_T_SUB_KILL_SS, (yyvsp[(2) - (3)].num), (yyvsp[(3) - (3)].num)); ;} break; - case 367: + case 377: {SET_ICMD_TYPE_STRING_INT_VALUE(OBPROXY_T_SUB_KILL_GLOBAL_SS_ID, (yyvsp[(2) - (3)].str),(yyvsp[(3) - (3)].num));;} break; - case 368: + case 378: {SET_ICMD_SUB_AND_ONE_STRING(OBPROXY_T_SUB_KILL_GLOBAL_SS_DBKEY, (yyvsp[(2) - (2)].str));;} break; - case 369: + case 379: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_KILL_CONNECTION, (yyvsp[(2) - (2)].num)); ;} break; - case 370: + case 380: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_KILL_CONNECTION, (yyvsp[(3) - (3)].num)); ;} break; - case 371: + case 381: { SET_ICMD_SUB_AND_ONE_ID(OBPROXY_T_SUB_KILL_QUERY, (yyvsp[(3) - (3)].num)); ;} break; - case 374: + case 384: { result->has_anonymous_block_ = false ; @@ -4260,22 +4277,22 @@ YYLTYPE yylloc; ;} break; - case 375: + case 385: { result->cur_stmt_type_ = OBPROXY_T_BEGIN; ;} break; - case 376: + case 386: { result->cur_stmt_type_ = OBPROXY_T_BEGIN; ;} break; - case 377: + case 387: { result->cur_stmt_type_ = OBPROXY_T_BEGIN; ;} break; - case 384: + case 394: { result->cur_stmt_type_ = OBPROXY_T_USE_DB; @@ -4283,27 +4300,27 @@ YYLTYPE yylloc; ;} break; - case 385: + case 395: { result->cur_stmt_type_ = OBPROXY_T_HELP; ;} break; - case 387: + case 397: {;} break; - case 388: + case 398: { result->part_name_ = (yyvsp[(2) - (2)].str); ;} break; - case 389: + case 399: { result->part_name_ = (yyvsp[(3) - (4)].str); ;} break; - case 390: + case 400: { handle_stmt_end(result); @@ -4311,14 +4328,14 @@ YYLTYPE yylloc; ;} break; - case 391: + case 401: { result->table_info_.table_name_ = (yyvsp[(1) - (1)].str); ;} break; - case 392: + case 402: { result->table_info_.database_name_ = (yyvsp[(1) - (3)].str); @@ -4326,7 +4343,7 @@ YYLTYPE yylloc; ;} break; - case 393: + case 403: { UPDATE_ALIAS_NAME((yyvsp[(2) - (2)].str)); @@ -4334,7 +4351,7 @@ YYLTYPE yylloc; ;} break; - case 394: + case 404: { UPDATE_ALIAS_NAME((yyvsp[(4) - (4)].str)); @@ -4343,7 +4360,7 @@ YYLTYPE yylloc; ;} break; - case 395: + case 405: { UPDATE_ALIAS_NAME((yyvsp[(3) - (3)].str)); @@ -4351,7 +4368,7 @@ YYLTYPE yylloc; ;} break; - case 396: + case 406: { UPDATE_ALIAS_NAME((yyvsp[(5) - (5)].str)); diff --git a/src/obproxy/opsql/parser/ob_proxy_parser_utf8_tab.h b/src/obproxy/opsql/parser/ob_proxy_parser_utf8_tab.h index 7ce9c0f28..16705243e 100644 --- a/src/obproxy/opsql/parser/ob_proxy_parser_utf8_tab.h +++ b/src/obproxy/opsql/parser/ob_proxy_parser_utf8_tab.h @@ -134,96 +134,104 @@ extern int ob_proxy_parser_utf8_yydebug; UNION = 333, FOR = 334, TX_READ_ONLY = 335, - AUTOCOMMIT_0 = 336, - SELECT_OBPROXY_ROUTE_ADDR = 337, - SET_OBPROXY_ROUTE_ADDR = 338, - NAME_OB_DOT = 339, - NAME_OB = 340, - EXPLAIN = 341, - DESC = 342, - DESCRIBE = 343, - NAME_STR = 344, - USE = 345, - HELP = 346, - SET_NAMES = 347, - SET_CHARSET = 348, - SET_PASSWORD = 349, - SET_DEFAULT = 350, - SET_OB_READ_CONSISTENCY = 351, - SET_TX_READ_ONLY = 352, - GLOBAL = 353, - SESSION = 354, - NUMBER_VAL = 355, - GROUP_ID = 356, - TABLE_ID = 357, - ELASTIC_ID = 358, - TESTLOAD = 359, - ODP_COMMENT = 360, - TNT_ID = 361, - DISASTER_STATUS = 362, - TRACE_ID = 363, - RPC_ID = 364, + SELECT_OBPROXY_ROUTE_ADDR = 336, + SET_OBPROXY_ROUTE_ADDR = 337, + NAME_OB_DOT = 338, + NAME_OB = 339, + EXPLAIN = 340, + DESC = 341, + DESCRIBE = 342, + NAME_STR = 343, + USE = 344, + HELP = 345, + SET_NAMES = 346, + SET_CHARSET = 347, + SET_PASSWORD = 348, + SET_DEFAULT = 349, + SET_OB_READ_CONSISTENCY = 350, + SET_TX_READ_ONLY = 351, + GLOBAL = 352, + SESSION = 353, + NUMBER_VAL = 354, + GROUP_ID = 355, + TABLE_ID = 356, + ELASTIC_ID = 357, + TESTLOAD = 358, + ODP_COMMENT = 359, + TNT_ID = 360, + DISASTER_STATUS = 361, + TRACE_ID = 362, + RPC_ID = 363, + TARGET_DB_SERVER = 364, DBP_COMMENT = 365, ROUTE_TAG = 366, SYS_TAG = 367, TABLE_NAME = 368, SCAN_ALL = 369, - PARALL = 370, - SHARD_KEY = 371, - INT_NUM = 372, - SHOW_PROXYNET = 373, - THREAD = 374, - CONNECTION = 375, - LIMIT = 376, - OFFSET = 377, - SHOW_PROCESSLIST = 378, - SHOW_PROXYSESSION = 379, - SHOW_GLOBALSESSION = 380, - ATTRIBUTE = 381, - VARIABLES = 382, - ALL = 383, - STAT = 384, - SHOW_PROXYCONFIG = 385, - DIFF = 386, - USER = 387, - LIKE = 388, - SHOW_PROXYSM = 389, - SHOW_PROXYCLUSTER = 390, - SHOW_PROXYRESOURCE = 391, - SHOW_PROXYCONGESTION = 392, - SHOW_PROXYROUTE = 393, - PARTITION = 394, - ROUTINE = 395, - SHOW_PROXYVIP = 396, - SHOW_PROXYMEMORY = 397, - OBJPOOL = 398, - SHOW_SQLAUDIT = 399, - SHOW_WARNLOG = 400, - SHOW_PROXYSTAT = 401, - REFRESH = 402, - SHOW_PROXYTRACE = 403, - SHOW_PROXYINFO = 404, - BINARY = 405, - UPGRADE = 406, - IDC = 407, - SHOW_TOPOLOGY = 408, - GROUP_NAME = 409, - SHOW_DB_VERSION = 410, - SHOW_DATABASES = 411, - SHOW_TABLES = 412, - SHOW_FULL_TABLES = 413, - SELECT_DATABASE = 414, - SHOW_CREATE_TABLE = 415, - SELECT_PROXY_VERSION = 416, - SHOW_COLUMNS = 417, - SHOW_INDEX = 418, - ALTER_PROXYCONFIG = 419, - ALTER_PROXYRESOURCE = 420, - PING_PROXY = 421, - KILL_PROXYSESSION = 422, - KILL_GLOBALSESSION = 423, - KILL = 424, - QUERY = 425 + STICKY_SESSION = 370, + PARALL = 371, + SHARD_KEY = 372, + INT_NUM = 373, + SHOW_PROXYNET = 374, + THREAD = 375, + CONNECTION = 376, + LIMIT = 377, + OFFSET = 378, + SHOW_PROCESSLIST = 379, + SHOW_PROXYSESSION = 380, + SHOW_GLOBALSESSION = 381, + ATTRIBUTE = 382, + VARIABLES = 383, + ALL = 384, + STAT = 385, + SHOW_PROXYCONFIG = 386, + DIFF = 387, + USER = 388, + LIKE = 389, + SHOW_PROXYSM = 390, + SHOW_PROXYCLUSTER = 391, + SHOW_PROXYRESOURCE = 392, + SHOW_PROXYCONGESTION = 393, + SHOW_PROXYROUTE = 394, + PARTITION = 395, + ROUTINE = 396, + SHOW_PROXYVIP = 397, + SHOW_PROXYMEMORY = 398, + OBJPOOL = 399, + SHOW_SQLAUDIT = 400, + SHOW_WARNLOG = 401, + SHOW_PROXYSTAT = 402, + REFRESH = 403, + SHOW_PROXYTRACE = 404, + SHOW_PROXYINFO = 405, + BINARY = 406, + UPGRADE = 407, + IDC = 408, + SHOW_ELASTIC_ID = 409, + SHOW_TOPOLOGY = 410, + GROUP_NAME = 411, + SHOW_DB_VERSION = 412, + SHOW_DATABASES = 413, + SHOW_TABLES = 414, + SHOW_FULL_TABLES = 415, + SELECT_DATABASE = 416, + SHOW_CREATE_TABLE = 417, + SELECT_PROXY_VERSION = 418, + SHOW_COLUMNS = 419, + SHOW_INDEX = 420, + ALTER_PROXYCONFIG = 421, + ALTER_PROXYRESOURCE = 422, + PING_PROXY = 423, + KILL_PROXYSESSION = 424, + KILL_GLOBALSESSION = 425, + KILL = 426, + QUERY = 427, + SHOW_MASTER_STATUS = 428, + SHOW_BINARY_LOGS = 429, + SHOW_BINLOG_EVENTS = 430, + PURGE_BINARY_LOGS = 431, + RESET_MASTER = 432, + SHOW_BINLOG_SERVER_FOR_TENANT = 433 }; #endif diff --git a/src/obproxy/optimizer/ob_sharding_select_log_plan.cpp b/src/obproxy/optimizer/ob_sharding_select_log_plan.cpp index b5c667c0b..3c3a654be 100644 --- a/src/obproxy/optimizer/ob_sharding_select_log_plan.cpp +++ b/src/obproxy/optimizer/ob_sharding_select_log_plan.cpp @@ -155,7 +155,7 @@ int ObShardingSelectLogPlan::do_handle_avg_expr(ObProxyExprAvg *agg_expr, T *&ex MEMCPY(buf, sql_string.ptr(), sql_string.length()); expr->set_expr_name(buf, sql_string.length()); if (OB_FAIL(handle_derived(expr))) { - LOG_WARN("fail to handle derived", K(ret)); + LOG_WARN("fail to handle derived", K(ret)); } } } @@ -490,8 +490,8 @@ int ObShardingSelectLogPlan::handle_derived(ObProxyExpr *expr, bool column_first ObProxyExprType expr_type = expr->get_expr_type(); if (OB_PROXY_EXPR_TYPE_COLUMN == expr_type || OB_PROXY_EXPR_TYPE_SHARDING_CONST == expr_type || expr->is_func_expr()) { - ObProxySelectStmt *select_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); - ObIArray &select_expr_array = select_stmt->select_exprs_; + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); + ObIArray &select_expr_array = dml_stmt->select_exprs_; // Priority is given to finding derived columns, all derived columns have aliases and can be uniquely located if (bret && do_need_derived(derived_exprs_, expr, column_first, bret)) { @@ -572,8 +572,8 @@ int ObShardingSelectLogPlan::analyze_group_by_clause() { int ret = OB_SUCCESS; - ObProxySelectStmt *select_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); - ObIArray &group_by_exprs = select_stmt->group_by_exprs_; + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); + ObIArray &group_by_exprs = dml_stmt->group_by_exprs_; for (int64_t i = 0; OB_SUCC(ret) && i < group_by_exprs.count(); i++) { ObProxyGroupItem *group_item = dynamic_cast(group_by_exprs.at(i)); @@ -596,8 +596,8 @@ int ObShardingSelectLogPlan::analyze_order_by_clause() { int ret = OB_SUCCESS; - ObProxySelectStmt *select_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); - ObIArray &order_by_exprs = select_stmt->order_by_exprs_; + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); + ObIArray &order_by_exprs = dml_stmt->order_by_exprs_; for (int64_t i = 0; OB_SUCC(ret) && i < order_by_exprs.count(); i++) { ObProxyOrderItem *order_item = dynamic_cast(order_by_exprs.at(i)); @@ -619,8 +619,8 @@ int ObShardingSelectLogPlan::analyze_order_by_clause() int ObShardingSelectLogPlan::analyze_select_clause() { int ret = OB_SUCCESS; - ObProxySelectStmt *select_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); - ObIArray &select_expr_array = select_stmt->select_exprs_; + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); + ObIArray &select_expr_array = dml_stmt->select_exprs_; for (int64_t i = 0; OB_SUCC(ret) && i < select_expr_array.count(); i++) { ObProxyExpr *select_expr = select_expr_array.at(i); @@ -636,9 +636,9 @@ int ObShardingSelectLogPlan::append_derived_order_by(bool &is_same_group_and_ord { int ret = OB_SUCCESS; - ObProxySelectStmt *select_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); - ObIArray &group_by_exprs = select_stmt->group_by_exprs_; - ObIArray &order_by_exprs = select_stmt->order_by_exprs_; + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); + ObIArray &group_by_exprs = dml_stmt->group_by_exprs_; + ObIArray &order_by_exprs = dml_stmt->order_by_exprs_; if (!group_by_exprs.empty() && order_by_exprs.empty()) { is_same_group_and_order = true; @@ -680,28 +680,28 @@ int ObShardingSelectLogPlan::append_derived_order_by(bool &is_same_group_and_ord int ObShardingSelectLogPlan::rewrite_sql(ObSqlString &new_sql) { int ret = OB_SUCCESS; - ObProxySelectStmt *select_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); ObString sql = client_request_.get_sql(); if (derived_columns_.empty() && derived_orders_.empty() - && (select_stmt->limit_size_ == -1 || select_stmt->limit_size_ == 0)) { + && (dml_stmt->limit_size_ == -1 || dml_stmt->limit_size_ == 0)) { new_sql.append(sql); } else { const char *sql_ptr = sql.ptr(); int64_t sql_len = sql.length(); if (derived_columns_.empty() && derived_orders_.empty()) { - int64_t limit_position = select_stmt->limit_token_off_; + int64_t limit_position = dml_stmt->limit_token_off_; new_sql.append(sql_ptr, limit_position); new_sql.append("LIMIT "); - if (select_stmt->limit_size_ == 0) { - new_sql.append_fmt("%d", select_stmt->limit_size_); + if (dml_stmt->limit_size_ == 0) { + new_sql.append_fmt("%d", dml_stmt->limit_size_); } else { - new_sql.append_fmt("%d", select_stmt->limit_offset_ + select_stmt->limit_size_); + new_sql.append_fmt("%d", dml_stmt->limit_offset_ + dml_stmt->limit_size_); } } else { - int64_t from_position = select_stmt->get_from_token_off(); - int64_t limit_position = select_stmt->limit_token_off_; + int64_t from_position = dml_stmt->get_from_token_off(); + int64_t limit_position = dml_stmt->limit_token_off_; new_sql.append(sql_ptr, from_position); if (!derived_columns_.empty()) { @@ -747,10 +747,10 @@ int ObShardingSelectLogPlan::rewrite_sql(ObSqlString &new_sql) if (limit_position > 0) { new_sql.append("LIMIT "); - if (select_stmt->limit_size_ == 0) { - new_sql.append_fmt("%d", select_stmt->limit_size_); + if (dml_stmt->limit_size_ == 0) { + new_sql.append_fmt("%d", dml_stmt->limit_size_); } else { - new_sql.append_fmt("%d", select_stmt->limit_offset_ + select_stmt->limit_size_); + new_sql.append_fmt("%d", dml_stmt->limit_offset_ + dml_stmt->limit_size_); } } } @@ -764,8 +764,8 @@ int ObShardingSelectLogPlan::add_agg_operator(bool need_set_limit) { int ret = OB_SUCCESS; - ObProxySelectStmt *select_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); - ObIArray &group_by_exprs = select_stmt->group_by_exprs_; + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); + ObIArray &group_by_exprs = dml_stmt->group_by_exprs_; T *agg_operator = NULL; ObProxyAggInput *agg_input = NULL; @@ -779,8 +779,8 @@ int ObShardingSelectLogPlan::add_agg_operator(bool need_set_limit) LOG_WARN("set child failed", K(ret)); } else { if (need_set_limit) { - agg_input->set_limit_offset(select_stmt->limit_offset_); - agg_input->set_limit_size(select_stmt->limit_size_); + agg_input->set_limit_offset(dml_stmt->limit_offset_); + agg_input->set_limit_size(dml_stmt->limit_size_); is_set_limit_ = true; } plan_root_ = agg_operator; @@ -816,8 +816,8 @@ int ObShardingSelectLogPlan::add_sort_operator(bool need_set_limit) { int ret = OB_SUCCESS; - ObProxySelectStmt *select_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); - ObIArray &order_by_exprs = select_stmt->order_by_exprs_; + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); + ObIArray &order_by_exprs = dml_stmt->order_by_exprs_; T *sort_operator = NULL; ObProxySortInput *sort_input = NULL; @@ -829,8 +829,8 @@ int ObShardingSelectLogPlan::add_sort_operator(bool need_set_limit) LOG_WARN("set child failed", K(ret)); } else { if (need_set_limit) { - sort_input->set_limit_offset(select_stmt->limit_offset_); - sort_input->set_limit_size(select_stmt->limit_size_); + sort_input->set_limit_offset(dml_stmt->limit_offset_); + sort_input->set_limit_size(dml_stmt->limit_size_); is_set_limit_ = true; } plan_root_ = sort_operator; @@ -865,9 +865,9 @@ int ObShardingSelectLogPlan::add_agg_and_sort_operator(bool is_same_group_and_or { int ret = OB_SUCCESS; - ObProxySelectStmt *select_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); - ObIArray &group_by_exprs = select_stmt->group_by_exprs_; - ObIArray &order_by_exprs = select_stmt->order_by_exprs_; + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); + ObIArray &group_by_exprs = dml_stmt->group_by_exprs_; + ObIArray &order_by_exprs = dml_stmt->order_by_exprs_; if (!group_by_exprs.empty() || !agg_exprs_.empty()) { if (!is_same_group_and_order) { @@ -908,7 +908,7 @@ int ObShardingSelectLogPlan::add_table_scan_operator(ObIArray(client_request_.get_parse_result().get_proxy_stmt()); + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); ObProxyTableScanOp *table_scan_op = NULL; ObProxyTableScanInput *table_scan_input = NULL; char *buf = NULL; @@ -920,7 +920,7 @@ int ObShardingSelectLogPlan::add_table_scan_operator(ObIArrayset_db_key_names(shard_connector_array))) { LOG_WARN("fail to set db key name", K(ret)); } else if (OB_FAIL(table_scan_input->set_shard_props(shard_prop_array))) { @@ -931,9 +931,9 @@ int ObShardingSelectLogPlan::add_table_scan_operator(ObIArrayset_agg_exprs(agg_exprs_))) { LOG_WARN("fail to set agg expr", K(ret)); - } else if (OB_FAIL(table_scan_input->set_group_exprs(select_stmt->group_by_exprs_))) { + } else if (OB_FAIL(table_scan_input->set_group_exprs(dml_stmt->group_by_exprs_))) { LOG_WARN("fail to set group exprs", K(ret)); - } else if (OB_FAIL(table_scan_input->set_order_exprs(select_stmt->order_by_exprs_))) { + } else if (OB_FAIL(table_scan_input->set_order_exprs(dml_stmt->order_by_exprs_))) { LOG_WARN("fail to set order exprs", K(ret)); } else { table_scan_input->set_request_sql(request_sql); @@ -948,7 +948,7 @@ int ObShardingSelectLogPlan::add_table_scan_operator(ObIArray(client_request_.get_parse_result().get_proxy_stmt()); + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); ObProxyProOp *op = NULL; ObProxyProInput *input = NULL; @@ -959,8 +959,8 @@ int ObShardingSelectLogPlan::add_projection_operator() input->set_calc_exprs(calc_exprs_); input->set_derived_column_count(derived_column_count_); if (!is_set_limit_) { - input->set_limit_offset(select_stmt->limit_offset_); - input->set_limit_size(select_stmt->limit_size_); + input->set_limit_offset(dml_stmt->limit_offset_); + input->set_limit_size(dml_stmt->limit_size_); is_set_limit_ = true; } if (OB_FAIL(op->set_child(0, plan_root_))) { @@ -977,9 +977,9 @@ int ObShardingSelectLogPlan::compare_group_and_order(bool &is_same_group_and_ord { int ret = OB_SUCCESS; - ObProxySelectStmt *select_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); - ObIArray &group_by_exprs = select_stmt->group_by_exprs_; - ObIArray &order_by_exprs = select_stmt->order_by_exprs_; + ObProxyDMLStmt *dml_stmt = static_cast(client_request_.get_parse_result().get_proxy_stmt()); + ObIArray &group_by_exprs = dml_stmt->group_by_exprs_; + ObIArray &order_by_exprs = dml_stmt->order_by_exprs_; if (!group_by_exprs.empty() && !order_by_exprs.empty() && group_by_exprs.count() == order_by_exprs.count()) { diff --git a/src/obproxy/packet/ob_mysql_packet_reader.cpp b/src/obproxy/packet/ob_mysql_packet_reader.cpp index d4800d9a5..d28ba1ba9 100644 --- a/src/obproxy/packet/ob_mysql_packet_reader.cpp +++ b/src/obproxy/packet/ob_mysql_packet_reader.cpp @@ -12,7 +12,6 @@ #define USING_LOG_PREFIX PROXY #include "packet/ob_mysql_packet_reader.h" -#include "rpc/obmysql/ob_mysql_util.h" #include "rpc/obmysql/packet/ompk_ok.h" using namespace oceanbase::common; @@ -111,20 +110,20 @@ inline int ObMysqlPacketReader::get_buf(ObIOBufferReader &buf_reader, const int6 return ret; } -inline int ObMysqlPacketReader::get_content_len_and_seq(ObIOBufferReader &buf_reader, - const int64_t offset, int64_t &content_len, uint8_t &seq) +int ObMysqlPacketReader::is_eof_packet(ObIOBufferReader &buf_reader, const int64_t offset, bool &is_eof) { int ret = OB_SUCCESS; char *pbuf = NULL; - if (OB_FAIL(get_buf(buf_reader, OB_MYSQL_NET_HEADER_LENGTH, offset, pbuf))) { + is_eof = false; + if (OB_FAIL(get_buf(buf_reader, proxy::MYSQL_NET_META_LENGTH, offset, pbuf))) { LOG_WARN("fail to get header buf", K(ret)); } else if (OB_ISNULL(pbuf)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("pbuf is null, which is unexpected", K(pbuf), K(ret)); } else { - content_len = static_cast(uint3korr(pbuf)); - seq = static_cast(uint1korr(pbuf + 3)); - } + int64_t eof = static_cast(uint1korr(pbuf + 4)); + is_eof = (proxy::MYSQL_EOF_PACKET_TYPE == eof); + } return ret; } @@ -191,12 +190,18 @@ int ObMysqlPacketReader::get_ok_packet_server_status(ObIOBufferReader &buf_reade int ObMysqlPacketReader::get_packet(ObIOBufferReader &buf_reader, ObMySQLPacket &packet) +{ + return get_packet(buf_reader, 0, packet); +} + +int ObMysqlPacketReader::get_packet(ObIOBufferReader &buf_reader, + const int64_t offset, + ObMySQLPacket &packet) { int ret = OB_SUCCESS; char *content_buf = NULL; int64_t content_len = 0; uint8_t seq = 0; - int64_t offset = 0; if (OB_FAIL(get_content_len_and_seq(buf_reader, offset, content_len, seq))) { LOG_WARN("fail to get content length and seq", K(content_len), K(seq), K(offset), K(ret)); } else if (OB_FAIL(get_buf(buf_reader, content_len, offset + OB_MYSQL_NET_HEADER_LENGTH, content_buf))) { diff --git a/src/obproxy/packet/ob_mysql_packet_reader.h b/src/obproxy/packet/ob_mysql_packet_reader.h index 75dadab07..a95758e34 100644 --- a/src/obproxy/packet/ob_mysql_packet_reader.h +++ b/src/obproxy/packet/ob_mysql_packet_reader.h @@ -15,6 +15,8 @@ #include "utils/ob_proxy_lib.h" #include "iocore/eventsystem/ob_io_buffer.h" +#include "proxy/mysqllib/ob_mysql_common_define.h" +#include "rpc/obmysql/ob_mysql_util.h" namespace oceanbase { @@ -44,6 +46,8 @@ class ObMysqlPacketReader // === GET function will not comsume the packet int get_content_len_and_seq(event::ObIOBufferReader &buf_reader, const int64_t offset, int64_t &content_len, uint8_t &seq); + int is_eof_packet(event::ObIOBufferReader &buf_reader, const int64_t offset, bool &is_eof); + // DESC: get the next ok packet from MIOBuffer // NOTE: 1. get function will NOT consume buffer as packet may hold some string int mio_buf // 2. if mio_buf.consume or reader.reset is called, do NOT use the packet any more @@ -71,6 +75,9 @@ class ObMysqlPacketReader obmysql::OMPKOK &ok_pkt); int get_packet(event::ObIOBufferReader &buf_reader, obmysql::ObMySQLPacket &packet); + int get_packet(event::ObIOBufferReader &buf_reader, + const int64_t offset, + obmysql::ObMySQLPacket &packet); int get_ok_packet_server_status(event::ObIOBufferReader &buf_reader, obmysql::ObServerStatusFlags &server_status); // === READ function will comsume the packet @@ -134,6 +141,26 @@ inline int ObMysqlPacketReader::read_packet_str(event::ObIOBufferReader &buf_rea return ret; } +inline int ObMysqlPacketReader::get_content_len_and_seq(event::ObIOBufferReader &buf_reader, + const int64_t offset, + int64_t &content_len, + uint8_t &seq) +{ + int ret = OB_SUCCESS; + char *pbuf = NULL; + if (OB_FAIL(get_buf(buf_reader, OB_MYSQL_NET_HEADER_LENGTH, offset, pbuf))) { + PROXY_LOG(WARN, "fail to get header buf", K(ret)); + } else if (OB_ISNULL(pbuf)) { + ret = OB_ERR_UNEXPECTED; + PROXY_LOG(WARN, "pbuf is null, which is unexpected", K(pbuf), K(ret)); + } else { + content_len = static_cast(uint3korr(pbuf)); + seq = static_cast(uint1korr(pbuf + 3)); + } + + return ret; +} + } // end of namespace packet } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/packet/ob_mysql_packet_util.cpp b/src/obproxy/packet/ob_mysql_packet_util.cpp index 6fe455e84..74eb479c4 100644 --- a/src/obproxy/packet/ob_mysql_packet_util.cpp +++ b/src/obproxy/packet/ob_mysql_packet_util.cpp @@ -72,14 +72,36 @@ int ObMysqlPacketUtil::encode_header(ObMIOBuffer &write_buf, return ret; } +int ObMysqlPacketUtil::encode_field_packet(ObMIOBuffer &write_buf, + uint8_t &seq, + ObMySQLField &field) { + int ret = OB_SUCCESS; + OMPKField field_packet(field); + field_packet.set_seq(seq++); + if (OB_FAIL(ObMysqlPacketWriter::write_field_packet(write_buf, field_packet))) { + LOG_WARN("fail to write field", K(field_packet), K(field), K(ret)); + --seq; + } + return ret; +} + int ObMysqlPacketUtil::encode_row_packet(ObMIOBuffer &write_buf, uint8_t &seq, const ObNewRow &row, ObIArray *fields) +{ + return encode_row_packet(write_buf, TEXT, seq, row, fields); +} + +int ObMysqlPacketUtil::encode_row_packet(ObMIOBuffer &write_buf, + MYSQL_PROTOCOL_TYPE protocol_type, + uint8_t &seq, + const ObNewRow &row, + ObIArray *fields) { int ret = OB_SUCCESS; - ObSMRow sm_row(TEXT, row, NULL, fields); + ObSMRow sm_row(protocol_type, row, NULL, fields); OMPKRow row_packet(sm_row); row_packet.set_seq(seq++); @@ -108,99 +130,6 @@ int ObMysqlPacketUtil::encode_eof_packet(ObMIOBuffer &write_buf, return ret; } -int ObMysqlPacketUtil::encode_executor_response_packet(ObMIOBuffer *write_buf, uint8_t &seq, - engine::ObProxyResultResp *result_resp) -{ - int ret = OB_SUCCESS; - - int64_t column_count = result_resp->get_column_count(); - ObSEArray *fields = NULL; - ObSEArray ob_fields; - - // header , cols , first eof - if (OB_SUCC(ret)) { - if (OB_FAIL(result_resp->get_fields(fields))) { - LOG_WARN("faild to push field", K(fields), K(ret)); - } else if (OB_ISNULL(fields)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("fields should not be null", K(ret)); - } else if (OB_UNLIKELY(fields->count() != column_count)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("fields count should equal column_count", K(column_count), "fileds count", fields->count(), K(ret)); - } else if (OB_FAIL(ObMysqlPacketUtil::encode_header(*write_buf, seq, *fields))) { - LOG_WARN("faild to encode header", K(fields), K(seq), K(ret)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < column_count; i++) { - ObMySQLField &mysql_field = fields->at(i); - ObField ob_field; - if (OB_FAIL(ObSMUtils::to_ob_field(mysql_field, ob_field))) { - LOG_WARN("faild to ob field", K(mysql_field), K(ret)); - } else if (OB_FAIL(ob_fields.push_back(ob_field))) { - LOG_WARN("faild to push ob field", K(ob_field), K(ret)); - } - } - } - } - - // rows - if (OB_SUCC(ret)) { - ObObj *objs = NULL; - int64_t buf_len = sizeof(ObObj) * column_count; - - if (OB_ISNULL(objs = static_cast(op_fixed_mem_alloc(buf_len)))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("faild to alloc obj array", K(column_count), K(ret)); - } else { - ObNewRow row; - //ObSEArray *row_array; - ObSEArray *row_array; - while ((OB_SUCC(ret)) && (OB_SUCC(result_resp->next(row_array)))) { - if (OB_ISNULL(row_array)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("row_array should not be null", K(ret)); - } else if (OB_UNLIKELY(row_array->count() != column_count)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("row_array count should equal column_count", K(column_count), - "row_array count", row_array->count(), K(ret)); - } - - for (int64_t i = 0; OB_SUCC(ret) && i < column_count; i++) { - objs[i] = *(row_array->at(i)); - } - - if (OB_SUCC(ret)) { - row.cells_ = objs; - row.count_ = column_count; - if (OB_FAIL(ObMysqlPacketUtil::encode_row_packet(*write_buf, seq, row, &ob_fields))) { - LOG_WARN("faild to encode row", K(seq), K(row), K(ret)); - } else { - row.reset(); - row_array = NULL; - } - } - } - - if (OB_ITER_END == ret) { - ret = OB_SUCCESS; - } - } - - if (OB_NOT_NULL(objs)) { - op_fixed_mem_free(objs, buf_len); - objs = NULL; - } - } - - // second eof - if (OB_SUCC(ret)) { - if (OB_FAIL(ObMysqlPacketUtil::encode_eof_packet(*write_buf, seq))) { - LOG_WARN("faild to encode row", K(seq), K(ret)); - } - } - - return ret; -} - int ObMysqlPacketUtil::encode_err_packet(ObMIOBuffer &write_buf, uint8_t &seq, const int errcode, const char *msg_buf) { return encode_err_packet(write_buf, seq, errcode, ObString::make_string(msg_buf)); diff --git a/src/obproxy/packet/ob_mysql_packet_util.h b/src/obproxy/packet/ob_mysql_packet_util.h index f9cc349dd..2073997e1 100644 --- a/src/obproxy/packet/ob_mysql_packet_util.h +++ b/src/obproxy/packet/ob_mysql_packet_util.h @@ -47,13 +47,20 @@ class ObMysqlPacketUtil static int encode_header(event::ObMIOBuffer &write_buf, uint8_t &seq, common::ObIArray &fields, uint16_t status_flag = 0); - static int encode_row_packet(event::ObMIOBuffer &write_buf, uint8_t &seq, + static int encode_field_packet(event::ObMIOBuffer &write_buf, + uint8_t &seq, + obmysql::ObMySQLField &field); + static int encode_row_packet(event::ObMIOBuffer &write_buf, + uint8_t &seq, + const common::ObNewRow &row, + common::ObIArray *fields = NULL); + static int encode_row_packet(event::ObMIOBuffer &write_buf, + obmysql::MYSQL_PROTOCOL_TYPE protocol_type, + uint8_t &seq, const common::ObNewRow &row, common::ObIArray *fields = NULL); static int encode_eof_packet(event::ObMIOBuffer &write_buf, uint8_t &seq, uint16_t status_flag = 0); - static int encode_executor_response_packet(event::ObMIOBuffer *write_buf, uint8_t &seq, - engine::ObProxyResultResp *result_resp); static int encode_err_packet(event::ObMIOBuffer &write_buf, uint8_t &seq, const int errcode, const char *msg_buf); diff --git a/src/obproxy/packet/ob_proxy_packet_writer.cpp b/src/obproxy/packet/ob_proxy_packet_writer.cpp index f879d1b76..d5d1a1089 100644 --- a/src/obproxy/packet/ob_proxy_packet_writer.cpp +++ b/src/obproxy/packet/ob_proxy_packet_writer.cpp @@ -35,18 +35,20 @@ namespace obproxy namespace packet { -int ObProxyPacketWriter::write_packet(event::ObMIOBuffer &write_buf, ObMysqlClientSession &client_session, +int ObProxyPacketWriter::write_packet(event::ObMIOBuffer &write_buf, + ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, obmysql::ObMySQLPacket &packet) { int ret = OB_SUCCESS; - ObProxyProtocol protocol = client_session.get_client_session_protocol(); - + if (protocol == ObProxyProtocol::PROTOCOL_OB20) { Ob20ProtocolHeader &ob20_head = client_session.get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session.get_compressed_seq() + 1); Ob20ProtocolHeaderParam ob20_head_param(client_session.get_cs_id(), ob20_head.request_id_, compressed_seq, - compressed_seq, true, false, - client_session.is_client_support_new_extra_info()); + compressed_seq, true, false, false, + client_session.is_client_support_new_extra_info(), + client_session.is_trans_internal_routing()); if (OB_FAIL(ObMysqlOB20PacketWriter::write_packet(write_buf, packet, ob20_head_param))) { LOG_WARN("fail to write ob20 packet", K(ret)); } else { @@ -61,18 +63,20 @@ int ObProxyPacketWriter::write_packet(event::ObMIOBuffer &write_buf, ObMysqlClie return ret; } -int ObProxyPacketWriter::write_raw_packet(event::ObMIOBuffer &write_buf, ObMysqlClientSession &client_session, +int ObProxyPacketWriter::write_raw_packet(event::ObMIOBuffer &write_buf, + ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, ObString &pkt_str) { int ret = OB_SUCCESS; - ObProxyProtocol client_protocol = client_session.get_client_session_protocol(); - if (client_protocol == ObProxyProtocol::PROTOCOL_OB20) { + if (protocol == ObProxyProtocol::PROTOCOL_OB20) { Ob20ProtocolHeader &ob20_head = client_session.get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session.get_compressed_seq() + 1); Ob20ProtocolHeaderParam ob20_head_param(client_session.get_cs_id(), ob20_head.request_id_, - compressed_seq, compressed_seq, true, false, - client_session.is_client_support_new_extra_info()); + compressed_seq, compressed_seq, true, false, false, + client_session.is_client_support_new_extra_info(), + client_session.is_trans_internal_routing()); if (OB_FAIL(ObMysqlOB20PacketWriter::write_raw_packet(write_buf, pkt_str, ob20_head_param))) { LOG_WARN("fail to write raw packet in ob20 format", K(ret)); } else { @@ -87,19 +91,23 @@ int ObProxyPacketWriter::write_raw_packet(event::ObMIOBuffer &write_buf, ObMysql return ret; } -int ObProxyPacketWriter::write_kv_resultset(event::ObMIOBuffer &write_buf, ObMysqlClientSession &client_session, - uint8_t &seq, const obmysql::ObMySQLField &field, ObObj &field_value, +int ObProxyPacketWriter::write_kv_resultset(event::ObMIOBuffer &write_buf, + ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, + uint8_t &seq, + const obmysql::ObMySQLField &field, + ObObj &field_value, const uint16_t status_flag) { int ret = OB_SUCCESS; - ObProxyProtocol client_protocol = client_session.get_client_session_protocol(); - if (client_protocol == ObProxyProtocol::PROTOCOL_OB20) { + if (protocol == ObProxyProtocol::PROTOCOL_OB20) { Ob20ProtocolHeader &ob20_head = client_session.get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session.get_compressed_seq() + 1); Ob20ProtocolHeaderParam ob20_head_param(client_session.get_cs_id(), ob20_head.request_id_, compressed_seq, - compressed_seq, true, false, - client_session.is_client_support_new_extra_info()); + compressed_seq, true, false, false, + client_session.is_client_support_new_extra_info(), + client_session.is_trans_internal_routing()); if (OB_FAIL(ObProto20Utils::encode_kv_resultset(write_buf, ob20_head_param, seq, field, field_value, status_flag))) { LOG_WARN("fail to encode kv resultset", K(ret)); @@ -114,19 +122,22 @@ int ObProxyPacketWriter::write_kv_resultset(event::ObMIOBuffer &write_buf, ObMys return ret; } -int ObProxyPacketWriter::write_ok_packet(event::ObMIOBuffer &write_buf, ObMysqlClientSession &client_session, - uint8_t &seq, const int64_t affected_rows, +int ObProxyPacketWriter::write_ok_packet(event::ObMIOBuffer &write_buf, + ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, + uint8_t &seq, + const int64_t affected_rows, const obmysql::ObMySQLCapabilityFlags &capability) { int ret = OB_SUCCESS; - ObProxyProtocol protocol = client_session.get_client_session_protocol(); if (protocol == ObProxyProtocol::PROTOCOL_OB20) { Ob20ProtocolHeader &ob20_head = client_session.get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session.get_compressed_seq() + 1); Ob20ProtocolHeaderParam ob20_head_param(client_session.get_cs_id(), ob20_head.request_id_, compressed_seq, - compressed_seq, true, false, - client_session.is_client_support_new_extra_info()); + compressed_seq, true, false, false, + client_session.is_client_support_new_extra_info(), + client_session.is_trans_internal_routing()); if (OB_FAIL(ObProto20Utils::encode_ok_packet(write_buf, ob20_head_param, seq, affected_rows, capability))) { LOG_WARN("fail to encode ok packet in ob20 format", K(ret)); } else { @@ -141,31 +152,6 @@ int ObProxyPacketWriter::write_ok_packet(event::ObMIOBuffer &write_buf, ObMysqlC return ret; } -int ObProxyPacketWriter::write_executor_resp_packet(event::ObMIOBuffer *write_buf, - ObMysqlClientSession *client_session, uint8_t &seq, - engine::ObProxyResultResp *result_resp) -{ - int ret = OB_SUCCESS; - ObProxyProtocol client_protocol = client_session->get_client_session_protocol(); - - if (client_protocol == ObProxyProtocol::PROTOCOL_OB20) { - Ob20ProtocolHeader &ob20_head = client_session->get_session_info().ob20_request_.ob20_header_; - uint8_t compressed_seq = static_cast(client_session->get_compressed_seq() + 1); - Ob20ProtocolHeaderParam ob20_head_param(client_session->get_cs_id(), ob20_head.request_id_, compressed_seq, - compressed_seq, true, false, - client_session->is_client_support_new_extra_info()); - if (OB_FAIL(ObProto20Utils::encode_executor_response_packet(write_buf, ob20_head_param, seq, result_resp))) { - LOG_WARN("fail to encode executor response ob20 packet", K(ret)); - } - } else { - if (OB_FAIL(ObMysqlPacketUtil::encode_executor_response_packet(write_buf, seq, result_resp))) { - LOG_WARN("fail to encode executor response packet", K(ret)); - } - } - - return ret; -} - int ObProxyPacketWriter::get_err_buf(int err_code, char *&buf) { int ret = OB_SUCCESS; @@ -195,19 +181,27 @@ int ObProxyPacketWriter::get_err_buf(int err_code, char *&buf) return ret; } -int ObProxyPacketWriter::write_error_packet(event::ObMIOBuffer &write_buf, proxy::ObMysqlClientSession *client_session, - uint8_t &seq, const int err_code, const char *msg_buf) +// build error packet back to client +int ObProxyPacketWriter::write_error_packet(event::ObMIOBuffer &write_buf, + proxy::ObMysqlClientSession *client_session, + const ObProxyProtocol protocol, + uint8_t &seq, + const int err_code, + const char *msg_buf) { - return write_error_packet(write_buf, client_session, seq, err_code, common::ObString::make_string(msg_buf)); + return write_error_packet(write_buf, client_session, protocol, seq, err_code, common::ObString::make_string(msg_buf)); } -int ObProxyPacketWriter::write_error_packet(event::ObMIOBuffer &write_buf, proxy::ObMysqlClientSession *client_session, - uint8_t &seq, const int err_code, const ObString &msg_buf) +int ObProxyPacketWriter::write_error_packet(event::ObMIOBuffer &write_buf, + proxy::ObMysqlClientSession *client_session, + const ObProxyProtocol protocol, + uint8_t &seq, + const int err_code, + const ObString &msg_buf) { int ret = OB_SUCCESS; - ObProxyProtocol client_protocol = client_session->get_client_session_protocol(); - if (client_protocol == ObProxyProtocol::PROTOCOL_OB20) { + if (protocol == ObProxyProtocol::PROTOCOL_OB20) { if (OB_ISNULL(client_session)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid client session ptr in ob20 mode", K(ret)); @@ -215,8 +209,9 @@ int ObProxyPacketWriter::write_error_packet(event::ObMIOBuffer &write_buf, proxy Ob20ProtocolHeader &ob20_head = client_session->get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session->get_compressed_seq() + 1); Ob20ProtocolHeaderParam ob20_head_param(client_session->get_cs_id(), ob20_head.request_id_, - compressed_seq, compressed_seq, true, false, - client_session->is_client_support_new_extra_info()); + compressed_seq, compressed_seq, true, false, false, + client_session->is_client_support_new_extra_info(), + client_session->is_trans_internal_routing()); if (OB_FAIL(ObProto20Utils::encode_err_packet(write_buf, ob20_head_param, seq, err_code, msg_buf))) { LOG_WARN("fail to encode err packet in ob20 format", K(ret)); } diff --git a/src/obproxy/packet/ob_proxy_packet_writer.h b/src/obproxy/packet/ob_proxy_packet_writer.h index 1fb184c8b..4b58c4db6 100644 --- a/src/obproxy/packet/ob_proxy_packet_writer.h +++ b/src/obproxy/packet/ob_proxy_packet_writer.h @@ -33,16 +33,18 @@ class ObProxyPacketWriter { // packet static int write_packet(event::ObMIOBuffer &write_buf, proxy::ObMysqlClientSession &client_session, + const proxy::ObProxyProtocol protocol, obmysql::ObMySQLPacket &packet); - static int write_raw_packet(event::ObMIOBuffer &write_buf, proxy::ObMysqlClientSession &client_session, + static int write_raw_packet(event::ObMIOBuffer &write_buf, + proxy::ObMysqlClientSession &client_session, + const proxy::ObProxyProtocol protocol, ObString &pkt_str); static int write_kv_resultset(event::ObMIOBuffer &write_buf, proxy::ObMysqlClientSession &client_session, - uint8_t &seq, const obmysql::ObMySQLField &field, ObObj &field_value, - const uint16_t status_flag); - static int write_ok_packet(event::ObMIOBuffer &write_buf, proxy::ObMysqlClientSession &client_session, uint8_t &seq, - const int64_t affected_rows, const obmysql::ObMySQLCapabilityFlags &capability); - static int write_executor_resp_packet(event::ObMIOBuffer *write_buf, proxy::ObMysqlClientSession *client_session, - uint8_t &seq, engine::ObProxyResultResp *result_resp); + const proxy::ObProxyProtocol protocol, uint8_t &seq, + const obmysql::ObMySQLField &field, ObObj &field_value, const uint16_t status_flag); + static int write_ok_packet(event::ObMIOBuffer &write_buf, proxy::ObMysqlClientSession &client_session, + const proxy::ObProxyProtocol protocol, uint8_t &seq, const int64_t affected_rows, + const obmysql::ObMySQLCapabilityFlags &capability); // get thread err buffer static int get_err_buf(int err_code, char *&buf); @@ -74,9 +76,11 @@ class ObProxyPacketWriter { } static int write_error_packet(event::ObMIOBuffer &write_buf, proxy::ObMysqlClientSession *client_session, - uint8_t &seq, const int err_code, const char *msg_buf); + const proxy::ObProxyProtocol protocol, uint8_t &seq, + const int err_code, const char *msg_buf); static int write_error_packet(event::ObMIOBuffer &write_buf, proxy::ObMysqlClientSession *client_session, - uint8_t &seq, const int err_code, const ObString &msg_buf); + const proxy::ObProxyProtocol protocol, uint8_t &seq, const int err_code, + const ObString &msg_buf); }; diff --git a/src/obproxy/prometheus/ob_prometheus_processor.h b/src/obproxy/prometheus/ob_prometheus_processor.h index 106516a8e..44525392f 100644 --- a/src/obproxy/prometheus/ob_prometheus_processor.h +++ b/src/obproxy/prometheus/ob_prometheus_processor.h @@ -88,7 +88,7 @@ class ObPrometheusProcessor obutils::ObAsyncCommonTask *prometheus_sync_cont_; char version_[100]; - char proxy_ip_[common::OB_IP_STR_BUFF]; // ip primary key + char proxy_ip_[common::MAX_IP_ADDR_LENGTH]; // ip primary key common::ObVector default_constant_labels_; ObPrometheusFamilyHashTable family_hash_; diff --git a/src/obproxy/proxy/api/ob_api_internal.h b/src/obproxy/proxy/api/ob_api_internal.h index d309439f6..a956efb12 100644 --- a/src/obproxy/proxy/api/ob_api_internal.h +++ b/src/obproxy/proxy/api/ob_api_internal.h @@ -93,6 +93,9 @@ class ObFeatureAPIHooks // Remove all hooks. void destroy(); + // Remove hooks indicated by id + void destroy(ID id); + // Add the hook cont to the front of the hooks for id. int prepend(ID id, ObContInternal *cont); @@ -120,7 +123,7 @@ class ObFeatureAPIHooks private: bool hooks_p_; // Flag for (not) empty container. - + // The array of hooks lists. ObAPIHooks hooks_[N]; }; @@ -203,6 +206,23 @@ inline void ObFeatureAPIHooks::destroy() hooks_p_ = false; } +template +inline void ObFeatureAPIHooks::destroy(ID id) +{ + if (is_valid(id)) { + hooks_[id].destroy(); + + bool has_hooks_or_not = false; + for (int i = 0; i < N; ++i) { + if (!hooks_[i].is_empty()) { + has_hooks_or_not = true; + break; + } + } + hooks_p_ = has_hooks_or_not; + } +} + template inline int ObFeatureAPIHooks::prepend(ID id, ObContInternal *cont) { diff --git a/src/obproxy/proxy/api/ob_mysql_sm_api.h b/src/obproxy/proxy/api/ob_mysql_sm_api.h index 8d70ed8e3..4099ffeac 100644 --- a/src/obproxy/proxy/api/ob_mysql_sm_api.h +++ b/src/obproxy/proxy/api/ob_mysql_sm_api.h @@ -116,6 +116,7 @@ class ObMysqlSMApi void txn_hook_append(const ObMysqlHookID id, ObContInternal *cont); void txn_hook_prepend(const ObMysqlHookID id, ObContInternal *cont); ObAPIHook *txn_hook_get(const ObMysqlHookID id); + void txn_destroy_hook(const ObMysqlHookID id); public: // Tunneling request to plugin @@ -180,6 +181,11 @@ inline ObAPIHook *ObMysqlSMApi::txn_hook_get(const ObMysqlHookID id) return api_hooks_.get(id); } +inline void ObMysqlSMApi::txn_destroy_hook(const ObMysqlHookID id) +{ + api_hooks_.destroy(id); +} + } // end of namespace proxy } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/proxy/client/Makemodule.am b/src/obproxy/proxy/client/Makemodule.am index 33b73fdd4..d62193b00 100644 --- a/src/obproxy/proxy/client/Makemodule.am +++ b/src/obproxy/proxy/client/Makemodule.am @@ -8,4 +8,6 @@ obproxy/proxy/client/ob_mysql_client_pool.cpp\ obproxy/proxy/client/ob_raw_mysql_client.h\ obproxy/proxy/client/ob_raw_mysql_client.cpp\ obproxy/proxy/client/ob_mysql_proxy.h\ -obproxy/proxy/client/ob_mysql_proxy.cpp +obproxy/proxy/client/ob_mysql_proxy.cpp\ +obproxy/proxy/client/ob_driver_client.h\ +obproxy/proxy/client/ob_driver_client.cpp diff --git a/src/obproxy/proxy/client/ob_client_utils.cpp b/src/obproxy/proxy/client/ob_client_utils.cpp index 20bf53655..cfc78c7bf 100644 --- a/src/obproxy/proxy/client/ob_client_utils.cpp +++ b/src/obproxy/proxy/client/ob_client_utils.cpp @@ -17,7 +17,7 @@ #include "rpc/obmysql/packet/ompk_handshake_response.h" #include "packet/ob_mysql_packet_reader.h" #include "packet/ob_mysql_packet_writer.h" - +#include "omt/ob_proxy_config_table_processor.h" using namespace oceanbase::common; using namespace oceanbase::obmysql; @@ -25,6 +25,8 @@ using namespace oceanbase::obproxy; using namespace oceanbase::obproxy::proxy; using namespace oceanbase::obproxy::event; using namespace oceanbase::obproxy::packet; +using namespace oceanbase::obproxy::omt; +using namespace oceanbase::obproxy::obutils; namespace oceanbase { @@ -41,7 +43,10 @@ void ObMysqlRequestParam::reset() current_idc_name_.reset(); is_user_idc_name_set_ = false; need_print_trace_stat_ = false; - + target_addr_.reset(); + ob_client_flags_.flags_ = 0; + mysql_client_ = NULL; + is_detect_client_ = false; } void ObMysqlRequestParam::reset_sql() @@ -81,6 +86,9 @@ int ObMysqlRequestParam::deep_copy(const ObMysqlRequestParam &other) is_user_idc_name_set_ = other.is_user_idc_name_set_; need_print_trace_stat_ = other.need_print_trace_stat_; target_addr_ = other.target_addr_; + ob_client_flags_.flags_ = other.ob_client_flags_.flags_; + mysql_client_ = other.mysql_client_; + is_detect_client_ = other.is_detect_client_; if (other.is_user_idc_name_set_ && !other.current_idc_name_.empty()) { MEMCPY(current_idc_name_buf_, other.current_idc_name_.ptr(), other.current_idc_name_.length()); current_idc_name_.assign_ptr(current_idc_name_buf_, other.current_idc_name_.length()); @@ -265,15 +273,15 @@ int64_t ObMysqlResultHandler::to_string(char *buf, const int64_t buf_len) const return pos; } -//------------------------- ObClientReuqestInfo--------------------------------// -void ObClientReuqestInfo::reset() +//------------------------- ObClientRequestInfo --------------------------------// +void ObClientRequestInfo::reset() { reset_names(); need_skip_stage2_ = false; request_param_.reset(); } -void ObClientReuqestInfo::reset_names() +void ObClientRequestInfo::reset_names() { if ((NULL != name_) && (name_len_ > 0)) { op_fixed_mem_free(name_, name_len_); @@ -282,31 +290,35 @@ void ObClientReuqestInfo::reset_names() name_len_ = 0; user_name_.reset(); database_name_.reset(); + cluster_name_.reset(); password_.reset(); password0_.reset(); password1_.reset(); using_password_num_ = -1; + password_version_ = 0; } -void ObClientReuqestInfo::reset_sql() +void ObClientRequestInfo::reset_sql() { request_param_.reset(); } -int64_t ObClientReuqestInfo::to_string(char *buf, const int64_t buf_len) const +int64_t ObClientRequestInfo::to_string(char *buf, const int64_t buf_len) const { int64_t pos = 0; J_OBJ_START(); J_KV(K_(user_name), K_(database_name), + K_(cluster_name), K_(request_param)); J_OBJ_END(); return pos; } -int ObClientReuqestInfo::set_names(const ObString &user_name, +int ObClientRequestInfo::set_names(const ObString &user_name, const ObString &password, const ObString &database_name, + const ObString &cluster_name, const ObString &password1) { int ret = OB_SUCCESS; @@ -315,13 +327,24 @@ int ObClientReuqestInfo::set_names(const ObString &user_name, LOG_WARN("user_name can not be NULL", K(user_name), K(ret)); } else { reset_names(); - int64_t total_len = user_name.length() + password.length() + password1.length() + database_name.length(); + int64_t total_len = user_name.length() + password.length() + password1.length() + + database_name.length() + cluster_name.length(); + if (user_name.prefix_case_match(ObProxyTableInfo::READ_ONLY_USERNAME)) { + if (password.empty()) { + total_len += ENC_STRING_BUF_LEN - 2; + } + if (password1.empty()) { + total_len += ENC_STRING_BUF_LEN - 2; + } + } + if (OB_ISNULL(name_ = static_cast(op_fixed_mem_alloc(total_len)))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to allocate mem", "alloc size", total_len, K(ret)); } else { int64_t pos = 0; name_len_ = total_len; + memset(name_, 0, total_len); MEMCPY(name_, user_name.ptr(), user_name.length()); user_name_.assign_ptr(name_, user_name.length()); pos += user_name.length(); @@ -329,25 +352,41 @@ int ObClientReuqestInfo::set_names(const ObString &user_name, if (!password.empty()) { MEMCPY(name_ + pos, password.ptr(), password.length()); password_.assign_ptr(name_ + pos, password.length()); + using_password_num_ = 0; password0_ = password_; pos += password.length(); + } else if (user_name.prefix_case_match(ObProxyTableInfo::READ_ONLY_USERNAME)) { + password0_.assign_ptr(name_ + pos, ENC_STRING_BUF_LEN - 2); + pos += ENC_STRING_BUF_LEN - 2; } if (!password1.empty()) { MEMCPY(name_ + pos, password1.ptr(), password1.length()); password1_.assign_ptr(name_ + pos, password1.length()); pos += password1.length(); + if (password_.empty()) { + password_ = password1_; + using_password_num_ = 1; + } + } else if (user_name.prefix_case_match(ObProxyTableInfo::READ_ONLY_USERNAME)) { + password1_.assign_ptr(name_ + pos, ENC_STRING_BUF_LEN - 2); + pos+= ENC_STRING_BUF_LEN - 2; } - if (!password.empty() && !password1.empty()) { + if (user_name.prefix_case_match(ObProxyTableInfo::READ_ONLY_USERNAME) && password0_.empty() && password1_.empty()) { using_password_num_ = 0; } - if (!database_name.empty()) { MEMCPY(name_ + pos, database_name.ptr(), database_name.length()); database_name_.assign_ptr(name_ + pos, database_name.length()); pos += database_name.length(); } + + if (!cluster_name.empty()) { + MEMCPY(name_ + pos, cluster_name.ptr(), cluster_name.length()); + cluster_name_.assign_ptr(name_ + pos, cluster_name.length()); + pos += cluster_name.length(); + } if (pos != total_len) { ret = OB_ERR_UNEXPECTED; LOG_WARN("pos must be equal to total len", K(pos), K(total_len), K(ret)); @@ -358,7 +397,7 @@ int ObClientReuqestInfo::set_names(const ObString &user_name, return ret; } -int ObClientReuqestInfo::set_request_param(const ObMysqlRequestParam &request_param) +int ObClientRequestInfo::set_request_param(const ObMysqlRequestParam &request_param) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!request_param.is_valid())) { @@ -418,7 +457,7 @@ int ObClientUtils::get_scramble(ObIOBufferReader *response_reader, char *buf, int ObClientUtils::build_handshake_response_packet( ObClientMysqlResp *handshake, - ObClientReuqestInfo *info, + ObClientRequestInfo *info, ObMIOBuffer *handshake_resp_buf) { int ret = OB_SUCCESS; @@ -486,6 +525,45 @@ int ObClientUtils::build_handshake_response_packet( return ret; } +const ObString& ObClientRequestInfo::get_password() +{ + int ret = OB_SUCCESS; + uint64_t global_version = get_global_proxy_config_table_processor().get_config_version(); + if (!cluster_name_.empty() && password_version_ != global_version && user_name_.prefix_case_match(ObProxyTableInfo::READ_ONLY_USERNAME)) { + ObConfigItem item; + ObVipAddr addr; + password_.reset(); + if (OB_FAIL(get_global_config_processor().get_proxy_config( + addr, cluster_name_, "", ObProxyTableInfo::OBSERVER_SYS_PASSWORD, item))) { + LOG_WARN("get observer_sys_password config failed", K_(cluster_name), K(ret)); + } else if (40 == strlen(item.str())) { + MEMCPY(password0_.ptr(), item.str(), strlen(item.str())); + password_ = password0_; + } else { + memset(password0_.ptr(), 0, password0_.length()); + } + + using_password_num_ = 0; + + if (OB_SUCC(ret)) { + if (OB_FAIL(get_global_config_processor().get_proxy_config( + addr, cluster_name_, "", ObProxyTableInfo::OBSERVER_SYS_PASSWORD1, item))) { + LOG_WARN("get observer_sys_password1 config failed", K_(cluster_name), K(ret)); + } else if (40 == strlen(item.str())) { + MEMCPY(password1_.ptr(), item.str(), strlen(item.str())); + } else { + memset(password1_.ptr(), 0, sizeof(password1_.length())); + } + } + if (OB_SUCC(ret)) { + password_version_ = global_version; + } + LOG_DEBUG("get new password success", K(password0_), K(password1_)); + } + + return password_; +} + } // end of namespace proxy } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/proxy/client/ob_client_utils.h b/src/obproxy/proxy/client/ob_client_utils.h index 6e94f66bc..bd281ddbf 100644 --- a/src/obproxy/proxy/client/ob_client_utils.h +++ b/src/obproxy/proxy/client/ob_client_utils.h @@ -16,6 +16,7 @@ #include "iocore/net/ob_net.h" #include "proxy/mysqllib/ob_mysql_transaction_analyzer.h" #include "proxy/mysqllib/ob_resultset_fetcher.h" +#include "utils/ob_proxy_table_define.h" namespace oceanbase { @@ -23,25 +24,50 @@ namespace obproxy { namespace proxy { +class ObMysqlClient; + +union ObClientFlags +{ + ObClientFlags() : flags_(0) {} + explicit ObClientFlags(uint32_t flag) : flags_(flag) {} + + bool is_skip_autocommit() const { return 1 == client_flags_.OB_CLIENT_SKIP_AUTOCOMMIT; } + bool is_send_request_direct() const { return 1 == client_flags_.OB_CLIENT_SEND_REQUEST_DIRECT; } + + uint32_t flags_; + struct ClinetFlags + { + uint32_t OB_CLIENT_SKIP_AUTOCOMMIT: 1; + uint32_t OB_CLIENT_SEND_REQUEST_DIRECT: 1; + uint32_t OB_CLIENT_FLAG_RESERVED_NOT_USE: 30; + } client_flags_; +}; + class ObMysqlRequestParam { public: ObMysqlRequestParam() : sql_(), is_deep_copy_(false), is_user_idc_name_set_(false), - need_print_trace_stat_(false), current_idc_name_(), target_addr_() {}; + need_print_trace_stat_(false), current_idc_name_(), + target_addr_(), ob_client_flags_(0), mysql_client_(NULL), + is_detect_client_(false) {}; explicit ObMysqlRequestParam(const char *sql) : sql_(sql), is_deep_copy_(false), is_user_idc_name_set_(false), - need_print_trace_stat_(false), current_idc_name_(), target_addr_() {}; + need_print_trace_stat_(false), current_idc_name_(), target_addr_(), + ob_client_flags_(0), mysql_client_(NULL), is_detect_client_(false) {}; ObMysqlRequestParam(const char *sql, const ObString &idc_name) : sql_(sql), is_deep_copy_(false), is_user_idc_name_set_(true), - need_print_trace_stat_(true), current_idc_name_(idc_name), target_addr_() {}; + need_print_trace_stat_(true), current_idc_name_(idc_name), target_addr_(), + ob_client_flags_(0), mysql_client_(NULL), is_detect_client_(false) {}; void reset(); void reset_sql(); void set_target_addr(const common::ObAddr addr) { target_addr_ = addr; } + void set_mysql_client(ObMysqlClient *mysql_client) { mysql_client_ = mysql_client; } + void set_is_detect_client(const bool is_detect_client) { is_detect_client_ = is_detect_client; } bool is_valid() const { return !sql_.empty(); } int deep_copy(const ObMysqlRequestParam &other); int deep_copy_sql(const common::ObString &sql); TO_STRING_KV(K_(sql), K_(is_deep_copy), K_(current_idc_name), K_(is_user_idc_name_set), - K_(need_print_trace_stat), K_(target_addr)); + K_(need_print_trace_stat), K_(target_addr), K(ob_client_flags_.flags_), K_(is_detect_client)); common::ObString sql_; bool is_deep_copy_; @@ -50,6 +76,11 @@ class ObMysqlRequestParam common::ObString current_idc_name_; char current_idc_name_buf_[OB_PROXY_MAX_IDC_NAME_LENGTH]; common::ObAddr target_addr_; + // using flags to affect client_vc acition + // bit 1: whether set autocommit + ObClientFlags ob_client_flags_; + ObMysqlClient* mysql_client_; + bool is_detect_client_; }; class ObClientMysqlResp @@ -153,15 +184,15 @@ inline int ObMysqlResultHandler::get_double(const char *col_name, double &double return (NULL == rs_fetcher_) ? (common::OB_INNER_STAT_ERROR) : (rs_fetcher_->get_double(col_name, double_val)); } -class ObClientReuqestInfo +class ObClientRequestInfo { public: - ObClientReuqestInfo() - : user_name_(), database_name_(), password_(), + ObClientRequestInfo() + : user_name_(), database_name_(), cluster_name_(), password_(), password0_(), password1_(), using_password_num_(-1), request_param_(), name_(NULL), name_len_(0), - need_skip_stage2_(false) {} - ~ObClientReuqestInfo() { reset(); } + need_skip_stage2_(false), password_version_(0) {} + ~ObClientRequestInfo() { reset(); } void reset(); void reset_names(); @@ -173,21 +204,28 @@ class ObClientReuqestInfo int set_names(const common::ObString &user_name, const common::ObString &password, const common::ObString &database_name, + const common::ObString &cluster_name, const common::ObString &password1 = ""); int set_request_param(const ObMysqlRequestParam &request_param); const common::ObString &get_user_name() const { return user_name_; } const common::ObString &get_database_name() const { return database_name_; } - const common::ObString &get_password() const { return password_; } + const common::ObString &get_password(); bool change_password() { bool bret = false; - if (using_password_num_ != -1) { + if (using_password_num_ != -1 && user_name_.prefix_case_match(ObProxyTableInfo::READ_ONLY_USERNAME)) { using_password_num_ = (using_password_num_ + 1) % 2; if (using_password_num_ == 0) { password_ = password0_; + if ('\0' == *password0_.ptr()) { + password_.reset(); + } } else { password_ = password1_; + if ('\0' == *password1_.ptr()) { + password_.reset(); + } } bret = true; } @@ -202,6 +240,7 @@ class ObClientReuqestInfo private: common::ObString user_name_; common::ObString database_name_; + common::ObString cluster_name_; common::ObString password_; common::ObString password0_; common::ObString password1_; @@ -210,8 +249,9 @@ class ObClientReuqestInfo char *name_; int64_t name_len_; bool need_skip_stage2_; + int64_t password_version_; - DISALLOW_COPY_AND_ASSIGN(ObClientReuqestInfo); + DISALLOW_COPY_AND_ASSIGN(ObClientRequestInfo); }; class ObClientUtils @@ -227,7 +267,7 @@ class ObClientUtils const int64_t buf_len, int64_t ©_len); static int build_handshake_response_packet(ObClientMysqlResp *handshake, - ObClientReuqestInfo *info, + ObClientRequestInfo *info, event::ObMIOBuffer *handshake_resp_buf); }; diff --git a/src/obproxy/proxy/client/ob_client_vc.cpp b/src/obproxy/proxy/client/ob_client_vc.cpp index e5935a1f8..8c80d7c31 100644 --- a/src/obproxy/proxy/client/ob_client_vc.cpp +++ b/src/obproxy/proxy/client/ob_client_vc.cpp @@ -18,9 +18,11 @@ #include "proxy/mysql/ob_mysql_client_session.h" #include "obutils/ob_resource_pool_processor.h" #include "proxy/mysql/ob_mysql_sm.h" +#include "utils/ob_proxy_table_define.h" using namespace oceanbase::common; using namespace oceanbase::obmysql; +using namespace oceanbase::obproxy; using namespace oceanbase::obproxy::event; using namespace oceanbase::obproxy::packet; using namespace oceanbase::obproxy::obutils; @@ -43,7 +45,7 @@ static int64_t const RESCHEDULE_GET_NETHANDLER_LOCK_INTERVAL = HRTIME_MSECONDS(1 ObClientVC::ObClientVC(ObMysqlClient &client_core) : ObNetVConnection(), magic_(CLIENT_MAGIC_ALIVE), disconnect_by_client_(false), - is_request_sent_(false), is_resp_received_(false), core_client_(&client_core), + is_request_sent_(false), core_client_(&client_core), pending_action_(NULL), read_state_(), write_state_(), addr_() { SET_HANDLER(&ObClientVC::main_handler); @@ -82,9 +84,8 @@ int ObClientVC::main_handler(int event, void *data) } case CLIENT_INFORM_MYSQL_CLIENT_TRANSFER_RESP_EVENT: { pending_action_ = NULL; - // notify ObMysqlClient to read mysql response - if (NULL != core_client_) { - core_client_->handle_event(VC_EVENT_READ_READY, &write_state_.vio_); + if (OB_FAIL(transfer_bytes())) { + LOG_ERROR("fail to transfer bytes", K(ret)); } break; } @@ -177,7 +178,6 @@ void ObClientVC::do_io_close(const int lerrno) } is_request_sent_ = false; - is_resp_received_ = false; if (NULL != core_client_ && !disconnect_by_client_) { core_client_->handle_event(CLIENT_VC_DISCONNECT_EVENT, NULL); @@ -195,21 +195,17 @@ void ObClientVC::reenable_re(ObVIO *vio) read_avail = reader->read_avail(); } _LOG_DEBUG("client_vc reenable_re %s, read_avail=%ld, reader=%p, thread=%p, " - "is_request_sent=%d, is_resp_received=%d", + "is_request_sent=%d", (ObVIO::WRITE == vio->op_) ? "Write" : "Read", read_avail, - reader, this_ethread(), is_request_sent_, is_resp_received_); + reader, this_ethread(), is_request_sent_); if (ObVIO::WRITE == vio->op_) { // write_vio - if (NULL != core_client_) { - if (read_avail > 0 && !is_resp_received_) { - int ret = OB_SUCCESS; - if (OB_ISNULL(pending_action_ = mutex_->thread_holding_->schedule_imm( - this, CLIENT_INFORM_MYSQL_CLIENT_TRANSFER_RESP_EVENT))) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("fail to schedule imm", K(ret)); - } else { - is_resp_received_ = true; - } + if (NULL != core_client_ && NULL == pending_action_ && read_avail > 0) { + int ret = OB_SUCCESS; + if (OB_ISNULL(pending_action_ = mutex_->thread_holding_->schedule_imm( + this, CLIENT_INFORM_MYSQL_CLIENT_TRANSFER_RESP_EVENT))) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("fail to schedule imm", K(ret)); } } } else if (ObVIO::READ == vio->op_) { // read_vio @@ -217,8 +213,7 @@ void ObClientVC::reenable_re(ObVIO *vio) if (!is_request_sent_) { if (addr_.is_valid()) { ObMysqlSM *sm = reinterpret_cast(read_state_.vio_.cont_); - sm->trans_state_.server_info_.set_addr(addr_.get_ipv4(), - static_cast(addr_.get_port())); + sm->trans_state_.server_info_.set_addr(net::ops_ip_sa_cast(addr_.get_sockaddr())); sm->trans_state_.force_retry_congested_ = true; sm->trans_state_.need_retry_ = false; } @@ -231,10 +226,59 @@ void ObClientVC::reenable_re(ObVIO *vio) } } +int ObClientVC::transfer_bytes() +{ + int ret = OB_SUCCESS; + + // Check the state of our write buffer as well as ntodo + ObVIO &vio = write_state_.vio_; + int64_t ntodo = vio.ntodo(); + ObIOBufferReader *reader = vio.get_reader(); + if (OB_ISNULL(reader)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to get reader", K(ret)); + } else { + int64_t bytes_avail = reader->read_avail(); + int64_t act_on = MIN(bytes_avail, ntodo); + int64_t total_added = 0; + ObMIOBuffer *transfer_to = core_client_->get_client_buf(); + + if (act_on <= 0) { + ret = OB_INVALID_ARGUMENT; + _LOG_WARN("act on data can not <= 0, avail=%ld, ntodo=%ld, " + "act_on=%ld, ret=%d", bytes_avail, ntodo, act_on, ret); + } else if (OB_ISNULL(transfer_to)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("resp buffer can not be NULL", K(transfer_to), K(ret)); + } else if (OB_FAIL(transfer_to->write(reader, act_on, total_added, 0)) + || act_on != total_added) { + LOG_WARN("failed to transfer data from iobuffer reader to iobfer", + K(act_on), K(total_added), K(ret)); + } else if (OB_FAIL(reader->consume(total_added))) { + LOG_WARN("fail to consume", K(total_added), K(ret)); + } else { + vio.ndone_ += total_added; + LOG_DEBUG("transfer_bytes succ", "ndone", vio.ndone_, "nbytes", vio.nbytes_); + if (write_state_.vio_.ntodo() > 0) { + if (NULL != write_state_.vio_.cont_) { + write_state_.vio_.cont_->handle_event(VC_EVENT_WRITE_READY, &write_state_.vio_); + } + } else { + // notify ObMysqlClient to read mysql response + if (NULL != core_client_) { + core_client_->handle_event(VC_EVENT_READ_READY, &write_state_.vio_); + } + } + } + } + + return ret; +} + ObMysqlClient::ObMysqlClient() : ObContinuation(), magic_(CLIENT_MAGIC_ALIVE), reentrancy_count_(0), terminate_(false), is_inited_(false), in_use_(false), is_request_complete_(false), use_short_connection_(false), - client_vc_(NULL), pool_(NULL), + client_vc_(NULL), pool_(NULL), cr_(NULL), active_timeout_action_(NULL), common_mutex_(), action_(), active_timeout_ms_(0), next_action_(CLIENT_ACTION_UNDEFINED), request_buf_(NULL), request_reader_(NULL), mysql_resp_(NULL), info_(), is_session_pool_client_(false), @@ -248,6 +292,7 @@ int ObMysqlClient::init(ObMysqlClientPool *pool, const ObString &password, const ObString &database, const bool is_meta_mysql_client, + const ObString &cluster_name, const ObString &password1, ClientPoolOption* client_pool_option) { @@ -262,8 +307,8 @@ int ObMysqlClient::init(ObMysqlClientPool *pool, } else if (OB_ISNULL(mutex = new_proxy_mutex(CLIENT_VC_LOCK))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to allocate mutex", K(ret)); - } else if (OB_FAIL(info_.set_names(user_name, password, database, password1))) { - LOG_WARN("fail to set names", K(user_name), K(password), K(database), K(ret)); + } else if (OB_FAIL(info_.set_names(user_name, password, database, cluster_name, password1))) { + LOG_WARN("fail to set names", K(user_name), K(password), K(database), K(cluster_name), K(ret)); } else { if (client_pool_option != NULL) { info_.set_need_skip_stage2(client_pool_option->need_skip_stage2_); @@ -282,6 +327,31 @@ int ObMysqlClient::init(ObMysqlClientPool *pool, return ret; } +int ObMysqlClient::init_detect_client(ObClusterResource *cr) +{ + int ret = OB_SUCCESS; + ObProxyMutex *mutex = NULL; + ObString password(get_global_proxy_config().observer_sys_password.str()); + if (OB_UNLIKELY(is_inited_ ||NULL == cr)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K_(is_inited), K(ret)); + } else if (OB_ISNULL(mutex = new_proxy_mutex(CLIENT_VC_LOCK))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate mutex", K(ret)); + } else if (OB_FAIL(info_.set_names(ObProxyTableInfo::DETECT_USERNAME_USER, password, "obproxy", "obproxy"))) { + LOG_WARN("fail to set names", K(ret)); + } else { + common_mutex_ = mutex; + mutex_ = common_mutex_; + next_action_ = CLIENT_ACTION_CONNECT; + cr->inc_ref(); + cr_ = cr; + is_inited_ = true; + use_short_connection_ = true; + } + return ret; +} + int ObMysqlClient::post_request( ObContinuation *cont, const ObMysqlRequestParam &request_param, @@ -378,7 +448,7 @@ int ObMysqlClient::post_request( mysql_resp_ = NULL; } action = NULL; - release(); + release(false); } return ret; @@ -439,12 +509,7 @@ int ObMysqlClient::main_handler(int event, void *data) } } - --reentrancy_count_; - if (OB_UNLIKELY(reentrancy_count_ < 0)) { - LOG_ERROR("invalid reentrancy_count", K_(reentrancy_count), K(this)); - } - - if (0 == reentrancy_count_) { + if (1 == reentrancy_count_) { // here common_mutex_ is free or held by this thread, so we can ensure lock it MUTEX_LOCK(lock, common_mutex_, this_ethread()); if (OB_SUCCESS == ret && need_connect_retry_ && CLIENT_ACTION_CONNECT == next_action_) { @@ -465,6 +530,11 @@ int ObMysqlClient::main_handler(int event, void *data) if (OB_SUCC(ret)) { do_post_request(); } + + --reentrancy_count_; + if (OB_UNLIKELY(reentrancy_count_ < 0)) { + LOG_ERROR("invalid reentrancy_count", K_(reentrancy_count), K(this)); + } } else { if (is_request_complete_) { if (OB_FAIL(handle_request_complete())) { @@ -475,9 +545,20 @@ int ObMysqlClient::main_handler(int event, void *data) if (terminate_) { kill_this(); he_ret = EVENT_DONE; + } else { + --reentrancy_count_; + if (OB_UNLIKELY(reentrancy_count_ < 0)) { + LOG_ERROR("invalid reentrancy_count", K_(reentrancy_count), K(this)); + } } } + } else { + --reentrancy_count_; + if (OB_UNLIKELY(reentrancy_count_ < 0)) { + LOG_ERROR("invalid reentrancy_count", K_(reentrancy_count), K(this)); + } } + return he_ret; } @@ -537,7 +618,7 @@ int ObMysqlClient::handle_request_complete() } } - release(); + release(true); if (need_callback) { cont->handle_event(CLIENT_TRANSPORT_MYSQL_RESP_EVENT, mysql_resp); } @@ -723,7 +804,9 @@ int ObMysqlClient::do_next_action(void *data) break; } case CLIENT_ACTION_READ_LOGIN_RESP: { - if (OB_FAIL(transfer_and_analyze_response(vio, OB_MYSQL_COM_LOGIN))) { + if (info_.get_request_param().is_detect_client_) { + is_request_complete_ = true; + } else if (OB_FAIL(transfer_and_analyze_response(vio, OB_MYSQL_COM_LOGIN))) { LOG_WARN("fail to transfer and analyze resposne", K(ret)); } else if (!mysql_resp_->is_resp_completed()) { ret = OB_ERR_UNEXPECTED; @@ -735,6 +818,12 @@ int ObMysqlClient::do_next_action(void *data) if (OB_FAIL(transport_mysql_resp())) { LOG_WARN("fail to transfrom mysql resp", K(ret)); } + } else if (info_.get_request_param().ob_client_flags_.is_skip_autocommit()) { + if (OB_FAIL(setup_read_normal_resp())) { + LOG_WARN("fail to setup read normal resp", K(ret)); + } else if (OB_FAIL(forward_mysql_request())) { + LOG_WARN("fail to schedule post request", K(ret)); + } } else { retry_times_ = 0; if (OB_FAIL(setup_read_autocommit_resp())) { @@ -797,61 +886,19 @@ int ObMysqlClient::do_next_action(void *data) int ObMysqlClient::transfer_and_analyze_response(ObVIO &vio, const obmysql::ObMySQLCmd cmd) { int ret = OB_SUCCESS; - // Check the state of our write buffer as well as ntodo - int64_t ntodo = vio.ntodo(); - ObIOBufferReader *reader = vio.get_reader(); - if (OB_ISNULL(reader)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("fail to get reader", K(ret)); - } else { - int64_t bytes_avail = reader->read_avail(); - int64_t act_on = MIN(bytes_avail, ntodo); - int64_t added = 0; - ObMIOBuffer *transfer_to = mysql_resp_->get_resp_miobuf(); - if (act_on <= 0) { - ret = OB_INVALID_ARGUMENT; - _LOG_WARN("act on data can not <= 0, avail=%ld, ntodo=%ld, " - "act_on=%ld, ret=%d", bytes_avail, ntodo, act_on, ret); - } else if (OB_ISNULL(transfer_to)) { + if (vio.ndone_ == vio.nbytes_) { + LOG_DEBUG("transfer_and_analyze_response"); + if (OB_FAIL(mysql_resp_->analyze_resp(cmd))) { + LOG_WARN("fail to analyze_trans_response", K(ret)); + } else if (!mysql_resp_->is_resp_completed()) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("resp buffer can not be NULL", K(transfer_to), K(ret)); - } else if (OB_FAIL(transfer_bytes(*transfer_to, *reader, act_on, added))) { - LOG_WARN("fail to transfer_bytes", K(ret)); - } else { - vio.ndone_ += added; - LOG_DEBUG("transfer_bytes succ", "ndone", vio.ndone_, "nbytes", vio.nbytes_); - if (vio.ndone_ == vio.nbytes_) { - LOG_DEBUG("transder_and_analyze_response", K(added)); - if (OB_FAIL(mysql_resp_->analyze_resp(cmd))) { - LOG_WARN("fail to analyze_trans_response", K(ret)); - } else if (!mysql_resp_->is_resp_completed()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("mysql response must be received completed here", K(ret)); - } - } else { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ndone should be equal to nbytes", - K_(vio.ndone), K_(vio.nbytes), K(ret)); - } + LOG_WARN("mysql response must be received completed here", K(ret)); } - } - - return ret; -} - -int ObMysqlClient::transfer_bytes(ObMIOBuffer &transfer_to, - ObIOBufferReader &transfer_from, - const int64_t act_on, int64_t &total_added) -{ - int ret = OB_SUCCESS; - - if (OB_FAIL(transfer_to.write(&transfer_from, act_on, total_added, 0)) - || act_on != total_added) { - LOG_WARN("failed to transfer data from iobuffer reader to iobfer", - K(act_on), K(total_added), K(ret)); - } else if (OB_FAIL(transfer_from.consume(total_added))) { - LOG_WARN("fail to consume", K(total_added), K(ret)); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ndone should be equal to nbytes", + K_(vio.ndone), K_(vio.nbytes), K(ret)); } return ret; @@ -864,7 +911,6 @@ int ObMysqlClient::forward_mysql_request() if (request_reader_->read_avail() > 0) { client_vc_->clear_request_sent(); - client_vc_->clear_resp_received(); client_vc_->reenable_read(); } @@ -1010,7 +1056,13 @@ int ObMysqlClient::do_new_connection_with_cr(ObMysqlClientSession *client_sessio { int ret = OB_SUCCESS; - ObClusterResource *cr = pool_->acquire_cluster_resource(); // inc ref + ObClusterResource *cr = NULL; + if (NULL != cr_) { + cr_->inc_ref(); + cr = cr_; + } else { + cr = pool_->acquire_cluster_resource(); // inc ref + } LOG_DEBUG("new connection", K(cr), KPC(cr)); if (OB_ISNULL(cr)) { ret = OB_ERR_UNEXPECTED; @@ -1039,6 +1091,10 @@ int ObMysqlClient::setup_read_handshake() } else { client_vc_->mutex_ = mutex_; client_session->set_proxy_mysql_client(); + if (info_.get_request_param().ob_client_flags_.is_send_request_direct()) { + client_session->set_can_send_request(); + client_session->is_need_update_dummy_entry_ = true; + } client_session->set_session_pool_client(is_session_pool_client_); if (is_session_pool_client_) { // client_session->set_is_dbmesh_user(false); @@ -1048,10 +1104,9 @@ int ObMysqlClient::setup_read_handshake() client_session->set_server_addr(server_addr_); client_session->set_first_dml_sql_got(); client_session->inner_request_param_ = &info_.get_request_param(); - client_vc_->clear_resp_received(); next_action_ = CLIENT_ACTION_READ_HANDSHAKE; - if (pool_->is_cluster_param()) { + if ((NULL != pool_ && pool_->is_cluster_param()) || NULL != cr_) { if (OB_FAIL(do_new_connection_with_cr(client_session))) { LOG_WARN("fail to new connection with cr", K(ret)); } @@ -1079,9 +1134,9 @@ int ObMysqlClient::setup_read_handshake() return ret; } -void ObMysqlClient::release() +void ObMysqlClient::release(bool is_need_check_reentry) { - if (OB_LIKELY(0 == reentrancy_count_) && OB_LIKELY(!terminate_)) { + if (OB_LIKELY(!is_need_check_reentry || 1 == reentrancy_count_) && OB_LIKELY(!terminate_)) { int ret = OB_SUCCESS; if (OB_FAIL(cancel_active_timeout())) { LOG_ERROR("fail to cancel timeout action," @@ -1089,9 +1144,11 @@ void ObMysqlClient::release() } else { // for defense, make sure client vc's mutex is common mutex when release to client pool; // Never free client vc in mysql client, it will be free by mysql_sm - if (NULL != client_vc_ && client_vc_->mutex_ != common_mutex_) { + if (!info_.get_request_param().is_detect_client_ && NULL != client_vc_ && client_vc_->mutex_ != common_mutex_) { client_vc_->handle_event(CLIENT_VC_SWAP_MUTEX_EVENT, common_mutex_.ptr_); - client_vc_->mutex_ = common_mutex_; + if (NULL != client_vc_) { + client_vc_->mutex_ = common_mutex_; + } } action_.set_continuation(NULL); action_.cancelled_ = false; @@ -1101,7 +1158,9 @@ void ObMysqlClient::release() in_use_ = false; is_request_complete_ = false; mutex_ = common_mutex_; // when idle, keep common_mutex_ - pool_->release_mysql_client(this); + if (NULL != pool_) { + pool_->release_mysql_client(this); + } } } } @@ -1130,6 +1189,11 @@ void ObMysqlClient::kill_this() pool_ = NULL; } + if (NULL != cr_) { + cr_->dec_ref(); + cr_ = NULL; + } + is_inited_ = false; in_use_ = false; use_short_connection_ = false; @@ -1156,7 +1220,7 @@ void ObMysqlClient::kill_this() int ObMysqlClient::alloc(ObMysqlClientPool *pool, ObMysqlClient *&client, const ObString &user_name, const ObString &password, - const ObString &database, const bool is_meta_mysql_client, + const ObString &database, const bool is_meta_mysql_client, const ObString &cluster_name, const ObString &password1, ClientPoolOption* client_pool_option) { int ret = OB_SUCCESS; @@ -1164,7 +1228,7 @@ int ObMysqlClient::alloc(ObMysqlClientPool *pool, ObMysqlClient *&client, if (OB_ISNULL(client = op_alloc(ObMysqlClient))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to allocate ObMysqlClient", K(ret)); - } else if (OB_FAIL(client->init(pool, user_name, password, database, is_meta_mysql_client, password1, client_pool_option))) { + } else if (OB_FAIL(client->init(pool, user_name, password, database, is_meta_mysql_client, cluster_name, password1, client_pool_option))) { LOG_WARN("fail to init client", K(ret)); } if (OB_FAIL(ret) && (NULL != client)) { diff --git a/src/obproxy/proxy/client/ob_client_vc.h b/src/obproxy/proxy/client/ob_client_vc.h index 9ccf8c466..195603231 100644 --- a/src/obproxy/proxy/client/ob_client_vc.h +++ b/src/obproxy/proxy/client/ob_client_vc.h @@ -80,6 +80,7 @@ class ObClientVC : public net::ObNetVConnection virtual void reenable(event::ObVIO *vio) { reenable_re(vio); } virtual void reenable_re(event::ObVIO *vio); void reenable_read() { reenable_re(&read_state_.vio_); } + int transfer_bytes(); // Timeouts virtual int set_active_timeout(ObHRTime timeout_in) { UNUSED(timeout_in); return 0; } @@ -101,14 +102,12 @@ class ObClientVC : public net::ObNetVConnection virtual int apply_options() { return 0; } void clear_request_sent() { is_request_sent_ = false; } - void clear_resp_received() { is_resp_received_ = false; } void set_addr(const common::ObAddr &addr) { addr_ = addr; } private: uint32_t magic_; bool disconnect_by_client_; // dissconnect by received VC_EVENT_EOS, sent by ObMysqlClient bool is_request_sent_; // used to inform client session read request only once - bool is_resp_received_; // used to inform mysql client read resp onely once ObMysqlClient *core_client_; event::ObAction *pending_action_; @@ -142,6 +141,7 @@ class ObMysqlClient : public event::ObContinuation const common::ObString &password, const common::ObString &database, const bool is_meta_mysql_client, + const common::ObString &cluster_name = "", const common::ObString &password1 = "", ClientPoolOption* client_pool_option = NULL); @@ -150,9 +150,12 @@ class ObMysqlClient : public event::ObContinuation const common::ObString &password, const common::ObString &database, const bool is_meta_mysql_client, + const common::ObString &cluster_name = "", const common::ObString &password1 = "", ClientPoolOption* client_pool_option = NULL); + int init_detect_client(obutils::ObClusterResource *cr); + // must be used under the mutex_'s lock bool is_avail() const { return !in_use_; } @@ -167,6 +170,8 @@ class ObMysqlClient : public event::ObContinuation static const char *get_client_event_name(const int64_t event); event::ObProxyMutex *get_common_mutex() { return common_mutex_.ptr_; } + void kill_this(); + event::ObMIOBuffer *get_client_buf() { return mysql_resp_->get_resp_miobuf(); } private: static const char *get_client_action_name(const ObClientActionType type); @@ -174,8 +179,6 @@ class ObMysqlClient : public event::ObContinuation int do_post_request(); int do_next_action(void *data); int transfer_and_analyze_response(event::ObVIO &vio, const obmysql::ObMySQLCmd cmd); - int transfer_bytes(event::ObMIOBuffer &transfer_to, event::ObIOBufferReader &transfer_from, - const int64_t act_on, int64_t &added); int notify_transfer_completed(); @@ -187,7 +190,6 @@ class ObMysqlClient : public event::ObContinuation int setup_read_normal_resp(); bool is_in_auth() const; int transport_mysql_resp(); - void kill_this(); int handle_client_vc_disconnect(); int forward_mysql_request(); @@ -196,7 +198,7 @@ class ObMysqlClient : public event::ObContinuation int handle_active_timeout(); int handle_request_complete(); - void release(); + void release(bool is_need_check_reentry); public: SLINK(ObMysqlClient, link_); @@ -215,6 +217,8 @@ class ObMysqlClient : public event::ObContinuation bool use_short_connection_; ObClientVC *client_vc_; ObMysqlClientPool *pool_; + // in some situtaion, we can create obmysql client without ClientPool + obutils::ObClusterResource *cr_; event::ObAction *active_timeout_action_; common::ObPtr common_mutex_; @@ -227,7 +231,7 @@ class ObMysqlClient : public event::ObContinuation event::ObIOBufferReader *request_reader_; ObClientMysqlResp *mysql_resp_; - ObClientReuqestInfo info_; + ObClientRequestInfo info_; bool is_session_pool_client_; ObProxySchemaKey schema_key_; diff --git a/src/obproxy/proxy/client/ob_driver_client.cpp b/src/obproxy/proxy/client/ob_driver_client.cpp new file mode 100644 index 000000000..29d1711fd --- /dev/null +++ b/src/obproxy/proxy/client/ob_driver_client.cpp @@ -0,0 +1,375 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + * + * ************************************************************* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "proxy/client/ob_driver_client.h" +#include "proxy/mysql/ob_mysql_client_session.h" +#include "iocore/eventsystem/ob_action.h" +#include "iocore/net/ob_socket_manager.h" + +using namespace oceanbase::common; +using namespace oceanbase::obproxy::event; +using namespace oceanbase::obproxy::net; + +#define SET_NONBLOCKING(fd) { \ + int tmp_ret = OB_SUCCESS; \ + int flags = fcntl(fd, F_GETFL); \ + int res = -1; \ + flags |= O_NONBLOCK; \ + if (OB_SUCCESS != (tmp_ret = ObSocketManager::fcntl(fd, F_SETFL, flags, res))) { \ + OBPROXY_DRIVER_CLIENT_LOG(WARN, "fail to set nonblocking", K(tmp_ret), K(errno), K(strerror(errno))); \ + if (OB_SUCCESS == ret) { \ + ret = tmp_ret; \ + } \ + } \ +} + +#define SET_BLOCKING(fd) { \ + int tmp_ret = OB_SUCCESS; \ + int flags = fcntl(fd, F_GETFL); \ + int res = -1; \ + flags &= ~O_NONBLOCK; \ + if (OB_SUCCESS != (tmp_ret = ObSocketManager::fcntl(fd, F_SETFL, flags, res))) { \ + OBPROXY_DRIVER_CLIENT_LOG(WARN, "fail to set blocking", K(ret), K(errno), K(strerror(errno))); \ + if (OB_SUCCESS == ret) { \ + ret = tmp_ret; \ + } \ + } \ +} + +namespace oceanbase +{ +namespace obproxy +{ +namespace proxy +{ + +ObDriverClient::ObDriverClient() : is_inited_(false), unix_fd_(-1), connect_timeout_(0), recv_timeout_(0), send_timeout_(0), cs_id_(-1) +{ +} + +ObDriverClient::~ObDriverClient() +{ + destroy(); +} + +void ObDriverClient::destroy() +{ + is_inited_ = false; + if (unix_fd_ != -1) { + close(unix_fd_); + unix_fd_ = -1; + } + connect_timeout_ = 0; + send_timeout_ = 0; + recv_timeout_ = 0; + cs_id_ = -1; +} + +int ObDriverClient::init() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "driver client init twice", K(this), K(ret)); + } else if (OB_FAIL(ObSocketManager::socket(AF_UNIX, SOCK_STREAM, 0, unix_fd_))) { + OBPROXY_DRIVER_CLIENT_LOG(ERROR, "dirver client create socket failed", K(this), K(ret)); + } else { + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "init driver client", K(this), K_(cs_id)); + is_inited_ = true; + } + return ret; +} + +int ObDriverClient::sync_connect() +{ + int ret = OB_SUCCESS; + struct sockaddr_un addr; + addr.sun_family = AF_UNIX; + memset(addr.sun_path, 0, sizeof(addr.sun_path)); + strncpy(addr.sun_path, get_global_layout().get_unix_domain_path(), sizeof(addr.sun_path) - 1); + if (OB_FAIL(ObSocketManager::connect(unix_fd_, (struct sockaddr*)&addr, sizeof(addr)))) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "driver client connect unix domain failed", K(this), K(errno), K(ret)); + } else { + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "driver client connect success" , K(this)); + } + return ret; +} + +int ObDriverClient::sync_connect_with_timeout() +{ + int ret = OB_SUCCESS; + if (connect_timeout_ < 0) { + ret = OB_ERR_UNEXPECTED; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "connect timeout value unexpected", K(connect_timeout_), K(ret)); + } else if (connect_timeout_ == 0) { + ret = sync_connect(); + } else { + int64_t timeout = connect_timeout_; + struct sockaddr_un addr; + addr.sun_family = AF_UNIX; + memset(addr.sun_path, 0, sizeof(addr.sun_path)); + strncpy(addr.sun_path, get_global_layout().get_unix_domain_path(), sizeof(addr.sun_path) - 1); + SET_NONBLOCKING(unix_fd_); + + int connect_rv = 0; + while (OB_SUCC(ret)) { + connect_rv = connect(unix_fd_, (struct sockaddr*)&addr, sizeof(addr)); + if (connect_rv < 0) { + int64_t prev_time = get_current_time(); + if (errno != EINPROGRESS && errno != EWOULDBLOCK && errno != EAGAIN) { + ret = ob_get_sys_errno(); + OBPROXY_DRIVER_CLIENT_LOG(WARN, "connect failed", K(ret)); + } else if (errno == EWOULDBLOCK || errno == EAGAIN) { + // The unix socket encounters the above socket sleep 1ms to prevent it from being called all the time. + // Refer to https://stackoverflow.com/questions/48222690/set-connect-timeout-on-unix-domain-socket + usleep(1000); + int64_t new_time = get_current_time(); + timeout -= (new_time - prev_time); + prev_time = new_time; + if (timeout <= 0) { + ret = OB_TIMEOUT; + OBPROXY_DRIVER_CLIENT_LOG(WARN ,"connect timeout", K_(connect_timeout), K(ret)); + } + } else if (errno == EINPROGRESS) { + while (OB_SUCC(ret)) { + struct pollfd pfd; + pfd.fd = unix_fd_; + pfd.events = POLLOUT; + connect_rv = poll(&pfd, 1, static_cast(timeout)); + if (connect_rv > 0) { + break; + } else if (connect_rv == 0) { + ret = OB_TIMEOUT; + OBPROXY_DRIVER_CLIENT_LOG(WARN ,"connect timeout", K_(connect_timeout), K(ret)); + } else { + if (errno != EINTR) { + ret = ob_get_sys_errno(); + OBPROXY_DRIVER_CLIENT_LOG(WARN, "poll failed", K(ret)); + } else { + int64_t new_time = get_current_time(); + timeout -= (new_time - prev_time); + prev_time = new_time; + if (timeout <= 0) { + ret = OB_TIMEOUT; + OBPROXY_DRIVER_CLIENT_LOG(WARN ,"connect timeout", K_(connect_timeout), K(ret)); + } + } + } + } + if (OB_SUCC(ret) && connect_rv > 0) { + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "connect with timeout success", K_(connect_timeout), K(ret)); + break; + } + } + } else { + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "connect with timeout success", K_(connect_timeout), K(ret)); + break; + } + } + SET_BLOCKING(unix_fd_); + } + + return ret; +} + +int ObDriverClient::sync_recv_internal(char *buf, int64_t buf_len, int64_t &recv_len, int recv_flags) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(NULL == buf || 0 >= buf_len)) { + ret = OB_ERR_UNEXPECTED; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "buf is null or len is invalid", K(buf_len), K(this), K_(cs_id), K(ret)); + } else { + + do { + recv_len = recv(unix_fd_, buf, buf_len, recv_flags); + } while (recv_len == -1 && EINTR == errno); + + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "sync_recv_internal recv finish", K(recv_len), K(errno)); + + if (EAGAIN == errno || EWOULDBLOCK == errno) { + // will call this func again, do nothing + } else if (-1 == recv_len) { + ret = ob_get_sys_errno(); + OBPROXY_DRIVER_CLIENT_LOG(WARN, "recv failed", K(ret), KP(buf), K(buf_len), K(recv_len), K(recv_flags)); + } else { + // success, do nothing + } + } + + return ret; +} + +int ObDriverClient::sync_wait_io_or_timeout(bool is_recv) +{ + int ret = OB_SUCCESS; + struct pollfd pfd; + int rv = 0; + int64_t timeout = 0; + int64_t prev_time = get_current_time(); + int64_t new_time = 0; + + memset(&pfd, 0, sizeof(pfd)); + pfd.fd = unix_fd_; + if (is_recv) { + timeout = recv_timeout_ <= 0 ? -1 : recv_timeout_; + pfd.events = POLLIN | POLLERR; + } else { + timeout = send_timeout_ <= 0 ? -1 : send_timeout_; + pfd.events = POLLOUT; + } + + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "sync_wait_io_or_timeout call poll", K(is_recv), K(timeout)); + + do { + // Prevent continuous interruptions, resulting in waiting + if (timeout > 0) { + new_time = get_current_time(); + timeout -= new_time - prev_time; + if (timeout < 0) { + timeout = 0; + } + prev_time = new_time; + } + rv = poll(&pfd, 1, static_cast(timeout)); + } while (rv == -1 && errno == EINTR); + + if (rv < 0) { + ret = ob_get_sys_errno(); + OBPROXY_DRIVER_CLIENT_LOG(WARN, "poll error", K(ret)); + } else if (rv == 0) { + ret = OB_TIMEOUT; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "poll timeout", K(timeout), K(ret)); + } else { + // recv >= 0 , do nothing + } + + return ret; +} + +int ObDriverClient::sync_recv_with_timeout(char *buf, int64_t buf_len, int64_t &recv_len) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(NULL == buf || 0 >= buf_len)) { + ret = OB_ERR_UNEXPECTED; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "buf is null or len is invalid", K(buf_len), K(this), K_(cs_id), K(ret)); + } else { + int recv_flags= MSG_DONTWAIT; + recv_len = -1; + + while (OB_SUCC(ret) && -1 == recv_len) { + if (OB_FAIL(sync_recv_internal(buf, buf_len, recv_len, recv_flags))) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "fail to call sync_recv_internal", K(buf_len), K(recv_len), K(ret)); + } else if (-1 == recv_len && OB_FAIL(sync_wait_io_or_timeout(true))) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "fail to call sync_wait_io_or_timeout", K(ret)); + } else { + // do nothing + } + } + + if (OB_FAIL(ret)) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "driver client recv failed", K(this), K(recv_len), K(recv_flags), K_(cs_id), K_(unix_fd), K(ret)); + } + + } + + return ret; +} + +int ObDriverClient::sync_send_internal(const char *buf, int64_t buf_len, int64_t &send_len, int send_flags) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(NULL == buf || 0 >= buf_len)) { + ret = OB_ERR_UNEXPECTED; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "buf is null or len is invalid", K(buf_len), K(this), K_(cs_id), K(ret)); + } else { + + do { + send_len = send(unix_fd_, buf, buf_len, send_flags); + } while (send_len == -1 && EINTR == errno); + + OBPROXY_DRIVER_CLIENT_LOG(DEBUG, "sync_send_internal send finish", K(send_len), K(errno)); + + if (EAGAIN == errno || EWOULDBLOCK == errno) { + // will call this func again, do nothing + } else if (-1 == send_len) { + ret = ob_get_sys_errno(); + OBPROXY_DRIVER_CLIENT_LOG(WARN, "send failed", K(ret), KP(buf), K(buf_len), K(send_len), K(send_flags)); + } else { + // success, do nothing + } + } + + return ret; +} + +int ObDriverClient::sync_send_with_timeout(const char *buf, int64_t buf_len, int64_t &send_len) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(NULL == buf || 0 >= buf_len)) { + ret = OB_ERR_UNEXPECTED; + OBPROXY_DRIVER_CLIENT_LOG(WARN, "buf is null or len is invalid", K(buf_len), K(this), K_(cs_id), K(ret)); + } else { + int send_flags = MSG_DONTWAIT | MSG_NOSIGNAL; + send_len = -1; + + while (OB_SUCC(ret) && -1 == send_len) { + if (OB_FAIL(sync_send_internal(buf, buf_len, send_len, send_flags))) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "fail to call sync_send_internal", K(buf_len), K(send_len), K(ret)); + } else if (-1 == send_len && OB_FAIL(sync_wait_io_or_timeout(false))) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "fail to call sync_wait_io_or_timeout", K(ret)); + } else { + // do nothing + } + } + + if (OB_FAIL(ret)) { + OBPROXY_DRIVER_CLIENT_LOG(WARN, "driver client send failed", K(this), K(send_len), K(send_flags), K_(cs_id), K_(unix_fd), K(ret)); + } + + } + + return ret; +} + +int64_t ObDriverClient::get_current_time() +{ + timeval tv; + gettimeofday(&tv, NULL); + int64_t current_time = tv.tv_sec * 1000 + tv.tv_usec / 1000; + return current_time; +} + +} // end of proxy +} // end of obproxy +} // end of oceanbase diff --git a/src/obproxy/proxy/client/ob_driver_client.h b/src/obproxy/proxy/client/ob_driver_client.h new file mode 100644 index 000000000..0e345c463 --- /dev/null +++ b/src/obproxy/proxy/client/ob_driver_client.h @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + * + * ************************************************************* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OB_DRIVER_CLIENT_H_ +#define OB_DRIVER_CLIENT_H_ + +#include "proxy/client/ob_client_utils.h" +#include "iocore/net/ob_net_vconnection.h" +#include "iocore/eventsystem/ob_ethread.h" + +namespace oceanbase +{ +namespace obproxy +{ +namespace proxy +{ + +class ObDriverClient +{ +public: + ObDriverClient(); + virtual ~ObDriverClient(); + int init(); + int sync_connect(); + int sync_connect_with_timeout(); + int sync_recv_with_timeout(char *buf, int64_t buf_len, int64_t &recv_len); + int sync_send_with_timeout(const char *buf, int64_t buf_len, int64_t &send_len); + inline void set_connect_timeout(const int64_t timeout) { connect_timeout_ = timeout; } + inline void set_cs_id(const int64_t cs_id) { cs_id_ = cs_id; } + void destroy(); + + int64_t get_connect_timeout() const { return connect_timeout_; } + int64_t get_recv_timeout() const { return recv_timeout_; } + void set_recv_timeout(const int64_t timeout) { recv_timeout_ = timeout; } + int64_t get_send_timeout() const { return send_timeout_; } + void set_send_timeout(const int64_t timeout) { send_timeout_ = timeout; } + +private: + inline int64_t get_current_time(); + int sync_recv_internal(char *buf, int64_t buf_len, int64_t &recv_len, int recv_flags); + int sync_send_internal(const char *buf, int64_t buf_len, int64_t &send_len, int send_flags); + int sync_wait_io_or_timeout(bool is_recv); + +private: + bool is_inited_; + int unix_fd_; + int64_t connect_timeout_; + int64_t recv_timeout_; + int64_t send_timeout_; + int64_t cs_id_; +private: +DISALLOW_COPY_AND_ASSIGN(ObDriverClient); +}; + +} // end of namespace proxy +} // end of namespace obproxy +} // end of namespace oceanbase + +#endif diff --git a/src/obproxy/proxy/client/ob_mysql_client_pool.cpp b/src/obproxy/proxy/client/ob_mysql_client_pool.cpp index 99ba5d7bf..423b2904f 100644 --- a/src/obproxy/proxy/client/ob_mysql_client_pool.cpp +++ b/src/obproxy/proxy/client/ob_mysql_client_pool.cpp @@ -158,6 +158,7 @@ int ObMysqlClientPool::init( const ObString &user_name, const ObString &password, const ObString &database, + const ObString &cluster_name, const ObString &password1, ClientPoolOption* client_pool_option) { @@ -175,7 +176,8 @@ int ObMysqlClientPool::init( ObMysqlClient *mysql_client = NULL; const int64_t mc_count = get_mysql_client_pool_count(is_meta_mysql_client); for (int64_t i = 0; (i < mc_count && OB_SUCC(ret)); ++i) { - if (OB_FAIL(ObMysqlClient::alloc(this, mysql_client, user_name, password, database, is_meta_mysql_client, password1, client_pool_option))) { + if (OB_FAIL(ObMysqlClient::alloc(this, mysql_client, user_name, password, database, is_meta_mysql_client, + cluster_name, password1, client_pool_option))) { LOG_WARN("fail to alloc mysql client", K(user_name), K(password), K(database), "idx", i, K(is_meta_mysql_client), K(ret)); } else if (OB_ISNULL(mysql_client)) { diff --git a/src/obproxy/proxy/client/ob_mysql_client_pool.h b/src/obproxy/proxy/client/ob_mysql_client_pool.h index 3e5e9b336..e02f27192 100644 --- a/src/obproxy/proxy/client/ob_mysql_client_pool.h +++ b/src/obproxy/proxy/client/ob_mysql_client_pool.h @@ -52,6 +52,7 @@ class ObMysqlClientPool : public common::ObSharedRefCount const common::ObString &user_name, const common::ObString &password, const common::ObString &database, + const common::ObString &cluster_name = "", const common::ObString &password1 = "", ClientPoolOption* client_pool_option = NULL); void destroy(); diff --git a/src/obproxy/proxy/client/ob_mysql_proxy.cpp b/src/obproxy/proxy/client/ob_mysql_proxy.cpp index 377a50a1a..97b40250d 100644 --- a/src/obproxy/proxy/client/ob_mysql_proxy.cpp +++ b/src/obproxy/proxy/client/ob_mysql_proxy.cpp @@ -173,7 +173,7 @@ int ObMysqlProxyCont::async_post_request(const ObMysqlRequestParam &request_para action = NULL; if (OB_UNLIKELY(!request_param.is_valid()) || OB_UNLIKELY(timeout_ms <= 0) - || OB_ISNULL(client_pool)) { + || (!request_param.is_detect_client_ && OB_ISNULL(client_pool))) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid input value", K(request_param), K(timeout_ms), K(ret)); } else if (OB_FAIL(request_param_.deep_copy(request_param))) { @@ -181,8 +181,10 @@ int ObMysqlProxyCont::async_post_request(const ObMysqlRequestParam &request_para } else { is_nonblock_ = true; timeout_ms_ = timeout_ms; - client_pool->inc_ref(); - client_pool_ = client_pool; + if (NULL != client_pool) { + client_pool->inc_ref(); + client_pool_ = client_pool; + } } if (OB_SUCC(ret)) { @@ -322,7 +324,13 @@ int ObMysqlProxyCont::do_post_request() if (OB_SUCC(ret)) { ret = OB_EAGAIN; if (NULL == mysql_client_) { - mysql_client_ = client_pool_->acquire_mysql_client(); + // For probing requests, in order to prevent competition for connection pool connections, + // use a separate mysql_client + if (NULL != request_param_.mysql_client_) { + mysql_client_ = request_param_.mysql_client_; + } else { + mysql_client_ = client_pool_->acquire_mysql_client(); + } } if (NULL != mysql_client_) { ObAction *action = NULL; @@ -463,6 +471,7 @@ int ObMysqlProxy::init(const int64_t timeout_ms, const ObString &user_name, const ObString &password, const ObString &database, + const ObString &cluster_name, const ObString &password1) { int ret = OB_SUCCESS; @@ -472,7 +481,7 @@ int ObMysqlProxy::init(const int64_t timeout_ms, } else if (OB_UNLIKELY(timeout_ms <= 0)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid input value", K(timeout_ms), K(ret)); - } else if (OB_FAIL(raw_mysql_client_.init(user_name, password, database, password1))) { + } else if (OB_FAIL(raw_mysql_client_.init(user_name, password, database, cluster_name, password1))) { LOG_WARN("fail to init raw mysql client", K(ret)); } else { timeout_ms_ = timeout_ms; @@ -500,7 +509,7 @@ int ObMysqlProxy::rebuild_client_pool(ObShardConnector *shard_conn, ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid input value", K(user_name)); } else { - if (OB_FAIL(alloc_client_pool(is_meta_mysql_client, user_name, password, database, password1, client_pool_option))) { + if (OB_FAIL(alloc_client_pool(is_meta_mysql_client, user_name, password, database, "", password1, client_pool_option))) { LOG_WARN("fail to alloc client pool", K(is_meta_mysql_client), K(user_name), K(database), K(ret)); } else { client_pool_->set_shard_conn(shard_conn); @@ -539,7 +548,7 @@ int ObMysqlProxy::rebuild_client_pool(ObClusterResource *cluster_resource, } else { ObString full_username(full_user_name); if (OB_FAIL(alloc_client_pool(is_meta_mysql_client, full_username, - password, database, password1, client_pool_option))) { + password, database, cluster_name, password1, client_pool_option))) { LOG_WARN("fail to alloc client pool", K(user_name), K(database), K(ret)); } else { client_pool_->set_cluster_resource(cluster_resource); @@ -613,7 +622,7 @@ int ObMysqlProxy::async_execute(ObContinuation *cont, LOG_DEBUG("ObMysqlProxy::async_execute", K(cont), K(request_param), K(timeout_ms), K(ret)); ObMysqlProxyCont *mp_cont = NULL; ObMysqlClientPool *pool = NULL; - if (OB_ISNULL(pool = acquire_client_pool())) { + if (!request_param.is_detect_client_ && OB_ISNULL(pool = acquire_client_pool())) { ret = OB_ENTRY_NOT_EXIST; LOG_WARN("client pool is null", K(ret)); } else { @@ -825,6 +834,7 @@ int ObMysqlProxy::alloc_client_pool(const bool is_meta_mysql_client, const ObString &user_name, const ObString &password, const ObString &database, + const ObString &cluster_name, const ObString &password1, ClientPoolOption* client_pool_option) { @@ -839,7 +849,7 @@ int ObMysqlProxy::alloc_client_pool(const bool is_meta_mysql_client, } else if (FALSE_IT(client_pool->inc_ref())) { // will dec_ref in destroy() } else if (OB_FAIL(client_pool->init(is_meta_mysql_client, user_name, - password, database, password1, client_pool_option))) { + password, database, cluster_name, password1, client_pool_option))) { LOG_WARN("fail to init client pool", K(user_name), K(password), K(database), K(is_meta_mysql_client), K(ret)); } else { @@ -851,14 +861,14 @@ int ObMysqlProxy::alloc_client_pool(const bool is_meta_mysql_client, client_pool_ = client_pool; // update raw mysql client info - ObClientReuqestInfo &info = raw_mysql_client_.get_request_info(); + ObClientRequestInfo &info = raw_mysql_client_.get_request_info(); info.reset_names(); bool need_skip_stage2 = false; if (client_pool_option) { need_skip_stage2 = client_pool_option->need_skip_stage2_; } info.set_need_skip_stage2(need_skip_stage2); - if (OB_FAIL(info.set_names(user_name, password, database))) { + if (OB_FAIL(info.set_names(user_name, password, database, cluster_name))) { LOG_WARN("fail to set raw mysql client request info", K(ret)); } } diff --git a/src/obproxy/proxy/client/ob_mysql_proxy.h b/src/obproxy/proxy/client/ob_mysql_proxy.h index 1f1d8f5c2..f671d55fa 100644 --- a/src/obproxy/proxy/client/ob_mysql_proxy.h +++ b/src/obproxy/proxy/client/ob_mysql_proxy.h @@ -57,6 +57,7 @@ class ObMysqlProxy const common::ObString &user_name, const common::ObString &password, const common::ObString &database, + const common::ObString &cluster_name = "", const common::ObString &password1 = ""); bool is_inited() const { return is_inited_; } void destroy(); @@ -116,6 +117,7 @@ class ObMysqlProxy const common::ObString &user_name, const common::ObString &password, const common::ObString &database, + const common::ObString &cluster_name = "", const common::ObString &password1 = "", ClientPoolOption* client_pool_option = NULL); public: diff --git a/src/obproxy/proxy/client/ob_raw_mysql_client.cpp b/src/obproxy/proxy/client/ob_raw_mysql_client.cpp index 8bdbb5896..08614b884 100644 --- a/src/obproxy/proxy/client/ob_raw_mysql_client.cpp +++ b/src/obproxy/proxy/client/ob_raw_mysql_client.cpp @@ -39,7 +39,7 @@ ObRawMysqlClientActor::ObRawMysqlClientActor() addr_(), request_buf_(NULL), request_reader_(NULL) {} -int ObRawMysqlClientActor::init(ObClientReuqestInfo &info) +int ObRawMysqlClientActor::init(ObClientRequestInfo &info) { int ret = OB_SUCCESS; if (OB_UNLIKELY(is_inited_)) { @@ -149,7 +149,7 @@ int ObRawMysqlClientActor::connect(const ObAddr &addr, const int64_t timeout_ms) options.f_blocking_ = true; // blocking read or send ObIpEndpoint ip; - ops_ip_copy(ip.sa_, addr.get_ipv4(), static_cast(addr.get_port())); + ip.assign(addr.get_sockaddr()); if (OB_FAIL(con_.open(options))) { LOG_WARN("fail to open connection", K(ret)); } else if (OB_FAIL(con_.connect(ip.sa_, options))) { @@ -401,6 +401,7 @@ int ObRawMysqlClientActor::read_response(const ObMySQLCmd cmd) int ObRawMysqlClient::init(const ObString &user_name, const ObString &password, const ObString &database, + const ObString &cluster_name, const ObString &password1) { int ret = OB_SUCCESS; @@ -412,7 +413,7 @@ int ObRawMysqlClient::init(const ObString &user_name, LOG_WARN("init twice", K_(is_inited), K(ret)); } else if (OB_FAIL(mutex_init(&mutex_))) { LOG_WARN("fail to init mutex", K(ret)); - } else if (OB_FAIL(info_.set_names(user_name, password, database, password1))) { + } else if (OB_FAIL(info_.set_names(user_name, password, database, cluster_name, password1))) { LOG_WARN("fail to set names", K(user_name), K(password), K(password1), K(database), K(ret)); int tmp_ret = OB_SUCCESS; if (OB_SUCCESS != (tmp_ret = mutex_destroy(&mutex_))) { diff --git a/src/obproxy/proxy/client/ob_raw_mysql_client.h b/src/obproxy/proxy/client/ob_raw_mysql_client.h index 37ff9a54b..f489aa107 100644 --- a/src/obproxy/proxy/client/ob_raw_mysql_client.h +++ b/src/obproxy/proxy/client/ob_raw_mysql_client.h @@ -33,7 +33,7 @@ class ObRawMysqlClientActor ObRawMysqlClientActor(); ~ObRawMysqlClientActor() { destroy(); } - int init(ObClientReuqestInfo &info); + int init(ObClientRequestInfo &info); int sync_raw_execute(const char *sql, const int64_t timeout_ms, ObClientMysqlResp *&resp); void reset() { destroy(); } bool is_avail() { return is_avail_; } @@ -51,7 +51,7 @@ class ObRawMysqlClientActor private: bool is_inited_; bool is_avail_; - ObClientReuqestInfo *info_; + ObClientRequestInfo *info_; ObClientMysqlResp *resp_; net::ObConnection con_; common::ObAddr addr_; @@ -82,13 +82,14 @@ class ObRawMysqlClient int init(const common::ObString &user_name, const common::ObString &password, const common::ObString &database, + const common::ObString &cluster_name, const common::ObString &password1 = ""); int sync_raw_execute(const char *sql, const int64_t timeout_ms, ObClientMysqlResp *&resp); int set_server_addr(const common::ObIArray &addrs); int set_target_server(const common::ObIArray &replicas); - ObClientReuqestInfo &get_request_info() { return info_; } + ObClientRequestInfo &get_request_info() { return info_; } int disconnect(); void destroy(); @@ -98,7 +99,7 @@ class ObRawMysqlClient private: static const int64_t DEFAULT_SERVER_ADDRS_COUNT = 3; bool is_inited_; - ObClientReuqestInfo info_; + ObClientRequestInfo info_; ObProxyReplicaLocation target_server_[DEFAULT_SERVER_ADDRS_COUNT]; ObRawMysqlClientActor actor_; ObMutex mutex_; diff --git a/src/obproxy/proxy/mysql/ob_mysql_client_session.cpp b/src/obproxy/proxy/mysql/ob_mysql_client_session.cpp index 9018da7b1..aae717e13 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_client_session.cpp +++ b/src/obproxy/proxy/mysql/ob_mysql_client_session.cpp @@ -63,19 +63,21 @@ ObMutex g_debug_cs_list_mutex; #endif ObMysqlClientSession::ObMysqlClientSession() - : can_direct_ok_(false), is_proxy_mysql_client_(false), active_(false), test_server_addr_(), + : can_direct_ok_(false), is_proxy_mysql_client_(false), can_direct_send_request_(false), + active_(false), test_server_addr_(), vc_ready_killed_(false), is_waiting_trans_first_request_(false), is_need_send_trace_info_(true), is_already_send_trace_info_(false), - is_first_handle_request_(true), is_in_trans_for_close_request_(false), - is_need_return_last_bound_ss_(false), - need_delete_cluster_(false), is_first_dml_sql_got_(false), compressed_seq_(0), + is_first_handle_request_(true), is_in_trans_for_close_request_(false), is_last_request_in_trans_(false), + is_trans_internal_routing_(false), is_need_return_last_bound_ss_(false), need_delete_cluster_(false), + is_first_dml_sql_got_(false), is_proxy_enable_trans_internal_routing_(false), compressed_seq_(0), cluster_resource_(NULL), dummy_entry_(NULL), is_need_update_dummy_entry_(false), - dummy_ldc_(), dummy_entry_valid_time_ns_(0), server_state_version_(0), + dummy_ldc_(), dummy_entry_valid_time_ns_(0), server_state_version_(0), inner_request_param_(NULL), tcp_init_cwnd_set_(false), half_close_(false), conn_decrease_(false), conn_prometheus_decrease_(false), vip_connection_decrease_(false), magic_(MYSQL_CS_MAGIC_DEAD), create_thread_(NULL), is_local_connection_(false), client_vc_(NULL), in_list_stat_(LIST_INIT), current_tid_(-1), - cs_id_(0), proxy_sessid_(0), bound_ss_(NULL), cur_ss_(NULL), lii_ss_(NULL), last_bound_ss_(NULL), read_buffer_(NULL), + cs_id_(0), proxy_sessid_(0), bound_ss_(NULL), cur_ss_(NULL), lii_ss_(NULL), last_bound_ss_(NULL), + trans_coordinator_ss_addr_(), read_buffer_(NULL), buffer_reader_(NULL), mysql_sm_(NULL), read_state_(MCS_INIT), ka_vio_(NULL), server_ka_vio_(NULL), trace_stats_(NULL), select_plan_(NULL), ps_id_(0), cursor_id_(CURSOR_ID_START), using_ldg_(false) @@ -157,13 +159,17 @@ void ObMysqlClientSession::destroy() is_already_send_trace_info_ = false; is_first_handle_request_ = true; is_in_trans_for_close_request_ = false; + is_last_request_in_trans_ = false; + is_trans_internal_routing_ = false; is_need_return_last_bound_ss_ = false; is_first_dml_sql_got_ = false; + is_proxy_enable_trans_internal_routing_ = false; compressed_seq_ = 0; - + trans_coordinator_ss_addr_.reset(); schema_key_.reset(); ObProxyClientSession::cleanup(); create_thread_ = NULL; + using_ldg_ = false; op_reclaim_free(this); } @@ -369,17 +375,14 @@ int ObMysqlClientSession::new_connection( if (OB_FAIL(fetch_tenant_by_vip())) { PROXY_CS_LOG(WARN, "fail to fetch tenant by vip", K(ret)); ret = OB_SUCCESS; - } else { - session_info_.set_is_read_only_user(ct_info_.vip_tenant_.is_read_only()); - session_info_.set_is_request_follower_user(ct_info_.vip_tenant_.is_request_follower()); - session_info_.set_vip_addr_name(ct_info_.vip_tenant_.vip_addr_.addr_); + } else if (is_vip_lookup_success()) { ObString user_name; if (!get_global_white_list_table_processor().can_ip_pass( ct_info_.vip_tenant_.cluster_name_, ct_info_.vip_tenant_.tenant_name_, - user_name, client_addr.ip_.v4_, false)) { + user_name, client_vc_->get_real_client_addr())) { ret = OB_ERR_CAN_NOT_PASS_WHITELIST; PROXY_CS_LOG(DEBUG, "can not pass white_list", K(ct_info_.vip_tenant_.cluster_name_), - K(ct_info_.vip_tenant_.tenant_name_), K(client_addr), K(ret)); + K(ct_info_.vip_tenant_.tenant_name_), K(client_addr), K(ret)); } } } @@ -406,15 +409,30 @@ int ObMysqlClientSession::new_connection( int ObMysqlClientSession::fetch_tenant_by_vip() { int ret = OB_SUCCESS; - if (OB_FAIL(get_global_vip_tenant_processor().get_vip_tenant(ct_info_.vip_tenant_))) { - //if login succ latter, we will desc cache miss stat. - MYSQL_SSN_INCREMENT_DYN_STAT(VIP_TO_TENANT_CACHE_MISS); - ct_info_.lookup_success_ = false; - PROXY_CS_LOG(INFO, "fail to get_vip_tenant", "vip_tenant", ct_info_.vip_tenant_, K(ret)); - } else { - MYSQL_SSN_INCREMENT_DYN_STAT(VIP_TO_TENANT_CACHE_HIT); - ct_info_.lookup_success_ = true; - PROXY_CS_LOG(DEBUG, "succ to get_vip_tenant name", "vip_tenant", ct_info_.vip_tenant_); + ct_info_.lookup_success_ = false; + ObVipAddr addr = ct_info_.vip_tenant_.vip_addr_; + ObConfigItem tenant_item, cluster_item; + bool found = false; + if (OB_FAIL(get_global_config_processor().get_proxy_config_with_level( + addr, "", "", "proxy_tenant_name", tenant_item, "LEVEL_VIP", found))) { + PROXY_CS_LOG(WARN, "get proxy tenant name config failed", K(addr), K(ret)); + } + + if (OB_SUCC(ret) && found) { + if (OB_FAIL(get_global_config_processor().get_proxy_config_with_level( + addr, "", "", "rootservice_cluster_name", cluster_item, "LEVEL_VIP", found))) { + PROXY_CS_LOG(WARN, "get cluster name config failed", K(addr), K(ret)); + } + } + + if (OB_SUCC(ret) && found) { + if (OB_FAIL(ct_info_.vip_tenant_.set_tenant_cluster(tenant_item.str(), cluster_item.str()))) { + PROXY_CS_LOG(WARN, "set tenant and cluster name failed", K(tenant_item), K(cluster_item), K(ret)); + } else { + session_info_.set_vip_addr_name(addr.addr_); + ct_info_.lookup_success_ = true; + PROXY_CS_LOG(DEBUG, "succ to get conn info", "vip_tenant", ct_info_.vip_tenant_); + } } return ret; } @@ -422,13 +440,9 @@ int ObMysqlClientSession::fetch_tenant_by_vip() int ObMysqlClientSession::get_vip_addr() { int ret = OB_SUCCESS; - int32_t ip; - int32_t port; int64_t vid; - ip = ntohl(client_vc_->get_virtual_ip()); - port = static_cast(client_vc_->get_virtual_port()); vid = static_cast(client_vc_->get_virtual_vid()); - ct_info_.vip_tenant_.vip_addr_.set(ip, port, vid); + ct_info_.vip_tenant_.vip_addr_.set(client_vc_->get_virtual_addr(), vid); // TODO, get client ip, slb ip from kernal @@ -580,6 +594,7 @@ int ObMysqlClientSession::create_scramble() uint64_t ObMysqlClientSession::get_next_proxy_sessid() { + // TODO: Consider IPv6 support static uint64_t next_proxy_sessid = 1; const ObAddr &addr = get_global_hot_upgrade_info().local_addr_; int64_t ipv4 = static_cast(addr.get_ipv4()); @@ -800,6 +815,8 @@ int ObMysqlClientSession::state_server_keep_alive(int event, void *data) case VC_EVENT_READ_READY: case VC_EVENT_EOS: // The server session closed or something is amiss + case VC_EVENT_DETECT_SERVER_DEAD: + // find server dead case VC_EVENT_ACTIVE_TIMEOUT: case VC_EVENT_INACTIVITY_TIMEOUT: @@ -864,7 +881,8 @@ int ObMysqlClientSession::state_keep_alive(int event, void *data) // fallthrough case VC_EVENT_ERROR: case VC_EVENT_ACTIVE_TIMEOUT: - case VC_EVENT_INACTIVITY_TIMEOUT: { + case VC_EVENT_INACTIVITY_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: { if (MCS_HALF_CLOSED == read_state_) { half_close_ = false; } @@ -1411,7 +1429,8 @@ bool ObMysqlClientSession::is_authorised_proxysys(const ObProxyLoginUserType typ int ret = OB_SUCCESS; //1.check ip - if (!get_global_proxy_config().skip_proxy_sys_private_check + if (RUN_MODE_PROXY == g_run_mode + && !get_global_proxy_config().skip_proxy_sys_private_check && !ops_is_ip_private(client_vc_->get_remote_addr()) && !ops_is_ip_loopback(client_vc_->get_remote_addr())) { char src_ip[INET6_ADDRSTRLEN]; @@ -1463,7 +1482,9 @@ bool ObMysqlClientSession::is_authorised_proxysys(const ObProxyLoginUserType typ bool ObMysqlClientSession::is_need_convert_vip_to_tname() { - return (get_global_proxy_config().need_convert_vip_to_tname && !this->is_proxy_mysql_client_ ); + return (get_global_proxy_config().need_convert_vip_to_tname + && !this->is_proxy_mysql_client_ + && RUN_MODE_PROXY == g_run_mode); } inline bool ObMysqlClientSession::need_close() const @@ -1614,7 +1635,7 @@ int ObMysqlClientSession::check_update_ldc() } else { need_ignore = true; } - PROXY_CS_LOG(ERROR, "fail to tryrdlock server_state_lock, ignore this update", + PROXY_CS_LOG(WARN, "fail to tryrdlock server_state_lock, ignore this update", K(err_no), "old_idc_name", dummy_ldc_.get_idc_name(), K(new_idc_name), diff --git a/src/obproxy/proxy/mysql/ob_mysql_client_session.h b/src/obproxy/proxy/mysql/ob_mysql_client_session.h index c3401c4b6..d991d91fd 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_client_session.h +++ b/src/obproxy/proxy/mysql/ob_mysql_client_session.h @@ -27,6 +27,7 @@ #include "optimizer/ob_sharding_select_log_plan.h" #include "optimizer/ob_proxy_optimizer_processor.h" #include "iocore/net/ob_unix_net_vconnection.h" +#include "ob_proxy_init.h" namespace oceanbase { @@ -107,10 +108,12 @@ class ObMysqlClientSession : public ObProxyClientSession inline ObMysqlServerSession *get_cur_server_session() const { return cur_ss_; } inline ObMysqlServerSession *get_lii_server_session() const { return lii_ss_; } inline ObMysqlServerSession *get_last_bound_server_session() const { return last_bound_ss_; } + inline net::ObIpEndpoint &get_trans_coordinator_ss_addr() { return trans_coordinator_ss_addr_; } inline void set_server_session(ObMysqlServerSession *ssession) { bound_ss_ = ssession; } inline void set_cur_server_session(ObMysqlServerSession *ssession) { cur_ss_ = ssession; } inline void set_lii_server_session(ObMysqlServerSession *ssession) { lii_ss_ = ssession; } inline void set_last_bound_server_session(ObMysqlServerSession *ssession) { last_bound_ss_ = ssession; } + inline void set_trans_coordinator_ss_addr(const sockaddr &addr) { trans_coordinator_ss_addr_.assign(addr); } bool is_hold_conn_id(const uint32_t conn_id); // Functions for manipulating api hooks @@ -133,13 +136,6 @@ class ObMysqlClientSession : public ObProxyClientSession //proxy inner mysql_client do need convert vip to tenant bool is_need_convert_vip_to_tname(); - // client protocol judgement - ObProxyProtocol get_client_session_protocol() const - { - return session_info_.is_client_support_ob20_protocol() ? - ObProxyProtocol::PROTOCOL_OB20 : ObProxyProtocol::PROTOCOL_NORMAL; - } - // client cap judgement bool is_client_support_full_link_trace() const { return session_info_.is_client_support_full_link_trace(); } bool is_client_support_new_extra_info() const { return session_info_.is_client_support_new_extra_info(); } @@ -236,6 +232,7 @@ class ObMysqlClientSession : public ObProxyClientSession void set_need_delete_cluster() { need_delete_cluster_ = true; } void set_proxy_mysql_client() { is_proxy_mysql_client_ = true; } + void set_can_send_request() { can_direct_send_request_ = true; } void set_session_pool_client(bool is_session_pool_client) { session_info_.is_session_pool_client_ = is_session_pool_client; } @@ -256,9 +253,14 @@ class ObMysqlClientSession : public ObProxyClientSession bool is_first_handle_request() const { return is_first_handle_request_; } void set_in_trans_for_close_request(bool is_in_trans_for_close_request) { is_in_trans_for_close_request_ = is_in_trans_for_close_request; } bool is_in_trans_for_close_request() const { return is_in_trans_for_close_request_; } + void set_last_request_in_trans(bool is_in_trans) { is_last_request_in_trans_ = is_in_trans; } + bool is_last_request_in_trans() { return is_last_request_in_trans_; } + void set_trans_internal_routing(bool is_internal_routing) { is_trans_internal_routing_ = is_internal_routing; } + bool is_trans_internal_routing() const { return is_trans_internal_routing_; } void set_need_return_last_bound_ss(bool is_need_return_last_bound_ss) { is_need_return_last_bound_ss_ = is_need_return_last_bound_ss; } bool is_need_return_last_bound_ss() const { return is_need_return_last_bound_ss_; } - + void set_proxy_enable_trans_internal_routing(bool is_enable_internal_route) { is_proxy_enable_trans_internal_routing_ = is_enable_internal_route; } + bool is_proxy_enable_trans_internal_routing() const { return is_proxy_enable_trans_internal_routing_; } bool enable_analyze_internal_cmd() const { return session_info_.enable_analyze_internal_cmd(); } bool is_metadb_user() const { return session_info_.is_metadb_user(); } bool is_proxysys_user() const { return session_info_.is_proxysys_user(); } @@ -332,6 +334,7 @@ class ObMysqlClientSession : public ObProxyClientSession bool can_direct_ok_; bool is_proxy_mysql_client_; // used for ObMysqlClient + bool can_direct_send_request_; // used for ObMysqlClient bool can_server_session_release_; //used for session release proxy::ObCommonAddr common_addr_; // session pool server_addr @@ -350,11 +353,13 @@ class ObMysqlClientSession : public ObProxyClientSession bool is_already_send_trace_info_; bool is_first_handle_request_; bool is_in_trans_for_close_request_; + bool is_last_request_in_trans_; + bool is_trans_internal_routing_; bool is_need_return_last_bound_ss_; bool need_delete_cluster_; bool is_first_dml_sql_got_;//default false, will route with merge status careless //it is true after user first dml sql arrived. - + bool is_proxy_enable_trans_internal_routing_; // from config, update each tranasction start uint8_t compressed_seq_; // seq management between client & proxy obutils::ObClusterResource *cluster_resource_; @@ -379,8 +384,6 @@ class ObMysqlClientSession : public ObProxyClientSession #endif private: - static const uint32_t LOCAL_IPV4_ADDR = 0x100007F; - enum ObClientReadState { MCS_INIT = 0, @@ -431,6 +434,9 @@ class ObMysqlClientSession : public ObProxyClientSession ObMysqlServerSession *lii_ss_; ObMysqlServerSession *last_bound_ss_; + // coordinator session address in transaction + net::ObIpEndpoint trans_coordinator_ss_addr_; + event::ObMIOBuffer *read_buffer_; event::ObIOBufferReader *buffer_reader_; @@ -459,11 +465,11 @@ class ObMysqlClientSession : public ObProxyClientSession inline void ObMysqlClientSession::set_local_connection() { - if (is_proxy_mysql_client_) { + if (is_proxy_mysql_client_ || RUN_MODE_CLIENT == g_run_mode) { is_local_connection_ = true; } else { if (OB_NOT_NULL(client_vc_)) { - is_local_connection_ = LOCAL_IPV4_ADDR == client_vc_->get_local_ip(); + is_local_connection_ = net::ops_is_ip_loopback(client_vc_->get_local_addr()); } } } @@ -481,13 +487,13 @@ inline uint32_t ObMysqlClientSession::get_next_ps_stmt_id() inline common::ObAddr ObMysqlClientSession::get_real_client_addr(net::ObNetVConnection *server_vc) { common::ObAddr ret_addr; - if (is_proxy_mysql_client_) { + if (is_proxy_mysql_client_ || RUN_MODE_CLIENT == g_run_mode) { if (OB_NOT_NULL(server_vc)) { - ret_addr.set_ipv4_addr(ntohl(server_vc->get_local_ip()), server_vc->get_local_port()); + ret_addr.set_sockaddr(server_vc->get_local_addr()); } } else { if (OB_NOT_NULL(client_vc_)) { - ret_addr.set_ipv4_addr(ntohl(client_vc_->get_real_client_ip()), client_vc_->get_real_client_port()); + ret_addr.set_sockaddr(client_vc_->get_real_client_addr()); } } PROXY_CS_LOG(DEBUG, "succ to get real client addr", K(ret_addr)); diff --git a/src/obproxy/proxy/mysql/ob_mysql_debug_names.cpp b/src/obproxy/proxy/mysql/ob_mysql_debug_names.cpp index 67c56fc66..2489e507a 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_debug_names.cpp +++ b/src/obproxy/proxy/mysql/ob_mysql_debug_names.cpp @@ -68,6 +68,10 @@ const char *ObMysqlDebugNames::get_event_name(const int event) ret = "VC_EVENT_ACTIVE_TIMEOUT"; break; + case VC_EVENT_DETECT_SERVER_DEAD: + ret = "VC_EVENT_DETECT_SERVER_DEAD"; + break; + case EVENT_INTERVAL: ret = "VC_EVENT_INTERVAL"; break; diff --git a/src/obproxy/proxy/mysql/ob_mysql_global_session_manager.cpp b/src/obproxy/proxy/mysql/ob_mysql_global_session_manager.cpp index cc70732bd..8216b4651 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_global_session_manager.cpp +++ b/src/obproxy/proxy/mysql/ob_mysql_global_session_manager.cpp @@ -81,6 +81,7 @@ int ObMysqlServerSessionList::main_handler(int event, void *data) case VC_EVENT_ERROR: case VC_EVENT_INACTIVITY_TIMEOUT: case VC_EVENT_ACTIVE_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: net_vc = static_cast((static_cast(data))->vc_server_); break; @@ -1042,4 +1043,4 @@ ObMysqlContJobList& get_global_server_conn_job_list() } // end of namespace proxy } // end of namespace obproxy -} // end of namespace oceanbase \ No newline at end of file +} // end of namespace oceanbase diff --git a/src/obproxy/proxy/mysql/ob_mysql_proxy_port.cpp b/src/obproxy/proxy/mysql/ob_mysql_proxy_port.cpp index 3d602d942..24a794a00 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_proxy_port.cpp +++ b/src/obproxy/proxy/mysql/ob_mysql_proxy_port.cpp @@ -23,10 +23,16 @@ namespace obproxy { namespace proxy { -ObMysqlProxyPort &get_global_proxy_port() +ObMysqlProxyPort &get_global_proxy_ipv4_port() { - static ObMysqlProxyPort g_proxy_port; - return g_proxy_port; + static ObMysqlProxyPort g_proxy_ipv4_port; + return g_proxy_ipv4_port; +} + +ObMysqlProxyPort &get_global_proxy_ipv6_port() +{ + static ObMysqlProxyPort g_proxy_ipv6_port; + return g_proxy_ipv6_port; } void ObMysqlProxyPort::reset() diff --git a/src/obproxy/proxy/mysql/ob_mysql_proxy_port.h b/src/obproxy/proxy/mysql/ob_mysql_proxy_port.h index 45fb1afb4..f94c93b97 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_proxy_port.h +++ b/src/obproxy/proxy/mysql/ob_mysql_proxy_port.h @@ -55,7 +55,8 @@ struct ObMysqlProxyPort net::ObIpAddr inbound_ip_; }; -ObMysqlProxyPort &get_global_proxy_port(); +ObMysqlProxyPort &get_global_proxy_ipv4_port(); +ObMysqlProxyPort &get_global_proxy_ipv6_port(); } // end of namespace proxy } // end of namespace obproxy diff --git a/src/obproxy/proxy/mysql/ob_mysql_proxy_server_main.cpp b/src/obproxy/proxy/mysql/ob_mysql_proxy_server_main.cpp index 80953a0ba..59ab305f1 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_proxy_server_main.cpp +++ b/src/obproxy/proxy/mysql/ob_mysql_proxy_server_main.cpp @@ -22,9 +22,11 @@ #include "iocore/eventsystem/ob_blocking_task.h" #include "iocore/eventsystem/ob_grpc_task.h" #include "iocore/eventsystem/ob_shard_watch_task.h" +#include "iocore/eventsystem/ob_shard_scan_all_task.h" #include "obutils/ob_congestion_manager.h" #include "obutils/ob_proxy_config.h" #include "dbconfig/ob_proxy_db_config_processor.h" +#include "ob_proxy_init.h" using namespace oceanbase::common; using namespace oceanbase::obproxy::event; @@ -41,7 +43,8 @@ namespace proxy { // global acceptor, ObMysqlProxyAccept -ObMysqlProxyAcceptor g_mysql_proxy_acceptor; +ObMysqlProxyAcceptor g_mysql_proxy_ipv4_acceptor; +ObMysqlProxyAcceptor g_mysql_proxy_ipv6_acceptor; // called from ob_api.cpp int ObMysqlProxyServerMain::make_net_accept_options( @@ -105,7 +108,7 @@ int ObMysqlProxyServerMain::init_mysql_proxy_server(const ObMysqlConfigParams &c // enable reclaim mysql sm op_reclaim_sparse_opt(ObMysqlSM, ObMysqlSM::instantiate_func, ENABLE_RECLAIM, 1); - if (OB_FAIL(init_mysql_proxy_port(config_params))) { + if (RUN_MODE_PROXY == g_run_mode && OB_FAIL(init_mysql_proxy_port(config_params))) { LOG_ERROR("fail to init mysql proxy port", K(ret)); } else if (OB_FAIL(init_mysql_stats())) { LOG_ERROR("fail to init_mysql_stats", K(ret)); @@ -119,11 +122,23 @@ int ObMysqlProxyServerMain::init_mysql_proxy_server(const ObMysqlConfigParams &c } #endif - if (OB_SUCC(ret)) { + int64_t ip_mode = config_params.ip_listen_mode_; + bool enable_ipv4 = (ip_mode == 1 || ip_mode == 3); + bool enable_ipv6 = (ip_mode == 2 || ip_mode == 3); + + if (OB_SUCC(ret) && enable_ipv4) { // do the configuration defined ports if (OB_FAIL(make_mysql_proxy_acceptor(config_params, - get_global_proxy_port(), - g_mysql_proxy_acceptor))) { + get_global_proxy_ipv4_port(), + g_mysql_proxy_ipv4_acceptor))) { + LOG_ERROR("fail to make mysql proxy acceptor", K(ret)); + } + } + + if (OB_SUCC(ret) && enable_ipv6) { + if (OB_FAIL(make_mysql_proxy_acceptor(config_params, + get_global_proxy_ipv6_port(), + g_mysql_proxy_ipv6_acceptor))) { LOG_ERROR("fail to make mysql proxy acceptor", K(ret)); } } @@ -133,15 +148,23 @@ int ObMysqlProxyServerMain::init_mysql_proxy_server(const ObMysqlConfigParams &c int ObMysqlProxyServerMain::start_mysql_proxy_acceptor() { int ret = OB_SUCCESS; - ObMysqlProxyPort &proxy_port = get_global_proxy_port(); + int64_t ip_mode = get_global_proxy_config().ip_listen_mode; + bool enable_ipv4 = (ip_mode == 1 || ip_mode == 3); + bool enable_ipv6 = (ip_mode == 2 || ip_mode == 3); // start accepting connections // although we make a good pretence here, I don't believe that ObNetProcessor::main_accept() // ever actually returns NULL. It would be useful to be able to detect errors // and spew them here though. - if (OB_ISNULL(g_net_processor.main_accept(*(g_mysql_proxy_acceptor.accept_), proxy_port.fd_, - g_mysql_proxy_acceptor.net_opt_))) { + if (enable_ipv4 && OB_ISNULL(g_net_processor.main_accept(*(g_mysql_proxy_ipv4_acceptor.accept_), + get_global_proxy_ipv4_port().fd_, + g_mysql_proxy_ipv4_acceptor.net_opt_))) { ret = OB_ERR_UNEXPECTED; - LOG_ERROR("fail to execute main accept", K(ret)); + LOG_ERROR("fail to execute ipv4 main accept", K(ret)); + } else if (enable_ipv6 && OB_ISNULL(g_net_processor.main_accept(*(g_mysql_proxy_ipv6_acceptor.accept_), + get_global_proxy_ipv6_port().fd_, + g_mysql_proxy_ipv6_acceptor.net_opt_))) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("fail to execute ipv6 main accept", K(ret)); } return ret; @@ -161,6 +184,7 @@ int ObMysqlProxyServerMain::start_processor_threads(const ObMysqlConfigParams &c int ret = OB_SUCCESS; int64_t stack_size = config_params.stack_size_; int64_t event_threads = config_params.work_thread_num_; + int64_t shard_scan_threads = config_params.shard_scan_thread_num_; int64_t task_threads = config_params.task_thread_num_; bool enable_cpu_topology = config_params.enable_cpu_topology_; bool automatic_match_work_thread = config_params.automatic_match_work_thread_; @@ -188,6 +212,11 @@ int ObMysqlProxyServerMain::start_processor_threads(const ObMysqlConfigParams &c } else if (get_global_proxy_config().enable_sharding && OB_FAIL(g_shard_watch_task_processor.start(grpc_watch_threads, stack_size))) { LOG_ERROR("fail to start grpc parent task processor", K(stack_size), K(ret)); + } else if (get_global_proxy_config().enable_sharding + && OB_FAIL(g_shard_scan_all_task_processor.start(shard_scan_threads > 0 ? shard_scan_threads + : g_event_processor.thread_count_for_type_[ET_CALL] / 2, + stack_size))) { + LOG_ERROR("fail to start grpc parent task processor", K(stack_size), K(ret)); } else if (OB_FAIL(init_cs_map_for_thread())) { LOG_ERROR("fail to init cs_map for thread", K(ret)); } else if (OB_FAIL(init_table_map_for_thread())) { @@ -210,30 +239,60 @@ int ObMysqlProxyServerMain::start_processor_threads(const ObMysqlConfigParams &c return ret; } +int ObMysqlProxyServerMain::init_inherited_info(ObMysqlProxyPort &proxy_port, const int fd) +{ + int ret = OB_SUCCESS; + proxy_port.fd_ = fd; + struct sockaddr_storage sock_addr; + int64_t namelen = sizeof(sock_addr); + memset(&sock_addr, 0, namelen); + if (OB_FAIL(ObSocketManager::getsockname(proxy_port.fd_, (struct sockaddr*)(&sock_addr), &namelen))) { + LOG_ERROR("fail to get sock name", K(ret)); + } else { + // This step of conversion is mainly to obtain the port number, sockaddr_in and sockaddr_in6 port number positions are compatible + struct sockaddr_in *ain = (sockaddr_in *)&sock_addr; + proxy_port.inbound_ip_.assign(*(struct sockaddr*)(&sock_addr)); + proxy_port.port_ = static_cast((ntohs)(ain->sin_port)); + LOG_INFO("succ init mysql proxy port by inherited fd", K(proxy_port)); + } + return ret; +} + int ObMysqlProxyServerMain::init_mysql_proxy_port(const ObMysqlConfigParams &config_params) { int ret = OB_SUCCESS; - ObMysqlProxyPort &proxy_port = get_global_proxy_port(); + ObMysqlProxyPort &proxy_ipv4_port = get_global_proxy_ipv4_port(); + ObMysqlProxyPort &proxy_ipv6_port = get_global_proxy_ipv6_port(); const ObHotUpgraderInfo &info = get_global_hot_upgrade_info(); + int64_t ip_mode = config_params.ip_listen_mode_; + bool enable_ipv4 = (ip_mode == 1 || ip_mode == 3); + bool enable_ipv6 = (ip_mode == 2 || ip_mode == 3); // init from inherited fd if (info.is_inherited_) { - proxy_port.fd_ = info.fd_; - struct sockaddr sock_addr; - int64_t namelen = sizeof(sock_addr); - memset(&sock_addr, 0, namelen); - if (OB_FAIL(ObSocketManager::getsockname(proxy_port.fd_, &sock_addr , &namelen))) { - LOG_ERROR("fail to get sock name", K(ret), K(ret)); - } else { - struct sockaddr_in *ain = (sockaddr_in *)&sock_addr; - proxy_port.inbound_ip_.assign(sock_addr); - proxy_port.port_ = static_cast((ntohs)(ain->sin_port)); - LOG_INFO("succ init mysql proxy port by inherited fd", K(proxy_port)); + if (enable_ipv4) { + if (OB_FAIL(init_inherited_info(proxy_ipv4_port, info.ipv4_fd_))) { + LOG_WARN("fail to init inherited info", K(ret)); + } + } + + if (OB_SUCC(ret) && enable_ipv6) { + if (OB_FAIL(init_inherited_info(proxy_ipv6_port, info.ipv6_fd_))) { + LOG_WARN("fail to init inherited info", K(ret)); + } } } else { // init from config - proxy_port.port_ = static_cast(config_params.listen_port_); - proxy_port.inbound_ip_ = config_params.local_bound_ip_; - LOG_INFO("succ init mysql proxy port by config", K(proxy_port)); + if (enable_ipv4) { + proxy_ipv4_port.port_ = static_cast(config_params.listen_port_); + proxy_ipv4_port.inbound_ip_ = config_params.local_bound_ip_; + LOG_INFO("succ init mysql proxy ipv4 port by config", K(proxy_ipv4_port)); + } + + if (enable_ipv6) { + proxy_ipv6_port.port_ = static_cast(config_params.listen_port_); + proxy_ipv6_port.inbound_ip_ = config_params.local_bound_ipv6_ip_; + LOG_INFO("succ init mysql proxy ipv6 port by config", K(proxy_ipv6_port)); + } } return ret; } diff --git a/src/obproxy/proxy/mysql/ob_mysql_proxy_server_main.h b/src/obproxy/proxy/mysql/ob_mysql_proxy_server_main.h index 290d21270..01195d510 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_proxy_server_main.h +++ b/src/obproxy/proxy/mysql/ob_mysql_proxy_server_main.h @@ -70,6 +70,7 @@ class ObMysqlProxyServerMain static int start_processor_threads(const ObMysqlConfigParams &config_params); static int init_mysql_proxy_port(const ObMysqlConfigParams &config_params); + static int init_inherited_info(ObMysqlProxyPort &proxy_port, const int fd); }; } // end of namespace proxy diff --git a/src/obproxy/proxy/mysql/ob_mysql_server_session.cpp b/src/obproxy/proxy/mysql/ob_mysql_server_session.cpp index 051d571b1..7409bb54c 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_server_session.cpp +++ b/src/obproxy/proxy/mysql/ob_mysql_server_session.cpp @@ -15,6 +15,7 @@ #include "prometheus/ob_sql_prometheus.h" #include "proxy/mysql/ob_mysql_global_session_manager.h" #include "obutils/ob_proxy_config.h" +#include "utils/ob_proxy_table_define.h" using namespace oceanbase::common; using namespace oceanbase::obproxy::event; @@ -142,7 +143,15 @@ void ObMysqlServerSession::do_io_shutdown(const ShutdownHowToType howto) void ObMysqlServerSession::do_io_close(const int alerrno) { - PROXY_SS_LOG(INFO, "server session do_io_close", K(*this), KP(server_vc_), KP(this)); + bool need_print = true; + if(NULL != client_session_ && + client_session_->get_session_info().get_priv_info().user_name_ == ObProxyTableInfo::DETECT_USERNAME_USER) { + need_print = false; + } + + if (need_print) { + PROXY_SS_LOG(INFO, "server session do_io_close", K(*this), KP(server_vc_), KP(this)); + } if (MSS_ACTIVE == state_) { MYSQL_DECREMENT_DYN_STAT(CURRENT_SERVER_TRANSACTIONS); --server_trans_stat_; @@ -174,9 +183,14 @@ void ObMysqlServerSession::do_io_close(const int alerrno) if (this == client_session_->get_last_bound_server_session()) { client_session_->set_last_bound_server_session(NULL); } - PROXY_SS_LOG(INFO, "server session is closing", K_(ss_id), K_(server_sessid), K_(server_ip), - "cs_id", client_session_->get_cs_id(), - "proxy_sessid", client_session_->get_proxy_sessid()); + if (server_ip_ == client_session_->get_trans_coordinator_ss_addr()) { + client_session_->get_trans_coordinator_ss_addr().reset(); + } + if (need_print) { + PROXY_SS_LOG(INFO, "server session is closing", K_(ss_id), K_(server_sessid), K_(server_ip), + "cs_id", client_session_->get_cs_id(), + "proxy_sessid", client_session_->get_proxy_sessid()); + } } else { PROXY_SS_LOG(INFO, "server session has not bound to client session", K(*this)); } diff --git a/src/obproxy/proxy/mysql/ob_mysql_session_manager.cpp b/src/obproxy/proxy/mysql/ob_mysql_session_manager.cpp index 44f4bb276..01741a120 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_session_manager.cpp +++ b/src/obproxy/proxy/mysql/ob_mysql_session_manager.cpp @@ -187,6 +187,7 @@ int ObServerSessionPool::event_handler(int event, void *data) case VC_EVENT_ERROR: case VC_EVENT_INACTIVITY_TIMEOUT: case VC_EVENT_ACTIVE_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: net_vc = static_cast((static_cast(data))->vc_server_); break; diff --git a/src/obproxy/proxy/mysql/ob_mysql_sm.cpp b/src/obproxy/proxy/mysql/ob_mysql_sm.cpp index 560b37cad..3297af194 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_sm.cpp +++ b/src/obproxy/proxy/mysql/ob_mysql_sm.cpp @@ -68,12 +68,15 @@ #include "omt/ob_conn_table_processor.h" #include "omt/ob_ssl_config_table_processor.h" #include "iocore/net/ob_inet.h" +#include "iocore/eventsystem/ob_shard_scan_all_task.h" #include "prometheus/ob_thread_prometheus.h" +#include "ob_proxy_init.h" #include "common/obsm_utils.h" #include "proxy/mysqllib/ob_proxy_ob20_request.h" #include "proxy/mysqllib/ob_mysql_resp_analyzer.h" #include "obproxy/packet/ob_proxy_packet_writer.h" #include "obproxy/cmd/ob_internal_cmd_processor.h" +#include "engine/ob_proxy_operator_cont.h" using namespace oceanbase::share; using namespace oceanbase::common; @@ -198,7 +201,8 @@ ObMysqlSM::ObMysqlSM() need_renew_cluster_resource_(false), is_in_trans_(true), retry_acquire_server_session_count_(0), start_acquire_server_session_time_(0), skip_plugin_(false), add_detect_server_cnt_(false), enable_cloud_full_username_(false), - enable_client_ssl_(false), enable_server_ssl_(false), config_version_(0) + enable_client_ssl_(false), enable_server_ssl_(false), enable_read_write_split_(false), + enable_transaction_split_(false), enable_ob_protocol_v2_(false), config_version_(0), target_db_server_(NULL) { static bool scatter_inited = false; @@ -230,6 +234,10 @@ inline void ObMysqlSM::cleanup() sm_cluster_resource_->dec_ref(); sm_cluster_resource_ = NULL; } + if (OB_NOT_NULL(target_db_server_)) { + op_free(target_db_server_); + target_db_server_ = NULL; + } } inline void ObMysqlSM::destroy() @@ -478,29 +486,6 @@ inline int ObMysqlSM::setup_client_request_read() ret = OB_ERR_UNEXPECTED; LOG_WARN("client session failed to do_io_read", K_(sm_id), K(ret)); } else { - // consume the ob20 tail crc(4) in client buf reader while analyzed all the mysql packet in ob20 payload - ObClientSessionInfo &client_session_info = get_client_session()->get_session_info(); - - ObProxyProtocol client_proto = get_client_session_protocol(); - bool ob20_req_received_done = client_session_info.ob20_request_.ob20_request_received_done_; - int64_t ob20_req_remain_payload_len = client_session_info.ob20_request_.remain_payload_len_; - LOG_DEBUG("setup client req read", K(client_proto), K(ob20_req_received_done), K(ob20_req_remain_payload_len)); - - if (client_proto == ObProxyProtocol::PROTOCOL_OB20 - && ob20_req_received_done - && ob20_req_remain_payload_len == 0) { - client_session_info.ob20_request_.reset(); - LOG_DEBUG("setup client request read consume ob20 tail crc len 4"); - int64_t read_avail = client_buffer_reader_->read_avail(); - if (OB_LIKELY(read_avail >= OB20_PROTOCOL_TAILER_LENGTH)) { - if (OB_FAIL(client_buffer_reader_->consume(OB20_PROTOCOL_TAILER_LENGTH))) { - LOG_WARN("fail to consume the last crc buffer in client request buffer", K(ret)); - } - } else { - LOG_DEBUG("client buffer reader has consumed all, no need consume the tail 4 crc in buffer", K(read_avail)); - } - } - if (OB_SUCC(ret)) { int64_t read_avail = client_buffer_reader_->read_avail(); if (read_avail > 0 @@ -543,6 +528,9 @@ int ObMysqlSM::state_client_request_read(int event, void *data) milestones_.trans_start_ = get_based_hrtime(); } } + + // record the config of enable_transaction_internal_routing + client_session_->set_proxy_enable_trans_internal_routing(trans_state_.mysql_config_params_->enable_transaction_internal_routing_ && is_enable_ob_protocol_v2()); } if (OB_UNLIKELY(get_global_performance_params().enable_trace_)) { @@ -597,7 +585,8 @@ int ObMysqlSM::state_client_request_read(int event, void *data) } case VC_EVENT_ERROR: - case VC_EVENT_ACTIVE_TIMEOUT: { + case VC_EVENT_ACTIVE_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: { LOG_WARN("ObMysqlSM::state_client_request_read", "event", ObMysqlDebugNames::get_event_name(event), K_(sm_id), "client_vc", client_session_ == NULL ? "NULL" : P(client_session_->get_netvc())); @@ -615,7 +604,8 @@ int ObMysqlSM::state_client_request_read(int event, void *data) } - if (OB_SUCC(ret) && !client_session_->is_proxy_mysql_client_) { + if (OB_SUCC(ret) && !client_session_->is_proxy_mysql_client_ + && RUN_MODE_PROXY == g_run_mode) { ObNetVConnection *vc = client_session_->get_netvc(); if (OB_UNLIKELY(NULL != vc && vc->options_.sockopt_flags_ != trans_state_.mysql_config_params_->client_sock_option_flag_out_)) { @@ -772,8 +762,8 @@ int ObMysqlSM::state_client_request_read(int event, void *data) set_client_wait_timeout(); // no request data to read, reset read trigger and avoid unnecessary reading - ObUnixNetVConnection* vc = static_cast(client_session_->get_netvc()); if (!client_session_->is_proxy_mysql_client_) { + ObUnixNetVConnection* vc = static_cast(client_session_->get_netvc()); if (!handling_ssl_request_) { vc->reset_read_trigger(); } @@ -908,6 +898,7 @@ int ObMysqlSM::state_handle_shard_ddl(int event, void *data) case VC_EVENT_EOS: case VC_EVENT_ACTIVE_TIMEOUT: case VC_EVENT_INACTIVITY_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: LOG_WARN("handle shard ddl meet error, will disconnect", K_(sm_id), "event", ObMysqlDebugNames::get_event_name(event), K(ret)); ret = OB_CONNECT_ERROR; @@ -953,18 +944,20 @@ int ObMysqlSM::process_shard_ddl_result(ObShardDDLStatus *ddl_status) } if (OB_SUCC(ret)) { + ObProxyProtocol client_protocol = get_client_session_protocol(); ObMysqlClientSession *client_session = get_client_session(); + if (ddl_status->is_success()) { const ObMySQLCapabilityFlags &capability = client_session->get_session_info().get_orig_capability_flags(); - if (OB_FAIL(ObMysqlPacketUtil::encode_ok_packet(*buf, seq, 0, capability))) { - LOG_WARN("[ObMysqlSM::do_internal_request] fail to encode login response ok packet", + if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, client_protocol, seq, 0, capability))) { + LOG_WARN("[ObMysqlSM::do_internal_request] fail to encode shard ddl ok packet", K_(sm_id), K(ret)); } } else { int64_t error_code = 0; if (OB_FAIL(get_int_value(ddl_status->get_error_code(), error_code))) { LOG_WARN("fail to get int error code", "errcode", ddl_status->get_error_code(), K(ret)); - } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, + } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, client_protocol, seq, static_cast(-error_code), ddl_status->get_error_message()))) { LOG_WARN("fail to encode err pacekt buf", K(seq), "errmsg", ddl_status->get_error_message(), @@ -987,19 +980,17 @@ int ObMysqlSM::setup_handle_execute_plan() ObShardingSelectLogPlan* plan = NULL; ObProxyOperator* operator_root = NULL; + ObProxyOperatorCont *operator_cont = NULL; + ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; int64_t total_len = client_buffer_reader_->read_avail(); - if (total_len > trans_state_.trans_info_.client_request_.get_packet_meta().pkt_len_) { - total_len = trans_state_.trans_info_.client_request_.get_packet_meta().pkt_len_; + if (total_len > client_request.get_packet_meta().pkt_len_) { + total_len = client_request.get_packet_meta().pkt_len_; } - ObShardProp *shard_prop = client_session_->get_session_info().get_shard_prop(); - ObHRTime execute_timeout = 0; - if (OB_NOT_NULL(shard_prop)) { - execute_timeout = HRTIME_MSECONDS(shard_prop->get_socket_timeout()); - } else { - execute_timeout = client_session_->get_session_info().get_query_timeout(); - } + uint8_t seq = static_cast(client_request.get_packet_meta().pkt_seq_ + 1); + + ObHRTime execute_timeout = get_query_timeout(); // consume data in client buffer reader if (OB_FAIL(client_buffer_reader_->consume(total_len))) { @@ -1013,16 +1004,23 @@ int ObMysqlSM::setup_handle_execute_plan() } else if (OB_NOT_NULL(pending_action_)){ ret = OB_ERR_UNEXPECTED; LOG_WARN("pending_action must be NULL here", K_(pending_action), K_(sm_id), K(ret)); - } else if (OB_FAIL(operator_root->open(this, pending_action_, hrtime_to_msec(execute_timeout)))) { - LOG_WARN("fail to open operator", K_(sm_id), K(execute_timeout), K(ret)); - } else if (OB_FAIL(operator_root->get_next_row())) { - LOG_WARN("fail to get next row", K_(sm_id), K(ret)); - } else if (OB_ISNULL(pending_action_)) { - LOG_WARN("pending action should not be null", K_(sm_id), K(ret)); + } else if (OB_ISNULL(operator_cont = new(std::nothrow) ObProxyOperatorCont(this, &self_ethread()))) { + LOG_WARN("fail to alloc parallel execute cont", K(ret)); + } else if (OB_FAIL(operator_cont->init(operator_root, seq, hrtime_to_msec(execute_timeout)))) { + LOG_WARN("fail to init execute cont", K(ret)); + } else if (OB_ISNULL(g_shard_scan_all_task_processor.schedule_imm(operator_cont, ET_SHARD_SCAN_ALL))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to schedule parallel execute cont", K(ret)); } else { + pending_action_ = &operator_cont->get_action(); client_session_->set_inactivity_timeout(execute_timeout); } + if (OB_FAIL(ret) && OB_LIKELY(NULL != operator_cont)) { + operator_cont->destroy(); + operator_cont = NULL; + } + return ret; } @@ -1034,14 +1032,14 @@ int ObMysqlSM::state_handle_execute_plan(int event, void *data) ObShardingSelectLogPlan* plan = NULL; ObProxyOperator* operator_root = NULL; - pending_action_ = NULL; switch (event) { - case VC_EVENT_READ_COMPLETE: + case ASYNC_PROCESS_DONE_EVENT: + pending_action_ = NULL; if (OB_ISNULL(data)) { ret = OB_ERR_NULL_VALUE; LOG_WARN("data is NULL", K_(sm_id), K(ret)); - } else if (OB_FAIL(process_executor_result(reinterpret_cast(data)))) { + } else if (OB_FAIL(process_executor_result(reinterpret_cast(data)))) { LOG_WARN("fail to process executor result, will disconnect", K_(sm_id), K(ret)); } else { trans_state_.next_action_ = ObMysqlTransact::SM_ACTION_INTERNAL_NOOP; @@ -1051,6 +1049,7 @@ int ObMysqlSM::state_handle_execute_plan(int event, void *data) case VC_EVENT_EOS: case VC_EVENT_ACTIVE_TIMEOUT: case VC_EVENT_INACTIVITY_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: LOG_WARN("handle execute plan meet error, will disconnect", K_(sm_id), "event", ObMysqlDebugNames::get_event_name(event), K(ret)); ret = OB_CONNECT_ERROR; @@ -1067,9 +1066,23 @@ int ObMysqlSM::state_handle_execute_plan(int event, void *data) } } + if (OB_NOT_NULL(pending_action_)) { + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = pending_action_->cancel())) { + LOG_WARN("failed to cancel pending action", K_(pending_action), K_(sm_id), K(tmp_ret)); + } + + if (OB_SUCC(ret)) { + ret = tmp_ret; + } + pending_action_ = NULL; + } + if (OB_ISNULL(plan = client_session_->get_sharding_select_log_plan())) { + ret = OB_ERR_UNEXPECTED; LOG_WARN("select log plan should not be null", K_(sm_id), K(ret)); } else if (OB_ISNULL(operator_root = plan->get_plan_root())) { + ret = OB_ERR_UNEXPECTED; LOG_WARN("operator should not be null", K_(sm_id), K(ret)); } else { operator_root->close(); @@ -1084,12 +1097,10 @@ int ObMysqlSM::state_handle_execute_plan(int event, void *data) return VC_EVENT_NONE; } -int ObMysqlSM::process_executor_result(ObProxyResultResp *result_resp) +int ObMysqlSM::process_executor_result(ObIOBufferReader *resp_reader) { int ret = OB_SUCCESS; - ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; - uint8_t seq = static_cast(client_request.get_packet_meta().pkt_seq_ + 1); ObMIOBuffer *buf = NULL; if (NULL != trans_state_.internal_buffer_) { @@ -1104,15 +1115,33 @@ int ObMysqlSM::process_executor_result(ObProxyResultResp *result_resp) if (OB_SUCC(ret)) { ObMysqlClientSession *client_session = get_client_session(); - if (result_resp->is_resultset_resp()) { - if (OB_FAIL(ObProxyPacketWriter::write_executor_resp_packet(buf, client_session, seq, result_resp))) { - LOG_WARN("fail to build shard scan resp", K(ret)); + ObProxyProtocol client_protocol = get_client_session_protocol(); + + if (client_protocol == ObProxyProtocol::PROTOCOL_OB20) { + Ob20ProtocolHeader &ob20_head = client_session->get_session_info().ob20_request_.ob20_header_; + uint8_t compressed_seq = static_cast(client_session->get_compressed_seq() + 1); + Ob20ProtocolHeaderParam ob20_head_param(client_session->get_cs_id(), ob20_head.request_id_, compressed_seq, + compressed_seq, true, false, false, + client_session->is_client_support_new_extra_info(), + client_session->is_trans_internal_routing()); + if (OB_FAIL(ObProto20Utils::consume_and_compress_data(resp_reader, buf, + resp_reader->read_avail(), ob20_head_param))) { + LOG_WARN("fail to consume and compress data for executor response packet in ob20", K(ret)); + } else { + LOG_DEBUG("succ to executor response in ob20 packet"); } } else { - if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, seq, result_resp->get_err_code(), - result_resp->get_err_msg()))) { - LOG_WARN("fail to encode err pacekt buf", K(seq), "errmsg", result_resp->get_err_msg(), - "errcode", result_resp->get_err_code(), K(ret)); + int64_t data_size = resp_reader->read_avail(); + int64_t bytes_written = 0; + if (OB_FAIL(buf->remove_append(resp_reader, bytes_written))) { + LOG_ERROR("Error while remove_append to buf", "Attempted size", data_size, + "wrote size", bytes_written, K(ret)); + } else if (OB_UNLIKELY(bytes_written != data_size)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected result", "Attempted size", data_size, + "wrote size", bytes_written, K(ret)); + } else { + LOG_DEBUG("succ to write to client", "Attempted size", bytes_written); } } } @@ -1137,8 +1166,7 @@ int ObMysqlSM::handle_shard_request(bool &need_response_for_stmt, bool &need_wai ObDbConfigLogicDb *db_info = NULL; if (!session_info.is_sharding_user() - || parse_result.is_shard_special_cmd() - || ObProxyShardUtils::is_special_db(trans_state_)) { + || parse_result.is_shard_special_cmd()) { // do nothing } else { if (obmysql::OB_MYSQL_COM_FIELD_LIST == req_cmd) { @@ -1146,10 +1174,12 @@ int ObMysqlSM::handle_shard_request(bool &need_response_for_stmt, bool &need_wai LOG_WARN("com_field_list cmd is unsupported for sharding table", K(ret)); } else if (obmysql::OB_MYSQL_COM_QUERY != req_cmd) { //do nothing - } else if (parse_result.is_invalid_stmt() && parse_result.has_shard_comment()) { - ret = OB_ERR_PARSER_SYNTAX; - LOG_WARN("fail to parse shard sql with shard comment", - "sql", client_request.get_sql(), K(ret)); + } else if (ObProxyShardUtils::is_special_db(parse_result)) { + if (OB_FAIL(ObProxyShardUtils::handle_information_schema_request(*client_session_, + trans_state_, + *client_buffer_reader_))) { + LOG_WARN("fail to handle information schema request", K(ret)); + } } else { // get logic db and check auth if (OB_FAIL(ObProxyShardUtils::get_logic_db_info(trans_state_, @@ -1164,14 +1194,24 @@ int ObMysqlSM::handle_shard_request(bool &need_response_for_stmt, bool &need_wai LOG_WARN("fail to check shard request", K(ret)); } else if (parse_result.is_dual_request()) { //do nothing + } else if (parse_result.is_ddl_stmt()) { + const ObString runtime_env = get_global_proxy_config().runtime_env.str(); + if (0 == runtime_env.case_compare(OB_PROXY_DBP_RUNTIME_ENV)) { + if (OB_FAIL(ObProxyShardUtils::handle_ddl_request(this, *client_session_, trans_state_, *db_info, need_wait_callback))) { + LOG_WARN("fail to handle ddl request", K(ret)); + } + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("ddl stmt is unsupported for sharding table", K(ret)); + } } else if (db_info->is_single_shard_db_table()) { // sindle db table - if (OB_FAIL(ObProxyShardUtils::handle_single_shard_request(this, *client_session_, - trans_state_, *client_buffer_reader_, *db_info, need_wait_callback))) { + if (OB_FAIL(ObProxyShardUtils::handle_single_shard_request(*client_session_, + trans_state_, *client_buffer_reader_, *db_info))) { LOG_WARN("fail to handle single shard request", K(ret)); } - } else if (OB_FAIL(ObProxyShardUtils::handle_shard_request(this, *client_session_, - trans_state_, *client_buffer_reader_, *db_info, need_wait_callback))) { + } else if (OB_FAIL(ObProxyShardUtils::handle_shard_request(*client_session_, + trans_state_, *client_buffer_reader_, *db_info))) { LOG_WARN("fail to handle shard request", K(ret)); } } @@ -1726,14 +1766,18 @@ inline bool ObMysqlSM::check_connection_throttle() bool ObMysqlSM::can_pass_white_list() { bool can_pass = false; - ObStringKV string_kv; - ObClientSessionInfo &session_info = client_session_->get_session_info(); - ObHSRResult &hsr = session_info.get_login_req().get_hsr_result(); - ObUnixNetVConnection* unix_vc = static_cast(client_session_->get_netvc()); - if (OB_UNLIKELY(NULL == unix_vc)) { - LOG_WARN("invalid unix_vc"); - } else if (get_global_white_list_table_processor().can_ip_pass(hsr.cluster_name_, hsr.tenant_name_, hsr.user_name_, unix_vc->get_real_client_ip(), true)) { + if (RUN_MODE_CLIENT == g_run_mode) { can_pass = true; + } else { + ObStringKV string_kv; + ObClientSessionInfo &session_info = client_session_->get_session_info(); + ObHSRResult &hsr = session_info.get_login_req().get_hsr_result(); + ObUnixNetVConnection* unix_vc = static_cast(client_session_->get_netvc()); + if (OB_UNLIKELY(NULL == unix_vc)) { + LOG_WARN("invalid unix_vc"); + } else if (get_global_white_list_table_processor().can_ip_pass(hsr.cluster_name_, hsr.tenant_name_, hsr.user_name_, unix_vc->get_real_client_addr())) { + can_pass = true; + } } return can_pass; @@ -1783,16 +1827,22 @@ int ObMysqlSM::analyze_capacity_flag_from_client() } // whether client truely support ob2.0 or not - if (!session_info.is_client_support_ob20_protocol() - || !is_client_send_client_mode) { - // reset ob2.0 cap - uint64_t client_cap = session_info.get_client_ob_capability(); - client_cap &= ~(OB_CAP_OB_PROTOCOL_V2); - session_info.set_client_ob_capability(client_cap); + // whether proxy config flag set or not + if (OB_SUCC(ret)) { + uint64_t origin_client_cap = session_info.get_client_ob_capability(); + if (!session_info.is_client_support_ob20_protocol() + || !is_client_send_client_mode + || !get_global_proxy_config().enable_ob_protocol_v2_with_client) { + origin_client_cap &= ~(OB_CAP_OB_PROTOCOL_V2); + session_info.set_client_ob_capability(origin_client_cap); + } } - uint64_t last_client_cap = session_info.get_client_ob_capability(); - LOG_INFO("final client capability flag", K(last_client_cap)); + if (OB_SUCC(ret)) { + const uint64_t last_client_cap = session_info.get_client_ob_capability(); + const bool is_client_support_ob20 = session_info.is_client_support_ob20_protocol(); + LOG_INFO("final client capability flag in negotiation", K(last_client_cap), K(is_client_support_ob20)); + } return ret; } @@ -2002,7 +2052,12 @@ void ObMysqlSM::analyze_mysql_request(ObMysqlAnalyzeStatus &status, const bool i // 3. if BEGIN or START TRANSACTION, try to hold it if (OB_LIKELY(OB_MYSQL_COM_QUERY == req_cmd)) { MYSQL_INCREMENT_DYN_STAT(TOTAL_QUERY_COUNT); - if (OB_UNLIKELY(client_request.get_parse_result().need_hold_start_trans())) { + // Not set start trans sql + // 1. already in transaction + // 2. already hold xa start + if (OB_UNLIKELY(client_request.get_parse_result().need_hold_start_trans() + && trans_state_.is_trans_first_request_ + && !trans_state_.is_hold_xa_start_)) { if (OB_FAIL(session_info.set_start_trans_sql(client_request.get_sql()))) { LOG_WARN("fail to set start transaction sqld", K_(sm_id), K(ret)); } @@ -2027,7 +2082,7 @@ void ObMysqlSM::analyze_mysql_request(ObMysqlAnalyzeStatus &status, const bool i if (OB_FAIL(analyze_login_request(ctx, status))) { LOG_WARN("fail to analyze login request", K(ret)); } - } else if (OB_MYSQL_COM_CHANGE_USER == req_cmd || OB_MYSQL_COM_RESET_CONNECTION == req_cmd) { + } else if (OB_MYSQL_COM_RESET_CONNECTION == req_cmd) { if (session_info.is_sharding_user() || session_info.is_session_pool_client_) { if (OB_FAIL(encode_error_message(OB_NOT_SUPPORTED))) { LOG_WARN("fail to encode unsupport change user error message", K(ret)); @@ -2067,6 +2122,31 @@ void ObMysqlSM::analyze_mysql_request(ObMysqlAnalyzeStatus &status, const bool i } else if (OB_MYSQL_COM_STMT_PREPARE_EXECUTE == req_cmd) { if (OB_FAIL(analyze_ps_prepare_execute_request())) { LOG_WARN("fail to analyze ps prepare execute request", K(ret)); + // Not set start trans sql + // 1. already in transaction + // 2. already hold xa start + // 3. already hold begin + } else if (get_global_proxy_config().enable_xa_route + && client_request.get_parse_result().need_hold_xa_start() + && trans_state_.is_trans_first_request_ + && !trans_state_.is_hold_start_trans_ + && !trans_state_.is_hold_xa_start_) { + LOG_DEBUG("[ObMysqlSM::analyze_mysql_request] save xa start request packet"); + session_info.set_start_trans_sql(client_request.get_req_pkt()); + // save the xa start ps id, session_info.ps_id_ will be reset at ObMysqlSM::setup_cmd_complete() + session_info.set_xa_start_ps_id(session_info.get_client_ps_id()); + } + } else if (OB_MYSQL_COM_CHANGE_USER == req_cmd) { + if (OB_UNLIKELY(session_info.is_sharding_user() || client_session_->using_ldg())) { + if (OB_FAIL(encode_error_message(OB_NOT_SUPPORTED))) { + LOG_WARN("fail to encode unsupport change user error message", K(ret)); + } else { + LOG_WARN("sharding or ldg not support change user", K(session_info.is_sharding_user()), + KPC_(client_session), K(ret)); + } + status = ANALYZE_ERROR; + } else if (OB_FAIL(analyze_change_user_request())) { + LOG_WARN("fail to analyze change user request", K(ret)); } } else { // do nothing @@ -2106,6 +2186,129 @@ void ObMysqlSM::analyze_mysql_request(ObMysqlAnalyzeStatus &status, const bool i milestone_diff(milestones_.client_.analyze_request_begin_, milestones_.client_.analyze_request_end_); } +int ObMysqlSM::analyze_change_user_request() +{ + int ret = OB_SUCCESS; + ObClientSessionInfo& client_info = client_session_->get_session_info(); + // len represents the size of the entire OB_MYSQL_COM_CHANGE_USER message + int64_t len = trans_state_.trans_info_.client_request_.get_packet_meta().pkt_len_; + if (OB_UNLIKELY(len <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid len", K(len), K(ret)); + } else { + ObVariableLenBuffer<128> user_buffer; + if (OB_FAIL(user_buffer.init(len))) { + LOG_WARN("fail to init user buffer", K(ret)); + } else { + char *start = const_cast(user_buffer.ptr()); + char *written_pos = client_buffer_reader_->copy(start, len, 0); + if (OB_UNLIKELY(written_pos != start + len)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("write pos not expected", K(written_pos), K(start), K(len), K(ret)); + } else if (OB_FAIL(client_buffer_reader_->consume_all())) { + LOG_WARN("client_buffer_reader consume_all failed", K(ret)); + } else { + ObMIOBuffer *write_buffer = client_buffer_reader_->writer(); + // buf points to the username part of OB_MYSQL_COM_CHANGE_USER + char *buf = start + MYSQL_NET_META_LENGTH; + ObString username = ObString::make_string(buf); + int64_t name_len = strlen(buf); + ObHSRResult result; + int64_t written_len = 0; + ObString& tenant_name = client_info.get_login_req().get_hsr_result().tenant_name_; + ObString& cluster_name = client_info.get_login_req().get_hsr_result().cluster_name_; + if (OB_FAIL(ObProxyAuthParser::parse_full_user_name(username, tenant_name, cluster_name, result))) { + LOG_WARN("parse full user name failed", K(ret)); + } else if (OB_FAIL(write_buffer->write(start, MYSQL_NET_META_LENGTH, written_len))) { + LOG_WARN("fail to write header", K(ret)); + } else if (OB_UNLIKELY(MYSQL_NET_META_LENGTH != written_len)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not write completely", K(written_len), K(ret)); + } + // write username + if (OB_SUCC(ret)) { + if (OB_FAIL(write_buffer->write(result.user_name_.ptr(), result.user_name_.length(), written_len))) { + LOG_WARN("fail to write username", K(ret)); + } else if (OB_UNLIKELY(result.user_name_.length() != written_len)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not write completely", K(written_len), K(ret)); + } + } + // write tenant name + int64_t new_name_len = 0; + if (OB_SUCC(ret)) { + if (result.has_tenant_username_ && result.has_cluster_username_) { + if (OB_UNLIKELY(tenant_name != result.tenant_name_ || cluster_name != result.cluster_name_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("name not match", K(result), K(tenant_name), K(cluster_name), K(ret)); + } + } else if (result.has_tenant_username_ && !result.has_cluster_username_) { + if (OB_UNLIKELY(tenant_name != result.tenant_name_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("name not match", K(result), K(tenant_name), K(ret)); + } + } else if (!result.has_tenant_username_ && !result.has_cluster_username_) { + // do nothing + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("should not come here", K(result), K(ret)); + } + if (OB_SUCC(ret)) { + if (OB_FAIL(write_buffer->write("@", 1, written_len))) { + LOG_WARN("fail to write @", K(ret)); + } else if (1 != written_len) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not write completely", K(written_len), K(ret)); + } else if (OB_FAIL(write_buffer->write(tenant_name.ptr(), tenant_name.length(), written_len))) { + LOG_WARN("fail to write tenant_name", K(ret)); + } else if (tenant_name.length() != written_len) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not write completely", K(written_len), K(ret)); + } else { + new_name_len = tenant_name.length() + result.user_name_.length() + 1; + } + } + LOG_DEBUG("change user name", K(result), K(tenant_name)); + } + // Write the rest of the message + if (OB_SUCC(ret)) { + if (OB_FAIL(write_buffer->write("\0", 1, written_len))) { + LOG_WARN("fail to write string null", K(ret)); + } else if (1 != written_len) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not write completely", K(written_len), K(ret)); + } else if (OB_FAIL(write_buffer->write(buf + name_len + 1, len - MYSQL_NET_META_LENGTH - name_len - 1, written_len))) { + LOG_WARN("fail to write left buffer", K(ret)); + } else if (written_len != len - MYSQL_NET_META_LENGTH - name_len - 1) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not write completely", K(written_len), K(ret)); + } else if (get_client_session_protocol() == ObProxyProtocol::PROTOCOL_OB20) { + char crc_buf[4]; + memset(crc_buf, 0, sizeof(crc_buf)); + if (OB_FAIL(write_buffer->write(crc_buf, 4, written_len))) { + LOG_WARN("fail to write crc_buf", K(ret)); + } else if (4 != written_len) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not write completely", K(written_len), K(ret)); + } + } + } + // Re-modify the message length + if (OB_SUCC(ret)) { + uint32_t new_len = static_cast(len - MYSQL_NET_HEADER_LENGTH + new_name_len - name_len); + client_buffer_reader_->replace(reinterpret_cast(&new_len), 3, 0); + ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; + client_request.get_packet_meta().pkt_len_ = new_len + MYSQL_NET_HEADER_LENGTH; + if (OB_FAIL(client_request.add_request(client_buffer_reader_, trans_state_.mysql_config_params_->request_buffer_length_))) { + LOG_WARN("fail to add com request", K(ret)); + } + } + } + } + } + return ret; +} + int ObMysqlSM::analyze_login_request(ObRequestAnalyzeCtx &ctx, ObMysqlAnalyzeStatus &status) { int ret = OB_SUCCESS; @@ -2116,7 +2319,7 @@ int ObMysqlSM::analyze_login_request(ObRequestAnalyzeCtx &ctx, ObMysqlAnalyzeSta ObUnixNetVConnection* unix_vc = static_cast(client_session_->get_netvc()); if (NULL == unix_vc) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("client unix vc is null", K(ret)); + LOG_WARN("client entry vc is null", K(ret)); } else if (!client_session_->is_proxy_mysql_client_ && hsr.response_.is_ssl_request() && !unix_vc->ssl_connected()) { if (OB_FAIL(unix_vc->ssl_init(ObUnixNetVConnection::SSL_SERVER, client_session_->get_vip_cluster_name(), @@ -2204,11 +2407,7 @@ int ObMysqlSM::analyze_login_request(ObRequestAnalyzeCtx &ctx, ObMysqlAnalyzeSta if (!client_session_->is_proxy_mysql_client_) { net::ObIpEndpoint client_addr; - if (client_session_->is_need_convert_vip_to_tname()) { - net::ops_ip_copy(client_addr, client_session_->get_netvc()->get_real_client_addr()); - } else { - net::ops_ip_copy(client_addr, client_session_->get_netvc()->get_remote_addr()); - } + net::ops_ip_copy(client_addr, ops_ip_sa_cast(client_session_->get_real_client_addr().get_sockaddr())); LOG_INFO("client login audit", K(client_addr), K(hsr.cluster_name_), K(hsr.tenant_name_), K(hsr.user_name_), "status", ret == OB_SUCCESS && status != ANALYZE_ERROR ? "success" : "failed"); } @@ -2227,24 +2426,19 @@ int ObMysqlSM::do_analyze_ps_prepare_request(const ObString &ps_sql) ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; ObPsEntry *ps_entry = NULL; + ObGlobalPsEntry *global_ps_entry = NULL; ObPsIdEntry *ps_id_entry = NULL; - bool is_new_ps_entry = false; - - ObBasePsEntryCache &ps_entry_cache = self_ethread().get_ps_entry_cache(); - ps_entry_cache.get_ps_entry(ps_sql, ps_entry); - - if (NULL == ps_entry) { - if (OB_FAIL(ObPsEntry::alloc_and_init_ps_entry(ps_sql, client_request.get_parse_result(), ps_entry))) { - LOG_WARN("fail to alloc and init ps entry", K(ret)); - } else if (OB_FAIL(ps_entry_cache.set_ps_entry(ps_entry))) { - LOG_WARN("fail to add ps entry to cache", K(ret)); - if (OB_LIKELY(NULL != ps_entry)) { - ps_entry->destroy(); - ps_entry = NULL; - } + if (get_global_proxy_config().enable_global_ps_cache) { + ObBasePsEntryGlobalCache& ps_entry_global_cache = get_global_ps_entry_cache(); + if (OB_FAIL(ps_entry_global_cache.acquire_or_create_ps_entry(ps_sql, client_request.get_parse_result(), global_ps_entry))) { + LOG_WARN("create ps entry failed", K(ps_sql), K(ret)); } else { - ps_entry->inc_ref(); - is_new_ps_entry = true; + ps_entry = global_ps_entry; + } + } else { + ObBasePsEntryThreadCache &ps_entry_thread_cache = self_ethread().get_ps_entry_cache(); + if (OB_FAIL(ps_entry_thread_cache.acquire_or_create_ps_entry(ps_sql, client_request.get_parse_result(), ps_entry))) { + LOG_WARN("create ps entry failed", K(ps_sql), K(ret)); } } @@ -2254,21 +2448,20 @@ int ObMysqlSM::do_analyze_ps_prepare_request(const ObString &ps_sql) LOG_WARN("fail to alloc ps id entry", K(ret)); } else if (OB_FAIL(session_info.add_ps_id_entry(ps_id_entry))) { LOG_WARN("fail to add ps id entry", KPC(ps_entry), K(ret)); - if (OB_LIKELY(NULL != ps_id_entry)) { - ps_id_entry->destroy(); - ps_id_entry = NULL; - } } else { // set current ps info session_info.set_ps_entry(ps_id_entry->ps_entry_); session_info.set_client_ps_id(ps_id_entry->ps_id_); session_info.set_ps_id_entry(ps_id_entry); } - } - - if (is_new_ps_entry) { - ps_entry->dec_ref(); - ps_entry = NULL; + if (OB_FAIL(ret)) { + if (OB_LIKELY(NULL != ps_id_entry)) { + ps_id_entry->destroy(); + ps_id_entry = NULL; + } else if (OB_LIKELY(NULL == ps_id_entry && NULL != ps_entry)) { + ps_entry->dec_ref(); + } + } } return ret; } @@ -2567,7 +2760,7 @@ int ObMysqlSM::analyze_text_ps_prepare_request(const ObRequestAnalyzeCtx &ctx) } int ObMysqlSM::do_parse_text_ps_prepare_sql(char*& text_ps_prepare_buf, - int64_t& text_ps_prepare_buf_len, + int64_t& text_ps_prepare_buf_len, ObString& text_ps_sql, const ObRequestAnalyzeCtx& ctx) { int ret = OB_SUCCESS; @@ -2579,8 +2772,8 @@ int ObMysqlSM::do_parse_text_ps_prepare_sql(char*& text_ps_prepare_buf, // This prepare statement needs to be parsed once ObProxyTextPsInfo prepare_info = client_request.get_parse_result().text_ps_info_; if (1 == prepare_info.param_count_) { - ObProxyTextPsParam ¶m = prepare_info.params_.at(0); - ObString user_name = param.str_value_.string_; + ObProxyTextPsParam* param = prepare_info.params_.at(0); + ObString user_name = param->str_value_.config_string_; ObObj user_value; if (OB_FAIL(cs_info.get_user_variable_value(user_name, user_value))) { LOG_WARN("get user variable failed", K(ret), K(user_name)); @@ -2635,7 +2828,7 @@ int ObMysqlSM::do_analyze_text_ps_prepare_request(const ObString& text_ps_sql) ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; ObTextPsEntry *text_ps_entry = NULL; - bool is_new_text_ps_entry = false; + ObGlobalTextPsEntry *global_text_ps_entry = NULL; ObString text_ps_name = client_request.get_parse_result().get_text_ps_name(); ObTextPsNameEntry *text_ps_name_entry = session_info.get_text_ps_name_entry(text_ps_name); LOG_DEBUG("prepare text ps name", K(client_request.get_parse_result().get_text_ps_name())); @@ -2661,21 +2854,17 @@ int ObMysqlSM::do_analyze_text_ps_prepare_request(const ObString& text_ps_sql) } } - ObBasePsEntryCache& text_ps_entry_cache = self_ethread().get_text_ps_entry_cache(); - text_ps_entry_cache.get_text_ps_entry(text_ps_sql, text_ps_entry); - if (OB_SUCC(ret) && NULL == text_ps_entry) { - if (OB_FAIL(ObTextPsEntry::alloc_and_init_text_ps_entry( - text_ps_sql, client_request.get_parse_result(), text_ps_entry))) { - LOG_WARN("fail to alloc and init text ps entry", K(ret)); - } else if (OB_FAIL(text_ps_entry_cache.set_text_ps_entry(text_ps_entry))) { - LOG_WARN("fail to add text ps entry to cache", K(ret)); - if (OB_LIKELY(NULL != text_ps_entry)) { - text_ps_entry->destroy(); - text_ps_entry = NULL; - } + if (get_global_proxy_config().enable_global_ps_cache) { + ObBasePsEntryGlobalCache& text_ps_entry_global_cache = get_global_text_ps_entry_cache(); + if (OB_FAIL(text_ps_entry_global_cache.acquire_or_create_ps_entry(text_ps_sql, client_request.get_parse_result(), global_text_ps_entry))) { + LOG_WARN("create text ps entry failed", K(text_ps_sql), K(ret)); } else { - text_ps_entry->inc_ref(); - is_new_text_ps_entry = true; + text_ps_entry = global_text_ps_entry; + } + } else { + ObBasePsEntryThreadCache &text_ps_entry_thread_cache = self_ethread().get_text_ps_entry_cache(); + if (OB_FAIL(text_ps_entry_thread_cache.acquire_or_create_ps_entry(text_ps_sql, client_request.get_parse_result(), text_ps_entry))) { + LOG_WARN("create text ps entry failed", K(text_ps_sql), K(ret)); } } @@ -2685,25 +2874,21 @@ int ObMysqlSM::do_analyze_text_ps_prepare_request(const ObString& text_ps_sql) LOG_WARN("fail to alloc text ps name entry", K(ret)); } else if (OB_FAIL(session_info.add_text_ps_name_entry(text_ps_name_entry))) { LOG_WARN("fail to add text ps name entry", KPC(text_ps_name_entry), K(ret)); + } else { + text_ps_name_entry->version_ = client_session_->inc_and_get_ps_id(); + session_info.set_client_ps_id(text_ps_name_entry->version_); + session_info.set_text_ps_name_entry(text_ps_name_entry); + LOG_DEBUG("session info add text ps name", K(client_request.get_parse_result().get_text_ps_name())); + } + if (OB_FAIL(ret)) { if (OB_LIKELY(NULL != text_ps_name_entry)) { text_ps_name_entry->destroy(); text_ps_name_entry = NULL; + } else if (OB_LIKELY(NULL == text_ps_name_entry && NULL != text_ps_entry)) { + text_ps_entry->destroy(); } - } else { - text_ps_name_entry->version_ = client_session_->inc_and_get_ps_id(); } } - - if (OB_SUCC(ret)) { - session_info.set_client_ps_id(text_ps_name_entry->version_); - session_info.set_text_ps_name_entry(text_ps_name_entry); - LOG_DEBUG("session info add text ps name", K(client_request.get_parse_result().get_text_ps_name())); - } - - if (is_new_text_ps_entry) { - text_ps_entry->dec_ref(); - text_ps_entry = NULL; - } return ret; } @@ -2854,6 +3039,7 @@ int ObMysqlSM::state_watch_for_client_abort(int event, void *data) case VC_EVENT_ERROR: case VC_EVENT_ACTIVE_TIMEOUT: case VC_EVENT_INACTIVITY_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: if (tunnel_.is_tunnel_active()) { // Check to see if the client is part of the tunnel. // If so forward the event to the tunnel. Otherwise, @@ -2883,6 +3069,16 @@ int ObMysqlSM::state_watch_for_client_abort(int event, void *data) milestones_.client_.client_end_ = get_based_hrtime(); set_client_abort(ObMysqlTransact::ABORTED, event); update_congestion_entry(event); + if (OB_MYSQL_COM_QUIT != trans_state_.trans_info_.client_request_.get_packet_meta().cmd_) { + if (NULL != trans_state_.congestion_entry_) { + trans_state_.congestion_entry_->set_client_feedback_failed_at(event::get_hrtime()); + if (trans_state_.congestion_entry_->client_feedback_congested_) { + if (NULL != sm_cluster_resource_) { + sm_cluster_resource_->alive_addr_set_.set_refactored(trans_state_.congestion_entry_->server_ip_); + } + } + } + } terminate_sm_ = true; break; @@ -3143,7 +3339,6 @@ int ObMysqlSM::state_observer_open(int event, void *data) trans_state_.current_.send_action_ = ObMysqlTransact::SERVER_SEND_HANDSHAKE; } LOG_DEBUG("succ to establish server sesssion", K_(sm_id)); - handle_observer_open(); } } @@ -3228,6 +3423,7 @@ int ObMysqlSM::state_server_response_read(int event, void *data) // fall through case VC_EVENT_ERROR: case VC_EVENT_ACTIVE_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: LOG_WARN("ObMysqlSM::state_server_response_read", "event", ObMysqlDebugNames::get_event_name(event), K_(sm_id)); // Error handling function @@ -3279,8 +3475,7 @@ int ObMysqlSM::state_server_response_read(int event, void *data) } bool need_receive_completed = false; - if (OB_UNLIKELY((NULL != client_session_ && client_session_->is_proxy_mysql_client_) - || ObMysqlTransact::SERVER_SEND_REQUEST != trans_state_.current_.send_action_)) { + if (ObMysqlTransact::SERVER_SEND_REQUEST != trans_state_.current_.send_action_) { need_receive_completed = true; } @@ -3441,7 +3636,8 @@ ObProxyProtocol ObMysqlSM::get_server_session_protocol() const if (NULL == server_session_ || (!server_session_->is_checksum_supported() && !server_session_->is_ob_protocol_v2_supported()) || ObMysqlTransact::SERVER_SEND_SAVED_LOGIN == trans_state_.current_.send_action_ || ObMysqlTransact::SERVER_SEND_LOGIN == trans_state_.current_.send_action_ - || ObMysqlTransact::SERVER_SEND_HANDSHAKE == trans_state_.current_.send_action_) { + || ObMysqlTransact::SERVER_SEND_HANDSHAKE == trans_state_.current_.send_action_ + || ObMysqlTransact::is_binlog_request(trans_state_)) { return ObProxyProtocol::PROTOCOL_NORMAL; } else if (server_session_->is_ob_protocol_v2_supported()) { return ObProxyProtocol::PROTOCOL_OB20; @@ -3613,7 +3809,9 @@ inline int ObMysqlSM::handle_first_compress_response_packet(ObMysqlAnalyzeStatus if (server_buffer_reader_->is_read_avail_more_than(MYSQL_COMPRESSED_HEALDER_LENGTH)) { ObMysqlCompressAnalyzer::AnalyzeMode mode; - if (!need_receive_completed || ObMysqlTransact::SERVER_SEND_REQUEST != trans_state_.current_.send_action_) { + if (ObMysqlTransact::SERVER_SEND_XA_START == trans_state_.current_.send_action_) { + mode = ObMysqlCompressAnalyzer::DECOMPRESS_MODE; + } else if (!need_receive_completed || ObMysqlTransact::SERVER_SEND_REQUEST != trans_state_.current_.send_action_) { mode = ObMysqlCompressAnalyzer::SIMPLE_MODE; } else { mode = ObMysqlCompressAnalyzer::DECOMPRESS_MODE; @@ -3838,6 +4036,7 @@ inline int ObMysqlSM::handle_first_normal_response_packet(ObMysqlAnalyzeStatus & bool is_autocommit_0 = false; if (OB_FAIL(client_session_->get_session_info().field_mgr_.get_common_sys_variable_value("autocommit", obj))) { LOG_DEBUG("fail to get autocommit val", K(ret)); + ret = OB_SUCCESS; } else if (obj.get_int() == 0) { LOG_DEBUG("autocommit is 0"); is_autocommit_0 = true; @@ -3845,7 +4044,8 @@ inline int ObMysqlSM::handle_first_normal_response_packet(ObMysqlAnalyzeStatus & if (OB_LIKELY(server_buffer_reader_->is_read_avail_more_than(MYSQL_NET_META_LENGTH))) { if (OB_UNLIKELY(!client_session_->get_session_info().is_oceanbase_server() - || trans_state_.mysql_config_params_->is_mysql_routing_mode())) { + || trans_state_.mysql_config_params_->is_mysql_routing_mode() + || ObMysqlTransact::is_binlog_request(trans_state_))) { LOG_DEBUG("handle_first_normal_response_packet", K(trans_state_.current_.state_), K(is_in_trans_), K(is_autocommit_0)); analyzer_.set_server_cmd(trans_state_.trans_info_.sql_cmd_, STANDARD_MYSQL_PROTOCOL_MODE, @@ -4016,18 +4216,11 @@ void ObMysqlSM::analyze_status_after_analyze_mysql_in_ob20_payload(ObMysqlAnalyz ObClientSessionInfo &client_session_info) { int64_t mysql_packet_len = trans_state_.trans_info_.client_request_.get_packet_len(); + int ret = OB_SUCCESS; if (OB_LIKELY(status == ANALYZE_DONE)) { - int ret = OB_SUCCESS; if (OB_UNLIKELY(mysql_packet_len == MYSQL_PACKET_MAX_LENGTH)) { status = ANALYZE_NOT_SUPPORT; LOG_WARN("do not support full mysql packet in ob2.0 payload now", K(status)); - } else if (OB_FAIL(analyze_ob20_remain_after_analyze_mysql_request_done(client_session_info))) { - if (ret == OB_NOT_SUPPORTED) { - status = ANALYZE_NOT_SUPPORT; - } else { - status = ANALYZE_ERROR; - LOG_WARN("fail to analyze ob20 remain after mysql req done", K(ret), K(status)); - } } } else if (OB_UNLIKELY(status == ANALYZE_CONT)) { status = ANALYZE_NOT_SUPPORT; @@ -4037,6 +4230,17 @@ void ObMysqlSM::analyze_status_after_analyze_mysql_in_ob20_payload(ObMysqlAnalyz } else { LOG_WARN("unexpected status after analyze mysql in ob20 payload", K(status)); } + + if (OB_FAIL(analyze_ob20_remain_after_analyze_mysql_request_done(client_session_info))) { + if (OB_LIKELY(status == ANALYZE_DONE)) { + if (ret == OB_NOT_SUPPORTED) { + status = ANALYZE_NOT_SUPPORT; + } else { + status = ANALYZE_ERROR; + LOG_WARN("fail to analyze ob20 remain after mysql req done", K(ret), K(status)); + } + } + } } int ObMysqlSM::analyze_ob20_remain_after_analyze_mysql_request_done(ObClientSessionInfo &client_session_info) @@ -4047,6 +4251,7 @@ int ObMysqlSM::analyze_ob20_remain_after_analyze_mysql_request_done(ObClientSess int64_t remain_payload_len = client_session_info.ob20_request_.remain_payload_len_; if (remain_payload_len < mysql_packet_len) { ret = OB_NOT_SUPPORTED; + client_session_info.ob20_request_.remain_payload_len_ = 0; LOG_WARN("unexpected situation after received total compress packet and total mysql packet", K(ret), K(remain_payload_len), K(mysql_packet_len)); } else { @@ -4340,6 +4545,7 @@ int ObMysqlSM::state_server_request_send(int event, void *data) case VC_EVENT_ERROR: case VC_EVENT_ACTIVE_TIMEOUT: case VC_EVENT_INACTIVITY_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: LOG_WARN("ObMysqlSM::state_server_request_send", "event", ObMysqlDebugNames::get_event_name(event), K_(sm_id)); // if something unusual happened in sending request, also need to get request write time @@ -4885,9 +5091,10 @@ int ObMysqlSM::tunnel_handler_response_transfered(int event, void *data) ret = OB_INNER_STAT_ERROR; LOG_WARN("client_entry or server entry is null, disconnect", K_(client_entry), K(ret)); } else { - // only the first request in one transaction will need to update pl, + // only the first request in one transaction or internal routing transaction will need to update pl, // begin(start transaction), or set autocommit = 0 is not the first request; - if (trans_state_.is_trans_first_request_) { + if ((trans_state_.is_trans_first_request_ || client_session_->is_trans_internal_routing()) + && !ObMysqlTransact::is_binlog_request(trans_state_)) { ObMysqlTransact::handle_pl_update(trans_state_); } @@ -4967,6 +5174,7 @@ int ObMysqlSM::tunnel_handler_server(int event, ObMysqlTunnelProducer &p) switch (event) { case VC_EVENT_INACTIVITY_TIMEOUT: case VC_EVENT_ACTIVE_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: case VC_EVENT_ERROR: // fall through case VC_EVENT_EOS: @@ -4978,6 +5186,7 @@ int ObMysqlSM::tunnel_handler_server(int event, ObMysqlTunnelProducer &p) trans_state_.current_.state_ = ObMysqlTransact::ACTIVE_TIMEOUT; break; case VC_EVENT_ERROR: + case VC_EVENT_DETECT_SERVER_DEAD: trans_state_.current_.state_ = ObMysqlTransact::CONNECTION_ERROR; break; case VC_EVENT_EOS: @@ -5165,7 +5374,8 @@ void ObMysqlSM::print_mysql_complete_log(ObMysqlTunnelProducer *p) bool print_warn_log = false; bool print_info_log = false; if (OB_LIKELY(NULL != client_session_)) { - if (OB_UNLIKELY(result.is_error_resp() && client_session_->is_proxy_mysql_client_)) { + if (OB_UNLIKELY(result.is_error_resp() && client_session_->is_proxy_mysql_client_ + && client_session_->get_session_info().get_priv_info().user_name_ != ObProxyTableInfo::DETECT_USERNAME_USER)) { if (result.is_not_supported_error()) { print_info_log = true; } else { @@ -5269,8 +5479,7 @@ void ObMysqlSM::update_safe_read_snapshot() ObSafeSnapshotEntry *entry = NULL; bool is_need_force_sync = true; ObAddr last_addr; - last_addr.set_ipv4_addr(trans_state_.server_info_.addr_.get_ip4_host_order(), - static_cast(trans_state_.server_info_.addr_.get_port_host_order())); + last_addr.set_sockaddr(trans_state_.server_info_.addr_.sa_); if (result.is_partition_hit()) { entry = sm_cluster_resource_->safe_snapshot_mgr_.get(last_addr); @@ -5384,7 +5593,7 @@ int ObMysqlSM::trim_ok_packet(ObIOBufferReader &reader) if (OK_PACKET_ACTION_CONSUME == analyze_result.get_ok_packet_action_type()) { if (OB_FAIL(ObProxySessionInfoHandler::analyze_extra_ok_packet( reader, client_session->get_session_info(), - server_session->get_session_info(), need_handle_sysvar, analyze_result))) { + server_session->get_session_info(), need_handle_sysvar, analyze_result, trans_state_.trace_log_))) { LOG_WARN("fail to analyze extra ok packet", K_(sm_id), K(ret)); } } else if (OK_PACKET_ACTION_REWRITE == analyze_result.get_ok_packet_action_type()) { @@ -5399,6 +5608,7 @@ int ObMysqlSM::trim_ok_packet(ObIOBufferReader &reader) trans_state_.is_auth_request_, need_handle_sysvar, analyze_result, + trans_state_.trace_log_, is_save_to_common_sys))) { LOG_WARN("fail to analyze rewrite ok packet", K_(sm_id), K(ret)); } @@ -5417,10 +5627,14 @@ int ObMysqlSM::trim_ok_packet(ObIOBufferReader &reader) // handle other variables if (OB_SUCC(ret)) { + bool is_only_sync_trans_sess = trans_state_.trans_info_.server_response_.get_analyze_result().is_error_resp(); if (OB_FAIL(handle_saved_session_variables())) { LOG_WARN("fail to handle saved session varialbes", K(ret)); - } else if (OB_FAIL(ObProxySessionInfoHandler::save_changed_sess_info( - client_session->get_session_info(), server_session->get_session_info(), analyze_result.get_extra_info()))) { + } else if (OB_FAIL(ObProxySessionInfoHandler::save_changed_sess_info(client_session->get_session_info(), + server_session->get_session_info(), + analyze_result.get_extra_info(), + trans_state_.trace_log_, + is_only_sync_trans_sess))) { LOG_WARN("fail to save changed session info", K(ret)); } } @@ -5459,8 +5673,17 @@ int ObMysqlSM::tunnel_handler_client(int event, ObMysqlTunnelConsumer &c) case VC_EVENT_INACTIVITY_TIMEOUT: case VC_EVENT_ACTIVE_TIMEOUT: case VC_EVENT_ERROR: - LOG_WARN("ObMysqlSM::tunnel_handler_client", "event", - ObMysqlDebugNames::get_event_name(event), K_(sm_id)); + case VC_EVENT_DETECT_SERVER_DEAD: { + // Probe user does not print disconnection log + bool is_detect_user = false; + if (NULL != client_session_ && client_session_->get_session_info().get_priv_info().user_name_ == ObProxyTableInfo::DETECT_USERNAME_USER) { + is_detect_user = true; + } + + if (!is_detect_user) { + LOG_WARN("ObMysqlSM::tunnel_handler_client", "event", + ObMysqlDebugNames::get_event_name(event), K_(sm_id)); + } // The client died or aborted. Check to see // if we should setup a background fill set_client_abort(ObMysqlTransact::ABORTED, event); @@ -5482,7 +5705,7 @@ int ObMysqlSM::tunnel_handler_client(int event, ObMysqlTunnelConsumer &c) // session and client session close_connection = true; break; - + } case VC_EVENT_WRITE_COMPLETE: { c.write_success_ = true; trans_state_.client_info_.abort_ = ObMysqlTransact::DIDNOT_ABORT; @@ -5557,6 +5780,7 @@ int ObMysqlSM::tunnel_handler_request_transfer_client(int event, ObMysqlTunnelPr case VC_EVENT_ERROR: case VC_EVENT_INACTIVITY_TIMEOUT: case VC_EVENT_ACTIVE_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: LOG_WARN("ObMysqlSM::tunnel_handler_request_transfer_client", "event", ObMysqlDebugNames::get_event_name(event), K_(sm_id)); // Did not complete request transfer tunneling. Abort the @@ -5644,6 +5868,7 @@ int ObMysqlSM::tunnel_handler_request_transfer_server(int event, ObMysqlTunnelCo case VC_EVENT_ERROR: case VC_EVENT_INACTIVITY_TIMEOUT: case VC_EVENT_ACTIVE_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: { LOG_WARN("ObMysqlSM::tunnel_handler_request_transfer_server", "event", ObMysqlDebugNames::get_event_name(event), K_(sm_id)); @@ -5781,17 +6006,21 @@ void ObMysqlSM::do_congestion_control_lookup() // 2. cur congestion is avail(base servers has been added) // 3. need pl lookup // 4. not mysql route mode - // + // 5. need use coordinator session in transaction (included in 'need pl lookup') // Attention! when force_retry_congested_, also need do congestion lookup if (OB_UNLIKELY(enable_congestion && sm_cluster_resource_->is_congestion_avail() - && trans_state_.need_pl_lookup_ + && trans_state_.is_need_pl_lookup() && !trans_state_.mysql_config_params_->is_mysql_routing_mode() && !trans_state_.mysql_config_params_->is_mock_routing_mode())) { trans_state_.need_congestion_lookup_ = true; + LOG_DEBUG("need to do congestion lookup", + K(trans_state_.is_need_pl_lookup()), + K(trans_state_.pl_lookup_state_)); } else { LOG_DEBUG("no need do congestion lookup", K_(sm_id), K(enable_congestion), - K(sm_cluster_resource_->is_congestion_avail()), "need_pl_lookup", trans_state_.need_pl_lookup_, + K(sm_cluster_resource_->is_congestion_avail()), + "pl_lookup_state", ObMysqlTransact::get_pl_lookup_state_string(trans_state_.pl_lookup_state_), "force_retry_congestion", trans_state_.force_retry_congested_, "route_mode", trans_state_.mysql_config_params_->server_routing_mode_); trans_state_.need_congestion_lookup_ = false; @@ -5990,6 +6219,75 @@ void ObMysqlSM::do_partition_location_lookup() } } +void ObMysqlSM::do_binlog_location_lookup() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(get_global_performance_params().enable_trace_)) { + milestones_.bl_lookup_begin_ = get_based_hrtime(); + milestones_.bl_lookup_end_ = 0; + } + + LOG_DEBUG("do binlog location lookup"); + MYSQL_SM_SET_DEFAULT_HANDLER(&ObMysqlSM::state_binlog_location_lookup); + if (OB_UNLIKELY(NULL != pending_action_)) { + trans_state_.pll_info_.lookup_success_ = false; + LOG_ERROR("do_binlog_location_lookup, pending_action_ should be NULL", + K_(pending_action), K_(sm_id)); + call_transact_and_set_next_state(NULL); + } else if (trans_state_.server_info_.addr_.is_valid()) { + trans_state_.pll_info_.lookup_success_ = true; + call_transact_and_set_next_state(NULL); + } else { + const ObTableEntryName &name = trans_state_.pll_info_.te_name_; + ObAction *bl_lookup_action_handle = NULL; + bool find_entry = false; + // Obtained from the cache, no longer retrieved from the remote end + ObTableRefHashMap &table_map = self_ethread().get_table_map(); + ObTableEntry *tmp_entry = NULL; + ObTableEntryKey key(name, 0, 0); + tmp_entry = table_map.get(key); + if (OB_LIKELY(NULL != tmp_entry)) { + tmp_entry->renew_last_access_time(); + ObMysqlRouteResult result; + result.table_entry_ = tmp_entry; + result.is_table_entry_from_remote_ = false; + tmp_entry->set_need_force_flush(false); + find_entry = true; + LOG_DEBUG("ObMysqlRoute get table entry succ", KPC(tmp_entry)); + state_binlog_location_lookup(TABLE_ENTRY_EVENT_LOOKUP_DONE, &result); + } + + if (OB_UNLIKELY(!find_entry)) { + ObRouteParam param; + param.cont_ = this; + param.need_pl_route_ = false; + param.force_renew_ = trans_state_.pll_info_.is_force_renew(); + param.is_need_force_flush_ = trans_state_.pll_info_.is_need_force_flush(); + param.mysql_proxy_ = &sm_cluster_resource_->mysql_proxy_; + param.timeout_us_ = hrtime_to_usec(trans_state_.mysql_config_params_->short_async_task_timeout_); + param.name_.shallow_copy(name); + param.cr_version_ = 0; + param.cr_id_ = 0; + + LOG_DEBUG("Doing binlog location lookup", K_(sm_id), K(param)); + bl_lookup_action_handle = NULL; + ret = ObMysqlRoute::get_route_entry(param, sm_cluster_resource_, bl_lookup_action_handle); + } + + if (OB_SUCC(ret)) { + if (NULL == bl_lookup_action_handle) { + // do nothing + } else { + pending_action_ = bl_lookup_action_handle; + } + } else { + trans_state_.pll_info_.lookup_success_ = false; + LOG_WARN("fail to get binlog table entry", K_(sm_id), K(name), K(ret)); + call_transact_and_set_next_state(NULL); + } + } +} + void ObMysqlSM::do_server_addr_lookup() { ObProxyKillQueryInfo *query_info = trans_state_.trans_info_.client_request_.query_info_; @@ -5998,7 +6296,7 @@ void ObMysqlSM::do_server_addr_lookup() // call ObMysqlTransact::handle_server_addr_lookup() to handle fail / success call_transact_and_set_next_state(NULL); - } else if (!trans_state_.need_pl_lookup_) { + } else if (!trans_state_.is_need_pl_lookup()) { // need use last server session query_info->errcode_ = OB_NOT_SUPPORTED; LOG_WARN("[ObMysqlSM::do_server_addr_lookup] As we need use last server session, " @@ -6028,7 +6326,7 @@ void ObMysqlSM::do_server_addr_lookup() // call ObMysqlTransact::handle_server_addr_lookup() to handle fail / success call_transact_and_set_next_state(NULL); } - }//end of trans_state_.need_pl_lookup_ + }//end of is_need_pl_lookup } int ObMysqlSM::state_congestion_control_lookup(int event, void *data) @@ -6059,7 +6357,9 @@ void ObMysqlSM::set_detect_server_info(net::ObIpEndpoint target_addr, int cnt, i if (OB_LIKELY(target_addr.is_valid() && NULL != sm_cluster_resource_ && NULL != client_session_ - && !client_session_->is_proxy_mysql_client_)) { + && !client_session_->is_proxy_mysql_client_ + //Optimize the performance in closed scenes, 1 means accurate detection + && (1 == get_global_proxy_config().server_detect_mode || add_detect_server_cnt_))) { bool found = false; common::DRWLock &server_state_lock1 = sm_cluster_resource_->get_server_state_lock(0); common::DRWLock &server_state_lock2 = sm_cluster_resource_->get_server_state_lock(1); @@ -6069,8 +6369,7 @@ void ObMysqlSM::set_detect_server_info(net::ObIpEndpoint target_addr, int cnt, i sm_cluster_resource_->get_server_state_info(sm_cluster_resource_->server_state_version_); for (int i = 0; !found && i < server_state_info.count(); i++) { ObServerStateSimpleInfo &info = server_state_info.at(i); - ObIpEndpoint addr; - ops_ip_copy(addr.sa_, info.addr_.ip_.v4_, static_cast(info.addr_.port_)); + ObIpEndpoint addr(info.addr_.get_sockaddr()); if (addr == target_addr) { // add_detect_server_cnt_ prevents do_observer_open from failing before, and subtracts 1 from cnt if (cnt > 0 && 1 == get_global_proxy_config().server_detect_mode) { @@ -6131,7 +6430,7 @@ int ObMysqlSM::do_observer_open() if (OB_UNLIKELY(trans_state_.is_rerouted_)) { release_server_session(); } - + if (add_detect_server_cnt_) { set_detect_server_info(trans_state_.pre_server_info_.addr_, -1, 0); } @@ -6322,23 +6621,41 @@ inline int ObMysqlSM::do_oceanbase_internal_observer_open(ObMysqlServerSession * last_session = client_session_->get_server_session(); // if need_pl_lookup is false, we must use last server session - // allow no last server session when OB_MYSQL_COM_STMT_CLOSE/OB_MYSQL_COM_STMT_FETCH and need_pl_lookup_ = false + // allow no last server session when OB_MYSQL_COM_STMT_CLOSE/OB_MYSQL_COM_STMT_FETCH and NEED_PL_LOOKUP obmysql::ObMySQLCmd cmd = trans_state_.trans_info_.sql_cmd_; - if (!trans_state_.need_pl_lookup_ + bool is_text_ps_close = trans_state_.trans_info_.client_request_.get_parse_result().is_text_ps_drop_stmt(); + if (!trans_state_.is_need_pl_lookup() && ((OB_MYSQL_COM_STMT_CLOSE != cmd && OB_MYSQL_COM_STMT_FETCH != cmd - && OB_MYSQL_COM_STMT_RESET != cmd) + && OB_MYSQL_COM_STMT_RESET != cmd + && OB_MYSQL_COM_STMT_GET_PIECE_DATA != cmd + && !is_text_ps_close) || !client_session_->is_need_return_last_bound_ss())) { - if (OB_ISNULL(last_session)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("last server session is NULL, disconnect", K_(sm_id), K(ret)); - } else if (OB_UNLIKELY(last_session->server_ip_ != trans_state_.server_info_.addr_)) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("last server session ip is unexpected", - K_(last_session->server_ip), K_(trans_state_.server_info_.addr), K_(sm_id), K(ret)); - } else { + ObMysqlServerSession *target_session = NULL; + if (trans_state_.pl_lookup_state_ == ObMysqlTransact::USE_COORDINATOR_SESSION) { + if (OB_FAIL(client_session_->acquire_svr_session(trans_state_.server_info_.addr_.sa_, false, target_session))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("acquire coordinator session fail, disconnect", K_(sm_id), K(ret)); + } + LOG_DEBUG("use coordinator server session", K_(sm_id)); + } else if (trans_state_.pl_lookup_state_ == ObMysqlTransact::USE_LAST_SERVER_SESSION){ + target_session = last_session; LOG_DEBUG("use last server session", K_(sm_id)); - selected_session = last_session; + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected pl lookup state", K(trans_state_.pl_lookup_state_)); + } + if (OB_SUCC(ret)) { + if (OB_ISNULL(target_session)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("target server session is NULL, disconnect", K_(sm_id), K(ret)); + } else if (OB_UNLIKELY(target_session->server_ip_ != trans_state_.server_info_.addr_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("target session ip is unexpected", + K_(target_session->server_ip), K_(trans_state_.server_info_.addr), K_(sm_id), K(ret)); + } else { + selected_session = target_session; + } } } else { LOG_DEBUG("sql cmd", K(cmd), K(client_session_->is_session_pool_client())); @@ -6426,6 +6743,7 @@ inline int ObMysqlSM::do_internal_observer_open() int ret = OB_SUCCESS; ObMysqlServerSession *selected_session = NULL; ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; + bool is_in_trans = ObMysqlTransact::is_in_trans(trans_state_); if (OB_LIKELY(client_session_->get_session_info().is_oceanbase_server())) { if (OB_FAIL(do_oceanbase_internal_observer_open(selected_session))) { @@ -6478,20 +6796,36 @@ inline int ObMysqlSM::do_internal_observer_open() "client_session version", client_info.get_session_version(), "server version", server_info.get_session_var_version(), "cmd", cmd); + + trans_state_.trace_log_.log_it("[get_conn]", + "time", get_based_hrtime(), + "lookup", trans_state_.pl_lookup_state_, + "sql_cmd", trans_state_.trans_info_.sql_cmd_, + "stmt_type", trans_state_.trans_info_.client_request_.get_parse_result().get_stmt_type(), + "in_trans", is_in_trans, + "internal_route", get_client_session()->is_trans_internal_routing() && is_in_trans, + "svr", server_session_->server_ip_, + "sessid", server_session_->get_server_sessid()); + if (OB_UNLIKELY(OB_MYSQL_COM_STMT_CLOSE == cmd - || OB_MYSQL_COM_STMT_RESET == cmd)) { + || OB_MYSQL_COM_STMT_RESET == cmd + || ObMysqlTransact::is_binlog_request(trans_state_) + || client_session_->can_direct_send_request_)) { // no need sync var on OB_MYSQL_COM_STMT_CLOSE trans_state_.current_.send_action_ = ObMysqlTransact::SERVER_SEND_REQUEST; } else if (OB_UNLIKELY(client_info.need_reset_database(server_info))) { trans_state_.current_.send_action_ = ObMysqlTransact::SERVER_SEND_USE_DATABASE; - } else if (OB_UNLIKELY(client_info.need_reset_session_vars(server_info))) { + } else if (OB_UNLIKELY(client_info.is_server_support_session_var_sync() && + client_info.need_reset_user_session_vars(server_info))) { + trans_state_.current_.send_action_ = ObMysqlTransact::SERVER_SEND_SESSION_USER_VARS; + } else if (OB_UNLIKELY(!(client_info.is_server_support_session_var_sync()) && + client_info.need_reset_session_vars(server_info))) { trans_state_.current_.send_action_ = ObMysqlTransact::SERVER_SEND_SESSION_VARS; - } else if (OB_UNLIKELY(client_info.need_reset_last_insert_id(server_info))) { - // TODO: current version proxy parse can't judge last_insert_id exactly, - // so we do not judge, whether sql_reuslt has_last_insert_id here - trans_state_.current_.send_action_ = ObMysqlTransact::SERVER_SEND_LAST_INSERT_ID; } else if (OB_UNLIKELY(trans_state_.is_hold_start_trans_)) { trans_state_.current_.send_action_ = ObMysqlTransact::SERVER_SEND_START_TRANS; + } else if (OB_UNLIKELY(trans_state_.is_hold_xa_start_)) { + trans_state_.current_.send_action_ = ObMysqlTransact::SERVER_SEND_XA_START; + LOG_DEBUG("[ObMysqlSM::do_internal_observer_open] set send action SERVER_SEND_XA_START to sync xa start"); } else if (OB_UNLIKELY(((OB_MYSQL_COM_STMT_EXECUTE == cmd) || (OB_MYSQL_COM_STMT_SEND_PIECE_DATA == cmd) || (OB_MYSQL_COM_STMT_SEND_LONG_DATA == cmd)) @@ -6507,6 +6841,16 @@ inline int ObMysqlSM::do_internal_observer_open() } else { if (OB_FAIL(connect_observer())) { LOG_WARN("failed to connection observer", K_(sm_id), K(ret)); + } else { + + trans_state_.trace_log_.log_it("[create_conn]", + "time", get_based_hrtime(), + "lookup", trans_state_.pl_lookup_state_, + "sql_cmd", trans_state_.trans_info_.sql_cmd_, + "stmt_type", trans_state_.trans_info_.client_request_.get_parse_result().get_stmt_type(), + "in_trans", is_in_trans, + "internal_route", get_client_session()->is_trans_internal_routing() && is_in_trans, + "svr", trans_state_.server_info_.addr_); } } } @@ -6577,6 +6921,7 @@ int ObMysqlSM::do_internal_request_for_sharding_init_db(ObMIOBuffer *buf) ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; ObMysqlClientSession *client_session = get_client_session(); ObClientSessionInfo &client_info = client_session->get_session_info(); + ObProxyProtocol client_procotol = get_client_session_protocol(); // handle use db stmt or OB_MYSQL_COM_INIT_DB cmd when sharding LOG_DEBUG("sharding init db"); @@ -6606,9 +6951,11 @@ int ObMysqlSM::do_internal_request_for_sharding_init_db(ObMIOBuffer *buf) LOG_WARN("fail to save user login info", K_(sm_id), K(ret)); } else { // if start trans is hold, we treat this resp is in trans - bool is_in_trans = (trans_state_.is_hold_start_trans_ || ObMysqlTransact::is_in_trans(trans_state_)); + bool is_in_trans = (trans_state_.is_hold_xa_start_ + || trans_state_.is_hold_start_trans_ + || ObMysqlTransact::is_in_trans(trans_state_)); if (OB_FAIL(ObMysqlResponseBuilder::build_ok_resq_with_state_changed(*buf, client_request, *client_session, - is_in_trans))) { + client_procotol, is_in_trans))) { LOG_WARN("[ObMysqlSM::do_internal_request] fail to build ok res", K_(sm_id), K(ret)); } } @@ -6623,12 +6970,13 @@ int ObMysqlSM::do_internal_request_for_sharding_show_db_version(ObMIOBuffer *buf ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; ObMysqlClientSession *client_session = get_client_session(); ObClientSessionInfo &client_info = client_session->get_session_info(); - ObProxyProtocol client_protocol = client_session->get_client_session_protocol(); + ObProxyProtocol client_protocol = get_client_session_protocol(); Ob20ProtocolHeader &ob20_head = client_session->get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session->get_compressed_seq() + 1); Ob20ProtocolHeaderParam ob20_head_param(client_session->get_cs_id(), ob20_head.request_id_, compressed_seq, - compressed_seq, true, false, - client_session->is_client_support_new_extra_info()); + compressed_seq, true, false, false, + client_session->is_client_support_new_extra_info(), + client_session->is_trans_internal_routing()); ObCmdInfo info(static_cast(client_request.get_packet_meta().pkt_seq_ + 1), trans_state_.mysql_config_params_->internal_cmd_mem_limited_, client_protocol, ob20_head_param); @@ -6660,12 +7008,13 @@ int ObMysqlSM::do_internal_request_for_sharding_show_db(ObMIOBuffer *buf) ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; ObMysqlClientSession *client_session = get_client_session(); ObClientSessionInfo &client_info = client_session->get_session_info(); - ObProxyProtocol client_protocol = client_session->get_client_session_protocol(); + ObProxyProtocol client_protocol = get_client_session_protocol(); Ob20ProtocolHeader &ob20_head = client_session->get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session->get_compressed_seq() + 1); Ob20ProtocolHeaderParam ob20_head_param(client_session->get_cs_id(), ob20_head.request_id_, compressed_seq, - compressed_seq, true, false, - client_session->is_client_support_new_extra_info()); + compressed_seq, true, false, false, + client_session->is_client_support_new_extra_info(), + client_session->is_trans_internal_routing()); ObCmdInfo info(static_cast(client_request.get_packet_meta().pkt_seq_ + 1), trans_state_.mysql_config_params_->internal_cmd_mem_limited_, client_protocol, ob20_head_param); @@ -6688,12 +7037,13 @@ int ObMysqlSM::do_internal_request_for_sharding_show_table(ObMIOBuffer *buf) ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; ObMysqlClientSession *client_session = get_client_session(); ObClientSessionInfo &client_info = client_session->get_session_info(); - ObProxyProtocol client_protocol = client_session->get_client_session_protocol(); + ObProxyProtocol client_protocol = get_client_session_protocol(); Ob20ProtocolHeader &ob20_head = client_session->get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session->get_compressed_seq() + 1); Ob20ProtocolHeaderParam ob20_head_param(client_session->get_cs_id(), ob20_head.request_id_, compressed_seq, - compressed_seq, true, false, - client_session->is_client_support_new_extra_info()); + compressed_seq, true, false, false, + client_session->is_client_support_new_extra_info(), + client_session->is_trans_internal_routing()); ObCmdInfo info(static_cast(client_request.get_packet_meta().pkt_seq_ + 1), trans_state_.mysql_config_params_->internal_cmd_mem_limited_, client_protocol, ob20_head_param); @@ -6727,7 +7077,7 @@ int ObMysqlSM::do_internal_request_for_sharding_show_table_status(ObMIOBuffer *b ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; ObMysqlClientSession *client_session = get_client_session(); ObClientSessionInfo &client_info = client_session->get_session_info(); - ObProxyProtocol client_protocol = client_session->get_client_session_protocol(); + ObProxyProtocol client_protocol = get_client_session_protocol(); Ob20ProtocolHeader &ob20_head = client_session->get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session->get_compressed_seq() + 1); @@ -6738,8 +7088,9 @@ int ObMysqlSM::do_internal_request_for_sharding_show_table_status(ObMIOBuffer *b ObString logic_tenant_name; Ob20ProtocolHeaderParam ob20_head_param(client_session->get_cs_id(), ob20_head.request_id_, compressed_seq, - compressed_seq, true, false, - client_session->is_client_support_new_extra_info()); + compressed_seq, true, false, false, + client_session->is_client_support_new_extra_info(), + client_session->is_trans_internal_routing()); ObCmdInfo info(static_cast(client_request.get_packet_meta().pkt_seq_ + 1), trans_state_.mysql_config_params_->internal_cmd_mem_limited_, client_protocol, ob20_head_param); @@ -6761,28 +7112,29 @@ int ObMysqlSM::do_internal_request_for_sharding_show_table_status(ObMIOBuffer *b return ret; } -int ObMysqlSM::do_internal_request_for_sharding_show_topology(ObMIOBuffer *buf) +int ObMysqlSM::do_internal_request_for_sharding_show_elastic_id(ObMIOBuffer *buf) { int ret = OB_SUCCESS; ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; ObMysqlClientSession *client_session = get_client_session(); ObClientSessionInfo &client_info = client_session->get_session_info(); - ObProxyProtocol client_protocol = client_session->get_client_session_protocol(); + ObProxyProtocol client_protocol = get_client_session_protocol(); Ob20ProtocolHeader &ob20_head = client_session->get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session->get_compressed_seq() + 1); Ob20ProtocolHeaderParam ob20_head_param(client_session->get_cs_id(), ob20_head.request_id_, compressed_seq, - compressed_seq, true, false, - client_session->is_client_support_new_extra_info()); + compressed_seq, true, false, false, + client_session->is_client_support_new_extra_info(), + client_session->is_trans_internal_routing()); ObCmdInfo info(static_cast(client_request.get_packet_meta().pkt_seq_ + 1), trans_state_.mysql_config_params_->internal_cmd_mem_limited_, client_protocol, ob20_head_param); - // handle show topology when sharding + // handle show elastic id when sharding ObInternalCmdInfo &cmd_info = *client_request.cmd_info_; ObString logic_db_name = cmd_info.get_like_string(); ObString logic_tenant_name; ObString group_name = cmd_info.get_value_string(); - LOG_DEBUG("sharding show topology", K(logic_db_name), K(group_name)); + LOG_DEBUG("sharding show elastic id", K(logic_db_name), K(group_name)); if (logic_db_name.empty()) { if (OB_FAIL(client_info.get_logic_database_name(logic_db_name))) { LOG_WARN("fail to get_logic_db_name", K(ret)); @@ -6790,13 +7142,52 @@ int ObMysqlSM::do_internal_request_for_sharding_show_topology(ObMIOBuffer *buf) } if (OB_FAIL(ret)) { // do nothing - } if (OB_FAIL(client_info.get_logic_tenant_name(logic_tenant_name))) { + } else if (OB_FAIL(client_info.get_logic_tenant_name(logic_tenant_name))) { LOG_WARN("fail to get_logic_tenant_name", K(ret)); - } else if (OB_FAIL(ObShowTopologyHandler::show_topology_cmd_callback(buf, info, logic_tenant_name, - logic_db_name, group_name))) { - LOG_WARN("[ObMysqlSM::do_internal_request] fail to handle show topology", K_(sm_id), K(ret)); + } else if (OB_FAIL(ObShowTopologyHandler::show_elastic_id_cmd_callback(buf, info, + logic_tenant_name, logic_db_name, group_name))) { + LOG_WARN("[ObMysqlSM::do_internal_request] fail to handle show elastic id", K_(sm_id), K(ret)); } + return ret; +} + +int ObMysqlSM::do_internal_request_for_sharding_show_topology(ObMIOBuffer *buf) +{ + int ret = OB_SUCCESS; + + ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; + ObMysqlClientSession *client_session = get_client_session(); + ObClientSessionInfo &client_info = client_session->get_session_info(); + ObProxyProtocol client_protocol = get_client_session_protocol(); + Ob20ProtocolHeader &ob20_head = client_session->get_session_info().ob20_request_.ob20_header_; + uint8_t compressed_seq = static_cast(client_session->get_compressed_seq() + 1); + Ob20ProtocolHeaderParam ob20_head_param(client_session->get_cs_id(), ob20_head.request_id_, compressed_seq, + compressed_seq, true, false, false, + client_session->is_client_support_new_extra_info(), + client_session->is_proxy_enable_trans_internal_routing()); + ObCmdInfo info(static_cast(client_request.get_packet_meta().pkt_seq_ + 1), + trans_state_.mysql_config_params_->internal_cmd_mem_limited_, client_protocol, ob20_head_param); + + // handle show topology when sharding + ObString logic_db_name; + ObString logic_tenant_name; + ObString logic_table_name = client_request.get_parse_result().get_table_name(); + LOG_DEBUG("sharding show topology", K(logic_db_name)); + if (logic_db_name.empty()) { + if (OB_FAIL(client_info.get_logic_database_name(logic_db_name))) { + LOG_WARN("fail to get_logic_db_name", K(ret)); + } + } + if (OB_FAIL(ret)) { + // do nothing + } else if (OB_FAIL(client_info.get_logic_tenant_name(logic_tenant_name))) { + LOG_WARN("fail to get_logic_tenant_name", K(ret)); + } else if (OB_FAIL(client_info.get_logic_database_name(logic_db_name))) { + } else if (OB_FAIL(ObShowTopologyHandler::show_topology_cmd_callback(buf, info, + logic_tenant_name, logic_db_name, logic_table_name))) { + LOG_WARN("[ObMysqlSM::do_internal_request] fail to handle show topology", K_(sm_id), K(ret)); + } return ret; } @@ -6807,12 +7198,13 @@ int ObMysqlSM::do_internal_request_for_sharding_select_db(ObMIOBuffer *buf) ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; ObMysqlClientSession *client_session = get_client_session(); ObClientSessionInfo &client_info = client_session->get_session_info(); - ObProxyProtocol client_protocol = client_session->get_client_session_protocol(); + ObProxyProtocol client_protocol = get_client_session_protocol(); Ob20ProtocolHeader &ob20_head = client_session->get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session->get_compressed_seq() + 1); Ob20ProtocolHeaderParam ob20_head_param(client_session->get_cs_id(), ob20_head.request_id_, compressed_seq, - compressed_seq, true, false, - client_session->is_client_support_new_extra_info()); + compressed_seq, true, false, false, + client_session->is_client_support_new_extra_info(), + client_session->is_trans_internal_routing()); ObCmdInfo info(static_cast(client_request.get_packet_meta().pkt_seq_ + 1), trans_state_.mysql_config_params_->internal_cmd_mem_limited_, client_protocol, ob20_head_param); @@ -6850,6 +7242,8 @@ void ObMysqlSM::do_internal_request() K_(sm_id), K(ret)); } else { buf = trans_state_.internal_buffer_; + ObProxyProtocol client_protocol = get_client_session_protocol(); + switch (trans_state_.trans_info_.sql_cmd_) { case OB_MYSQL_COM_HANDSHAKE: { OMPKHandshake handshake; @@ -6885,7 +7279,7 @@ void ObMysqlSM::do_internal_request() } } - if (FAILEDx(ObProxyPacketWriter::write_packet(*buf, *client_session_, handshake))) { + if (FAILEDx(ObProxyPacketWriter::write_packet(*buf, *client_session_, client_protocol, handshake))) { LOG_WARN("fail to build handshake packet", K_(sm_id), K(ret)); } else { ObMySQLCapabilityFlags capability(handshake.get_server_capability()); @@ -6905,7 +7299,8 @@ void ObMysqlSM::do_internal_request() ObMysqlAuthRequest &orig_auth_req = client_session_->get_session_info().get_login_req(); const ObMySQLCapabilityFlags &capability = client_session_->get_session_info().get_orig_capability_flags(); uint8_t pkt_seq = static_cast(orig_auth_req.get_packet_meta().pkt_seq_ + 1); - if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, pkt_seq, 0, capability))) { + if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, client_protocol, + pkt_seq, 0, capability))) { LOG_WARN("fail to write ok packet", K(ret)); } } @@ -6915,7 +7310,8 @@ void ObMysqlSM::do_internal_request() LOG_DEBUG("proxy response OB_MYSQL_COM_PING ok packet", K_(sm_id), "cs_id", client_session_->get_cs_id()); uint8_t pkt_seq = static_cast(trans_state_.trans_info_.client_request_.get_packet_meta().pkt_seq_ + 1); const ObMySQLCapabilityFlags &capability = client_session_->get_session_info().get_orig_capability_flags(); - if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, pkt_seq, 0, capability))) { + if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, client_protocol, + pkt_seq, 0, capability))) { LOG_WARN("fail to encode OB_MYSQL_COM_PING response ok packet", K(ret)); } break; @@ -6946,7 +7342,8 @@ void ObMysqlSM::do_internal_request() uint8_t pkt_seq = static_cast(trans_state_.trans_info_.client_request_.get_packet_meta().pkt_seq_ + 1); const ObMySQLCapabilityFlags &capability = client_info.get_orig_capability_flags(); - if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, pkt_seq, 0, capability))) { + if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, client_protocol, + pkt_seq, 0, capability))) { LOG_WARN("[ObMysqlSM::do_internal_request] fail to build OB_MYSQL_COM_STMT_RESET response ok packet", K_(sm_id), K(client_ps_id), K(ret)); } @@ -6970,17 +7367,28 @@ void ObMysqlSM::do_internal_request() case OB_MYSQL_COM_DELAYED_INSERT: case OB_MYSQL_COM_CHANGE_USER: case OB_MYSQL_COM_SHUTDOWN: + case OB_MYSQL_COM_STMT_PREPARE_EXECUTE: case OB_MYSQL_COM_DAEMON: { ObProxyMysqlRequest &client_request = trans_state_.trans_info_.client_request_; ObClientSessionInfo &client_info = client_session_->get_session_info(); uint8_t next_seq = static_cast(client_request.get_packet_meta().pkt_seq_ + 1); // 1. hold_start_trans if (client_request.get_parse_result().need_hold_start_trans()) { + // hold begin reset hold xa start trans_state_.is_hold_start_trans_ = true; - if (OB_FAIL(ObMysqlResponseBuilder::build_start_trans_resp(*buf, client_request, *client_session_))) { + if (OB_FAIL(ObMysqlResponseBuilder::build_start_trans_resp(*buf, client_request, + *client_session_, client_protocol))) { LOG_WARN("[ObMysqlSM::do_internal_request] fail to build start trans resp", K_(sm_id), K(ret)); } - + // hold_xa_start + } else if (client_request.get_parse_result().need_hold_xa_start()) { + LOG_DEBUG("[ObMysqlSM::do_internal_request] to build xa start resp"); + // hold xa start reset hold begin + trans_state_.is_hold_xa_start_ = true; + if (OB_FAIL(ObMysqlResponseBuilder::build_prepare_execute_xa_start_resp(*buf, client_request, + *client_session_, client_protocol))) { + LOG_WARN("[ObMysqlSM::do_internal_request] fail to build xa start resp", K_(sm_id), K(ret)); + } // 2. bad_route_request } else if (ObMysqlTransact::is_bad_route_request(trans_state_)) { trans_state_.mysql_errcode_ = OB_NOT_SUPPORTED; @@ -6992,6 +7400,7 @@ void ObMysqlSM::do_internal_request() } else { // throw away the former 'begin' or 'start transaction' trans_state_.is_hold_start_trans_ = false; + trans_state_.is_hold_xa_start_ = false; } // 3. not_supported @@ -7004,32 +7413,21 @@ void ObMysqlSM::do_internal_request() // 4. select_tx_ro } else if (client_request.get_parse_result().is_select_tx_ro()) { // if start trans is hold, we treat this resp is in trans - bool is_in_trans = (trans_state_.is_hold_start_trans_ || ObMysqlTransact::is_in_trans(trans_state_)); + bool is_in_trans = (trans_state_.is_hold_xa_start_ + || trans_state_.is_hold_start_trans_ + || ObMysqlTransact::is_in_trans(trans_state_)); if (OB_FAIL(ObMysqlResponseBuilder::build_select_tx_ro_resp(*buf, client_request, *client_session_, - is_in_trans))) { + client_protocol, is_in_trans))) { LOG_WARN("[ObMysqlSM::do_internal_request] fail to build select @@tx_read_only", K_(sm_id), K(ret)); } - - // 5. set_autocommit_0 - } else if (client_request.get_parse_result().is_set_autocommit_0()) { - // if start trans is hold, we treat this resp is in trans - bool is_in_trans = (trans_state_.is_hold_start_trans_ || ObMysqlTransact::is_in_trans(trans_state_)); - ObObj value; - value.set_int(0); - if (client_info.update_common_sys_variable("autocommit", value, true, false)) { - LOG_WARN("fail to update sys variable", K_(sm_id), K(ret)); - } else if (OB_FAIL(ObMysqlResponseBuilder::build_ok_resq_with_state_changed(*buf, client_request, - *client_session_, is_in_trans))) { - LOG_WARN("[ObMysqlSM::do_internal_request] fail to build set autocommit = 0", K_(sm_id), K(ret)); - } - // 6. ping_proxy } else if (client_request.get_parse_result().is_ping_proxy_cmd() && !client_request.get_parse_result().is_internal_error_cmd()) { if (OB_LIKELY(get_global_hot_upgrade_info().need_conn_accept_)) { uint8_t pkt_seq = static_cast(trans_state_.trans_info_.client_request_.get_packet_meta().pkt_seq_ + 1); const ObMySQLCapabilityFlags &capability = client_session_->get_session_info().get_orig_capability_flags(); - if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, pkt_seq, 0, capability))) { + if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, client_protocol, + pkt_seq, 0, capability))) { LOG_WARN("fail to write ok packet", K(ret)); } } else { @@ -7044,7 +7442,8 @@ void ObMysqlSM::do_internal_request() // python mysql will send 'SET autocommit=0' after connected, proxysys need resp ok packet uint8_t pkt_seq = static_cast(trans_state_.trans_info_.client_request_.get_packet_meta().pkt_seq_ + 1); const ObMySQLCapabilityFlags &capability = client_session_->get_session_info().get_orig_capability_flags(); - if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, pkt_seq, 0, capability))) { + if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, client_protocol, + pkt_seq, 0, capability))) { LOG_WARN("fail to build ok packet", K(ret)); } } else { @@ -7058,15 +7457,14 @@ void ObMysqlSM::do_internal_request() // 8. select route_addr } else if (client_request.get_parse_result().is_select_route_addr()) { ObMysqlServerSession *last_session = client_session_->get_server_session(); - int64_t addr = 0; if (NULL != last_session && NULL != last_session->get_netvc()) { - addr = ObMysqlTransact::build_addr_from_ip_port( - ntohl(last_session->get_netvc()->get_remote_ip()), - last_session->get_netvc()->get_remote_port()); // if start trans is hold, we treat this resp is in trans - bool is_in_trans = (trans_state_.is_hold_start_trans_ || ObMysqlTransact::is_in_trans(trans_state_)); + bool is_in_trans = (trans_state_.is_hold_xa_start_ + || trans_state_.is_hold_start_trans_ + || ObMysqlTransact::is_in_trans(trans_state_)); if (OB_FAIL(ObMysqlResponseBuilder::build_select_route_addr_resp(*buf, client_request, - *client_session_, is_in_trans, addr))) { + *client_session_, client_protocol, is_in_trans, + last_session->get_netvc()->get_remote_addr()))) { LOG_WARN("[ObMysqlSM::do_internal_request] fail to build select @obproxy_route_addr", K_(sm_id), K(ret)); } } else { @@ -7081,9 +7479,11 @@ void ObMysqlSM::do_internal_request() } else if (client_request.get_parse_result().is_set_route_addr()) { client_info.set_obproxy_route_addr(client_request.get_parse_result().cmd_info_.integer_[0]); // if start trans is hold, we treat this resp is in trans - bool is_in_trans = (trans_state_.is_hold_start_trans_ || ObMysqlTransact::is_in_trans(trans_state_)); + bool is_in_trans = (trans_state_.is_hold_xa_start_ + || trans_state_.is_hold_start_trans_ + || ObMysqlTransact::is_in_trans(trans_state_)); if (OB_FAIL(ObMysqlResponseBuilder::build_set_route_addr_resp(*buf, client_request, *client_session_, - is_in_trans))) { + client_protocol, is_in_trans))) { LOG_WARN("[ObMysqlSM::do_internal_request] fail to build set @obproxy_route_addr", K_(sm_id), K(ret)); } else { LOG_DEBUG("@obproxy_route_addr is set", K(client_info.get_obproxy_route_addr())); @@ -7145,6 +7545,11 @@ void ObMysqlSM::do_internal_request() if (OB_FAIL(do_internal_request_for_sharding_show_table_status(buf))) { LOG_WARN("fail to do internal request for sharding show db", K_(sm_id), K(ret)); } + } else if (client_session_->get_session_info().is_sharding_user() + && client_request.get_parse_result().is_show_elastic_id_stmt()) { + if (OB_FAIL(do_internal_request_for_sharding_show_elastic_id(buf))) { + LOG_WARN("fail to do internal request for sharding show db", K_(sm_id), K(ret)); + } } else if (client_session_->get_session_info().is_sharding_user() && client_request.get_parse_result().is_show_topology_stmt()) { if (OB_FAIL(do_internal_request_for_sharding_show_topology(buf))) { @@ -7158,9 +7563,11 @@ void ObMysqlSM::do_internal_request() // 13. select_proxy_version } else if (client_request.get_parse_result().is_select_proxy_version()) { // if start trans is hold, we treat this resp is in trans - bool is_in_trans = (trans_state_.is_hold_start_trans_ || ObMysqlTransact::is_in_trans(trans_state_)); - if (OB_FAIL(ObMysqlResponseBuilder::build_select_proxy_version_resp(*buf, client_request, - *client_session_, is_in_trans))) { + bool is_in_trans = (trans_state_.is_hold_xa_start_ + || trans_state_.is_hold_start_trans_ + || ObMysqlTransact::is_in_trans(trans_state_)); + if (OB_FAIL(ObMysqlResponseBuilder::build_select_proxy_version_resp(*buf, client_request, *client_session_, + client_protocol, is_in_trans))) { LOG_WARN("[ObMysqlSM::do_internal_request] fail to build select proxy_version", K_(sm_id), K(ret)); } // 14. drop prepare stmt @@ -7169,9 +7576,9 @@ void ObMysqlSM::do_internal_request() uint32_t client_ps_id = client_info.get_client_ps_id(); uint8_t pkt_seq = static_cast(trans_state_.trans_info_.client_request_.get_packet_meta().pkt_seq_ + 1); const ObMySQLCapabilityFlags &capability = client_info.get_orig_capability_flags(); - if (OB_FAIL(ObMysqlPacketUtil::encode_ok_packet(*buf, pkt_seq, 0, capability))) { - LOG_WARN("[ObMysqlSM::do_internal_request] fail to encode drop/deallocate prepare stmt response ok packet", - K_(sm_id), K(client_ps_id), K(ret)); + if (OB_FAIL(ObProxyPacketWriter::write_ok_packet(*buf, *client_session_, client_protocol, + pkt_seq, 0, capability))) { + LOG_WARN("fail to write ok packet", K(ret)); } else { client_info.delete_text_ps_name_entry(text_ps_name); client_info.remove_ps_id_addrs(client_ps_id); @@ -7195,9 +7602,10 @@ void ObMysqlSM::do_internal_request() Ob20ProtocolHeader &ob20_head = client_session_->get_session_info().ob20_request_.ob20_header_; uint8_t compressed_seq = static_cast(client_session_->get_compressed_seq() + 1); Ob20ProtocolHeaderParam ob20_head_param(client_session_->get_cs_id(), ob20_head.request_id_, compressed_seq, - compressed_seq, true, false, - client_session_->is_client_support_new_extra_info()); - cmd_info.set_protocol(client_session_->get_client_session_protocol()); + compressed_seq, true, false, false, + client_session_->is_client_support_new_extra_info(), + client_session_->is_trans_internal_routing()); + cmd_info.set_protocol(get_client_session_protocol()); cmd_info.set_ob20_head_param(ob20_head_param); ObAction *cmd_handler = NULL; @@ -7270,6 +7678,7 @@ inline void ObMysqlSM::set_client_abort(const ObMysqlTransact::ObAbortStateType break; case VC_EVENT_ERROR: + case VC_EVENT_DETECT_SERVER_DEAD: trans_state_.client_info_.state_ = ObMysqlTransact::CONNECTION_ERROR; xflush_head = XFH_CONNECTION_ERROR; break; @@ -7310,7 +7719,7 @@ inline void ObMysqlSM::set_client_abort(const ObMysqlTransact::ObAbortStateType "request_cmd", get_mysql_cmd_str(trans_state_.trans_info_.client_request_.get_packet_meta().cmd_), "sql_cmd", get_mysql_cmd_str(trans_state_.trans_info_.sql_cmd_), "sql", trans_state_.trans_info_.get_print_sql()); - } else { + } else if (client_session_->get_session_info().get_priv_info().user_name_ != ObProxyTableInfo::DETECT_USERNAME_USER) { LOG_WARN("client will abort soon", K_(sm_id), K(cs_id), @@ -7515,9 +7924,10 @@ void ObMysqlSM::handle_observer_open() //fall through case ObMysqlTransact::SERVER_SEND_SESSION_VARS: //fall through - case ObMysqlTransact::SERVER_SEND_LAST_INSERT_ID: + case ObMysqlTransact::SERVER_SEND_SESSION_USER_VARS: //fall through case ObMysqlTransact::SERVER_SEND_START_TRANS: + case ObMysqlTransact::SERVER_SEND_XA_START: //fall through case ObMysqlTransact::SERVER_SEND_PREPARE: case ObMysqlTransact::SERVER_SEND_TEXT_PS_PREPARE: @@ -7654,7 +8064,8 @@ void ObMysqlSM::handle_server_setup_error(int event, void *data) : ObMysqlTransact::CONNECTION_CLOSED); break; } - case VC_EVENT_ERROR: { + case VC_EVENT_ERROR: + case VC_EVENT_DETECT_SERVER_DEAD: { trans_state_.current_.state_ = ObMysqlTransact::CONNECTION_ERROR; break; } @@ -7786,13 +8197,15 @@ int ObMysqlSM::setup_client_transfer(ObMysqlVCType to_vc_type) switch (to_vc_type) { case MYSQL_TRANSFORM_VC: MYSQL_SM_SET_DEFAULT_HANDLER(&ObMysqlSM::state_request_wait_for_transform_read); - if (OB_ISNULL(api_.request_transform_info_.entry_) - || api_.request_transform_info_.entry_->vc_ != api_.request_transform_info_.vc_) { + if (OB_ISNULL(api_.request_transform_info_.entry_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid internal state", KP_(api_.request_transform_info_.vc), K_(sm_id), K(ret)); + } else if (api_.request_transform_info_.entry_->vc_ != api_.request_transform_info_.vc_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid internal state", - K_(api_.request_transform_info_.entry), - K_(api_.request_transform_info_.entry_->vc), - K_(api_.request_transform_info_.vc), K_(sm_id), K(ret)); + KP_(api_.request_transform_info_.entry), + KP_(api_.request_transform_info_.entry_->vc), + KP_(api_.request_transform_info_.vc), K_(sm_id), K(ret)); } else if (OB_ISNULL(c = tunnel_.add_consumer(api_.request_transform_info_.entry_->vc_, client_entry_->vc_, &ObMysqlSM::tunnel_handler_transform_write, @@ -8015,7 +8428,8 @@ int ObMysqlSM::setup_server_request_send() server_entry_->write_buffer_ = (buf_start != client_buffer_reader_) ? buf_start->writer() : NULL; // set query_timeout to each request, ddl stmt will never timeout - if (OB_UNLIKELY(trans_state_.trans_info_.client_request_.get_parse_result().is_ddl_stmt())) { + if (OB_UNLIKELY(trans_state_.trans_info_.client_request_.get_parse_result().is_ddl_stmt() + || ObMysqlTransact::is_binlog_request(trans_state_))) { cancel_server_query_timeout(); // if PL/SQL: // 1. if in trans, use trx timeout @@ -8026,7 +8440,9 @@ int ObMysqlSM::setup_server_request_send() } else if (OB_UNLIKELY(trans_state_.trans_info_.client_request_.get_parse_result().is_call_stmt() || trans_state_.trans_info_.client_request_.get_parse_result().is_text_ps_call_stmt() || trans_state_.trans_info_.client_request_.get_parse_result().has_anonymous_block())) { - if (trans_state_.is_hold_start_trans_ || ObMysqlTransact::is_in_trans(trans_state_)) { + if (trans_state_.is_hold_xa_start_ + || trans_state_.is_hold_start_trans_ + || ObMysqlTransact::is_in_trans(trans_state_)) { set_server_trx_timeout(); } else { cancel_server_query_timeout(); @@ -8237,7 +8653,9 @@ int ObMysqlSM::setup_internal_transfer(MysqlSMHandler handler_arg) // if the internal request is not the first request and not proxysys, // it means that it is in trans (or hold trans), in this case we do NOT change the trans_state_ if (trans_state_.is_trans_first_request_) { - if (trans_state_.is_auth_request_ || trans_state_.is_hold_start_trans_) { + if (trans_state_.is_auth_request_ + || trans_state_.is_hold_start_trans_ + || trans_state_.is_hold_xa_start_) { trans_state_.current_.state_ = ObMysqlTransact::CMD_COMPLETE; } else { // proxysys && !OB_MYSQL_COM_LOGIN &&!OB_MYSQL_COM_HANDSHAKE will also enter here @@ -8349,6 +8767,11 @@ int ObMysqlSM::setup_server_transfer() if (is_resultset) { LOG_ERROR("compress protocol's never reach here", K(is_resultset)); } + } else if (get_global_proxy_config().enable_binlog_service + && (OB_MYSQL_COM_REGISTER_SLAVE == trans_state_.trans_info_.sql_cmd_ + || OB_MYSQL_COM_BINLOG_DUMP == trans_state_.trans_info_.sql_cmd_ + || OB_MYSQL_COM_BINLOG_DUMP_GTID == trans_state_.trans_info_.sql_cmd_)) { + analyzer = &analyzer_; } else { analyzer = is_resultset ? &analyzer_ : NULL; } @@ -8384,6 +8807,7 @@ int ObMysqlSM::setup_cmd_complete() reinterpret_cast(client_session_->get_last_bound_server_session()), K_(sm_id), K(ret)); } else { + ObMysqlTransact::record_trans_state(trans_state_, ObMysqlTransact::is_in_trans(trans_state_)); set_detect_server_info(trans_state_.server_info_.addr_, -1, ObTimeUtility::current_time()); if (OB_UNLIKELY(add_detect_server_cnt_)) { LOG_ERROR("setup_cmd_complete, add_detect_server_cnt_ should be false"); @@ -8458,32 +8882,63 @@ int ObMysqlSM::setup_cmd_complete() } } - // it's necessary to end full link trace resource after trans/resp finished - if (OB_FAIL(handle_resp_for_end_flt_trace(ObMysqlTransact::TRANSACTION_COMPLETE == trans_state_.current_.state_))) { - LOG_WARN("fail to handle resp for end flt trace", K(ret)); - } else { - cmd_size_stats_.reset(); - if (OB_UNLIKELY(get_global_performance_params().enable_trace_)) { - cmd_time_stats_.reset(); - } - trans_state_.reset(); - // reset ps info - if (NULL != server_session_) { - server_session_->get_session_info().reset_server_ps_id(); - } - if (NULL != client_session_) { - client_session_->get_session_info().reset_recv_client_ps_id(); - client_session_->get_session_info().reset_client_ps_id(); - client_session_->get_session_info().reset_ps_entry(); - client_session_->get_session_info().reset_client_cursor_id(); + // consume the ob20 tail crc(4) in client buf reader while analyzed all the mysql packet in ob20 payload + ObClientSessionInfo &client_session_info = get_client_session()->get_session_info(); + ObProxyProtocol client_proto = get_client_session_protocol(); + bool ob20_req_received_done = client_session_info.ob20_request_.ob20_request_received_done_; + int64_t ob20_req_remain_payload_len = client_session_info.ob20_request_.remain_payload_len_; + if (client_proto == ObProxyProtocol::PROTOCOL_OB20 + && ob20_req_received_done + && ob20_req_remain_payload_len == 0) { + client_session_info.ob20_request_.reset(); + int64_t read_avail = client_buffer_reader_->read_avail(); + LOG_DEBUG("before handle tail crc in setup cmd complete", K(read_avail)); + if (OB_LIKELY(read_avail >= OB20_PROTOCOL_TAILER_LENGTH)) { + if (OB_FAIL(client_buffer_reader_->consume(OB20_PROTOCOL_TAILER_LENGTH))) { + LOG_WARN("fail to consume the last crc buffer in client request buffer", K(ret)); + } + } else { + // nothing + // cause buffer could be consumed all before, eg: handle internal request } + } - // wait new client request - if (OB_FAIL(setup_client_request_read())) { - LOG_WARN("failed to setup_client_request_read", K_(sm_id), K(ret)); + // it's necessary to end full link trace resource after trans/resp finished + if (OB_SUCC(ret)) { + if (OB_FAIL(handle_resp_for_end_flt_trace(ObMysqlTransact::TRANSACTION_COMPLETE + == trans_state_.current_.state_))) { + LOG_WARN("fail to handle resp for end flt trace", K(ret)); + } else { + cmd_size_stats_.reset(); + if (OB_UNLIKELY(get_global_performance_params().enable_trace_)) { + cmd_time_stats_.reset(); + } + if (ObMysqlTransact::is_in_trans(trans_state_) && client_session_->is_trans_internal_routing()) { + trans_state_.server_info_.reset(); + trans_state_.pll_info_.reset(); + trans_state_.current_.attempts_ = 1; + trans_state_.reset_congestion_entry(); + } + trans_state_.reset(); + // reset ps info + if (NULL != server_session_) { + server_session_->get_session_info().reset_server_ps_id(); + } + if (NULL != client_session_) { + client_session_->get_session_info().reset_recv_client_ps_id(); + client_session_->get_session_info().reset_client_ps_id(); + client_session_->get_session_info().reset_ps_entry(); + client_session_->get_session_info().reset_client_cursor_id(); + } + + // wait new client request + if (OB_FAIL(setup_client_request_read())) { + LOG_WARN("failed to setup_client_request_read", K_(sm_id), K(ret)); + } } } } + return ret; } @@ -8500,14 +8955,14 @@ bool ObMysqlSM::need_close_last_used_ss() if (OB_LIKELY(NULL != client_session_) && NULL != (last_ss = client_session_->get_server_session()) && client_session_->get_session_info().is_read_consistency_set() - && client_session_->dummy_ldc_.is_readonly_zone_exist()) { + && client_session_->dummy_ldc_.is_readonly_zone_exist() + && !ObMysqlTransact::is_in_trans(trans_state_)) { common::ObAddr tmp_addr; - (void)tmp_addr.set_ipv4_addr(last_ss->server_ip_.get_ip4_host_order(), static_cast(last_ss->server_ip_.get_port_host_order())); + (void)tmp_addr.set_sockaddr(last_ss->server_ip_.sa_); const bool is_last_route_readonly_zone = client_session_->dummy_ldc_.is_readonly_zone(tmp_addr); const bool is_weak_read = (common::WEAK == static_cast(client_session_->get_session_info().get_read_consistency())); common::ObAddr current_addr; - (void)current_addr.set_ipv4_addr(trans_state_.server_info_.addr_.get_ip4_host_order(), - static_cast(trans_state_.server_info_.addr_.get_port_host_order())); + (void)current_addr.set_sockaddr(trans_state_.server_info_.addr_.sa_); const bool is_current_route_readonly_zone = client_session_->dummy_ldc_.is_readonly_zone(current_addr); // if readonly zone exist, should choose readonly zone when weak read and close connection which connect to readwrite zone if (is_last_route_readonly_zone != is_current_route_readonly_zone) { @@ -8523,7 +8978,9 @@ bool ObMysqlSM::need_close_last_used_ss() bool ObMysqlSM::can_server_session_release() { bool result = false; - bool is_in_trans = (trans_state_.is_hold_start_trans_ || ObMysqlTransact::is_in_trans(trans_state_)); + bool is_in_trans = (trans_state_.is_hold_start_trans_ + || trans_state_.is_hold_xa_start_ + || ObMysqlTransact::is_in_trans(trans_state_)); bool is_allowed_state_ = (ObMysqlTransact::STATE_UNDEFINED == trans_state_.current_.state_ || ObMysqlTransact::TRANSACTION_COMPLETE == trans_state_.current_.state_); // here should handle some case before release @@ -8744,7 +9201,8 @@ inline void ObMysqlSM::update_congestion_entry(const int event) int64_t client_connect_timeout = 0; if ((VC_EVENT_EOS == event || VC_EVENT_INACTIVITY_TIMEOUT == event - || VC_EVENT_ACTIVE_TIMEOUT == event) + || VC_EVENT_ACTIVE_TIMEOUT == event + || VC_EVENT_DETECT_SERVER_DEAD) && ObMysqlTransact::SM_ACTION_OBSERVER_OPEN == trans_state_.next_action_ && 0 == milestones_.server_connect_end_ && OB_LIKELY(NULL != pending_action_) @@ -9225,8 +9683,9 @@ inline void ObMysqlSM::update_cmd_stats() trans_stats_.send_all_session_vars_time_ += cmd_time_stats_.server_send_all_session_variable_time_; trans_stats_.send_use_database_time_ += cmd_time_stats_.server_send_use_database_time_; trans_stats_.send_session_vars_time_ += cmd_time_stats_.server_send_session_variable_time_; - trans_stats_.send_last_insert_id_time_ += cmd_time_stats_.server_send_last_insert_id_time_; + trans_stats_.send_session_user_vars_time_ += cmd_time_stats_.server_send_session_user_variable_time_; trans_stats_.send_start_trans_time_ += cmd_time_stats_.server_send_start_trans_time_; + trans_stats_.send_xa_start_time_ += cmd_time_stats_.server_send_xa_start_time_; trans_stats_.build_server_request_time_ += cmd_time_stats_.build_server_request_time_; int64_t slow_time_threshold = trans_state_.mysql_config_params_->slow_query_time_threshold_; @@ -9258,9 +9717,13 @@ inline void ObMysqlSM::update_cmd_stats() ObString cluster_name; ObString logic_tenant_name; ObString logic_database_name; + ObString trans_internal_routing_state; + bool is_in_trans = ObMysqlTransact::is_in_trans(trans_state_); + bool is_trans_internal_routing = false; if (NULL != client_session_) { proxy_sessid = client_session_->get_proxy_sessid(); cs_id = client_session_->get_cs_id(); + is_trans_internal_routing = client_session_->is_trans_internal_routing(); const ObClientSessionInfo &cs_info = client_session_->get_session_info(); cs_info.get_user_name(user_name); cs_info.get_tenant_name(tenant_name); @@ -9268,6 +9731,7 @@ inline void ObMysqlSM::update_cmd_stats() cs_info.get_logic_database_name(logic_database_name); cs_info.get_logic_tenant_name(logic_tenant_name); } + trans_internal_routing_state = is_in_trans ? (is_trans_internal_routing ? "trans internal routing" : "trans not internal routing") : "not in trans"; get_server_session_ids(server_sessid, ss_id); if (print_info_log) { @@ -9291,7 +9755,8 @@ inline void ObMysqlSM::update_cmd_stats() K_(sm_id), K_(cmd_size_stats), K_(cmd_time_stats), - "sql", trans_state_.trans_info_.get_print_sql()); + "sql", trans_state_.trans_info_.get_print_sql(), + K(trans_internal_routing_state)); } else { LOG_WARN(log_head, "client_ip", trans_state_.client_info_.addr_, @@ -9312,7 +9777,8 @@ inline void ObMysqlSM::update_cmd_stats() K_(sm_id), K_(cmd_size_stats), K_(cmd_time_stats), - "sql", trans_state_.trans_info_.get_print_sql()); + "sql", trans_state_.trans_info_.get_print_sql(), + K(trans_internal_routing_state)); } } @@ -9563,6 +10029,10 @@ inline void ObMysqlSM::set_next_state() do_partition_location_lookup(); break; + case ObMysqlTransact::SM_ACTION_BINLOG_LOCATION_LOOKUP: + do_binlog_location_lookup(); + break; + case ObMysqlTransact::SM_ACTION_CONGESTION_CONTROL_LOOKUP: do_congestion_control_lookup(); break; @@ -9621,6 +10091,44 @@ inline void ObMysqlSM::set_next_state() } } +int ObMysqlSM::state_binlog_location_lookup(int event, void *data) +{ + int ret = OB_SUCCESS; + STATE_ENTER(ObMysqlSM::state_binlog_location_lookup, event); + pending_action_ = NULL; + if (OB_UNLIKELY(get_global_performance_params().enable_trace_)) { + milestones_.bl_lookup_end_ = get_based_hrtime(); + cmd_time_stats_.bl_lookup_time_ += milestone_diff(milestones_.bl_lookup_begin_, milestones_.bl_lookup_end_); + milestones_.bl_process_begin_ = milestones_.bl_lookup_end_; + } + + if (OB_UNLIKELY(TABLE_ENTRY_EVENT_LOOKUP_DONE != event) || OB_ISNULL(data)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("unexpected event type, it should not happen", K(event), K(data), K(ret)); + } else { + ObMysqlRouteResult *result = reinterpret_cast(data); + if (OB_UNLIKELY(NULL == result || NULL == result->table_entry_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get binlog entry failed", K(result), K(ret)); + } else { + trans_state_.pll_info_.set_route_info(*result); + trans_state_.pll_info_.lookup_success_ = true; + call_transact_and_set_next_state(NULL); + } + } + + if (OB_FAIL(ret)) { + trans_state_.inner_errcode_ = ret; + // failed, disconnect + trans_state_.pll_info_.lookup_success_ = false; + trans_state_.current_.state_ = ObMysqlTransact::INTERNAL_ERROR; + // call ObMysqlTransact::handle_bl_lookup() to handle fail / success + call_transact_and_set_next_state(NULL); + } + + return EVENT_DONE; +} + } // end of namespace proxy } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/proxy/mysql/ob_mysql_sm.h b/src/obproxy/proxy/mysql/ob_mysql_sm.h index 15415c240..ec159024a 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_sm.h +++ b/src/obproxy/proxy/mysql/ob_mysql_sm.h @@ -33,6 +33,7 @@ #include "utils/ob_proxy_lib.h" #include "utils/ob_proxy_monitor_utils.h" +#include "utils/ob_target_db_server.h" #include "iocore/eventsystem/ob_event_system.h" #include "proxy/mysqllib/ob_mysql_request_analyzer.h" #include "proxy/mysqllib/ob_mysql_compress_analyzer.h" @@ -157,14 +158,15 @@ class ObMysqlSM : public event::ObContinuation int process_shard_ddl_result(ObShardDDLStatus *ddl_status); int setup_handle_execute_plan(); int state_handle_execute_plan(int event, void *data); - int process_executor_result(engine::ObProxyResultResp *result_resp); - + int process_executor_result(event::ObIOBufferReader *resp_reader); + int handle_shard_request(bool &need_response_for_stmt, bool &need_wait_callback); int check_user_identity(const ObString &user_name, const ObString &tenant_name, const ObString &cluster_name); int save_user_login_info(ObClientSessionInfo &session_info, ObHSRResult &hsr_result); void analyze_mysql_request(ObMysqlAnalyzeStatus &status, const bool is_mysql_req_in_ob20 = false); int analyze_login_request(ObRequestAnalyzeCtx &ctx, ObMysqlAnalyzeStatus &status); + int analyze_change_user_request(); int analyze_ps_prepare_request(); int do_analyze_ps_prepare_request(const ObString &ps_sql); int analyze_ps_execute_request(bool is_large_request = false); @@ -306,6 +308,7 @@ class ObMysqlSM : public event::ObContinuation int state_watch_for_client_abort(int event, void *data); int state_server_addr_lookup(int event, void *data); int state_partition_location_lookup(int event, void *data); + int state_binlog_location_lookup(int event, void *data); int state_add_to_list(int event, void *data); int state_remove_from_list(int event, void *data); @@ -336,6 +339,7 @@ class ObMysqlSM : public event::ObContinuation int tunnel_handler_plugin_client(int event, ObMysqlTunnelConsumer &c); void do_partition_location_lookup(); + void do_binlog_location_lookup(); void do_congestion_control_lookup(); void do_server_addr_lookup(); int do_observer_open(); @@ -348,6 +352,7 @@ class ObMysqlSM : public event::ObContinuation int do_internal_request_for_sharding_show_db(event::ObMIOBuffer *buf); int do_internal_request_for_sharding_show_table(event::ObMIOBuffer *buf); int do_internal_request_for_sharding_show_table_status(event::ObMIOBuffer *buf); + int do_internal_request_for_sharding_show_elastic_id(event::ObMIOBuffer *buf); int do_internal_request_for_sharding_show_topology(event::ObMIOBuffer *buf); int do_internal_request_for_sharding_select_db(event::ObMIOBuffer *buf); int connect_observer(); @@ -438,7 +443,8 @@ class ObMysqlSM : public event::ObContinuation int handle_req_to_generate_root_span_by_proxy(); int handle_for_end_proxy_trace(trace::UUID &trace_id); int handle_resp_for_end_flt_trace(bool is_trans_completed); - + void set_enable_ob_protocol_v2(const bool enable_ob_protocol_v2) { enable_ob_protocol_v2_ = enable_ob_protocol_v2; } + bool is_enable_ob_protocol_v2() const { return enable_ob_protocol_v2_; } private: static const int64_t HISTORY_SIZE = 32; @@ -486,7 +492,11 @@ class ObMysqlSM : public event::ObContinuation bool enable_cloud_full_username_; bool enable_client_ssl_; bool enable_server_ssl_; + bool enable_read_write_split_; + bool enable_transaction_split_; + bool enable_ob_protocol_v2_; // limit the scope of changing enable_protocol_v2_ to client session level uint64_t config_version_; + ObTargetDbServer *target_db_server_; private: // private functions @@ -589,16 +599,16 @@ inline void ObMysqlSM::set_internal_cmd_timeout(const ObHRTime timeout) inline int64_t ObMysqlSM::get_query_timeout() { int64_t timeout = HRTIME_NSECONDS(trans_state_.mysql_config_params_->observer_query_timeout_delta_); - if (OB_LIKELY(NULL != client_session_) && OB_LIKELY(NULL != server_session_)) { - dbconfig::ObShardProp *shard_prop = client_session_->get_session_info().get_shard_prop(); - if (OB_NOT_NULL(shard_prop)) { - timeout = HRTIME_MSECONDS(shard_prop->get_socket_timeout()); + if (OB_LIKELY(NULL != client_session_)) { + int64_t hint_query_timeout = trans_state_.trans_info_.client_request_.get_parse_result().get_hint_query_timeout(); + // if the request contains query_timeout in hint, we use it + if (hint_query_timeout > 0) { + // the query timeout in hint is in microseconds(us), so convert it into nanoseconds + timeout += HRTIME_USECONDS(hint_query_timeout); } else { - int64_t hint_query_timeout = trans_state_.trans_info_.client_request_.get_parse_result().get_hint_query_timeout(); - // if the request contains query_timeout in hint, we use it - if (hint_query_timeout > 0) { - // the query timeout in hint is in microseconds(us), so convert it into nanoseconds - timeout += HRTIME_USECONDS(hint_query_timeout); + dbconfig::ObShardProp *shard_prop = client_session_->get_session_info().get_shard_prop(); + if (OB_NOT_NULL(shard_prop)) { + timeout = HRTIME_MSECONDS(shard_prop->get_socket_timeout()); } else { // we do parse in trans now, so we can use query_timeout in anycase timeout += client_session_->get_session_info().get_query_timeout(); diff --git a/src/obproxy/proxy/mysql/ob_mysql_sm_time_stat.cpp b/src/obproxy/proxy/mysql/ob_mysql_sm_time_stat.cpp index f8bd54807..6efcbb0b6 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_sm_time_stat.cpp +++ b/src/obproxy/proxy/mysql/ob_mysql_sm_time_stat.cpp @@ -37,6 +37,9 @@ int64_t ObCmdTimeStat::to_string(char *buf, const int64_t buf_len) const TO_STRING_TIME_US(pl_lookup_time_); TO_STRING_TIME_US(pl_process_time_); + TO_STRING_TIME_US(bl_lookup_time_); + TO_STRING_TIME_US(bl_process_time_); + #if OB_DETAILED_SLOW_QUERY TO_STRING_TIME_US(debug_assign_time_); TO_STRING_TIME_US(debug_consistency_time_); @@ -58,9 +61,10 @@ int64_t ObCmdTimeStat::to_string(char *buf, const int64_t buf_len) const TO_STRING_TIME_US(server_send_saved_login_time_); TO_STRING_TIME_US(server_send_use_database_time_); TO_STRING_TIME_US(server_send_session_variable_time_); + TO_STRING_TIME_US(server_send_session_user_variable_time_); TO_STRING_TIME_US(server_send_all_session_variable_time_); - TO_STRING_TIME_US(server_send_last_insert_id_time_); TO_STRING_TIME_US(server_send_start_trans_time_); + TO_STRING_TIME_US(server_send_xa_start_time_); TO_STRING_TIME_US(build_server_request_time_); TO_STRING_TIME_US(plugin_compress_request_time_); TO_STRING_TIME_US(prepare_send_request_to_server_time_); @@ -100,9 +104,10 @@ int64_t ObTransactionStat::to_string(char *buf, const int64_t buf_len) const TO_STRING_TIME_US(send_saved_login_time_); TO_STRING_TIME_US(send_use_database_time_); TO_STRING_TIME_US(send_session_vars_time_); + TO_STRING_TIME_US(send_session_user_vars_time_); TO_STRING_TIME_US(send_all_session_vars_time_); - TO_STRING_TIME_US(send_last_insert_id_time_); TO_STRING_TIME_US(send_start_trans_time_); + TO_STRING_TIME_US(send_xa_start_time_); TO_STRING_TIME_US(build_server_request_time_); TO_STRING_TIME_US(plugin_compress_request_time_); TO_STRING_TIME_US(prepare_send_request_to_server_time_); diff --git a/src/obproxy/proxy/mysql/ob_mysql_sm_time_stat.h b/src/obproxy/proxy/mysql/ob_mysql_sm_time_stat.h index 04b11120e..45d19c9dd 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_sm_time_stat.h +++ b/src/obproxy/proxy/mysql/ob_mysql_sm_time_stat.h @@ -69,7 +69,8 @@ struct ObTransactionMilestones ObTransactionMilestones() : last_client_cmd_end_(0), server_connect_begin_(0), server_connect_end_(0), server_first_write_begin_(0), pl_lookup_begin_(0), pl_lookup_end_(0), - pl_process_begin_(0), pl_process_end_(0), congestion_control_begin_(0), + pl_process_begin_(0), pl_process_end_(0), bl_lookup_begin_(0), bl_lookup_end_(0), + bl_process_begin_(0), bl_process_end_(0), congestion_control_begin_(0), congestion_control_end_(0), congestion_process_begin_(0), congestion_process_end_(0), cluster_resource_create_begin_(0), cluster_resource_create_end_(0), trans_start_(0), trans_finish_(0), do_observer_open_begin_(0), do_observer_open_end_(0) @@ -111,6 +112,14 @@ struct ObTransactionMilestones ObHRTime pl_process_begin_; ObHRTime pl_process_end_; + // binlog location lookup + ObHRTime bl_lookup_begin_; + ObHRTime bl_lookup_end_; + + // binlog location process + ObHRTime bl_process_begin_; + ObHRTime bl_process_end_; + // congestion_control_lookup ObHRTime congestion_control_begin_; ObHRTime congestion_control_end_; @@ -154,6 +163,8 @@ struct ObCmdTimeStat ObHRTime cluster_resource_create_time_; ObHRTime pl_lookup_time_; ObHRTime pl_process_time_; + ObHRTime bl_lookup_time_; + ObHRTime bl_process_time_; #if OB_DETAILED_SLOW_QUERY ObHRTime debug_assign_time_; @@ -177,9 +188,10 @@ struct ObCmdTimeStat ObHRTime server_send_saved_login_time_; ObHRTime server_send_use_database_time_; ObHRTime server_send_session_variable_time_; + ObHRTime server_send_session_user_variable_time_; ObHRTime server_send_all_session_variable_time_; - ObHRTime server_send_last_insert_id_time_; ObHRTime server_send_start_trans_time_; + ObHRTime server_send_xa_start_time_; ObHRTime build_server_request_time_; ObHRTime plugin_compress_request_time_; @@ -241,9 +253,10 @@ struct ObTransactionStat ObHRTime send_saved_login_time_; ObHRTime send_use_database_time_; ObHRTime send_session_vars_time_; + ObHRTime send_session_user_vars_time_; ObHRTime send_all_session_vars_time_; - ObHRTime send_last_insert_id_time_; ObHRTime send_start_trans_time_; + ObHRTime send_xa_start_time_; ObHRTime build_server_request_time_; ObHRTime plugin_compress_request_time_; diff --git a/src/obproxy/proxy/mysql/ob_mysql_transact.cpp b/src/obproxy/proxy/mysql/ob_mysql_transact.cpp index 9988c2bbd..c4d134bdd 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_transact.cpp +++ b/src/obproxy/proxy/mysql/ob_mysql_transact.cpp @@ -38,6 +38,7 @@ #include "lib/encrypt/ob_encrypted_helper.h" #include "proxy/shard/obproxy_shard_utils.h" #include "rpc/obmysql/packet/ompk_change_user.h" +#include "rpc/obmysql/packet/ompk_prepare_execute.h" #include "omt/ob_proxy_config_table_processor.h" using namespace oceanbase::share; @@ -61,6 +62,62 @@ namespace proxy #define MYSQL_INCREMENT_TRANS_STAT(X) update_stat(s, X, 1); #define MYSQL_SUM_TIME_STAT(X, cost) update_stat(s, X, cost); +bool ObMysqlTransact::is_in_trans(ObTransState &s) +{ + // if a trans is commit, the state will be set to TRANSACTION_COMPLETE, + // so if current state is CMD_COMPLETE, it means that we have send a sql successfully and + // the trans has not commit, that is to say "in trans" + // so far, there are three cases NOT in trans: + // 1. handshake response (login packet) need pl lookup + // 2. the first sql of one transaction + // 3. the second sql of one transaction, if the first sql is 'begin' or 'start transaction' + + // s.current_.state_ may changed to CONNECTION_ALIVE on state_server_response_read, + // here add last_request_in_trans to correct transaction state + + bool is_in_trans = false; + if (!s.is_auth_request_ && !s.is_hold_start_trans_ && !s.is_hold_xa_start_) { + if (ObMysqlTransact::CMD_COMPLETE == s.current_.state_) { + is_in_trans = true; + } else if (ObMysqlTransact::TRANSACTION_COMPLETE != s.current_.state_ + && s.sm_->client_session_ != NULL + && s.sm_->client_session_->is_last_request_in_trans()) { + is_in_trans = true; + } + } + return is_in_trans; +} + +void ObMysqlTransact::record_trans_state(ObTransState &s, bool is_in_trans) +{ + ObMysqlClientSession *client_session = s.sm_->get_client_session(); + bool last_request_in_trans = client_session->is_last_request_in_trans(); + if (client_session->is_proxy_enable_trans_internal_routing()) { + // set distributed transaction route flag + bool server_trans_internal_routing = s.trans_info_.server_response_.get_analyze_result().is_server_trans_internal_routing(); + bool is_trans_internal_routing = ObMysqlTransact::handle_set_trans_internal_routing(s, server_trans_internal_routing); + + if (!last_request_in_trans && is_in_trans) { + client_session->set_trans_coordinator_ss_addr(s.server_info_.addr_.sa_); + LOG_DEBUG("start internal routing transaction", "coordinator addr", client_session->get_trans_coordinator_ss_addr()); + s.trace_log_.set_need_print(is_trans_internal_routing); + s.trace_log_.log_it("[trans_start]", + "proxy_sessid", client_session->get_proxy_sessid(), + "coordinator", s.server_info_.addr_, + "sql_cmd", s.trans_info_.sql_cmd_, + "stmt_type", s.trans_info_.client_request_.get_parse_result().get_stmt_type()); + } else if (last_request_in_trans && !is_in_trans) { + // close txn, refresh enable_transaction_internal_routing_ + LOG_DEBUG("internal routing transaction close", "coordinator addr", client_session->get_trans_coordinator_ss_addr()); + client_session->get_trans_coordinator_ss_addr().reset(); + } + + client_session->set_trans_internal_routing(is_trans_internal_routing); + LOG_DEBUG("set transaction internal routing flag", "internal routing state", is_trans_internal_routing); + } + client_session->set_last_request_in_trans(is_in_trans); +} + void ObMysqlTransact::handle_error_jump(ObTransState &s) { LOG_WARN("[ObMysqlTransact::handle_error_jump]"); @@ -127,6 +184,31 @@ bool ObMysqlTransact::ObTransState::is_for_update_sql(common::ObString src_sql) return bret; } +ObConsistencyLevel ObMysqlTransact::ObTransState::get_read_write_consistency_level(ObClientSessionInfo &session_info) +{ + ObConsistencyLevel ret_level = common::STRONG; + bool enable_weak_read = false; + if (ObMysqlTransact::is_in_trans(sm_->trans_state_) + || 0 == session_info.get_cached_variables().get_autocommit() + || is_hold_start_trans_ + || is_hold_xa_start_) { + if (ObMysqlTransact::is_in_trans(sm_->trans_state_) + || is_hold_start_trans_ + || is_hold_xa_start_) { + enable_weak_read = false; + } else { + enable_weak_read = sm_->enable_read_write_split_ && sm_->enable_transaction_split_; + } + } else { + enable_weak_read = sm_->enable_read_write_split_; + } + + if (enable_weak_read) { + ret_level = common::WEAK; + } + return ret_level; +} + ObConsistencyLevel ObMysqlTransact::ObTransState::get_trans_consistency_level( ObClientSessionInfo &cs_info) { @@ -152,14 +234,20 @@ ObConsistencyLevel ObMysqlTransact::ObTransState::get_trans_consistency_level( trans_info_.client_request_.get_parse_result().is_text_ps_select_stmt()) { const ObConsistencyLevel sql_hint = trans_info_.client_request_.get_parse_result().get_hint_consistency_level(); const ObConsistencyLevel sys_var = static_cast(cs_info.get_read_consistency()); + const ObConsistencyLevel read_write_consistence_level = get_read_write_consistency_level(cs_info); if (common::STRONG == sql_hint || common::WEAK == sql_hint) { ret_level = sql_hint; } else { - if (common::STRONG == sys_var || common::WEAK == sys_var) { + if (common::WEAK == sys_var) { ret_level = sys_var; } else { - PROXY_LOG(DEBUG, "unsupport ob_read_consistency vars, maybe proxy is old, use strong read " + if (common::STRONG == read_write_consistence_level || common::WEAK == read_write_consistence_level) { + ret_level = read_write_consistence_level; + } + if (common::STRONG != sys_var) { + PROXY_LOG(DEBUG, "unsupport ob_read_consistency vars, maybe proxy is old, use strong read " "instead", "sys_var", get_consistency_level_str(sys_var)); + } } } if (common::WEAK == ret_level) { @@ -296,10 +384,8 @@ void ObMysqlTransact::acquire_cached_server_session(ObTransState &s) } else if (get_global_proxy_config().enable_cached_server && !s.sm_->client_session_->is_proxy_mysql_client_ && NULL != last_session && OB_LIKELY(!s.mysql_config_params_->is_random_routing_mode())) { - const int32_t ip = ops_ip4_addr_host_order(last_session->get_netvc()->get_remote_addr()); - const int32_t port = static_cast(ops_ip_port_host_order(last_session->get_netvc()->get_remote_addr())); ObAddr last_addr; - last_addr.set_ipv4_addr(ip, port); + last_addr.set_sockaddr(last_session->get_netvc()->get_remote_addr()); #if OB_DETAILED_SLOW_QUERY ObHRTime t1 = common::get_hrtime_internal(); #endif @@ -367,8 +453,13 @@ bool ObMysqlTransact::can_direct_ok_for_login(ObTransState &s) { bool bret = false; ObClientSessionInfo &cs_info = s.sm_->client_session_->get_session_info(); - if (!(obmysql::OB_MYSQL_COM_LOGIN == s.trans_info_.sql_cmd_ && s.is_auth_request_ && s.sm_->client_session_->is_session_pool_client())) { - // should only session_pool_client and LOGIN for auth + if (!(obmysql::OB_MYSQL_COM_LOGIN == s.trans_info_.sql_cmd_ && s.is_auth_request_)) { + // should only LOGIN for auth + } else if (s.sm_->client_session_->can_direct_send_request_) { + //scan all return ok + bret = true; + } else if (!s.sm_->client_session_->is_session_pool_client()) { + // should only session_pool_client } else if (cs_info.is_sharding_user()) { bret = true; } else if (!s.sm_->client_session_->is_proxy_mysql_client_ && get_global_proxy_config().enable_no_sharding_skip_real_conn) { @@ -497,7 +588,7 @@ void ObMysqlTransact::handle_mysql_request(ObTransState &s) int ret = OB_SUCCESS; sockaddr sa; memset(&sa, 0, sizeof(sa)); - bool need_pl_lookup = ObMysqlTransact::need_pl_lookup(s); + bool need_pl_lookup = (ObMysqlTransact::need_pl_lookup(s) == NEED_PL_LOOKUP); ObMysqlServerSession *last_session = s.sm_->client_session_->get_server_session(); if (need_pl_lookup) { ObMysqlServerSession *svr_session = NULL; @@ -567,32 +658,59 @@ void ObMysqlTransact::handle_ps_close_reset(ObTransState &s) int ret = OB_SUCCESS; ObMysqlClientSession *client_session = s.sm_->get_client_session(); - ObPsIdAddrs::ADDR_HASH_SET &remove_addrs = client_session->get_session_info().get_request_send_addrs(); + ObIArray &remove_addrs = client_session->get_session_info().get_request_send_addrs(); // At the end of each request, server_entry_ and server_session_ will be placed, // including the internal jump of the close command multiple times. if (!client_session->is_first_handle_request()) { s.sm_->release_server_session(); // If it is not the first time to come in, it will also be judged according to the transaction status of the first time. - s.need_pl_lookup_ = s.need_pl_lookup_ && !client_session->is_in_trans_for_close_request(); + bool need_pl_lookup = s.is_need_pl_lookup() && !client_session->is_in_trans_for_close_request(); + // sync pl_lookup_state_ + if (!need_pl_lookup) { + if (client_session->is_proxy_enable_trans_internal_routing()) { + s.pl_lookup_state_ = USE_COORDINATOR_SESSION; + } else { + s.pl_lookup_state_ = USE_LAST_SERVER_SESSION; + } + } } else { // The first time you come in, record the previous transaction status client_session->set_in_trans_for_close_request(is_in_trans(s)); remove_addrs.reuse(); + bool found = false; uint32_t client_ps_id = client_session->get_session_info().get_client_ps_id(); // If greater than 1 << 31L, it means cursor_id; otherwise, it is ps_id if (client_ps_id >= (CURSOR_ID_START)) { ObCursorIdAddr *cursor_id_addr = client_session->get_session_info().get_cursor_id_addr(client_ps_id); if (NULL != cursor_id_addr) { - remove_addrs.set_refactored(cursor_id_addr->get_addr()); + for (int64_t i = 0; !found && i< remove_addrs.count(); i++) { + if (remove_addrs.at(i) == cursor_id_addr->get_addr()) { + found = true; + } + } + if (!found) { + if (OB_FAIL(remove_addrs.push_back(cursor_id_addr->get_addr()))) { + LOG_WARN("fail to push back addr", K(ret)); + } + } } } else { ObPsIdAddrs *ps_id_addrs = client_session->get_session_info().get_ps_id_addrs(client_ps_id); - if (NULL != ps_id_addrs && 0 != ps_id_addrs->get_addrs().size()) { - ObPsIdAddrs::ADDR_HASH_SET::iterator iter = ps_id_addrs->get_addrs().begin(); - ObPsIdAddrs::ADDR_HASH_SET::iterator iter_end = ps_id_addrs->get_addrs().end(); - for (; iter != iter_end; iter++) { - remove_addrs.set_refactored(iter->first); + if (NULL != ps_id_addrs && 0 != ps_id_addrs->get_addrs().count()) { + ObIArray &array = ps_id_addrs->get_addrs(); + for (int64_t i = 0; i < array.count(); i++) { + found = false; + for (int64_t j = 0; !found && j < remove_addrs.count(); j++) { + if (remove_addrs.at(j) == array.at(i)) { + found = true; + } + } + if (!found) { + if (OB_FAIL(remove_addrs.push_back(array.at(i)))) { + LOG_WARN("fail to push back addr", K(ret)); + } + } } } } @@ -605,7 +723,7 @@ void ObMysqlTransact::handle_ps_close_reset(ObTransState &s) * 1. last_session does not exist. * 2. last_bound_session is not null. */ - if (!s.need_pl_lookup_ && client_session->is_first_handle_request() + if (!s.is_need_pl_lookup() && client_session->is_first_handle_request() && (NULL == last_session || NULL != last_bound_session)) { LOG_ERROR("[ObMysqlTransact::handle request] something is wrong, we have to disconnect", "is_first_handle_close_request_", client_session->is_first_handle_request(), @@ -616,35 +734,32 @@ void ObMysqlTransact::handle_ps_close_reset(ObTransState &s) bool is_need_send_to_bound_ss = false; ObIpEndpoint addr; - if (0 != remove_addrs.size()) { + if (0 != remove_addrs.count()) { is_need_send_cmd = true; /* If no routing is required, and it is the first time to come in * Then check if there is any need to send to bound_ss, if so, send it first, * otherwise migrate the connection, and then migrate back */ - if (!s.need_pl_lookup_ + if (!s.is_need_pl_lookup() && client_session->is_first_handle_request()) { - ObPsIdAddrs::ADDR_HASH_SET::iterator iter = remove_addrs.begin(); - ObPsIdAddrs::ADDR_HASH_SET::iterator iter_end = remove_addrs.end(); - - for (; iter != iter_end; iter++) { - if (iter->first == ObIpEndpoint(last_session->get_netvc()->get_remote_addr())) { + for (int64_t i = 0; i < remove_addrs.count(); i++) { + if (remove_addrs.at(i) == ObIpEndpoint(last_session->get_netvc()->get_remote_addr())) { is_need_send_to_bound_ss = true; - addr = iter->first; + addr = remove_addrs.at(i); break; } } } if (!is_need_send_to_bound_ss) { - addr = remove_addrs.begin()->first; + addr = remove_addrs.at(0); } } if (is_need_send_cmd) { // If no routing is required, and there is no last server session in the server to be sent, migrate ObMysqlServerSession *last_bound_session = client_session->get_last_bound_server_session(); - if (!s.need_pl_lookup_ + if (!s.is_need_pl_lookup() && !is_need_send_to_bound_ss && NULL == last_bound_session) { client_session->attach_server_session(NULL); @@ -660,6 +775,7 @@ void ObMysqlTransact::handle_ps_close_reset(ObTransState &s) start_access_control(s); } } else { + LOG_DEBUG("handle_ps_close_reset don't need send cmd"); // This indicates that session migration has occurred and needs to be migrated back if (client_session->is_need_return_last_bound_ss()) { if (NULL != last_bound_session) { @@ -693,12 +809,16 @@ void ObMysqlTransact::handle_oceanbase_request(ObTransState &s) int ret = OB_SUCCESS; ObClientSessionInfo &cs_info = get_client_session_info(s); ObProxyMysqlRequest &client_request = s.trans_info_.client_request_; - if (OB_LIKELY(cs_info.is_allow_use_last_session())) { - s.need_pl_lookup_ = need_pl_lookup(s); - } else { - s.need_pl_lookup_ = true; + ObPLLookupState state = need_pl_lookup(s); + // if target db server set + bool hint_target_db = OB_NOT_NULL(client_request.get_parse_result().get_target_db_server()) + && !client_request.get_parse_result().get_target_db_server()->is_empty(); + bool conf_target_db = OB_NOT_NULL(s.sm_->target_db_server_) + && !s.sm_->target_db_server_->is_empty(); + s.pl_lookup_state_ = state; + if (OB_UNLIKELY(!cs_info.is_allow_use_last_session())) { + s.pl_lookup_state_ = NEED_PL_LOOKUP; } - // generate span before each request if (s.sm_->get_client_session()->is_first_handle_request()) { if (OB_FAIL(s.sm_->handle_req_for_begin_proxy_root_span())) { @@ -707,18 +827,25 @@ void ObMysqlTransact::handle_oceanbase_request(ObTransState &s) } obmysql::ObMySQLCmd cmd = s.trans_info_.sql_cmd_; - - if (OB_UNLIKELY(cs_info.is_sharding_user()) - && OB_FAIL(ObProxyShardUtils::update_sys_read_consistency_if_need(cs_info))) { + if (is_in_trans(s) + && s.sm_->get_client_session()->is_proxy_enable_trans_internal_routing() + && OB_UNLIKELY(!s.sm_->get_client_session()->get_trans_coordinator_ss_addr().is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("coordinator session addr is invalid, we have to disconnect", K(ret)); + TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); // disconnect + } else if (OB_UNLIKELY(cs_info.is_sharding_user()) + && OB_FAIL(ObProxyShardUtils::update_sys_read_consistency_if_need(cs_info))) { LOG_WARN("fail to update_sys_read_consistency_if_need", K(ret)); TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); // disconnect + } else if (s.sm_->get_client_session()->get_session_info().get_priv_info().user_name_ == ObProxyTableInfo::DETECT_USERNAME_USER && s.server_info_.addr_.is_valid()) { + lookup_skip_open_server(s); } else if (OB_UNLIKELY(need_server_session_lookup(s))) { TRANSACT_RETURN(SM_ACTION_SERVER_ADDR_LOOKUP, handle_server_addr_lookup); } else if (OB_UNLIKELY(obmysql::OB_MYSQL_COM_STMT_CLOSE == cmd || obmysql::OB_MYSQL_COM_STMT_RESET == cmd)) { handle_ps_close_reset(s); } else if (client_request.get_parse_result().is_text_ps_drop_stmt()) { handle_ps_close_reset(s); - } else if (OB_LIKELY(s.need_pl_lookup_)) { + } else if (OB_LIKELY(s.is_need_pl_lookup())) { // if need pl lookup, we should extract pl info first if (OB_FAIL(extract_partition_info(s))) { LOG_WARN("fail to extract partition info", K(ret)); @@ -780,26 +907,80 @@ void ObMysqlTransact::handle_oceanbase_request(ObTransState &s) LOG_DEBUG("succ to set target addr for send piece/prepare execute/send long data", "address", s.server_info_.addr_, KPC(info)); } - } else if ((s.mysql_config_params_->is_mock_routing_mode() && !s.sm_->client_session_->is_proxy_mysql_client_) - || s.mysql_config_params_->is_mysql_routing_mode()) { - if (OB_FAIL(s.mysql_config_params_->get_one_test_server_addr(s.server_info_.addr_))) { - LOG_INFO("mysql or mock mode, but test server addr in not set, do normal pl lookup", K(ret)); - if (NULL == s.sm_->client_session_->dummy_entry_) { - s.sm_->client_session_->is_need_update_dummy_entry_ = true; - } - ret = OB_SUCCESS; - } else { - s.sm_->client_session_->test_server_addr_ = s.server_info_.addr_; - s.pll_info_.lookup_success_ = true; - LOG_DEBUG("mysql mode, test server is valid, just use it and skip pl lookup", + } else { /* do nothing */} + + // Specified server addr + // 1. target_db_server (comment & multi levle config) + // 2. test_server_addr & server_routing_mode (deprecated global config) + + // target db server (sql comment & multi level config) + if (OB_SUCC(ret) && !s.pll_info_.lookup_success_) { + // Use target_db_server + // exsit in sql comment parsed result + if (hint_target_db) { + if (OB_FAIL(client_request.get_parse_result().get_target_db_server()->get(s.server_info_.addr_))) { + LOG_WARN("fail to get target db server from sql comment", K(ret)); + TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); + } else { + // in case of dummy entry is NULL + if (NULL == s.sm_->client_session_->dummy_entry_) { + s.sm_->client_session_->is_need_update_dummy_entry_ = true; + } + s.pll_info_.lookup_success_ = true; + LOG_DEBUG("succ to get target db server from sql comment", "address", s.server_info_.addr_); + } + // exist in multi level config target_db_server + } else if (conf_target_db) { + s.sm_->target_db_server_->reuse(); + if (OB_FAIL(s.sm_->target_db_server_->get(s.server_info_.addr_))) { + LOG_WARN("fail to get target db server from multi level config", K(ret)); + TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); + } else { + // in case of dummy entry is NULL + if (NULL == s.sm_->client_session_->dummy_entry_) { + s.sm_->client_session_->is_need_update_dummy_entry_ = true; + } + s.pll_info_.lookup_success_ = true; + LOG_DEBUG("succ to get target db server from multi level config", + "address", s.server_info_.addr_); + } + } else { /* do nothing */} + } else if (OB_SUCC(ret)) { + if ((hint_target_db && !client_request.get_parse_result().get_target_db_server()->contains(s.server_info_.addr_)) || + (!hint_target_db && conf_target_db && !s.sm_->target_db_server_->contains(s.server_info_.addr_))) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("Not allow to route to", "choosen server", s.server_info_.addr_, K(ret)); + TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); } - } else if (OB_UNLIKELY(!s.mysql_config_params_->is_random_routing_mode() + } + // deprecated global config + if (OB_SUCC(ret) && !s.pll_info_.lookup_success_) { + if ((s.mysql_config_params_->is_mock_routing_mode() && !s.sm_->client_session_->is_proxy_mysql_client_) + || s.mysql_config_params_->is_mysql_routing_mode()) { + if (OB_FAIL(s.mysql_config_params_->get_one_test_server_addr(s.server_info_.addr_))) { + LOG_INFO("mysql or mock mode, but test server addr in not set, do normal pl lookup", K(ret)); + if (NULL == s.sm_->client_session_->dummy_entry_) { + s.sm_->client_session_->is_need_update_dummy_entry_ = true; + } + ret = OB_SUCCESS; + } else { + s.sm_->client_session_->test_server_addr_ = s.server_info_.addr_; + s.pll_info_.lookup_success_ = true; + LOG_DEBUG("mysql mode, test server is valid, just use it and skip pl lookup", + "address", s.server_info_.addr_); + } + } else { /* do nothing */} + } + + if (OB_SUCC(ret) && !s.pll_info_.lookup_success_) { + if (OB_UNLIKELY(!s.mysql_config_params_->is_random_routing_mode() && !s.api_server_addr_set_ - && s.pll_info_.te_name_.is_all_dummy_table() + && s.pll_info_.te_name_.is_all_dummy_table() && cs_info.is_allow_use_last_session())) { - acquire_cached_server_session(s); - } // end of !is_in_test_mode + acquire_cached_server_session(s); + } + } if (OB_SUCC(ret)) { TRANSACT_RETURN(SM_ACTION_PARTITION_LOCATION_LOOKUP, handle_pl_lookup); @@ -807,11 +988,30 @@ void ObMysqlTransact::handle_oceanbase_request(ObTransState &s) } } else { // !need_pl_lookup - LOG_DEBUG("[ObMysqlTransact::handle request] force to use last server session"); - ObMysqlServerSession *last_session = s.sm_->client_session_->get_server_session(); + LOG_DEBUG("[ObMysqlTransact::handle request] force to use last server session/coordinator server session", K(get_pl_lookup_state_string(s.pl_lookup_state_))); ObMysqlClientSession *client_session = s.sm_->get_client_session(); + ObMysqlServerSession *last_session = client_session->get_server_session(); + sockaddr target_addr; + + if (s.pl_lookup_state_ == USE_COORDINATOR_SESSION) { + LOG_DEBUG("use coordinator session"); + target_addr = client_session->get_trans_coordinator_ss_addr().sa_; + } else if (s.pl_lookup_state_ == USE_LAST_SERVER_SESSION) { + LOG_DEBUG("use last server session"); + if (OB_UNLIKELY(NULL == last_session )) { + TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[ObMysqlTransact::handle request] last server session is invalid, we have to disconnect", K(ret)); + } else { + target_addr = last_session->get_netvc()->get_remote_addr(); + } + } else { + TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[ObMysqlTransact::handle request] unexpected pl lookup state, we have to disconnect", K(s.pl_lookup_state_), K(ret)); + } - if (OB_LIKELY(NULL != last_session)) { + if (OB_SUCC(ret)) { if (obmysql::OB_MYSQL_COM_STMT_FETCH == cmd) { ObCursorIdAddr *cursor_id_addr = NULL; if (OB_FAIL(cs_info.get_cursor_id_addr(cursor_id_addr))) { @@ -822,11 +1022,16 @@ void ObMysqlTransact::handle_oceanbase_request(ObTransState &s) TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); } } else { - if (OB_UNLIKELY(cursor_id_addr->get_addr() != last_session->get_netvc()->get_remote_addr())) { - client_session->attach_server_session(NULL); - last_session->do_io_read(client_session, 0, NULL); - client_session->set_last_bound_server_session(last_session); - client_session->set_need_return_last_bound_ss(true); + if (OB_SUCC(ret) && OB_UNLIKELY(!ops_ip_addr_port_eq(cursor_id_addr->get_addr(), target_addr))) { + if (USE_COORDINATOR_SESSION == s.pl_lookup_state_) { + // under internal routing transaction, OB_MYSQL_COM_STMT_FETCH may be routed to participant + // don't need compare target server + } else { + client_session->attach_server_session(NULL); + last_session->do_io_read(client_session, 0, NULL); + client_session->set_last_bound_server_session(last_session); + client_session->set_need_return_last_bound_ss(true); + } } s.server_info_.set_addr(cursor_id_addr->get_addr()); @@ -841,26 +1046,31 @@ void ObMysqlTransact::handle_oceanbase_request(ObTransState &s) } else { TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); } - } else if (OB_UNLIKELY(cursor_id_addr->get_addr() != last_session->get_netvc()->get_remote_addr())) { - s.mysql_errcode_ = OB_ERR_DISTRIBUTED_NOT_SUPPORTED; - s.mysql_errmsg_ = "fetch cursor target server is not the trans server"; - int tmp_ret = OB_SUCCESS; - if (OB_UNLIKELY(OB_SUCCESS != (tmp_ret = build_error_packet(s, client_session)))) { - LOG_WARN("fail to build err packet", K(tmp_ret)); + } else if (OB_UNLIKELY(!ops_ip_addr_port_eq(cursor_id_addr->get_addr(), target_addr))) { + if (USE_COORDINATOR_SESSION == s.pl_lookup_state_) { + // under internal routing transaction, OB_MYSQL_COM_STMT_GET_PIECE_DATA may be routed to participant + // don't need compare target server + target_addr = cursor_id_addr->get_addr().sa_; } else { - LOG_WARN("fetch cursor target server is not the trans server", - "fetch cursor target server", cursor_id_addr->get_addr(), - "trans server", ObIpEndpoint(last_session->get_netvc()->get_remote_addr())); - } + s.mysql_errcode_ = OB_ERR_DISTRIBUTED_NOT_SUPPORTED; + s.mysql_errmsg_ = "fetch cursor target server is not the trans server"; + int tmp_ret = OB_SUCCESS; + if (OB_UNLIKELY(OB_SUCCESS != (tmp_ret = build_error_packet(s, client_session)))) { + LOG_WARN("fail to build err packet", K(tmp_ret)); + } else { + LOG_WARN("fetch cursor target server is not the trans server", + "fetch cursor target server", cursor_id_addr->get_addr(), + "trans server", ObIpEndpoint(target_addr)); + } - ret = OB_ERR_DISTRIBUTED_NOT_SUPPORTED; - s.inner_errcode_ = ret; - s.current_.state_ = ObMysqlTransact::INTERNAL_ERROR; - TRANSACT_RETURN(SM_ACTION_INTERNAL_NOOP, NULL); + ret = OB_ERR_DISTRIBUTED_NOT_SUPPORTED; + s.inner_errcode_ = ret; + s.current_.state_ = ObMysqlTransact::INTERNAL_ERROR; + TRANSACT_RETURN(SM_ACTION_INTERNAL_NOOP, NULL); + } } - if (OB_SUCC(ret)) { - s.server_info_.set_addr(last_session->get_netvc()->get_remote_addr()); + s.server_info_.set_addr(target_addr); s.pll_info_.lookup_success_ = true; } } else if (obmysql::OB_MYSQL_COM_STMT_SEND_PIECE_DATA == cmd @@ -881,7 +1091,7 @@ void ObMysqlTransact::handle_oceanbase_request(ObTransState &s) ret = OB_ERR_UNEXPECTED; LOG_WARN("info is invalid", K(ret)); TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); - } else if (OB_UNLIKELY(info->get_addr() != last_session->get_netvc()->get_remote_addr())) { + } else if (OB_UNLIKELY(!ops_ip_addr_port_eq(info->get_addr(), target_addr))) { s.mysql_errcode_ = OB_ERR_DISTRIBUTED_NOT_SUPPORTED; s.mysql_errmsg_ = "send piece info target server is not the trans server"; int tmp_ret = OB_SUCCESS; @@ -890,7 +1100,7 @@ void ObMysqlTransact::handle_oceanbase_request(ObTransState &s) } else { LOG_WARN("send piece/long data target server is not the trans server", "target server", info->get_addr(), - "trans server", ObIpEndpoint(last_session->get_netvc()->get_remote_addr())); + "trans server", ObIpEndpoint(target_addr)); } ret = OB_ERR_DISTRIBUTED_NOT_SUPPORTED; @@ -900,22 +1110,29 @@ void ObMysqlTransact::handle_oceanbase_request(ObTransState &s) } if (OB_SUCC(ret)) { - s.server_info_.set_addr(last_session->get_netvc()->get_remote_addr()); + s.server_info_.set_addr(target_addr); s.pll_info_.lookup_success_ = true; } } else { - s.server_info_.set_addr(last_session->get_netvc()->get_remote_addr()); + s.server_info_.set_addr(target_addr); s.pll_info_.lookup_success_ = true; } if (OB_SUCC(ret)) { - start_access_control(s); + // if target db server set, then make sure target db server is the choosen server + if ((hint_target_db && !client_request.get_parse_result().get_target_db_server()->contains(s.server_info_.addr_)) || + (!hint_target_db && conf_target_db && !s.sm_->target_db_server_->contains(s.server_info_.addr_))) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("Not allow to route to", "choosen server", s.server_info_.addr_, K(ret)); + TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); + } else { + start_access_control(s); + } } - } else { - LOG_WARN("[ObMysqlTransact::handle request] last session is NULL, we have to disconnect"); - TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); } } // end of !s.need_pl_lookup + + LOG_DEBUG("handle oceanbase request, is addr valid:", K(s.server_info_.addr_.is_valid())); } void ObMysqlTransact::handle_fetch_request(ObTransState &s) @@ -998,6 +1215,8 @@ void ObMysqlTransact::handle_request(ObTransState &s) } // so it's an internal request TRANSACT_RETURN(SM_ACTION_INTERNAL_REQUEST, handle_internal_request); + } else if (OB_UNLIKELY(is_binlog_request(s))) { + handle_binlog_request(s); } else { if (OB_UNLIKELY(get_global_performance_params().enable_stat_)) { if (obmysql::OB_MYSQL_COM_QUERY == s.trans_info_.sql_cmd_) { @@ -1049,31 +1268,131 @@ void ObMysqlTransact::handle_request(ObTransState &s) } } -inline bool ObMysqlTransact::need_use_last_server_session(ObTransState &s) +inline bool ObMysqlTransact::need_use_coordinator_session(ObTransState &s) { + // session in trans internal routing state + bool use_coordinator = false; + int ret = OB_SUCCESS; + ObSqlParseResult &parser_result = s.trans_info_.client_request_.get_parse_result(); + ObClientSessionInfo &session_info = s.sm_->get_client_session()->get_session_info(); + if (ObMysqlTransact::is_trans_specified(s)) { + if (s.sm_->get_client_session() != NULL + && s.sm_->get_client_session()->get_server_session() != NULL + && ops_ip_addr_port_eq (s.sm_->get_client_session()->get_trans_coordinator_ss_addr(), + s.sm_->get_client_session()->get_server_session()->get_netvc()->get_remote_addr())) { + LOG_WARN("internal routing transaction specified, coordinator session not equal with last session", K(ret)); + } + use_coordinator = true; + } else if (s.trans_info_.request_content_length_ > 0) { + // large request, route to coordinator session + use_coordinator = true; + } else if (s.sm_->get_client_session()->is_trans_internal_routing() + && is_sql_able_to_route_participant_in_trans(parser_result, s.trans_info_.sql_cmd_)) { + use_coordinator = false; + } else if (s.sm_->get_client_session()->is_trans_internal_routing() && parser_result.is_text_ps_execute_stmt()) { + ObTextPsEntry* text_ps_entry = NULL; + ObTextPsNameEntry* text_ps_name_entry = session_info.get_text_ps_name_entry(); + if (OB_ISNULL(text_ps_name_entry)) { + use_coordinator = true; + ret = OB_ERR_PREPARE_STMT_NOT_FOUND; + LOG_WARN("need use coordinator on text ps execute stmt, get text ps name entry failed", K(ret)); + } else if (OB_ISNULL(text_ps_entry = text_ps_name_entry->text_ps_entry_) || !text_ps_entry->is_valid()) { + use_coordinator = true; + ret = OB_INVALID_ERROR; + LOG_WARN("need use coordinator on text ps execute stmt, get text ps entry failed", K(ret)); + } else { + use_coordinator = !is_sql_able_to_route_participant_in_trans(text_ps_entry->get_base_ps_parse_result(), s.trans_info_.sql_cmd_); + } + } else { + // the rest of sql, use coordinator session + use_coordinator = true; + } + return use_coordinator; +} + +bool ObMysqlTransact::is_sql_able_to_route_participant_in_trans(obutils::ObSqlParseResult& base_sql_parse_result, obmysql::ObMySQLCmd sql_cmd) { + // transaction internal routing rule + // (1) route dml with table name to participant + // (2) route OB_MYSQL_COM_STMT_EXECUTE or text ps execute with inner sql like (1) to participant + // (3) route sql command except OB_MYSQL_COM_QUERY/OB_MYSQL_COM_STMT_PREPARE/OB_MYSQL_COM_STMT_EXECUTE to coordinator + // (4) route dual request to coordinator, in case of sql like `select DBMS_XA.XA_START(DBMS_XA_XID(?,?,?), 65536) from dual;` start xa transaction + // (5) route multi-stmt to coordinator + + bool able_to_route = false; + switch (sql_cmd) { + case obmysql::OB_MYSQL_COM_QUERY: + case obmysql::OB_MYSQL_COM_STMT_PREPARE: + case obmysql::OB_MYSQL_COM_STMT_EXECUTE: + able_to_route = true; + break; + + default: + able_to_route = false; + break; + } + if (able_to_route) { + if (base_sql_parse_result.is_dual_request()) { + able_to_route = false; + } else { + able_to_route = (base_sql_parse_result.is_text_ps_prepare_stmt() + && base_sql_parse_result.is_text_ps_inner_dml_stmt() + && !base_sql_parse_result.is_text_ps_call_stmt() + && !base_sql_parse_result.is_multi_semicolon_in_stmt() + && base_sql_parse_result.get_table_name_length() > 0) + || (base_sql_parse_result.is_dml_stmt() + && !base_sql_parse_result.is_multi_stmt() + && !base_sql_parse_result.is_multi_semicolon_in_stmt() + && base_sql_parse_result.get_table_name_length() > 0); + } + } + return able_to_route; +} + +inline ObMysqlTransact::ObPLLookupState ObMysqlTransact::need_pl_lookup(ObTransState &s) { - // there are three cases we must force to use last server session - // 1. trans has begin, other sql must send to the same server session - // 2. a func depend on last execute sql - // 3. has already specified transaction characteristics (set transaction xxx), not commit yet, - return (is_in_trans(s) - || OB_UNLIKELY(NULL != s.sm_->client_session_ - && !s.sm_->client_session_->is_session_pool_client() - && (s.trans_info_.client_request_.get_parse_result().has_dependent_func() - || s.sm_->client_session_->get_session_info().is_trans_specified()))); + ObPLLookupState state = NEED_PL_LOOKUP; + bool trans_specified = is_trans_specified(s); + bool is_dep_func = has_dependent_func(s); + bool in_trans = is_in_trans(s); + if (in_trans && s.sm_->get_client_session()->is_proxy_enable_trans_internal_routing()) { + if (is_dep_func) { + state = USE_LAST_SERVER_SESSION; + } else { + state = need_use_coordinator_session(s) ? USE_COORDINATOR_SESSION : NEED_PL_LOOKUP; + } + } else { + state =(in_trans || trans_specified || is_dep_func) ? USE_LAST_SERVER_SESSION : NEED_PL_LOOKUP; + } + // if we don't use last server session/coordinator session, we must do pl lookup + LOG_DEBUG("need pl lookup", "state", get_pl_lookup_state_string(state), + "sql_cmd", ObProxyParserUtils::get_sql_cmd_name(s.trans_info_.sql_cmd_), + "is trans specified", trans_specified, + "has dependent func", is_dep_func, + "is in trans", in_trans); + + return state; +} + +inline bool ObMysqlTransact::is_trans_specified(ObTransState &s) +{ + return OB_UNLIKELY(NULL != s.sm_->client_session_ + && !s.sm_->client_session_->is_session_pool_client() + && s.sm_->client_session_->get_session_info().is_trans_specified()); } -inline bool ObMysqlTransact::need_pl_lookup(ObTransState &s) +inline bool ObMysqlTransact::has_dependent_func(ObTransState &s) { - // if we don't use last server session, we must do pl lookup - return !need_use_last_server_session(s); + return OB_UNLIKELY(NULL != s.sm_->client_session_ + && !s.sm_->client_session_->is_session_pool_client() + && (s.trans_info_.client_request_.get_parse_result().has_dependent_func())); } //reroute conditions: -// 1. Transaction first SQL +// 1. Transaction first SQL/FREE TRANSACTION ROUTE // 2. No reroute has occurred // 3. It is not a large request, and the request is less than 4K // (because the data in the read_buffer will be consumed again here, and the second routing will be copied from the 4K Buffer) // 4. In case of EXECUTE or PREPARE_EXECUTE request, no pieceInfo structure exists +// 5.Non-designated primary zone/IP routing inline bool ObMysqlTransact::is_need_reroute(ObMysqlTransact::ObTransState &s) { int ret = OB_SUCCESS; @@ -1082,10 +1401,17 @@ inline bool ObMysqlTransact::is_need_reroute(ObMysqlTransact::ObTransState &s) bool is_need_reroute = false; is_need_reroute = s.mysql_config_params_->enable_reroute_ - && !s.is_rerouted_ && s.need_pl_lookup_ - && s.is_trans_first_request_ + && '\0' == s.mysql_config_params_->proxy_primary_zone_name_[0] + && !s.is_rerouted_ && s.is_need_pl_lookup() + && (s.is_trans_first_request_ + || (ObMysqlTransact::is_in_trans(s) + && s.sm_->client_session_->is_trans_internal_routing())) && !s.trans_info_.client_request_.is_large_request() - && total_request_packet_len == cached_request_packet_len; + && total_request_packet_len == cached_request_packet_len + && (OB_ISNULL(s.trans_info_.client_request_.get_parse_result().get_target_db_server()) + || s.trans_info_.client_request_.get_parse_result().get_target_db_server()->is_empty()) + && (OB_ISNULL(s.sm_->target_db_server_) || s.sm_->target_db_server_->is_empty()); + if (is_need_reroute && (obmysql::OB_MYSQL_COM_STMT_PREPARE_EXECUTE == s.trans_info_.client_request_.get_packet_meta().cmd_ @@ -1159,37 +1485,48 @@ int ObMysqlTransact::extract_partition_info(ObTransState &s) } else { is_table_name_from_parser = true; - database_name = parse_result.get_database_name(); - if (OB_LIKELY(database_name.empty())) { + if (OB_LIKELY(parse_result.get_database_name().empty())) { if (OB_SUCCESS != cs_info.get_database_name(database_name)) { database_name = OB_SYS_DATABASE_NAME; } + ObProxyParseString tmp_database_name; + tmp_database_name.str_ = database_name.ptr(); + tmp_database_name.end_ptr_ = database_name.ptr() + database_name.length() - 1; + tmp_database_name.str_len_ = database_name.length(); + tmp_database_name.quote_type_ = OBPROXY_QUOTE_T_INVALID; + if (OB_FAIL(parse_result.set_db_name(tmp_database_name))) { + LOG_WARN("parse result set db name failed", K(ret)); + } } else { is_database_name_from_parser = true; } - package_name = parse_result.get_package_name(); - if (OB_UNLIKELY(!package_name.empty())) { - is_package_name_from_parser = true; - } - - // if run here, means table name and db name all come from parse result - if (OB_UNLIKELY(s.sm_->client_session_->get_session_info().is_oracle_mode())) { - if (is_table_name_from_parser && OBPROXY_QUOTE_T_INVALID == parse_result.get_table_name_quote()) { - string_to_upper_case(table_name.ptr(), table_name.length()); - } - if (is_database_name_from_parser && OBPROXY_QUOTE_T_INVALID == parse_result.get_database_name_quote()) { - string_to_upper_case(database_name.ptr(), database_name.length()); + if (OB_SUCC(ret)) { + database_name = parse_result.get_database_name(); + package_name = parse_result.get_package_name(); + if (OB_UNLIKELY(!package_name.empty())) { + is_package_name_from_parser = true; } - if (is_package_name_from_parser && OBPROXY_QUOTE_T_INVALID == parse_result.get_package_name_quote()) { - string_to_upper_case(package_name.ptr(), package_name.length()); + + // if run here, means table name and db name all come from parse result + if (OB_UNLIKELY(s.sm_->client_session_->get_session_info().is_oracle_mode())) { + if (is_table_name_from_parser && OBPROXY_QUOTE_T_INVALID == parse_result.get_table_name_quote()) { + string_to_upper_case(table_name.ptr(), table_name.length()); + } + if (is_database_name_from_parser && OBPROXY_QUOTE_T_INVALID == parse_result.get_database_name_quote()) { + string_to_upper_case(database_name.ptr(), database_name.length()); + } + if (is_package_name_from_parser && OBPROXY_QUOTE_T_INVALID == parse_result.get_package_name_quote()) { + string_to_upper_case(package_name.ptr(), package_name.length()); + } } } } if (OB_SUCC(ret)) { if (IS_CLUSTER_VERSION_LESS_THAN_V4(s.sm_->sm_cluster_resource_->cluster_version_) - && tenant_name == OB_SYS_TENANT_NAME && database_name == OB_SYS_DATABASE_NAME) { + && tenant_name == OB_SYS_TENANT_NAME && database_name == OB_SYS_DATABASE_NAME + && !get_global_proxy_config().enable_qa_mode) { table_name = OB_ALL_DUMMY_TNAME; } } @@ -1550,6 +1887,12 @@ void ObMysqlTransact::handle_congestion_control_lookup(ObTransState &s) "and will expand its retry interval to avoid other connections use this server", KPC(cgt_entry)); cgt_entry->set_alive_failed_at(get_hrtime()); + if (get_global_proxy_config().server_detect_mode != 0) { + if (OB_LIKELY(NULL != s.sm_->sm_cluster_resource_)) { + s.sm_->sm_cluster_resource_->alive_addr_set_.set_refactored(cgt_entry->server_ip_); + } + is_in_alive_congested = true; + } } else { is_in_alive_congested = true; } @@ -1656,8 +1999,7 @@ void ObMysqlTransact::check_safe_read_snapshot(ObTransState &s) ObSafeSnapshotEntry *entry = NULL; const ObProxyPartitionLocation *pl = s.pll_info_.route_.cur_chosen_pl_; ObAddr addr; - addr.set_ipv4_addr(s.server_info_.addr_.get_ip4_host_order(), - static_cast(s.server_info_.addr_.get_port_host_order())); + addr.set_sockaddr(s.server_info_.addr_.sa_); if (OB_ISNULL(pl) || pl->is_server_changed()) { // get the max snapshot server of all server int64_t count = s.sm_->client_session_->dummy_ldc_.count(); @@ -1809,6 +2151,22 @@ void ObMysqlTransact::handle_pl_lookup(ObTransState &s) "addr", s.server_info_.addr_, "attempts", s.current_.attempts_, "sm_id", s.sm_->sm_id_); + } else if (OB_UNLIKELY(is_server_addr_set + && ((OB_NOT_NULL(s.sm_->target_db_server_) && !s.sm_->target_db_server_->is_empty()) + || (OB_NOT_NULL(s.trans_info_.client_request_.get_parse_result().get_target_db_server()) + && !s.trans_info_.client_request_.get_parse_result().get_target_db_server()->is_empty())))) { + if (OB_NOT_NULL(s.sm_->client_session_->dummy_entry_) + && s.sm_->client_session_->dummy_entry_->is_avail_state() + && s.sm_->client_session_->dummy_entry_->is_valid() + && is_addr_logonly(s.server_info_.addr_, s.sm_->client_session_->dummy_entry_->get_tenant_servers())) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("Not allow to route to logonly replica", "choosen server", s.server_info_.addr_, K(ret)); + } + LOG_DEBUG("[ObMysqlTransact::handle_pl_lookup] use target db server and server addr is set, " + "use cached session", + "addr", s.server_info_.addr_, + "attempts", s.current_.attempts_, + "sm_id", s.sm_->sm_id_); } else { const ObProxyReplicaLocation *replica = NULL; #if OB_DETAILED_SLOW_QUERY @@ -1845,7 +2203,7 @@ void ObMysqlTransact::handle_pl_lookup(ObTransState &s) const ObProxyReplicaLocation *replica = pl->get_replica(i); if (NULL != replica && replica->is_leader()) { fill_addr = true; - s.server_info_.set_addr(replica->server_.get_ipv4(), static_cast(replica->server_.get_port())); + s.server_info_.set_addr(ops_ip_sa_cast(replica->server_.get_sockaddr())); LOG_DEBUG("set addr here", K(s.server_info_.addr_)); s.pll_info_.route_.cur_chosen_server_.replica_ = replica; s.pll_info_.route_.leader_item_.is_used_ = true; @@ -1870,7 +2228,7 @@ void ObMysqlTransact::handle_pl_lookup(ObTransState &s) ObSEArray simple_servers_info( ObServerStateRefreshCont::DEFAULT_SERVER_COUNT, *allocator); get_region_name_and_server_info(s, simple_servers_info, region_names); - ObString proxy_primary_zone_name(s.mysql_config_params_->proxy_primary_zone_name_); + ObString proxy_primary_zone_name(s.mysql_config_params_->proxy_primary_zone_name_); if (OB_FAIL(s.pll_info_.route_.fill_replicas( consistency_level, @@ -1927,9 +2285,8 @@ void ObMysqlTransact::handle_pl_lookup(ObTransState &s) ret = OB_ERR_UNEXPECTED; LOG_WARN("no replica avail", K(replica), K(ret)); } else { - s.server_info_.set_addr(replica->server_.get_ipv4(), - static_cast(replica->server_.get_port())); - LOG_DEBUG("set addr here", K(s.server_info_.addr_)); + s.server_info_.set_addr(ops_ip_sa_cast(replica->server_.get_sockaddr())); + LOG_DEBUG("get replica by pl lookup, set addr", K(s.server_info_.addr_)); } if (found_leader_force_congested) { @@ -1981,25 +2338,32 @@ void ObMysqlTransact::handle_server_addr_lookup(ObTransState &s) // server session lookup failed, response err/ok packet LOG_DEBUG("[ObMysqlTransact::handle_server_addr_lookup] server addr lookup " "failed, response err/ok packet", "errcode", query_info->errcode_); + ObMIOBuffer *buf = NULL; + ObMysqlSM *sm = s.sm_; + // consume data in client buffer reader - if (OB_FAIL(s.sm_->get_client_buffer_reader()->consume_all())) { + if (OB_ISNULL(sm)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpect empty sm", K(ret)); + } else if (OB_FAIL(sm->get_client_buffer_reader()->consume_all())) { LOG_WARN("[ObMysqlTransact::handle_server_addr_lookup] fail to consume client_buffer_reader_", K(ret)); } else if (OB_FAIL(s.alloc_internal_buffer(MYSQL_BUFFER_SIZE))) { LOG_WARN("[ObMysqlTransact::handle_server_addr_lookup] fail to allocate internal miobuffer", K(ret)); } else { buf = s.internal_buffer_; uint8_t seq = static_cast(s.trans_info_.client_request_.get_packet_meta().pkt_seq_ + 1); - ObMysqlClientSession *client_session = s.sm_->get_client_session(); + ObMysqlClientSession *client_session = sm->get_client_session(); + ObProxyProtocol client_protocol = sm->get_client_session_protocol(); switch (query_info->errcode_) { case OB_SUCCESS: { - if (OB_ISNULL(s.sm_->client_session_)) { + if (OB_ISNULL(client_session)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("[ObMysqlTransact::handle_server_addr_lookup] client session is NULL, will disconnect", K(ret)); } else { const ObMySQLCapabilityFlags &capability = get_client_session_info(s).get_orig_capability_flags(); - if (OB_FAIL(ObMysqlPacketUtil::encode_ok_packet(*buf, seq, 0, capability))) { + if (ObProxyPacketWriter::write_ok_packet(*buf, *client_session, client_protocol, seq, 0, capability)) { LOG_WARN("[ObMysqlTransact::handle_server_addr_lookup] fail to build ok resp " "packet", K(ret)); } @@ -2011,8 +2375,8 @@ void ObMysqlTransact::handle_server_addr_lookup(ObTransState &s) char *err_msg = NULL; if (OB_FAIL(ObProxyPacketWriter::get_user_err_buf(query_info->errcode_, err_msg, query_info->cs_id_))) { LOG_WARN("fail to get user err buf", K(ret)); - } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, seq, - query_info->errcode_, err_msg))) { + } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, client_protocol, + seq, query_info->errcode_, err_msg))) { LOG_WARN("[ObMysqlTransact::build_error_packet] fail to build not supported err resp", K(ret)); } break; @@ -2021,8 +2385,8 @@ void ObMysqlTransact::handle_server_addr_lookup(ObTransState &s) char *err_msg = NULL; if (OB_FAIL(ObProxyPacketWriter::get_user_err_buf(query_info->errcode_, err_msg, query_info->priv_name_))) { LOG_WARN("fail to get user err buf", K(ret)); - } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, seq, - query_info->errcode_, err_msg))) { + } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, client_protocol, + seq, query_info->errcode_, err_msg))) { LOG_WARN("[ObMysqlTransact::handle_server_addr_lookup] fail to build no privilege err resp packet", K(ret), "priv_name", query_info->priv_name_); } @@ -2032,8 +2396,8 @@ void ObMysqlTransact::handle_server_addr_lookup(ObTransState &s) char *err_msg = NULL; if (OB_FAIL(ObProxyPacketWriter::get_err_buf(query_info->errcode_, err_msg))) { LOG_WARN("fail to get err buf", K(ret)); - } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, seq, - query_info->errcode_, err_msg))) { + } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, client_protocol, + seq, query_info->errcode_, err_msg))) { LOG_WARN("[ObMysqlTransact::build_error_packet] fail to build err resp packet", K(ret)); } break; @@ -2074,7 +2438,7 @@ void ObMysqlTransact::handle_server_addr_lookup(ObTransState &s) inline void ObMysqlTransact::start_access_control(ObTransState &s) { - if (s.need_pl_lookup_) { + if (s.is_need_pl_lookup()) { TRANSACT_RETURN(SM_ACTION_API_OBSERVER_PL, ObMysqlTransact::lookup_skip_open_server); s.sm_->set_skip_plugin(true); } else { @@ -2087,26 +2451,6 @@ inline void ObMysqlTransact::lookup_skip_open_server(ObTransState &s) TRANSACT_RETURN(SM_ACTION_OBSERVER_OPEN, ObMysqlTransact::handle_response); } -inline int ObMysqlTransact::build_user_request( - ObTransState &s, ObIOBufferReader *client_buffer_reader, - ObIOBufferReader *&reader, int64_t &request_len) -{ - int ret = OB_SUCCESS; - - if (s.sm_->client_session_->get_session_info().is_oceanbase_server()) { - if (OB_FAIL(build_oceanbase_user_request(s, client_buffer_reader, reader, request_len))) { - LOG_WARN("fail to build oceanbase user request", K(ret)); - } - } else { - // no need compress, send directly - int64_t client_request_len = s.trans_info_.client_request_.get_packet_len(); - request_len = client_request_len; - reader = client_buffer_reader; - } - - return ret; -} - int ObMysqlTransact::rewrite_stmt_id(ObTransState &s, ObIOBufferReader *client_buffer_reader) { int ret = OB_SUCCESS; @@ -2172,12 +2516,32 @@ int ObMysqlTransact::rewrite_stmt_id(ObTransState &s, ObIOBufferReader *client_b return ret; } +inline int ObMysqlTransact::build_user_request( + ObTransState &s, ObIOBufferReader *client_buffer_reader, + ObIOBufferReader *&reader, int64_t &request_len) +{ + int ret = OB_SUCCESS; + + if (s.sm_->client_session_->get_session_info().is_oceanbase_server()) { + if (OB_FAIL(build_oceanbase_user_request(s, client_buffer_reader, reader, request_len))) { + LOG_WARN("fail to build oceanbase user request", K(ret)); + } + } else { + // no need compress, send directly + int64_t client_request_len = s.trans_info_.client_request_.get_packet_len(); + request_len = client_request_len; + reader = client_buffer_reader; + } + + return ret; +} + inline int ObMysqlTransact::build_oceanbase_user_request( ObTransState &s, ObIOBufferReader *client_buffer_reader, ObIOBufferReader *&reader, int64_t &request_len) { int ret = OB_SUCCESS; - ObProxyProtocol ob_proxy_protocol = s.sm_->get_server_session_protocol(); + ObProxyProtocol server_protocol = s.sm_->get_server_session_protocol(); int64_t client_request_len = s.trans_info_.client_request_.get_packet_len(); // obproxy only send one mysql request packet at once; // if received multi request packets, we will send it one by one; @@ -2197,10 +2561,11 @@ inline int ObMysqlTransact::build_oceanbase_user_request( } else if (OB_FAIL(rewrite_stmt_id(s, client_buffer_reader))) { LOG_WARN("rewrite stmt id failed", K(ret)); } else { + obmysql::ObMySQLCmd req_cmd_type = s.trans_info_.client_request_.get_packet_meta().cmd_; ObIOBufferReader *request_buffer_reader = client_buffer_reader; ObMIOBuffer *write_buffer = NULL; - if (ObProxyProtocol::PROTOCOL_OB20 == ob_proxy_protocol - || ObProxyProtocol::PROTOCOL_CHECKSUM == ob_proxy_protocol) { // convert standard mysql protocol to compression protocol + if (ObProxyProtocol::PROTOCOL_OB20 == server_protocol + || ObProxyProtocol::PROTOCOL_CHECKSUM == server_protocol) { // convert standard mysql protocol to compression protocol uint8_t compress_seq = 0; if (OB_ISNULL(write_buffer = new_miobuffer(MYSQL_BUFFER_SIZE))) { ret = OB_ALLOCATE_MEMORY_FAILED; @@ -2208,18 +2573,46 @@ inline int ObMysqlTransact::build_oceanbase_user_request( } else if (OB_ISNULL(reader = write_buffer->alloc_reader())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("[ObMysqlTransact::build_user_request] failed to allocate iobuffer reader", K(ret)); - } else if ((obmysql::OB_MYSQL_COM_STMT_CLOSE == s.trans_info_.client_request_.get_packet_meta().cmd_ - || obmysql::OB_MYSQL_COM_STMT_RESET == s.trans_info_.client_request_.get_packet_meta().cmd_ + } else if ((obmysql::OB_MYSQL_COM_STMT_CLOSE == req_cmd_type + || obmysql::OB_MYSQL_COM_STMT_RESET == req_cmd_type || s.trans_info_.client_request_.get_parse_result().is_text_ps_drop_stmt()) && OB_ISNULL(request_buffer_reader = client_buffer_reader->clone())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("[ObMysqlTransact::build_user_request] failed to clone client buffer reader", K(ret)); } else { - if (ObProxyProtocol::PROTOCOL_OB20 == ob_proxy_protocol) { + if (ObProxyProtocol::PROTOCOL_OB20 == server_protocol) { if (OB_FAIL(build_oceanbase_ob20_user_request(s, *write_buffer, *request_buffer_reader, client_request_len, compress_seq))) { LOG_WARN("fail to build oceanbase ob20 user request", K(ret), K(client_request_len), K(compress_seq)); - } + } else { + // handle tail crc for other cmd type, close will send to every server, do not clear buf here + if (obmysql::OB_MYSQL_COM_STMT_CLOSE != req_cmd_type + && obmysql::OB_MYSQL_COM_STMT_RESET != req_cmd_type + && !s.trans_info_.client_request_.get_parse_result().is_text_ps_drop_stmt()) { + ObProxyProtocol client_protocol = s.sm_->get_client_session_protocol(); + if (client_protocol == ObProxyProtocol::PROTOCOL_OB20) { + ObClientSessionInfo &cs_info = s.sm_->get_client_session()->get_session_info(); + const bool ob20_req_received_done = cs_info.ob20_request_.ob20_request_received_done_; + const int64_t ob20_req_remain_payload_len = cs_info.ob20_request_.remain_payload_len_; + if (ob20_req_received_done + && ob20_req_remain_payload_len == 0) { + cs_info.ob20_request_.ob20_request_received_done_ = false; + int64_t read_avail = client_buffer_reader->read_avail(); + LOG_DEBUG("after build user ob req, handle ob20 tail crc in buffer", + K(ob20_req_received_done), K(ob20_req_remain_payload_len), K(read_avail)); + if (read_avail >= OB20_PROTOCOL_TAILER_LENGTH) { + if (OB_FAIL(client_buffer_reader->consume(OB20_PROTOCOL_TAILER_LENGTH))) { + LOG_WARN("fail to consume the last crc buffer in client request buffer", K(ret)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected enter here, client-proxy use ob2.0, handled mysql packet in payload done," + " unexpected remain buffer len, expect tail crc 4", K(ret), K(read_avail)); + } + } + } + } + } // else } else { // compress protocol const bool use_fast_compress = true; @@ -2231,8 +2624,8 @@ inline int ObMysqlTransact::build_oceanbase_user_request( } } - if (obmysql::OB_MYSQL_COM_STMT_CLOSE == s.trans_info_.client_request_.get_packet_meta().cmd_ - || obmysql::OB_MYSQL_COM_STMT_RESET == s.trans_info_.client_request_.get_packet_meta().cmd_ + if (obmysql::OB_MYSQL_COM_STMT_CLOSE == req_cmd_type + || obmysql::OB_MYSQL_COM_STMT_RESET == req_cmd_type || s.trans_info_.client_request_.get_parse_result().is_text_ps_drop_stmt()) { request_buffer_reader->dealloc(); request_buffer_reader = NULL; @@ -2241,15 +2634,15 @@ inline int ObMysqlTransact::build_oceanbase_user_request( if (OB_SUCC(ret)) { s.sm_->get_server_session()->set_compressed_seq(compress_seq); request_len = reader->read_avail(); - LOG_DEBUG("build user compressed request succ", K(ob_proxy_protocol), + LOG_DEBUG("build user compressed request succ", K(server_protocol), "origin len", client_request_len, "compress len", request_len, "compress seq", compress_seq); } } } else { // no need compress, send directly request_len = client_request_len; - if (obmysql::OB_MYSQL_COM_STMT_CLOSE == s.trans_info_.client_request_.get_packet_meta().cmd_ - || obmysql::OB_MYSQL_COM_STMT_RESET == s.trans_info_.client_request_.get_packet_meta().cmd_ + if (obmysql::OB_MYSQL_COM_STMT_CLOSE == req_cmd_type + || obmysql::OB_MYSQL_COM_STMT_RESET == req_cmd_type || s.trans_info_.client_request_.get_parse_result().is_text_ps_drop_stmt()) { int64_t written_len = 0; if (OB_ISNULL(write_buffer = new_miobuffer(MYSQL_BUFFER_SIZE))) { @@ -2280,7 +2673,7 @@ inline int ObMysqlTransact::build_oceanbase_user_request( } LOG_DEBUG("[ObMysqlTransact::build_user_request] send request to observer", - "sm_id", s.sm_->sm_id_, K(ob_proxy_protocol), K(client_request_len), + "sm_id", s.sm_->sm_id_, K(server_protocol), K(client_request_len), "total_client_request_len", (reader != NULL) ? reader->read_avail() : 0, "request len send to server", request_len, K(s.trans_info_.request_content_length_), @@ -2306,11 +2699,13 @@ int ObMysqlTransact::build_oceanbase_ob20_user_request(ObTransState &s, ObMIOBuf bool generated_extra_info = false; bool is_last_packet = false; const bool need_reroute = is_need_reroute(s); + const bool is_weak_read = (WEAK == s.sm_->trans_state_.get_trans_consistency_level(s.sm_->get_client_session()->get_session_info())); ObSEArray extra_info; ObSqlString sess_info_value; - char client_ip_buf[MAX_IP_BUFFER_LEN] = "0"; - char server_extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "0"; + char client_ip_buf[MAX_IP_BUFFER_LEN] = "\0"; + char server_extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; ObMysqlServerSession *server_session = s.sm_->get_server_session(); + ObMysqlClientSession *client_session = s.sm_->get_client_session(); uint32_t req_id = server_session->get_next_server_request_id(); while (OB_SUCC(ret) && remain_req_len > 0) { @@ -2335,8 +2730,9 @@ int ObMysqlTransact::build_oceanbase_ob20_user_request(ObTransState &s, ObMIOBuf if (OB_SUCC(ret)) { Ob20ProtocolHeaderParam ob20_head_param(server_session->get_server_sessid(), - req_id, compress_seq, compress_seq, is_last_packet, need_reroute, - server_session->get_session_info().is_new_extra_info_supported()); + req_id, compress_seq, compress_seq, is_last_packet, is_weak_read, need_reroute, + server_session->get_session_info().is_new_extra_info_supported(), + client_session->is_trans_internal_routing()); if (OB_FAIL(ObProto20Utils::consume_and_compress_data(&request_buffer_reader, &write_buffer, curr_req_len, ob20_head_param, &extra_info))) { LOG_WARN("fail to consume and compress ob20 data", K(ret)); @@ -2353,6 +2749,24 @@ int ObMysqlTransact::build_oceanbase_ob20_user_request(ObTransState &s, ObMIOBuf return ret; } +bool ObMysqlTransact::handle_set_trans_internal_routing(ObMysqlTransact::ObTransState &s, bool server_transaction_routing_flag) +{ + // used to set the header flag + // if session in a transaction, return the config of enable_internal_transaction_routing in server + // else return the config enable_internal_transaction_routing + bool internal_routing_flag = false; + if (is_trans_specified(s)) { + // trans_spcified, disable trans internal routing + internal_routing_flag = false; + } else if (!is_in_trans(s)) { + // do nothing, return config of enable_internal_transaction + internal_routing_flag = s.sm_->get_client_session()->is_proxy_enable_trans_internal_routing(); + } else { + internal_routing_flag = s.sm_->get_client_session()->is_proxy_enable_trans_internal_routing() && server_transaction_routing_flag; + } + return internal_routing_flag; +} + inline int ObMysqlTransact::build_normal_login_request( ObTransState &s, ObIOBufferReader *&reader, int64_t &request_len) { @@ -2429,6 +2843,9 @@ inline int ObMysqlTransact::build_normal_login_request( int ObMysqlTransact::build_server_request(ObTransState &s, ObIOBufferReader *&reader, int64_t &request_len) { int ret = OB_SUCCESS; + LOG_DEBUG("[ObMysqlTransact::build_server_request] checking sending sql", + "cur_send_action", ObMysqlTransact::get_send_action_name(s.current_.send_action_), K(s.trans_info_.get_print_sql()), K(is_in_trans(s)), + K(s.sm_->get_client_session()->get_cs_id())); ObIOBufferReader *client_buffer_reader = NULL; BuildFunc build_func = NULL; reader = NULL; @@ -2476,7 +2893,9 @@ int ObMysqlTransact::build_server_request(ObTransState &s, ObIOBufferReader *&re } case SERVER_SEND_SAVED_LOGIN: - if (s.sm_->client_session_->get_session_info().is_oceanbase_server()) { + if (is_binlog_request(s)) { + build_func = ObMysqlRequestBuilder::build_binlog_login_packet; + } else if (s.sm_->client_session_->get_session_info().is_oceanbase_server()) { // write the buffor using saved login packet directly build_func = ObMysqlRequestBuilder::build_saved_login_packet; } else { @@ -2497,14 +2916,18 @@ int ObMysqlTransact::build_server_request(ObTransState &s, ObIOBufferReader *&re case SERVER_SEND_SESSION_VARS: build_func = ObMysqlRequestBuilder::build_session_vars_sync_packet; break; - - case SERVER_SEND_LAST_INSERT_ID: - build_func = ObMysqlRequestBuilder::build_last_insert_id_sync_packet; + + case SERVER_SEND_SESSION_USER_VARS: + build_func = ObMysqlRequestBuilder::build_session_user_vars_sync_packet; break; case SERVER_SEND_START_TRANS: build_func = ObMysqlRequestBuilder::build_start_trans_request; break; + + case SERVER_SEND_XA_START: + build_func = ObMysqlRequestBuilder::build_xa_start_request; + break; case SERVER_SEND_PREPARE: build_func = ObMysqlRequestBuilder::build_prepare_request; @@ -2658,7 +3081,7 @@ inline int ObMysqlTransact::do_handle_prepare_succ(ObTransState &s, uint32_t ser ObClientSessionInfo &cs_info = get_client_session_info(s); ObServerSessionInfo &ss_info = get_server_session_info(s); - uint32_t client_ps_id = cs_info.get_client_ps_id(); + uint32_t client_ps_id = s.is_hold_xa_start_? cs_info.get_xa_start_ps_id() : cs_info.get_client_ps_id(); ObPsIdPair *ps_id_pair = ss_info.get_ps_id_pair(client_ps_id); /* here two case: * if first in: @@ -2747,7 +3170,7 @@ inline int ObMysqlTransact::do_handle_execute_succ(ObTransState &s) ObClientSessionInfo &cs_info = get_client_session_info(s); ObServerSessionInfo &ss_info = get_server_session_info(s); - uint32_t client_ps_id = cs_info.get_client_ps_id(); + uint32_t client_ps_id = s.is_hold_xa_start_? cs_info.get_xa_start_ps_id() : cs_info.get_client_ps_id(); ObPsIdPair *ps_id_pair = ss_info.get_ps_id_pair(client_ps_id); ObCursorIdPair *cursor_id_pair = ss_info.get_curosr_id_pair(client_ps_id); if (OB_ISNULL(ps_id_pair)) { @@ -2797,6 +3220,79 @@ inline int ObMysqlTransact::do_handle_execute_succ(ObTransState &s) return ret; } +inline int ObMysqlTransact::do_handle_prepare_execute_xa_succ(ObIOBufferReader &buf_reader) { + int ret = OB_SUCCESS; + int64_t offset = 0; + int64_t content_len = 0; + uint8_t seq = 0; + ObMysqlPacketReader pkt_reader; + ObNewRow row; + ObSMRow sm_row(BINARY, row); + OMPKRow row_pkt(sm_row); + OMPKPrepareExecute prepare_execute_pkt; + int32_t eof_count_before_result_set = 0; + // read prepare execute resp + if (OB_FAIL(pkt_reader.get_packet(buf_reader, prepare_execute_pkt))) { + LOG_WARN("fail to get prepare execute resp of xa start", K(ret)); + } else if (prepare_execute_pkt.get_column_num() > 0 && FALSE_IT(++eof_count_before_result_set)) { + } else if (prepare_execute_pkt.get_param_num() > 0 && FALSE_IT(++eof_count_before_result_set)) { + } else { + LOG_DEBUG("succ to get eof count of resp of xa start sync", K(eof_count_before_result_set)); + } + + int32_t eof_count = 0; + // num-param * coldef & eof & one row coldef & eof + while (OB_SUCC(ret) && eof_count < eof_count_before_result_set) { + bool is_eof = false; + if (OB_FAIL(pkt_reader.is_eof_packet(buf_reader, offset, is_eof))) { + LOG_WARN("fail test eof of resp of xa start sync", K(ret)); + } else if (OB_FAIL(pkt_reader.get_content_len_and_seq(buf_reader, offset, content_len, seq))) { + LOG_WARN("fail to read packet len and seq of resp of xa start sync", K(ret)); + } else { + offset += content_len + MYSQL_NET_HEADER_LENGTH; + } + if (is_eof) { + ++eof_count; + LOG_DEBUG("succ to read eof of resp of xa start sync", K(eof_count)); + } + } + + // read ProtocolBinary::ResultsetRow + if (OB_SUCC(ret)) { + if (OB_FAIL(pkt_reader.get_packet(buf_reader, offset, row_pkt))) { + LOG_WARN("fail to get result set row packet of resp of xa start sync", K(ret)); + } else { + // 0a 00 00 08 00 00 00 00 00 00 00 00 00 00 + // ^^^^^^^^^^^ header + // ^^ packet header + // ^^ bitmap + // ^^^^^^^^^^^^^^^^^^^^^^^ long/int(8/4bytes) + const char *content_buf = row_pkt.get_cdata(); + int64_t content_len = row_pkt.get_clen(); + int8_t pkt_hdr = -1; + int8_t bitmap = -1; + int32_t xa_result = -1; + if (OB_FAIL(ObMysqlPacketUtil::get_int1(content_buf, content_len, pkt_hdr))) { + LOG_WARN("fail to get pkt hdr from row packet of resp of xa start sync", K(ret)); + } else if (OB_FAIL(ObMysqlPacketUtil::get_int1(content_buf, content_len, bitmap))) { + LOG_WARN("fail to get bitmap from row packet of resp of xa start sync", K(ret)); + } else if (OB_UNLIKELY(pkt_hdr != 0x00)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("wrong result set row pkt hdr of resp of xa start sync", K(ret), K(pkt_hdr)); + } else if (OB_FAIL(ObMysqlPacketUtil::get_int4(content_buf, content_len, xa_result))) { + LOG_WARN("fail to get xa result of resp of xa start sync", K(ret)); + } else if (OB_UNLIKELY(xa_result != 0)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to sync xa start", K(xa_result), K(ret)); + } else { + LOG_DEBUG("succ to sync xa start"); + } + } + } + + return ret; +} + inline void ObMysqlTransact::handle_execute_succ(ObTransState &s) { int ret = OB_SUCCESS; @@ -2842,11 +3338,12 @@ inline void ObMysqlTransact::handle_prepare_execute_succ(ObTransState &s) } else if (OB_FAIL(do_handle_prepare_succ(s, server_ps_id))) { LOG_WARN("fail to do handle prepare succ", K(ret)); } - if (OB_SUCC(ret) && s.trans_info_.server_response_.get_analyze_result().is_resultset_resp()) { if (OB_FAIL(do_handle_execute_succ(s))) { LOG_WARN("fail to do handle execute succ", K(ret)); - } + } else if (s.is_hold_xa_start_ && OB_FAIL(do_handle_prepare_execute_xa_succ(*buf_reader))) { + LOG_WARN("fail to do handle prepare execute xa succ", K(ret)); + } else {} } } @@ -2915,6 +3412,7 @@ int ObMysqlTransact::handle_text_ps_drop_succ(ObTransState &s, bool &is_user_req int ret = OB_SUCCESS; is_user_request = false; + // text_ps_drop can not handle session info in trim_ok_packet, handle here ObClientSessionInfo &cs_info = get_client_session_info(s); ObServerSessionInfo &ss_info = get_server_session_info(s); uint32_t ps_id = cs_info.get_client_ps_id(); @@ -2923,8 +3421,14 @@ int ObMysqlTransact::handle_text_ps_drop_succ(ObTransState &s, bool &is_user_req LOG_WARN("fail to erase server addr", K(ret)); } else if (OB_FAIL(ss_info.remove_text_ps_version(ps_id))) { LOG_WARN("fail to remove text ps id", K(ret)); + } else if (OB_FAIL(ObProxySessionInfoHandler::save_changed_sess_info(s.sm_->get_client_session()->get_session_info(), + s.sm_->get_server_session()->get_session_info(), + s.trans_info_.server_response_.get_analyze_result().get_extra_info(), + s.trace_log_, + false))) { + LOG_WARN("fail to save changed session info", K(get_send_action_name(s.current_.send_action_))); + s.current_.state_ = INTERNAL_ERROR; } - return ret; } @@ -3060,7 +3564,7 @@ int ObMysqlTransact::handle_reset_connection_request_succ(ObTransState &s) int ObMysqlTransact::clear_session_related_source(ObTransState &s) { int ret = OB_SUCCESS; - + ObClientSessionInfo &client_info = get_client_session_info(s); ObServerSessionInfo &server_info = get_server_session_info(s); @@ -3086,7 +3590,7 @@ int ObMysqlTransact::clear_session_related_source(ObTransState &s) if (OB_NOT_NULL(client_session)) { client_session->get_session_manager().purge_keepalives(); } - + LOG_DEBUG("succ to clear session related source"); } @@ -3103,46 +3607,45 @@ inline int ObMysqlTransact::handle_user_set_request_succ(ObTransState &s) ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid session, client session is NULL"); } else if (OB_LIKELY(set_info.node_count_ > 0)) { - ObClientSessionInfo &client_info = get_client_session_info(s); for (int i = 0; OB_SUCC(ret) && i < set_info.node_count_; i++) { - SetVarNode &var_node = set_info.var_nodes_.at(i); + SetVarNode* var_node = set_info.var_nodes_.at(i); ObObj value; - if (SET_VALUE_TYPE_INT == var_node.value_type_) { - value.set_int(var_node.int_value_); - } else if (SET_VALUE_TYPE_NUMBER == var_node.value_type_) { - const char *nptr = var_node.str_value_.buf_; + if (SET_VALUE_TYPE_INT == var_node->value_type_) { + value.set_int(var_node->int_value_); + } else if (SET_VALUE_TYPE_NUMBER == var_node->value_type_) { + const char *nptr = var_node->str_value_.ptr(); char *end_ptr = NULL; double double_val = strtod(nptr, &end_ptr); if (*nptr != '\0' && *end_ptr == '\0') { value.set_double(double_val); } else { - OBLOG_LOG(WARN, "invalid double value", "str", var_node.str_value_.string_); - value.set_varchar(var_node.str_value_.string_); + OBLOG_LOG(WARN, "invalid double value", "str", var_node->str_value_); + value.set_varchar(var_node->str_value_.config_string_); } } else { - if (0 == var_node.var_name_.string_.case_compare("character_set_results") - && 0 == var_node.str_value_.string_.case_compare("NULL")) { + if (0 == var_node->var_name_.config_string_.case_compare("character_set_results") + && 0 == var_node->str_value_.config_string_.case_compare("NULL")) { value.set_varchar(ObString::make_empty_string()); } else { - value.set_varchar(var_node.str_value_.string_); + value.set_varchar(var_node->str_value_.config_string_); } } // TODO: if not exist, insert; otherwise, cmp and update - if (SET_VAR_USER == var_node.var_type_) { - if (OB_FAIL(client_info.replace_user_variable(var_node.var_name_.string_, + if (SET_VAR_USER == var_node->var_type_) { + if (OB_FAIL(client_info.replace_user_variable(var_node->var_name_.config_string_, value))) { - LOG_WARN("fail to replace user variable", K(var_node), K(ret)); + LOG_WARN("fail to replace user variable", KPC(var_node), K(ret)); } else { - LOG_DEBUG("succ to update user variables", "key", var_node.var_name_.string_, K(value)); + LOG_DEBUG("succ to update user variables", "key", var_node->var_name_, K(value)); } - } else if (SET_VAR_SYS == var_node.var_type_) { - if (OB_FAIL(client_info.update_common_sys_variable(var_node.var_name_.string_, + } else if (SET_VAR_SYS == var_node->var_type_) { + if (OB_FAIL(client_info.update_common_sys_variable(var_node->var_name_.config_string_, value, true, false))) { - LOG_WARN("fail to update common sys variable", K(var_node), K(ret)); + LOG_WARN("fail to update common sys variable", KPC(var_node), K(ret)); } else { - LOG_DEBUG("succ to update common sys variables", "key", var_node.var_name_.string_, K(value)); + LOG_DEBUG("succ to update common sys variables", "key", var_node->var_name_.config_string_, K(value)); } } } @@ -3298,15 +3801,21 @@ inline void ObMysqlTransact::handle_use_db_succ(ObTransState &s) } } -void ObMysqlTransact::handle_error_resp(ObTransState &s) +void ObMysqlTransact::handle_error_resp(ObTransState &s, bool &is_user_request) { ObRespAnalyzeResult &resp = s.trans_info_.server_response_.get_analyze_result(); ObProxyMysqlRequest& client_request = s.trans_info_.client_request_; - bool is_user_request = false; + is_user_request = false; int64_t max_connect_attempts = get_max_connect_attempts(s); ObServerStateType pre_state = s.current_.state_; s.current_.state_ = RESPONSE_ERROR; + s.trace_log_.log_it("[get_error]", "code", resp.error_pkt_.get_err_code(), "trace_id", resp.server_trace_id_); + if (resp.is_mysql_wrong_arguments_error() + || resp.is_trans_free_route_not_supported_error() + || resp.is_internal_error()) { + LOG_WARN("trace_log", K(s.trace_log_)); + } switch(s.current_.send_action_) { case SERVER_SEND_HANDSHAKE: if (!s.sm_->client_session_->get_session_info().is_oceanbase_server()) { @@ -3445,6 +3954,8 @@ void ObMysqlTransact::handle_error_resp(ObTransState &s) } else { is_user_request = true; } + } else if (resp.is_trans_free_route_not_supported_error()) { + s.current_.error_type_ = TRANS_FREE_ROUTE_NOT_SUPPORTED_ERROR; } else if (resp.is_ora_fatal_error()) { s.current_.error_type_ = ORA_FATAL_ERROR; } else if (resp.is_standby_weak_readonly_error() @@ -3452,9 +3963,10 @@ void ObMysqlTransact::handle_error_resp(ObTransState &s) && OB_DEFAULT_CLUSTER_ID == s.sm_->sm_cluster_resource_->get_cluster_id()) { // if primary switchover, need disconnection when get STANDBY_WEAK_READONLY_ERROR error s.current_.error_type_ = STANDBY_WEAK_READONLY_ERROR; - } else if (s.is_trans_first_request_ - && !s.trans_info_.client_request_.is_large_request() - && (total_request_packet_len == cached_request_packet_len)) { + } else if ((s.is_trans_first_request_ + || (ObMysqlTransact::is_in_trans(s) && s.sm_->get_client_session()->is_trans_internal_routing())) + && !s.trans_info_.client_request_.is_large_request() + && (total_request_packet_len == cached_request_packet_len)) { if (resp.is_reroute_error()) { s.current_.error_type_ = REQUEST_REROUTE_ERROR; // if all attempts were failed, we should transfer the error pkt to client finally @@ -3497,7 +4009,7 @@ void ObMysqlTransact::handle_error_resp(ObTransState &s) } case SERVER_SEND_ALL_SESSION_VARS: case SERVER_SEND_SESSION_VARS: - case SERVER_SEND_LAST_INSERT_ID: + case SERVER_SEND_SESSION_USER_VARS: s.current_.error_type_ = RESET_SESSION_VARS_COMMON_ERROR; break; @@ -3508,6 +4020,11 @@ void ObMysqlTransact::handle_error_resp(ObTransState &s) case SERVER_SEND_START_TRANS: s.current_.error_type_ = START_TRANS_COMMON_ERROR; break; + + case SERVER_SEND_XA_START: + LOG_DEBUG("[ObMysqlTransact::handle_error_resp] xa start resp error"); + s.current_.error_type_ = START_XA_START_ERROR; + break; case SERVER_SEND_PREPARE: s.current_.error_type_ = SYNC_PREPARE_COMMON_ERROR; @@ -3595,6 +4112,8 @@ void ObMysqlTransact::handle_error_resp(ObTransState &s) } s.is_rerouted_ = true; } + } else if (TRANS_FREE_ROUTE_NOT_SUPPORTED_ERROR == s.current_.error_type_) { + s.is_rerouted_ = true; } @@ -3635,7 +4154,7 @@ void ObMysqlTransact::handle_error_resp(ObTransState &s) } } -inline void ObMysqlTransact::handle_resultset_resp(ObTransState &s) +inline void ObMysqlTransact::handle_resultset_resp(ObTransState &s, bool &is_user_request) { if (OB_UNLIKELY(obmysql::OB_MYSQL_COM_STMT_PREPARE == s.trans_info_.sql_cmd_ || SERVER_SEND_PREPARE == s.current_.send_action_)) { @@ -3647,17 +4166,27 @@ inline void ObMysqlTransact::handle_resultset_resp(ObTransState &s) } // consume response of non-user request + if (OB_UNLIKELY(SERVER_SEND_XA_START == s.current_.send_action_)) { + if (s.sm_->get_client_session()->is_proxy_enable_trans_internal_routing()) { + record_trans_state(s, true); + } + LOG_DEBUG("[ObMysqlTransact::handle_resultset_resp] reset xa start flag s.is_hold_xa_start_"); + s.is_hold_xa_start_ = false; + } if (OB_UNLIKELY(SERVER_SEND_REQUEST != s.current_.send_action_)) { //LOG_WARN("handle_resultset_resp, not expected"); consume_response_packet(s); + is_user_request = false; + } else { + is_user_request = true; } } -inline void ObMysqlTransact::handle_ok_resp(ObTransState &s) +inline void ObMysqlTransact::handle_ok_resp(ObTransState &s, bool &is_user_request) { int ret = OB_SUCCESS; // in fact, we handle ok, eof, resultset and other responses in this function - bool is_user_request = false; + is_user_request = false; if (NULL != s.sm_->client_session_ && NULL != s.sm_->get_server_session()) { ObClientSessionInfo &client_info = get_client_session_info(s); @@ -3677,6 +4206,7 @@ inline void ObMysqlTransact::handle_ok_resp(ObTransState &s) case SERVER_SEND_ALL_SESSION_VARS: case SERVER_SEND_SESSION_VARS: + case SERVER_SEND_SESSION_USER_VARS: ObProxySessionInfoHandler::assign_session_vars_version(client_info, server_info); // send session var function will send last_insert_id in passing ObProxySessionInfoHandler::assign_last_insert_id_version(client_info, server_info); @@ -3688,12 +4218,9 @@ inline void ObMysqlTransact::handle_ok_resp(ObTransState &s) handle_use_db_succ(s); break; - case SERVER_SEND_LAST_INSERT_ID: - ObProxySessionInfoHandler::assign_last_insert_id_version(client_info, server_info); - break; - case SERVER_SEND_START_TRANS: // reset hold start trans flag if receive ok packet + LOG_DEBUG("sync session info from the ok packet of the sql `begin`"); s.is_hold_start_trans_ = false; break; @@ -3711,28 +4238,35 @@ inline void ObMysqlTransact::handle_ok_resp(ObTransState &s) K(client_info), K(server_info)); break; } + + // due to server may retrun reroute error in internal routing trans + // internal routing trans allow to record transaction state after begin statement + if (s.current_.send_action_ == SERVER_SEND_START_TRANS && s.sm_->get_client_session()->is_proxy_enable_trans_internal_routing()) { + record_trans_state(s, true); + } } - if (obmysql::OB_MYSQL_COM_STMT_SEND_PIECE_DATA == s.trans_info_.sql_cmd_) { - ObPieceInfo *info = NULL; - ObClientSessionInfo &cs_info = get_client_session_info(s); - if (OB_FAIL(cs_info.get_piece_info(info))) { - if (OB_HASH_NOT_EXIST == ret) { - if (OB_ISNULL(info = op_alloc(ObPieceInfo))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - PROXY_API_LOG(ERROR, "fail to allocate memory for piece info", K(ret)); - } else { - info->set_ps_id(cs_info.get_client_ps_id()); - info->set_addr(s.sm_->get_server_session()->get_netvc()->get_remote_addr()); - if (OB_FAIL(cs_info.add_piece_info(info))) { - PROXY_API_LOG(WARN, "fail to add piece info", K(ret)); - op_free(info); - info = NULL; + if (OB_SUCC(ret)) { + if (obmysql::OB_MYSQL_COM_STMT_SEND_PIECE_DATA == s.trans_info_.sql_cmd_) { + ObPieceInfo *info = NULL; + ObClientSessionInfo &cs_info = get_client_session_info(s); + if (OB_FAIL(cs_info.get_piece_info(info))) { + if (OB_HASH_NOT_EXIST == ret) { + if (OB_ISNULL(info = op_alloc(ObPieceInfo))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + PROXY_API_LOG(ERROR, "fail to allocate memory for piece info", K(ret)); + } else { + info->set_ps_id(cs_info.get_client_ps_id()); + info->set_addr(s.sm_->get_server_session()->get_netvc()->get_remote_addr()); + if (OB_FAIL(cs_info.add_piece_info(info))) { + PROXY_API_LOG(WARN, "fail to add piece info", K(ret)); + op_free(info); + info = NULL; + } } } } } - if (OB_FAIL(ret)) { s.current_.state_ = INTERNAL_ERROR; LOG_WARN("add piece info failed", K(ret)); @@ -3755,57 +4289,70 @@ inline void ObMysqlTransact::handle_handshake_pkt(ObTransState &s) if (OB_LIKELY(NULL != client_session) && OB_LIKELY(SERVER_SEND_HANDSHAKE == s.current_.send_action_) && OB_LIKELY(NULL != server_session)) { - ObRespAnalyzeResult &result = s.trans_info_.server_response_.get_analyze_result(); - - uint32_t conn_id = 0; - //use connection id from OMPKHandshakeResponse Packet when the follow happened - //1. proxy_mysql_client - //2. client service mode - //3. mysql routing mode - if (client_session->is_proxy_mysql_client_ - || OB_CLIENT_SERVICE_MODE == s.mysql_config_params_->proxy_service_mode_ - || s.mysql_config_params_->is_mysql_routing_mode()) { - conn_id = result.get_connection_id(); - } else { - //if use server service mode, connection id is equal to cs_id - conn_id = client_session->get_cs_id(); - } - server_session->set_server_sessid(conn_id); - ObMySQLCapabilityFlags capability(result.get_server_capability()); - server_session->get_session_info().save_compatible_capability_flags(capability); - ObAddr client_addr = client_session->get_real_client_addr(const_cast(server_session->get_netvc())); - - //we need update proxy_sessid when first connect server - if (0 == client_session->get_proxy_sessid()) { - client_session->set_proxy_sessid(ObMysqlClientSession::get_next_proxy_sessid()); - LOG_INFO("succ to set proxy_sessid", "cs_id", client_session->get_cs_id(), - "proxy_sessid", client_session->get_proxy_sessid(), - "server_ip", server_session->server_ip_, - "ss_id", server_session->ss_id_, - "server_sessid", conn_id, - "is_proxy_mysql_client", client_session->is_proxy_mysql_client_, - "ss_fd", server_session->get_netvc()->get_conn_fd(), - K(client_addr)); - } - LOG_DEBUG("succ to fill conn id for server session", K(conn_id), - "ss_id", server_session->ss_id_, - "cs_id", client_session->get_cs_id(), - "proxy_sessid", client_session->get_proxy_sessid(), - "is_proxy_mysql_client", client_session->is_proxy_mysql_client_, - K(client_addr)); - - if (s.mysql_config_params_->enable_client_ip_checkout_) { - if (OB_UNLIKELY(!client_addr.is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("real client add is invalid, it should not happened", K(client_addr), K(ret)); + // for probing SQL + if (client_session->get_session_info().get_priv_info().user_name_ == ObProxyTableInfo::DETECT_USERNAME_USER) { + // Simulate the return of ERROR messages + LOG_DEBUG("get handshake from detect server success"); + s.mysql_errcode_ = OB_NOT_SUPPORTED; + s.mysql_errmsg_ = "not supported, bad route request"; + if (OB_FAIL(ObMysqlTransact::build_error_packet(s, client_session))) { + LOG_WARN("fail to encode err packet buf", K(ret)); } + ret = OB_NOT_SUPPORTED; } else { - client_addr.reset(); - } - if (OB_SUCC(ret)) { - if (s.sm_->client_session_->get_session_info().is_oceanbase_server()) { - if (OB_FAIL(handle_oceanbase_handshake_pkt(s, conn_id, client_addr))) { - LOG_WARN("fail to handle oceanbase handshke pkt", K(conn_id), K(client_addr), K(ret)); + ObRespAnalyzeResult &result = s.trans_info_.server_response_.get_analyze_result(); + + uint32_t conn_id = 0; + //use connection id from OMPKHandshakeResponse Packet when the follow happened + //1. proxy_mysql_client + //2. client service mode + //3. mysql routing mode + if (client_session->is_proxy_mysql_client_ + || OB_CLIENT_SERVICE_MODE == s.mysql_config_params_->proxy_service_mode_ + || s.mysql_config_params_->is_mysql_routing_mode()) { + conn_id = result.get_connection_id(); + } else { + //if use server service mode, connection id is equal to cs_id + conn_id = client_session->get_cs_id(); + } + server_session->set_server_sessid(conn_id); + ObMySQLCapabilityFlags capability(result.get_server_capability()); + server_session->get_session_info().save_compatible_capability_flags(capability); + ObAddr client_addr = client_session->get_real_client_addr(const_cast(server_session->get_netvc())); + + //we need update proxy_sessid when first connect server + if (0 == client_session->get_proxy_sessid()) { + client_session->set_proxy_sessid(ObMysqlClientSession::get_next_proxy_sessid()); + LOG_INFO("succ to set proxy_sessid", "cs_id", client_session->get_cs_id(), + "proxy_sessid", client_session->get_proxy_sessid(), + "server_ip", server_session->server_ip_, + "ss_id", server_session->ss_id_, + "server_sessid", conn_id, + "is_proxy_mysql_client", client_session->is_proxy_mysql_client_, + "ss_fd", server_session->get_netvc()->get_conn_fd(), + K(client_addr)); + } + LOG_DEBUG("succ to fill conn id for server session", K(conn_id), + "ss_id", server_session->ss_id_, + "cs_id", client_session->get_cs_id(), + "proxy_sessid", client_session->get_proxy_sessid(), + "is_proxy_mysql_client", client_session->is_proxy_mysql_client_, + K(client_addr)); + s.trace_log_.log_it("[handshake]", "svr", s.server_info_.addr_, "svr_sessid", server_session->get_server_sessid()); + + if (s.mysql_config_params_->enable_client_ip_checkout_) { + if (OB_UNLIKELY(!client_addr.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("real client add is invalid, it should not happened", K(client_addr), K(ret)); + } + } else { + client_addr.reset(); + } + if (OB_SUCC(ret)) { + if (s.sm_->client_session_->get_session_info().is_oceanbase_server()) { + if (OB_FAIL(handle_oceanbase_handshake_pkt(s, conn_id, client_addr))) { + LOG_WARN("fail to handle oceanbase handshke pkt", K(conn_id), K(client_addr), K(ret)); + } } } } @@ -3825,7 +4372,7 @@ inline int ObMysqlTransact::handle_oceanbase_handshake_pkt(ObTransState &s, uint // current proxy support use compress, and inner request also use compress bool use_compress = s.mysql_config_params_->enable_compression_protocol_; - bool use_ob_protocol_v2 = s.mysql_config_params_->enable_ob_protocol_v2_; + bool use_ob_protocol_v2 = s.sm_->is_enable_ob_protocol_v2(); bool use_ssl = s.sm_->enable_server_ssl_ && !s.sm_->client_session_->is_proxy_mysql_client_ && s.trans_info_.server_response_.get_analyze_result().support_ssl() @@ -3950,24 +4497,39 @@ void ObMysqlTransact::handle_db_reset(ObTransState &s) inline void ObMysqlTransact::handle_first_response_packet(ObTransState &s) { ObRespAnalyzeResult &resp = s.trans_info_.server_response_.get_analyze_result(); - + bool is_user_request = false; // handle resp if (resp.is_resultset_resp()) { MYSQL_INCREMENT_TRANS_STAT(SERVER_RESULTSET_RESPONSES); - handle_resultset_resp(s); + handle_resultset_resp(s, is_user_request); } else if (resp.is_ok_resp()) { MYSQL_INCREMENT_TRANS_STAT(SERVER_OK_RESPONSES); - handle_ok_resp(s); + handle_ok_resp(s, is_user_request); } else if (resp.is_error_resp()) { MYSQL_INCREMENT_TRANS_STAT(SERVER_ERROR_RESPONSES); - handle_error_resp(s); + handle_error_resp(s, is_user_request); } else if (resp.is_handshake_pkt()) { MYSQL_INCREMENT_TRANS_STAT(SERVER_OTHER_RESPONSES); handle_handshake_pkt(s); } else { MYSQL_INCREMENT_TRANS_STAT(SERVER_OTHER_RESPONSES); - handle_ok_resp(s); + handle_ok_resp(s, is_user_request); } + + if (s.current_.send_action_ != SERVER_SEND_SAVED_LOGIN + && s.current_.send_action_ != SERVER_SEND_HANDSHAKE + && !is_user_request) { + bool is_only_sync_trans_sess = resp.is_error_resp(); + if (OB_SUCCESS != ObProxySessionInfoHandler::save_changed_sess_info(s.sm_->get_client_session()->get_session_info(), + s.sm_->get_server_session()->get_session_info(), + resp.get_extra_info(), + s.trace_log_, + is_only_sync_trans_sess)) { + s.current_.state_ = INTERNAL_ERROR; + LOG_WARN("fail to save changed session info", K(get_send_action_name(s.current_.send_action_))); + } + } + } inline ObServerSessionInfo &ObMysqlTransact::get_server_session_info(ObTransState &s) @@ -4072,7 +4634,7 @@ inline void ObMysqlTransact::update_trace_stat(ObTransState &s) trace_record->server_state_ = static_cast(s.current_.state_); trace_record->send_action_ = static_cast(s.current_.send_action_); trace_record->resp_error_ = static_cast(s.current_.error_type_); - trace_record->addr_.set_ipv4_addr(s.server_info_.get_ipv4(), s.server_info_.get_port()); + trace_record->addr_.set_sockaddr(s.server_info_.addr_.sa_); if (0 == trace_stats->last_trace_end_time_) { trace_record->cost_time_us_ = static_cast(hrtime_to_usec( milestone_diff(s.sm_->milestones_.pl_lookup_begin_, get_based_hrtime(s)))); @@ -4098,16 +4660,18 @@ void ObMysqlTransact::handle_oceanbase_server_resp_error(ObTransState &s, ObMySQ case REQUEST_CONNECT_ERROR: case REQUEST_SERVER_INIT_ERROR: case REQUEST_REROUTE_ERROR: - case REQUEST_SERVER_STOPPING_ERROR: { - // before retry send request, write the saved packet to client buffer - ObString req_pkt = s.trans_info_.client_request_.get_req_pkt(); - int64_t pkt_len = req_pkt.length(); + case REQUEST_SERVER_STOPPING_ERROR: + case TRANS_FREE_ROUTE_NOT_SUPPORTED_ERROR: { + // before retry send request, write the req packet back to client buffer ObIOBufferReader *client_reader = s.sm_->get_client_buffer_reader(); - int64_t written_len = 0; if (OB_ISNULL(client_reader)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("[ObMysqlTransact::handle_server_resp_error] client reader is NULL"); } else { + // rewrite request to client buffer in order to retry + ObString req_pkt = s.trans_info_.client_request_.get_req_pkt(); + int64_t pkt_len = req_pkt.length(); + int64_t written_len = 0; if (0 != client_reader->read_avail() || req_pkt.empty()) { ret = OB_INNER_STAT_ERROR; LOG_ERROR("[ObMysqlTransact::handle_server_resp_error] invalid internal state", @@ -4152,6 +4716,7 @@ void ObMysqlTransact::handle_oceanbase_server_resp_error(ObTransState &s, ObMySQ case SAVED_LOGIN_COMMON_ERROR: case RESET_SESSION_VARS_COMMON_ERROR: case START_TRANS_COMMON_ERROR: + case START_XA_START_ERROR: case SYNC_DATABASE_COMMON_ERROR: { //current server session is still ok s.sm_->clear_server_entry(); @@ -4285,7 +4850,7 @@ inline void ObMysqlTransact::handle_response_from_server(ObTransState &s) "request_cmd", get_mysql_cmd_str(s.trans_info_.client_request_.get_packet_meta().cmd_), "sql_cmd", get_mysql_cmd_str(s.trans_info_.sql_cmd_), "sql", s.trans_info_.get_print_sql()); - } else { + } else if (s.need_retry_) { LOG_WARN("connection error", "server_state", ObMysqlTransact::get_server_state_name(s.current_.state_), "request_cmd", get_mysql_cmd_str(s.trans_info_.client_request_.get_packet_meta().cmd_), @@ -4314,13 +4879,16 @@ void ObMysqlTransact::handle_oceanbase_retry_server_connection(ObTransState &s) ObPieceInfo *info = NULL; ObSSRetryStatus retry_status = NO_NEED_RETRY; const int64_t max_connect_attempts = get_max_connect_attempts(s); + bool is_reroute_to_coordinator = false; ObIpEndpoint old_target_server; net::ops_ip_copy(old_target_server, s.server_info_.addr_.sa_); int64_t obproxy_route_addr = 0; + bool is_internal_routing = false; if (NULL != s.sm_ && NULL != s.sm_->client_session_) { obproxy_route_addr = s.sm_->client_session_->get_session_info().get_obproxy_route_addr(); + is_internal_routing = s.sm_->client_session_->is_trans_internal_routing(); } if (OB_FAIL(s.sm_->get_client_session()->get_session_info().get_piece_info(info))) { @@ -4332,14 +4900,20 @@ void ObMysqlTransact::handle_oceanbase_retry_server_connection(ObTransState &s) if (OB_UNLIKELY(s.mysql_config_params_->is_mysql_routing_mode())) { LOG_DEBUG("in mysql mode, no need retry, will disconnect"); retry_status = NO_NEED_RETRY; + } else if (OB_UNLIKELY(is_in_trans(s) + && s.sm_->get_client_session()->is_proxy_enable_trans_internal_routing() + && !s.sm_->get_client_session()->get_trans_coordinator_ss_addr().is_valid())) { + // check coordinator addr in transaction + LOG_WARN("coordinator add is invalid in transaction, no need retry"); + retry_status = NO_NEED_RETRY; + // we will update retry_status only the follow all happened - // 1. not in transaction + // 1. not in transaction / in internal routing tranaction // 2. attempts_ is less then max_connect_attempts // 3. is not kill query // 4. is not piece info - } else if (!is_in_trans(s) - && s.need_retry_ + } else if (s.need_retry_ && s.current_.attempts_ < max_connect_attempts && 0 == obproxy_route_addr && !s.trans_info_.client_request_.is_kill_query() @@ -4347,17 +4921,30 @@ void ObMysqlTransact::handle_oceanbase_retry_server_connection(ObTransState &s) && obmysql::OB_MYSQL_COM_STMT_GET_PIECE_DATA != s.trans_info_.sql_cmd_ && !second_in) { ++s.current_.attempts_; - LOG_DEBUG("start next retry"); - - if (s.pll_info_.is_force_renew()) { // force pl lookup - retry_status = NOT_FOUND_EXISTING_ADDR; - } else if (REQUEST_REROUTE_ERROR == s.current_.error_type_) { - retry_status = FOUND_EXISTING_ADDR; - net::ops_ip_copy(s.server_info_.addr_, s.reroute_info_.replica_.server_.get_ipv4(), - static_cast(s.reroute_info_.replica_.server_.get_port())); - } else { - retry_status = retry_server_connection_not_open(s); + LOG_DEBUG("start next retry", "is in trans:", is_in_trans(s)); + // if use target db server then no need renew, will retry server from target db server + if ((OB_NOT_NULL(s.trans_info_.client_request_.get_parse_result().get_target_db_server()) + && !s.trans_info_.client_request_.get_parse_result().get_target_db_server()->is_empty()) + || (OB_NOT_NULL(s.sm_->target_db_server_) && !s.sm_->target_db_server_->is_empty())) { + s.pll_info_.force_renew_state_ = ObPartitionLookupInfo::ObForceRenewState::NO_NEED_RENEW; + s.pll_info_.is_need_force_flush_ = false; } + if (s.current_.error_type_ == TRANS_FREE_ROUTE_NOT_SUPPORTED_ERROR) { + // downgrade transaction internal routing, route the rest of request to coordinator session + LOG_DEBUG("transaction internal routing retry", K(s.trans_info_.sql_cmd_)); + retry_status = FOUND_EXISTING_ADDR; + s.server_info_.set_addr(s.sm_->get_client_session()->get_trans_coordinator_ss_addr()); + is_reroute_to_coordinator = true; + } else if (!is_in_trans(s) || is_internal_routing) { + if (s.pll_info_.is_force_renew()) { // force pl lookup + retry_status = NOT_FOUND_EXISTING_ADDR; + } else if (REQUEST_REROUTE_ERROR == s.current_.error_type_) { + retry_status = FOUND_EXISTING_ADDR; + s.server_info_.set_addr(ops_ip_sa_cast(s.reroute_info_.replica_.server_.get_sockaddr())); + } else { + retry_status = retry_server_connection_not_open(s); + } + } } if (NULL == s.congestion_entry_ || !s.congestion_entry_->is_congested()) { @@ -4403,14 +4990,21 @@ void ObMysqlTransact::handle_oceanbase_retry_server_connection(ObTransState &s) s.congestion_entry_->dec_ref(); s.congestion_entry_ = NULL; } - s.congestion_lookup_success_ = false; - s.need_congestion_lookup_ = true; + if (is_reroute_to_coordinator) { + s.congestion_lookup_success_ = true; + s.need_congestion_lookup_ = false; + s.pl_lookup_state_ = USE_COORDINATOR_SESSION; + } else { + s.congestion_lookup_success_ = false; + s.need_congestion_lookup_ = true; + } LOG_DEBUG("FOUND_EXISTING_ADDR, Retrying...", "attempts now", s.current_.attempts_, K(max_connect_attempts), "retry observer", s.server_info_.addr_, - "force_retry_congested", s.force_retry_congested_); + "force_retry_congested", s.force_retry_congested_, + "is reroute to coordinaotr", is_reroute_to_coordinator); TRANSACT_RETURN(SM_ACTION_CONGESTION_CONTROL_LOOKUP, handle_congestion_control_lookup); } else if (NOT_FOUND_EXISTING_ADDR == retry_status) { // before retry another server, reset analyze result @@ -4449,7 +5043,15 @@ void ObMysqlTransact::handle_oceanbase_retry_server_connection(ObTransState &s) void ObMysqlTransact::handle_retry_server_connection(ObTransState &s) { - if (s.sm_->client_session_->get_session_info().is_oceanbase_server()) { + /* + * reset response transform hook to keep the plugin created as the correct order + * otherwise, the packet handled by plugin will be err, eg, reroute err packet + */ + s.sm_->api_.txn_destroy_hook(OB_MYSQL_RESPONSE_TRANSFORM_HOOK); + + // Binlog requests also do not support retries + if (s.sm_->client_session_->get_session_info().is_oceanbase_server() + && !is_binlog_request(s)) { handle_oceanbase_retry_server_connection(s); } else { handle_server_connection_break(s); @@ -4517,14 +5119,32 @@ ObMysqlTransact::ObSSRetryStatus ObMysqlTransact::retry_server_connection_not_op if (s.current_.attempts_ == get_max_connect_attempts(s)) { handle_retry_last_time(s); } - - if ((s.mysql_config_params_->is_mock_routing_mode() && !s.sm_->client_session_->is_proxy_mysql_client_) + // target db server (sql comment & multi level config) + if (OB_NOT_NULL(s.trans_info_.client_request_.get_parse_result().get_target_db_server()) + && !s.trans_info_.client_request_.get_parse_result().get_target_db_server()->is_empty()) { + if (OB_FAIL(s.trans_info_.client_request_.get_parse_result().get_target_db_server()->get_next(s.server_info_.addr_))) { + LOG_WARN("fail to get target db server from sql comment, will disconnect", K(ret)); + } else { + ret_status = FOUND_EXISTING_ADDR; + LOG_DEBUG("succ to get target db server from sql comment, will retry", + "address", s.server_info_.addr_); + } + } else if (OB_NOT_NULL(s.sm_->target_db_server_) && !s.sm_->target_db_server_->is_empty()) { + if (OB_FAIL(s.sm_->target_db_server_->get_next(s.server_info_.addr_))) { + LOG_WARN("fail to get target db server from multi level config, will disconnect", K(ret)); + } else { + ret_status = FOUND_EXISTING_ADDR; + LOG_DEBUG("succ to get target db server from multi level config, will retry", + "address", s.server_info_.addr_); + } + // config: server_routing_mode & test_server_addr + } else if ((s.mysql_config_params_->is_mock_routing_mode() && !s.sm_->client_session_->is_proxy_mysql_client_) || s.mysql_config_params_->is_mysql_routing_mode()) { if (OB_FAIL(s.mysql_config_params_->get_one_test_server_addr(s.server_info_.addr_))) { LOG_WARN("mysql or mock mode, but test server addr in not set, disconnect", K(ret)); } else { s.sm_->client_session_->test_server_addr_ = s.server_info_.addr_; - LOG_DEBUG("mysql mode, test server is valid, just use it and skip pl lookup", + LOG_DEBUG("mysql mode, test server is valid, just use it to retry", "address", s.server_info_.addr_); } } else if (s.pll_info_.replica_size() > 0) { @@ -4549,7 +5169,8 @@ ObMysqlTransact::ObSSRetryStatus ObMysqlTransact::retry_server_connection_not_op } if ((NULL != replica) && replica->is_valid()) { - s.server_info_.set_addr(replica->server_.get_ipv4(), static_cast(replica->server_.get_port())); + struct sockaddr_storage sockaddr = replica->server_.get_sockaddr(); + s.server_info_.set_addr(*(struct sockaddr*)(&(sockaddr))); LOG_DEBUG("set addr here", K(s.server_info_.addr_)); ret_status = FOUND_EXISTING_ADDR; } else { @@ -4590,35 +5211,51 @@ ObMysqlTransact::ObSSRetryStatus ObMysqlTransact::retry_server_connection_not_op inline void ObMysqlTransact::handle_server_connection_break(ObTransState &s) { if (NULL != s.sm_->client_session_) { - int64_t ss_id = (OB_ISNULL(s.sm_->get_server_session()) ? 0 : s.sm_->get_server_session()->ss_id_); - uint32_t server_sessid = (OB_ISNULL(s.sm_->get_server_session()) ? 0 : s.sm_->get_server_session()->get_server_sessid()); - - LOG_INFO("[ObMysqlTransact::handle_server_connection_break]", - "client_ip", s.client_info_.addr_, - "server_ip", s.server_info_.addr_, - "cs_id", s.sm_->client_session_->get_cs_id(), - "proxy_sessid", s.sm_->client_session_->get_proxy_sessid(), - K(ss_id), - K(server_sessid), - "sm_id", s.sm_->sm_id_, - "proxy_user_name", s.sm_->client_session_->get_session_info().get_priv_info().get_proxy_user_name(), - "database_name", s.sm_->client_session_->get_session_info().get_database_name(), - "server_state", ObMysqlTransact::get_server_state_name(s.current_.state_), - "request_cmd", get_mysql_cmd_str(s.trans_info_.client_request_.get_packet_meta().cmd_), - "sql_cmd", get_mysql_cmd_str(s.trans_info_.sql_cmd_), - "sql", s.trans_info_.get_print_sql()); - - if (obmysql::OB_MYSQL_COM_QUIT != s.trans_info_.sql_cmd_) { - OBPROXY_XF_LOG(INFO, XFH_CONNECTION_SERVER_ABORT, - "client_ip", s.client_info_.addr_, - "server_ip", s.server_info_.addr_, - "cluster_name", s.sm_->client_session_->get_session_info().get_priv_info().cluster_name_, - "tenant_name", s.sm_->client_session_->get_session_info().get_priv_info().tenant_name_, - "user_name", s.sm_->client_session_->get_session_info().get_priv_info().user_name_, - "db", s.sm_->client_session_->get_session_info().get_database_name(), - "server_state", ObMysqlTransact::get_server_state_name(s.current_.state_), - "sql", s.trans_info_.client_request_.get_print_sql(), - "request_cmd", get_mysql_cmd_str(s.trans_info_.sql_cmd_)); + if (s.sm_->client_session_->get_session_info().get_priv_info().user_name_ == ObProxyTableInfo::DETECT_USERNAME_USER) { + // do nothing + } else { + int64_t ss_id = (OB_ISNULL(s.sm_->get_server_session()) ? 0 : s.sm_->get_server_session()->ss_id_); + uint32_t server_sessid = (OB_ISNULL(s.sm_->get_server_session()) ? 0 : s.sm_->get_server_session()->get_server_sessid()); + + LOG_INFO("[ObMysqlTransact::handle_server_connection_break]", + "client_ip", s.client_info_.addr_, + "server_ip", s.server_info_.addr_, + "cs_id", s.sm_->client_session_->get_cs_id(), + "proxy_sessid", s.sm_->client_session_->get_proxy_sessid(), + K(ss_id), + K(server_sessid), + "sm_id", s.sm_->sm_id_, + "proxy_user_name", s.sm_->client_session_->get_session_info().get_priv_info().get_proxy_user_name(), + "database_name", s.sm_->client_session_->get_session_info().get_database_name(), + "server_state", ObMysqlTransact::get_server_state_name(s.current_.state_), + "request_cmd", get_mysql_cmd_str(s.trans_info_.client_request_.get_packet_meta().cmd_), + "sql_cmd", get_mysql_cmd_str(s.trans_info_.sql_cmd_), + "sql", s.trans_info_.get_print_sql()); + + if (obmysql::OB_MYSQL_COM_QUIT != s.trans_info_.sql_cmd_) { + OBPROXY_XF_LOG(INFO, XFH_CONNECTION_SERVER_ABORT, + "client_ip", s.client_info_.addr_, + "server_ip", s.server_info_.addr_, + "cluster_name", s.sm_->client_session_->get_session_info().get_priv_info().cluster_name_, + "tenant_name", s.sm_->client_session_->get_session_info().get_priv_info().tenant_name_, + "user_name", s.sm_->client_session_->get_session_info().get_priv_info().user_name_, + "db", s.sm_->client_session_->get_session_info().get_database_name(), + "server_state", ObMysqlTransact::get_server_state_name(s.current_.state_), + "sql", s.trans_info_.client_request_.get_print_sql(), + "request_cmd", get_mysql_cmd_str(s.trans_info_.sql_cmd_)); + + s.trace_log_.log_it("[svr_connection_break]", + "cli", s.client_info_.addr_, + "svr", s.server_info_.addr_, + "cluster", s.sm_->client_session_->get_session_info().get_priv_info().cluster_name_, + "tenant", s.sm_->client_session_->get_session_info().get_priv_info().tenant_name_, + "user", s.sm_->client_session_->get_session_info().get_priv_info().user_name_, + "db", s.sm_->client_session_->get_session_info().get_database_name(), + "svr_state", ObMysqlTransact::get_server_state_name(s.current_.state_), + "sql", s.trans_info_.client_request_.get_print_sql(), + "sql_cmd", get_mysql_cmd_str(s.trans_info_.sql_cmd_)); + LOG_WARN("trace_log", K(s.trace_log_)); + } } } else { LOG_INFO("[ObMysqlTransact::handle_server_connection_break]", @@ -4636,6 +5273,14 @@ inline void ObMysqlTransact::handle_server_connection_break(ObTransState &s) "server_state", ObMysqlTransact::get_server_state_name(s.current_.state_), "sql", s.trans_info_.client_request_.get_print_sql(), "request_cmd", get_mysql_cmd_str(s.trans_info_.sql_cmd_)); + + s.trace_log_.log_it("[svr_connection_break]", + "cli", s.client_info_.addr_, + "svr", s.server_info_.addr_, + "svr_state", ObMysqlTransact::get_server_state_name(s.current_.state_), + "sql", s.trans_info_.client_request_.get_print_sql(), + "sql_cmd", get_mysql_cmd_str(s.trans_info_.sql_cmd_)); + LOG_WARN("trace_log", K(s.trace_log_)); } } @@ -4652,7 +5297,7 @@ inline void ObMysqlTransact::handle_server_connection_break(ObTransState &s) void ObMysqlTransact::handle_on_forward_server_response(ObTransState &s) { LOG_DEBUG("[ObMysqlTransact::handle_on_forward_server_response]", - "cur_send_action", ObMysqlTransact::get_send_action_name(s.current_.send_action_)); + "cur_send_action", ObMysqlTransact::get_send_action_name(s.current_.send_action_),"startm trans", s.is_hold_start_trans_); switch (s.current_.send_action_) { case SERVER_SEND_HANDSHAKE: { @@ -4705,7 +5350,7 @@ void ObMysqlTransact::handle_on_forward_server_response(ObTransState &s) break; } else if (client_info.is_oceanbase_server()) { bool is_proxy_mysql_client_ = s.sm_->client_session_->is_proxy_mysql_client_; - if (client_info.need_reset_all_session_vars() && !is_proxy_mysql_client_) { + if (client_info.need_reset_all_session_vars() && !is_binlog_request(s) && !is_proxy_mysql_client_) { // 1.if global vars changed, we need to sync all session vars to keep // server session vars is equal to the snapshot of client session // 2.proxy mysql client no need sync all session vars @@ -4730,7 +5375,9 @@ void ObMysqlTransact::handle_on_forward_server_response(ObTransState &s) //obutils::ObSqlParseResult &sql_result = s.trans_info_.client_request_.get_parse_result(); obmysql::ObMySQLCmd cmd = s.trans_info_.client_request_.get_packet_meta().cmd_; if (obmysql::OB_MYSQL_COM_STMT_CLOSE == cmd - || obmysql::OB_MYSQL_COM_STMT_RESET == cmd) { + || obmysql::OB_MYSQL_COM_STMT_RESET == cmd + || is_binlog_request(s) + || s.sm_->client_session_->can_direct_send_request_) { // no need sync var, send to server directly s.current_.send_action_ = SERVER_SEND_REQUEST; s.next_action_ = SM_ACTION_API_SEND_REQUEST; @@ -4757,13 +5404,17 @@ void ObMysqlTransact::handle_on_forward_server_response(ObTransState &s) ObClientSessionInfo &client_info = get_client_session_info(s); ObServerSessionInfo &server_info = get_server_session_info(s); //obutils::ObSqlParseResult &sql_result = s.trans_info_.client_request_.get_parse_result(); - if (client_info.need_reset_session_vars(server_info)) { + if (client_info.is_server_support_session_var_sync() && + client_info.need_reset_user_session_vars(server_info)) { + s.current_.send_action_ = SERVER_SEND_SESSION_USER_VARS; + s.next_action_ = SM_ACTION_API_SEND_REQUEST; + break; + } else if (!client_info.is_server_support_session_var_sync() && + client_info.need_reset_session_vars(server_info)) { s.current_.send_action_ = SERVER_SEND_SESSION_VARS; s.next_action_ = SM_ACTION_API_SEND_REQUEST; break; - } else { - // fall through: - } + } else { /* fall through */ } } else { s.current_.state_ = INTERNAL_ERROR; handle_server_connection_break(s); @@ -4775,27 +5426,24 @@ void ObMysqlTransact::handle_on_forward_server_response(ObTransState &s) } __attribute__ ((fallthrough)); case SERVER_SEND_SESSION_VARS: - case SERVER_SEND_LAST_INSERT_ID: + case SERVER_SEND_SESSION_USER_VARS: case SERVER_SEND_PREPARE: case SERVER_SEND_TEXT_PS_PREPARE: + case SERVER_SEND_XA_START: case SERVER_SEND_START_TRANS: { if (OB_LIKELY(NULL != s.sm_->client_session_) && OB_LIKELY(NULL != s.sm_->get_server_session())) { ObClientSessionInfo &client_info = get_client_session_info(s); ObServerSessionInfo &server_info = get_server_session_info(s); obmysql::ObMySQLCmd cmd = s.trans_info_.client_request_.get_packet_meta().cmd_; ObProxyMysqlRequest &client_request = s.trans_info_.client_request_; - //obutils::ObSqlParseResult &sql_result = s.trans_info_.client_request_.get_parse_result(); - if (client_info.need_reset_last_insert_id(server_info)) { - // TODO: current version proxy parse can't judge last_insert_id exactly, - // so we do not judge, whether sql_reuslt has_last_insert_id here - // if it is large request, we do not parse the sql, we don't know whether the sql contains - // last_insert_id, in this case we will sync last_insert_id if need - s.current_.send_action_ = SERVER_SEND_LAST_INSERT_ID; - } else if (s.is_hold_start_trans_) { + if (s.is_hold_start_trans_) { s.current_.send_action_ = SERVER_SEND_START_TRANS; + } else if (s.is_hold_xa_start_) { + LOG_DEBUG("[ObMysqlTransact::handle_on_forward_server_response] set send action SERVER_SEND_XA_START for sync xa start"); + s.current_.send_action_ = SERVER_SEND_XA_START; } else if ((obmysql::OB_MYSQL_COM_STMT_EXECUTE == cmd - || obmysql::OB_MYSQL_COM_STMT_SEND_PIECE_DATA == cmd - || obmysql::OB_MYSQL_COM_STMT_SEND_LONG_DATA == cmd) + || obmysql::OB_MYSQL_COM_STMT_SEND_PIECE_DATA == cmd + || obmysql::OB_MYSQL_COM_STMT_SEND_LONG_DATA == cmd) && client_info.need_do_prepare(server_info)) { s.current_.send_action_ = SERVER_SEND_PREPARE; } else if (client_request.get_parse_result().is_text_ps_execute_stmt() && @@ -4909,11 +5557,11 @@ inline void ObMysqlTransact::update_sync_session_stat(ObTransState &s) MYSQL_INCREMENT_TRANS_STAT(SEND_CHANGED_SESSION_VARS_REQUESTS); break; - case SERVER_SEND_LAST_INSERT_ID: - s.sm_->cmd_time_stats_.server_send_last_insert_id_time_ += cost; + case SERVER_SEND_SESSION_USER_VARS: + s.sm_->cmd_time_stats_.server_send_session_user_variable_time_ += cost; s.sm_->cmd_time_stats_.server_sync_session_variable_time_ += cost; - MYSQL_SUM_TIME_STAT(TOTAL_SEND_LAST_INSERT_ID_TIME, cost); - MYSQL_INCREMENT_TRANS_STAT(SEND_LAST_INSERT_ID_REQUESTS); + MYSQL_SUM_TIME_STAT(TOTAL_SEND_CHANGED_SESSION_USER_VARS_TIME, cost); + MYSQL_INCREMENT_TRANS_STAT(SEND_CHANGED_SESSION_USER_VARS_REQUESTS); break; case SERVER_SEND_START_TRANS: @@ -4922,6 +5570,13 @@ inline void ObMysqlTransact::update_sync_session_stat(ObTransState &s) MYSQL_SUM_TIME_STAT(TOTAL_SEND_START_TRANS_TIME, cost); MYSQL_INCREMENT_TRANS_STAT(SEND_START_TRANS_REQUESTS); break; + + case SERVER_SEND_XA_START: + s.sm_->cmd_time_stats_.server_send_xa_start_time_ += cost; + s.sm_->cmd_time_stats_.server_sync_session_variable_time_ += cost; + MYSQL_SUM_TIME_STAT(TOTAL_SEND_XA_START_TIME, cost); + MYSQL_INCREMENT_TRANS_STAT(SEND_XA_START_REQUESTS); + break; case SERVER_SEND_HANDSHAKE: case SERVER_SEND_LOGIN: @@ -5177,12 +5832,18 @@ int ObMysqlTransact::build_error_packet(ObTransState &s, ObMysqlClientSession *c } if (OB_SUCC(ret)) { + ObMysqlSM *sm = s.sm_; + ObProxyProtocol client_protocol = ObProxyProtocol::PROTOCOL_NORMAL; + if (sm != NULL) { + client_protocol = sm->get_client_session_protocol(); + } + int errcode = s.mysql_errcode_; s.inner_errcode_ = s.mysql_errcode_; uint8_t next_seq = 0; if (s.is_auth_request_) { - if ((NULL != s.sm_) && (NULL != s.sm_->client_session_)) { - ObMysqlAuthRequest &auth_req = s.sm_->client_session_->get_session_info().get_login_req(); + if (client_session != NULL) { + ObMysqlAuthRequest &auth_req = client_session->get_session_info().get_login_req(); next_seq = static_cast(auth_req.get_packet_meta().pkt_seq_ + 1); } } else { @@ -5192,7 +5853,8 @@ int ObMysqlTransact::build_error_packet(ObTransState &s, ObMysqlClientSession *c if (NULL != s.mysql_errmsg_) { const char *errmsg = s.mysql_errmsg_; - if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, next_seq, errcode, errmsg))) { + if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, client_protocol, + next_seq, errcode, errmsg))) { LOG_WARN("[ObMysqlTransact::build_error_packet] fail to encode err pacekt buf", K(next_seq), K(errmsg), K(errcode), K(ret)); } @@ -5207,8 +5869,8 @@ int ObMysqlTransact::build_error_packet(ObTransState &s, ObMysqlClientSession *c int64_t name_len = 0; const char *name_str = NULL; bool has_auth_resp = false; - if ((NULL != s.sm_) && (NULL != s.sm_->client_session_)) { - ObClientSessionInfo &client_info = s.sm_->client_session_->get_session_info(); + if (client_session != NULL) { + ObClientSessionInfo &client_info = client_session->get_session_info(); ObMysqlAuthRequest &auth_req = client_info.get_login_req(); ObHSRResult &result = auth_req.get_hsr_result(); if (!result.is_clustername_from_default_) { @@ -5226,8 +5888,8 @@ int ObMysqlTransact::build_error_packet(ObTransState &s, ObMysqlClientSession *c if (OB_FAIL(databuff_printf(errmsg, BUF_LEN, pos, ob_str_user_error(errcode), name_len, name_str, strlen(ip_buff), ip_buff, (has_auth_resp ? "YES" : "NO")))) { LOG_WARN("fail to fill err_msg", K(ret)); - } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, next_seq, - errcode, errmsg))) { + } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, client_protocol, + next_seq, errcode, errmsg))) { LOG_WARN("[ObMysqlTransact::build_error_packet] fail to encode err pacekt buf", K(next_seq), K(errcode), K(ret)); } else { @@ -5249,8 +5911,8 @@ int ObMysqlTransact::build_error_packet(ObTransState &s, ObMysqlClientSession *c char *err_msg = NULL; if (OB_FAIL(ObProxyPacketWriter::get_err_buf(errcode, err_msg))) { LOG_WARN("fail to get err buf", K(ret)); - } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, next_seq, - errcode, err_msg))) { + } else if (OB_FAIL(ObProxyPacketWriter::write_error_packet(*buf, client_session, client_protocol, + next_seq, errcode, err_msg))) { LOG_WARN("[ObMysqlTransact::build_error_packet] fail to build not supported err resp", K(ret)); } else { // nothing @@ -5313,6 +5975,13 @@ void ObMysqlTransact::ObTransState::refresh_mysql_config() } } + // record v2 config + if (is_auth_request_) { + bool enable_v2 = mysql_config_params_->enable_ob_protocol_v2_; + sm_->set_enable_ob_protocol_v2(enable_v2); + PROXY_CS_LOG(DEBUG, "client session start with ", "enable_ob_protocol_v2:", enable_v2, "cs_id", sm_->get_client_session()->get_cs_id()); + } + // Start to get the version number. If there are concurrent modifications, the version will be pushed up. // The next time it is executed, it will continue to be updated. ObNetVConnection *client_vc = static_cast(sm_->get_client_session()->get_netvc()); @@ -5320,11 +5989,9 @@ void ObMysqlTransact::ObTransState::refresh_mysql_config() ObClientSessionInfo &session_info = sm_->get_client_session()->get_session_info(); uint64_t global_version = get_global_proxy_config_table_processor().get_config_version(); if (sm_->config_version_ != global_version && NULL != client_vc) { - int32_t ip = ntohl(client_vc->get_virtual_ip()); - int32_t port = static_cast(client_vc->get_virtual_port()); int64_t vid = static_cast(client_vc->get_virtual_vid()); ObVipAddr addr; - addr.set(ip, port, vid); + addr.set(client_vc->get_virtual_addr(), vid); ObString tenant_name; ObString cluster_name; if (client_session->is_need_convert_vip_to_tname() && client_session->is_vip_lookup_success()) { @@ -5353,7 +6020,9 @@ void ObMysqlTransact::ObTransState::refresh_mysql_config() LOG_DEBUG("get config succ", K(addr), K(cluster_name), K(tenant_name), K_(sm_->proxy_route_policy), K_(sm_->proxy_idc_name), K_(sm_->enable_cloud_full_username), K_(sm_->enable_client_ssl), - K_(sm_->enable_server_ssl), K(ret)); + K_(sm_->enable_server_ssl), K_(sm_->enable_transaction_split), K_(sm_->enable_transaction_split), + K(session_info.is_request_follower_user()), K(session_info.is_read_only_user()), + K_(sm_->target_db_server), K(ret)); } } @@ -5363,6 +6032,7 @@ int ObMysqlTransact::ObTransState::get_config_item(const ObString& cluster_name, const int64_t global_version) { int ret = OB_SUCCESS; + ObClientSessionInfo &session_info = sm_->get_client_session()->get_session_info(); if (OB_SUCC(ret)) { ObConfigItem item; if (OB_FAIL(get_global_config_processor().get_proxy_config( @@ -5413,6 +6083,99 @@ int ObMysqlTransact::ObTransState::get_config_item(const ObString& cluster_name, } } + if (OB_SUCC(ret)) { + ObConfigItem item; + if (OB_FAIL(get_global_config_processor().get_proxy_config( + addr, cluster_name, tenant_name, "target_db_server", item))) { + LOG_WARN("fail to get target_db_server", K(addr), K(cluster_name), K(tenant_name), K(ret)); + // if config empty + } else if (OB_ISNULL(item.str()) || strlen(item.str()) == 0 ) { + // target db server not null, reset it + if (OB_NOT_NULL(sm_->target_db_server_)) { + op_free(sm_->target_db_server_); + sm_->target_db_server_ = NULL; + // target db server is null, do nothing + } else { /* do nothing */} + // if config not empty + // target db server is null, allocate and init one + } else if (OB_ISNULL(sm_->target_db_server_) && OB_ISNULL(sm_->target_db_server_ = op_alloc(ObTargetDbServer))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc memory to for target db server", K(ret)); + } else if (OB_FAIL(sm_->target_db_server_->init(item.str(), strlen(item.str())))) { + LOG_WARN("fail to load target db server from multi level config", K(ret)); + } + } + + if (OB_SUCC(ret)) { + ObConfigIntItem int_item; + if (OB_FAIL(get_global_config_processor().get_proxy_config_int_item( + addr, cluster_name, tenant_name, "obproxy_read_only", int_item))) { + LOG_WARN("get vip obproxy_read_only failed", K(addr), K(cluster_name), K(tenant_name), K(ret)); + } else { + bool is_read_only = (ReadOnly == int_item.get_value()); + bool is_sys_var_update = (session_info.is_read_only_user() != is_read_only); + session_info.set_is_read_only_user(is_read_only); + if (is_sys_var_update) { + ObString tx_read_only("tx_read_only"); + ObString tx_read_only_true; + if (session_info.is_read_only_user()) { + tx_read_only_true = "1"; + } else { + tx_read_only_true = "0"; + } + if (OB_FAIL(session_info.update_sys_variable(tx_read_only, tx_read_only_true))) { + LOG_WARN("replace user variables failed", K(tx_read_only_true), K(ret)); + } + } + } + } + + if (OB_SUCC(ret)) { + ObConfigIntItem int_item; + if (OB_FAIL(get_global_config_processor().get_proxy_config_int_item( + addr, cluster_name, tenant_name, "obproxy_read_consistency", int_item))) { + LOG_WARN("get vip obproxy_read_consistency failed", K(addr), K(cluster_name), K(tenant_name), K(ret)); + } else { + bool is_request_follower = (RequestFollower == int_item.get_value()); + bool is_sys_var_update = (session_info.is_request_follower_user() != is_request_follower); + session_info.set_is_request_follower_user(is_request_follower); + if (is_sys_var_update) { + ObString ob_read_consistency("ob_read_consistency"); + ObString weak; + if (session_info.is_request_follower_user()) { + weak = "2"; + } else { + weak = "3"; + } + if (OB_FAIL(session_info.update_sys_variable(ob_read_consistency, weak))) { + LOG_WARN("replace user variables failed", K(weak), K(ret)); + } else { + session_info.set_read_consistency_set_flag(true); + } + } + } + } + + if (OB_SUCC(ret)) { + ObConfigBoolItem bool_item; + if (OB_FAIL(get_global_config_processor().get_proxy_config_bool_item( + addr, cluster_name, tenant_name, "enable_read_write_split", bool_item))) { + LOG_WARN("get enable_read_write_split failed", K(addr), K(cluster_name), K(tenant_name), K(ret)); + } else { + sm_->enable_read_write_split_ = bool_item.get_value(); + } + } + + if (OB_SUCC(ret)) { + ObConfigBoolItem bool_item; + if (OB_FAIL(get_global_config_processor().get_proxy_config_bool_item( + addr, cluster_name, tenant_name, "enable_transaction_split", bool_item))) { + LOG_WARN("get enable_transaction_split failed", K(addr), K(cluster_name), K(tenant_name), K(ret)); + } else { + sm_->enable_transaction_split_ = bool_item.get_value(); + } + } + if (OB_SUCC(ret) && global_version > 0) { sm_->config_version_ = global_version; } @@ -5629,6 +6392,10 @@ const char *ObMysqlTransact::get_server_resp_error_name(ObMysqlTransact::ObServe ret = "START_TRANS_COMMON_ERROR"; break; + case ObMysqlTransact::START_XA_START_ERROR: + ret = "START_XA_START_ERROR"; + break; + case ObMysqlTransact::SYNC_DATABASE_COMMON_ERROR: ret = "SYNC_DATABASE_COMMON_ERROR"; break; @@ -5673,6 +6440,9 @@ const char *ObMysqlTransact::get_server_resp_error_name(ObMysqlTransact::ObServe ret = "SYANDBY_WEAK_READONLY_ERROR"; break; + case ObMysqlTransact::TRANS_FREE_ROUTE_NOT_SUPPORTED_ERROR: + ret = "TRANS_FREE_ROUTE_NOT_SUPPORTED_ERROR"; + break; case ObMysqlTransact::MAX_RESP_ERROR: ret = "MAX_RESP_ERR"; break; @@ -5788,13 +6558,17 @@ const char *ObMysqlTransact::get_send_action_name( case ObMysqlTransact::SERVER_SEND_SESSION_VARS: ret = "SERVER_SEND_SESSION_VARS"; break; + + case ObMysqlTransact::SERVER_SEND_SESSION_USER_VARS: + ret = "SERVER_SEND_SESSION_USER_VARS"; + break; case ObMysqlTransact::SERVER_SEND_START_TRANS: ret = "SERVER_SEND_START_TRANS"; break; - case ObMysqlTransact::SERVER_SEND_LAST_INSERT_ID: - ret = "SERVER_SEND_LAST_INSERT_ID"; + case ObMysqlTransact::SERVER_SEND_XA_START: + ret = "SERVER_SEND_XA_START"; break; case ObMysqlTransact::SERVER_SEND_REQUEST: @@ -5852,7 +6626,13 @@ bool ObMysqlTransact::is_internal_request(ObTransState &s) || s.trans_info_.client_request_.get_parse_result().is_show_table_status_stmt()) && !is_single_shard_db_table(s)))) || (s.is_trans_first_request_ + && !s.is_hold_xa_start_ && s.trans_info_.client_request_.get_parse_result().need_hold_start_trans()) + || (s.is_trans_first_request_ + && !s.is_hold_start_trans_ + && !s.is_hold_xa_start_ + && s.trans_info_.client_request_.get_parse_result().need_hold_xa_start() + && get_global_proxy_config().enable_xa_route) || s.trans_info_.client_request_.get_parse_result().is_internal_request() || is_bad_route_request(s)) || !is_supported_mysql_cmd(s.trans_info_.sql_cmd_) @@ -5862,6 +6642,95 @@ bool ObMysqlTransact::is_internal_request(ObTransState &s) &&s.trans_info_.client_request_.get_parse_result().is_set_ob_read_consistency()); } +int64_t ObMysqlTransact::get_max_connect_attempts(ObTransState &s) +{ + int64_t target_db_server_num = 0; + if (NULL != s.trans_info_.client_request_.get_parse_result().get_target_db_server() + && 0 < s.trans_info_.client_request_.get_parse_result().get_target_db_server()->num()) { + target_db_server_num = s.trans_info_.client_request_.get_parse_result().get_target_db_server()->num(); + } else if (NULL != s.sm_->target_db_server_ && 0 < s.sm_->target_db_server_->num()) { + target_db_server_num = s.sm_->target_db_server_->num(); + } + return std::max(target_db_server_num, std::max(s.mysql_config_params_->connect_observer_max_retries_, + get_max_connect_attempts_from_replica(s.pll_info_.replica_size()))); +} + +bool ObMysqlTransact::is_binlog_request(const ObTransState &s) +{ + bool bret = false; + if (get_global_proxy_config().enable_binlog_service + && (obmysql::OB_MYSQL_COM_REGISTER_SLAVE == s.trans_info_.client_request_.get_packet_meta().cmd_ + || obmysql::OB_MYSQL_COM_BINLOG_DUMP == s.trans_info_.client_request_.get_packet_meta().cmd_ + || obmysql::OB_MYSQL_COM_BINLOG_DUMP_GTID == s.trans_info_.client_request_.get_packet_meta().cmd_ + || s.trans_info_.client_request_.get_parse_result().is_binlog_stmt())) { + bret = true; + } + + return bret; +} + +void ObMysqlTransact::handle_binlog_request(ObTransState &s) +{ + ObClientSessionInfo &cs_info = get_client_session_info(s); + ObString cluster_name = cs_info.get_priv_info().cluster_name_; + ObString tenant_name = cs_info.get_priv_info().tenant_name_; + + ObTableEntryName &te_name = s.pll_info_.te_name_; + te_name.cluster_name_ = cluster_name; + te_name.tenant_name_ = tenant_name; + // mock database name + te_name.database_name_ = OB_SYS_DATABASE_NAME; + te_name.table_name_ = OB_ALL_BINLOG_DUMMY_TNAME; + LOG_DEBUG("handle binlog request", K(te_name)); + TRANSACT_RETURN(SM_ACTION_BINLOG_LOCATION_LOOKUP, handle_bl_lookup); +} + +void ObMysqlTransact::handle_bl_lookup(ObTransState &s) +{ + int ret = OB_SUCCESS; + ++s.pll_info_.pl_attempts_; + + if (OB_UNLIKELY(!s.pll_info_.lookup_success_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[ObMysqlTransact::handle_bl_lookup] " + "fail to lookup binlog location, will disconnect", K(ret)); + } else if (s.server_info_.addr_.is_valid()) { + // do nothing + } else { + LOG_DEBUG("ObMysqlTransact::handle_bl_lookup] binlog location lookup successful", + "pl_attempts", s.pll_info_.pl_attempts_); + const ObProxyPartitionLocation *pl = s.pll_info_.route_.table_entry_->get_first_pl(); + if (NULL != pl && pl->replica_count() > 0) { + s.server_info_.set_addr(ops_ip_sa_cast(pl->get_replica(0)->server_.get_sockaddr())); + s.pll_info_.route_.cur_chosen_server_.replica_ = pl->get_replica(0); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("not found binlog server replica", K(ret)); + } + } + + if (OB_SUCC(ret)) { + LOG_DEBUG("[ObMysqlTransact::handle_bl_lookup] chosen server, and begin to congestion lookup", + "addr", s.server_info_.addr_, + "attempts", s.current_.attempts_, + "sm_id", s.sm_->sm_id_); + if (OB_UNLIKELY(get_global_performance_params().enable_trace_)) { + s.sm_->milestones_.bl_process_end_ = get_based_hrtime(s); + s.sm_->cmd_time_stats_.bl_process_time_ += + milestone_diff(s.sm_->milestones_.bl_process_begin_, s.sm_->milestones_.bl_process_end_); + } + // At present, binlog does not have high-availability features. + // After routing, it directly forwards and does not follow the disaster recovery management process. + TRANSACT_RETURN(SM_ACTION_OBSERVER_OPEN, ObMysqlTransact::handle_response); + } + + if (OB_FAIL(ret)) { + s.inner_errcode_ = ret; + // disconnect + TRANSACT_RETURN(SM_ACTION_SEND_ERROR_NOOP, NULL); + } +} + } // end of namespace proxy } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/proxy/mysql/ob_mysql_transact.h b/src/obproxy/proxy/mysql/ob_mysql_transact.h index feaf25ddf..6a5242956 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_transact.h +++ b/src/obproxy/proxy/mysql/ob_mysql_transact.h @@ -24,10 +24,12 @@ #include "proxy/mysqllib/ob_mysql_config_processor.h" #include "proxy/route/ob_table_cache.h" #include "proxy/route/ob_server_route.h" +#include "proxy/route/ob_tenant_server.h" #include "proxy/mysql/ob_mysql_proxy_port.h" #include "cmd/ob_show_sqlaudit_handler.h" #include "proxy/api/ob_transform.h" #include "proxy/mysqllib/ob_proxy_ob20_request.h" +#include "lib/oblog/ob_simple_trace.h" namespace oceanbase { @@ -68,6 +70,12 @@ class ObMysqlTransact MAYBE_ABORTED, ABORTED }; + enum ObPLLookupState + { + NEED_PL_LOOKUP = 0, + USE_LAST_SERVER_SESSION, + USE_COORDINATOR_SESSION + }; enum ObMysqlTransactMagic { @@ -84,6 +92,8 @@ class ObMysqlTransact }; static common::ObString get_retry_status_string(const ObSSRetryStatus status); + static common::ObString get_pl_lookup_state_string(const ObPLLookupState state); + // Please do not forget to fix ObServerState // (ob_api.h) in case of any modifications in @@ -127,6 +137,8 @@ class ObMysqlTransact RESET_SESSION_VARS_COMMON_ERROR, // sync start trans related START_TRANS_COMMON_ERROR, + // sync xa start related + START_XA_START_ERROR, // sync database related SYNC_DATABASE_COMMON_ERROR, // sync com_stmt_prepare @@ -143,7 +155,7 @@ class ObMysqlTransact REQUEST_READ_ONLY_ERROR, REQUEST_REROUTE_ERROR, STANDBY_WEAK_READONLY_ERROR, - + TRANS_FREE_ROUTE_NOT_SUPPORTED_ERROR, // attention!! add error type between MIN_RESP_ERROR and MAX_RESP_ERROR MAX_RESP_ERROR }; @@ -183,6 +195,8 @@ class ObMysqlTransact SM_ACTION_API_SEND_RESPONSE, SM_ACTION_API_CMD_COMPLETE, SM_ACTION_API_SM_SHUTDOWN, + + SM_ACTION_BINLOG_LOCATION_LOOKUP, }; enum ObAttachDummyEntryType @@ -267,12 +281,13 @@ class ObMysqlTransact SERVER_SEND_ALL_SESSION_VARS, SERVER_SEND_USE_DATABASE, SERVER_SEND_SESSION_VARS, - SERVER_SEND_LAST_INSERT_ID, + SERVER_SEND_SESSION_USER_VARS, SERVER_SEND_START_TRANS, + SERVER_SEND_XA_START, SERVER_SEND_REQUEST, SERVER_SEND_PREPARE, SERVER_SEND_SSL_REQUEST, - SERVER_SEND_TEXT_PS_PREPARE, + SERVER_SEND_TEXT_PS_PREPARE }; struct ObCurrentInfo @@ -381,15 +396,11 @@ class ObMysqlTransact { return route_.get_next_avail_replica(); } - const ObProxyReplicaLocation *get_next_replica(const uint32_t cur_ip, const uint16_t cur_port, - const bool is_force_retry) - { - return route_.get_next_replica(cur_ip, cur_port, is_force_retry); - } const ObProxyReplicaLocation *get_leader_replica_from_remote() { return route_.get_leader_replica_from_remote(); } + void reset_consistency(); void reset_pl(); void reset(); @@ -481,11 +492,12 @@ class ObMysqlTransact sm_(NULL), mysql_config_params_(NULL), is_rerouted_(false), - need_pl_lookup_(false), + pl_lookup_state_ (NEED_PL_LOOKUP), is_auth_request_(false), is_trans_first_request_(false), is_proxysys_tenant_(false), is_hold_start_trans_(false), + is_hold_xa_start_(false), send_reqeust_direct_(false), source_(SOURCE_NONE), pre_transform_source_(SOURCE_NONE), @@ -514,7 +526,8 @@ class ObMysqlTransact api_mysql_sm_shutdown_(false), api_server_addr_set_(false), need_retry_(true), - sqlaudit_record_queue_(NULL) + sqlaudit_record_queue_(NULL), + trace_log_() { memset(user_args_, 0, sizeof(user_args_)); } @@ -530,7 +543,7 @@ class ObMysqlTransact PROXY_TXN_LOG(WARN, "invalid argument", K(sm), K(ret)); } else { sm_ = sm; - need_pl_lookup_ = true; + pl_lookup_state_ = NEED_PL_LOOKUP; current_stats_ = &first_stats_; trans_info_.reset(); } @@ -665,30 +678,19 @@ class ObMysqlTransact reroute_info_.reset(); if (CMD_COMPLETE == current_.state_) { - if (!is_hold_start_trans_) { + if (!is_hold_start_trans_ && !is_hold_xa_start_) { is_trans_first_request_ = false; } if (obmysql::OB_MYSQL_COM_LOGIN == trans_info_.sql_cmd_) { is_auth_request_ = false; } + pll_info_.reset_consistency(); } else if (TRANSACTION_COMPLETE == current_.state_) { + trace_log_.reset(); is_trans_first_request_ = true; is_auth_request_ = false; - - if (NULL != congestion_entry_) { - // if this trans succ, just set avlie this server; - if (!is_congestion_entry_updated_) { - congestion_entry_->set_alive_congested_free(); - } - congestion_entry_->dec_ref(); - congestion_entry_ = NULL; - } - is_congestion_entry_updated_ = false; - congestion_entry_not_exist_count_ = 0; - need_congestion_lookup_ = true; - congestion_lookup_success_ = false; - force_retry_congested_ = false; + reset_congestion_entry(); mysql_errmsg_ = NULL; inner_errcode_ = 0; inner_errmsg_ = NULL; @@ -708,6 +710,23 @@ class ObMysqlTransact } else { /* do nothing */ } } + void reset_congestion_entry() + { + if (NULL != congestion_entry_) { + // if this trans succ, just set alive this server; + if (!is_congestion_entry_updated_) { + congestion_entry_->set_alive_congested_free(); + } + congestion_entry_->dec_ref(); + congestion_entry_ = NULL; + } + is_congestion_entry_updated_ = false; + congestion_entry_not_exist_count_ = 0; + need_congestion_lookup_ = true; + congestion_lookup_success_ = false; + force_retry_congested_ = false; + } + void destroy() { record_transaction_stats(); @@ -735,9 +754,11 @@ class ObMysqlTransact static bool is_for_update_sql(common::ObString src_sql); common::ObConsistencyLevel get_trans_consistency_level(ObClientSessionInfo &cs_info); + common::ObConsistencyLevel get_read_write_consistency_level(ObClientSessionInfo &session_info); bool is_request_readonly_zone_support(ObClientSessionInfo &cs_info); ObRoutePolicyEnum get_route_policy(ObMysqlClientSession &cs, const bool need_use_dup_replica); void get_route_policy(ObProxyRoutePolicyEnum policy, ObRoutePolicyEnum& ret_policy); + bool is_need_pl_lookup() { return pl_lookup_state_ == NEED_PL_LOOKUP; } event::ObFixedArenaAllocator<1024> arena_; @@ -754,11 +775,13 @@ class ObMysqlTransact ObTransactInfo trans_info_; bool is_rerouted_; - bool need_pl_lookup_; + // determin if do pl lookup + ObPLLookupState pl_lookup_state_; bool is_auth_request_; bool is_trans_first_request_; bool is_proxysys_tenant_; bool is_hold_start_trans_; // indicate whether hold begin(start transaction) + bool is_hold_xa_start_; bool send_reqeust_direct_; // when send sync all session variables, we can send user request directly ObSourceType source_; @@ -803,6 +826,7 @@ class ObMysqlTransact bool need_retry_; ObSqlauditRecordQueue *sqlaudit_record_queue_; + common::ObSimpleTrace<4096> trace_log_; private: DISALLOW_COPY_AND_ASSIGN(ObTransState); @@ -841,11 +865,13 @@ class ObMysqlTransact static void handle_error_jump(ObTransState &s); static void handle_internal_request(ObTransState &s); + static void handle_binlog_request(ObTransState &s); static void handle_server_addr_lookup(ObTransState &s); static void get_region_name_and_server_info(ObTransState &s, common::ObIArray &simple_servers_info, common::ObIArray ®ion_names); static void handle_pl_lookup(ObTransState &s); + static void handle_bl_lookup(ObTransState &s); static void modify_pl_lookup(ObTransState &s); static void handle_congestion_control_lookup(ObTransState &s); static void handle_congestion_entry_not_exist(ObTransState &s); @@ -868,6 +894,7 @@ class ObMysqlTransact static bool is_dbmesh_pool_user(ObTransState &s); static bool is_internal_request(ObTransState &s); + static bool is_binlog_request(const ObTransState &s); static bool is_single_shard_db_table(ObTransState &s); static bool can_direct_ok_for_login(ObTransState &s); static bool is_in_trans(ObTransState &s); @@ -876,15 +903,15 @@ class ObMysqlTransact static bool is_bad_route_request(ObTransState &s); static bool is_session_memory_overflow(ObTransState &s); static bool need_use_dup_replica(const common::ObConsistencyLevel level, ObTransState &s); - static bool need_pl_lookup(ObTransState &s); - static bool need_use_last_server_session(ObTransState &s); + static ObPLLookupState need_pl_lookup(ObTransState &s); + static bool need_use_coordinator_session(ObTransState &s); static bool is_db_reset(ObTransState &s); static bool need_server_session_lookup(ObTransState &s); static int64_t get_max_connect_attempts_from_replica(const int64_t replica_size); static int64_t get_max_connect_attempts(ObTransState &s); static int build_table_entry_request_packet(ObTransState &s, event::ObIOBufferReader *&reader); - static void handle_resultset_resp(ObTransState &s); + static void handle_resultset_resp(ObTransState &s, bool &is_user_request); static int fetch_table_entry_info(ObTransState &s); static ObClientSessionInfo &get_client_session_info(ObTransState &s); @@ -896,8 +923,8 @@ class ObMysqlTransact static void handle_handshake_pkt(ObTransState &s); static int handle_oceanbase_handshake_pkt(ObTransState &s, uint32_t conn_id, ObAddr &client_addr); - static void handle_error_resp(ObTransState &s); - static void handle_ok_resp(ObTransState &s); + static void handle_error_resp(ObTransState &s, bool &is_user_request); + static void handle_ok_resp(ObTransState &s, bool &is_user_request); static void handle_db_reset(ObTransState &s); static void handle_first_response_packet(ObTransState &s); @@ -920,6 +947,7 @@ class ObMysqlTransact static void handle_execute_succ(ObTransState &s); static int do_handle_execute_succ(ObTransState &s); static void handle_prepare_execute_succ(ObTransState &s); + static int do_handle_prepare_execute_xa_succ(event::ObIOBufferReader &buf_reader); static void handle_text_ps_prepare_succ(ObTransState &s); static int handle_text_ps_drop_succ(ObTransState &s, bool &is_user_request); static int handle_change_user_request_succ(ObTransState &s); @@ -955,12 +983,17 @@ class ObMysqlTransact static const char *get_send_action_name(ObMysqlTransact::ObServerSendActionType type); static const char *get_server_resp_error_name(ObMysqlTransact::ObServerRespErrorType type); - static int64_t build_addr_from_ip_port(const uint32_t ip, const uint16_t port); static void get_ip_port_from_addr(const int64_t addr, uint32_t &ip, uint16_t &port); static void check_safe_read_snapshot(ObTransState &s); static bool is_need_reroute(ObMysqlTransact::ObTransState &s); static bool is_need_use_sql_table_cache(ObMysqlTransact::ObTransState &s); + static bool handle_set_trans_internal_routing(ObMysqlTransact::ObTransState &s, bool server_transaction_routing_flag); + static bool is_sql_able_to_route_participant_in_trans(obutils::ObSqlParseResult& base_sql_parse_result, obmysql::ObMySQLCmd sql_cmd); + static bool is_trans_specified(ObTransState &s); + static bool has_dependent_func(ObTransState &s); + static void record_trans_state(ObTransState &s, bool is_in_trans); + static bool is_addr_logonly(const net::ObIpEndpoint &addr, const ObTenantServer *ts); }; inline bool ObMysqlTransact::is_need_use_sql_table_cache(ObMysqlTransact::ObTransState &s) @@ -974,20 +1007,6 @@ inline bool ObMysqlTransact::is_need_use_sql_table_cache(ObMysqlTransact::ObTran typedef void (*TransactEntryFunc)(ObMysqlTransact::ObTransState &s); -inline bool ObMysqlTransact::is_in_trans(ObTransState &s) -{ - // if a trans is commit, the state will be set to TRANSACTION_COMPLETE, - // so if current state is CMD_COMPLETE, it means that we have send a sql successfully and - // the trans has not commit, that is to say "in trans" - // so far, there are three cases NOT in trans: - // 1. handshake response (login packet) need pl lookup - // 2. the first sql of one transaction - // 3. the second sql of one transaction, if the first sql is 'begin' or 'start transaction' - return (!s.is_auth_request_ - && ObMysqlTransact::CMD_COMPLETE == s.current_.state_ - && !s.is_hold_start_trans_); -} - inline bool ObMysqlTransact::is_user_trans_complete(ObTransState &s) { return (!s.is_trans_first_request_ @@ -998,7 +1017,7 @@ inline bool ObMysqlTransact::is_user_trans_complete(ObTransState &s) inline bool ObMysqlTransact::is_bad_route_request(ObTransState &s) { bool bret = false; - if (s.mysql_config_params_->enable_bad_route_reject_ && s.is_hold_start_trans_) { + if (s.mysql_config_params_->enable_bad_route_reject_ && (s.is_hold_start_trans_ || s.is_hold_xa_start_)) { obutils::ObSqlParseResult &parse_result = s.trans_info_.client_request_.get_parse_result(); const ObString &table_name = parse_result.get_table_name(); bret = table_name.empty(); @@ -1036,11 +1055,6 @@ inline int64_t ObMysqlTransact::get_max_connect_attempts_from_replica(const int6 return (replica_size * 2 + 1); } -inline int64_t ObMysqlTransact::get_max_connect_attempts(ObTransState &s) -{ - return std::max(s.mysql_config_params_->connect_observer_max_retries_, - get_max_connect_attempts_from_replica(s.pll_info_.replica_size())); -} inline bool ObMysqlTransact::is_in_auth_process(ObTransState &s) { @@ -1087,6 +1101,11 @@ inline int64_t milestone_diff(const ObHRTime start, const ObHRTime end) return (start > 0 && end > start) ? (end - start) : 0; } +inline void ObMysqlTransact::ObPartitionLookupInfo::reset_consistency() +{ + route_.set_consistency_level(common::INVALID_CONSISTENCY); +} + inline void ObMysqlTransact::ObPartitionLookupInfo::reset_pl() { route_.reset(); @@ -1129,11 +1148,16 @@ inline void ObMysqlTransact::update_sql_cmd(ObTransState &s) case SERVER_SEND_ALL_SESSION_VARS: case SERVER_SEND_SESSION_VARS: - case SERVER_SEND_LAST_INSERT_ID: + case SERVER_SEND_SESSION_USER_VARS: case SERVER_SEND_START_TRANS: case SERVER_SEND_TEXT_PS_PREPARE: s.trans_info_.sql_cmd_ = obmysql::OB_MYSQL_COM_QUERY; break; + + case SERVER_SEND_XA_START: + PROXY_TXN_LOG(DEBUG, "[ObMysqlTransact::update_sql_cmd] set s.trans_info_.sql_cmd OB_MYSQL_COM_STMT_PREPARE_EXECUTE for sync xa start"); + s.trans_info_.sql_cmd_ = obmysql::OB_MYSQL_COM_STMT_PREPARE_EXECUTE; + break; case SERVER_SEND_PREPARE: s.trans_info_.sql_cmd_ = obmysql::OB_MYSQL_COM_STMT_PREPARE; @@ -1177,9 +1201,23 @@ inline common::ObString ObMysqlTransact::get_retry_status_string(const ObSSRetry return common::ObString::make_string(str); } -inline int64_t ObMysqlTransact::build_addr_from_ip_port(const uint32_t ip, const uint16_t port) +inline common::ObString ObMysqlTransact::get_pl_lookup_state_string(const ObPLLookupState state) { - return (static_cast(port) << 32) | ip; + const char *str = ""; + switch (state) { + case NEED_PL_LOOKUP: + str = "NEED_PL_LOOKUP"; + break; + case USE_LAST_SERVER_SESSION: + str = "USE_LAST_SERVER_SESSION"; + break; + case USE_COORDINATOR_SESSION: + str = "USE_COORDINATOR_SESSION"; + break; + default: + str = "UNKNOWN"; + } + return common::ObString::make_string(str); } inline void ObMysqlTransact::get_ip_port_from_addr(const int64_t addr, uint32_t &ip, uint16_t &port) @@ -1190,6 +1228,28 @@ inline void ObMysqlTransact::get_ip_port_from_addr(const int64_t addr, uint32_t port = static_cast((addr & PORT_MASK) >> 32); } +inline bool ObMysqlTransact::is_addr_logonly(const net::ObIpEndpoint &addr, const ObTenantServer *ts) +{ + bool ret = false; + if (OB_ISNULL(ts)) { + ret = false; + } else { + int64_t cnt = ts->server_count_; + ObAddr tmp_addr; + tmp_addr.reset(); + tmp_addr.set_sockaddr(addr.sa_); + for (int64_t i = 0; i < cnt; ++i) { + if (tmp_addr == ts->get_replica_location(i)->server_ + && (common::REPLICA_TYPE_LOGONLY == ts->get_replica_location(i)->get_replica_type() + || common::REPLICA_TYPE_ENCRYPTION_LOGONLY == ts->get_replica_location(i)->get_replica_type())) { + ret = true; + break; + } + } + } + return ret; +} + } // end of namespace proxy } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/proxy/mysql/ob_mysql_tunnel.cpp b/src/obproxy/proxy/mysql/ob_mysql_tunnel.cpp index 7cdcf90b4..fa39e1571 100644 --- a/src/obproxy/proxy/mysql/ob_mysql_tunnel.cpp +++ b/src/obproxy/proxy/mysql/ob_mysql_tunnel.cpp @@ -588,7 +588,8 @@ inline int ObMysqlTunnel::producer_handler_packet(int event, ObMysqlTunnelProduc case VC_EVENT_READ_COMPLETE: case MYSQL_TUNNEL_EVENT_PRECOMPLETE: case VC_EVENT_INACTIVITY_TIMEOUT: - case VC_EVENT_EOS: { + case VC_EVENT_EOS: + case VC_EVENT_DETECT_SERVER_DEAD: { p.packet_analyzer_.last_server_event_ = event; // If we couldn't understand the encoding, return an error @@ -765,6 +766,7 @@ bool ObMysqlTunnel::producer_handler(int event, ObMysqlTunnelProducer &p) case VC_EVENT_ERROR: case VC_EVENT_ACTIVE_TIMEOUT: case VC_EVENT_INACTIVITY_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: case MYSQL_TUNNEL_EVENT_CONSUMER_DETACH: p.alive_ = false; p.bytes_read_ = p.read_vio_->ndone_; @@ -915,7 +917,8 @@ bool ObMysqlTunnel::consumer_handler(int event, ObMysqlTunnelConsumer &c) case VC_EVENT_EOS: case VC_EVENT_ERROR: case VC_EVENT_ACTIVE_TIMEOUT: - case VC_EVENT_INACTIVITY_TIMEOUT: { + case VC_EVENT_INACTIVITY_TIMEOUT: + case VC_EVENT_DETECT_SERVER_DEAD: { c.alive_ = false; c.bytes_written_ = c.write_vio_ ? c.write_vio_->ndone_ : 0; diff --git a/src/obproxy/proxy/mysql/ob_prepare_statement_struct.cpp b/src/obproxy/proxy/mysql/ob_prepare_statement_struct.cpp index ab9252373..e60c7380a 100644 --- a/src/obproxy/proxy/mysql/ob_prepare_statement_struct.cpp +++ b/src/obproxy/proxy/mysql/ob_prepare_statement_struct.cpp @@ -96,10 +96,8 @@ DEF_TO_STRING(ObTextPsNameEntry) return pos; } -void ObBasePsEntry::destroy() { - if (NULL != ps_entry_cache_) { - ps_entry_cache_->delete_base_ps_entry(this); - } +void ObBasePsEntry::destroy() +{ base_ps_parse_result_.reset(); } @@ -125,16 +123,22 @@ int ObPsIdAddrs::alloc_ps_id_addrs(uint32_t ps_id, const struct sockaddr &addr, int ObPsIdAddrs::add_addr(const struct sockaddr &socket_addr) { int ret = OB_SUCCESS; net::ObIpEndpoint addr(socket_addr); - if (OB_FAIL(addrs_.set_refactored(addr))) { + if (OB_FAIL(addrs_.push_back(addr))) { LOG_WARN("set refactored failed", K(addr), K(ret)); } return ret; } + int ObPsIdAddrs::remove_addr(const struct sockaddr &socket_addr) { int ret = OB_SUCCESS; net::ObIpEndpoint addr(socket_addr); - if (OB_FAIL(addrs_.erase_refactored(addr))) { - LOG_WARN("set refactored failed", K(addr), K(ret)); + for(int64_t i = 0; OB_SUCC(ret) && i < addrs_.count(); i++) { + if (addr == addrs_.at(i)) { + if (OB_FAIL(addrs_.remove(i))) { + LOG_WARN("fail to remove", K(i), K(ret)); + } + break; + } } return ret; } @@ -217,40 +221,6 @@ int ObPsSqlMeta::set_param_type(const char *param_type, int64_t param_type_len) return ret; } -int ObPsEntry::alloc_and_init_ps_entry(const ObString &ps_sql, - const ObSqlParseResult &parse_result, - ObPsEntry *&entry) -{ - int ret = OB_SUCCESS; - int64_t alloc_size = 0; - char *buf = NULL; - - int64_t obj_size = sizeof(ObPsEntry); - int64_t sql_len = ps_sql.length() + PARSE_EXTRA_CHAR_NUM; - - alloc_size += sizeof(ObPsEntry) + sql_len; - if (OB_ISNULL(buf = static_cast(op_fixed_mem_alloc(alloc_size)))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("fail to alloc mem for ps entry", K(alloc_size), K(ret)); - } else { - entry = new (buf) ObPsEntry(); - if (OB_FAIL(entry->init(buf + obj_size, alloc_size - obj_size))) { - LOG_WARN("fail to init ps entry", K(ret)); - } else if (OB_FAIL(entry->set_sql(ps_sql))) { - LOG_WARN("fail to set ps sql", K(ret)); - } else { - entry->set_base_ps_parse_result(parse_result); - } - } - - if (OB_FAIL(ret) && NULL != buf) { - op_fixed_mem_free(buf, alloc_size); - entry = NULL; - alloc_size = 0; - } - return ret; -} - int ObPsEntry::init(char *buf_start, int64_t buf_len) { int ret = OB_SUCCESS; @@ -287,9 +257,17 @@ int ObPsEntry::set_sql(const ObString &ps_sql) return ret; } +void ObPsEntry::free() +{ + if (NULL != ps_entry_cache_) { + ps_entry_cache_->delete_base_ps_entry(this); + } + destroy(); +} + void ObPsEntry::destroy() { - LOG_INFO("ps entry will be destroyed", KPC(this)); + LOG_DEBUG("ps entry will be destroyed", KPC(this)); if (OB_LIKELY(is_inited_)) { ObBasePsEntry::destroy(); is_inited_ = false; @@ -300,96 +278,12 @@ void ObPsEntry::destroy() } } -void ObBasePsEntryCache::destroy() -{ - ObBasePsEntryMap::iterator last = base_ps_map_.end(); - ObBasePsEntryMap::iterator tmp_iter; - for (ObBasePsEntryMap::iterator base_ps_iter = base_ps_map_.begin(); base_ps_iter != last;) { - tmp_iter = base_ps_iter; - ++base_ps_iter; - tmp_iter->destroy(); - } - base_ps_map_.reset(); -} - -int init_ps_entry_cache_for_thread() -{ - int ret = OB_SUCCESS; - const int64_t event_thread_count = g_event_processor.thread_count_for_type_[ET_CALL]; - for (int64_t i = 0; i < event_thread_count && OB_SUCC(ret); ++i) { - if (OB_FAIL(init_ps_entry_cache_for_one_thread(i))) { - PROXY_NET_LOG(WARN, "fail to new ObBasePsEntryCache", K(i), K(ret)); - } - } - return ret; -} - -int init_text_ps_entry_cache_for_thread() -{ - int ret = OB_SUCCESS; - const int64_t event_thread_count = g_event_processor.thread_count_for_type_[ET_CALL]; - for (int64_t i = 0; i < event_thread_count && OB_SUCC(ret); ++i) { - if (OB_FAIL(init_text_ps_entry_cache_for_one_thread(i))) { - PROXY_NET_LOG(WARN, "fail to new ObBasePsEntryCache", K(i), K(ret)); - } - } - return ret; -} - -int init_ps_entry_cache_for_one_thread(int64_t index) +void ObGlobalPsEntry::free() { - int ret = OB_SUCCESS; - if (OB_ISNULL(g_event_processor.event_thread_[ET_CALL][index]->ps_entry_cache_ - = new (std::nothrow) ObBasePsEntryCache())) { - ret = OB_ALLOCATE_MEMORY_FAILED; - PROXY_NET_LOG(WARN, "fail to new ObBasePsEntryCache", K(index), K(ret)); - } - return ret; -} - -int init_text_ps_entry_cache_for_one_thread(int64_t index) -{ - int ret = OB_SUCCESS; - if (OB_ISNULL(g_event_processor.event_thread_[ET_CALL][index]->text_ps_entry_cache_ - = new (std::nothrow) ObBasePsEntryCache())) { - ret = OB_ALLOCATE_MEMORY_FAILED; - PROXY_NET_LOG(WARN, "fail to new ObBasePsEntryCache", K(index), K(ret)); - } - return ret; -} - -int ObTextPsEntry::alloc_and_init_text_ps_entry(const ObString &text_ps_sql, - const ObSqlParseResult &parse_result, - ObTextPsEntry *&entry) -{ - int ret = OB_SUCCESS; - int64_t alloc_size = 0; - char *buf = NULL; - - int64_t obj_size = sizeof(ObTextPsEntry); - int64_t sql_len = text_ps_sql.length() + PARSE_EXTRA_CHAR_NUM; - - alloc_size = obj_size + sql_len; - if (OB_ISNULL(buf = static_cast(op_fixed_mem_alloc(alloc_size)))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("fail to alloc mem for text ps entry", K(alloc_size), K(ret)); - } else { - entry = new (buf) ObTextPsEntry(); - if (OB_FAIL(entry->init(buf + obj_size, alloc_size - obj_size, text_ps_sql))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("fail to alloc mem for text ps entry", K(alloc_size), K(ret)); - } else { - entry->set_base_ps_parse_result(parse_result); - } - } - - if (OB_FAIL(ret) && NULL != buf) { - op_fixed_mem_free(buf, alloc_size); - entry = NULL; - alloc_size = 0; + LOG_DEBUG("global ps entry will be destroyed", KPC(this)); + if (NULL != ps_entry_cache_) { + ps_entry_cache_->delete_base_ps_entry(this); } - - return ret; } int ObTextPsEntry::init(char *buf_start, int64_t buf_len, const ObString &text_ps_sql) @@ -419,6 +313,14 @@ int ObTextPsEntry::init(char *buf_start, int64_t buf_len, const ObString &text_p return ret; } +void ObTextPsEntry::free() +{ + if (NULL != ps_entry_cache_) { + ps_entry_cache_->delete_base_ps_entry(this); + } + destroy(); +} + void ObTextPsEntry::destroy() { LOG_INFO("text ps entry will be destroyed", KPC(this)); @@ -432,6 +334,14 @@ void ObTextPsEntry::destroy() } } +void ObGlobalTextPsEntry::free() +{ + LOG_INFO("global text ps entry will be destroyed", KPC(this)); + if (NULL != ps_entry_cache_) { + ps_entry_cache_->delete_base_ps_entry(this); + } +} + int ObTextPsNameEntry::alloc_text_ps_name_entry(const ObString &text_ps_name, ObTextPsEntry *text_ps_entry, ObTextPsNameEntry *&text_ps_name_entry) @@ -466,6 +376,99 @@ void ObTextPsNameEntry::destroy() op_fixed_mem_free(this, total_len); } +void ObBasePsEntryThreadCache::delete_base_ps_entry(ObBasePsEntry *base_ps_entry) +{ + ps_entry_thread_map_.remove(base_ps_entry); +} + +void ObBasePsEntryThreadCache::destroy() +{ + ObBasePsEntryMap::iterator last = ps_entry_thread_map_.end(); + ObBasePsEntryMap::iterator tmp_iter; + for (ObBasePsEntryMap::iterator base_ps_iter = ps_entry_thread_map_.begin(); base_ps_iter != last;) { + tmp_iter = base_ps_iter; + ++base_ps_iter; + tmp_iter->destroy(); + } + ps_entry_thread_map_.reset(); +} + +void ObBasePsEntryGlobalCache::delete_base_ps_entry(ObBasePsEntry *base_ps_entry) +{ + common::DRWLock::WRLockGuard guard(lock_); + ps_entry_global_map_.remove(base_ps_entry); +} + +void ObBasePsEntryGlobalCache::destroy() +{ + ObBasePsEntryGlobalMap::iterator last = ps_entry_global_map_.end(); + ObBasePsEntryGlobalMap::iterator tmp_iter; + for (ObBasePsEntryGlobalMap::iterator base_ps_iter = ps_entry_global_map_.begin(); base_ps_iter != last;) { + tmp_iter = base_ps_iter; + ++base_ps_iter; + tmp_iter->destroy(); + } + ps_entry_global_map_.reset(); +} + +int init_ps_entry_cache_for_thread() +{ + int ret = OB_SUCCESS; + const int64_t event_thread_count = g_event_processor.thread_count_for_type_[ET_CALL]; + for (int64_t i = 0; i < event_thread_count && OB_SUCC(ret); ++i) { + if (OB_FAIL(init_ps_entry_cache_for_one_thread(i))) { + PROXY_NET_LOG(WARN, "fail to new ObBasePsEntryThreadCache", K(i), K(ret)); + } + } + return ret; +} + +int init_text_ps_entry_cache_for_thread() +{ + int ret = OB_SUCCESS; + const int64_t event_thread_count = g_event_processor.thread_count_for_type_[ET_CALL]; + for (int64_t i = 0; i < event_thread_count && OB_SUCC(ret); ++i) { + if (OB_FAIL(init_text_ps_entry_cache_for_one_thread(i))) { + PROXY_NET_LOG(WARN, "fail to new ObBasePsEntryThreadCache", K(i), K(ret)); + } + } + return ret; +} + +int init_ps_entry_cache_for_one_thread(int64_t index) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(g_event_processor.event_thread_[ET_CALL][index]->ps_entry_cache_ + = new (std::nothrow) ObBasePsEntryThreadCache())) { + ret = OB_ALLOCATE_MEMORY_FAILED; + PROXY_NET_LOG(WARN, "fail to new ObBasePsEntryThreadCache", K(index), K(ret)); + } + return ret; +} + +int init_text_ps_entry_cache_for_one_thread(int64_t index) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(g_event_processor.event_thread_[ET_CALL][index]->text_ps_entry_cache_ + = new (std::nothrow) ObBasePsEntryThreadCache())) { + ret = OB_ALLOCATE_MEMORY_FAILED; + PROXY_NET_LOG(WARN, "fail to new ObBasePsEntryThreadCache", K(index), K(ret)); + } + return ret; +} + +ObBasePsEntryGlobalCache &get_global_ps_entry_cache() +{ + static ObBasePsEntryGlobalCache ps_entry_cache; + return ps_entry_cache; +} + +ObBasePsEntryGlobalCache &get_global_text_ps_entry_cache() +{ + static ObBasePsEntryGlobalCache text_ps_entry_cache; + return text_ps_entry_cache; +} + } // end of namespace proxy } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/proxy/mysql/ob_prepare_statement_struct.h b/src/obproxy/proxy/mysql/ob_prepare_statement_struct.h index 3e56d5344..83fa44aa0 100644 --- a/src/obproxy/proxy/mysql/ob_prepare_statement_struct.h +++ b/src/obproxy/proxy/mysql/ob_prepare_statement_struct.h @@ -45,19 +45,9 @@ class ObPsIdAddrs static const int BUCKET_SIZE = 8; static const int NODE_NUM = 8; - // use SimpleAllocer to save mem - typedef common::hash::ObHashSet, - common::hash::equal_to, - common::hash::SimpleAllocer::AllocType, NODE_NUM> - > ADDR_HASH_SET; - ObPsIdAddrs() : ps_id_(0), addrs_() { - addrs_.create(BUCKET_SIZE); } ObPsIdAddrs(uint32_t ps_id) : ps_id_(ps_id), addrs_() { - addrs_.create(BUCKET_SIZE); } ~ObPsIdAddrs() {}; @@ -65,13 +55,12 @@ class ObPsIdAddrs void destroy(); int add_addr(const struct sockaddr &socket_addr); int remove_addr(const struct sockaddr &socket_addr); - ADDR_HASH_SET &get_addrs() { return addrs_; } + ObIArray &get_addrs() { return addrs_; } int64_t to_string(char *buf, const int64_t buf_len) const; public: uint32_t ps_id_; // client ps id - ADDR_HASH_SET addrs_; - + ObSEArray addrs_; LINK(ObPsIdAddrs, ps_id_addrs_link_); }; @@ -115,8 +104,7 @@ class ObBasePsEntry : public common::ObSharedRefCount const common::ObString &get_base_ps_sql() { return base_ps_sql_; } - virtual void free() { destroy(); } - + virtual void free() {} virtual void destroy(); public: @@ -189,13 +177,14 @@ class ObPsEntry : public ObBasePsEntry ObPsEntry() : ObBasePsEntry() {} ~ObPsEntry() {} + template static int alloc_and_init_ps_entry(const common::ObString &ps_sql, const obutils::ObSqlParseResult &parse_result, - ObPsEntry *&entry); + T *&entry); int init(char *buf_start, int64_t buf_len); - void destroy(); + virtual void free(); + virtual void destroy(); int set_sql(const common::ObString &ps_sql); - int64_t to_string(char *buf, const int64_t buf_len) const; private: @@ -205,6 +194,61 @@ class ObPsEntry : public ObBasePsEntry DISALLOW_COPY_AND_ASSIGN(ObPsEntry); }; +class ObGlobalPsEntry : public ObPsEntry +{ +public: + ObGlobalPsEntry() : ObPsEntry() {} + ~ObGlobalPsEntry() {} + virtual void free(); + template + static int alloc_and_init_ps_entry(const common::ObString &ps_sql, + const obutils::ObSqlParseResult &parse_result, + T *&entry); +}; + +template +int ObGlobalPsEntry::alloc_and_init_ps_entry(const ObString &ps_sql, + const obutils::ObSqlParseResult &parse_result, + T *&entry) +{ + return ObPsEntry::alloc_and_init_ps_entry(ps_sql, parse_result, entry); +} + +template +int ObPsEntry::alloc_and_init_ps_entry(const ObString &ps_sql, + const obutils::ObSqlParseResult &parse_result, + T *&entry) +{ + int ret = OB_SUCCESS; + int64_t alloc_size = 0; + char *buf = NULL; + + int64_t obj_size = sizeof(T); + int64_t sql_len = ps_sql.length() + PARSE_EXTRA_CHAR_NUM; + + alloc_size += sizeof(T) + sql_len; + if (OB_ISNULL(buf = static_cast(op_fixed_mem_alloc(alloc_size)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + PROXY_SM_LOG(WARN, "fail to alloc mem for ps entry", K(alloc_size), K(ret)); + } else { + entry = new (buf) T(); + if (OB_FAIL(entry->init(buf + obj_size, alloc_size - obj_size))) { + PROXY_SM_LOG(WARN, "fail to init ps entry", K(ret)); + } else if (OB_FAIL(entry->set_sql(ps_sql))) { + PROXY_SM_LOG(WARN, "fail to set ps sql", K(ret)); + } else { + entry->set_base_ps_parse_result(parse_result); + } + } + + if (OB_FAIL(ret) && NULL != buf) { + op_fixed_mem_free(buf, alloc_size); + entry = NULL; + alloc_size = 0; + } + return ret; +} + // stored in client session info class ObPsIdEntry { @@ -212,7 +256,6 @@ class ObPsIdEntry ObPsIdEntry() : ps_id_(0), ps_entry_(NULL), ps_meta_() {} ObPsIdEntry(uint32_t client_id, ObPsEntry *entry) : ps_id_(client_id), ps_entry_(entry) { - ps_entry_->inc_ref(); } ~ObPsIdEntry() {} @@ -268,20 +311,77 @@ class ObPsIdPair class ObTextPsEntry : public ObBasePsEntry { public: - ObTextPsEntry() : ObBasePsEntry() {} - ~ObTextPsEntry() { destroy(); } + ObTextPsEntry() : ObBasePsEntry() {} + ~ObTextPsEntry() { } - static int alloc_and_init_text_ps_entry(const common::ObString &sql, - const obutils::ObSqlParseResult &parse_result, - ObTextPsEntry *&entry); + template + static int alloc_and_init_ps_entry(const common::ObString &sql, + const obutils::ObSqlParseResult &parse_result, + T *&entry); int init(char *buf_start, int64_t buf_len, const common::ObString &text_ps_sql); - void destroy(); + virtual void free(); + virtual void destroy(); int64_t to_string(char *buf, const int64_t buf_len) const; private: DISALLOW_COPY_AND_ASSIGN(ObTextPsEntry); }; +template +int ObTextPsEntry::alloc_and_init_ps_entry(const ObString &text_ps_sql, + const obutils::ObSqlParseResult &parse_result, + T *&entry) +{ + int ret = OB_SUCCESS; + int64_t alloc_size = 0; + char *buf = NULL; + + int64_t obj_size = sizeof(T); + int64_t sql_len = text_ps_sql.length() + PARSE_EXTRA_CHAR_NUM; + + alloc_size = obj_size + sql_len; + if (OB_ISNULL(buf = static_cast(op_fixed_mem_alloc(alloc_size)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + PROXY_SM_LOG(WARN, "fail to alloc mem for text ps entry", K(alloc_size), K(ret)); + } else { + entry = new (buf) T(); + if (OB_FAIL(entry->init(buf + obj_size, alloc_size - obj_size, text_ps_sql))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + PROXY_SM_LOG(WARN, "fail to alloc mem for text ps entry", K(alloc_size), K(ret)); + } else { + entry->set_base_ps_parse_result(parse_result); + } + } + + if (OB_FAIL(ret) && NULL != buf) { + op_fixed_mem_free(buf, alloc_size); + entry = NULL; + alloc_size = 0; + } + + return ret; +} + +class ObGlobalTextPsEntry : public ObTextPsEntry +{ +public: + ObGlobalTextPsEntry() : ObTextPsEntry() {} + ~ObGlobalTextPsEntry() {} + virtual void free(); + template + static int alloc_and_init_ps_entry(const common::ObString &sql, + const obutils::ObSqlParseResult &parse_result, + T *&entry); +}; + +template +int ObGlobalTextPsEntry::alloc_and_init_ps_entry(const ObString &sql, + const obutils::ObSqlParseResult &parse_result, + T *&entry) +{ + return ObTextPsEntry::alloc_and_init_ps_entry(sql, parse_result, entry); +} + class ObTextPsNameEntry { public: @@ -291,7 +391,6 @@ class ObTextPsNameEntry { text_ps_name_.assign_ptr(buf, static_cast(buf_len)); text_ps_entry_ = entry; - text_ps_entry_->inc_ref(); } static int alloc_text_ps_name_entry(const ObString &text_ps_name, @@ -315,13 +414,28 @@ class ObTextPsNameEntry class ObBasePsEntryCache { public: - ObBasePsEntryCache() : base_ps_map_() {} - ~ObBasePsEntryCache() { destroy(); } + ObBasePsEntryCache() {} + virtual ~ObBasePsEntryCache() { destroy(); } + virtual void destroy() {} + +public: + virtual void delete_base_ps_entry(ObBasePsEntry *base_ps_entry) { + UNUSED(base_ps_entry); + } + +private: + DISALLOW_COPY_AND_ASSIGN(ObBasePsEntryCache); +}; + +class ObBasePsEntryThreadCache : public ObBasePsEntryCache +{ +public: + ObBasePsEntryThreadCache() : ObBasePsEntryCache(), ps_entry_thread_map_() {} + ~ObBasePsEntryThreadCache() { destroy(); } void destroy(); public: static const int64_t HASH_BUCKET_SIZE = 64; - struct ObBasePsEntryHashing { typedef const common::ObString &Key; @@ -332,71 +446,210 @@ class ObBasePsEntryCache static Key key(Value const *value) { return value->base_ps_sql_; } static bool equal(Key lhs, Key rhs) { return lhs == rhs; } }; - typedef common::hash::ObBuildInHashMap ObBasePsEntryMap; public: - int get_ps_entry(const common::ObString &sql, ObPsEntry *&ps_entry) - { - int ret = common::OB_SUCCESS; - ObBasePsEntry *tmp_entry = NULL; - if (OB_FAIL(base_ps_map_.get_refactored(sql, tmp_entry))) { - //do nothing - } else { - ps_entry = static_cast(tmp_entry); - } - return ret; + template + int acquire_ps_entry(const common::ObString &sql, T *&ps_entry); + + template + int create_ps_entry(const common::ObString &sql, + const obutils::ObSqlParseResult &parse_result, + T *&ps_entry); + + template + int acquire_or_create_ps_entry(const common::ObString &sql, + const obutils::ObSqlParseResult &parse_result, + T *&ps_entry); + + void delete_base_ps_entry(ObBasePsEntry *base_ps_entry); + +private: + ObBasePsEntryMap ps_entry_thread_map_; + DISALLOW_COPY_AND_ASSIGN(ObBasePsEntryThreadCache); +}; + +template +int ObBasePsEntryThreadCache::acquire_ps_entry(const ObString &sql, T *&ps_entry) +{ + int ret = OB_SUCCESS; + ObBasePsEntry *tmp_entry = NULL; + if (OB_FAIL(ps_entry_thread_map_.get_refactored(sql, tmp_entry))) { + //do nothing + } else { + ps_entry = static_cast(tmp_entry); + ps_entry->inc_ref(); } + return ret; +} - int set_ps_entry(ObPsEntry *ps_entry) - { - ObBasePsEntry *tmp_entry = static_cast(ps_entry); - tmp_entry->set_ps_entry_cache(this); - return base_ps_map_.unique_set(tmp_entry); +template +int ObBasePsEntryThreadCache::create_ps_entry(const common::ObString &sql, + const obutils::ObSqlParseResult &parse_result, + T *&ps_entry) +{ + int ret = OB_SUCCESS; + ObBasePsEntry* tmp_ps_entry = NULL; + if (OB_FAIL(ps_entry_thread_map_.get_refactored(sql, tmp_ps_entry))) { + if (OB_HASH_NOT_EXIST == ret) { + if (OB_FAIL(T::alloc_and_init_ps_entry(sql, parse_result, ps_entry))) { + PROXY_SM_LOG(WARN, "fail to alloc and init ps entry", K(ret)); + } else if (OB_FAIL(ps_entry_thread_map_.unique_set(ps_entry))) { + PROXY_SM_LOG(WARN, "fail to add ps entry to cache", K(ret)); + if (OB_LIKELY(NULL != ps_entry)) { + ps_entry->destroy(); + ps_entry = NULL; + } + } else { + ObBasePsEntry *tmp_entry = static_cast(ps_entry); + tmp_entry->set_ps_entry_cache(this); + } + } + } else { + ps_entry = static_cast(tmp_ps_entry); } + if (OB_SUCC(ret)) { + ps_entry->inc_ref(); + } + return ret; +} - int get_text_ps_entry(const common::ObString &sql, ObTextPsEntry *&text_ps_entry) - { - int ret = common::OB_SUCCESS; - ObBasePsEntry *tmp_entry = NULL; - if (OB_FAIL(base_ps_map_.get_refactored(sql, tmp_entry))) { - //do nothing +template +int ObBasePsEntryThreadCache::acquire_or_create_ps_entry(const ObString &sql, + const obutils::ObSqlParseResult &parse_result, + T *&ps_entry) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(acquire_ps_entry(sql, ps_entry))) { + if (OB_HASH_NOT_EXIST == ret) { + if (OB_FAIL(create_ps_entry(sql, parse_result, ps_entry))) { + PROXY_SM_LOG(WARN, "fail to create ps entry", K(sql), K(ret)); + } else { + PROXY_SM_LOG(DEBUG, "succ to create ps entry", K(sql), KPC(ps_entry)); + } } else { - text_ps_entry = static_cast(tmp_entry); + PROXY_SM_LOG(WARN, "fail to get ps entry", K(sql), K(ret)); } - return ret; } + return ret; +} + +class ObBasePsEntryGlobalCache : public ObBasePsEntryCache +{ +public: + ObBasePsEntryGlobalCache() : ObBasePsEntryCache(), lock_(), ps_entry_global_map_() {} + ~ObBasePsEntryGlobalCache() { destroy(); } + void destroy(); - int set_text_ps_entry(ObTextPsEntry *text_ps_entry) +public: + static const int64_t HASH_BUCKET_SIZE = 64; + struct ObBasePsEntryHashing { - ObBasePsEntry *tmp_entry = text_ps_entry; - tmp_entry->set_ps_entry_cache(this); - return base_ps_map_.unique_set(tmp_entry); + typedef const common::ObString &Key; + typedef ObBasePsEntry Value; + typedef ObDLList(ObBasePsEntry, base_ps_entry_link_) ListHead; + + static uint64_t hash(Key key) { return key.hash(); } + static Key key(Value const *value) { return value->base_ps_sql_; } + static bool equal(Key lhs, Key rhs) { return lhs == rhs; } + static int64_t inc_ref(Value* value) { return ATOMIC_AAF(&value->ref_count_, 1); } + static bool bcas_ref(Value* value, int64_t cmpv, int64_t newv) { return ATOMIC_BCAS(&value->ref_count_, cmpv, newv); } + static int64_t get_ref(Value* value) { return ATOMIC_LOAD(&value->ref_count_); } + static void destroy(Value* value) { value->destroy(); } + }; + typedef common::hash::ObBuildInHashMapForRefCount ObBasePsEntryGlobalMap; + +public: + template + int acquire_ps_entry(const common::ObString &sql, T *&ps_entry); + + template + int create_ps_entry(const common::ObString &sql, + const obutils::ObSqlParseResult &parse_result, + T *&ps_entry); + + template + int acquire_or_create_ps_entry(const common::ObString &sql, + const obutils::ObSqlParseResult &parse_result, + T *&ps_entry); + + void delete_base_ps_entry(ObBasePsEntry *base_ps_entry); + +private: + common::DRWLock lock_; + ObBasePsEntryGlobalMap ps_entry_global_map_; + DISALLOW_COPY_AND_ASSIGN(ObBasePsEntryGlobalCache); +}; + +template +int ObBasePsEntryGlobalCache::acquire_ps_entry(const ObString &sql, T *&ps_entry) +{ + int ret = OB_SUCCESS; + common::DRWLock::RDLockGuard guard(lock_); + ObBasePsEntry *tmp_entry = NULL; + if (OB_FAIL(ps_entry_global_map_.get_refactored(sql, tmp_entry))) { + //do nothing + } else { + ps_entry = static_cast(tmp_entry); } + return ret; +} - int delete_text_ps_entry(ObTextPsEntry *text_ps_entry) - { - if (NULL != text_ps_entry) { - base_ps_map_.remove(text_ps_entry->base_ps_sql_); - text_ps_entry->destroy(); +template +int ObBasePsEntryGlobalCache::create_ps_entry(const common::ObString &sql, + const obutils::ObSqlParseResult &parse_result, + T *&ps_entry) +{ + int ret = OB_SUCCESS; + DRWLock::WRLockGuard guard(lock_); + ObBasePsEntry* tmp_ps_entry = NULL; + if (OB_FAIL(ps_entry_global_map_.get_refactored(sql, tmp_ps_entry))) { + if (OB_HASH_NOT_EXIST == ret) { + if (OB_FAIL(T::alloc_and_init_ps_entry(sql, parse_result, ps_entry))) { + PROXY_SM_LOG(WARN, "fail to alloc and init ps entry", K(ret)); + } else if (OB_FAIL(ps_entry_global_map_.unique_set(ps_entry))) { + PROXY_SM_LOG(WARN, "fail to add ps entry to cache", K(ret)); + if (OB_LIKELY(NULL != ps_entry)) { + ps_entry->destroy(); + ps_entry = NULL; + } + } else { + ObBasePsEntry *tmp_entry = static_cast(ps_entry); + tmp_entry->set_ps_entry_cache(this); + } } - return common::OB_SUCCESS; + } else { + ps_entry = static_cast(tmp_ps_entry); } + return ret; +} - void delete_base_ps_entry(ObBasePsEntry *base_ps_entry) - { - base_ps_map_.remove(base_ps_entry); +template +int ObBasePsEntryGlobalCache::acquire_or_create_ps_entry(const ObString &sql, + const obutils::ObSqlParseResult &parse_result, + T *&ps_entry) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(acquire_ps_entry(sql, ps_entry))) { + if (OB_HASH_NOT_EXIST == ret) { + if (OB_FAIL(create_ps_entry(sql, parse_result, ps_entry))) { + PROXY_SM_LOG(WARN, "fail to create ps entry", K(sql), K(ret)); + } else { + PROXY_SM_LOG(DEBUG, "succ to create ps entry", K(sql), KPC(ps_entry)); + } + } else { + PROXY_SM_LOG(WARN, "fail to get ps entry", K(sql), K(ret)); + } } - -private: - ObBasePsEntryMap base_ps_map_; - DISALLOW_COPY_AND_ASSIGN(ObBasePsEntryCache); -}; + return ret; +} int init_ps_entry_cache_for_thread(); int init_ps_entry_cache_for_one_thread(int64_t index); int init_text_ps_entry_cache_for_thread(); int init_text_ps_entry_cache_for_one_thread(int64_t index); +ObBasePsEntryGlobalCache &get_global_ps_entry_cache(); +ObBasePsEntryGlobalCache &get_global_text_ps_entry_cache(); } // end of namespace proxy } // end of namespace obproxy diff --git a/src/obproxy/proxy/mysqllib/ob_2_0_protocol_struct.h b/src/obproxy/proxy/mysqllib/ob_2_0_protocol_struct.h index a5b9251c7..c0904b971 100644 --- a/src/obproxy/proxy/mysqllib/ob_2_0_protocol_struct.h +++ b/src/obproxy/proxy/mysqllib/ob_2_0_protocol_struct.h @@ -15,6 +15,8 @@ #include "proxy/mysqllib/ob_mysql_common_define.h" #include "obutils/ob_proxy_buf.h" +#include "lib/container/ob_se_array.h" +#include "lib/string/ob_sql_string.h" namespace oceanbase { @@ -54,6 +56,7 @@ union Ob20ProtocolFlags bool is_extra_info_exist() const { return 1 == st_flags_.OB_EXTRA_INFO_EXIST; } bool is_last_packet() const { return 1 == st_flags_.OB_IS_LAST_PACKET; } bool is_new_extra_info() const { return 1 == st_flags_.OB_IS_NEW_EXTRA_INFO; } + bool is_trans_internal_routing() const { return 1 == st_flags_.OB_IS_TRANS_INTERNAL_ROUTING; } uint32_t flags_; struct Protocol20Flags @@ -62,40 +65,103 @@ union Ob20ProtocolFlags uint32_t OB_IS_LAST_PACKET: 1; uint32_t OB_IS_PROXY_REROUTE: 1; uint32_t OB_IS_NEW_EXTRA_INFO: 1; - uint32_t OB_FLAG_RESERVED_NOT_USE: 28; + uint32_t OB_IS_WEAK_READ: 1; + uint32_t OB_IS_TRANS_INTERNAL_ROUTING: 1; + uint32_t OB_FLAG_RESERVED_NOT_USE: 26; } st_flags_; }; +enum SessionSyncInfoType { + //SESSION_SYNC_USER_VAR, // for user variables + SESSION_SYNC_APPLICATION_INFO = 0, // for application info + SESSION_SYNC_APPLICATION_CONTEXT = 1, // for app ctx + SESSION_SYNC_CLIENT_ID = 2, // for client identifier + SESSION_SYNC_CONTROL_INFO = 3, // for full trace link control info + SESSION_SYNC_SYS_VAR = 4, // for system variables + SESSION_SYNC_TXN_STATIC_INFO = 5, // 5: basic txn info + SESSION_SYNC_TXN_DYNAMIC_INFO = 6, // 6: txn dynamic info + SESSION_SYNC_TXN_PARTICIPANTS_INFO = 7, // 7: txn dynamic info + SESSION_SYNC_TXN_EXTRA_INFO = 8, // 8: txn dynamic info + SESSION_SYNC_MAX_TYPE, +}; + struct Ob20ExtraInfo { public: - // for session info sync mechanism - bool is_exist_sess_info_; - obutils::ObVariableLenBuffer<32> extra_info_buf_; // save total extra info kv - obutils::ObVariableLenBuffer<32> sess_info_buf_; // save only session info - common::ObString sess_info_; - - // ob20 info - uint32_t extra_len_; // extra len in ob20 payload, if the flag.exist_extra_info - -public: - Ob20ExtraInfo() : is_exist_sess_info_(false), sess_info_(), extra_len_(0) {} + Ob20ExtraInfo() : is_exist_sess_info_(false), extra_info_buf_(), sess_info_buf_(), + sess_info_count_(0), extra_len_(0), sess_info_length_(), + sess_info_cur_idx_(0), sess_info_offset_(0) {} ~Ob20ExtraInfo() {} void reset() { is_exist_sess_info_ = false; extra_info_buf_.reset(); sess_info_buf_.reset(); - sess_info_.reset(); + sess_info_count_ = 0; extra_len_ = 0; + + sess_info_length_.reset(); + sess_info_cur_idx_ = 0; + sess_info_offset_ = 0; } - inline bool exist_sess_info() const { return is_exist_sess_info_; } - inline common::ObString get_sess_info() const { return sess_info_; } - - TO_STRING_KV(K_(is_exist_sess_info), K_(sess_info), K_(extra_len)); + inline uint32_t get_sess_info_count() { return sess_info_count_; } + inline int get_next_sess_info(common::ObString &sess_info); + void reset_sess_info_iterate_idx() { + sess_info_cur_idx_ = 0; + sess_info_offset_ = 0; + } + int add_sess_info_buf(const char *str, const int64_t len); + TO_STRING_KV(K_(is_exist_sess_info), K_(sess_info_count), K_(extra_len)); +public: + // for session info sync mechanism + bool is_exist_sess_info_; + obutils::ObVariableLenBuffer<32> extra_info_buf_; // save last packet extra info kv + common::ObSqlString sess_info_buf_; // save all sess info + uint32_t sess_info_count_; + uint32_t extra_len_; // extra len in ob20 payload, if the flag.exist_extra_info + +private: + // sess info iterator info + common::ObSEArray sess_info_length_; + uint32_t sess_info_cur_idx_; + uint64_t sess_info_offset_; }; +int Ob20ExtraInfo::get_next_sess_info(common::ObString &sess_info) +{ + sess_info.reset(); + int ret = common::OB_SUCCESS; + uint64_t length = sess_info_length_.at(sess_info_cur_idx_); + uint64_t buf_length = sess_info_buf_.length(); + if (sess_info_offset_ + length > buf_length) { + ret = common::OB_ERR_UNEXPECTED; + PROXY_LOG(WARN, "unexpected length of sess info buffer", K(ret), K(sess_info_offset_), K(length)); + } else { + sess_info.assign_ptr(sess_info_buf_.ptr() + sess_info_offset_, static_cast(length)); + sess_info_offset_ += length; + sess_info_cur_idx_ ++; + } + return ret; +} + +int Ob20ExtraInfo::add_sess_info_buf(const char *value, const int64_t len) +{ + int ret = common::OB_SUCCESS; + if (OB_UNLIKELY(NULL == value || 0 >= len)) { + ret = common::OB_INVALID_ARGUMENT; + PROXY_LOG(WARN, "invalid argument", K(value), K(len), K(ret)); + } else if (OB_FAIL(sess_info_buf_.append(value, len))) { + PROXY_LOG(WARN, "fail to append sess info buf", K(value), K(len), K(ret)); + } else if (OB_FAIL(sess_info_length_.push_back(len))) { + PROXY_LOG(WARN, "fail to record sess info buf length", K(ret)); + } else { + is_exist_sess_info_ = true; + sess_info_count_++; + } + return ret; +} + class Ob20ProtocolHeader { public: @@ -139,13 +205,22 @@ class Ob20ProtocolHeader // used for transfer function argument class Ob20ProtocolHeaderParam { public: - Ob20ProtocolHeaderParam() : connection_id_(0), request_id_(0), compressed_seq_(0), pkt_seq_(0), - is_last_packet_(false), is_need_reroute_(false), is_new_extra_info_(false) {} + Ob20ProtocolHeaderParam() : connection_id_(0), + request_id_(0), + compressed_seq_(0), + pkt_seq_(0), + is_last_packet_(false), + is_weak_read_(false), + is_need_reroute_(false), + is_new_extra_info_(false), + is_trans_internal_routing_(false) {} Ob20ProtocolHeaderParam(uint32_t conn_id, uint32_t req_id, uint8_t compressed_seq, uint8_t pkt_seq, - bool is_last_packet, bool is_need_reroute, bool is_new_extra_info) + bool is_last_packet, bool is_weak_read, bool is_need_reroute, + bool is_new_extra_info, bool is_trans_internal_routing) : connection_id_(conn_id), request_id_(req_id), compressed_seq_(compressed_seq), - pkt_seq_(pkt_seq), is_last_packet_(is_last_packet), is_need_reroute_(is_need_reroute), - is_new_extra_info_(is_new_extra_info) {} + pkt_seq_(pkt_seq), is_last_packet_(is_last_packet), + is_weak_read_(is_weak_read), is_need_reroute_(is_need_reroute), + is_new_extra_info_(is_new_extra_info), is_trans_internal_routing_(is_trans_internal_routing) {} ~Ob20ProtocolHeaderParam() {} Ob20ProtocolHeaderParam(const Ob20ProtocolHeaderParam ¶m) { @@ -159,8 +234,10 @@ class Ob20ProtocolHeaderParam { compressed_seq_ = param.compressed_seq_; pkt_seq_ = param.pkt_seq_; is_last_packet_ = param.is_last_packet_; + is_weak_read_ = param.is_weak_read_; is_need_reroute_ = param.is_need_reroute_; is_new_extra_info_ = param.is_new_extra_info_; + is_trans_internal_routing_ = param.is_trans_internal_routing_; } return *this; } @@ -170,27 +247,32 @@ class Ob20ProtocolHeaderParam { uint8_t get_compressed_seq() const { return compressed_seq_; } uint8_t get_pkt_seq() const { return pkt_seq_; } bool is_last_packet() const { return is_last_packet_; } + bool is_weak_read() const { return is_weak_read_; } bool is_need_reroute() const { return is_need_reroute_; } bool is_new_extra_info() const { return is_new_extra_info_; } - + bool is_trans_internal_routing() const { return is_trans_internal_routing_; } void reset() { MEMSET(this, 0x0, sizeof(Ob20ProtocolHeaderParam)); is_last_packet_ = false; + is_weak_read_ = false; is_need_reroute_ = false; is_new_extra_info_ = false; + is_trans_internal_routing_ = false; } - TO_STRING_KV(K_(connection_id), K_(request_id), K_(compressed_seq), - K_(pkt_seq), K_(is_last_packet), K_(is_need_reroute), K_(is_new_extra_info)); + TO_STRING_KV(K_(connection_id), K_(request_id), K_(compressed_seq), K_(pkt_seq), + K_(is_last_packet), K_(is_need_reroute), K_(is_new_extra_info), K_(is_trans_internal_routing)); private: uint32_t connection_id_; uint32_t request_id_; uint8_t compressed_seq_; uint8_t pkt_seq_; bool is_last_packet_; + bool is_weak_read_; bool is_need_reroute_; bool is_new_extra_info_; + bool is_trans_internal_routing_; }; diff --git a/src/obproxy/proxy/mysqllib/ob_2_0_protocol_utils.cpp b/src/obproxy/proxy/mysqllib/ob_2_0_protocol_utils.cpp index 8650b26ac..183a18a51 100644 --- a/src/obproxy/proxy/mysqllib/ob_2_0_protocol_utils.cpp +++ b/src/obproxy/proxy/mysqllib/ob_2_0_protocol_utils.cpp @@ -131,39 +131,6 @@ int ObProto20Utils::encode_err_packet(event::ObMIOBuffer &write_buf, const Ob20P return ret; } -int ObProto20Utils::encode_executor_response_packet(event::ObMIOBuffer *write_buf, - const Ob20ProtocolHeaderParam &ob20_head_param, - uint8_t &seq, engine::ObProxyResultResp *result_resp) -{ - int ret = OB_SUCCESS; - - event::ObIOBufferReader *tmp_mio_reader = NULL; - event::ObMIOBuffer *tmp_mio_buf = NULL; - - if (OB_ISNULL(tmp_mio_buf = new_empty_miobuffer(MYSQL_BUFFER_SIZE))) { - ret = common::OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("fail to alloc miobuffer", K(ret)); - } else if (OB_ISNULL(tmp_mio_reader = tmp_mio_buf->alloc_reader())) { - ret = common::OB_ERR_UNEXPECTED; - LOG_WARN("fail to alloc reader", K(ret)); - } else if (OB_FAIL(ObMysqlPacketUtil::encode_executor_response_packet(write_buf, seq, result_resp))) { - LOG_WARN("fail to encode err packet buf", K(ret)); - } else if (OB_FAIL(ObProto20Utils::consume_and_compress_data(tmp_mio_reader, write_buf, - tmp_mio_reader->read_avail(), ob20_head_param))) { - LOG_WARN("fail to consume and compress data for executor response packet in ob20", K(ret)); - } else { - LOG_DEBUG("succ to executor response in ob20 packet"); - } - - if (OB_LIKELY(tmp_mio_buf != NULL)) { - free_miobuffer(tmp_mio_buf); - tmp_mio_buf = NULL; - tmp_mio_reader = NULL; - } - - return ret; -} - int ObProto20Utils::analyze_ok_packet_and_get_reroute_info(ObIOBufferReader *reader, const int64_t pkt_len, const ObMySQLCapabilityFlags &cap, @@ -350,11 +317,11 @@ inline int ObProto20Utils::reserve_proto20_hdr(ObMIOBuffer *write_buf, char *&hd inline int ObProto20Utils::fill_proto20_header(char *hdr_start, const int64_t payload_len, const uint8_t compressed_seq, const uint8_t packet_seq, const uint32_t request_id, const uint32_t connid, - const bool is_last_packet, const bool is_need_reroute, - const bool is_extra_info_exist, const bool is_new_extra_info) + const bool is_last_packet, const bool is_weak_read, + const bool is_need_reroute, const bool is_extra_info_exist, + const bool is_new_extra_info, const bool is_trans_internal_routing) { int ret = OB_SUCCESS; - //include compress header and ob20 header int64_t header_len = MYSQL_COMPRESSED_HEALDER_LENGTH + OB20_PROTOCOL_HEADER_LENGTH; //compress payload @@ -366,7 +333,9 @@ inline int ObProto20Utils::fill_proto20_header(char *hdr_start, const int64_t pa flag.st_flags_.OB_EXTRA_INFO_EXIST = is_extra_info_exist ? 1 : 0; flag.st_flags_.OB_IS_LAST_PACKET = is_last_packet ? 1 : 0; flag.st_flags_.OB_IS_PROXY_REROUTE = is_need_reroute ? 1 : 0; + flag.st_flags_.OB_IS_WEAK_READ = is_weak_read ? 1 : 0; flag.st_flags_.OB_IS_NEW_EXTRA_INFO = is_new_extra_info ? 1 : 0; + flag.st_flags_.OB_IS_TRANS_INTERNAL_ROUTING = is_trans_internal_routing ? 1 : 0; uint16_t reserved = 0; uint16_t header_checksum = 0; int64_t pos = 0; @@ -571,8 +540,9 @@ int ObProto20Utils::fill_proto20_new_extra_info(ObMIOBuffer *write_buf, const Ob } else if (OB_UNLIKELY(FLT_TYPE_AND_LEN != type_written_len)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected check written len", K(ret), K(type_written_len)); - } else if (OB_FAIL(write_buf->write(ptr, len, value_written_len))) { - LOG_WARN("fail to write obj value to buf", K(ret), K(obj_value)); + } else if (OB_NOT_NULL(ptr) && len > 0 + && OB_FAIL(write_buf->write(ptr, len, value_written_len))) { + LOG_WARN("fail to write obj value to buf", K(ret), K(obj_value), K(len), K(NULL == ptr), K(obj_key)); } else if (OB_UNLIKELY(len != value_written_len)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected check written len", K(ret), K(len), K(value_written_len)); @@ -667,15 +637,17 @@ int ObProto20Utils::consume_and_compress_data(ObIOBufferReader *reader, const uint32_t request_id = ob20_head_param.get_request_id(); const uint32_t conn_id = ob20_head_param.get_connection_id(); const bool is_last_packet = ob20_head_param.is_last_packet(); + const bool is_weak_read = ob20_head_param.is_weak_read(); const bool is_need_reroute = ob20_head_param.is_need_reroute(); const bool is_new_extra_info = ob20_head_param.is_new_extra_info(); + const bool is_trans_internal_routing = ob20_head_param.is_trans_internal_routing(); if (OB_ISNULL(reader) || OB_ISNULL(write_buf) || data_len > reader->read_avail()) { ret = OB_INVALID_ARGUMENT; int64_t tmp_read_avail = ((NULL == reader) ? 0 : reader->read_avail()); LOG_ERROR("invalid input value", K(reader), K(write_buf), K(data_len), K(compressed_seq), - K(packet_seq), K(request_id), K(conn_id), K(is_last_packet), K(is_need_reroute), - "read_avail", tmp_read_avail, K(ret)); + K(packet_seq), K(request_id), K(conn_id), K(is_last_packet), K(is_weak_read), + K(is_need_reroute), "read_avail", tmp_read_avail, K(ret)); } else if (OB_FAIL(reserve_proto20_hdr(write_buf, hdr_start))) { LOG_ERROR("fail to reserve proto20 hdr", K(ret)); } else if (OB_NOT_NULL(extra_info) @@ -688,17 +660,22 @@ int ObProto20Utils::consume_and_compress_data(ObIOBufferReader *reader, LOG_ERROR("fail to fill proto20 tailer", K(crc64), K(ret)); } else if (OB_FAIL(fill_proto20_header(hdr_start, payload_len, compressed_seq, packet_seq, request_id, conn_id, - is_last_packet, is_need_reroute, - is_extra_info_exist, is_new_extra_info))) { + is_last_packet, is_weak_read, is_need_reroute, + is_extra_info_exist, is_new_extra_info, is_trans_internal_routing))) { LOG_ERROR("fail to fill_proto20_header", K(payload_len), K(compressed_seq), K(packet_seq), K(request_id), K(conn_id), K(is_last_packet), - K(is_need_reroute), K(ret)); + K(is_weak_read), K(is_need_reroute), K(ret)); } else { LOG_DEBUG("build mysql compress packet with ob20 succ", "origin len", data_len, K(compressed_seq), K(crc64)); } return ret; } +bool ObProto20Utils::is_trans_related_sess_info(int16_t type) +{ + return SESSION_SYNC_TXN_STATIC_INFO <= type && type <= SESSION_SYNC_TXN_EXTRA_INFO; +} + int ObProxyTraceUtils::build_client_ip(ObIArray &extra_info, char *buf, int64_t buf_len, @@ -742,26 +719,51 @@ int ObProxyTraceUtils::build_client_ip(ObIArray &extra_info, } int ObProxyTraceUtils::build_sync_sess_info(common::ObIArray &extra_info, + common::ObSqlString &info_value, common::hash::ObHashMap &sess_info_hash_map, - common::ObSqlString &info_value) + common::hash::ObHashMap &client_sess_field_version, + common::hash::ObHashMap &server_sess_field_version, + ObMysqlSM *sm) { int ret = OB_SUCCESS; ObObJKV ob_sess_info; - ob_sess_info.key_.set_varchar(OB_V20_PRO_EXTRA_KV_NAME_SYNC_SESSION_INFO, static_cast(STRLEN(OB_V20_PRO_EXTRA_KV_NAME_SYNC_SESSION_INFO))); ob_sess_info.key_.set_default_collation_type(); - common::hash::ObHashMap::iterator last = sess_info_hash_map.end(); - common::hash::ObHashMap::iterator it = sess_info_hash_map.begin(); - for (; it != last; ++it) { - info_value.append(it->second); + const int MAX_TYPE_RECORD = 32; + char type_record[MAX_TYPE_RECORD]; + memset(type_record, '0', MAX_TYPE_RECORD); + bool is_sess_exist = false; + + SessFieldHashMap::iterator last = sess_info_hash_map.end(); + SessFieldHashMap::iterator it = sess_info_hash_map.begin(); + for (; it != last && OB_SUCC(ret); ++it) { + int16_t sess_info_type = it->first; + int64_t client_version = 0; + int64_t server_version = 0; + if (OB_FAIL(ObProxyTraceUtils::get_sess_field_version(client_version , sess_info_type, client_sess_field_version))) { + LOG_WARN("fail to get client session field version", K(ret), K(sess_info_type)); + } else if (OB_FAIL(ObProxyTraceUtils::get_sess_field_version(server_version , sess_info_type, server_sess_field_version))) { + LOG_WARN("fail to get server session field version", K(ret), K(sess_info_type)); + } else if (client_version > server_version) { + is_sess_exist = true; + if (sess_info_type < MAX_TYPE_RECORD) { + type_record[sess_info_type] = '1'; + } + info_value.append(it->second); + } } - ob_sess_info.value_.set_varchar(info_value.string()); - ob_sess_info.value_.set_default_collation_type(); - - if (OB_FAIL(extra_info.push_back(ob_sess_info))) { - LOG_WARN("fail to push back", K(ret)); + if (is_sess_exist) { + type_record[MAX_TYPE_RECORD - 1] = '\0'; + sm->trans_state_.trace_log_.log_it("[send_sess]", "type", type_record); + } + if (OB_SUCC(ret)) { + ob_sess_info.value_.set_varchar(info_value.string()); + ob_sess_info.value_.set_default_collation_type(); + if (OB_FAIL(extra_info.push_back(ob_sess_info))) { + LOG_WARN("fail to push back", K(ret)); + } } return ret; } @@ -894,8 +896,13 @@ int ObProxyTraceUtils::build_related_extra_info_all(ObIArray &extra_inf if (!client_session->is_proxy_mysql_client_ && client_info.need_reset_sess_info_vars(server_info) && is_last_packet) { - SessFieldHashMap& sess_info_hash_map = client_info.get_sess_info_map(); - if (OB_FAIL(ObProxyTraceUtils::build_sync_sess_info(extra_info, sess_info_hash_map, sess_info_value))) { + SessFieldHashMap &sess_info_hash_map = client_info.get_sess_info_map(); + LOG_DEBUG("send session info to server", "server addr", sm->trans_state_.server_info_.addr_); + if (OB_FAIL(ObProxyTraceUtils::build_sync_sess_info(extra_info, sess_info_value, + sess_info_hash_map, + client_info.get_sess_field_version(), + server_info.get_sess_field_version(), + sm))) { LOG_WARN("fail to build sync sess info", K(ret)); } } @@ -905,6 +912,20 @@ int ObProxyTraceUtils::build_related_extra_info_all(ObIArray &extra_inf return ret; } +int ObProxyTraceUtils::get_sess_field_version(int64_t &version, int16_t type, common::hash::ObHashMap &map) +{ + int ret = OB_SUCCESS; + version = 0; + if (OB_FAIL(map.get_refactored(type, version))) { + if (OB_HASH_NOT_EXIST == ret) { + version = 0; + ret = OB_SUCCESS; + } else { + LOG_WARN("query session field version failed", K(type), K(ret)); + } + } + return ret; +} } // end of namespace proxy } // end of namespace obproxy diff --git a/src/obproxy/proxy/mysqllib/ob_2_0_protocol_utils.h b/src/obproxy/proxy/mysqllib/ob_2_0_protocol_utils.h index 0f4dbd8a1..883917d73 100644 --- a/src/obproxy/proxy/mysqllib/ob_2_0_protocol_utils.h +++ b/src/obproxy/proxy/mysqllib/ob_2_0_protocol_utils.h @@ -54,9 +54,6 @@ class ObProto20Utils const uint16_t status_flag = 0); static int encode_err_packet(event::ObMIOBuffer &write_buf, const Ob20ProtocolHeaderParam &ob20_head_param, uint8_t &seq, const int err_code, const ObString &msg_buf); - static int encode_executor_response_packet(event::ObMIOBuffer *write_buf, - const Ob20ProtocolHeaderParam &ob20_head_param, - uint8_t &seq, engine::ObProxyResultResp *result_resp); // analyze utils static int analyze_ok_packet_and_get_reroute_info(event::ObIOBufferReader *reader, const int64_t pkt_len, @@ -81,9 +78,11 @@ class ObProto20Utils static int fill_proto20_header(char *hdr_start, const int64_t payload_len, const uint8_t compressed_seq, const uint8_t packet_seq, const uint32_t request_id, const uint32_t connid, - const bool is_last_packet, const bool is_need_reroute, - const bool is_extra_info_exist, const bool is_new_extra_info); + const bool is_last_packet, const bool is_weak_read, + const bool is_need_reroute, const bool is_extra_info_exist, + const bool is_new_extra_info, const bool is_trans_internal_routing); static int reserve_proto20_hdr(event::ObMIOBuffer *write_buf, char *&hdr_start); + static bool is_trans_related_sess_info(int16_t type); private: inline static int analyze_compressed_packet_header(const char *start, const int64_t len, @@ -107,12 +106,17 @@ class ObProxyTraceUtils static int build_extra_info_for_client(ObMysqlSM *sm, char *buf, const int64_t len, common::ObIArray &extra_info); static int build_sync_sess_info(common::ObIArray &extra_info, - common::hash::ObHashMap& sess_info_hash_map, - common::ObSqlString& info_value); + common::ObSqlString &info_value, + common::hash::ObHashMap &sess_info_hash_map, + common::hash::ObHashMap &client_sess_field_version, + common::hash::ObHashMap &server_sess_field_version, + ObMysqlSM *sm); static int build_related_extra_info_all(common::ObIArray &extra_info, ObMysqlSM *sm, char *ip_buf, const int64_t ip_buf_len, char *extra_info_buf, const int64_t extra_info_buf_len, common::ObSqlString &info_value, const bool is_last_packet); + static int get_sess_field_version(int64_t &version, int16_t type, common::hash::ObHashMap &map); + private: DISALLOW_COPY_AND_ASSIGN(ObProxyTraceUtils); }; diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_common_define.h b/src/obproxy/proxy/mysqllib/ob_mysql_common_define.h index e21ee9a6d..76806ac16 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_common_define.h +++ b/src/obproxy/proxy/mysqllib/ob_mysql_common_define.h @@ -176,17 +176,18 @@ bool is_supported_mysql_cmd(const obmysql::ObMySQLCmd mysql_cmd) // Stored Procedures case obmysql::OB_MYSQL_COM_STMT_FETCH: case obmysql::OB_MYSQL_COM_CHANGE_USER: + // binlog related + case obmysql::OB_MYSQL_COM_REGISTER_SLAVE: + case obmysql::OB_MYSQL_COM_BINLOG_DUMP: + case obmysql::OB_MYSQL_COM_BINLOG_DUMP_GTID: // pieceinfo case obmysql::OB_MYSQL_COM_STMT_SEND_PIECE_DATA: case obmysql::OB_MYSQL_COM_STMT_GET_PIECE_DATA: ret = true; break; // Replication Protocol - case obmysql::OB_MYSQL_COM_BINLOG_DUMP: case obmysql::OB_MYSQL_COM_TABLE_DUMP: case obmysql::OB_MYSQL_COM_CONNECT_OUT: - case obmysql::OB_MYSQL_COM_REGISTER_SLAVE: - case obmysql::OB_MYSQL_COM_BINLOG_DUMP_GTID: // Stored Procedures case obmysql::OB_MYSQL_COM_SET_OPTION: ret = false; diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_compress_ob20_analyzer.cpp b/src/obproxy/proxy/mysqllib/ob_mysql_compress_ob20_analyzer.cpp index 974217776..b0e6fbc2e 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_compress_ob20_analyzer.cpp +++ b/src/obproxy/proxy/mysqllib/ob_mysql_compress_ob20_analyzer.cpp @@ -330,17 +330,10 @@ int ObMysqlCompressOB20Analyzer::do_obobj_extra_info_decode(const char *buf, LOG_DEBUG("deserialize extra info", K(key), K(value)); if (0 == key.get_string().case_compare(OB_V20_PRO_EXTRA_KV_NAME_SYNC_SESSION_INFO)) { - extra_info.sess_info_buf_.reset(); const char *value_ptr = value.get_string().ptr(); const int64_t value_len = value.get_string().length(); - if (OB_FAIL(extra_info.sess_info_buf_.init(value_len))) { - LOG_WARN("fail int alloc mem", K(value_len), K(ret)); - } else if (OB_FAIL(extra_info.sess_info_buf_.write(value_ptr, value_len))) { + if (OB_FAIL(extra_info.add_sess_info_buf(value_ptr, value_len))) { LOG_WARN("fail to write sess info to buf", K(ret), K(value)); - } else { - extra_info.sess_info_.assign_ptr(extra_info.sess_info_buf_.ptr(), - static_cast(extra_info.sess_info_buf_.len())); - extra_info.is_exist_sess_info_ = true; } } else if (0 == key.get_string().case_compare(OB_V20_PRO_EXTRA_KV_NAME_FULL_LINK_TRACE)) { int64_t full_pos = 0; @@ -380,14 +373,8 @@ int ObMysqlCompressOB20Analyzer::do_new_extra_info_decode(const char *buf, } else { Ob20NewExtraInfoProtocolKeyType type = static_cast(key_type); if (type == SESS_INFO) { - extra_info.sess_info_buf_.reset(); - if (OB_FAIL(extra_info.sess_info_buf_.init(key_len))) { - LOG_WARN("fail to init sess info buf", K(ret), K(key_len)); - } else if (OB_FAIL(extra_info.sess_info_buf_.write(buf + pos, key_len))) { + if (OB_FAIL(extra_info.add_sess_info_buf(buf+pos, key_len))) { LOG_WARN("fail to write sess info buf", K(ret), K(key_len)); - } else { - extra_info.sess_info_.assign_ptr(extra_info.sess_info_buf_.ptr(), key_len); - extra_info.is_exist_sess_info_ = true; } } else if (type == FULL_TRC) { int64_t full_pos = 0; @@ -570,7 +557,7 @@ int ObMysqlCompressOB20Analyzer::analyze_last_compress_packet( } else if (OB_FAIL(decompress_data(start, len, resp))) { LOG_WARN("fail to decompress last mysql packet", K(ret)); } - + resp.get_analyze_result().is_server_trans_internal_routing_ = curr_compressed_ob20_header_.flag_.is_trans_internal_routing(); return ret; } diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_compress_ob20_analyzer.h b/src/obproxy/proxy/mysqllib/ob_mysql_compress_ob20_analyzer.h index 17d268a55..7fd1bdb76 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_compress_ob20_analyzer.h +++ b/src/obproxy/proxy/mysqllib/ob_mysql_compress_ob20_analyzer.h @@ -54,7 +54,7 @@ class ObMysqlCompressOB20Analyzer : public ObMysqlCompressAnalyzer ObMysqlCompressOB20Analyzer() : ObMysqlCompressAnalyzer(), last_ob20_seq_(0), request_id_(0), sessid_(0), remain_head_checked_len_(0), extra_header_len_(0), extra_len_(0), extra_checked_len_(0), payload_checked_len_(0), tail_checked_len_(0), - ob20_analyzer_state_(OB20_ANALYZER_MAX), crc64_(0), curr_compressed_ob20_header_() + ob20_analyzer_state_(OB20_ANALYZER_MAX), crc64_(0), result_(), curr_compressed_ob20_header_() {} virtual ~ObMysqlCompressOB20Analyzer() { reset(); } diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_config_processor.cpp b/src/obproxy/proxy/mysqllib/ob_mysql_config_processor.cpp index 1c5a27093..b693c5958 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_config_processor.cpp +++ b/src/obproxy/proxy/mysqllib/ob_mysql_config_processor.cpp @@ -74,6 +74,7 @@ ObMysqlConfigParams::ObMysqlConfigParams() task_thread_num_(0), block_thread_num_(0), grpc_thread_num_(0), + shard_scan_thread_num_(0), automatic_match_work_thread_(true), enable_congestion_(false), @@ -86,6 +87,7 @@ ObMysqlConfigParams::ObMysqlConfigParams() enable_reroute_(false), enable_index_route_(false), enable_causal_order_read_(true), + enable_transaction_internal_routing_(true), sqlaudit_mem_limited_(0), internal_cmd_mem_limited_(0), @@ -116,7 +118,9 @@ ObMysqlConfigParams::ObMysqlConfigParams() proxy_id_(0), client_max_memory_size_(0), enable_cpu_isolate_(false), - enable_primary_zone_(true) + enable_primary_zone_(true), + ip_listen_mode_(0), + local_bound_ipv6_ip_() { proxy_idc_name_[0] = '\0'; } @@ -169,6 +173,7 @@ int ObMysqlConfigParams::assign_config(const ObProxyConfig &proxy_config) CONFIG_ITEM_ASSIGN(task_thread_num); CONFIG_ITEM_ASSIGN(block_thread_num); CONFIG_ITEM_ASSIGN(grpc_thread_num); + CONFIG_ITEM_ASSIGN(shard_scan_thread_num); CONFIG_ITEM_ASSIGN(automatic_match_work_thread); CONFIG_ITEM_ASSIGN(enable_congestion); @@ -178,6 +183,7 @@ int ObMysqlConfigParams::assign_config(const ObProxyConfig &proxy_config) CONFIG_ITEM_ASSIGN(enable_proxy_scramble); CONFIG_ITEM_ASSIGN(enable_compression_protocol); CONFIG_ITEM_ASSIGN(enable_ob_protocol_v2); + CONFIG_ITEM_ASSIGN(enable_transaction_internal_routing); CONFIG_ITEM_ASSIGN(enable_reroute); CONFIG_ITEM_ASSIGN(enable_index_route); CONFIG_ITEM_ASSIGN(enable_causal_order_read); @@ -210,6 +216,7 @@ int ObMysqlConfigParams::assign_config(const ObProxyConfig &proxy_config) CONFIG_ITEM_ASSIGN(client_max_memory_size); CONFIG_ITEM_ASSIGN(enable_cpu_isolate); CONFIG_ITEM_ASSIGN(enable_primary_zone); + CONFIG_ITEM_ASSIGN(ip_listen_mode); if (OB_SUCC(ret)) { obsys::CRLockGuard guard(proxy_config.rwlock_); @@ -255,6 +262,9 @@ int ObMysqlConfigParams::assign_config(const ObProxyConfig &proxy_config) if(OB_UNLIKELY(0 != local_bound_ip_.load(proxy_config.local_bound_ip))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to assign ip value", K(proxy_config.local_bound_ip.str()), K(ret)); + } else if (OB_UNLIKELY(0 != local_bound_ipv6_ip_.load(proxy_config.local_bound_ipv6_ip))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to assign ipv6 value", K(proxy_config.local_bound_ipv6_ip.str()), K(ret)); } } @@ -308,7 +318,7 @@ DEF_TO_STRING(ObMysqlConfigParams) J_COMMA(); J_KV(K_(short_async_task_timeout), K_(short_async_task_timeout), K_(min_congested_connect_timeout), K_(tenant_location_valid_time), K_(local_bound_ip), K_(listen_port), K_(stack_size), K_(work_thread_num), - K_(task_thread_num), K_(block_thread_num), K_(grpc_thread_num), K_(automatic_match_work_thread), + K_(task_thread_num), K_(block_thread_num), K_(grpc_thread_num), K_(shard_scan_thread_num), K_(automatic_match_work_thread), K_(enable_congestion), K_(enable_bad_route_reject), K_(test_server_addr), K_(sqlaudit_mem_limited), K_(max_connections), K_(client_max_connections), K_(enable_client_connection_lru_disconnect), K_(connect_observer_max_retries), @@ -324,7 +334,8 @@ DEF_TO_STRING(ObMysqlConfigParams) K_(default_inactivity_timeout), K_(enable_partition_table_route), K_(enable_pl_route), K_(enable_cluster_checkout), K_(enable_client_ip_checkout), K_(enable_proxy_scramble), K_(enable_compression_protocol), K_(enable_ob_protocol_v2), - K_(enable_reroute), K_(enable_index_route), K_(enable_causal_order_read)); + K_(enable_reroute), K_(enable_index_route), K_(enable_causal_order_read), + K_(ip_listen_mode), K_(local_bound_ipv6_ip)); J_OBJ_END(); return pos; } diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_config_processor.h b/src/obproxy/proxy/mysqllib/ob_mysql_config_processor.h index 2ae3edbc2..86020f9b8 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_config_processor.h +++ b/src/obproxy/proxy/mysqllib/ob_mysql_config_processor.h @@ -102,6 +102,7 @@ struct ObMysqlConfigParams : public ObConfigInfo CfgInt task_thread_num_; CfgInt block_thread_num_; CfgInt grpc_thread_num_; + CfgInt shard_scan_thread_num_; CfgBool automatic_match_work_thread_; CfgBool enable_congestion_; CfgBool enable_bad_route_reject_; @@ -113,6 +114,7 @@ struct ObMysqlConfigParams : public ObConfigInfo CfgBool enable_reroute_; CfgBool enable_index_route_; CfgBool enable_causal_order_read_; + CfgBool enable_transaction_internal_routing_; CfgIpPortList test_server_addr_; CfgInt sqlaudit_mem_limited_; @@ -145,6 +147,8 @@ struct ObMysqlConfigParams : public ObConfigInfo CfgInt client_max_memory_size_; CfgBool enable_cpu_isolate_; CfgBool enable_primary_zone_; + CfgInt ip_listen_mode_; + CfgIp local_bound_ipv6_ip_; char proxy_idc_name_[OB_PROXY_MAX_IDC_NAME_LENGTH + 1]; char proxy_primary_zone_name_[common::MAX_ZONE_LENGTH + 1]; }; diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_ob20_packet_write.cpp b/src/obproxy/proxy/mysqllib/ob_mysql_ob20_packet_write.cpp index ded4f5027..ad197d8b4 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_ob20_packet_write.cpp +++ b/src/obproxy/proxy/mysqllib/ob_mysql_ob20_packet_write.cpp @@ -155,8 +155,10 @@ int ObMysqlOB20PacketWriter::write_request_packet(ObMIOBuffer &mio_buf, const uint8_t compressed_seq, const uint8_t pkt_seq, bool is_last_packet, + bool is_weak_read, bool is_need_reroute, bool is_new_extra_info, + bool is_trans_internal_routing, const common::ObIArray *extra_info) { int ret = OB_SUCCESS; @@ -168,8 +170,9 @@ int ObMysqlOB20PacketWriter::write_request_packet(ObMIOBuffer &mio_buf, LOG_WARN("we cannot support packet which is larger than 16MB", K(sql_str), K(MYSQL_PACKET_MAX_LENGTH), K(ret)); } else { - Ob20ProtocolHeaderParam ob20_head_param(conn_id, req_id, compressed_seq, pkt_seq, is_last_packet, is_need_reroute, - is_new_extra_info); + Ob20ProtocolHeaderParam ob20_head_param(conn_id, req_id, compressed_seq, pkt_seq, is_last_packet, + is_weak_read, is_need_reroute, + is_new_extra_info, is_trans_internal_routing); ObMySQLRawPacket com_pkt(cmd); com_pkt.set_content(sql_str.ptr(), static_cast(sql_str.length())); if (OB_FAIL(ObMysqlOB20PacketWriter::write_compressed_packet(mio_buf, com_pkt, ob20_head_param, extra_info))) { diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_ob20_packet_write.h b/src/obproxy/proxy/mysqllib/ob_mysql_ob20_packet_write.h index 82778e9f6..f9ab96688 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_ob20_packet_write.h +++ b/src/obproxy/proxy/mysqllib/ob_mysql_ob20_packet_write.h @@ -38,8 +38,8 @@ class ObMysqlOB20PacketWriter static int write_request_packet(event::ObMIOBuffer &mio_buf, const obmysql::ObMySQLCmd cmd, const common::ObString &sql_str, const uint32_t conn_id, const uint32_t req_id, const uint8_t compressed_seq, - const uint8_t pkt_seq, bool is_last_packet, - bool is_need_reroute, bool is_new_extra_info, + const uint8_t pkt_seq, bool is_last_packet, bool is_weak_read, + bool is_need_reroute, bool is_new_extra_info, bool is_trans_internal_routing, const common::ObIArray *extra_info = NULL); static int write_packet(event::ObMIOBuffer &mio_buf, const char *buf, const int64_t buf_len, const Ob20ProtocolHeaderParam &ob20_head_param); diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_packet_rewriter.cpp b/src/obproxy/proxy/mysqllib/ob_mysql_packet_rewriter.cpp index 1a08a57ef..97233be23 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_packet_rewriter.cpp +++ b/src/obproxy/proxy/mysqllib/ob_mysql_packet_rewriter.cpp @@ -132,7 +132,7 @@ int ObHandshakeResponseParam::write_client_addr_buf(const common::ObAddr &addr) int ret = OB_SUCCESS; if (OB_UNLIKELY(!addr.is_valid())) { //do not write - } else if (OB_UNLIKELY(!addr.ip_to_string(client_ip_buf_, OB_MAX_IP_BUF_LEN))) { + } else if (OB_UNLIKELY(!addr.ip_to_string(client_ip_buf_, MAX_IP_ADDR_LENGTH))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to ip_to_string", K(addr), K(ret)); } @@ -188,7 +188,7 @@ int ObMysqlPacketRewriter::rewrite_ok_packet(const OMPKOK &src_ok, if (OB_FAIL(des_ok.add_system_var(str_kv))) { LOG_WARN("fail to add system var while rewrite ok packet", K(ret)); } else { - LOG_DEBUG("succ to add system var in ok packet", K(str_kv)); + LOG_DEBUG("succ to add system var in ok packet back to client", K(str_kv), K(cap)); } } } @@ -239,13 +239,13 @@ int ObMysqlPacketRewriter::rewrite_handshake_response_packet( } // find client_ip - if (param.enable_client_ip_checkout_) { + if (RUN_MODE_PROXY == g_run_mode && param.enable_client_ip_checkout_) { ObStringKV string_kv; for (int64_t i = 0; OB_SUCC(ret) && i < tg_hsr.get_connect_attrs().count(); ++i) { string_kv = tg_hsr.get_connect_attrs().at(i); if (0 == string_kv.key_.case_compare(OB_MYSQL_CLIENT_IP)) { if (!string_kv.value_.empty()) { - snprintf(param.client_ip_buf_, ObHandshakeResponseParam::OB_MAX_IP_BUF_LEN, "%.*s", string_kv.value_.length(), string_kv.value_.ptr()); + snprintf(param.client_ip_buf_, MAX_IP_ADDR_LENGTH, "%.*s", string_kv.value_.length(), string_kv.value_.ptr()); } break; } @@ -254,6 +254,26 @@ int ObMysqlPacketRewriter::rewrite_handshake_response_packet( // reset before add tg_hsr.reset_connect_attr(); + // add transparent transit conn attrs & find client_ip + OMPKHandshakeResponse &orig_hsr = orig_auth_req.get_hsr_result().response_; + bool find_client_ip = false; + for (int64_t i = 0; OB_SUCC(ret) && i < orig_hsr.get_connect_attrs().count(); ++i) { + ObStringKV kv; + // transit conn attrs OB_MYSQL_OB_CLIENT + if (OB_FAIL(orig_hsr.get_connect_attrs().at(i, kv))) { + LOG_WARN("fail access handshake response connect attrs", K(i), K(ret)); + } else if (kv.key_.prefix_match(OB_MYSQL_OB_CLIENT)) { + if (OB_FAIL(tg_hsr.get_connect_attrs().push_back(kv))) { + LOG_WARN("fail push back transparent transmit connect attrs", K(kv), K(ret)); + } else { /* succ */ } + } else if (!find_client_ip + && param.enable_client_ip_checkout_ + && 0 == kv.key_.case_compare(OB_MYSQL_CLIENT_IP) + && !kv.value_.empty()){ + snprintf(param.client_ip_buf_, MAX_IP_ADDR_LENGTH, "%.*s", kv.value_.length(), kv.value_.ptr()); + find_client_ip = true; + } else { /* do nothing */ } + } // 4. add obproxy specified connect attrs: // a. proxy_mode // b. connection id @@ -281,9 +301,7 @@ int ObMysqlPacketRewriter::rewrite_handshake_response_packet( LOG_WARN("fail to add client ip", K(param.client_ip_buf_), K(ret)); } else if (OB_FAIL(add_connect_attr(OB_MYSQL_PROXY_VERSION, param.proxy_version_buf_, tg_hsr))) { LOG_WARN("fail to add proxy version", K(param.proxy_version_buf_), K(ret)); - } else { - //do nothing - } + } else { /* succ */ } return ret; diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_packet_rewriter.h b/src/obproxy/proxy/mysqllib/ob_mysql_packet_rewriter.h index 1c75aa839..238ecbcf9 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_packet_rewriter.h +++ b/src/obproxy/proxy/mysqllib/ob_mysql_packet_rewriter.h @@ -64,7 +64,6 @@ struct ObHandshakeResponseParam static const int64_t OB_MAX_UINT32_BUF_LEN = 11; // string length of max uint32_t(2**32 - 1) static const int64_t OB_MAX_VERSION_BUF_LEN = 22; // string length of (xxx.xxx.xxx.xxx.xxx) - static const int64_t OB_MAX_IP_BUF_LEN = 20; // string length of (xxx.xxx.xxx.xxx.xxx) bool is_saved_login_; bool use_compress_; @@ -81,7 +80,7 @@ struct ObHandshakeResponseParam char global_vars_version_buf_[OB_MAX_UINT64_BUF_LEN]; char cap_buf_[OB_MAX_UINT64_BUF_LEN]; char proxy_scramble_buf_[obmysql::OMPKHandshake::SCRAMBLE_TOTAL_SIZE]; - char client_ip_buf_[OB_MAX_IP_BUF_LEN]; + char client_ip_buf_[MAX_IP_ADDR_LENGTH]; char cluster_id_buf_[OB_MAX_UINT64_BUF_LEN]; private: diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_request_analyzer.cpp b/src/obproxy/proxy/mysqllib/ob_mysql_request_analyzer.cpp index 1bd9891db..b95aa448e 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_request_analyzer.cpp +++ b/src/obproxy/proxy/mysqllib/ob_mysql_request_analyzer.cpp @@ -163,7 +163,8 @@ void ObMysqlRequestAnalyzer::analyze_request(const ObRequestAnalyzeCtx &ctx, && !client_request.is_sharding_user() && !client_request.is_proxysys_user() && !ctx.using_ldg_ - && OB_MYSQL_COM_STMT_SEND_LONG_DATA != sql_cmd) { + && OB_MYSQL_COM_STMT_SEND_LONG_DATA != sql_cmd + && OB_MYSQL_COM_CHANGE_USER != sql_cmd) { if (OB_FAIL(do_analyze_request(ctx, sql_cmd, auth_request, client_request, is_oracle_mode))) { status = ANALYZE_ERROR; LOG_WARN("fail to dispatch mysql cmd", "analyze status", @@ -371,6 +372,7 @@ void ObMysqlRequestAnalyzer::extract_fileds(const ObExprParseResult& result, ObP void ObMysqlRequestAnalyzer::extract_fileds(const ObExprParseResult& result, SqlFieldResult &sql_result) { + int ret = OB_SUCCESS; int64_t total_num = result.all_relation_info_.relation_num_; ObProxyRelationExpr* relation_expr = NULL; ObString name_str; @@ -398,34 +400,43 @@ void ObMysqlRequestAnalyzer::extract_fileds(const ObExprParseResult& result, Sql } if (relation_expr->right_value_ != NULL) { ObProxyTokenNode *token = relation_expr->right_value_->head_; - SqlField field; - field.reset(); - field.column_name_.set(name_str); - SqlColumnValue column_value; - while (NULL != token) { - switch(token->type_) { - case TOKEN_INT_VAL: - column_value.value_type_ = TOKEN_INT_VAL; - column_value.column_int_value_ = token->int_value_; - column_value.column_value_.set_integer(token->int_value_); - field.column_values_.push_back(column_value); - break; - case TOKEN_STR_VAL: - column_value.value_type_ = TOKEN_STR_VAL; - value_str.assign_ptr(token->str_value_.str_, - token->str_value_.str_len_); - column_value.column_value_.set(value_str); - field.column_values_.push_back(column_value); - break; - default: - LOG_DEBUG("invalid token type", "token type", get_obproxy_token_type(token->type_)); - break; + SqlField* field = NULL; + if (OB_FAIL(SqlField::alloc_sql_field(field))) { + LOG_WARN("fail to alloc sql field", K(ret)); + } else { + field->column_name_.set_value(name_str.length(), name_str.ptr()); + SqlColumnValue column_value; + while (OB_SUCC(ret) && NULL != token) { + switch(token->type_) { + case TOKEN_INT_VAL: + column_value.value_type_ = TOKEN_INT_VAL; + column_value.column_int_value_ = token->int_value_; + column_value.column_value_.set_integer(token->int_value_); + if (OB_FAIL(field->column_values_.push_back(column_value))) { + LOG_WARN("fail to push column_value", K(ret)); + } + break; + case TOKEN_STR_VAL: + column_value.value_type_ = TOKEN_STR_VAL; + value_str.assign_ptr(token->str_value_.str_, + token->str_value_.str_len_); + column_value.column_value_.set_value(value_str); + if (OB_FAIL(field->column_values_.push_back(column_value))) { + LOG_WARN("fail to push back column_value", K(ret)); + } + break; + default: + LOG_DEBUG("invalid token type", "token type", get_obproxy_token_type(token->type_)); + break; + } + token = token->next_; + } + if (OB_SUCC(ret) && field->is_valid() && OB_SUCCESS == sql_result.fields_.push_back(field)) { + ++sql_result.field_num_; + } else { + field->reset(); + field = NULL; } - token = token->next_; - } - if (field.is_valid()) { - sql_result.fields_.push_back(field); - ++sql_result.field_num_; } } else { LOG_WARN("right value is null"); @@ -467,7 +478,6 @@ int ObMysqlRequestAnalyzer::parse_sql_fileds(ObProxyMysqlRequest &client_request ObExprParser expr_parser(*allocator, parse_mode); ObString sql = client_request.get_sql(); expr_result.part_key_info_.key_num_ = 0; - expr_result.target_mask_ = 0; ObString expr_sql = ObProxyMysqlRequest::get_expr_sql(sql, sql_parse_result.get_parsed_length()); if (SELECT_STMT_PARSE_MODE == parse_mode) { const char *expr_sql_str = expr_sql.ptr(); @@ -542,6 +552,18 @@ inline int ObMysqlRequestAnalyzer::do_analyze_request( LOG_WARN("fail to parse sql", K(sql), K(ret)); } else if (OB_FAIL(handle_internal_cmd(client_request))) { LOG_WARN("fail to handle internal cmd", K(sql), K(ret)); + } else if (sql_parse_result.is_dual_request() + && OB_MYSQL_COM_STMT_PREPARE_EXECUTE == sql_cmd + && get_global_proxy_config().enable_xa_route) { + // specically check if sql is xa start + // from obci only one format: select DBMS_XA.XA_START(?, ?) from dual + ObString tmp = sql; + tmp.split_on(' '); + ObString dbms_xa_start = tmp.split_on(' ').split_on('(').trim(); + if (0 == dbms_xa_start.case_compare("DBMS_XA.XA_START")) { + sql_parse_result.set_xa_start_stmt(true); + LOG_DEBUG("[ObMysqlRequestAnalyzer::do_analyze_request] receive xa start req in prepare execute packet"); + } } } } else { @@ -574,20 +596,6 @@ inline int ObMysqlRequestAnalyzer::do_analyze_request( } break; } - case OB_MYSQL_COM_PING: { - // proxy handle mysql_ping() by itself - int64_t len = 0; - if (NULL == ctx.reader_) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid buffer reader", K_(ctx.reader), K(ret)); - } else if (MYSQL_NET_META_LENGTH != (len = ctx.reader_->read_avail())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("buffer reader length is not equal to MYSQL_NET_META_LENGTH", K(len)); - ObMysqlPacketReader reader; - reader.print_reader(*ctx.reader_); - } - break; - } case OB_MYSQL_COM_CHANGE_USER: case OB_MYSQL_COM_RESET_CONNECTION: case OB_MYSQL_COM_INIT_DB: { @@ -621,6 +629,7 @@ inline int ObMysqlRequestAnalyzer::do_analyze_request( break; } } + case OB_MYSQL_COM_PING: case OB_MYSQL_COM_HANDSHAKE: case OB_MYSQL_COM_QUIT: { break; @@ -733,7 +742,8 @@ int ObMysqlRequestAnalyzer::handle_internal_cmd(ObProxyMysqlRequest &client_requ parse_result.set_err_stmt_type(OBPROXY_T_ERR_NOT_SUPPORTED); } is_internal_cmd = true; - } else if (client_request.is_sharding_user() && parse_result.is_show_topology_stmt()) { + } else if (client_request.is_sharding_user() && (parse_result.is_show_topology_stmt() + || parse_result.is_show_elastic_id_stmt())) { is_internal_cmd = true; } @@ -800,6 +810,16 @@ int ObMysqlRequestAnalyzer::analyze_execute_header(const int64_t param_num, int ObMysqlRequestAnalyzer::parse_param_type(const int64_t param_num, ObIArray ¶m_types, const char *&buf, int64_t &data_len) +{ + ObSEArray type_infos; + return parse_param_type(param_num, param_types, type_infos, buf, data_len); +} + +// The default data of this method is complete and can only come in once +int ObMysqlRequestAnalyzer::parse_param_type(const int64_t param_num, + ObIArray ¶m_types, + ObIArray &type_infos, + const char *&buf, int64_t &data_len) { int ret = OB_SUCCESS; @@ -813,10 +833,11 @@ int ObMysqlRequestAnalyzer::parse_param_type(const int64_t param_num, LOG_WARN("fail to get int1", K(data_len), K(ret)); } else if (OB_FAIL(param_types.push_back(static_cast(type)))) { LOG_WARN("fail to push back param type", K(type), K(ret)); + } else if (OB_FAIL(type_infos.push_back(TypeInfo()))) { + LOG_WARN("fail to push back empty type info", K(ret)); } else if (OB_MYSQL_TYPE_COMPLEX == type) { - TypeInfo type_name_info; + TypeInfo &type_name_info = type_infos.at(i); uint8_t elem_type = 0; - // skip all complex type bytes if (OB_FAIL(decode_type_info(buf, data_len, type_name_info))) { LOG_WARN("failed to decode type info", K(ret)); } else if (type_name_info.type_name_.empty()) { @@ -1047,9 +1068,8 @@ int ObMysqlRequestAnalyzer::analyze_send_long_data_param(ObProxyMysqlRequest &cl ret = OB_INVALID_ARGUMENT; LOG_WARN("fail to get param name from prepare result", K(ret), K(param_id), K(sql_result.field_num_)); } else { - obutils::SqlField &field = sql_result.fields_.at(param_id); - param_name = field.column_name_.string_; - + obutils::SqlField* field = sql_result.fields_.at(param_id); + param_name = field->column_name_.config_string_; ObProxyPartKeyInfo &key_info = part_info->get_part_key_info(); for (uint64_t i = 0; i < key_info.key_num_; ++i) { ObProxyPartKey &part_key = key_info.part_keys_[i]; @@ -1134,7 +1154,6 @@ int ObMysqlRequestAnalyzer::parse_param_value(ObIAllocator &allocator, ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid input value", K(data), K(ret)); } else { - ObCollationType cs_type = ObCharset::get_default_collation(charset); switch (type) { case OB_MYSQL_TYPE_TINY: { int8_t value; @@ -1211,10 +1230,13 @@ int ObMysqlRequestAnalyzer::parse_param_value(ObIAllocator &allocator, case OB_MYSQL_TYPE_VARCHAR: case OB_MYSQL_TYPE_VAR_STRING: case OB_MYSQL_TYPE_NEWDECIMAL: - case OB_MYSQL_TYPE_OB_UROWID: { + case OB_MYSQL_TYPE_OB_UROWID: + case OB_MYSQL_TYPE_JSON: + case OB_MYSQL_TYPE_GEOMETRY: { ObString str; ObString dst; uint64_t length = 0; + common::ObCollationType cs_type = common::ObCharset::get_default_collation(charset); if (OB_FAIL(ObMysqlPacketUtil::get_length(data, buf_len, length))) { LOG_ERROR("decode varchar param value failed", K(buf_len), K(ret)); } else if (buf_len < length) { @@ -1223,7 +1245,7 @@ int ObMysqlRequestAnalyzer::parse_param_value(ObIAllocator &allocator, } else { str.assign_ptr(data, static_cast(length)); if (OB_FAIL(ob_write_string(allocator, str, dst))) { - LOG_WARN("Failed to write str", K(ret)); + LOG_WARN("failed to ob write string", K(ret)); } else { if (OB_MYSQL_TYPE_NEWDECIMAL == type) { number::ObNumber nb; @@ -1459,8 +1481,7 @@ int ObMysqlRequestAnalyzer::decode_type_info(const char*& buf, int64_t &buf_len, } } if (OB_SUCC(ret)) { - uint64_t version = 0; - if (OB_FAIL(ObMysqlPacketUtil::get_length(buf, buf_len, version))) { + if (OB_FAIL(ObMysqlPacketUtil::get_length(buf, buf_len, type_info.version_))) { LOG_WARN("failed to get version", K(ret)); } } diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_request_analyzer.h b/src/obproxy/proxy/mysqllib/ob_mysql_request_analyzer.h index dd3a65875..58c88db54 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_request_analyzer.h +++ b/src/obproxy/proxy/mysqllib/ob_mysql_request_analyzer.h @@ -103,6 +103,11 @@ class ObMysqlRequestAnalyzer common::ObIArray ¶m_types, const char *&buf, int64_t &data_len); + static int parse_param_type(const int64_t param_num, + common::ObIArray ¶m_types, + common::ObIArray &type_infos, + const char *&buf, int64_t &data_len); + static int parse_param_type_from_reader(int64_t& param_offset, const int64_t param_num, common::ObIArray ¶m_types, @@ -136,16 +141,6 @@ class ObMysqlRequestAnalyzer static int analyze_sql_id(const ObString &sql, ObProxyMysqlRequest &client_request, common::ObString &sql_id); -private: - struct TypeInfo { - TypeInfo() : relation_name_(), type_name_(), is_elem_type_(false) {} ; - common::ObString relation_name_; - common::ObString type_name_; - ObObjType elem_type_; - bool is_elem_type_; - TO_STRING_KV(K_(relation_name), K_(type_name), K_(elem_type), K_(is_elem_type)); - }; - private: int get_payload_length(const char *buffer); int is_request_finished(const ObRequestBuffer &buff, bool &is_finish); @@ -172,11 +167,11 @@ class ObMysqlRequestAnalyzer const char *&data, int64_t &buf_len, ObObj ¶m); static int parse_mysql_time_value(const char *&data, int64_t &buf_len, ObObj ¶m); - static int decode_type_info(const char*& buf, int64_t &buf_len, TypeInfo &type_info); + static int decode_type_info(const char*& buf, int64_t &buf_len, obmysql::TypeInfo &type_info); static int decode_type_info_from_reader(event::ObIOBufferReader* reader, int64_t &decoded_offset, - TypeInfo &type_info); + obmysql::TypeInfo &type_info); static int get_uint1_from_reader(event::ObIOBufferReader* reader, int64_t &decoded_offset, diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_request_builder.cpp b/src/obproxy/proxy/mysqllib/ob_mysql_request_builder.cpp index 6e22ed9bd..4d28b0d4f 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_request_builder.cpp +++ b/src/obproxy/proxy/mysqllib/ob_mysql_request_builder.cpp @@ -58,15 +58,19 @@ int ObMysqlRequestBuilder::build_database_sync_packet(ObMysqlSM *sm, uint8_t compressed_seq = 0; if (ObProxyProtocol::PROTOCOL_OB20 == ob_proxy_protocol) { ObSEArray extra_info; - char extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; - if (OB_FAIL(ObProxyTraceUtils::build_extra_info_for_server(sm, extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, - extra_info, true))) { - LOG_WARN("fail to build extra info for server", K(ret)); + ObSqlString sess_info_value; + char client_ip_buf[MAX_IP_BUFFER_LEN] = "\0"; + char server_extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; + if (OB_FAIL(ObProxyTraceUtils::build_related_extra_info_all(extra_info, sm, + client_ip_buf, MAX_IP_BUFFER_LEN, server_extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, + sess_info_value, true))) { + LOG_WARN("fail to build related extra info", K(ret)); } else if (OB_FAIL(ObMysqlOB20PacketWriter::write_request_packet(mio_buf, cmd, db_name, server_session->get_server_sessid(), server_session->get_next_server_request_id(), - compressed_seq, compressed_seq, true, false, + compressed_seq, compressed_seq, true, false, false, server_info.is_new_extra_info_supported(), + sm->get_client_session()->is_trans_internal_routing(), &extra_info))) { LOG_WARN("fail to write request packet in ob20", K(ret)); } else { /* nothing */ } @@ -102,16 +106,20 @@ int ObMysqlRequestBuilder::build_all_session_vars_sync_packet(ObMysqlSM *sm, } else { uint8_t compressed_seq = 0; if (ObProxyProtocol::PROTOCOL_OB20 == ob_proxy_protocol) { - ObSEArray extra_info; - char extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; - if (OB_FAIL(ObProxyTraceUtils::build_extra_info_for_server(sm, extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, - extra_info, true))) { - LOG_WARN("fail to build extra info for server", K(ret)); + ObSEArray extra_info; + ObSqlString sess_info_value; + char client_ip_buf[MAX_IP_BUFFER_LEN] = "\0"; + char server_extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; + if (OB_FAIL(ObProxyTraceUtils::build_related_extra_info_all(extra_info, sm, + client_ip_buf, MAX_IP_BUFFER_LEN, server_extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, + sess_info_value, true))) { + LOG_WARN("fail to build related extra info", K(ret)); } else if (OB_FAIL(ObMysqlOB20PacketWriter::write_request_packet(mio_buf, cmd, reset_sql.string(), server_session->get_server_sessid(), server_session->get_next_server_request_id(), - compressed_seq, compressed_seq, true, false, + compressed_seq, compressed_seq, true, false, false, server_info.is_new_extra_info_supported(), + sm->get_client_session()->is_trans_internal_routing(), &extra_info))) { LOG_WARN("fail to write request packet in ob20", K(ret)); } else { /* nothing */ } @@ -148,16 +156,20 @@ int ObMysqlRequestBuilder::build_session_vars_sync_packet(ObMysqlSM *sm, } else { uint8_t compressed_seq = 0; if (ObProxyProtocol::PROTOCOL_OB20 == ob_proxy_protocol) { - ObSEArray extra_info; - char extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; - if (OB_FAIL(ObProxyTraceUtils::build_extra_info_for_server(sm, extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, - extra_info, true))) { - LOG_WARN("fail to build extra info for server", K(ret)); + ObSEArray extra_info; + ObSqlString sess_info_value; + char client_ip_buf[MAX_IP_BUFFER_LEN] = "\0"; + char server_extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; + if (OB_FAIL(ObProxyTraceUtils::build_related_extra_info_all(extra_info, sm, + client_ip_buf, MAX_IP_BUFFER_LEN, server_extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, + sess_info_value, true))) { + LOG_WARN("fail to build related extra info", K(ret)); } else if (OB_FAIL(ObMysqlOB20PacketWriter::write_request_packet(mio_buf, cmd, reset_sql.string(), server_session->get_server_sessid(), server_session->get_next_server_request_id(), - compressed_seq, compressed_seq, true, false, - server_info.is_new_extra_info_supported(), + compressed_seq, compressed_seq, true, false, false, + server_info.is_new_extra_info_supported(), + sm->get_client_session()->is_trans_internal_routing(), &extra_info))) { LOG_WARN("fail to write request packet in ob20", K(ret)); } else { /* nothing */ } @@ -177,32 +189,36 @@ int ObMysqlRequestBuilder::build_session_vars_sync_packet(ObMysqlSM *sm, return ret; } -int ObMysqlRequestBuilder::build_last_insert_id_sync_packet(ObMysqlSM *sm, - ObMIOBuffer &mio_buf, - ObClientSessionInfo &client_info, - ObMysqlServerSession *server_session, - const ObProxyProtocol ob_proxy_protocol) +int ObMysqlRequestBuilder::build_session_user_vars_sync_packet(ObMysqlSM *sm, + ObMIOBuffer &mio_buf, + ObClientSessionInfo &client_info, + ObMysqlServerSession *server_session, + const ObProxyProtocol ob_proxy_protocol) { int ret = OB_SUCCESS; ObMySQLCmd cmd = OB_MYSQL_COM_QUERY; ObSqlString reset_sql; ObServerSessionInfo &server_info = server_session->get_session_info(); - if (OB_FAIL(client_info.extract_last_insert_id_reset_sql(server_info, reset_sql))) { - LOG_WARN("fail to extract last_insert_id variable reset sql", K(ret)); + if (OB_FAIL(client_info.extract_user_variable_reset_sql(server_info, reset_sql))) { + LOG_WARN("fail to extract variable reset sql", K(ret)); } else { uint8_t compressed_seq = 0; if (ObProxyProtocol::PROTOCOL_OB20 == ob_proxy_protocol) { - ObSEArray extra_info; - char extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; - if (OB_FAIL(ObProxyTraceUtils::build_extra_info_for_server(sm, extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, - extra_info, true))) { + ObSEArray extra_info; + ObSqlString sess_info_value; + char client_ip_buf[MAX_IP_BUFFER_LEN] = "\0"; + char server_extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; + if (OB_FAIL(ObProxyTraceUtils::build_related_extra_info_all(extra_info, sm, + client_ip_buf, MAX_IP_BUFFER_LEN, server_extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, + sess_info_value, true))) { LOG_WARN("fail to build extra info for server", K(ret)); } else if (OB_FAIL(ObMysqlOB20PacketWriter::write_request_packet(mio_buf, cmd, reset_sql.string(), - server_session->get_server_sessid(), - server_session->get_next_server_request_id(), - compressed_seq, compressed_seq, true, false, - server_info.is_new_extra_info_supported(), - &extra_info))) { + server_session->get_server_sessid(), + server_session->get_next_server_request_id(), + compressed_seq, compressed_seq, true, false, false, + server_info.is_new_extra_info_supported(), + sm->get_client_session()->is_trans_internal_routing(), + &extra_info))) { LOG_WARN("fail to write request packet in ob20", K(ret)); } else { /* nothing */ } } else { @@ -213,12 +229,11 @@ int ObMysqlRequestBuilder::build_last_insert_id_sync_packet(ObMysqlSM *sm, if (OB_SUCC(ret)) { server_session->set_compressed_seq(compressed_seq); - LOG_DEBUG("will sync last_insert_id variable", K(reset_sql)); + LOG_DEBUG("will sync session user variables", K(reset_sql)); } else { LOG_WARN("fail to write packet", K(cmd), K(reset_sql), K(ob_proxy_protocol), K(ret)); } } - return ret; } @@ -235,16 +250,20 @@ int ObMysqlRequestBuilder::build_start_trans_request(ObMysqlSM *sm, uint8_t compressed_seq = 0; if (ObProxyProtocol::PROTOCOL_OB20 == ob_proxy_protocol) { - ObSEArray extra_info; - char extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; - if (OB_FAIL(ObProxyTraceUtils::build_extra_info_for_server(sm, extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, - extra_info, true))) { - LOG_WARN("fail to build extra info for server", K(ret)); + ObSEArray extra_info; + ObSqlString sess_info_value; + char client_ip_buf[MAX_IP_BUFFER_LEN] = "\0"; + char server_extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; + if (OB_FAIL(ObProxyTraceUtils::build_related_extra_info_all(extra_info, sm, + client_ip_buf, MAX_IP_BUFFER_LEN, server_extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, + sess_info_value, true))) { + LOG_WARN("fail to build related extra info", K(ret)); } else if (OB_FAIL(ObMysqlOB20PacketWriter::write_request_packet(mio_buf, cmd, sql, server_session->get_server_sessid(), server_session->get_next_server_request_id(), - compressed_seq, compressed_seq, true, false, + compressed_seq, compressed_seq, true, false, false, server_info.is_new_extra_info_supported(), + sm->get_client_session()->is_trans_internal_routing(), &extra_info))) { LOG_WARN("fail to write request packet in ob20", K(ret)); } else { /* nothing */ } @@ -264,6 +283,54 @@ int ObMysqlRequestBuilder::build_start_trans_request(ObMysqlSM *sm, return ret; } +int ObMysqlRequestBuilder::build_xa_start_request(ObMysqlSM *sm, + ObMIOBuffer &mio_buf, + ObClientSessionInfo &client_info, + ObMysqlServerSession *server_session, + const ObProxyProtocol ob_proxy_protocol) +{ + LOG_DEBUG("start to build xa start request"); + int ret = OB_SUCCESS; + ObString &xa_start_req_pkt = client_info.get_start_trans_sql(); + ObString xa_pkt_payload(xa_start_req_pkt.length() - MYSQL_NET_META_LENGTH, + xa_start_req_pkt.ptr() + MYSQL_NET_META_LENGTH); + ObServerSessionInfo &server_info = server_session->get_session_info(); + ObMySQLCmd cmd = OB_MYSQL_COM_STMT_PREPARE_EXECUTE; + uint8_t compressed_seq = 0; + if (ObProxyProtocol::PROTOCOL_OB20 == ob_proxy_protocol) { + ObSEArray extra_info; + ObSqlString sess_info_value; + char client_ip_buf[MAX_IP_BUFFER_LEN] = "\0"; + char server_extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; + if (OB_FAIL(ObProxyTraceUtils::build_related_extra_info_all(extra_info, sm, + client_ip_buf, MAX_IP_BUFFER_LEN, server_extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, + sess_info_value, true))) { + LOG_WARN("fail to build related extra info", K(ret)); + } else if (OB_FAIL(ObMysqlOB20PacketWriter::write_request_packet(mio_buf, cmd, xa_pkt_payload, + server_session->get_server_sessid(), + server_session->get_next_server_request_id(), + compressed_seq, compressed_seq, true, false, false, + server_info.is_new_extra_info_supported(), + sm->get_client_session()->is_trans_internal_routing(), + &extra_info))) { + LOG_WARN("fail to write request packet in ob20", K(ret)); + } else { /* nothing */ } + } else { + const bool need_compress = ob_proxy_protocol == ObProxyProtocol::PROTOCOL_CHECKSUM ? true : false; + ret = ObMysqlPacketWriter::write_request_packet(mio_buf, cmd, xa_pkt_payload, compressed_seq, + need_compress, server_info.is_checksum_on()); + } + + if (OB_SUCC(ret)) { + server_session->set_compressed_seq(compressed_seq); + LOG_DEBUG("will send to sync xa start", K(xa_pkt_payload)); + } else { + LOG_WARN("fail to write xa start request to buffer", K(cmd), K(xa_pkt_payload), K(ob_proxy_protocol), K(ret)); + } + + return OB_SUCCESS; +} + int ObMysqlRequestBuilder::build_prepare_request(ObMysqlSM *sm, ObMIOBuffer &mio_buf, ObClientSessionInfo &client_info, @@ -279,16 +346,20 @@ int ObMysqlRequestBuilder::build_prepare_request(ObMysqlSM *sm, } else { uint8_t compressed_seq = 0; if (ObProxyProtocol::PROTOCOL_OB20 == ob_proxy_protocol) { - ObSEArray extra_info; - char extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; - if (OB_FAIL(ObProxyTraceUtils::build_extra_info_for_server(sm, extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, - extra_info, true))) { - LOG_WARN("fail to build extra info for server", K(ret)); + ObSEArray extra_info; + ObSqlString sess_info_value; + char client_ip_buf[MAX_IP_BUFFER_LEN] = "\0"; + char server_extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; + if (OB_FAIL(ObProxyTraceUtils::build_related_extra_info_all(extra_info, sm, + client_ip_buf, MAX_IP_BUFFER_LEN, server_extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, + sess_info_value, true))) { + LOG_WARN("fail to build related extra info", K(ret)); } else if (OB_FAIL(ObMysqlOB20PacketWriter::write_request_packet(mio_buf, cmd, ps_sql, server_session->get_server_sessid(), server_session->get_next_server_request_id(), - compressed_seq, compressed_seq, true, false, - server_info.is_new_extra_info_supported(), + compressed_seq, compressed_seq, true, false, false, + server_info.is_new_extra_info_supported(), + sm->get_client_session()->is_trans_internal_routing(), &extra_info))) { LOG_WARN("fail to write request packet in ob20", K(ret)); } else { /* nothing */ } @@ -338,16 +409,20 @@ int ObMysqlRequestBuilder::build_text_ps_prepare_request(ObMysqlSM *sm, } else { uint8_t compressed_seq = 0; if (ObProxyProtocol::PROTOCOL_OB20 == ob_proxy_protocol) { - ObSEArray extra_info; - char extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; - if (OB_FAIL(ObProxyTraceUtils::build_extra_info_for_server(sm, extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, - extra_info, true))) { - LOG_WARN("fail to build extra info for server", K(ret)); + ObSEArray extra_info; + ObSqlString sess_info_value; + char client_ip_buf[MAX_IP_BUFFER_LEN] = "\0"; + char server_extra_info_buf[SERVER_EXTRA_INFO_BUF_MAX_LEN] = "\0"; + if (OB_FAIL(ObProxyTraceUtils::build_related_extra_info_all(extra_info, sm, + client_ip_buf, MAX_IP_BUFFER_LEN, server_extra_info_buf, SERVER_EXTRA_INFO_BUF_MAX_LEN, + sess_info_value, true))) { + LOG_WARN("fail to build related extra info", K(ret)); } else if (OB_FAIL(ObMysqlOB20PacketWriter::write_request_packet(mio_buf, cmd, sql, server_session->get_server_sessid(), server_session->get_next_server_request_id(), - compressed_seq, compressed_seq, true, false, - server_info.is_new_extra_info_supported(), + compressed_seq, compressed_seq, true, false, false, + server_info.is_new_extra_info_supported(), + sm->get_client_session()->is_trans_internal_routing(), &extra_info))) { LOG_WARN("fail to write request packet in ob20", K(ret)); } else { /* nothing */ } @@ -368,6 +443,24 @@ int ObMysqlRequestBuilder::build_text_ps_prepare_request(ObMysqlSM *sm, return ret; } +int ObMysqlRequestBuilder::build_binlog_login_packet(ObMysqlSM *sm, + ObMIOBuffer &mio_buf, + ObClientSessionInfo &client_info, + ObMysqlServerSession *server_session, + const ObProxyProtocol ob_proxy_protocol) +{ + UNUSED(sm); + UNUSED(server_session); + UNUSED(ob_proxy_protocol); + + OMPKHandshakeResponse tg_hsr = client_info.get_login_req().get_hsr_result().response_; + tg_hsr.set_username(client_info.get_login_req().get_hsr_result().full_name_); + tg_hsr.set_seq(1); + tg_hsr.reset_connect_attr(); + + return packet::ObMysqlPacketWriter::write_packet(mio_buf, tg_hsr); +} + } // end of namespace proxy } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_request_builder.h b/src/obproxy/proxy/mysqllib/ob_mysql_request_builder.h index e7ea39e32..137b40974 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_request_builder.h +++ b/src/obproxy/proxy/mysqllib/ob_mysql_request_builder.h @@ -53,6 +53,13 @@ class ObMysqlRequestBuilder ObClientSessionInfo &client_info, ObMysqlServerSession *server_session, const ObProxyProtocol ob_proxy_protocol); + + // build binlog login request + static int build_binlog_login_packet(ObMysqlSM *sm, + event::ObMIOBuffer &mio_buf, + ObClientSessionInfo &client_info, + ObMysqlServerSession *server_session, + const ObProxyProtocol ob_proxy_protocol); // build saved login packet to send saved login request static int build_saved_login_packet(ObMysqlSM *sm, @@ -88,12 +95,12 @@ class ObMysqlRequestBuilder ObMysqlServerSession *server_session, const ObProxyProtocol ob_proxy_protocol); - // build OB_MYSQL_COM_QUERY packet to sync last_insert_id var - static int build_last_insert_id_sync_packet(ObMysqlSM *sm, - event::ObMIOBuffer &mio_buf, - ObClientSessionInfo &client_info, - ObMysqlServerSession *server_session, - const ObProxyProtocol ob_proxy_protocol); + // build OB_MYSQL_COM_QUERY packet to sync session user vars + static int build_session_user_vars_sync_packet(ObMysqlSM *sm, + event::ObMIOBuffer &mio_buf, + ObClientSessionInfo &client_info, + ObMysqlServerSession *server_session, + const ObProxyProtocol ob_proxy_protocol); // build start transaction request packet static int build_start_trans_request(ObMysqlSM *sm, @@ -101,6 +108,12 @@ class ObMysqlRequestBuilder ObClientSessionInfo &client_info, ObMysqlServerSession *server_session, const ObProxyProtocol ob_proxy_protocol); + + static int build_xa_start_request(ObMysqlSM *sm, + event::ObMIOBuffer &mio_buf, + ObClientSessionInfo &client_info, + ObMysqlServerSession *server_session, + const ObProxyProtocol ob_proxy_protocol); // build mysql request packet static int build_mysql_request(event::ObMIOBuffer &mio_buf, diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_resp_analyzer.cpp b/src/obproxy/proxy/mysqllib/ob_mysql_resp_analyzer.cpp index 4c8813dd1..b8b752c58 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_resp_analyzer.cpp +++ b/src/obproxy/proxy/mysqllib/ob_mysql_resp_analyzer.cpp @@ -75,7 +75,10 @@ inline int ObMysqlPacketMetaAnalyzer::update_cur_type(ObRespResult &result, cons // paket will treat as ok packet. // so in ResultSet Protocol, a packet can be detemined as ok packet by // both 0x00 === pkt_type and 1 != has_already_recived_eof_pkt_cnt - if (OB_MYSQL_COM_STMT_PREPARE == result.get_cmd()) { + if (OB_MYSQL_COM_BINLOG_DUMP == result.get_cmd() + || OB_MYSQL_COM_BINLOG_DUMP_GTID == result.get_cmd()) { + break; + } else if (OB_MYSQL_COM_STMT_PREPARE == result.get_cmd()) { /* Preapre Request, in OCEANBASE, maybe error + ok. in this case, should set OK_PACKET_ENDING_TYPE */ if (0 == prepare_ok_pkt_cnt && 0 == err_pkt_cnt) { cur_type_ = PREPARE_OK_PACKET_ENDING_TYPE; @@ -176,7 +179,10 @@ ObRespResult::ObRespResult() mysql_mode_(UNDEFINED_MYSQL_PROTOCOL_MODE), resp_type_(MAX_RESP_TYPE), trans_state_(IN_TRANS_STATE_BY_DEFAULT), - reserved_len_(0) + reserved_len_(0), + all_pkt_cnt_(0), + expect_pkt_cnt_(0), + is_recv_resultset_(false) { MEMSET(pkt_cnt_, 0, sizeof(pkt_cnt_)); } @@ -480,6 +486,27 @@ int ObRespResult::is_resp_finished(bool &finished, ObMysqlRespEndingType &ending } break; } + case OB_MYSQL_COM_BINLOG_DUMP: + case OB_MYSQL_COM_BINLOG_DUMP_GTID : { + if (1 == pkt_cnt_[EOF_PACKET_ENDING_TYPE]) { + finished = true; + ending_type = EOF_PACKET_ENDING_TYPE; + } else if (1 == pkt_cnt_[ERROR_PACKET_ENDING_TYPE]) { + finished = true; + ending_type = ERROR_PACKET_ENDING_TYPE; + } + break; + } + case OB_MYSQL_COM_REGISTER_SLAVE: { + if (1 == pkt_cnt_[ERROR_PACKET_ENDING_TYPE]) { + finished = true; + ending_type = ERROR_PACKET_ENDING_TYPE; + } else if (1 == pkt_cnt_[OK_PACKET_ENDING_TYPE]) { + finished = true; + ending_type = OK_PACKET_ENDING_TYPE; + } + break; + } default : { if (!is_supported_mysql_cmd(cmd_)) { ret = OB_NOT_SUPPORTED; diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_response.h b/src/obproxy/proxy/mysqllib/ob_mysql_response.h index 1003e9169..de5431d00 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_response.h +++ b/src/obproxy/proxy/mysqllib/ob_mysql_response.h @@ -78,7 +78,7 @@ struct ObRespAnalyzeResult bool is_server_can_use_compress() const { return (1 == server_capabilities_lower_.capability_flag_.OB_SERVER_CAN_USE_COMPRESS); } void set_server_trace_id(const common::ObString &trace_id); bool support_ssl() const { return 1 == server_capabilities_lower_.capability_flag_.OB_SERVER_SSL; } - + bool is_server_trans_internal_routing() const { return is_server_trans_internal_routing_; } bool is_not_supported_error() const { return (is_error_resp() && ER_NOT_SUPPORTED_YET == error_pkt_.get_err_code()); @@ -135,6 +135,18 @@ struct ObRespAnalyzeResult { return (is_error_resp() && -common::OB_STANDBY_WEAK_READ_ONLY == error_pkt_.get_err_code()); } + bool is_trans_free_route_not_supported_error() const + { + return (is_error_resp() && -common::OB_TRANS_FREE_ROUTE_NOT_SUPPORTED == error_pkt_.get_err_code()); + } + bool is_mysql_wrong_arguments_error() const + { + return (is_error_resp() && ER_WRONG_ARGUMENTS == error_pkt_.get_err_code()); + } + bool is_internal_error() const + { + return (is_error_resp() && -common::OB_INTERNAL_ERROR == error_pkt_.get_err_code()); + } inline uint32_t get_server_capability() const { @@ -186,7 +198,7 @@ struct ObRespAnalyzeResult Ob20ExtraInfo extra_info_; common::FLTObjManage flt_; - + bool is_server_trans_internal_routing_; DISALLOW_COPY_AND_ASSIGN(ObRespAnalyzeResult); }; @@ -235,6 +247,7 @@ inline void ObRespAnalyzeResult::reset() server_trace_id_.reset(); extra_info_.reset(); flt_.reset(); + is_server_trans_internal_routing_ = false; } inline void ObRespAnalyzeResult::set_server_trace_id(const common::ObString &trace_id) diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_response_builder.cpp b/src/obproxy/proxy/mysqllib/ob_mysql_response_builder.cpp index 39727b65c..596b68c05 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_response_builder.cpp +++ b/src/obproxy/proxy/mysqllib/ob_mysql_response_builder.cpp @@ -13,6 +13,9 @@ #define USING_LOG_PREFIX PROXY #include "proxy/mysqllib/ob_mysql_response_builder.h" #include "rpc/obmysql/packet/ompk_ok.h" +#include "rpc/obmysql/packet/ompk_prepare_execute.h" +#include "rpc/obmysql/packet/ompk_prepare_execute_req.h" +#include "rpc/obmysql/packet/ompk_eof.h" #include "packet/ob_proxy_cached_packets.h" #include "packet/ob_mysql_packet_writer.h" #include "packet/ob_mysql_packet_util.h" @@ -38,6 +41,7 @@ const ObString ObMysqlResponseBuilder::OBPROXY_PROXY_VERSION_NAME = "proxy_versi int ObMysqlResponseBuilder::build_ok_resp(ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, const bool is_in_trans, const bool is_state_changed) { @@ -60,8 +64,8 @@ int ObMysqlResponseBuilder::build_ok_resp(ObMIOBuffer &mio_buf, if (is_state_changed) { ssf.status_flags_.OB_SERVER_SESSION_STATE_CHANGED = 1; } - if (0 != autocommit) { - ssf.status_flags_.OB_SERVER_STATUS_AUTOCOMMIT = 1; + if (0 == autocommit) { + ssf.status_flags_.OB_SERVER_STATUS_AUTOCOMMIT = 0; } //ok_packet.set_server_status(ssf.status_flags_); ok_packet->set_status_flags(ssf.flags_); @@ -69,7 +73,7 @@ int ObMysqlResponseBuilder::build_ok_resp(ObMIOBuffer &mio_buf, ObString pkt_str; if (OB_FAIL(ok_packet->get_packet_str(pkt_str))) { LOG_WARN("fail to get ok packet str", K(ret)); - } else if (OB_FAIL(ObProxyPacketWriter::write_raw_packet(mio_buf, client_session, pkt_str))) { + } else if (OB_FAIL(ObProxyPacketWriter::write_raw_packet(mio_buf, client_session, protocol, pkt_str))) { LOG_WARN("fail to write packet", K(ret)); } } @@ -77,9 +81,187 @@ int ObMysqlResponseBuilder::build_ok_resp(ObMIOBuffer &mio_buf, return ret; } +/** + * @brief build OB_MYSQL_COM_STMT_PREPARE_EXECUTE response of XA_START request + * OB_MYSQL_COM_STMT_PREPARE_EXECUTE + * struct of OB_MYSQL_COM_STMT_PREPARE_EXECUTE RESPONSE: + * Prepare + * param_num > 0 ? ColDef * param_num + * Eof + * col_num > 0 ? ColDef * col_num + * Eof + * Row + * Eof + * Ok + * + * @param mio_buf + * @param client_request + * @param info + * @return int + */ +int ObMysqlResponseBuilder::build_prepare_execute_xa_start_resp(ObMIOBuffer &mio_buf, + ObProxyMysqlRequest &client_request, + ObMysqlClientSession &client_session, + const ObProxyProtocol protocol) +{ + int ret = OB_SUCCESS; + ObClientSessionInfo &info = client_session.get_session_info(); + OMPKPrepareExecuteReq prepare_req_pkt; + ObIOBufferReader *tmp_mio_reader = NULL; + ObMIOBuffer *tmp_mio_buf = &mio_buf; + + if (protocol == ObProxyProtocol::PROTOCOL_OB20) { + if (OB_ISNULL(tmp_mio_buf = new_empty_miobuffer())) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to new miobuffer", K(ret)); + } else if (OB_ISNULL(tmp_mio_reader = tmp_mio_buf->alloc_reader())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to alloc reader", K(ret)); + } + } + + if (OB_SUCC(ret)) { + // decode the prepare execute request + prepare_req_pkt.set_content(client_request.get_req_pkt().ptr() + MYSQL_NET_HEADER_LENGTH, + static_cast(client_request.get_packet_len())); + if (OB_FAIL(prepare_req_pkt.decode())) { + LOG_WARN("fail to decode the xa start prepare execute", K(ret)); + } + } + + if (OB_SUCC(ret)) { + // get seq + uint8_t seq = static_cast(client_request.get_packet_meta().pkt_seq_ + 1); + uint32_t sid = info.get_client_ps_id(); + int64_t autocommit = info.get_cached_variables().get_autocommit(); + // write prepare execute resp + OMPKPrepareExecute prepare_pkt; + prepare_pkt.set_seq(seq++); + prepare_pkt.set_status(0); + prepare_pkt.set_statement_id(sid); + prepare_pkt.set_column_num(1); + prepare_pkt.set_param_num(static_cast(prepare_req_pkt.get_param_num())); + prepare_pkt.set_warning_count(0); + prepare_pkt.set_extend_flag(0); + prepare_pkt.set_has_result_set(1); + if (OB_FAIL(ObMysqlPacketWriter::write_packet(*tmp_mio_buf, prepare_pkt))) { + seq--; + LOG_WARN("fail to write prepare pkt of resp of xa start hold", K(ret)); + } + // write params Coldef + for (int32_t i = 0; OB_SUCC(ret) && i < prepare_req_pkt.get_param_num(); i++) { + ObMySQLField param_field; + param_field.cname_ = "?"; + param_field.type_ = prepare_req_pkt.get_param_types().at(i); + param_field.type_info_ = prepare_req_pkt.get_type_infos().at(i); + param_field.flags_ = 0; + param_field.charsetnr_ = static_cast(info.get_collation_connection()); + param_field.length_ = 0; + if (OB_FAIL(ObMysqlPacketUtil::encode_field_packet(*tmp_mio_buf, seq, param_field))) { + LOG_WARN("fail to write field pkt of resp of xa start hold", K(ret), K(param_field)); + } + } + // write Eof + if (prepare_req_pkt.get_param_num() > 0 && OB_SUCC(ret)) { + uint16_t status_flag_0 = 0; + status_flag_0 |= (1 << OB_SERVER_STATUS_IN_TRANS_POS); + if (0 != autocommit) { + status_flag_0 |= (1 << OB_SERVER_STATUS_AUTOCOMMIT_POS); + } + if (OB_FAIL(ObMysqlPacketUtil::encode_eof_packet(*tmp_mio_buf, seq, status_flag_0))){ + LOG_WARN("fail to write eof pkt of resp of xa start hold", K(ret)); + } + } + // ColDef: row field + if (OB_SUCC(ret)) { + ObMySQLField row_col_field; + row_col_field.cname_ = client_request.get_parse_sql(); + row_col_field.org_cname_ = client_request.get_parse_sql(); + row_col_field.type_ = OB_MYSQL_TYPE_LONG; + row_col_field.flags_ = OB_MYSQL_BINARY_FLAG; + row_col_field.charsetnr_ = CS_TYPE_BINARY; + row_col_field.length_ = 0; + if (OB_FAIL(ObMysqlPacketUtil::encode_field_packet(*tmp_mio_buf, seq, row_col_field))) { + LOG_WARN("fail to write field pkt of resp of xa start hold", K(ret)); + } + } + // Eof + if (OB_SUCC(ret)) { + uint16_t status_flag_1 = 0; + if (0 != autocommit) { + status_flag_1 |= (1 << OB_SERVER_STATUS_AUTOCOMMIT_POS); + } + status_flag_1 |= (1 << OB_SERVER_STATUS_IN_TRANS_POS); + status_flag_1 |= (1 << OB_SERVER_STATUS_CURSOR_EXISTS_POS); + if (OB_FAIL(ObMysqlPacketUtil::encode_eof_packet(*tmp_mio_buf, seq, status_flag_1))) { + LOG_WARN("fail to write eof pkt of resp of xa start hold", K(ret)); + } + } + // Row + if (OB_SUCC(ret)) { + ObObj field_value; + field_value.set_int32(0); + ObNewRow row; + row.cells_ = &field_value; + row.count_ = 1; + if (ObMysqlPacketUtil::encode_row_packet(*tmp_mio_buf, BINARY, seq, row)) { + LOG_WARN("fail to write row pkt", K(ret)); + } + } + // write Eof + if (OB_SUCC(ret)) { + uint16_t status_flag_2 = 0; + if (0 != autocommit) { + status_flag_2 |= (1 << OB_SERVER_STATUS_AUTOCOMMIT_POS); + } + status_flag_2 |= (1 << OB_SERVER_STATUS_IN_TRANS_POS); + status_flag_2 |= (1 << OB_SERVER_STATUS_LAST_ROW_SENT_POS); + if (OB_FAIL(ObMysqlPacketUtil::encode_eof_packet(*tmp_mio_buf, seq, status_flag_2))) { + LOG_WARN("fail to write eof pkt of resp of xa start hold", K(ret)); + } + } + // Ok + if (OB_SUCC(ret)) { + uint16_t status_flag_3 = 0; + if (0 != autocommit) { + status_flag_3 |= (1 << OB_SERVER_STATUS_AUTOCOMMIT_POS); + } + status_flag_3 |= (1 << OB_SERVER_STATUS_IN_TRANS_POS); + status_flag_3 |= (1 << OB_SERVER_STATUS_NO_INDEX_USED_POS); + status_flag_3 |= (1 << OB_SERVER_STATUS_CURSOR_EXISTS_POS); + status_flag_3 |= (1 << OB_SERVER_STATUS_LAST_ROW_SENT_POS); + status_flag_3 |= (1 << OB_SERVER_SESSION_STATE_CHANGED_POS); + if (OB_FAIL(ObMysqlPacketUtil::encode_ok_packet(*tmp_mio_buf, seq, 0, info.get_orig_capability_flags(), status_flag_3))) { + LOG_WARN("fail to write last ok pkt of resp of xa start hold", K(ret)); + } else { + LOG_DEBUG("succ to write prepare execute packets of resp of xa start hold"); + } + } else { + LOG_WARN("fail to write prepare execute packets of resp of xa start hold", K(ret)); + } + + if (OB_SUCC(ret) && protocol == ObProxyProtocol::PROTOCOL_OB20) { + Ob20ProtocolHeader &ob20_head = client_session.get_session_info().ob20_request_.ob20_header_; + uint8_t compressed_seq = static_cast(client_session.get_compressed_seq() + 1); + Ob20ProtocolHeaderParam ob20_head_param(client_session.get_cs_id(), ob20_head.request_id_, compressed_seq, + compressed_seq, true, false, false, + client_session.is_client_support_new_extra_info(), + client_session.is_trans_internal_routing()); + if (OB_FAIL(ObProto20Utils::consume_and_compress_data(tmp_mio_reader, &mio_buf, + tmp_mio_reader->read_avail(), ob20_head_param))) { + LOG_WARN("fail to consume and compress data for executor response packet in ob20", K(ret)); + } else { + LOG_DEBUG("succ to executor response in ob20 packet"); + } + } + } + return ret; +} + int ObMysqlResponseBuilder::build_select_tx_ro_resp(ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, const bool is_in_trans) { int ret = OB_SUCCESS; @@ -111,7 +293,7 @@ int ObMysqlResponseBuilder::build_select_tx_ro_resp(ObMIOBuffer &mio_buf, } // encode to mio_buf - if (OB_FAIL(ObProxyPacketWriter::write_kv_resultset(mio_buf, client_session, seq, + if (OB_FAIL(ObProxyPacketWriter::write_kv_resultset(mio_buf, client_session, protocol, seq, field, field_value, status_flag))) { LOG_WARN("fail to write kv resultset", K(ret)); } @@ -122,8 +304,9 @@ int ObMysqlResponseBuilder::build_select_tx_ro_resp(ObMIOBuffer &mio_buf, int ObMysqlResponseBuilder::build_select_route_addr_resp(ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, const bool is_in_trans, - int64_t addr) + const struct sockaddr &addr) { int ret = OB_SUCCESS; ObClientSessionInfo &info = client_session.get_session_info(); @@ -135,13 +318,16 @@ int ObMysqlResponseBuilder::build_select_route_addr_resp(ObMIOBuffer &mio_buf, ObMySQLField field; field.cname_ = OBPROXY_ROUTE_ADDR_NAME; field.org_cname_ = OBPROXY_ROUTE_ADDR_NAME; - field.type_ = OB_MYSQL_TYPE_LONGLONG; + field.type_ = OB_MYSQL_TYPE_VARCHAR; field.charsetnr_ = CS_TYPE_BINARY; field.flags_ = OB_MYSQL_BINARY_FLAG; // get filed value ObObj field_value; - field_value.set_int(addr); + char buf[MAX_IP_ADDR_LENGTH]; + memset(buf, 0, sizeof(buf)); + net::ops_ip_ntop(addr, buf, MAX_IP_ADDR_LENGTH); + field_value.set_varchar(buf); // get status flag uint16_t status_flag = 0; @@ -154,7 +340,7 @@ int ObMysqlResponseBuilder::build_select_route_addr_resp(ObMIOBuffer &mio_buf, } // encode to mio_buf - if (OB_FAIL(ObProxyPacketWriter::write_kv_resultset(mio_buf, client_session, seq, + if (OB_FAIL(ObProxyPacketWriter::write_kv_resultset(mio_buf, client_session, protocol, seq, field, field_value, status_flag))) { LOG_WARN("fail to write kv resultset", K(ret)); } @@ -165,6 +351,7 @@ int ObMysqlResponseBuilder::build_select_route_addr_resp(ObMIOBuffer &mio_buf, int ObMysqlResponseBuilder::build_select_proxy_version_resp(ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, const bool is_in_trans) { int ret = OB_SUCCESS; @@ -201,7 +388,8 @@ int ObMysqlResponseBuilder::build_select_proxy_version_resp(ObMIOBuffer &mio_buf } // encode to mio_buf - if (OB_FAIL(ObProxyPacketWriter::write_kv_resultset(mio_buf, client_session, seq, field, field_value, status_flag))) { + if (OB_FAIL(ObProxyPacketWriter::write_kv_resultset(mio_buf, client_session, protocol, + seq, field, field_value, status_flag))) { LOG_WARN("fail to write kv resultset", K(ret)); } diff --git a/src/obproxy/proxy/mysqllib/ob_mysql_response_builder.h b/src/obproxy/proxy/mysqllib/ob_mysql_response_builder.h index 0c0cbb105..e021a0ce5 100644 --- a/src/obproxy/proxy/mysqllib/ob_mysql_response_builder.h +++ b/src/obproxy/proxy/mysqllib/ob_mysql_response_builder.h @@ -13,6 +13,8 @@ #ifndef OBPROXY_MYSQL_RESPONSE_BUILDER_H #define OBPROXY_MYSQL_RESPONSE_BUILDER_H #include "utils/ob_proxy_lib.h" +#include "common/obsm_row.h" +#include "proxy/mysqllib/ob_mysql_common_define.h" namespace oceanbase { @@ -34,60 +36,77 @@ class ObMysqlResponseBuilder static const common::ObString OBPROXY_PROXY_VERSION_NAME; static int build_ok_resp(event::ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, - ObMysqlClientSession &client_session, const bool is_in_trans, const bool is_state_changed); + ObMysqlClientSession &client_session, const ObProxyProtocol protocol, + const bool is_in_trans, const bool is_state_changed); static int build_start_trans_resp(event::ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, - ObMysqlClientSession &client_session); + ObMysqlClientSession &client_session, const ObProxyProtocol protocol); + + static int build_prepare_execute_xa_start_resp(event::ObMIOBuffer &mio_buf, + ObProxyMysqlRequest &client_request, + ObMysqlClientSession &client_session, + const ObProxyProtocol protocol); static int build_select_tx_ro_resp(event::ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, const bool is_in_trans); static int build_ok_resq_with_state_changed(event::ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, const bool is_in_trans); - static int build_select_route_addr_resp(event::ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, - ObMysqlClientSession &client_session, const bool is_in_trans, int64_t addr); + static int build_select_route_addr_resp(event::ObMIOBuffer &mio_buf, + ObProxyMysqlRequest &client_request, + ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, + const bool is_in_trans, + const struct sockaddr &addr); static int build_set_route_addr_resp(event::ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, const bool is_in_trans); static int build_select_proxy_version_resp(event::ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, const bool is_in_trans); }; inline int ObMysqlResponseBuilder::build_start_trans_resp(event::ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, - ObMysqlClientSession &client_session) + ObMysqlClientSession &client_session, + const ObProxyProtocol protocol) { static const bool is_in_trans = true; static const bool is_state_changed = false; - return build_ok_resp(mio_buf, client_request, client_session, is_in_trans, is_state_changed); + return build_ok_resp(mio_buf, client_request, client_session, protocol, is_in_trans, is_state_changed); } inline int ObMysqlResponseBuilder::build_ok_resq_with_state_changed(event::ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, const bool is_in_trans) { static const bool is_state_changed = true; - return build_ok_resp(mio_buf, client_request, client_session, is_in_trans, is_state_changed); + return build_ok_resp(mio_buf, client_request, client_session, protocol, is_in_trans, is_state_changed); } inline int ObMysqlResponseBuilder::build_set_route_addr_resp(event::ObMIOBuffer &mio_buf, ObProxyMysqlRequest &client_request, ObMysqlClientSession &client_session, + const ObProxyProtocol protocol, const bool is_in_trans) { static const bool is_state_changed = false; - return build_ok_resp(mio_buf, client_request, client_session, is_in_trans, is_state_changed); + return build_ok_resp(mio_buf, client_request, client_session, protocol, is_in_trans, is_state_changed); } } // end of namespace proxy diff --git a/src/obproxy/proxy/mysqllib/ob_proxy_mysql_request.h b/src/obproxy/proxy/mysqllib/ob_proxy_mysql_request.h index 40d0fd1da..39e9a86a4 100644 --- a/src/obproxy/proxy/mysqllib/ob_proxy_mysql_request.h +++ b/src/obproxy/proxy/mysqllib/ob_proxy_mysql_request.h @@ -78,6 +78,7 @@ class ObProxyMysqlRequest static common::ObString get_print_sql(const common::ObString &req_sql, const int64_t sql_len = PRINT_SQL_LEN); common::ObString get_req_pkt(); obutils::ObSqlParseResult &get_parse_result(); + const obutils::ObSqlParseResult &get_parse_result() const; obutils::ObSqlParseResult *get_ps_parse_result() { return ps_result_; } void set_ps_parse_result(obutils::ObSqlParseResult *ps_result) { ps_result_ = ps_result; } void set_text_ps_parse_result(obutils::ObSqlParseResult *text_ps_result) @@ -111,6 +112,7 @@ class ObProxyMysqlRequest int64_t get_packet_len() { return meta_.pkt_len_; } ObMysqlPacketMeta &get_packet_meta() { return meta_; } + const ObMysqlPacketMeta &get_packet_meta() const { return meta_; } void set_packet_meta(const ObMysqlPacketMeta &meta) { meta_ = meta; } // add received request @@ -196,7 +198,17 @@ inline void ObProxyMysqlRequest::reset(bool is_reset_origin_db_table /* true */) inline obutils::ObSqlParseResult &ObProxyMysqlRequest::get_parse_result() { obutils::ObSqlParseResult *result = &result_; - if ((obmysql::OB_MYSQL_COM_STMT_EXECUTE == meta_.cmd_ || obmysql::OB_MYSQL_COM_STMT_SEND_LONG_DATA == meta_.cmd_) + if ((obmysql::OB_MYSQL_COM_STMT_EXECUTE == meta_.cmd_ || obmysql::OB_MYSQL_COM_STMT_SEND_LONG_DATA == meta_.cmd_) + && NULL != ps_result_) { + result = ps_result_; + } + return *result; +} + +const obutils::ObSqlParseResult &ObProxyMysqlRequest::get_parse_result() const +{ + const obutils::ObSqlParseResult *result = &result_; + if ((obmysql::OB_MYSQL_COM_STMT_EXECUTE == meta_.cmd_ || obmysql::OB_MYSQL_COM_STMT_SEND_LONG_DATA == meta_.cmd_) && NULL != ps_result_) { result = ps_result_; } diff --git a/src/obproxy/proxy/mysqllib/ob_proxy_ob20_request.h b/src/obproxy/proxy/mysqllib/ob_proxy_ob20_request.h index 2fe651323..befc96198 100644 --- a/src/obproxy/proxy/mysqllib/ob_proxy_ob20_request.h +++ b/src/obproxy/proxy/mysqllib/ob_proxy_ob20_request.h @@ -40,7 +40,7 @@ struct ObProxyObProto20Request { // ob20 payload could contain more than one mysql packet, the total mysql packet len stored here int64_t remain_payload_len_; - bool ob20_request_received_done_; + bool ob20_request_received_done_; // ob2.0 request from client received done, and tail crc not handled yet Ob20ProtocolHeader ob20_header_; TO_STRING_KV(K_(remain_payload_len), K_(ob20_request_received_done), K_(ob20_header)); diff --git a/src/obproxy/proxy/mysqllib/ob_proxy_session_info.cpp b/src/obproxy/proxy/mysqllib/ob_proxy_session_info.cpp index aa945369d..6268bd3b4 100644 --- a/src/obproxy/proxy/mysqllib/ob_proxy_session_info.cpp +++ b/src/obproxy/proxy/mysqllib/ob_proxy_session_info.cpp @@ -182,7 +182,7 @@ void ObServerSessionInfo::reuse_text_ps_version_set() ObClientSessionInfo::ObClientSessionInfo() : is_inited_(false), is_trans_specified_(false), is_global_vars_changed_(false), - is_user_idc_name_set_(false), is_read_consistency_set_(false), is_oracle_mode_(false), + is_user_idc_name_set_(false), is_read_consistency_set_(false), is_oracle_mode_(false), is_proxy_route_policy_set_(false), enable_shard_authority_(false), enable_reset_db_(true), client_cap_(0), server_cap_(0), safe_read_snapshot_(0), @@ -192,7 +192,8 @@ ObClientSessionInfo::ObClientSessionInfo() var_set_processor_(NULL), cluster_id_(OB_INVALID_CLUSTER_ID), real_meta_cluster_name_(), real_meta_cluster_name_str_(NULL), server_type_(DB_OB_MYSQL), shard_conn_(NULL), shard_prop_(NULL), - group_id_(OBPROXY_MAX_DBMESH_ID), is_allow_use_last_session_(true), + group_id_(OBPROXY_MAX_DBMESH_ID), table_id_(OBPROXY_MAX_DBMESH_ID), es_id_(OBPROXY_MAX_DBMESH_ID), + is_allow_use_last_session_(true), consistency_level_prop_(INVALID_CONSISTENCY), recv_client_ps_id_(0), ps_id_(0), ps_entry_(NULL), ps_id_entry_(NULL), ps_id_entry_map_(), text_ps_name_entry_(NULL), text_ps_name_entry_map_(), cursor_id_(0), cursor_id_addr_map_(), @@ -200,14 +201,13 @@ ObClientSessionInfo::ObClientSessionInfo() is_read_only_user_(false), is_request_follower_user_(false) { - const int BUCKET_SIZE = 8; is_session_pool_client_ = true; MEMSET(scramble_buf_, 0, sizeof(scramble_buf_)); MEMSET(idc_name_buf_, 0, sizeof(idc_name_buf_)); MEMSET(client_host_buf_, 0, sizeof(client_host_buf_)); MEMSET(username_buf_, 0, sizeof(username_buf_)); - request_send_addrs_.create(BUCKET_SIZE); ob20_request_.reset(); + ob20_request_.reset(); } ObClientSessionInfo::~ObClientSessionInfo() @@ -319,7 +319,7 @@ int ObClientSessionInfo::set_tenant_name(const ObString &tenant_name) int ObClientSessionInfo::set_vip_addr_name(const common::ObAddr &vip_addr) { int ret = OB_SUCCESS; - char vip_name[OB_IP_STR_BUFF]; + char vip_name[MAX_IP_ADDR_LENGTH]; if (OB_UNLIKELY(!vip_addr.ip_to_string(vip_name, static_cast(sizeof(vip_name))))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to covert ip to string", K(vip_name), K(ret)); @@ -377,19 +377,25 @@ int ObClientSessionInfo::set_ldg_logical_tenant_name(const ObString &tenant_name return field_mgr_.set_ldg_logical_tenant_name(tenant_name); } -int ObClientSessionInfo::update_sess_sync_info(const ObString& sess_info) +int ObClientSessionInfo::update_sess_sync_info(const ObString& sess_info, common::ObSimpleTrace<4096> &trace_log) { int ret = OB_SUCCESS; const char *buf = sess_info.ptr(); const int64_t len = sess_info.length(); const char *end = buf + len; // decode sess_info + const int MAX_TYPE_RECORD = 32; + char type_record[MAX_TYPE_RECORD]; + memset(type_record, '0', MAX_TYPE_RECORD); if (NULL != sess_info.ptr()) { while (OB_SUCC(ret) && buf < end) { int16_t info_type = 0; int32_t info_len = 0; ObMySQLUtil::get_int2(buf, info_type); ObMySQLUtil::get_int4(buf, info_len); + if(info_type < MAX_TYPE_RECORD) { + type_record[info_type] = '1'; + } if (buf + info_len > end) { ret = OB_ERR_UNEXPECTED; LOG_ERROR("data is error", K(info_type), K(info_len), K(len), K(ret)); @@ -397,11 +403,19 @@ int ObClientSessionInfo::update_sess_sync_info(const ObString& sess_info) LOG_DEBUG("extra info", K(info_type), K(info_len), K(len)); char* info_value = NULL; ObString info_value_string; + if (OB_FAIL(inc_sess_field_version(info_type))) { + LOG_WARN("fail to update sess field versoin", K(info_type), K(ret)); + } if (OB_SUCC(sess_info_hash_map_.get_refactored(info_type, info_value_string))) { sess_info_hash_map_.erase_refactored(info_type); int64_t total_len = info_value_string.length(); op_fixed_mem_free(info_value_string.ptr(), total_len); } + int64_t client_version = 0; + if (OB_FAIL(ObProxyTraceUtils::get_sess_field_version(client_version , info_type, version_.sess_field_version_))) { + LOG_WARN("fail to set client session field version", K(info_type), K(ret)); + } else { + } info_value_string.reset(); if (OB_ISNULL(info_value = static_cast(op_fixed_mem_alloc(info_len + 6)))) { ret = OB_ALLOCATE_MEMORY_FAILED; @@ -417,6 +431,8 @@ int ObClientSessionInfo::update_sess_sync_info(const ObString& sess_info) } } } + type_record[MAX_TYPE_RECORD - 1] = '\0'; + trace_log.log_it("[get_sess]", "type", type_record); if (OB_SUCC(ret)) { version_.inc_sess_info_version(); LOG_DEBUG("update sess info succ", K(sess_info)); @@ -879,6 +895,46 @@ int ObClientSessionInfo::extract_all_variable_reset_sql(ObSqlString &sql) return ret; } +int ObClientSessionInfo::extract_user_variable_reset_sql(ObServerSessionInfo &server_info, + ObSqlString &sql) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("client session is not inited", K(ret)); + } else { + bool need_reset = false; + if (OB_FAIL(sql.append_fmt("SET"))) { + LOG_WARN("fail to append_fmt 'SET'", K(ret)); + } else if (!is_oceanbase_server()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("extract user variable reset sql only for oceanbase server"); + } else { /* do nothing */ } + + //reset user variable + if (OB_SUCC(ret)) { + if (need_reset_user_session_vars(server_info)) { + need_reset = true; + if (OB_FAIL(field_mgr_.format_user_var(sql))) { + LOG_WARN("fail to format_user_var.", K(sql), K(*this), + K(server_info), K(ret)); + } + } + } + + if (OB_SUCC(ret)) { + if (need_reset) { + *(sql.ptr() + sql.length() - 1) = ';'; //replace ',' with ';' + } else { + sql.reset(); + } + } else { + sql.reset(); + } + } + return ret; +} + int ObClientSessionInfo::extract_variable_reset_sql(ObServerSessionInfo &server_info, ObSqlString &sql) { @@ -1215,7 +1271,7 @@ void ObClientSessionInfo::destroy() field_mgr_.destroy(); login_req_.destroy(); destroy_sess_info_map(); - is_inited_ = false; + is_inited_ = false; } if (NULL != var_set_processor_) { ObDefaultSysVarSet *sys_set = field_mgr_.get_sys_var_set(); @@ -1267,6 +1323,8 @@ void ObClientSessionInfo::destroy() shard_prop_ = NULL; } group_id_ = OBPROXY_MAX_DBMESH_ID; + table_id_ = OBPROXY_MAX_DBMESH_ID; + es_id_ = OBPROXY_MAX_DBMESH_ID; is_allow_use_last_session_ = true; up_info_.reset(); } diff --git a/src/obproxy/proxy/mysqllib/ob_proxy_session_info.h b/src/obproxy/proxy/mysqllib/ob_proxy_session_info.h index 3d3e17a81..ec50f4f62 100644 --- a/src/obproxy/proxy/mysqllib/ob_proxy_session_info.h +++ b/src/obproxy/proxy/mysqllib/ob_proxy_session_info.h @@ -19,10 +19,12 @@ #include "lib/hash_func/murmur_hash.h" #include "lib/hash/ob_build_in_hashmap.h" #include "lib/hash/ob_hashset.h" +#include "lib/oblog/ob_simple_trace.h" #include "utils/ob_proxy_utils.h" #include "obutils/ob_cached_variables.h" #include "proxy/mysqllib/ob_session_field_mgr.h" #include "proxy/mysqllib/ob_proxy_auth_parser.h" +#include "proxy/mysqllib/ob_2_0_protocol_utils.h" #include "proxy/route/ob_ldc_struct.h" #include "proxy/mysql/ob_prepare_statement_struct.h" #include "proxy/mysql/ob_cursor_struct.h" @@ -48,6 +50,7 @@ class ObDefaultSysVarSet; namespace proxy { typedef common::hash::ObHashMap SessFieldHashMap; +typedef common::hash::ObHashMap SessFieldVersionHashMap; enum ObProxyChecksumSwitch { @@ -59,9 +62,9 @@ enum ObProxyChecksumSwitch class ObSessionVarVersion { public: - ObSessionVarVersion() { reset(); } + ObSessionVarVersion() { reset(); sess_field_version_.create(32, ObModIds::OB_PROXY_SESS_SYNC); } ~ObSessionVarVersion() { reset(); } - void reset() { memset(this, 0, sizeof(ObSessionVarVersion)); } + void reset(); void inc_common_hot_sys_var_version() { common_hot_sys_var_version_++; } void inc_common_sys_var_version() { common_sys_var_version_++; } @@ -73,6 +76,10 @@ class ObSessionVarVersion void inc_db_name_version() { db_name_version_++; } void inc_last_insert_id_version() { last_insert_id_version_++; } void inc_sess_info_version() { sess_info_version_++; } + int inc_sess_field_version(int16_t type); + SessFieldVersionHashMap& get_sess_field_version() { return sess_field_version_; } + + TO_STRING_KV(K_(common_hot_sys_var_version), K_(common_sys_var_version), K_(mysql_hot_sys_var_version), K_(mysql_sys_var_version), K_(hot_sys_var_version), K_(sys_var_version), K_(user_var_version), @@ -88,11 +95,44 @@ class ObSessionVarVersion int64_t db_name_version_; int64_t last_insert_id_version_; int64_t sess_info_version_; + SessFieldVersionHashMap sess_field_version_; private: DISALLOW_COPY_AND_ASSIGN(ObSessionVarVersion); }; + +inline int ObSessionVarVersion::inc_sess_field_version(int16_t type) +{ + int ret = OB_SUCCESS; + int64_t new_version = 0; + if (OB_FAIL(ObProxyTraceUtils::get_sess_field_version(new_version, type, sess_field_version_))) { + _PROXY_LOG(WARN, "fail to update session field versoin, query version failed, field type:%d, ret:%d",type, ret); + } + + if (OB_SUCC(ret)) { + new_version++; + if (OB_FAIL(sess_field_version_.set_refactored(type, new_version, 1))) { + _PROXY_LOG(WARN, "update session field versoin failed, field type:%d, ret:%d", type, ret); + } + } + return ret; +} + +inline void ObSessionVarVersion::reset() { + common_hot_sys_var_version_ = 0; + common_sys_var_version_ = 0; + mysql_hot_sys_var_version_ = 0; + mysql_sys_var_version_ = 0; + hot_sys_var_version_ = 0; + sys_var_version_ = 0; + user_var_version_ = 0; + db_name_version_ = 0; + last_insert_id_version_ = 0; + sess_info_version_ = 0; + sess_field_version_.clear(); +} + class ObSessionVarValHash { public: @@ -184,7 +224,7 @@ class ObServerSessionInfo int64_t get_db_name_version() const { return version_.db_name_version_; } int64_t get_last_insert_id_version() const { return version_.last_insert_id_version_; } int64_t get_sess_info_version() const { return version_.sess_info_version_; } - + SessFieldVersionHashMap& get_sess_field_version() { return version_.sess_field_version_; } void set_common_hot_sys_var_version(const int64_t version) { version_.common_hot_sys_var_version_ = version; } void set_common_sys_var_version(const int64_t version) { version_.common_sys_var_version_ = version; } void set_mysql_hot_sys_var_version(const int64_t version) { version_.mysql_hot_sys_var_version_ = version; } @@ -455,6 +495,12 @@ class ObClientSessionInfo return OB_TEST_CAPABILITY(server_cap_, OB_CAP_PL_ROUTE); } + bool is_server_support_session_var_sync() const { + return OB_TEST_CAPABILITY(server_cap_, OB_CAP_OB_PROTOCOL_V2) + && OB_TEST_CAPABILITY(server_cap_, OB_CAP_PROXY_SESSION_SYNC) + && OB_TEST_CAPABILITY(server_cap_, OB_CAP_PROXY_SESSION_VAR_SYNC); + } + bool is_oracle_mode() const { bool is_oracle_mode = false; if (is_sharding_user()) { @@ -486,6 +532,9 @@ class ObClientSessionInfo int64_t get_db_name_version() const { return version_.db_name_version_; } int64_t get_last_insert_id_version() const { return version_.last_insert_id_version_; } int64_t get_sess_info_version() const { return version_.sess_info_version_; } + SessFieldVersionHashMap& get_sess_field_version() { return version_.sess_field_version_; } + int inc_sess_field_version(int16_t type) { return version_.inc_sess_field_version(type); } + void set_db_name_version(const int64_t version) { version_.db_name_version_ = version; } @@ -499,7 +548,7 @@ class ObClientSessionInfo int set_ldg_logical_tenant_name(const common::ObString &tenant_name); int set_logic_tenant_name(const common::ObString &logic_tenant_name); int set_logic_database_name(const common::ObString &logic_database_name); - int update_sess_sync_info(const common::ObString& sess_info); + int update_sess_sync_info(const common::ObString& sess_info, common::ObSimpleTrace<4096> &trace_log); int get_cluster_name(common::ObString &cluster_name) const; int get_tenant_name(common::ObString &tenant_name) const; int get_vip_addr_name(common::ObString &vip_addr_name) const; @@ -571,6 +620,7 @@ class ObClientSessionInfo int extract_all_variable_reset_sql(common::ObSqlString &sql); int extract_variable_reset_sql(ObServerSessionInfo &server_info, common::ObSqlString &sql); + int extract_user_variable_reset_sql(ObServerSessionInfo &server_info, ObSqlString &sql); int extract_oceanbase_variable_reset_sql(ObServerSessionInfo &server_info, common::ObSqlString &sql, bool &need_reset); int extract_mysql_variable_reset_sql(ObServerSessionInfo &server_info, @@ -607,7 +657,7 @@ class ObClientSessionInfo //proxy route policy ObProxyRoutePolicyEnum get_proxy_route_policy() const { return proxy_route_policy_; } - void set_proxy_route_policy(ObProxyRoutePolicyEnum policy) { + void set_proxy_route_policy(ObProxyRoutePolicyEnum policy) { proxy_route_policy_ = policy; is_proxy_route_policy_set_ = true; } @@ -618,7 +668,6 @@ class ObClientSessionInfo void set_trans_specified_flag() { is_trans_specified_ = true; } void clear_trans_specified_flag() { is_trans_specified_ = false; } bool is_trans_specified() const { return is_trans_specified_; } - void set_user_identity(const ObProxyLoginUserType identity) { user_identity_ = identity; } ObProxyLoginUserType get_user_identity() const { return user_identity_; } bool enable_analyze_internal_cmd() const; @@ -666,10 +715,12 @@ class ObClientSessionInfo // deep copy, this function will alloc buf int set_start_trans_sql(const common::ObString &sql); + void set_xa_start_ps_id(const int32_t ps_id) { xa_start_ps_id_ = ps_id; } // reset start trans sql, free buf void reset_start_trans_sql(); - // get start trans sql + // get start trans sql / xa start req pkt common::ObString &get_start_trans_sql() { return saved_start_trans_sql_; } + int32_t get_xa_start_ps_id() const { return xa_start_ps_id_; }; obproxy::ObDefaultSysVarSet *get_sys_var_set() { return field_mgr_.get_sys_var_set(); } void set_sysvar_set_processor(ObSysVarSetProcessor &var_set_processor) { var_set_processor_ = &var_set_processor; } @@ -731,6 +782,12 @@ class ObClientSessionInfo void set_group_id(const int64_t group_id) { group_id_ = group_id; } int64_t get_group_id() { return group_id_; } + void set_table_id(const int64_t table_id) { table_id_ = table_id; } + int64_t get_table_id() { return table_id_; } + + void set_es_id(const int64_t es_id) { es_id_ = es_id; } + int64_t get_es_id() { return es_id_; } + bool is_sys_hot_version_changed() const { return hash_version_.hot_sys_var_version_ != version_.hot_sys_var_version_; } @@ -861,12 +918,17 @@ class ObClientSessionInfo void destroy_ps_id_addrs_map(); void destroy_sess_info_map(); - ObPsIdAddrs::ADDR_HASH_SET &get_request_send_addrs() { return request_send_addrs_; } + common::ObIArray &get_request_send_addrs() { return request_send_addrs_; } int remove_request_send_addr(const struct sockaddr &socket_addr) { int ret = OB_SUCCESS; net::ObIpEndpoint addr(socket_addr); - if (OB_FAIL(request_send_addrs_.erase_refactored(addr))) { - PROXY_LOG(WARN, "fail to erase refactored", K(addr), K(ret)); + for (int64_t i = 0; OB_SUCC(ret) && i < request_send_addrs_.count(); i++) { + if (addr == request_send_addrs_.at(i)) { + if (OB_FAIL(request_send_addrs_.remove(i))) { + PROXY_LOG(WARN, "fail to remove item", K(i), K(ret)); + } + break; + } } return ret; } @@ -941,8 +1003,12 @@ class ObClientSessionInfo dbconfig::ObShardUserPrivInfo up_info_; // saved start transaction sql + // saved xa start request packet (prepare execute) common::ObString saved_start_trans_sql_; + // saved xa start request's ps id + uint32_t xa_start_ps_id_; + ObProxyLoginUserType user_identity_; ObSessionVarVersion version_; // cached variables @@ -950,6 +1016,7 @@ class ObClientSessionInfo // global variables version, will be set at the first time get login responce(OK packet) int64_t global_vars_version_; // obproxy_route_addr + // TODO: only support IPv4, IPv6 unsupported int64_t obproxy_route_addr_; ObSysVarSetProcessor *var_set_processor_; @@ -967,6 +1034,8 @@ class ObClientSessionInfo dbconfig::ObShardConnector *shard_conn_; dbconfig::ObShardProp *shard_prop_; int64_t group_id_; + int64_t table_id_; + int64_t es_id_; bool is_allow_use_last_session_; common::ObString client_host_; @@ -991,14 +1060,14 @@ class ObClientSessionInfo ObPsIdAddrsMap ps_id_addrs_map_; ObPieceInfoMap piece_info_map_; - ObPsIdAddrs::ADDR_HASH_SET request_send_addrs_; + common::ObSEArray request_send_addrs_; bool is_read_only_user_; bool is_request_follower_user_; char text_ps_name_buf_[common::OB_MAX_TEXT_PS_NAME_LENGTH]; - - SessFieldHashMap sess_info_hash_map_; + + SessFieldHashMap sess_info_hash_map_; DISALLOW_COPY_AND_ASSIGN(ObClientSessionInfo); }; @@ -1231,7 +1300,8 @@ inline bool ObClientSessionInfo::need_reset_session_vars(const ObServerSessionIn || need_reset_hot_session_vars(server_info) || need_reset_cold_session_vars(server_info) || need_reset_user_session_vars(server_info) - || need_reset_safe_read_snapshot(server_info); + || need_reset_safe_read_snapshot(server_info) + || need_reset_last_insert_id(server_info); } else { bret = need_reset_common_hot_session_vars(server_info) || need_reset_common_cold_session_vars(server_info) @@ -1247,7 +1317,7 @@ inline bool ObClientSessionInfo::need_reset_sess_info_vars(const ObServerSession bool bret = false; // TODO: Processing for sharding connection pools bret = get_sess_info_version() > server_info.get_sess_info_version(); - PROXY_LOG(DEBUG, "need_reset_sess_info_vars", K(bret), + PROXY_LOG(DEBUG, "need_reset_sess_info_vars", K(bret), K(get_sess_info_version()), K(server_info.get_sess_info_version())); return bret; } diff --git a/src/obproxy/proxy/mysqllib/ob_proxy_session_info_handler.cpp b/src/obproxy/proxy/mysqllib/ob_proxy_session_info_handler.cpp index f8f79f1b4..2ffd5e997 100644 --- a/src/obproxy/proxy/mysqllib/ob_proxy_session_info_handler.cpp +++ b/src/obproxy/proxy/mysqllib/ob_proxy_session_info_handler.cpp @@ -49,7 +49,8 @@ int ObProxySessionInfoHandler::analyze_extra_ok_packet(ObIOBufferReader &reader, ObClientSessionInfo &client_info, ObServerSessionInfo &server_info, const bool need_handle_sysvar, - ObRespAnalyzeResult &resp_result) + ObRespAnalyzeResult &resp_result, + common::ObSimpleTrace<4096> &trace_log) { int ret = OB_SUCCESS; @@ -65,7 +66,7 @@ int ObProxySessionInfoHandler::analyze_extra_ok_packet(ObIOBufferReader &reader, LOG_WARN("fail to get ok packet", K(ret)); // save changed info } else if (OB_FAIL(save_changed_session_info(client_info, server_info, false, - need_handle_sysvar, src_ok, resp_result, false))) { + need_handle_sysvar, src_ok, resp_result, trace_log, false))) { LOG_WARN("fail to save changed session info", K(ret)); } else { LOG_DEBUG("analyze_extra_ok_packet", K(src_ok)); @@ -95,6 +96,7 @@ int ObProxySessionInfoHandler::rebuild_ok_packet(ObIOBufferReader &reader, const bool is_auth_request, const bool need_handle_sysvar, ObRespAnalyzeResult &resp_result, + common::ObSimpleTrace<4096> &trace_log, const bool is_save_to_common_sys) { int ret = OB_SUCCESS; @@ -118,6 +120,7 @@ int ObProxySessionInfoHandler::rebuild_ok_packet(ObIOBufferReader &reader, need_handle_sysvar, src_ok, resp_result, + trace_log, is_save_to_common_sys))) { LOG_WARN("fail to save changed session info", K(is_auth_request), K(ret)); } else { @@ -173,6 +176,7 @@ int ObProxySessionInfoHandler::rewrite_query_req_by_sharding(ObClientSessionInfo obmysql::ObMySQLCmd tmp_req_cmd = obmysql::OB_MYSQL_COM_MAX_NUM; client_request.reset(false); + client_request.set_user_identity(USER_TYPE_SHARDING); ObMysqlRequestAnalyzer::analyze_request(target_ctx, tmp_auth_req, client_request, tmp_req_cmd, status); @@ -605,9 +609,9 @@ inline int ObProxySessionInfoHandler::rewrite_common_login_req(ObClientSessionIn } if (param.use_ob_protocol_v2_) { - cap |= (OB_CAP_OB_PROTOCOL_V2 | OB_CAP_PROXY_NEW_EXTRA_INFO | OB_CAP_PROXY_REROUTE | OB_CAP_PROXY_SESSION_SYNC); + cap |= (OB_CAP_OB_PROTOCOL_V2 | OB_CAP_PROXY_NEW_EXTRA_INFO | OB_CAP_PROXY_REROUTE | OB_CAP_PROXY_SESSION_SYNC | OB_CAP_PROXY_SESSION_VAR_SYNC); } else { - cap &= ~(OB_CAP_OB_PROTOCOL_V2 | OB_CAP_PROXY_NEW_EXTRA_INFO | OB_CAP_PROXY_REROUTE | OB_CAP_PROXY_SESSION_SYNC); + cap &= ~(OB_CAP_OB_PROTOCOL_V2 | OB_CAP_PROXY_NEW_EXTRA_INFO | OB_CAP_PROXY_REROUTE | OB_CAP_PROXY_SESSION_SYNC | OB_CAP_PROXY_SESSION_VAR_SYNC); } param.cluster_name_ = cluster_name; @@ -727,7 +731,9 @@ int ObProxySessionInfoHandler::handle_capability_flag_var(ObClientSessionInfo &c client_info.set_client_ob_capability(client_cap); client_info.set_server_ob_capability(server_cap); - LOG_INFO("succ to set ob_capability_flag", K(client_cap), K(server_cap), K(orig_client_cap), K(orig_server_cap), + LOG_INFO("succ to set ob_capability_flag in negotiation", + K(client_cap), K(server_cap), K(orig_client_cap), K(orig_server_cap), + "client_support_ob_v2", client_info.is_client_support_ob20_protocol(), "server_support_checksum", server_info.is_checksum_supported(), "server_support_ob_v2", server_info.is_ob_protocol_v2_supported(), K(is_auth_request)); @@ -1113,10 +1119,13 @@ int ObProxySessionInfoHandler::save_changed_session_info(ObClientSessionInfo &cl const bool need_handle_sysvar, OMPKOK &ok_pkt, ObRespAnalyzeResult &resp_result, + common::ObSimpleTrace<4096> &trace_log, const bool is_save_to_common_sys) { int ret = OB_SUCCESS; // 1. save server status + trace_log.log_it("[svr_status]", "in_trans", ok_pkt.get_server_status().status_flags_.OB_SERVER_STATUS_IN_TRANS, + "ac", ok_pkt.get_server_status().status_flags_.OB_SERVER_STATUS_AUTOCOMMIT); if (is_auth_request) { bool is_oracle_mode = 1 == ok_pkt.get_server_status().status_flags_.OB_SERVER_STATUS_RESERVED; LOG_DEBUG("will set oracle mode ", K(is_oracle_mode)); @@ -1384,19 +1393,48 @@ int ObProxySessionInfoHandler::assign_session_vars_version( } int ObProxySessionInfoHandler::save_changed_sess_info(ObClientSessionInfo& client_info, - ObServerSessionInfo& server_info, Ob20ExtraInfo& extra_info) + ObServerSessionInfo& server_info, Ob20ExtraInfo& extra_info, common::ObSimpleTrace<4096> &trace_log, bool is_only_sync_trans_sess) { int ret = OB_SUCCESS; if (extra_info.exist_sess_info()) { - if (OB_FAIL(client_info.update_sess_sync_info(extra_info.get_sess_info()))) { - LOG_WARN("failed to update sess sync info", K(ret), K(extra_info)); + ObString sess_info; + extra_info.reset_sess_info_iterate_idx(); + for (uint32_t i = 0; OB_SUCC(ret) && i < extra_info.get_sess_info_count(); i++) { + if (OB_FAIL(extra_info.get_next_sess_info(sess_info))) { + LOG_WARN("fail to update sess sync info", K(ret)); + } else if (OB_FAIL(client_info.update_sess_sync_info(sess_info, trace_log))) { + LOG_WARN("fail to update sess sync info", K(ret), K(extra_info)); + } } } + bool need_update_version = true; if (OB_SUCC(ret)) { - int64_t c_sess_info_version = client_info.get_sess_info_version(); - server_info.set_sess_info_version(c_sess_info_version); + SessFieldVersionHashMap::iterator last = client_info.get_sess_field_version().end(); + SessFieldVersionHashMap::iterator it = client_info.get_sess_field_version().begin(); + for (; it != last && OB_SUCC(ret); ++it) { + int16_t sess_info_type = it->first; + int64_t client_version = 0; + + if (OB_FAIL(ObProxyTraceUtils::get_sess_field_version(client_version , sess_info_type, client_info.get_sess_field_version()))) { + LOG_WARN("fail to set client session field version", K(ret), K(sess_info_type)); + } else if (is_only_sync_trans_sess && !ObProto20Utils::is_trans_related_sess_info(sess_info_type)) { + // internal routing trans not support sync session info idempotent + // here keep session info syncing in some case for only internal routing trans as temporary processing + int64_t server_version = 0; + if (OB_FAIL(ObProxyTraceUtils::get_sess_field_version(server_version, sess_info_type, server_info.get_sess_field_version()))) { + LOG_WARN("fail to get server session field version", K(ret), K(sess_info_type)); + } else if (client_version > server_version) { + need_update_version = false; + } + } else if (OB_FAIL(server_info.get_sess_field_version().set_refactored(sess_info_type, client_version, 1))) { + LOG_WARN("fail to set sess field versoin", K(sess_info_type), K(ret)); + } + } } + if (OB_SUCC(ret) && need_update_version) { + server_info.set_sess_info_version(client_info.get_sess_info_version()); + } return ret; } diff --git a/src/obproxy/proxy/mysqllib/ob_proxy_session_info_handler.h b/src/obproxy/proxy/mysqllib/ob_proxy_session_info_handler.h index 630865479..aac0cc178 100644 --- a/src/obproxy/proxy/mysqllib/ob_proxy_session_info_handler.h +++ b/src/obproxy/proxy/mysqllib/ob_proxy_session_info_handler.h @@ -15,6 +15,7 @@ #include "rpc/obmysql/ob_mysql_packet.h" #include "utils/ob_proxy_lib.h" #include "proxy/mysqllib/ob_2_0_protocol_struct.h" +#include "lib/oblog/ob_simple_trace.h" namespace oceanbase { @@ -73,6 +74,7 @@ class ObProxySessionInfoHandler const bool need_handle_sysvar, obmysql::OMPKOK &ok_pkt, ObRespAnalyzeResult &resp_result, + common::ObSimpleTrace<4096> &trace_log, const bool is_save_to_common_sys = false); // The @reader must has only one receive completed ok packet, @@ -85,13 +87,15 @@ class ObProxySessionInfoHandler const bool is_auth_request, const bool need_handle_sysvar, ObRespAnalyzeResult &resp_result, + common::ObSimpleTrace<4096> &trace_log, const bool is_save_to_common_sys); static int analyze_extra_ok_packet(event::ObIOBufferReader &reader, ObClientSessionInfo &client_info, ObServerSessionInfo &server_info, const bool need_handle_sysvar, - ObRespAnalyzeResult &resp_result); + ObRespAnalyzeResult &resp_result, + common::ObSimpleTrace<4096> &trace_log); static int rewrite_query_req_by_sharding(ObClientSessionInfo &client_info, ObProxyMysqlRequest &client_request, @@ -171,7 +175,9 @@ class ObProxySessionInfoHandler bool &need_save); static int save_changed_sess_info(ObClientSessionInfo& client_info, ObServerSessionInfo& server_info, - Ob20ExtraInfo& extra_info); + Ob20ExtraInfo& extra_info, + common::ObSimpleTrace<4096> &trace_log, + bool is_only_sync_trans_sess); private: static ObProxySysVarType get_sys_var_type(const common::ObString &var_name); diff --git a/src/obproxy/proxy/mysqllib/ob_resultset_fetcher.h b/src/obproxy/proxy/mysqllib/ob_resultset_fetcher.h index 465b246a2..a188b38a5 100644 --- a/src/obproxy/proxy/mysqllib/ob_resultset_fetcher.h +++ b/src/obproxy/proxy/mysqllib/ob_resultset_fetcher.h @@ -45,6 +45,7 @@ } \ } +// limit max length #define PROXY_EXTRACT_STRBUF_FIELD_MYSQL(result, column_name, field, max_length, real_length) \ if (OB_SUCCESS == ret) { \ ObString str_value; \ @@ -66,6 +67,27 @@ } \ } +// unlimit max length +#define PROXY_EXTRACT_STRBUF_FIELD_MYSQL_UNLIMIT_LENGTH(result, column_name, field, real_length, allocator) \ +if (OB_SUCCESS == ret) { \ + ObString str_value; \ + if (OB_SUCCESS == (ret = (result).get_varchar(column_name, str_value))) { \ + if (str_value.empty()) { \ + real_length = 0; \ + field = NULL; \ + } else if (OB_ISNULL(field = static_cast(allocator.alloc(str_value.length() + 1)))) { \ + ret = OB_ALLOCATE_MEMORY_FAILED; \ + LOG_WARN("fail to allc part key name", K(field), K(str_value.length()), K(ret)); \ + } else { \ + MEMCPY(field, str_value.ptr(), str_value.length()); \ + real_length = str_value.length(); \ + field[str_value.length()] = '\0'; \ + } \ + } else { \ + PROXY_LOG(WARN, "fail to extract strbuf field mysql", K(column_name), K(real_length), K(ret)); \ + } \ +} + namespace oceanbase { namespace common diff --git a/src/obproxy/proxy/mysqllib/ob_session_field_mgr.h b/src/obproxy/proxy/mysqllib/ob_session_field_mgr.h index cbe099568..7d21e0cfb 100644 --- a/src/obproxy/proxy/mysqllib/ob_session_field_mgr.h +++ b/src/obproxy/proxy/mysqllib/ob_session_field_mgr.h @@ -108,10 +108,10 @@ enum ObSessionFieldStat enum ObSessionVarType { - OB_SESSION_USER_VAR = 0, - OB_SESSION_SYS_VAR, - OB_SESSION_COMMON_SYS_VAR, - OB_SESSION_MYSQL_SYS_VAR, + OB_SESSION_USER_VAR = 0, // user variable + OB_SESSION_SYS_VAR, // system variable only oceanbase supported + OB_SESSION_COMMON_SYS_VAR, // system variable oceanbase and mysql both supported + OB_SESSION_MYSQL_SYS_VAR, // system variable only mysql supported OB_SESSION_VAR_MAX, }; diff --git a/src/obproxy/proxy/plugins/ob_mysql_request_compress_transform_plugin.cpp b/src/obproxy/proxy/plugins/ob_mysql_request_compress_transform_plugin.cpp index a7feb83e1..d886b6129 100644 --- a/src/obproxy/proxy/plugins/ob_mysql_request_compress_transform_plugin.cpp +++ b/src/obproxy/proxy/plugins/ob_mysql_request_compress_transform_plugin.cpp @@ -149,9 +149,12 @@ int ObMysqlRequestCompressTransformPlugin::build_compressed_packet(bool is_last_ PROXY_API_LOG(WARN, "fail to build related extra info all", K(ret)); } else { ObMysqlServerSession *server_session = sm_->get_server_session(); + ObMysqlClientSession *client_session = sm_->get_client_session(); + const bool is_weak_read = (WEAK == sm_->trans_state_.get_trans_consistency_level(client_session->get_session_info())); Ob20ProtocolHeaderParam ob20_head_param(server_session->get_server_sessid(), request_id_, compressed_seq_, - compressed_seq_, is_last_segment, is_need_reroute, - server_session->get_session_info().is_new_extra_info_supported()); + compressed_seq_, is_last_segment, is_weak_read, is_need_reroute, + server_session->get_session_info().is_new_extra_info_supported(), + client_session->is_trans_internal_routing()); if (OB_FAIL(ObProto20Utils::consume_and_compress_data(local_reader_, mio_buffer_, local_reader_->read_avail(), ob20_head_param, &extra_info))) { PROXY_API_LOG(WARN, "fail to consume and compress data with OB20", K(ret)); diff --git a/src/obproxy/proxy/plugins/ob_mysql_request_compress_transform_plugin.h b/src/obproxy/proxy/plugins/ob_mysql_request_compress_transform_plugin.h index f586fffd0..6a463892a 100644 --- a/src/obproxy/proxy/plugins/ob_mysql_request_compress_transform_plugin.h +++ b/src/obproxy/proxy/plugins/ob_mysql_request_compress_transform_plugin.h @@ -101,10 +101,10 @@ class ObMysqlRequestCompressGlobalPlugin : public ObGlobalPlugin PROXY_API_LOG(DEBUG, "need_enable_plugin", "request_content_length", sm->trans_state_.trans_info_.request_content_length_, "enable_compression_protocol", sm->trans_state_.mysql_config_params_->enable_compression_protocol_, - "enable_ob_protocol_v2", sm->trans_state_.mysql_config_params_->enable_ob_protocol_v2_); + "enable_ob_protocol_v2", sm->is_enable_ob_protocol_v2()); return (sm->trans_state_.trans_info_.request_content_length_ > 0 && (sm->trans_state_.mysql_config_params_->enable_compression_protocol_ - || sm->trans_state_.mysql_config_params_->enable_ob_protocol_v2_)); + || sm->is_enable_ob_protocol_v2())); } private: diff --git a/src/obproxy/proxy/plugins/ob_mysql_response_compress_transform_plugin.cpp b/src/obproxy/proxy/plugins/ob_mysql_response_compress_transform_plugin.cpp index f85cda266..ea4105a56 100644 --- a/src/obproxy/proxy/plugins/ob_mysql_response_compress_transform_plugin.cpp +++ b/src/obproxy/proxy/plugins/ob_mysql_response_compress_transform_plugin.cpp @@ -152,13 +152,31 @@ int ObMysqlResponseCompressTransformPlugin::consume(event::ObIOBufferReader *rea // get consume size again, for trim the last packet consume_size = local_transfer_reader_->read_avail() - analyze_result.get_reserved_len_for_ob20_ok(); - // just send all data in local_transfer_reader_ - if (consume_size != (produce_size = produce(local_transfer_reader_, consume_size))) { - ret = OB_ERR_UNEXPECTED; - PROXY_API_LOG(WARN, "fail to produce", "expected size", consume_size, - "actual size", produce_size, K(ret)); - } else if (OB_FAIL(local_transfer_reader_->consume(consume_size))) { - PROXY_API_LOG(WARN, "fail to consume local transfer reader", K(consume_size), K(ret)); + // Here is a situation: + // under the 2.0 protocol, the last 4 tail checksum bytes were not read, + // but the Tunnel sent all the MySQL content. + // For ClientVC, after receiving all MySQL content, + // it does not judge the end of the response based on the content, + // but judges based on write_state_.vio_.ntodo(), + // but because Tunnel has not read the last 4 tail checksum bytes, + // Tunnel will not modify nbytes in ntodo, + // causing ClientVC to think Have not finished receiving, continue to wait, do not continue to process. + // After the Tunnel receives the last 4 tail checksum bytes, + // since these 4 bytes are not sent to the Client, + // the Client VC will not be triggered again. + // As a result, the Tunnel ends directly, and the ClientVC How Hung lives + // + // Therefore, it is modified here that if the entire Tunnel is not over, + // the last bit of MySQL packet content will not be sent, and will not be sent until the entire Tunnel is over + if (!analyze_result.is_last_ok_handled() || analyzer_->is_stream_finished()) { + // just send all data in local_transfer_reader_ + if (consume_size != (produce_size = produce(local_transfer_reader_, consume_size))) { + ret = OB_ERR_UNEXPECTED; + PROXY_API_LOG(WARN, "fail to produce", "expected size", consume_size, + "actual size", produce_size, K(ret)); + } else if (OB_FAIL(local_transfer_reader_->consume(consume_size))) { + PROXY_API_LOG(WARN, "fail to consume local transfer reader", K(consume_size), K(ret)); + } } } } diff --git a/src/obproxy/proxy/plugins/ob_mysql_response_compress_transform_plugin.h b/src/obproxy/proxy/plugins/ob_mysql_response_compress_transform_plugin.h index d054c4313..d2c248353 100644 --- a/src/obproxy/proxy/plugins/ob_mysql_response_compress_transform_plugin.h +++ b/src/obproxy/proxy/plugins/ob_mysql_response_compress_transform_plugin.h @@ -95,8 +95,6 @@ class ObMysqlResponseCompressGlobalPlugin : public ObGlobalPlugin { return (!sm->trans_state_.trans_info_.client_request_.is_internal_cmd() && NULL != sm->client_session_ - // inner sql will received compeleted, no need plugin - && !sm->client_session_->is_proxy_mysql_client_ && ObMysqlTransact::SERVER_SEND_REQUEST == sm->trans_state_.current_.send_action_ && !sm->trans_state_.trans_info_.server_response_.get_analyze_result().is_decompressed() && (ObProxyProtocol::PROTOCOL_CHECKSUM == sm->get_server_session_protocol() diff --git a/src/obproxy/proxy/plugins/ob_mysql_response_cursor_transform_plugin.cpp b/src/obproxy/proxy/plugins/ob_mysql_response_cursor_transform_plugin.cpp index 2c9bbea3e..5850cb384 100644 --- a/src/obproxy/proxy/plugins/ob_mysql_response_cursor_transform_plugin.cpp +++ b/src/obproxy/proxy/plugins/ob_mysql_response_cursor_transform_plugin.cpp @@ -343,6 +343,7 @@ int ObMysqlResponseCursorTransformPlugin::skip_field_value(const char *&data, in break; } case OB_MYSQL_TYPE_GEOMETRY: + case OB_MYSQL_TYPE_JSON: case OB_MYSQL_TYPE_BLOB: case OB_MYSQL_TYPE_LONG_BLOB: case OB_MYSQL_TYPE_MEDIUM_BLOB: diff --git a/src/obproxy/proxy/plugins/ob_mysql_response_ob20_transform_plugin.cpp b/src/obproxy/proxy/plugins/ob_mysql_response_ob20_transform_plugin.cpp index 3111dff61..613690e2e 100644 --- a/src/obproxy/proxy/plugins/ob_mysql_response_ob20_transform_plugin.cpp +++ b/src/obproxy/proxy/plugins/ob_mysql_response_ob20_transform_plugin.cpp @@ -154,6 +154,7 @@ int ObMysqlResponseOb20ProtocolTransformPlugin::build_ob20_head_and_extra(ObMIOB uint8_t last_compressed_seq = static_cast(client_session->get_compressed_seq() + 1); const bool is_new_extra_info = client_session->get_session_info().is_client_support_new_extra_info(); bool is_extra_info_exist = false; + bool is_trans_internal_routing = false; if (OB_FAIL(ObProto20Utils::fill_proto20_extra_info(write_buf, &extra_info, is_new_extra_info, payload_len, tail_crc_, is_extra_info_exist))) { @@ -165,9 +166,10 @@ int ObMysqlResponseOb20ProtocolTransformPlugin::build_ob20_head_and_extra(ObMIOB ob20_head.request_id_, client_session->get_cs_id(), is_last_packet, - false, + false, false, is_extra_info_exist, - is_new_extra_info))) { + is_new_extra_info, + is_trans_internal_routing))) { LOG_WARN("fail to fill ob20 head", K(ret)); } else { client_session->set_compressed_seq(last_compressed_seq); diff --git a/src/obproxy/proxy/plugins/ob_trim_okpacket_transform_plugin.h b/src/obproxy/proxy/plugins/ob_trim_okpacket_transform_plugin.h index f92e46622..d95dc327b 100644 --- a/src/obproxy/proxy/plugins/ob_trim_okpacket_transform_plugin.h +++ b/src/obproxy/proxy/plugins/ob_trim_okpacket_transform_plugin.h @@ -181,7 +181,7 @@ class ObTrimOkPakcetTransformPlugin : public ObTransformationPlugin if (OB_SUCCESS != (ret = src_ok.decode())) { PROXY_API_LOG(WARN, "fail to decode ok packet", K(src_ok), K(ret)); } else if (OB_SUCCESS != (ret = ObProxySessionInfoHandler::save_changed_session_info( - client_info, server_info, sm_->trans_state_.is_auth_request_, NULL, src_ok, analyze_result))) { + client_info, server_info, sm_->trans_state_.is_auth_request_, NULL, src_ok, analyze_result, sm_->trans_state_.trace_log_))) { _PROXY_API_LOG(WARN, "fail to save changed session info, is_auth_request=%d, ret=%d", sm_->trans_state_.is_auth_request_, ret); } diff --git a/src/obproxy/proxy/route/ob_mysql_route.cpp b/src/obproxy/proxy/route/ob_mysql_route.cpp index 60cd0ecc6..008ba529c 100644 --- a/src/obproxy/proxy/route/ob_mysql_route.cpp +++ b/src/obproxy/proxy/route/ob_mysql_route.cpp @@ -493,35 +493,33 @@ inline int ObMysqlRoute::check_and_rebuild_call_params() ObSessionSysField *sys_filed = NULL; ObSessionUserField *user_filed = NULL; for (int32_t i = 0; OB_SUCC(ret) && i < call_info.param_count_; ++i) { - ObProxyCallParam &call_param = call_info.params_.at(i); - if (CALL_TOKEN_SYS_VAR == call_param.type_) { + ObProxyCallParam* call_param = call_info.params_.at(i); + if (CALL_TOKEN_SYS_VAR == call_param->type_) { sys_filed = NULL; - if (OB_FAIL(client_info.get_sys_variable(call_param.str_value_.string_, sys_filed))) { - LOG_INFO("fail to find sys variables", "name", call_param.str_value_.string_, K(ret)); + if (OB_FAIL(client_info.get_sys_variable(call_param->str_value_.config_string_, sys_filed))) { + LOG_INFO("fail to find sys variables", "name", call_param->str_value_.config_string_, K(ret)); } else if (NULL != sys_filed) { - char *buf = call_param.str_value_.buf_; - const int64_t max_size = call_param.str_value_.get_max_size(); + char buf[OBPROXY_MAX_STRING_VALUE_LENGTH]; int64_t pos = 0; - if (OB_FAIL(sys_filed->value_.print_sql_literal(buf, max_size, pos))) { + if (OB_FAIL(sys_filed->value_.print_sql_literal(buf, OBPROXY_MAX_STRING_VALUE_LENGTH, pos))) { LOG_INFO("fail to print sql literal", K(pos), K(i), KPC(sys_filed), K(ret)); } else { ObString new_value(pos, buf); - call_param.str_value_.set(new_value); + call_param->str_value_.set_value(new_value); } } - } else if (CALL_TOKEN_USER_VAR == call_param.type_) { + } else if (CALL_TOKEN_USER_VAR == call_param->type_) { user_filed = NULL; - if (OB_FAIL(client_info.get_user_variable(call_param.str_value_.string_, user_filed))) { - LOG_INFO("fail to find sys variables, ignore", "name", call_param.str_value_.string_, K(ret)); + if (OB_FAIL(client_info.get_user_variable(call_param->str_value_.config_string_, user_filed))) { + LOG_INFO("fail to find sys variables", K_(call_param->str_value_.config_string), K(ret)); } else if (NULL != user_filed) { - char *buf = call_param.str_value_.buf_; - const int64_t max_size = call_param.str_value_.get_max_size(); + char buf[OBPROXY_MAX_STRING_VALUE_LENGTH]; int64_t pos = 0; - if (OB_FAIL(user_filed->value_.print_plain_str_literal(buf, max_size, pos))) { + if (OB_FAIL(user_filed->value_.print_plain_str_literal(buf, OBPROXY_MAX_STRING_VALUE_LENGTH, pos))) { LOG_INFO("fail to print sql literal, ignore", K(pos), K(i), KPC(user_filed), K(ret)); } else { ObString new_value(pos, buf); - call_param.str_value_.set(new_value); + call_param->str_value_.set_value(new_value); } } } diff --git a/src/obproxy/proxy/route/ob_route_struct.h b/src/obproxy/proxy/route/ob_route_struct.h index 6ca19bcec..d6bfbdba9 100644 --- a/src/obproxy/proxy/route/ob_route_struct.h +++ b/src/obproxy/proxy/route/ob_route_struct.h @@ -203,9 +203,7 @@ int ObProxyRerouteInfo::deserialize_struct_content(const char *buf, const int64_ if (ObAddr::IPV4 == version) { replica_.server_.set_ipv4_addr(ipv4, port); } else { - // must IPV6, not support yet, TODO open below later - //server_.set_ipv6_addr(ipv6_high, ipv6_low, port); - replica_.server_.reset(); + replica_.server_.set_ipv6_addr(ipv6_high, ipv6_low, port); } } int64_t table_name_len = 0; @@ -233,7 +231,7 @@ inline int ObProxyReplicaLocation::add_addr(const char *ip, const int64_t port) int ret = common::OB_SUCCESS; if (OB_UNLIKELY(NULL == ip || port <= 0)) { ret = common::OB_INVALID_ARGUMENT; - } else if (OB_UNLIKELY(!server_.set_ipv4_addr(ip, static_cast(port)))) { + } else if (OB_UNLIKELY(!server_.set_ip_addr(ip, static_cast(port)))) { ret = common::OB_INVALID_ARGUMENT; } return ret; @@ -517,6 +515,7 @@ struct ObTableEntryName bool is_sys_tenant() const; bool is_oceanbase_db() const; bool is_all_dummy_table() const; + bool is_binlog_table() const; int deep_copy(const ObTableEntryName &name, char *buf, const int64_t buf_len); void shallow_copy(const ObTableEntryName &name); void shallow_copy(const common::ObString &cluster_name, const common::ObString &tenant_name, @@ -525,7 +524,6 @@ struct ObTableEntryName const common::ObString &database_name, const common::ObString &package_name, const common::ObString &table_name); - common::ObString cluster_name_; common::ObString tenant_name_; common::ObString database_name_; @@ -585,6 +583,12 @@ inline bool ObTableEntryName::is_all_dummy_table() const return is_valid() && table_name_[0] == '_' && all_dummy_tname_str == table_name_; } +inline bool ObTableEntryName::is_binlog_table() const +{ + static const common::ObString binlog_tname_str(share::OB_ALL_BINLOG_DUMMY_TNAME); + return is_valid() && binlog_tname_str == table_name_; +} + inline bool ObTableEntryName::is_ob_dummy() const { return is_oceanbase_db() && is_all_dummy_table(); diff --git a/src/obproxy/proxy/route/ob_route_utils.cpp b/src/obproxy/proxy/route/ob_route_utils.cpp index cf72edb6d..0b702046a 100644 --- a/src/obproxy/proxy/route/ob_route_utils.cpp +++ b/src/obproxy/proxy/route/ob_route_utils.cpp @@ -64,20 +64,12 @@ static const char *PROXY_TENANT_SCHEMA_SQL = "ORDER BY %s ASC, role ASC LIMIT %ld"; static const char *PROXY_PART_INFO_SQL = - "SELECT /*+READ_CONSISTENCY(WEAK)*/ template_num, part_level, part_num, part_type, part_space, part_expr, " - "part_interval_bin, interval_start_bin, sub_part_num, sub_part_type, sub_part_space, " - "sub_part_expr, def_sub_part_interval_bin, def_sub_interval_start_bin, " - "part_key_num, part_key_name, part_key_type, part_key_idx, part_key_level, part_key_extra, " - "spare1, spare2, spare4, spare5 " + "SELECT /*+READ_CONSISTENCY(WEAK)*/ * " "FROM oceanbase.%s " "WHERE table_id = %lu order by part_key_idx LIMIT %d;"; static const char *PROXY_PART_INFO_SQL_V4 = - "SELECT /*+READ_CONSISTENCY(WEAK)*/ template_num, part_level, part_num, part_type, part_space, part_expr, " - "part_interval_bin, interval_start_bin, sub_part_num, sub_part_type, sub_part_space, " - "sub_part_expr, def_sub_part_interval_bin, def_sub_interval_start_bin, " - "part_key_num, part_key_name, part_key_type, part_key_idx, part_key_level, part_key_extra, " - "part_key_collation_type, part_key_rowkey_idx, part_key_expr, part_key_length, part_key_precision, part_key_scale " + "SELECT /*+READ_CONSISTENCY(WEAK)*/ * " "FROM oceanbase.%s " "WHERE table_id = %lu and tenant_name = '%.*s' order by part_key_idx LIMIT %d;"; @@ -98,17 +90,17 @@ static const char *PROXY_FIRST_PART_SQL_V4 = "WHERE table_id = %lu and tenant_name = '%.*s' LIMIT %ld;"; static const char *PROXY_SUB_PART_SQL = - "SELECT /*+READ_CONSISTENCY(WEAK)*/ part_id, sub_part_id, high_bound_val_bin " + "SELECT /*+READ_CONSISTENCY(WEAK)*/ part_id, sub_part_id, part_name, high_bound_val_bin " "FROM oceanbase.%s " "WHERE table_id = %lu and part_id = %ld LIMIT %ld;"; static const char *PROXY_NON_TEMPLATE_SUB_PART_SQL = - "SELECT /*+READ_CONSISTENCY(WEAK)*/ part_id, sub_part_id, high_bound_val_bin " + "SELECT /*+READ_CONSISTENCY(WEAK)*/ part_id, sub_part_id, part_name, high_bound_val_bin " "FROM oceanbase.%s " "WHERE table_id = %lu LIMIT %ld;"; -static const char *PROXY_SUB_PART_SQL_V4 = - "SELECT /*+READ_CONSISTENCY(WEAK)*/ tablet_id, part_id, sub_part_id, high_bound_val_bin " +static const char *PROXY_SUB_PART_SQL_V4 = + "SELECT /*+READ_CONSISTENCY(WEAK)*/ tablet_id, part_id, sub_part_id, part_name, high_bound_val_bin " "FROM oceanbase.%s " "WHERE table_id = %lu and tenant_name = '%.*s' LIMIT %ld;"; @@ -132,6 +124,9 @@ static const char *PROXY_ROUTINE_SCHEMA_SQL_V4 = "WHERE tenant_name = '%.*s' and database_name = '%.*s' and package_name = '%.*s' " "and routine_name = '%.*s';"; +static const char *PROXY_BINLOG_ADDR_SQL = + "show binlog server for tenant `%.*s`.`%.*s`"; + static void get_tenant_name(const ObString &origin_tenant_name, char *new_tenant_name_buf, ObString &new_tenant_name) { new_tenant_name = origin_tenant_name; int32_t pos = 0; @@ -315,6 +310,32 @@ int ObRouteUtils::get_sub_part_sql(char *sql_buf, return ret; } +int ObRouteUtils::get_binlog_entry_sql(char *sql_buf, + const int64_t buf_len, + const ObString &cluster_name, + const ObString &tenant_name) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(sql_buf) || OB_UNLIKELY(buf_len <= 0) + || OB_UNLIKELY(cluster_name.empty()) + || OB_UNLIKELY(tenant_name.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid input value", LITERAL_K(sql_buf), K(buf_len), K(cluster_name), K(tenant_name), K(ret)); + } else { + int64_t len = 0; + len = static_cast(snprintf(sql_buf, buf_len, PROXY_BINLOG_ADDR_SQL, + cluster_name.length(), cluster_name.ptr(), + tenant_name.length(), tenant_name.ptr())); + + if (OB_UNLIKELY(len <= 0) || OB_UNLIKELY(len >= buf_len)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to fill binlog sql", K(sql_buf), K(len), K(buf_len), K(ret)); + } + } + + return ret; +} + bool is_fake_ip_port(const char *ip_str, const int64_t port) { const ObString fake_ip("0.0.0.0"); @@ -328,7 +349,7 @@ int ObRouteUtils::fetch_table_entry(ObResultSetFetcher &rs_fetcher, { int ret = OB_SUCCESS; int64_t tmp_real_str_len = 0; - char ip_str[OB_IP_STR_BUFF]; + char ip_str[MAX_IP_ADDR_LENGTH]; ip_str[0] = '\0'; int64_t port = 0; uint64_t table_id = OB_INVALID_ID; @@ -355,7 +376,7 @@ int ObRouteUtils::fetch_table_entry(ObResultSetFetcher &rs_fetcher, replica_type = -1; table_type = -1; - PROXY_EXTRACT_STRBUF_FIELD_MYSQL(rs_fetcher, "svr_ip", ip_str, OB_IP_STR_BUFF, tmp_real_str_len); + PROXY_EXTRACT_STRBUF_FIELD_MYSQL(rs_fetcher, "svr_ip", ip_str, MAX_IP_ADDR_LENGTH, tmp_real_str_len); PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sql_port", port, int64_t); PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "table_id", table_id, uint64_t); PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "role", role, int64_t); @@ -515,6 +536,32 @@ int ObRouteUtils::fetch_table_entry(ObResultSetFetcher &rs_fetcher, return ret; } +int ObRouteUtils::split_part_expr(ObString expr, ObIArray &arr) +{ + int ret = OB_SUCCESS; + ObString tmp; + while (OB_SUCC(ret) && !expr.empty()) { + tmp = expr.split_on(',').trim(); + if (tmp.empty()) { + tmp = expr.trim(); + expr.reset(); + } + if (tmp[0] == '`') { + tmp.assign_ptr(tmp.ptr() + 1, tmp.length() - 1); + } + if (tmp[tmp.length() - 1] == '`') { + tmp.assign_ptr(tmp.ptr(), tmp.length() - 1); + } + if (OB_FAIL(arr.push_back(tmp))) { + LOG_WARN("fail to push back", K(tmp), K(ret)); + } else { + LOG_DEBUG("succ to push back", K(tmp)); + } + } + return ret; +} + + int ObRouteUtils::fetch_part_info(ObResultSetFetcher &rs_fetcher, ObProxyPartInfo &part_info, const int64_t cluster_version) { int ret = OB_SUCCESS; @@ -522,6 +569,8 @@ int ObRouteUtils::fetch_part_info(ObResultSetFetcher &rs_fetcher, ObProxyPartInf ObPartitionLevel part_level = PARTITION_LEVEL_ONE; int64_t part_key_num = 1; int64_t template_num = 1; + ObString part_expr; + ObString sub_part_expr; // init part key info part_info.get_part_key_info().key_num_ = 0; @@ -557,6 +606,39 @@ int ObRouteUtils::fetch_part_info(ObResultSetFetcher &rs_fetcher, ObProxyPartInf part_key_num = OBPROXY_MAX_PART_KEY_NUM; } + // get part expr + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_expr", part_expr); + char *buf = NULL; + if (part_expr.empty()) { + LOG_DEBUG("part expression is empty"); + } else if (OB_ISNULL(buf = static_cast(part_info.get_allocator().alloc(part_expr.length())))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allc part key name", K(buf), K(part_expr.length()), K(ret)); + } else { + memcpy(buf, part_expr.ptr(), part_expr.length()); + part_expr.assign_ptr(buf, part_expr.length()); + } + + // get sub part expr + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "sub_part_expr", sub_part_expr); + if (sub_part_expr.empty()) { + LOG_DEBUG("sub part expression is empty"); + } else if (OB_ISNULL(buf = static_cast(part_info.get_allocator().alloc(sub_part_expr.length())))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allc part key name", K(buf), K(sub_part_expr.length()), K(ret)); + } else { + memcpy(buf, sub_part_expr.ptr(), sub_part_expr.length()); + sub_part_expr.assign_ptr(buf, sub_part_expr.length()); + } + // split part expression + if (part_info.get_part_level() >= PARTITION_LEVEL_ONE + && OB_FAIL(split_part_expr(part_expr, part_info.get_part_columns()))) { + LOG_WARN("fail to split part expr", K(ret)); + } else if (part_info.get_part_level() == PARTITION_LEVEL_TWO + && OB_FAIL(split_part_expr(sub_part_expr, part_info.get_sub_part_columns())) ) { + LOG_WARN("fail to split sub part expr", K(ret)); + } + if (OB_FAIL(fetch_part_option(rs_fetcher, part_info))) { LOG_WARN("fail to get part option", K(ret)); } @@ -568,73 +650,25 @@ int ObRouteUtils::fetch_part_info(ObResultSetFetcher &rs_fetcher, ObProxyPartInf if (OB_SUCC(ret)) { if (OB_FAIL(fetch_part_key(rs_fetcher, part_info, cluster_version))) { LOG_WARN("fail to get part key", K(ret)); - } // end of if + } } // end of if (OB_SUCC(ret)) } // end of else } // end of for - - if (OB_SUCC(ret) && IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { - if (OB_FAIL(build_part_desc(part_info, cluster_version))) { - LOG_WARN("fail to build part desc ", K(part_info), K(ret)); - } - } - return ret; -} - -int ObRouteUtils::build_part_desc(ObProxyPartInfo &part_info, const int64_t cluster_version) { - int ret = OB_SUCCESS; - ObProxyPartOption &sub_part_opt = part_info.get_sub_part_option(); - - // for first part, we will build part desc in fetch_first_part - if (part_info.has_unknown_part_key()) { - LOG_INFO("part key type is unsopported, no need build part_desc", K(part_info)); - } else if (!part_info.is_template_table()) { - LOG_INFO("part table is non-template table, build hash and key part_desc later", K(part_info)); - } else if (OB_FAIL(build_part_desc(part_info, PARTITION_LEVEL_TWO, sub_part_opt, cluster_version))) { - LOG_WARN("fail to build sub part", K(sub_part_opt), K(ret)); - } else { - // do nothing - } - - return ret; -} - -int ObRouteUtils::build_part_desc(ObProxyPartInfo &part_info, - const ObPartitionLevel part_level, - ObProxyPartOption &part_opt, - const int64_t cluster_version) { - int ret = OB_SUCCESS; - ObProxyPartMgr &part_mgr = part_info.get_part_mgr(); - - if (part_level != PARTITION_LEVEL_TWO) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(part_level), K(ret)); - } else { - if (part_opt.is_hash_part(cluster_version)) { - if (OB_FAIL(part_mgr.build_hash_part(part_info.is_oracle_mode(), - part_level, - part_opt.part_func_type_, - part_opt.part_num_, - part_opt.part_space_, - part_info.is_template_table(), - part_info.get_part_key_info(), - NULL, - cluster_version))) { - LOG_WARN("fail to build hash part", K(part_opt), K(ret)); - } - } else if (part_opt.is_key_part(cluster_version)) { - if (OB_FAIL(part_mgr.build_key_part(part_level, - part_opt.part_func_type_, - part_opt.part_num_, - part_opt.part_space_, - part_info.is_template_table(), - part_info.get_part_key_info(), - NULL, - cluster_version))) { - LOG_WARN("fail to build key part", K(part_opt), K(ret)); + if (OB_SUCC(ret)) { + // handle generated key, map the key for generated key calculation to real key + for (int64_t i = 0; i < part_info.get_part_key_info().key_num_; ++i) { + if (part_info.get_part_key_info().part_keys_[i].generated_col_idx_ >= 0) { + for (int64_t j = 0; j < part_info.get_part_key_info().key_num_; ++j) { + ObProxyParseString *l = &part_info.get_part_key_info().part_keys_[i].name_; + ObProxyParseString *r = &part_info.get_part_key_info().part_keys_[j].name_; + if (i != j && l->str_ != NULL + && r->str_ != NULL + && l->str_len_ == r->str_len_ + && 0 == strncasecmp(l->str_, r->str_, l->str_len_)) { + part_info.get_part_key_info().part_keys_[i].real_source_idx_ = j; + } + } } - } else { - // we will build range part desc when fetch the range column } } return ret; @@ -744,120 +778,153 @@ inline int ObRouteUtils::fetch_part_key(ObResultSetFetcher &rs_fetcher, { int ret = OB_SUCCESS; - ObProxyPartKeyInfo &part_key_info = part_info.get_part_key_info(); - ObIAllocator &allocator = part_info.get_allocator(); - ObPartitionLevel part_key_level = PARTITION_LEVEL_ONE; - int64_t part_key_idx = -1; - ObObjType part_key_type = ObMaxType; - ObCollationType part_key_cs_type = CS_TYPE_INVALID; - ObString part_key_name; - ObString part_key_extra; - ObString constraint_part_key; - int64_t idx_in_rowid = -1; - ObString part_key_accuracy; - int64_t part_key_length = -1; - int64_t part_key_precision = -1; - int64_t part_key_scale = -1; - - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_level", part_key_level, ObPartitionLevel); - // part key idx is the order of part key in all columns - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_idx", part_key_idx, int64_t); - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_type", part_key_type, ObObjType); - PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_key_name", part_key_name); - // use part_key_extra as generated key expr - PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_key_extra", part_key_extra); - if (IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { - PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "spare4", constraint_part_key); - // use spare1 as table collation type - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "spare1", part_key_cs_type, ObCollationType); - // use spare2 as rowid index - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "spare2", idx_in_rowid, int64_t); - // use spare5 as the accuracy of the part key - PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "spare5", part_key_accuracy); + // only process OBPROXY_MAX_PART_KEY_NUM part key + if (OBPROXY_MAX_PART_KEY_NUM <= part_info.get_part_key_info().key_num_) { + LOG_WARN("proxy does not support to fetch more part key", K(OBPROXY_MAX_PART_KEY_NUM)); } else { - PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_key_expr", constraint_part_key); - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_collation_type", part_key_cs_type, ObCollationType); - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_rowkey_idx", idx_in_rowid, int64_t); - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_length", part_key_length, int64_t); - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_precision", part_key_precision, int64_t); - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_scale", part_key_scale, int64_t); - } - - LOG_DEBUG("fetch part key", K(part_key_level), K(part_key_idx), K(part_key_type), K(part_key_name), - K(part_key_extra), K(constraint_part_key), K(part_key_cs_type), K(idx_in_rowid), K(part_key_accuracy), - K(part_key_length), K(part_key_precision), K(part_key_scale)); - - if (!is_obj_type_supported(part_key_type)) { - part_info.set_unknown_part_key(true); - } + ObProxyPartKeyInfo &part_key_info = part_info.get_part_key_info(); + ObIAllocator &allocator = part_info.get_allocator(); + ObPartitionLevel part_key_level = PARTITION_LEVEL_ONE; + int64_t part_key_idx = -1; + ObObjType part_key_type = ObMaxType; + ObCollationType part_key_cs_type = CS_TYPE_INVALID; + ObString part_key_name; + ObString part_key_extra; + + // here store serialized default value + // mysql mode return serialized ObObj with relevant column's type + // oracle mode return serialized ObObj with varchar type + char *part_key_default_value = NULL; + int default_val_len = 0; + + ObString constraint_part_key; + int64_t idx_in_rowid = -1; + ObString part_key_accuracy; + int64_t part_key_length = -1; + int64_t part_key_precision = -1; + int64_t part_key_scale = -1; + + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_level", part_key_level, ObPartitionLevel); + // part key idx is the order of part key in all columns + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_idx", part_key_idx, int64_t); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_type", part_key_type, ObObjType); + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_key_name", part_key_name); + // use part_key_extra as generated key expr + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_key_extra", part_key_extra); + if (IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "spare4", constraint_part_key); + // use spare1 as table collation type + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "spare1", part_key_cs_type, ObCollationType); + // use spare2 as rowid index + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "spare2", idx_in_rowid, int64_t); + // use spare5 as the accuracy of the part key + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "spare5", part_key_accuracy); + } else { + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_key_expr", constraint_part_key); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_collation_type", part_key_cs_type, ObCollationType); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_rowkey_idx", idx_in_rowid, int64_t); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_length", part_key_length, int64_t); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_precision", part_key_precision, int64_t); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_key_scale", part_key_scale, int64_t); + } - ObProxyPartKey *part_key = &part_key_info.part_keys_[part_key_info.key_num_]; + if (OB_SUCC(ret)){ + PROXY_EXTRACT_STRBUF_FIELD_MYSQL_UNLIMIT_LENGTH(rs_fetcher, "part_key_default_value", part_key_default_value, default_val_len, allocator); + if (OB_ERR_COLUMN_NOT_FOUND == ret) { + LOG_DEBUG("part key default value not exist, continue", K(ret)); + ret = OB_SUCCESS; + } + } - if (PARTITION_LEVEL_ONE == part_key_level) { - part_key->level_ = PART_KEY_LEVEL_ONE; - } else if (PARTITION_LEVEL_TWO == part_key_level) { - part_key->level_ = PART_KEY_LEVEL_TWO; - } else { - ret = OB_INVALID_ARGUMENT_FOR_EXTRACT; - LOG_WARN("part key level is invalid", K(part_key_level), K(ret)); - } + LOG_DEBUG("fetch part key", K(part_key_level), K(part_key_idx), K(part_key_type), K(part_key_name), + K(part_key_extra), K(constraint_part_key), K(part_key_cs_type), + K(idx_in_rowid), K(part_key_accuracy), K(part_key_default_value), + K(part_key_length), K(part_key_precision), K(part_key_scale)); - char *buf = NULL; - if (OB_ISNULL(buf = static_cast(allocator.alloc(part_key_name.length())))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("fail to allc part key name", K(buf), K(part_key_name.length()), K(ret)); - } else { - memcpy(buf, part_key_name.ptr(), part_key_name.length()); - } + if (!is_obj_type_supported(part_key_type)) { + part_info.set_unknown_part_key(true); + } - if (OB_SUCC(ret)) { - part_key->idx_ = part_key_idx; - part_key->name_.str_len_ = part_key_name.length(); - part_key->name_.str_ = buf; - part_key->obj_type_ = part_key_type; - part_key->idx_in_rowid_ = idx_in_rowid; - part_key->accuracy_.valid_ = 0; // not valid accuracy + ObProxyPartKey *part_key = &part_key_info.part_keys_[part_key_info.key_num_]; - if (IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { - parse_part_key_accuracy(part_key, part_key_type, &allocator, part_key_accuracy); + if (PARTITION_LEVEL_ONE == part_key_level) { + part_key->level_ = PART_KEY_LEVEL_ONE; + } else if (PARTITION_LEVEL_TWO == part_key_level) { + part_key->level_ = PART_KEY_LEVEL_TWO; } else { - set_part_key_accuracy(part_key, part_key_type, - static_cast(part_key_length), - static_cast(part_key_precision), - static_cast(part_key_scale)); + ret = OB_INVALID_ARGUMENT_FOR_EXTRACT; + LOG_WARN("part key level is invalid", K(part_key_level), K(ret)); } - if (CS_TYPE_INVALID == part_key_cs_type) { - part_key->cs_type_ = ObCharset::get_default_collation(ObCharset::get_default_charset()); + char *buf = NULL; + if (OB_ISNULL(buf = static_cast(allocator.alloc(part_key_name.length())))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allc part key name", K(buf), K(part_key_name.length()), K(ret)); } else { - part_key->cs_type_ = part_key_cs_type; + memcpy(buf, part_key_name.ptr(), part_key_name.length()); } - if (!part_key_extra.empty() || !constraint_part_key.empty()) { - part_key->is_generated_ = true; - part_info.set_has_generated_key(true); - int64_t generated_key_idx = part_key_info.key_num_; - ++part_key_info.key_num_; - if (OB_FAIL(add_generated_part_key(part_key_extra, generated_key_idx, part_info))) { - LOG_WARN("fail to add generated key", K(part_key_extra), K(ret)); - } - const char *sep_pos = NULL; - ObString tmp_str; - while (NULL != (sep_pos = (constraint_part_key.find(PART_KEY_EXTRA_SEPARATOR)))) { - tmp_str = constraint_part_key.split_on(sep_pos); - if (OB_FAIL(add_generated_part_key(tmp_str, generated_key_idx, part_info))) { - LOG_WARN("fail to add generated key", K(tmp_str), K(ret)); + if (OB_SUCC(ret)) { + part_key->idx_ = part_key_idx; + part_key->name_.str_len_ = part_key_name.length(); + part_key->name_.str_ = buf; + part_key->obj_type_ = part_key_type; + part_key->idx_in_rowid_ = idx_in_rowid; + part_key->accuracy_.valid_ = 0; // not valid accuracy + ObIArray &columns = (part_key->level_ == PART_KEY_LEVEL_ONE ? + part_info.get_part_columns() : part_info.get_sub_part_columns()); + for (int i = 0; i < columns.count(); i++) { + ObString col(part_key->name_.str_len_, part_key->name_.str_); + if (columns.at(i).case_compare(col) == 0) { + part_key->idx_in_part_columns_ = i; + break; } } - if (OB_FAIL(add_generated_part_key(constraint_part_key, generated_key_idx, part_info))) { - LOG_WARN("fail to add generated key", K(constraint_part_key), K(ret)); + part_key->default_value_.str_len_ = default_val_len; + part_key->default_value_.str_ = part_key_default_value; + part_key->generated_col_idx_ = -1; + part_key->real_source_idx_ = -1; + + if (IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { + parse_part_key_accuracy(part_key, part_key_type, &allocator, part_key_accuracy); + } else { + set_part_key_accuracy(part_key, part_key_type, + static_cast(part_key_length), + static_cast(part_key_precision), + static_cast(part_key_scale)); + } + + if (CS_TYPE_INVALID == part_key_cs_type) { + part_key->cs_type_ = ObCharset::get_default_collation(ObCharset::get_default_charset()); + } else { + part_key->cs_type_ = part_key_cs_type; + } + + if (!part_key_extra.empty() || !constraint_part_key.empty()) { + part_key->is_generated_ = true; + part_info.set_has_generated_key(true); + int64_t generated_key_idx = part_key_info.key_num_; + ++part_key_info.key_num_; + if (OB_FAIL(add_generated_part_key(part_key_extra, generated_key_idx, part_info))) { + LOG_WARN("fail to add generated key", K(part_key_extra), K(ret)); + } + const char *sep_pos = NULL; + ObString tmp_str; + while (NULL != (sep_pos = (constraint_part_key.find(PART_KEY_EXTRA_SEPARATOR)))) { + tmp_str = constraint_part_key.split_on(sep_pos); + if (OB_FAIL(add_generated_part_key(tmp_str, generated_key_idx, part_info))) { + LOG_WARN("fail to add generated key", K(tmp_str), K(ret)); + } + } + if (OB_FAIL(add_generated_part_key(constraint_part_key, generated_key_idx, part_info))) { + LOG_WARN("fail to add generated key", K(constraint_part_key), K(ret)); + } + } else { + part_key->is_generated_ = false; + ++part_key_info.key_num_; } - } else { - part_key->is_generated_ = false; - ++part_key_info.key_num_; } } - return ret; } @@ -892,7 +959,6 @@ int ObRouteUtils::add_generated_part_key(const ObString &part_key_extra, LOG_WARN("generated function param num is unexpectedlly larger than 3", "child num", child->child_num_, K(OBPROXY_MAX_PARAM_NUM), K(ret)); } else { - LOG_DEBUG("succ to parse generated function expr", "func_expr_result:", ObFuncExprParseResultPrintWrapper(result)); part_key_info.part_keys_[part_key_info.key_num_].func_type_ = func_expr_node->func_type_; part_key_info.part_keys_[part_key_info.key_num_].param_num_ = child->child_num_; part_key_info.part_keys_[part_key_info.key_num_].generated_col_idx_ = generated_key_idx; @@ -910,6 +976,7 @@ int ObRouteUtils::add_generated_part_key(const ObString &part_key_extra, part_key_info.part_keys_[part_key_info.key_num_].level_ = part_key.level_; part_key_info.part_keys_[part_key_info.key_num_].obj_type_ = part_key.obj_type_; part_key_info.part_keys_[part_key_info.key_num_].cs_type_ = part_key.cs_type_; + part_key_info.part_keys_[part_key_info.key_num_].idx_in_part_columns_ = part_key.idx_in_part_columns_; part_key_info.part_keys_[part_key_info.key_num_].is_generated_ = false; } child_param_node = child_param_node->next_; @@ -928,6 +995,12 @@ inline int ObRouteUtils::fetch_part_option(ObResultSetFetcher &rs_fetcher, ObProxyPartOption &first_part_opt = part_info.get_first_part_option(); ObProxyPartOption &sub_part_opt = part_info.get_sub_part_option(); + //get all sub part num + int64_t all_sub_part_num=0; + //"all_part_num" in __all_virtual_proxy_partition_info + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "all_part_num", all_sub_part_num, int64_t); + part_info.get_part_mgr().set_all_sub_part_num(all_sub_part_num); + // get first part PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_num", first_part_opt.part_num_, int64_t); PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_type", first_part_opt.part_func_type_, @@ -951,6 +1024,7 @@ int ObRouteUtils::fetch_first_part(ObResultSetFetcher &rs_fetcher, ObProxyPartIn if (OB_FAIL(part_info.get_part_mgr().build_range_part(share::schema::PARTITION_LEVEL_ONE, part_info.get_first_part_option().part_func_type_, part_info.get_first_part_option().part_num_, + part_info.get_part_columns().count(), part_info.is_template_table(), part_info.get_part_key_info(), rs_fetcher, @@ -961,6 +1035,7 @@ int ObRouteUtils::fetch_first_part(ObResultSetFetcher &rs_fetcher, ObProxyPartIn if (OB_FAIL(part_info.get_part_mgr().build_list_part(share::schema::PARTITION_LEVEL_ONE, part_info.get_first_part_option().part_func_type_, part_info.get_first_part_option().part_num_, + part_info.get_part_columns().count(), part_info.is_template_table(), part_info.get_part_key_info(), rs_fetcher, @@ -973,6 +1048,7 @@ int ObRouteUtils::fetch_first_part(ObResultSetFetcher &rs_fetcher, ObProxyPartIn part_info.get_first_part_option().part_func_type_, part_info.get_first_part_option().part_num_, part_info.get_first_part_option().part_space_, + part_info.get_part_columns().count(), part_info.is_template_table(), part_info.get_part_key_info(), &rs_fetcher, @@ -984,6 +1060,7 @@ int ObRouteUtils::fetch_first_part(ObResultSetFetcher &rs_fetcher, ObProxyPartIn part_info.get_first_part_option().part_func_type_, part_info.get_first_part_option().part_num_, part_info.get_first_part_option().part_space_, + part_info.get_part_columns().count(), part_info.is_template_table(), part_info.get_part_key_info(), &rs_fetcher, @@ -1006,6 +1083,7 @@ int ObRouteUtils::fetch_sub_part(ObResultSetFetcher &rs_fetcher, ObProxyPartInfo if (OB_FAIL(part_info.get_part_mgr().build_range_part(share::schema::PARTITION_LEVEL_TWO, part_info.get_sub_part_option().part_func_type_, part_info.get_sub_part_option().part_num_, + part_info.get_sub_part_columns().count(), part_info.is_template_table(), part_info.get_part_key_info(), rs_fetcher, @@ -1014,6 +1092,7 @@ int ObRouteUtils::fetch_sub_part(ObResultSetFetcher &rs_fetcher, ObProxyPartInfo } } else { if (OB_FAIL(part_info.get_part_mgr().build_sub_range_part_with_non_template(part_info.get_sub_part_option().part_func_type_, + part_info.get_sub_part_columns().count(), part_info.get_part_key_info(), rs_fetcher, cluster_version))) { @@ -1025,6 +1104,7 @@ int ObRouteUtils::fetch_sub_part(ObResultSetFetcher &rs_fetcher, ObProxyPartInfo if (OB_FAIL(part_info.get_part_mgr().build_list_part(share::schema::PARTITION_LEVEL_TWO, part_info.get_sub_part_option().part_func_type_, part_info.get_sub_part_option().part_num_, + part_info.get_sub_part_columns().count(), part_info.is_template_table(), part_info.get_part_key_info(), rs_fetcher, @@ -1033,6 +1113,7 @@ int ObRouteUtils::fetch_sub_part(ObResultSetFetcher &rs_fetcher, ObProxyPartInfo } } else { if (OB_FAIL(part_info.get_part_mgr().build_sub_list_part_with_non_template(part_info.get_sub_part_option().part_func_type_, + part_info.get_sub_part_columns().count(), part_info.get_part_key_info(), rs_fetcher, cluster_version))) { @@ -1046,6 +1127,7 @@ int ObRouteUtils::fetch_sub_part(ObResultSetFetcher &rs_fetcher, ObProxyPartInfo part_info.get_sub_part_option().part_func_type_, part_info.get_sub_part_option().part_num_, part_info.get_sub_part_option().part_space_, + part_info.get_sub_part_columns().count(), part_info.is_template_table(), part_info.get_part_key_info(), &rs_fetcher, @@ -1056,6 +1138,7 @@ int ObRouteUtils::fetch_sub_part(ObResultSetFetcher &rs_fetcher, ObProxyPartInfo if (OB_FAIL(part_info.get_part_mgr().build_sub_hash_part_with_non_template(part_info.is_oracle_mode(), part_info.get_sub_part_option().part_func_type_, part_info.get_sub_part_option().part_space_, + part_info.get_sub_part_columns().count(), part_info.get_part_key_info(), rs_fetcher, cluster_version))) { @@ -1068,6 +1151,7 @@ int ObRouteUtils::fetch_sub_part(ObResultSetFetcher &rs_fetcher, ObProxyPartInfo part_info.get_sub_part_option().part_func_type_, part_info.get_sub_part_option().part_num_, part_info.get_sub_part_option().part_space_, + part_info.get_sub_part_columns().count(), part_info.is_template_table(), part_info.get_part_key_info(), &rs_fetcher, @@ -1077,6 +1161,7 @@ int ObRouteUtils::fetch_sub_part(ObResultSetFetcher &rs_fetcher, ObProxyPartInfo } else { if (OB_FAIL(part_info.get_part_mgr().build_sub_key_part_with_non_template(part_info.get_sub_part_option().part_func_type_, part_info.get_sub_part_option().part_space_, + part_info.get_sub_part_columns().count(), part_info.get_part_key_info(), rs_fetcher, cluster_version))) { @@ -1321,7 +1406,7 @@ int ObRouteUtils::fetch_one_partition_entry_info( { int ret = OB_SUCCESS; int64_t tmp_real_str_len = 0; - char ip_str[OB_IP_STR_BUFF]; + char ip_str[MAX_IP_ADDR_LENGTH]; ip_str[0] = '\0'; int64_t port = 0; uint64_t table_id = OB_INVALID_ID; @@ -1341,7 +1426,7 @@ int ObRouteUtils::fetch_one_partition_entry_info( ip_str[0] = '\0'; port = 0; - PROXY_EXTRACT_STRBUF_FIELD_MYSQL(rs_fetcher, "svr_ip", ip_str, OB_IP_STR_BUFF, tmp_real_str_len); + PROXY_EXTRACT_STRBUF_FIELD_MYSQL(rs_fetcher, "svr_ip", ip_str, MAX_IP_ADDR_LENGTH, tmp_real_str_len); PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sql_port", port, int64_t); PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "table_id", table_id, uint64_t); PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "role", role, int64_t); @@ -1554,6 +1639,73 @@ int ObRouteUtils::fetch_one_routine_entry_info( return ret; } +int ObRouteUtils::fetch_binlog_entry(ObResultSetFetcher &rs_fetcher, + ObTableEntry &entry) +{ + int ret = OB_SUCCESS; + int64_t tmp_real_str_len = 0; + char ip[OB_IP_PORT_STR_BUFF]; + char status[32]; + int64_t port = 0; + ObProxyReplicaLocation prl; + ObProxyPartitionLocation *ppl = NULL; + ObSEArray server_list; + + while (OB_SUCC(ret) && OB_SUCC(rs_fetcher.next())) { + ip[0] = '\0'; + status[0] = '\0'; + prl.reset(); + bool binlog_service_ok = false; + + PROXY_EXTRACT_STRBUF_FIELD_MYSQL(rs_fetcher, "ip", ip, OB_IP_PORT_STR_BUFF, tmp_real_str_len); + PROXY_EXTRACT_STRBUF_FIELD_MYSQL(rs_fetcher, "status", status, sizeof(status), tmp_real_str_len); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "port", port, int64_t); + + if (0 == strcasecmp("OK", status)) { + binlog_service_ok = true; + } + + if (OB_SUCC(ret) && binlog_service_ok) { + if (OB_FAIL(prl.add_addr(ip, port))) { + LOG_WARN("invalid ip or port in fetching binlog entry", K(ret)); + } else if (server_list.push_back(prl)) { + LOG_WARN("fail to add server", K(prl), K(ret)); + } + } + } + + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } + + if (OB_SUCC(ret) && !server_list.empty()) { + if (OB_ISNULL(ppl = op_alloc(ObProxyPartitionLocation))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate memory for ObProxyPartitionLocation", K(ret)); + } else if (OB_FAIL(ppl->set_replicas(server_list))) { + LOG_WARN("fail to set replicas", K(server_list), K(ret)); + } else if (!server_list.empty() && OB_UNLIKELY(!ppl->is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ppl should not unavailabe", KPC(ppl), K(ret)); + } else { + if (ppl->is_valid()) { + if (OB_FAIL(entry.set_first_partition_location(ppl))) { + LOG_WARN("fail to set first partition location", K(ret)); + } else { + ppl = NULL; + } + } + } + } + + if (NULL != ppl) { + op_free(ppl); + ppl = NULL; + } + + return ret; +} + } // end of namespace proxy } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/proxy/route/ob_route_utils.h b/src/obproxy/proxy/route/ob_route_utils.h index ceddfa25e..c908b22d5 100644 --- a/src/obproxy/proxy/route/ob_route_utils.h +++ b/src/obproxy/proxy/route/ob_route_utils.h @@ -48,7 +48,7 @@ class ObRouteUtils static int get_first_part_sql(char *sql_buf, const int64_t buf_len, const uint64_t table_id, const bool is_hash_part, ObTableEntryName &name, const int64_t cluster_version); static int get_sub_part_sql(char *sql_buf, const int64_t buf_len, const uint64_t table_id, - const bool is_template_table, ObTableEntryName &name, const int64_t cluster_version); + const bool is_template_table, ObTableEntryName &name, const int64_t cluster_version); static int fetch_table_entry(obproxy::ObResultSetFetcher &rs_fetcher, ObTableEntry &entry, const int64_t cluster_version); @@ -59,6 +59,14 @@ class ObRouteUtils static int fetch_sub_part(obproxy::ObResultSetFetcher &rs_fetcher, ObProxyPartInfo &part_info, const int64_t cluster_version); + static int get_binlog_entry_sql(char *sql_buf, + const int64_t buf_len, + const ObString &cluster_name, + const ObString &tenant_name); + + static int fetch_binlog_entry(obproxy::ObResultSetFetcher &rs_fetcher, ObTableEntry &entry); + static int split_part_expr(common::ObString expr, common::ObIArray &arr); + static int build_sys_dummy_entry(const common::ObString &cluster_name, const int64_t cluster_id, const obutils::LocationList &rs_list, @@ -112,12 +120,6 @@ class ObRouteUtils const int64_t generated_key_idx, ObProxyPartInfo &part_info); static int fetch_part_option(obproxy::ObResultSetFetcher &rs_fetcher, ObProxyPartInfo &part_info); - static int build_part_desc(ObProxyPartInfo &part_info, const int64_t cluster_version); - static int build_part_desc(ObProxyPartInfo &part_info, - const share::schema::ObPartitionLevel part_level, - ObProxyPartOption &part_opt, - const int64_t cluster_version); - }; bool is_fake_ip_port(const char *ip_str, const int64_t port); diff --git a/src/obproxy/proxy/route/ob_server_route.h b/src/obproxy/proxy/route/ob_server_route.h index 905ba2733..64b9afbed 100644 --- a/src/obproxy/proxy/route/ob_server_route.h +++ b/src/obproxy/proxy/route/ob_server_route.h @@ -53,8 +53,6 @@ class ObServerRoute // | | // +<---------------------------------------+ const ObProxyReplicaLocation *get_next_avail_replica(); - const ObProxyReplicaLocation *get_next_replica(const uint32_t cur_ip, const uint16_t cur_port, - const bool is_force_retry); const ObProxyReplicaLocation *get_leader_replica_from_remote() const; ObTableEntry *get_dummy_entry(); @@ -437,27 +435,6 @@ inline const ObProxyReplicaLocation *ObServerRoute::get_next_avail_replica() return cur_chosen_server_.replica_; } -inline const ObProxyReplicaLocation *ObServerRoute::get_next_replica( - const uint32_t cur_ip, - const uint16_t cur_port, - const bool is_force_retry) -{ - UNUSED(is_force_retry); - const ObProxyReplicaLocation *replica = NULL; - bool found = false; - leader_item_.is_used_ = true; - while (!found) { - replica = get_next_avail_replica(); - if (NULL == replica) { - found = true; - } else if ((cur_ip != replica->server_.get_ipv4()) - || (cur_port != static_cast(replica->server_.get_port()))) { - found = true; - } - } - return replica; -} - inline bool ObServerRoute::is_partition_table() const { return ((NULL != table_entry_) && table_entry_->is_partition_table()); diff --git a/src/obproxy/proxy/route/ob_table_entry.cpp b/src/obproxy/proxy/route/ob_table_entry.cpp index 42155b324..409e07c89 100644 --- a/src/obproxy/proxy/route/ob_table_entry.cpp +++ b/src/obproxy/proxy/route/ob_table_entry.cpp @@ -118,6 +118,7 @@ int ObTableEntry::set_names(const ObTableEntryName &name) LOG_WARN("fail to deep copy table entry names", K(ret)); } else { is_dummy_entry_ = name_.is_all_dummy_table(); + is_binlog_entry_ = name_.is_binlog_table(); } return ret; } diff --git a/src/obproxy/proxy/route/ob_table_entry.h b/src/obproxy/proxy/route/ob_table_entry.h index b04cd2760..34edf1856 100644 --- a/src/obproxy/proxy/route/ob_table_entry.h +++ b/src/obproxy/proxy/route/ob_table_entry.h @@ -40,7 +40,7 @@ class ObTableEntry : public ObRouteEntry { public: ObTableEntry() - : ObRouteEntry(), is_inited_(false), is_dummy_entry_(false), is_entry_from_rslist_(false), + : ObRouteEntry(), is_inited_(false), is_dummy_entry_(false), is_binlog_entry_(NULL), is_entry_from_rslist_(false), is_empty_entry_allowed_(false), is_need_force_flush_(false), has_dup_replica_(false), table_id_(common::OB_INVALID_ID), table_type_(share::schema::MAX_TABLE_TYPE), part_num_(0), replica_num_(0), name_(), buf_len_(0), buf_start_(NULL), first_pl_(NULL) @@ -70,7 +70,7 @@ class ObTableEntry : public ObRouteEntry bool is_dummy_entry() const { return is_dummy_entry_; } bool is_sys_dummy_entry() const { return is_dummy_entry_ && name_.is_sys_tenant(); } bool is_common_dummy_entry() const { return is_dummy_entry_ && !name_.is_sys_tenant(); } - bool is_location_entry() const { return !is_dummy_entry_ && 1 == part_num_; } + bool is_location_entry() const { return (!is_dummy_entry_ && 1 == part_num_) || is_binlog_entry_; } bool is_part_info_entry() const { return !is_dummy_entry_ && part_num_ > 1; } bool is_non_partition_table() const { return (1 == get_part_num()); } bool is_partition_table() const { return (get_part_num() > 1); } @@ -125,6 +125,7 @@ class ObTableEntry : public ObRouteEntry private: bool is_inited_; bool is_dummy_entry_; + bool is_binlog_entry_; bool is_entry_from_rslist_; bool is_empty_entry_allowed_; bool is_need_force_flush_; @@ -164,7 +165,7 @@ inline bool ObTableEntry::is_valid() const || (is_location_entry() && NULL != first_pl_ && OB_LIKELY(first_pl_->is_valid())) || (is_part_info_entry() && NULL != part_info_ && OB_LIKELY(part_info_->is_valid())))) ) - ); + ) || is_binlog_entry_; } inline int64_t ObTableEntry::get_server_count() const diff --git a/src/obproxy/proxy/route/ob_table_entry_cont.cpp b/src/obproxy/proxy/route/ob_table_entry_cont.cpp index 7f4cc91bb..a5a4950bd 100644 --- a/src/obproxy/proxy/route/ob_table_entry_cont.cpp +++ b/src/obproxy/proxy/route/ob_table_entry_cont.cpp @@ -240,6 +240,9 @@ const char *ObTableEntryCont::get_state_name(const ObTableEntryLookupState state case LOOKUP_DONE_STATE: name = "LOOKUP_DONE_STATE"; break; + case LOOKUP_BINLOG_ENTRY_STATE: + name = "LOOKUP_BINLOG_ENTRY_STATE"; + break; default: name = "Unknown State"; LOG_WARN("Unknown State", K(state)); @@ -392,6 +395,7 @@ inline int ObTableEntryCont::set_next_state() bool is_part_table_route_supported = table_param_.is_partition_table_route_supported_; switch (state_) { case LOOKUP_TABLE_ENTRY_STATE: + case LOOKUP_BINLOG_ENTRY_STATE: if (OB_ISNULL(newest_table_entry_)) { next_state = LOOKUP_DONE_STATE; } else if (newest_table_entry_->is_partition_table() && is_part_table_route_supported) { @@ -428,12 +432,7 @@ inline int ObTableEntryCont::set_next_state() next_state = LOOKUP_DONE_STATE; ret = OB_ERR_UNEXPECTED; LOG_WARN("part info should not be null here", K(ret)); - } else if ((!IS_CLUSTER_VERSION_LESS_THAN_V4(table_param_.cluster_version_) - && PARTITION_LEVEL_TWO == newest_table_entry_->get_part_info()->get_part_level()) - || (IS_CLUSTER_VERSION_LESS_THAN_V4(table_param_.cluster_version_) - && (!newest_table_entry_->get_part_info()->is_template_table() - || newest_table_entry_->get_part_info()->get_sub_part_option().is_range_part(table_param_.cluster_version_) - || newest_table_entry_->get_part_info()->get_sub_part_option().is_list_part(table_param_.cluster_version_)))) { + } else if (newest_table_entry_->get_part_info()->has_sub_part()) { next_state = LOOKUP_SUB_PART_STATE; } else { next_state = LOOKUP_DONE_STATE; @@ -483,6 +482,9 @@ inline int ObTableEntryCont::handle_client_resp(void *data) case LOOKUP_SUB_PART_STATE: ret = handle_sub_part_resp(*rs_fetcher); break; + case LOOKUP_BINLOG_ENTRY_STATE: + ret = handle_binlog_entry_resp(*rs_fetcher); + break; case LOOKUP_DONE_STATE: default: ret = OB_ERR_UNEXPECTED; @@ -541,6 +543,22 @@ inline int ObTableEntryCont::handle_table_entry_resp(ObResultSetFetcher &rs_fetc return ret; } +int ObTableEntryCont::handle_binlog_entry_resp(ObResultSetFetcher &rs_fetcher) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(ObTableEntry::alloc_and_init_table_entry(table_param_.name_, 0, 0, newest_table_entry_))) { + LOG_WARN("fail to alloc and init table entry", "name", table_param_.name_, K(ret)); + } else if (OB_ISNULL(newest_table_entry_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table entry should not be NULL", K_(newest_table_entry), K(ret)); + } else if (OB_FAIL(ObRouteUtils::fetch_binlog_entry(rs_fetcher, + *newest_table_entry_))) { + LOG_WARN("fail to fetch binlog entry info", K(ret)); + } + + return ret; +} + inline int ObTableEntryCont::handle_part_info_resp(ObResultSetFetcher &rs_fetcher) { int ret = OB_SUCCESS; @@ -887,13 +905,33 @@ inline int ObTableEntryCont::lookup_entry_remote() ObMysqlProxy *mysql_proxy = table_param_.mysql_proxy_; char sql[OB_SHORT_SQL_LENGTH]; sql[0] = '\0'; - if (OB_FAIL(ObRouteUtils::get_table_entry_sql(sql, OB_SHORT_SQL_LENGTH, table_param_.name_, - table_param_.is_need_force_flush_, table_param_.cluster_version_))) { - LOG_WARN("fail to get table entry sql", K(sql), K(ret)); + if (table_param_.name_.table_name_ == OB_ALL_BINLOG_DUMMY_TNAME) { + if (OB_FAIL(ObRouteUtils::get_binlog_entry_sql(sql, OB_SHORT_SQL_LENGTH, + table_param_.name_.cluster_name_, table_param_.name_.tenant_name_))) { + LOG_WARN("fail to get binlog entry sql", K(ret)); + } else { + state_ = LOOKUP_BINLOG_ENTRY_STATE; + ObMysqlRequestParam request_param(sql); + ObAddr addr; + if (OB_FAIL(addr.parse_from_cstring(get_global_proxy_config().binlog_service_ip.str()))) { + LOG_WARN("parse from cstring failed", K(ret)); + } else { + request_param.set_target_addr(addr); + request_param.ob_client_flags_.client_flags_.OB_CLIENT_SKIP_AUTOCOMMIT = 1; + if (OB_FAIL(mysql_proxy->async_read(this, request_param, pending_action_))) { + LOG_WARN("fail to aysnc read", K(sql), K(addr), K(ret)); + } + } + } } else { - const ObMysqlRequestParam request_param(sql, table_param_.current_idc_name_); - if (OB_FAIL(mysql_proxy->async_read(this, request_param, pending_action_))) { - LOG_WARN("fail to nonblock read", K(sql), K_(table_param), K(ret)); + if (OB_FAIL(ObRouteUtils::get_table_entry_sql(sql, OB_SHORT_SQL_LENGTH, table_param_.name_, + table_param_.is_need_force_flush_, table_param_.cluster_version_))) { + LOG_WARN("fail to get table entry sql", K(sql), K(ret)); + } else { + const ObMysqlRequestParam request_param(sql, table_param_.current_idc_name_); + if (OB_FAIL(mysql_proxy->async_read(this, request_param, pending_action_))) { + LOG_WARN("fail to nonblock read", K(sql), K_(table_param), K(ret)); + } } } diff --git a/src/obproxy/proxy/route/ob_table_entry_cont.h b/src/obproxy/proxy/route/ob_table_entry_cont.h index a330b6e6f..189bae912 100644 --- a/src/obproxy/proxy/route/ob_table_entry_cont.h +++ b/src/obproxy/proxy/route/ob_table_entry_cont.h @@ -50,6 +50,7 @@ enum ObTableEntryLookupState LOOKUP_PART_INFO_STATE, LOOKUP_FIRST_PART_STATE, LOOKUP_SUB_PART_STATE, + LOOKUP_BINLOG_ENTRY_STATE, LOOKUP_DONE_STATE, }; @@ -142,6 +143,7 @@ class ObTableEntryCont : public obutils::ObAsyncCommonTask int handle_sub_part_resp(ObResultSetFetcher &rs_fetcher); int handle_lookup_remote(); int handle_lookup_remote_done(); + int handle_binlog_entry_resp(ObResultSetFetcher &rs_fetcher); int handle_lookup_remote_for_update(); int add_to_global_cache(bool &add_succ); diff --git a/src/obproxy/proxy/route/obproxy_expr_calculator.cpp b/src/obproxy/proxy/route/obproxy_expr_calculator.cpp index 27c163031..c22bc8004 100644 --- a/src/obproxy/proxy/route/obproxy_expr_calculator.cpp +++ b/src/obproxy/proxy/route/obproxy_expr_calculator.cpp @@ -47,8 +47,10 @@ int ObProxyExprCalculator::calculate_partition_id(common::ObArenaAllocator &allo { int ret = OB_SUCCESS; ObString part_name = parse_result.get_part_name(); + bool old_is_oracle_mode = lib::is_oracle_mode(); + lib::set_oracle_mode(client_info.is_oracle_mode()); if (!part_name.empty()) { - if (OB_FAIL(part_info.get_part_mgr().get_part_with_part_name(part_name, partition_id))) { + if (OB_FAIL(part_info.get_part_mgr().get_part_with_part_name(part_name, partition_id, part_info, route, *this))) { LOG_WARN("fail to get part id with part name", K(part_name), K(ret)); } } @@ -92,7 +94,8 @@ int ObProxyExprCalculator::calculate_partition_id(common::ObArenaAllocator &allo LOG_INFO("fail to do expr parse", K(print_sql), K(part_info), "expr_parse_result", ObExprParseResultPrintWrapper(expr_parse_result)); } else if (OB_FAIL(do_expr_resolve(expr_parse_result, client_request, &client_info, ps_id_entry, - text_ps_entry, part_info, allocator, resolve_result, partition_id))) { + text_ps_entry, part_info, allocator, resolve_result, + parse_result, partition_id))) { LOG_INFO("fail to do expr resolve", K(print_sql), "expr_parse_result", ObExprParseResultPrintWrapper(expr_parse_result), K(part_info), KPC(ps_id_entry), KPC(text_ps_entry), K(resolve_result)); @@ -126,6 +129,7 @@ int ObProxyExprCalculator::calculate_partition_id(common::ObArenaAllocator &allo } } + lib::set_oracle_mode(old_is_oracle_mode); return ret; } @@ -197,14 +201,6 @@ int ObProxyExprCalculator::do_expr_parse(const common::ObString &req_sql, expr_result.part_key_info_.part_keys_[i] = key_info.part_keys_[i]; } - expr_result.target_mask_ = 0; - if (PARTITION_LEVEL_ONE == part_info.get_part_level()) { - expr_result.target_mask_ = FIRST_PART_MASK; - } else if (PARTITION_LEVEL_TWO == part_info.get_part_level()) { - expr_result.target_mask_ = BOTH_PART_MASK; - } else { - // do nothing - } if (OB_FAIL(expr_parser.parse_reqsql(req_sql, parse_result.get_parsed_length(), expr_result, parse_result.get_stmt_type(), connection_collation))) { LOG_DEBUG("fail to do expr parse_reqsql", K(req_sql), K(ret)); @@ -247,6 +243,7 @@ int ObProxyExprCalculator::do_expr_resolve(ObExprParseResult &parse_result, ObProxyPartInfo &part_info, ObIAllocator &allocator, ObExprResolverResult &resolve_result, + const ObSqlParseResult &sql_parse_result, int64_t &partition_id) { int ret = OB_SUCCESS; @@ -257,7 +254,10 @@ int ObProxyExprCalculator::do_expr_resolve(ObExprParseResult &parse_result, ctx.ps_id_entry_ = ps_id_entry; ctx.text_ps_entry_ = text_ps_entry; ctx.client_info_ = client_info; - + ctx.parse_result_ = &parse_result; + ctx.is_insert_stm_ = sql_parse_result.is_insert_stmt(); + ObSqlParseResult &result = const_cast(sql_parse_result); + ctx.sql_field_result_ = &result.get_sql_filed_result(); ObExprResolver expr_resolver(allocator); if (parse_result.has_rowid_) { @@ -332,7 +332,8 @@ int ObProxyExprCalculator::do_partition_id_calc(ObExprResolverResult &resolve_re LOG_DEBUG("do partition id calc", K(sub_part_id), K(tablet_id), K(part_info.has_sub_part())); - if (OB_SUCC(ret)) { + if (OB_SUCC(ret) + && (tablet_id != -1 || (first_part_id != OB_INVALID_INDEX && (!part_info.has_sub_part() || sub_part_id != OB_INVALID_INDEX)))) { if (tablet_id == -1) { partition_id = generate_phy_part_id(first_part_id, sub_part_id, part_info.get_part_level()); } else { @@ -378,8 +379,10 @@ int ObProxyExprCalculator::calc_part_id_by_random_choose_from_exist(ObProxyPartI if (OB_FAIL(ObRandomNumUtils::get_random_num(0, first_part_num - 1, rand_num))) { LOG_WARN("fail to get random num in first part", K(first_part_num), K(ret)); } else { - if (OB_FAIL(part_mgr.get_first_part_id_by_idx(rand_num, first_part_id, tablet_id))) { - LOG_WARN("failed to random get first part id by idx", K(rand_num), K(ret)); + if (OB_FAIL(part_mgr.get_first_part_id_by_random(rand_num, first_part_id, tablet_id))) { + LOG_WARN("failed to get first part id by random", K(rand_num), K(ret)); + } else { + //nothing; } } } @@ -434,6 +437,7 @@ int ObProxyExprCalculator::calc_partition_id_using_rowid(ObExprResolverContext & { int ret = OB_SUCCESS; const ObProxyRelationInfo *relation_info = ctx.relation_info_; + if (OB_ISNULL(relation_info)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid ctx relation info", K(ret)); @@ -458,7 +462,7 @@ int ObProxyExprCalculator::calc_partition_id_using_rowid(ObExprResolverContext & } } // for } - + return ret; } @@ -470,21 +474,30 @@ int ObProxyExprCalculator::calc_partition_id_with_rowid(ObProxyRelationExpr *rel { int ret = OB_SUCCESS; - ObNewRange &range = resolve_result.ranges_[0]; - ObExprResolver expr_resolver(allocator); - if (OB_FAIL(expr_resolver.resolve_token_list(relation, ctx.part_info_, ctx.client_request_, ctx.client_info_, - ctx.ps_id_entry_, ctx.text_ps_entry_, range, true))) { - LOG_INFO("fail to resolve token list with rowid", K(ret)); + ObObj *target_obj = NULL; + void *buf = NULL; + if (OB_ISNULL(buf = allocator.alloc(sizeof(ObObj)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc mem", K(ret)); + } else if (OB_ISNULL(target_obj = new (buf) ObObj())) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to new mem", K(ret)); } else { - ObObj &obj = const_cast(range.get_start_key().get_obj_ptr()[0]); - if (!obj.is_varchar()) { - ret = OB_ERR_UNEXPECTED; - LOG_INFO("expected obj type after resolved from execute", K(ret), K(obj.get_type())); + ObExprResolver expr_resolver(allocator); + if (OB_FAIL(expr_resolver.resolve_token_list(relation, ctx.part_info_, ctx.client_request_, ctx.client_info_, + ctx.ps_id_entry_, ctx.text_ps_entry_, + target_obj, ctx.sql_field_result_, true))) { + LOG_INFO("fail to resolve token list with rowid", K(ret)); } else { - ObString obj_str = obj.get_varchar(); - if (OB_FAIL(calc_partition_id_with_rowid_str(obj_str.ptr(), obj_str.length(), allocator, resolve_result, - *ctx.part_info_, partition_id))) { - LOG_INFO("fail to calc partition id with rowid str within execute", K(ret)); + if (!target_obj->is_varchar()) { + ret = OB_ERR_UNEXPECTED; + LOG_INFO("expected obj type after resolved from execute", K(ret), K(target_obj->get_type())); + } else { + ObString obj_str = target_obj->get_varchar(); + if (OB_FAIL(calc_partition_id_with_rowid_str(obj_str.ptr(), obj_str.length(), allocator, + resolve_result, *ctx.part_info_, partition_id))) { + LOG_INFO("fail to calc partition id with rowid str within execute", K(ret)); + } } } } @@ -502,10 +515,9 @@ int ObProxyExprCalculator::calc_partition_id_with_rowid_str(const char *str, int ret = OB_SUCCESS; ObURowIDData rowid_data; - ObArray pk_vals; if (OB_FAIL(ObURowIDData::decode2urowid(str, str_len, allocator, rowid_data))) { LOG_WARN("decode2urowid failed", K(ret)); - } else if (OB_FAIL(rowid_data.get_obobj_or_partition_id_from_decoded(part_info, resolve_result, partition_id))) { + } else if (OB_FAIL(rowid_data.get_obobj_or_partition_id_from_decoded(part_info, resolve_result, partition_id, allocator))) { LOG_WARN("fail to get obobj or partition id by rowid data", K(ret)); } else { // nothing @@ -533,7 +545,7 @@ int ObExprCalcTool::build_dtc_params_with_tz_info(ObClientSessionInfo *session_i } /* - * for ObTimestampLTZType, input timestamp string, and we also need time_zone from session + * for ObTimestampLTZType, ObTimestampTZType input timestamp string, and we also need time_zone from session * in order to decide the absolutely time */ int ObExprCalcTool::build_tz_info(ObClientSessionInfo *session_info, @@ -541,22 +553,31 @@ int ObExprCalcTool::build_tz_info(ObClientSessionInfo *session_info, ObTimeZoneInfo &tz_info) { int ret = OB_SUCCESS; + if (ObTimestampLTZType == obj_type || ObTimestampTZType == obj_type) { + if (OB_FAIL(build_tz_info_for_all_type(session_info, tz_info))) { + LOG_WARN("fail to build time zone info with session", K(ret)); + } + } + return ret; +} + +int ObExprCalcTool::build_tz_info_for_all_type(ObClientSessionInfo *session_info, + ObTimeZoneInfo &tz_info) +{ + int ret = OB_SUCCESS; + ObObj value_obj; + ObString sys_key_name = ObString::make_string(oceanbase::sql::OB_SV_TIME_ZONE); - if (ObTimestampLTZType == obj_type) { - ObObj value_obj; - ObString sys_key_name = ObString::make_string(oceanbase::sql::OB_SV_TIME_ZONE); - if (OB_FAIL(session_info->get_sys_variable_value(sys_key_name, value_obj))) { - LOG_WARN("fail to get sys var from session", K(ret), K(sys_key_name)); + if (OB_FAIL(session_info->get_sys_variable_value(sys_key_name, value_obj))) { + LOG_WARN("fail to get sys var from session", K(ret), K(sys_key_name)); + } else { + ObString value_str = value_obj.get_string(); + if (OB_FAIL(tz_info.set_timezone(value_str))) { + LOG_WARN("fail to set time zone for tz_info", K(ret), K(value_str)); } else { - ObString value_str = value_obj.get_string(); - if (OB_FAIL(tz_info.set_timezone(value_str))) { - LOG_WARN("fail to set time zone for tz_info", K(ret), K(value_str)); - } else { - LOG_DEBUG("succ to set time zone for tz_info", K(value_str)); - } + LOG_DEBUG("succ to set time zone for tz_info", K(value_str)); } } - return ret; } diff --git a/src/obproxy/proxy/route/obproxy_expr_calculator.h b/src/obproxy/proxy/route/obproxy_expr_calculator.h index 484eabf41..a657c074b 100644 --- a/src/obproxy/proxy/route/obproxy_expr_calculator.h +++ b/src/obproxy/proxy/route/obproxy_expr_calculator.h @@ -59,6 +59,10 @@ class ObProxyExprCalculator ObServerRoute &route, ObProxyPartInfo &part_info, int64_t &partition_id); + int calc_part_id_by_random_choose_from_exist(ObProxyPartInfo &part_info, + int64_t &first_part_id, + int64_t &sub_part_id, + int64_t &phy_part_id); private: // do parse -> do resolve -> do partition id calc int do_expr_parse(const common::ObString &req_sql, @@ -75,6 +79,7 @@ class ObProxyExprCalculator ObProxyPartInfo &part_info, common::ObIAllocator &allocator, opsql::ObExprResolverResult &resolve_result, + const obutils::ObSqlParseResult &sql_parse_result, int64_t &partition_id); int do_partition_id_calc(opsql::ObExprResolverResult &resolve_result, ObClientSessionInfo &client_info, @@ -96,21 +101,17 @@ class ObProxyExprCalculator opsql::ObExprResolverResult &resolve_result, common::ObIAllocator &allocator, int64_t &partition_id); + int calc_partition_id_with_rowid(ObProxyRelationExpr *relation, + opsql::ObExprResolverContext &ctx, + common::ObIAllocator &allocator, + opsql::ObExprResolverResult &resolve_result, + int64_t &partition_id); int calc_partition_id_with_rowid_str(const char *str, const int64_t str_len, common::ObIAllocator &allocator, opsql::ObExprResolverResult &resolve_result, ObProxyPartInfo &part_info, int64_t &partition_id); - int calc_partition_id_with_rowid(ObProxyRelationExpr *relation, - opsql::ObExprResolverContext &ctx, - common::ObIAllocator &allocator, - opsql::ObExprResolverResult &resolve_result, - int64_t &partition_id); - int calc_part_id_by_random_choose_from_exist(ObProxyPartInfo &part_info, - int64_t &first_part_id, - int64_t &sub_part_id, - int64_t &phy_part_id); }; class ObExprCalcTool { @@ -122,6 +123,9 @@ class ObExprCalcTool { static int build_tz_info(ObClientSessionInfo *session_info, common::ObObjType obj_type, common::ObTimeZoneInfo &tz_info); + + static int build_tz_info_for_all_type(ObClientSessionInfo *session_info, + common::ObTimeZoneInfo &tz_info); static int build_dtc_params(ObClientSessionInfo *session_info, common::ObObjType obj_type, common::ObDataTypeCastParams &dtc_params); diff --git a/src/obproxy/proxy/route/obproxy_part_info.cpp b/src/obproxy/proxy/route/obproxy_part_info.cpp index 7ff2a9024..d5621c04e 100644 --- a/src/obproxy/proxy/route/obproxy_part_info.cpp +++ b/src/obproxy/proxy/route/obproxy_part_info.cpp @@ -94,6 +94,7 @@ int ObProxyPartInfo::alloc(ObProxyPartInfo *&part_info) void ObProxyPartInfo::free() { + part_mgr_.destroy(); allocator_.reset(); op_fixed_mem_free(this, sizeof(ObProxyPartInfo)); } diff --git a/src/obproxy/proxy/route/obproxy_part_info.h b/src/obproxy/proxy/route/obproxy_part_info.h index cd15e4147..2f2a0bbee 100644 --- a/src/obproxy/proxy/route/obproxy_part_info.h +++ b/src/obproxy/proxy/route/obproxy_part_info.h @@ -68,6 +68,8 @@ class ObProxyPartInfo share::schema::ObPartitionLevel get_part_level() const { return part_level_; } common::ObCollationType get_table_cs_type() const { return table_cs_type_; } + common::ObIArray &get_part_columns() { return part_columns_; } + common::ObIArray &get_sub_part_columns() { return sub_part_columns_; } ObProxyPartOption &get_first_part_option() { return first_part_option_; } ObProxyPartOption &get_sub_part_option() { return sub_part_option_; } ObProxyPartMgr &get_part_mgr() { return part_mgr_; } @@ -91,6 +93,9 @@ class ObProxyPartInfo share::schema::ObPartitionLevel part_level_; common::ObCollationType table_cs_type_; + common::ObSEArray part_columns_; + common::ObSEArray sub_part_columns_; + common::ObArenaAllocator allocator_; ObProxyPartOption first_part_option_; ObProxyPartOption sub_part_option_; diff --git a/src/obproxy/proxy/route/obproxy_part_mgr.cpp b/src/obproxy/proxy/route/obproxy_part_mgr.cpp index 2e0e76a07..a61883049 100644 --- a/src/obproxy/proxy/route/obproxy_part_mgr.cpp +++ b/src/obproxy/proxy/route/obproxy_part_mgr.cpp @@ -17,7 +17,11 @@ #include "share/part/ob_part_desc_key.h" #include "share/part/ob_part_desc_range.h" #include "share/part/ob_part_desc_list.h" +#include "share/part/ob_part_mgr_util.h" #include "proxy/mysqllib/ob_resultset_fetcher.h" +#include "utils/ob_proxy_utils.h" +#include "proxy/route/obproxy_expr_calculator.h" +#include "proxy/route/ob_server_route.h" using namespace oceanbase::common; using namespace oceanbase::share::schema; @@ -27,59 +31,101 @@ namespace obproxy { namespace proxy { -int64_t ObPartNameIdPair::to_string(char *buf, const int64_t buf_len) const -{ - int64_t pos = 0; - J_OBJ_START(); - J_KV(K_(part_name), K_(part_id), K_(tablet_id)); - J_OBJ_END(); - return pos; -} ObProxyPartMgr::ObProxyPartMgr(ObIAllocator &allocator) : first_part_desc_(NULL) , sub_part_desc_(NULL) , first_part_num_(0) , sub_part_num_(NULL) - , part_pair_array_(NULL) + , all_first_part_name_buf_(NULL) + , all_sub_part_name_buf_(NULL) + , all_first_part_name_length_(0) + , all_sub_part_name_length_(0) + , first_part_name_id_map_() + , sub_part_name_id_map_() , allocator_(allocator) , cluster_version_(0) { } +void ObProxyPartMgr::destroy() +{ + if(first_part_name_id_map_.created()) { + first_part_name_id_map_.destroy(); + } + if(sub_part_name_id_map_.created()) { + sub_part_name_id_map_.destroy(); + } +} int ObProxyPartMgr::get_part_with_part_name(const ObString &part_name, - int64_t &part_id) + int64_t &part_id, + ObProxyPartInfo &part_info, + ObServerRoute &route, + ObProxyExprCalculator &expr_calculator) { int ret = OB_SUCCESS; - if (NULL != part_pair_array_&& first_part_num_ > 0) { - bool found = false; - for (int64_t i = 0; !found && i < first_part_num_; ++i) { - if (part_pair_array_[i].get_part_name().case_compare(part_name) == 0) { - int64_t tablet_id = part_pair_array_[i].get_tablet_id(); - if (tablet_id != -1) { - part_id = tablet_id; + if ( part_name.length() <= 0 || part_name.length() > MAX_PART_NAME_LENGTH) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("error part name", K(part_name)); + } else { + ObPartitionLevel part_level = part_info.get_part_level(); + ObString store_part_name; + int64_t * part_id_ptr = NULL; + PART_NAME_BUF tmp_buf;//64 byte stack buf + store_part_name.assign_ptr((char *)&tmp_buf, part_name.length()); + MEMCPY(store_part_name.ptr(), part_name.ptr(), store_part_name.length()); + string_to_upper_case(store_part_name.ptr(), store_part_name.length()); + if ((sub_part_name_id_map_.created()) && OB_NOT_NULL(part_id_ptr = (int64_t *)sub_part_name_id_map_.get(store_part_name))) { + //find sub part name, get ptr->(physical part id) + part_id = *part_id_ptr; + LOG_DEBUG("succ to get part id by sub part name", K(part_id), K(part_name)); + } else if ((first_part_name_id_map_.created()) && OB_NOT_NULL(part_id_ptr = (int64_t *)first_part_name_id_map_.get(store_part_name))) { + //find first part name, get ptr->(first part id) + LOG_DEBUG("succ to get part id by first part name", K(*part_id_ptr), K(part_name)); + if(OB_LIKELY(PARTITION_LEVEL_ONE == part_level)) { + part_id = *part_id_ptr; + } else if((PARTITION_LEVEL_TWO == part_level) + && !obutils::get_global_proxy_config().enable_primary_zone + && !obutils::get_global_proxy_config().enable_cached_server) { + int64_t first_part_id = *part_id_ptr; + int64_t sub_part_id = OB_INVALID_INDEX; + if(OB_FAIL(expr_calculator.calc_part_id_by_random_choose_from_exist(part_info, first_part_id, sub_part_id, part_id))) { + LOG_DEBUG("fail to get random part id by first part name", K(first_part_id), K(part_id), K(part_name)); } else { - part_id = part_pair_array_[i].get_part_id(); + // get part id by random, no need update pl + route.no_need_pl_update_ = true; + LOG_DEBUG("succ to get random part id by first part name", K(first_part_id), K(sub_part_id), K(part_id)); } - found = true; + } else { + //do nothing } } - if (found) { - LOG_DEBUG("succ to get part id with part name", K(part_id), K(part_name)); - } } return ret; } -int ObProxyPartMgr::get_first_part_id_by_idx(const int64_t idx, int64_t &part_id, int64_t &tablet_id) +int ObProxyPartMgr::get_first_part_id_by_random(const int64_t rand_num, + int64_t &first_part_id, + int64_t &tablet_id) { int ret = OB_SUCCESS; - if (idx < 0 || idx >= first_part_num_ || OB_ISNULL(part_pair_array_)) { + ObSEArray part_ids; + ObSEArray tablet_ids; + if (OB_ISNULL(first_part_desc_)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("fail to get part id by idx", K(ret), K(idx), K(first_part_num_), K(part_pair_array_)); + LOG_WARN("fail to get first part, null ptr", K(ret)); } else { - part_id = part_pair_array_[idx].get_part_id(); - tablet_id = part_pair_array_[idx].get_tablet_id(); + if (OB_FAIL(first_part_desc_->get_part_by_num(rand_num, part_ids, tablet_ids))) { + LOG_WARN("fail to get first part by random", K(first_part_desc_), K(ret)); + } else { + if (part_ids.count() >= 1) { + first_part_id = part_ids[0]; + } + if (tablet_ids.count() >= 1) { + tablet_id = tablet_ids[0]; + } + } } + return ret; } @@ -211,6 +257,7 @@ int ObProxyPartMgr::build_hash_part(const bool is_oracle_mode, const ObPartitionFuncType part_func_type, const int64_t part_num, const int64_t part_space, + const int64_t part_col_num, const bool is_template_table, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher *rs_fetcher /*NULL*/, @@ -219,10 +266,11 @@ int ObProxyPartMgr::build_hash_part(const bool is_oracle_mode, int ret = OB_SUCCESS; void *tmp_buf = NULL; ObPartDescHash *desc_hash = NULL; - int64_t part_id = -1; - ObString part_name; + PART_NAME_BUF *name_buf = NULL; + int64_t *name_len_buf = NULL; + int64_t *part_id_buf = NULL; int64_t sub_part_num = 0; - int64_t tablet_id = -1; + ObString part_name; int64_t *part_array = NULL; // After observer v4.0, there is no concept of template partition @@ -235,6 +283,8 @@ int ObProxyPartMgr::build_hash_part(const bool is_oracle_mode, } else if (OB_ISNULL(desc_hash = new (tmp_buf) ObPartDescHash())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("part mgr reach memory limit", K(ret)); + } else if (OB_FAIL(alloc_name_buf(name_buf, name_len_buf, part_id_buf, part_num))) { + LOG_WARN("fail to alloc name buf", K(ret)); } else if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) && OB_ISNULL(desc_hash->tablet_id_array_ = (int64_t*)allocator_.alloc(sizeof(int64_t) * part_num))) { ret = OB_REACH_MEMORY_LIMIT; LOG_WARN("part mgr reach memory limit, alloc tablet id array failed", K(ret), K(part_num)); @@ -242,44 +292,68 @@ int ObProxyPartMgr::build_hash_part(const bool is_oracle_mode, ret = OB_REACH_MEMORY_LIMIT; LOG_WARN("part mgr reach memory limit, alloc part array failed", K(ret), K(part_num)); } else { - if (NULL != rs_fetcher && PARTITION_LEVEL_ONE == part_level) { - first_part_num_ = part_num; - if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObPartNameIdPair) * part_num))) { - ret = OB_REACH_MEMORY_LIMIT; - LOG_WARN("part mgr reach memory limit", K(ret)); - } else if (OB_ISNULL(part_pair_array_ = new (tmp_buf) ObPartNameIdPair[part_num])) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(part_num), K(ret)); - } else if (!is_template_table && OB_ISNULL(sub_part_num_ = (int64_t *)allocator_.alloc(sizeof(int64_t) * part_num))) { - ret = OB_REACH_MEMORY_LIMIT; - LOG_WARN("part mgr reach memory limit", K(ret)); - } - for (int64_t i = 0; i < part_num && OB_SUCC(ret); ++i) { - if (OB_FAIL(rs_fetcher->next())) { - LOG_DEBUG("failed to get next rs_fetcher", K(ret)); - } else { - PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "part_id", part_id, int64_t); - PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(*rs_fetcher, "part_name", part_name); - part_pair_array_[i].set_part_id(part_id); - if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { - PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "tablet_id", tablet_id, int64_t); - part_pair_array_[i].set_tablet_id(tablet_id); - desc_hash->tablet_id_array_[i] = tablet_id; - part_array[i] = part_id; - } - if (OB_FAIL(part_pair_array_[i].set_part_name(part_name))) { - LOG_WARN("fail to set part name", K(part_name), K(ret)); - } else if (!is_template_table) { - PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "sub_part_num", sub_part_num, int64_t); - sub_part_num_[i] = sub_part_num; + if (NULL != rs_fetcher) { + if (PARTITION_LEVEL_ONE == part_level) { + first_part_num_ = part_num; + if (!is_template_table && OB_ISNULL(sub_part_num_ = (int64_t *)allocator_.alloc(sizeof(int64_t) * part_num))) { + ret = OB_REACH_MEMORY_LIMIT; + LOG_WARN("part mgr reach memory limit", K(ret)); + } + for (int64_t i = 0; i < part_num && OB_SUCC(ret); ++i) { + if (OB_FAIL(rs_fetcher->next())) { + LOG_DEBUG("fail to get next rs_fetcher", K(ret)); + } else { + PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "part_id", part_id_buf[i], int64_t); + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(*rs_fetcher, "part_name", part_name); + + if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { + int64_t tablet_id = -1; + part_array[i] = part_id_buf[i]; + PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "tablet_id", tablet_id, int64_t); + desc_hash->tablet_id_array_[i] = tablet_id; + if ((tablet_id != -1) && (tablet_id != 0)) { + part_id_buf[i] = tablet_id; + } + } + + if (part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[i], part_name.ptr(), part_name.length()); + name_len_buf[i] = part_name.length(); + all_first_part_name_length_ += part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[i] = 0; + } + + if (!is_template_table) { + PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "sub_part_num", sub_part_num, int64_t); + sub_part_num_[i] = sub_part_num; + } } + } // end for + if (OB_ITER_END == ret) { + LOG_DEBUG("empty first hash part info, maybe ob version < 2.1", K(ret)); + ret = OB_SUCCESS; } - } // end for - if (OB_ITER_END == ret) { - LOG_DEBUG("empty first hash part info, maybe ob version < 2.1", K(ret)); - ret = OB_SUCCESS; + } else if (PARTITION_LEVEL_TWO == part_level) { + for (int64_t i = 0; i < part_num && OB_SUCC(ret); ++i) {//part_num=sub part num + if (OB_FAIL(rs_fetcher->next())) { + LOG_DEBUG("fail to get next rs_fetcher", K(ret)); + } else { + PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "sub_part_id", part_id_buf[i], int64_t); + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(*rs_fetcher, "part_name", part_name); + if (part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[i], part_name.ptr(), part_name.length()); + name_len_buf[i] = part_name.length(); + all_sub_part_name_length_ += part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[i] = 0; + } + } + } // end for + } else { + //nothing } - } // end NULL != rs_fetcher && PARTITION_LEVEL_ONE == part_level + } // end NULL != rs_fetcher } if (OB_SUCC(ret)) { @@ -291,30 +365,52 @@ int ObProxyPartMgr::build_hash_part(const bool is_oracle_mode, desc_hash->set_part_num(part_num); desc_hash->set_part_level(part_level); desc_hash->set_part_func_type(part_func_type); - // find the first match key, should consider whether the key is both part one and part two? + for (int i = 0; i < part_col_num; i++) { + desc_hash->get_accuracies().push_back(ObAccuracy()); + desc_hash->get_obj_types().push_back(ObObjType()); + desc_hash->get_cs_types().push_back(ObCollationType()); + } + // find all keys in this level for (int i = 0; i < key_info.key_num_; ++i) { if (static_cast(key_info.part_keys_[i].level_) == part_level) { - desc_hash->set_part_key_type(static_cast(key_info.part_keys_[i].obj_type_)); - desc_hash->set_part_key_cs_type(static_cast(key_info.part_keys_[i].cs_type_)); - desc_hash->set_accuracy(key_info.part_keys_[i].accuracy_); - break; + ObAccuracy accuracy(key_info.part_keys_[i].accuracy_.valid_, + key_info.part_keys_[i].accuracy_.length_, + key_info.part_keys_[i].accuracy_.precision_, + key_info.part_keys_[i].accuracy_.scale_); + desc_hash->get_accuracies().at(key_info.part_keys_[i].idx_in_part_columns_) = accuracy; + desc_hash->get_obj_types().at(key_info.part_keys_[i].idx_in_part_columns_) = static_cast(key_info.part_keys_[i].obj_type_); + desc_hash->get_cs_types().at(key_info.part_keys_[i].idx_in_part_columns_) = static_cast(key_info.part_keys_[i].cs_type_); } } + if (PARTITION_LEVEL_ONE == part_level) { first_part_desc_ = desc_hash; + if (OB_FAIL(init_first_part_map())) { + LOG_DEBUG("fail to create first part name id map", K(ret)); + } else if (OB_FAIL(build_part_name_id_map(name_buf, name_len_buf, part_id_buf, all_first_part_name_buf_, all_first_part_name_length_, part_num, first_part_name_id_map_))) { + LOG_DEBUG("fail to build first part name id map", K(ret)); + } } else if (PARTITION_LEVEL_TWO == part_level) { sub_part_desc_ = desc_hash; + if (OB_FAIL(init_sub_part_map())) { + LOG_DEBUG("fail to create temp sub part name id map", K(ret)); + } else if (OB_FAIL(build_temp_sub_part_name_id_map(name_buf, name_len_buf, part_id_buf, part_num))) { + LOG_DEBUG("fail to build temp sub part name id map", K(ret)); + } } else { ret = OB_INVALID_ARGUMENT; LOG_WARN("part level invalid", K(part_level), K(ret)); } } + + free_name_buf(name_buf, name_len_buf, part_id_buf); return ret; } int ObProxyPartMgr::build_sub_hash_part_with_non_template(const bool is_oracle_mode, const ObPartitionFuncType part_func_type, const int64_t part_space, + const int64_t part_col_num, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, const int64_t cluster_version) @@ -323,7 +419,12 @@ int ObProxyPartMgr::build_sub_hash_part_with_non_template(const bool is_oracle_m void *tmp_buf = NULL; ObPartDescHash *desc_hash = NULL; common::ObPartDesc *sub_part_desc = NULL; - int64_t part_id = -1; + PART_NAME_BUF *name_buf = NULL; + int64_t *name_len_buf = NULL; + int64_t *part_id_buf = NULL; + int64_t first_part_id = -1; + int64_t sub_part_id = -1; + ObString sub_part_name; // alloc desc_range if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObPartDescHash) * first_part_num_))) { @@ -331,9 +432,12 @@ int ObProxyPartMgr::build_sub_hash_part_with_non_template(const bool is_oracle_m LOG_WARN("part mgr reach memory limit", K(ret)); } else if (OB_ISNULL(sub_part_desc = new (tmp_buf) ObPartDescHash[first_part_num_])) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(ret)); + LOG_WARN("fail to do placement new", K(tmp_buf), K(ret)); + } else if (OB_FAIL(alloc_name_buf(name_buf, name_len_buf, part_id_buf, all_sub_part_num_))) { + LOG_WARN("fail to alloc name buf", K(ret)); } + int64_t index=0; for (int64_t i = 0; i < first_part_num_ && OB_SUCC(ret); ++i) { desc_hash = (((ObPartDescHash *)sub_part_desc) + i); if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) && OB_ISNULL(desc_hash->tablet_id_array_ = (int64_t*)allocator_.alloc(sizeof(int64_t) * sub_part_num_[i]))) { @@ -342,30 +446,52 @@ int ObProxyPartMgr::build_sub_hash_part_with_non_template(const bool is_oracle_m } for (int64_t j = 0; j < sub_part_num_[i] && OB_SUCC(ret); ++j) { - if (OB_FAIL(rs_fetcher.next())) { - LOG_WARN("failed to get next rs_fetcher", K(ret)); + if (OB_FAIL(rs_fetcher.next()) || index >= all_sub_part_num_) { + LOG_WARN("fail to get next rs_fetcher", K(ret)); } else { - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_id", part_id, int64_t); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_id", first_part_id, int64_t); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sub_part_id", sub_part_id, int64_t); + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_name", sub_part_name); if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "tablet_id", desc_hash->tablet_id_array_[j], int64_t); } + if (sub_part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[index], sub_part_name.ptr(), sub_part_name.length()); + name_len_buf[index] = sub_part_name.length(); + if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { + part_id_buf[index] = desc_hash->tablet_id_array_[j]; + } else { + part_id_buf[index] = generate_phy_part_id(first_part_id, sub_part_id); + } + all_sub_part_name_length_ += sub_part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[index] = 0; + } + ++index; } } - if (OB_SUCC(ret)) { desc_hash->set_oracle_mode(is_oracle_mode); - desc_hash->set_first_part_id(part_id); + desc_hash->set_first_part_id(first_part_id); desc_hash->set_part_space(part_space); desc_hash->set_part_num(sub_part_num_[i]); desc_hash->set_part_level(PARTITION_LEVEL_TWO); desc_hash->set_part_func_type(part_func_type); - // find the first match key, should consider whether the key is both part one and part two? + for (int i = 0; i < part_col_num; i++) { + desc_hash->get_accuracies().push_back(ObAccuracy()); + desc_hash->get_obj_types().push_back(ObObjType()); + desc_hash->get_cs_types().push_back(ObCollationType()); + } + // find all keys in this level for (int i = 0; i < key_info.key_num_; ++i) { if (static_cast(key_info.part_keys_[i].level_) == PARTITION_LEVEL_TWO) { - desc_hash->set_part_key_type(static_cast(key_info.part_keys_[i].obj_type_)); - desc_hash->set_part_key_cs_type(static_cast(key_info.part_keys_[i].cs_type_)); - desc_hash->set_accuracy(key_info.part_keys_[i].accuracy_); - break; + ObAccuracy accuracy(key_info.part_keys_[i].accuracy_.valid_, + key_info.part_keys_[i].accuracy_.length_, + key_info.part_keys_[i].accuracy_.precision_, + key_info.part_keys_[i].accuracy_.scale_); + desc_hash->get_accuracies().at(key_info.part_keys_[i].idx_in_part_columns_) = accuracy; + desc_hash->get_obj_types().at(key_info.part_keys_[i].idx_in_part_columns_) = static_cast(key_info.part_keys_[i].obj_type_); + desc_hash->get_cs_types().at(key_info.part_keys_[i].idx_in_part_columns_) = static_cast(key_info.part_keys_[i].cs_type_); } } } @@ -373,8 +499,14 @@ int ObProxyPartMgr::build_sub_hash_part_with_non_template(const bool is_oracle_m if (OB_SUCC(ret)) { sub_part_desc_ = sub_part_desc; + if (OB_FAIL(init_sub_part_map())) { + LOG_DEBUG("fail to create non temp sub part name id map", K(ret)); + } else if (OB_FAIL(build_part_name_id_map(name_buf, name_len_buf, part_id_buf, all_sub_part_name_buf_, all_sub_part_name_length_, all_sub_part_num_, sub_part_name_id_map_))) { + LOG_DEBUG("fail to build non temp sub part name id map", K(ret)); + } } + free_name_buf(name_buf, name_len_buf, part_id_buf); return ret; } @@ -382,6 +514,7 @@ int ObProxyPartMgr::build_key_part(const ObPartitionLevel part_level, const ObPartitionFuncType part_func_type, const int64_t part_num, const int64_t part_space, + const int64_t part_col_num, const bool is_template_table, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher *rs_fetcher /*NULL*/, @@ -390,9 +523,11 @@ int ObProxyPartMgr::build_key_part(const ObPartitionLevel part_level, int ret = OB_SUCCESS; void *tmp_buf = NULL; ObPartDescKey *desc_key = NULL; - int64_t part_id = -1; - ObString part_name; + PART_NAME_BUF *name_buf = NULL; + int64_t *name_len_buf = NULL; + int64_t *part_id_buf = NULL; int64_t sub_part_num = 0; + ObString part_name; int64_t *part_array = NULL; if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) && PARTITION_LEVEL_TWO == part_level) { @@ -404,6 +539,8 @@ int ObProxyPartMgr::build_key_part(const ObPartitionLevel part_level, } else if (OB_ISNULL(desc_key = new (tmp_buf) ObPartDescKey())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("part mgr reach memory limit", K(ret)); + } else if (OB_FAIL(alloc_name_buf(name_buf, name_len_buf, part_id_buf, part_num))) { + LOG_WARN("fail to alloc name buf", K(ret)); } else if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) && OB_ISNULL(desc_key->tablet_id_array_ = (int64_t*)allocator_.alloc(sizeof(int64_t) * part_num))) { ret = OB_REACH_MEMORY_LIMIT; LOG_WARN("part mgr reach memory limit", K(ret), K(part_num)); @@ -411,46 +548,70 @@ int ObProxyPartMgr::build_key_part(const ObPartitionLevel part_level, ret = OB_REACH_MEMORY_LIMIT; LOG_WARN("fail to alloc part array", K(ret), K(part_num)); } else { - if (NULL != rs_fetcher && PARTITION_LEVEL_ONE == part_level) { - first_part_num_ = part_num; - if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObPartNameIdPair) * part_num))) { - ret = OB_REACH_MEMORY_LIMIT; - LOG_WARN("part mgr reach memory limit", K(ret)); - } else if (OB_ISNULL(part_pair_array_ = new (tmp_buf) ObPartNameIdPair[part_num])) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(part_num), K(ret)); - } else if (!is_template_table && OB_ISNULL(sub_part_num_ = (int64_t *)allocator_.alloc(sizeof(int64_t) * part_num))) { - ret = OB_REACH_MEMORY_LIMIT; - LOG_WARN("part mgr reach memory limit", K(ret)); - } - for (int64_t i = 0; i < part_num && OB_SUCC(ret); ++i) { - if (OB_FAIL(rs_fetcher->next())) { - LOG_DEBUG("failed to get next rs_fetcher", K(ret)); - } else { - PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "part_id", part_id, int64_t); - PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(*rs_fetcher, "part_name", part_name); - part_pair_array_[i].set_part_id(part_id); - if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { - int64_t tablet_id = -1; - PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "tablet_id", tablet_id, int64_t); - part_pair_array_[i].set_tablet_id(tablet_id); - desc_key->tablet_id_array_[i] = tablet_id; - part_array[i] = part_id; - } - if (OB_FAIL(part_pair_array_[i].set_part_name(part_name))) { - LOG_WARN("fail to set part name", K(part_name), K(ret)); - } else if (!is_template_table) { - PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "sub_part_num", sub_part_num, int64_t); - sub_part_num_[i] = sub_part_num; + if (NULL != rs_fetcher) { + if (PARTITION_LEVEL_ONE == part_level) { + first_part_num_ = part_num; + if (!is_template_table && OB_ISNULL(sub_part_num_ = (int64_t *)allocator_.alloc(sizeof(int64_t) * part_num))) { + ret = OB_REACH_MEMORY_LIMIT; + LOG_WARN("part mgr reach memory limit", K(ret)); + } + for (int64_t i = 0; i < part_num && OB_SUCC(ret); ++i) { + if (OB_FAIL(rs_fetcher->next())) { + LOG_DEBUG("fail to get next rs_fetcher", K(ret)); + } else { + PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "part_id", part_id_buf[i], int64_t); + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(*rs_fetcher, "part_name", part_name); + + if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { + int64_t tablet_id = -1; + part_array[i] = part_id_buf[i]; + PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "tablet_id", tablet_id, int64_t); + desc_key->tablet_id_array_[i] = tablet_id; + if ((tablet_id != -1) && (tablet_id != 0)) { + part_id_buf[i] = tablet_id; + } + } + + if (part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[i], part_name.ptr(), part_name.length()); + name_len_buf[i] = part_name.length(); + all_first_part_name_length_ += part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[i] = 0; + } + + if (!is_template_table) { + PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "sub_part_num", sub_part_num, int64_t); + sub_part_num_[i] = sub_part_num; + } } + } // end for + if (OB_ITER_END == ret) { + LOG_DEBUG("empty first key part info, maybe ob version < 2.1", K(ret)); + ret = OB_SUCCESS; } - } // end for - if (OB_ITER_END == ret) { - LOG_DEBUG("empty first key part info, maybe ob version < 2.1", K(ret)); - ret = OB_SUCCESS; + } else if (PARTITION_LEVEL_TWO == part_level) { + for (int64_t i = 0; i < part_num && OB_SUCC(ret); ++i) {//part_num=sub part num + if (OB_FAIL(rs_fetcher->next())) { + LOG_DEBUG("fail to get next rs_fetcher", K(ret)); + } else { + PROXY_EXTRACT_INT_FIELD_MYSQL(*rs_fetcher, "sub_part_id", part_id_buf[i], int64_t); + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(*rs_fetcher, "part_name", part_name); + if (part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[i], part_name.ptr(), part_name.length()); + name_len_buf[i] = part_name.length(); + all_sub_part_name_length_ += part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[i] = 0; + } + } + } // end for + } else { + //nothing } - } // end NULL != rs_fetcher && PARTITION_LEVEL_ONE == part_level + } // end NULL != rs_fetcher } + if (OB_SUCC(ret)) { if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { desc_key->set_part_array(part_array); @@ -459,29 +620,50 @@ int ObProxyPartMgr::build_key_part(const ObPartitionLevel part_level, desc_key->set_part_num(part_num); desc_key->set_part_level(part_level); desc_key->set_part_func_type(part_func_type); - // find the first match key, should consider whether the key is both part one and part two? + for (int i = 0; i < part_col_num; i++) { + desc_key->get_accuracies().push_back(ObAccuracy()); + desc_key->get_obj_types().push_back(ObObjType()); + desc_key->get_cs_types().push_back(ObCollationType()); + } + // find all keys in this level for (int i = 0; i < key_info.key_num_; ++i) { if (static_cast(key_info.part_keys_[i].level_) == part_level) { - desc_key->set_part_key_type(static_cast(key_info.part_keys_[i].obj_type_)); - desc_key->set_part_key_cs_type(static_cast(key_info.part_keys_[i].cs_type_)); - desc_key->set_accuracy(key_info.part_keys_[i].accuracy_); - break; + ObAccuracy accuracy(key_info.part_keys_[i].accuracy_.valid_, + key_info.part_keys_[i].accuracy_.length_, + key_info.part_keys_[i].accuracy_.precision_, + key_info.part_keys_[i].accuracy_.scale_); + desc_key->get_accuracies().at(key_info.part_keys_[i].idx_in_part_columns_) = accuracy; + desc_key->get_obj_types().at(key_info.part_keys_[i].idx_in_part_columns_) = static_cast(key_info.part_keys_[i].obj_type_); + desc_key->get_cs_types().at(key_info.part_keys_[i].idx_in_part_columns_) = static_cast(key_info.part_keys_[i].cs_type_); } } if (PARTITION_LEVEL_ONE == part_level) { first_part_desc_ = desc_key; + if (OB_FAIL(init_first_part_map())) { + LOG_DEBUG("fail to create first part name id map", K(ret)); + } else if (OB_FAIL(build_part_name_id_map(name_buf, name_len_buf, part_id_buf, all_first_part_name_buf_, all_first_part_name_length_, part_num, first_part_name_id_map_))) { + LOG_DEBUG("fail to build first part name id map", K(ret)); + } } else if (PARTITION_LEVEL_TWO == part_level) { sub_part_desc_ = desc_key; + if (OB_FAIL(init_sub_part_map())) { + LOG_DEBUG("fail to create temp sub part name id map", K(ret)); + } else if (OB_FAIL(build_temp_sub_part_name_id_map(name_buf, name_len_buf, part_id_buf, part_num))) { + LOG_DEBUG("fail to build temp sub part name id map", K(ret)); + } } else { ret = OB_INVALID_ARGUMENT; LOG_WARN("part level invalid", K(part_level), K(ret)); } } + + free_name_buf(name_buf, name_len_buf, part_id_buf); return ret; } int ObProxyPartMgr::build_sub_key_part_with_non_template(const ObPartitionFuncType part_func_type, const int64_t part_space, + const int64_t part_col_num, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, const int64_t cluster_version) @@ -490,7 +672,12 @@ int ObProxyPartMgr::build_sub_key_part_with_non_template(const ObPartitionFuncTy void *tmp_buf = NULL; ObPartDescKey *desc_key = NULL; common::ObPartDesc *sub_part_desc = NULL; - int64_t part_id = -1; + PART_NAME_BUF *name_buf = NULL; + int64_t *name_len_buf = NULL; + int64_t *part_id_buf = NULL; + int64_t first_part_id = -1; + int64_t sub_part_id = -1; + ObString sub_part_name; // alloc desc_range if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObPartDescKey) * first_part_num_))) { @@ -498,9 +685,12 @@ int ObProxyPartMgr::build_sub_key_part_with_non_template(const ObPartitionFuncTy LOG_WARN("part mgr reach memory limit", K(ret)); } else if (OB_ISNULL(sub_part_desc = new (tmp_buf) ObPartDescKey[first_part_num_])) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(ret)); + LOG_WARN("fail to do placement new", K(tmp_buf), K(ret)); + } else if (OB_FAIL(alloc_name_buf(name_buf, name_len_buf, part_id_buf, all_sub_part_num_))) { + LOG_WARN("fail to alloc name buf", K(ret)); } + int64_t index=0; for (int64_t i = 0; i < first_part_num_ && OB_SUCC(ret); ++i) { desc_key = (((ObPartDescKey *)sub_part_desc) + i); if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) && OB_ISNULL(desc_key->tablet_id_array_ = (int64_t*)allocator_.alloc(sizeof(int64_t) * sub_part_num_[i]))) { @@ -509,29 +699,52 @@ int ObProxyPartMgr::build_sub_key_part_with_non_template(const ObPartitionFuncTy } for (int64_t j = 0; j < sub_part_num_[i] && OB_SUCC(ret); ++j) { - if (OB_FAIL(rs_fetcher.next())) { - LOG_WARN("failed to get next rs_fetcher", K(ret)); + if (OB_FAIL(rs_fetcher.next()) || index >= all_sub_part_num_) { + LOG_WARN("fail to get next rs_fetcher", K(ret)); } else { - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_id", part_id, int64_t); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_id", first_part_id, int64_t); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sub_part_id", sub_part_id, int64_t); + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_name", sub_part_name); if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "tablet_id", desc_key->tablet_id_array_[j], int64_t); } + if (sub_part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[index], sub_part_name.ptr(), sub_part_name.length()); + name_len_buf[index] = sub_part_name.length(); + if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { + part_id_buf[index] = desc_key->tablet_id_array_[j]; + } else { + part_id_buf[index] = generate_phy_part_id(first_part_id, sub_part_id); + } + all_sub_part_name_length_ += sub_part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[index] = 0; + } + ++index; } } if (OB_SUCC(ret)) { - desc_key->set_first_part_id(part_id); + desc_key->set_first_part_id(first_part_id); desc_key->set_part_space(part_space); desc_key->set_part_num(sub_part_num_[i]); desc_key->set_part_level(PARTITION_LEVEL_TWO); desc_key->set_part_func_type(part_func_type); - // find the first match key, should consider whether the key is both part one and part two? + for (int i = 0; i < part_col_num; i++) { + desc_key->get_accuracies().push_back(ObAccuracy()); + desc_key->get_obj_types().push_back(ObObjType()); + desc_key->get_cs_types().push_back(ObCollationType()); + } + // find all keys in this level for (int i = 0; i < key_info.key_num_; ++i) { if (static_cast(key_info.part_keys_[i].level_) == PARTITION_LEVEL_TWO) { - desc_key->set_part_key_type(static_cast(key_info.part_keys_[i].obj_type_)); - desc_key->set_part_key_cs_type(static_cast(key_info.part_keys_[i].cs_type_)); - desc_key->set_accuracy(key_info.part_keys_[i].accuracy_); - break; + ObAccuracy accuracy(key_info.part_keys_[i].accuracy_.valid_, + key_info.part_keys_[i].accuracy_.length_, + key_info.part_keys_[i].accuracy_.precision_, + key_info.part_keys_[i].accuracy_.scale_); + desc_key->get_accuracies().at(key_info.part_keys_[i].idx_in_part_columns_) = accuracy; + desc_key->get_obj_types().at(key_info.part_keys_[i].idx_in_part_columns_) = static_cast(key_info.part_keys_[i].obj_type_); + desc_key->get_cs_types().at(key_info.part_keys_[i].idx_in_part_columns_) = static_cast(key_info.part_keys_[i].cs_type_); } } } @@ -539,14 +752,21 @@ int ObProxyPartMgr::build_sub_key_part_with_non_template(const ObPartitionFuncTy if (OB_SUCC(ret)) { sub_part_desc_ = sub_part_desc; + if (OB_FAIL(init_sub_part_map())) { + LOG_DEBUG("fail to create non temp sub part name id map", K(ret)); + } else if (OB_FAIL(build_part_name_id_map(name_buf, name_len_buf, part_id_buf, all_sub_part_name_buf_, all_sub_part_name_length_, all_sub_part_num_, sub_part_name_id_map_))) { + LOG_DEBUG("fail to build non temp sub part name id map", K(ret)); + } } + free_name_buf(name_buf, name_len_buf, part_id_buf); return ret; } int ObProxyPartMgr::build_range_part(const ObPartitionLevel part_level, const ObPartitionFuncType part_func_type, const int64_t part_num, + const int64_t part_col_num, const bool is_template_table, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, @@ -556,8 +776,11 @@ int ObProxyPartMgr::build_range_part(const ObPartitionLevel part_level, void *tmp_buf = NULL; ObPartDescRange *desc_range = NULL; RangePartition *part_array = NULL; - ObString part_name; + PART_NAME_BUF *name_buf = NULL; + int64_t *name_len_buf = NULL; + int64_t *part_id_buf = NULL; int64_t sub_part_num = 0; + ObString part_name; if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) && PARTITION_LEVEL_TWO == part_level) { ret = OB_ERR_UNEXPECTED; @@ -568,7 +791,7 @@ int ObProxyPartMgr::build_range_part(const ObPartitionLevel part_level, LOG_WARN("part mgr reach memory limit", K(ret)); } else if (OB_ISNULL(desc_range = new (tmp_buf) ObPartDescRange())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(ret)); + LOG_WARN("fail to do placement new", K(tmp_buf), K(ret)); } else if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) && OB_ISNULL(desc_range->tablet_id_array_ = (int64_t*)allocator_.alloc(sizeof(int64_t) * part_num))) { ret = OB_REACH_MEMORY_LIMIT; LOG_WARN("part mgr reach memory limit", K(ret)); @@ -577,17 +800,13 @@ int ObProxyPartMgr::build_range_part(const ObPartitionLevel part_level, LOG_WARN("part mgr reach memory limit", K(ret)); } else if (OB_ISNULL(part_array = new (tmp_buf) RangePartition[part_num])) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(part_num), K(ret)); + LOG_WARN("fail to do placement new", K(tmp_buf), K(part_num), K(ret)); + } else if (OB_FAIL(alloc_name_buf(name_buf, name_len_buf, part_id_buf, part_num))) { + LOG_WARN("fail to alloc name buf", K(ret)); } else { if (PARTITION_LEVEL_ONE == part_level) { first_part_num_ = part_num; - if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObPartNameIdPair) * part_num))) { - ret = OB_REACH_MEMORY_LIMIT; - LOG_WARN("part mgr reach memory limit", K(ret)); - } else if (OB_ISNULL(part_pair_array_ = new (tmp_buf) ObPartNameIdPair[part_num])) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(part_num), K(ret)); - } else if (!is_template_table && OB_ISNULL(sub_part_num_ = (int64_t *)allocator_.alloc(sizeof(int64_t) * part_num))) { + if (!is_template_table && OB_ISNULL(sub_part_num_ = (int64_t *)allocator_.alloc(sizeof(int64_t) * part_num))) { ret = OB_REACH_MEMORY_LIMIT; LOG_WARN("part mgr reach memory limit", K(ret)); } @@ -599,27 +818,42 @@ int ObProxyPartMgr::build_range_part(const ObPartitionLevel part_level, int64_t pos = 0; for (int64_t i = 0; i < part_num && OB_SUCC(ret); ++i) { if (OB_FAIL(rs_fetcher.next())) { - LOG_WARN("failed to get next rs_fetcher", K(ret)); + LOG_WARN("fail to get next rs_fetcher", K(ret)); } else { if (PARTITION_LEVEL_ONE == part_level) { PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_id", part_array[i].part_id_, int64_t); + part_id_buf[i] = part_array[i].part_id_; if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { int64_t tablet_id = -1; PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "tablet_id", tablet_id, int64_t); - part_pair_array_[i].tablet_id_ = tablet_id; desc_range->tablet_id_array_[i] = tablet_id; + if ((tablet_id != -1) && (tablet_id != 0)) { + part_id_buf[i] = tablet_id; + } } PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_name", part_name); - - part_pair_array_[i].set_part_id(part_array[i].part_id_); - if (OB_FAIL(part_pair_array_[i].set_part_name(part_name))) { - LOG_WARN("fail to set part name", K(part_name), K(ret)); - } else if (!is_template_table) { + if (part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[i], part_name.ptr(), part_name.length()); + name_len_buf[i] = part_name.length(); + all_first_part_name_length_ += part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[i] = 0; + } + if (!is_template_table) { PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sub_part_num", sub_part_num, int64_t); sub_part_num_[i] = sub_part_num; } } else if (PARTITION_LEVEL_TWO == part_level) { - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sub_part_id", part_array[i].part_id_, int64_t); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sub_part_id", part_array[i].part_id_, int64_t);//sub_part_id + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_name", part_name); + part_id_buf[i] = part_array[i].part_id_; + if (part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[i], part_name.ptr(), part_name.length()); + name_len_buf[i] = part_name.length(); + all_sub_part_name_length_ += part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[i] = 0; + } } else { ret = OB_INVALID_ARGUMENT; } @@ -627,10 +861,10 @@ int ObProxyPartMgr::build_range_part(const ObPartitionLevel part_level, pos = 0; if (OB_FAIL(ret)) { - LOG_WARN("failed to fetch result", K(ret)); + LOG_WARN("fail to fetch result", K(ret)); } else if (OB_FAIL(part_array[i].high_bound_val_.deserialize(allocator_, tmp_str.ptr(), tmp_str.length(), pos))) { - LOG_WARN("failed to deserialize", K(tmp_str), K(ret)); + LOG_WARN("fail to deserialize", K(tmp_str), K(ret)); } else { // do nothing } @@ -641,7 +875,7 @@ int ObProxyPartMgr::build_range_part(const ObPartitionLevel part_level, if (OB_SUCC(ret)) { if (OB_FAIL(desc_range->set_part_array(part_array, part_num))) { - LOG_WARN("failed to set_part_array, unexpected ", K(ret)); + LOG_WARN("fail to set_part_array, unexpected ", K(ret)); } } @@ -649,25 +883,45 @@ int ObProxyPartMgr::build_range_part(const ObPartitionLevel part_level, if (OB_SUCC(ret)) { desc_range->set_part_level(part_level); desc_range->set_part_func_type(part_func_type); - for (int k = 0; k < key_info.key_num_; ++k) { - if (static_cast(key_info.part_keys_[k].level_) == part_level) { - desc_range->set_accuracy(key_info.part_keys_[k].accuracy_); - break; + for (int i = 0; i < part_col_num; i++) { + desc_range->get_accuracies().push_back(ObAccuracy()); + } + // find all keys in this level + for (int i = 0; i < key_info.key_num_; ++i) { + if (static_cast(key_info.part_keys_[i].level_) == part_level) { + ObAccuracy accuracy(key_info.part_keys_[i].accuracy_.valid_, + key_info.part_keys_[i].accuracy_.length_, + key_info.part_keys_[i].accuracy_.precision_, + key_info.part_keys_[i].accuracy_.scale_); + desc_range->get_accuracies().at(key_info.part_keys_[i].idx_in_part_columns_) = accuracy; } } if (PARTITION_LEVEL_ONE == part_level) { first_part_desc_ = desc_range; + if (OB_FAIL(init_first_part_map())) { + LOG_DEBUG("fail to create first part name id map", K(ret)); + } else if (OB_FAIL(build_part_name_id_map(name_buf, name_len_buf, part_id_buf, all_first_part_name_buf_, all_first_part_name_length_, part_num, first_part_name_id_map_))) { + LOG_DEBUG("fail to build first part name id map", K(ret)); + } } else if (PARTITION_LEVEL_TWO == part_level) { sub_part_desc_ = desc_range; + if (OB_FAIL(init_sub_part_map())) { + LOG_DEBUG("fail to create temp sub part name id map", K(ret)); + } else if (OB_FAIL(build_temp_sub_part_name_id_map(name_buf, name_len_buf, part_id_buf, part_num))) { + LOG_DEBUG("fail to build temp sub part name id map", K(ret)); + } } else { ret = OB_INVALID_ARGUMENT; LOG_WARN("part level invalid", K(part_level), K(ret)); } } + + free_name_buf(name_buf, name_len_buf, part_id_buf); return ret; } int ObProxyPartMgr::build_sub_range_part_with_non_template(const ObPartitionFuncType part_func_type, + const int64_t part_col_num, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, const int64_t cluster_version) @@ -676,6 +930,10 @@ int ObProxyPartMgr::build_sub_range_part_with_non_template(const ObPartitionFunc void *tmp_buf = NULL; RangePartition *part_array = NULL; common::ObPartDesc *sub_part_desc = NULL; + PART_NAME_BUF *name_buf = NULL; + int64_t *name_len_buf = NULL; + int64_t *part_id_buf = NULL; + ObString sub_part_name; // alloc desc_range if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObPartDescRange) * first_part_num_))) { @@ -683,11 +941,13 @@ int ObProxyPartMgr::build_sub_range_part_with_non_template(const ObPartitionFunc LOG_WARN("part mgr reach memory limit", K(ret)); } else if (OB_ISNULL(sub_part_desc = new (tmp_buf) ObPartDescRange[first_part_num_])) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(ret)); + LOG_WARN("fail to do placement new", K(tmp_buf), K(ret)); + } else if (OB_FAIL(alloc_name_buf(name_buf, name_len_buf, part_id_buf, all_sub_part_num_))) { + LOG_WARN("fail to alloc name buf", K(ret)); } - // build desc_range ObString tmp_str; + int64_t index = 0; int64_t pos = 0; ObPartDescRange *desc_range = NULL; for (int64_t i = 0; i < first_part_num_ && OB_SUCC(ret); ++i) { @@ -698,7 +958,7 @@ int ObProxyPartMgr::build_sub_range_part_with_non_template(const ObPartitionFunc LOG_WARN("part mgr reach memory limit", K(ret)); } else if (OB_ISNULL(part_array = new (tmp_buf) RangePartition[sub_part_num_[i]])) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), "sub_part_index", i, + LOG_WARN("fail to do placement new", K(tmp_buf), "sub_part_index", i, "sub_part_num", sub_part_num_[i], K(ret)); } else if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) && OB_ISNULL(desc_range->tablet_id_array_ = (int64_t*)allocator_.alloc(sizeof(int64_t) * sub_part_num_[i]))) { ret = OB_REACH_MEMORY_LIMIT; @@ -706,22 +966,37 @@ int ObProxyPartMgr::build_sub_range_part_with_non_template(const ObPartitionFunc } for (int64_t j = 0; j < sub_part_num_[i] && OB_SUCC(ret); ++j) { - if (OB_FAIL(rs_fetcher.next())) { - LOG_WARN("failed to get next rs_fetcher", K(ret)); + if (OB_FAIL(rs_fetcher.next()) || index >= all_sub_part_num_) { + LOG_WARN("fail to get next rs_fetcher", K(ret)); } else { PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_id", part_array[j].first_part_id_, int64_t); PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sub_part_id", part_array[j].part_id_, int64_t); PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "high_bound_val_bin", tmp_str); + if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "tablet_id", desc_range->tablet_id_array_[j], int64_t); } + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_name", sub_part_name); + if (sub_part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[index], sub_part_name.ptr(), sub_part_name.length()); + name_len_buf[index] = sub_part_name.length(); + if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { + part_id_buf[index] = desc_range->tablet_id_array_[j]; + } else { + part_id_buf[index] = generate_phy_part_id(part_array[j].first_part_id_, part_array[j].part_id_); + } + all_sub_part_name_length_ += sub_part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[index] = 0; + } + ++index; pos = 0; if (OB_FAIL(ret)) { - LOG_WARN("failed to fetch result", K(ret)); + LOG_WARN("fail to fetch result", K(ret)); } else if (OB_FAIL(part_array[j].high_bound_val_.deserialize(allocator_, tmp_str.ptr(), tmp_str.length(), pos))) { - LOG_WARN("failed to deserialize", K(tmp_str), K(ret)); + LOG_WARN("fail to deserialize", K(tmp_str), K(ret)); } else { // do nothing } @@ -731,28 +1006,42 @@ int ObProxyPartMgr::build_sub_range_part_with_non_template(const ObPartitionFunc if (OB_SUCC(ret)) { desc_range->set_part_level(PARTITION_LEVEL_TWO); desc_range->set_part_func_type(part_func_type); - for (int k = 0; k < key_info.key_num_; ++k) { - if (static_cast(key_info.part_keys_[k].level_) == PARTITION_LEVEL_TWO) { - desc_range->set_accuracy(key_info.part_keys_[k].accuracy_); - break; + for (int i = 0; i < part_col_num; i++) { + desc_range->get_accuracies().push_back(ObAccuracy()); + } + // find all keys in this level + for (int i = 0; i < key_info.key_num_; ++i) { + if (static_cast(key_info.part_keys_[i].level_) == PARTITION_LEVEL_TWO) { + ObAccuracy accuracy(key_info.part_keys_[i].accuracy_.valid_, + key_info.part_keys_[i].accuracy_.length_, + key_info.part_keys_[i].accuracy_.precision_, + key_info.part_keys_[i].accuracy_.scale_); + desc_range->get_accuracies().at(key_info.part_keys_[i].idx_in_part_columns_) = accuracy; } } if (OB_FAIL(desc_range->set_part_array(part_array, sub_part_num_[i]))) { - LOG_WARN("failed to set_part_array, unexpected ", K(ret)); + LOG_WARN("fail to set_part_array, unexpected ", K(ret)); } } } // end of for if (OB_SUCC(ret)) { sub_part_desc_ = sub_part_desc; + if (OB_FAIL(init_sub_part_map())) { + LOG_DEBUG("fail to create non temp sub part name id map", K(ret)); + } else if (OB_FAIL(build_part_name_id_map(name_buf, name_len_buf, part_id_buf, all_sub_part_name_buf_, all_sub_part_name_length_, all_sub_part_num_, sub_part_name_id_map_))) { + LOG_DEBUG("fail to build non temp sub part name id map", K(ret)); + } } + free_name_buf(name_buf, name_len_buf, part_id_buf); return ret; } int ObProxyPartMgr::build_list_part(const ObPartitionLevel part_level, const ObPartitionFuncType part_func_type, const int64_t part_num, + const int64_t part_col_num, const bool is_template_table, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, @@ -762,8 +1051,11 @@ int ObProxyPartMgr::build_list_part(const ObPartitionLevel part_level, void *tmp_buf = NULL; ObPartDescList *desc_list = NULL; ListPartition *part_array = NULL; - ObString part_name; + PART_NAME_BUF *name_buf = NULL; + int64_t *name_len_buf = NULL; + int64_t *part_id_buf = NULL; int64_t sub_part_num = 0; + ObString part_name; if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) && PARTITION_LEVEL_TWO == part_level) { ret = OB_ERR_UNEXPECTED; @@ -774,7 +1066,7 @@ int ObProxyPartMgr::build_list_part(const ObPartitionLevel part_level, LOG_WARN("part mgr reach memory limit", K(ret)); } else if (OB_ISNULL(desc_list = new (tmp_buf) ObPartDescList())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(ret)); + LOG_WARN("fail to do placement new", K(tmp_buf), K(ret)); } else if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) && OB_ISNULL(desc_list->tablet_id_array_ = (int64_t*)allocator_.alloc(sizeof(int64_t) * part_num))) { ret = OB_REACH_MEMORY_LIMIT; LOG_WARN("part mgr reach memory limit, alloc tablet id array failed", K(ret)); @@ -783,17 +1075,13 @@ int ObProxyPartMgr::build_list_part(const ObPartitionLevel part_level, LOG_WARN("part mgr reach memory limit", K(ret)); } else if (OB_ISNULL(part_array = new (tmp_buf) ListPartition[part_num])) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(part_num), K(ret)); + LOG_WARN("fail to do placement new", K(tmp_buf), K(part_num), K(ret)); + } else if (OB_FAIL(alloc_name_buf(name_buf, name_len_buf, part_id_buf, part_num))) { + LOG_WARN("fail to alloc name buf", K(ret)); } else { if (PARTITION_LEVEL_ONE == part_level) { first_part_num_ = part_num; - if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObPartNameIdPair) * part_num))) { - ret = OB_REACH_MEMORY_LIMIT; - LOG_WARN("part mgr reach memory limit", K(ret)); - } else if (OB_ISNULL(part_pair_array_ = new (tmp_buf) ObPartNameIdPair[part_num])) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(part_num), K(ret)); - } else if (!is_template_table && OB_ISNULL(sub_part_num_ = (int64_t *)allocator_.alloc(sizeof(int64_t) * part_num))) { + if (!is_template_table && OB_ISNULL(sub_part_num_ = (int64_t *)allocator_.alloc(sizeof(int64_t) * part_num))) { ret = OB_REACH_MEMORY_LIMIT; LOG_WARN("part mgr reach memory limit", K(ret)); } @@ -806,29 +1094,44 @@ int ObProxyPartMgr::build_list_part(const ObPartitionLevel part_level, ObNewRow row; ObNewRow tmp_row; ObObj obj_array[OB_USER_ROW_MAX_COLUMNS_COUNT]; - row.assign(obj_array, OB_USER_ROW_MAX_COLUMNS_COUNT); for (int64_t i = 0; i < part_num && OB_SUCC(ret); ++i) { if (OB_FAIL(rs_fetcher.next())) { - LOG_WARN("failed to get next rs_fetcher", K(ret)); + LOG_WARN("fail to get next rs_fetcher", K(ret)); } else { if (PARTITION_LEVEL_ONE == part_level) { PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_id", part_array[i].part_id_, int64_t); - PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_name", part_name); + part_id_buf[i] = part_array[i].part_id_; if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { int64_t tablet_id = -1; PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "tablet_id", tablet_id, int64_t); - part_pair_array_[i].tablet_id_ = tablet_id; desc_list->tablet_id_array_[i] = tablet_id; + if ((tablet_id != -1) && (tablet_id != 0)) { + part_id_buf[i] = tablet_id; + } } - part_pair_array_[i].set_part_id(part_array[i].part_id_); - if (OB_FAIL(part_pair_array_[i].set_part_name(part_name))) { - LOG_WARN("fail to set part name", K(part_name), K(ret)); - } else if (!is_template_table) { + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_name", part_name); + if (part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[i], part_name.ptr(), part_name.length()); + name_len_buf[i] = part_name.length(); + all_first_part_name_length_ += part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[i] = 0; + } + if (!is_template_table) { PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sub_part_num", sub_part_num, int64_t); sub_part_num_[i] = sub_part_num; } } else if (PARTITION_LEVEL_TWO == part_level) { - PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sub_part_id", part_array[i].part_id_, int64_t); + PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sub_part_id", part_array[i].part_id_, int64_t);//sub_part_id + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_name", part_name); + part_id_buf[i] = part_array[i].part_id_; + if (part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[i], part_name.ptr(), part_name.length()); + name_len_buf[i] = part_name.length(); + all_sub_part_name_length_ += part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[i] = 0; + } } else { ret = OB_INVALID_ARGUMENT; } @@ -839,6 +1142,7 @@ int ObProxyPartMgr::build_list_part(const ObPartitionLevel part_level, } else { // deserialize ob rows array while (OB_SUCC(ret) && pos < tmp_str.length()) { + row.assign(obj_array, OB_USER_ROW_MAX_COLUMNS_COUNT); if (OB_FAIL(row.deserialize(tmp_str.ptr(), tmp_str.length(), pos))) { LOG_WARN("fail to deserialize ob row", K(tmp_str), K(ret)); } else if (OB_FAIL(ob_write_row(allocator_, row, tmp_row))) { @@ -858,7 +1162,7 @@ int ObProxyPartMgr::build_list_part(const ObPartitionLevel part_level, if (OB_SUCC(ret)) { if (OB_FAIL(desc_list->set_part_array(part_array, part_num))) { - LOG_WARN("failed to set_part_array, unexpected ", K(ret)); + LOG_WARN("fail to set_part_array, unexpected ", K(ret)); } } @@ -866,25 +1170,45 @@ int ObProxyPartMgr::build_list_part(const ObPartitionLevel part_level, if (OB_SUCC(ret)) { desc_list->set_part_level(part_level); desc_list->set_part_func_type(part_func_type); - for (int k = 0; k < key_info.key_num_; ++k) { - if (static_cast(key_info.part_keys_[k].level_) == part_level) { - desc_list->set_accuracy(key_info.part_keys_[k].accuracy_); - break; + for (int i = 0; i < part_col_num; i++) { + desc_list->get_accuracies().push_back(ObAccuracy()); + } + // find all keys in this level + for (int i = 0; i < key_info.key_num_; ++i) { + if (static_cast(key_info.part_keys_[i].level_) == part_level) { + ObAccuracy accuracy(key_info.part_keys_[i].accuracy_.valid_, + key_info.part_keys_[i].accuracy_.length_, + key_info.part_keys_[i].accuracy_.precision_, + key_info.part_keys_[i].accuracy_.scale_); + desc_list->get_accuracies().at(key_info.part_keys_[i].idx_in_part_columns_) = accuracy; } } if (PARTITION_LEVEL_ONE == part_level) { first_part_desc_ = desc_list; + if (OB_FAIL(init_first_part_map())) { + LOG_DEBUG("fail to create first part name id map", K(ret)); + } else if (OB_FAIL(build_part_name_id_map(name_buf, name_len_buf, part_id_buf, all_first_part_name_buf_, all_first_part_name_length_, part_num, first_part_name_id_map_))) { + LOG_DEBUG("fail to build first part name id map", K(ret)); + } } else if (PARTITION_LEVEL_TWO == part_level) { sub_part_desc_ = desc_list; + if (OB_FAIL(init_sub_part_map())) { + LOG_DEBUG("fail to create temp sub part name id map", K(ret)); + } else if (OB_FAIL(build_temp_sub_part_name_id_map(name_buf, name_len_buf, part_id_buf, part_num))) { + LOG_DEBUG("fail to build temp sub part name id map", K(ret)); + } } else { ret = OB_INVALID_ARGUMENT; LOG_WARN("part level invalid", K(part_level), K(ret)); } } + + free_name_buf(name_buf, name_len_buf, part_id_buf); return ret; } int ObProxyPartMgr::build_sub_list_part_with_non_template(const ObPartitionFuncType part_func_type, + const int64_t part_col_num, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, const int64_t cluster_version) @@ -893,23 +1217,28 @@ int ObProxyPartMgr::build_sub_list_part_with_non_template(const ObPartitionFuncT void *tmp_buf = NULL; ListPartition *part_array = NULL; common::ObPartDesc *sub_part_desc = NULL; - + PART_NAME_BUF *name_buf = NULL; + int64_t *name_len_buf = NULL; + int64_t *part_id_buf = NULL; + ObString sub_part_name; + // alloc desc_range if (OB_ISNULL(tmp_buf = allocator_.alloc(sizeof(ObPartDescList) * first_part_num_))) { ret = OB_REACH_MEMORY_LIMIT; LOG_WARN("part mgr reach memory limit", K(ret)); } else if (OB_ISNULL(sub_part_desc = new (tmp_buf) ObPartDescList[first_part_num_])) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), K(ret)); + LOG_WARN("fail to do placement new", K(tmp_buf), K(ret)); + } else if (OB_FAIL(alloc_name_buf(name_buf, name_len_buf, part_id_buf, all_sub_part_num_))) { + LOG_WARN("fail to alloc name buf", K(ret)); } - // build desc_list ObString tmp_str; + int64_t index = 0; int64_t pos = 0; ObNewRow row; ObNewRow tmp_row; ObObj obj_array[OB_USER_ROW_MAX_COLUMNS_COUNT]; - row.assign(obj_array, OB_USER_ROW_MAX_COLUMNS_COUNT); ObPartDescList *desc_list = NULL; for (int64_t i = 0; i < first_part_num_ && OB_SUCC(ret); ++i) { tmp_buf = NULL; @@ -919,7 +1248,7 @@ int ObProxyPartMgr::build_sub_list_part_with_non_template(const ObPartitionFuncT LOG_WARN("part mgr reach memory limit", K(ret)); } else if (OB_ISNULL(part_array = new (tmp_buf) ListPartition[sub_part_num_[i]])) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed to do placement new", K(tmp_buf), "sub_part_index", i, + LOG_WARN("fail to do placement new", K(tmp_buf), "sub_part_index", i, "sub_part_num", sub_part_num_[i], K(ret)); } else if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) && OB_ISNULL(desc_list->tablet_id_array_ = (int64_t*)allocator_.alloc(sizeof(int64_t) * sub_part_num_[i]))) { ret = OB_REACH_MEMORY_LIMIT; @@ -927,22 +1256,38 @@ int ObProxyPartMgr::build_sub_list_part_with_non_template(const ObPartitionFuncT } for (int64_t j = 0; j < sub_part_num_[i] && OB_SUCC(ret); ++j) { - if (OB_FAIL(rs_fetcher.next())) { - LOG_WARN("failed to get next rs_fetcher", K(ret)); + if (OB_FAIL(rs_fetcher.next()) || index >= all_sub_part_num_) { + LOG_WARN("fail to get next rs_fetcher", K(ret)); } else { PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "part_id", part_array[j].first_part_id_, int64_t); PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "sub_part_id", part_array[j].part_id_, int64_t); PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "high_bound_val_bin", tmp_str); + if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { PROXY_EXTRACT_INT_FIELD_MYSQL(rs_fetcher, "tablet_id", desc_list->tablet_id_array_[j], int64_t); } + PROXY_EXTRACT_VARCHAR_FIELD_MYSQL(rs_fetcher, "part_name", sub_part_name); + if (sub_part_name.length() <= MAX_PART_NAME_LENGTH) { + MEMCPY(name_buf[index], sub_part_name.ptr(), sub_part_name.length()); + name_len_buf[index] = sub_part_name.length(); + if (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version)) { + part_id_buf[index] = desc_list->tablet_id_array_[j]; + } else { + part_id_buf[index] = generate_phy_part_id(part_array[j].first_part_id_, part_array[j].part_id_); + } + all_sub_part_name_length_ += sub_part_name.length(); + } else {//treat too long name string as empty string + name_len_buf[index] = 0; + } + ++index; pos = 0; if (OB_FAIL(ret)) { LOG_WARN("fail to fetch result", K(ret)); } else { // deserialize ob rows array while (OB_SUCC(ret) && pos < tmp_str.length()) { + row.assign(obj_array, OB_USER_ROW_MAX_COLUMNS_COUNT); if (OB_FAIL(row.deserialize(tmp_str.ptr(), tmp_str.length(), pos))) { LOG_WARN("fail to deserialize ob row", K(tmp_str), K(ret)); } else if (OB_FAIL(ob_write_row(allocator_, row, tmp_row))) { @@ -963,22 +1308,35 @@ int ObProxyPartMgr::build_sub_list_part_with_non_template(const ObPartitionFuncT if (OB_SUCC(ret)) { desc_list->set_part_level(PARTITION_LEVEL_TWO); desc_list->set_part_func_type(part_func_type); - for (int k = 0; k < key_info.key_num_; ++k) { - if (static_cast(key_info.part_keys_[k].level_) == PARTITION_LEVEL_TWO) { - desc_list->set_accuracy(key_info.part_keys_[k].accuracy_); - break; + for (int i = 0; i < part_col_num; i++) { + desc_list->get_accuracies().push_back(ObAccuracy()); + } + // find all keys in this level + for (int i = 0; i < key_info.key_num_; ++i) { + if (static_cast(key_info.part_keys_[i].level_) == PARTITION_LEVEL_TWO) { + ObAccuracy accuracy(key_info.part_keys_[i].accuracy_.valid_, + key_info.part_keys_[i].accuracy_.length_, + key_info.part_keys_[i].accuracy_.precision_, + key_info.part_keys_[i].accuracy_.scale_); + desc_list->get_accuracies().at(key_info.part_keys_[i].idx_in_part_columns_) = accuracy; } } if (OB_FAIL(desc_list->set_part_array(part_array, sub_part_num_[i]))) { - LOG_WARN("failed to set_part_array, unexpected ", K(ret)); + LOG_WARN("fail to set_part_array, unexpected ", K(ret)); } } } // end of for if (OB_SUCC(ret)) { sub_part_desc_ = sub_part_desc; + if (OB_FAIL(init_sub_part_map())) { + LOG_DEBUG("fail to create non temp sub part name id map", K(ret)); + } else if (OB_FAIL(build_part_name_id_map(name_buf, name_len_buf, part_id_buf, all_sub_part_name_buf_, all_sub_part_name_length_, all_sub_part_num_, sub_part_name_id_map_))) { + LOG_DEBUG("fail to build non temp sub part name id map", K(ret)); + } } + free_name_buf(name_buf, name_len_buf, part_id_buf); return ret; } @@ -1057,6 +1415,112 @@ int ObProxyPartMgr::get_sub_part_num_by_first_part_id(ObProxyPartInfo &part_info return ret; } +int ObProxyPartMgr::build_part_name_id_map(const PART_NAME_BUF * const name_buf, + const int64_t * const name_len_buf, + const int64_t * const part_id_buf, + char * target_part_name_buf, + const int64_t total_part_name_len, + const int64_t part_num, + PartNameIdMap& part_name_id_map) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(name_buf) || OB_ISNULL(name_len_buf) || OB_ISNULL(part_id_buf)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("fail to get part name buf", K(ret)); + } else if (OB_NOT_NULL(target_part_name_buf)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("part name buf is alloc twice", K(ret)); + } else if (OB_ISNULL(target_part_name_buf = (char *)allocator_.alloc(total_part_name_len))) { + ret = OB_REACH_MEMORY_LIMIT; + LOG_WARN("part mgr reach memory limit when alloc all first part name buf", K(ret)); + } else { + ObString part_name; + int64_t pos = 0; + for (int64_t i = 0; OB_SUCC(ret) && i < part_num; ++i) { + if (OB_LIKELY( 0 != name_len_buf[i])) { + part_name.assign_ptr(target_part_name_buf + pos, static_cast(name_len_buf[i])); + MEMCPY(target_part_name_buf + pos, name_buf[i], name_len_buf[i]); + string_to_upper_case(part_name.ptr(), part_name.length()); + part_name_id_map.set_refactored(part_name, part_id_buf[i]); + pos += name_len_buf[i]; + } + } + } + return ret; +} + +int ObProxyPartMgr::build_temp_sub_part_name_id_map(const PART_NAME_BUF * const name_buf, + const int64_t * const name_len_buf, + const int64_t * const part_id_buf, + const int64_t part_num) +{ + int ret = OB_SUCCESS; + all_sub_part_name_length_ = (all_first_part_name_length_ * part_num) //total length of first-part-name + + (all_sub_part_name_length_ * first_part_num_) //total length of sub-part-name + + (part_num * first_part_num_); //total length of 's' + if (OB_ISNULL(name_buf) || OB_ISNULL(name_len_buf) || OB_ISNULL(part_id_buf)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("fail to get part name buf", K(ret)); + } else if (OB_ISNULL(all_sub_part_name_buf_ = (char *)allocator_.alloc(sizeof(char) * all_sub_part_name_length_))) { + ret = OB_REACH_MEMORY_LIMIT; + LOG_WARN("part mgr reach memory limit when alloc all first part name buf", K(ret)); + } else { + ObString part_name; + int64_t pos = 0; + int64_t tmp_len = 0; + PartNameIdMap::const_iterator iter = first_part_name_id_map_.begin(); + PartNameIdMap::const_iterator end = first_part_name_id_map_.end(); + for (; OB_SUCC(ret) && iter !=end; iter++) { + for (int64_t i = 0; OB_SUCC(ret) && i < part_num; ++i) { + if (OB_LIKELY(0 != name_len_buf[i])) { + tmp_len = iter->first.length() + 1 + name_len_buf[i];//first part name + 's' + sub part name + if (OB_LIKELY(tmp_len <= MAX_PART_NAME_LENGTH)) { + part_name.assign_ptr(all_sub_part_name_buf_ + pos, static_cast(tmp_len)); + MEMCPY(all_sub_part_name_buf_ + pos, iter->first.ptr(), iter->first.length()); + pos += iter->first.length(); + all_sub_part_name_buf_[pos++] = 'S'; + MEMCPY(all_sub_part_name_buf_ + pos, name_buf[i], name_len_buf[i]); + pos += name_len_buf[i]; + string_to_upper_case(part_name.ptr(), part_name.length()); + sub_part_name_id_map_.set_refactored(part_name, generate_phy_part_id(iter->second, part_id_buf[i])); + } + } + } + } + } + return ret; +} + +int ObProxyPartMgr::alloc_name_buf(PART_NAME_BUF *&name_buf, int64_t *&name_len_buf, int64_t *&part_id_buf, const int64_t part_num) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(name_buf = (PART_NAME_BUF *)allocator_.alloc(sizeof(PART_NAME_BUF) * part_num))) { + ret = OB_REACH_MEMORY_LIMIT; + LOG_WARN("part mgr reach memory limit when alloc name buf", K(ret)); + } else if (OB_ISNULL(name_len_buf = (int64_t *)allocator_.alloc(sizeof(int64_t) * part_num))) { + ret = OB_REACH_MEMORY_LIMIT; + LOG_WARN("part mgr reach memory limit when alloc name len buf", K(ret)); + } else if (OB_ISNULL(part_id_buf = (int64_t *)allocator_.alloc(sizeof(int64_t) * part_num))) { + ret = OB_REACH_MEMORY_LIMIT; + LOG_WARN("part mgr reach memory limit when alloc part id buf", K(ret)); + } + + return ret; +} + +void ObProxyPartMgr::free_name_buf(PART_NAME_BUF *name_buf, int64_t *name_len_buf, int64_t *part_id_buf) +{ + if (OB_NOT_NULL(part_id_buf)) { + allocator_.free(part_id_buf); + } + if (OB_NOT_NULL(name_len_buf)) { + allocator_.free(name_len_buf); + } + if (OB_NOT_NULL(name_buf)) { + allocator_.free(name_buf); + } +} + int64_t ObProxyPartMgr::to_string(char *buf, const int64_t buf_len) const { int64_t pos = 0; diff --git a/src/obproxy/proxy/route/obproxy_part_mgr.h b/src/obproxy/proxy/route/obproxy_part_mgr.h index ff82ae003..f1c8e341e 100644 --- a/src/obproxy/proxy/route/obproxy_part_mgr.h +++ b/src/obproxy/proxy/route/obproxy_part_mgr.h @@ -29,67 +29,28 @@ namespace obproxy class ObResultSetFetcher; namespace proxy { - -class ObPartNameIdPair -{ -public: - ObPartNameIdPair() : part_id_(-1), tablet_id_(-1) - { - part_name_buf_[0] = '\0'; - } - ~ObPartNameIdPair() {} - - int set_part_name(const common::ObString &part_name); - void set_part_id(int64_t part_id) { part_id_ = part_id; } - void set_tablet_id(const int64_t tablet_id) { tablet_id_ = tablet_id; } - - const common::ObString get_part_name() const { return part_name_; } - int64_t get_part_id() const { return part_id_; } - int64_t get_tablet_id() const { return tablet_id_; } - - int assign(const ObPartNameIdPair &other); - int64_t to_string(char *buf, const int64_t buf_len) const; -public: - common::ObString part_name_; - int64_t part_id_; - int64_t tablet_id_; - -private: - char part_name_buf_[common::OB_MAX_PARTITION_NAME_LENGTH]; - DISALLOW_COPY_AND_ASSIGN(ObPartNameIdPair); -}; - -inline int ObPartNameIdPair::set_part_name(const common::ObString &part_name) -{ - int ret = common::OB_SUCCESS; - if (part_name.length() > common::OB_MAX_PARTITION_NAME_LENGTH) { - ret = common::OB_INVALID_ARGUMENT; - PROXY_LOG(WARN, "invalid part name", K(part_name), K(ret)); - } else { - MEMCPY(part_name_buf_, part_name.ptr(), part_name.length()); - part_name_.assign_ptr(part_name_buf_, part_name.length()); - } - return ret; -} - -inline int ObPartNameIdPair::assign(const ObPartNameIdPair &other) -{ - int ret = common::OB_SUCCESS; - set_part_id(other.get_part_id()); - set_tablet_id(other.get_tablet_id()); - ret = set_part_name(other.get_part_name()); - return ret; -} +class ObProxyExprCalculator; +class ObServerRoute; class ObProxyPartMgr { +private: + const static int64_t MAX_PART_NAME_LENGTH = common::OB_MAX_PARTITION_NAME_LENGTH;//64 + typedef char PART_NAME_BUF[MAX_PART_NAME_LENGTH]; + typedef hash::ObHashMap PartNameIdMap; public: explicit ObProxyPartMgr(common::ObIAllocator &allocator); ~ObProxyPartMgr() { } - + void destroy(); + int get_part_with_part_name(const common::ObString &part_name, - int64_t &part_id_); - int get_first_part_id_by_idx(const int64_t idx, int64_t &part_id, int64_t &tablet_id); + int64_t &part_id, + ObProxyPartInfo &part_info, + ObServerRoute &route, + ObProxyExprCalculator &expr_calculator); + int get_first_part_id_by_random(const int64_t rand_num, + int64_t &first_part_id, + int64_t &tablet_id); int get_first_part(common::ObNewRange &range, common::ObIAllocator &allocator, common::ObIArray &part_ids, @@ -112,6 +73,7 @@ class ObProxyPartMgr const share::schema::ObPartitionFuncType part_func_type, const int64_t part_num, const int64_t part_space, + const int64_t part_col_num, const bool is_template_table, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher *rs_fetcher, @@ -119,6 +81,7 @@ class ObProxyPartMgr int build_sub_hash_part_with_non_template(const bool is_oracle_mode, const share::schema::ObPartitionFuncType part_func_type, const int64_t part_space, + const int64_t part_col_num, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, const int64_t cluster_version); @@ -126,34 +89,40 @@ class ObProxyPartMgr const share::schema::ObPartitionFuncType part_func_type, const int64_t part_num, const int64_t part_space, + const int64_t part_col_num, const bool is_template_table, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher *rs_fetcher, const int64_t cluster_version); int build_sub_key_part_with_non_template(const share::schema::ObPartitionFuncType part_func_type, const int64_t part_space, + const int64_t part_col_num, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, const int64_t cluster_version); int build_range_part(const share::schema::ObPartitionLevel part_level, const share::schema::ObPartitionFuncType part_func_type, const int64_t part_num, + const int64_t part_col_num, const bool is_template_table, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, const int64_t cluster_version); int build_sub_range_part_with_non_template(const share::schema::ObPartitionFuncType part_func_type, + const int64_t part_col_num, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, const int64_t cluster_verison); int build_list_part(const share::schema::ObPartitionLevel part_level, const share::schema::ObPartitionFuncType part_func_type, const int64_t part_num, + const int64_t part_col_num, const bool is_template_table, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, const int64_t cluster_version); int build_sub_list_part_with_non_template(const share::schema::ObPartitionFuncType part_func_type, + const int64_t part_col_num, const ObProxyPartKeyInfo &key_info, ObResultSetFetcher &rs_fetcher, const int64_t cluster_version); @@ -169,21 +138,57 @@ class ObProxyPartMgr ObPartDesc *&sub_part_desc_ptr, const int64_t cluster_version); + void set_all_sub_part_num(int64_t all_sub_part_num); common::ObObjType get_first_part_type() const; common::ObObjType get_sub_part_type() const; void set_cluster_version(const int64_t cluster_version) { cluster_version_ = cluster_version; } int64_t to_string(char *buf, const int64_t buf_len) const; +private: + int init_first_part_map(); + int init_sub_part_map(); + int alloc_name_buf(PART_NAME_BUF *&name_buf, int64_t *&name_len_buf, int64_t *&part_id_buf, const int64_t part_num); + void free_name_buf(PART_NAME_BUF *name_buf, int64_t *name_len_buf, int64_t *part_id_buf); + int build_part_name_id_map(const PART_NAME_BUF * const name_buf, + const int64_t * const name_len_buf, + const int64_t * const part_id_buf, + char * target_part_name_buf, + const int64_t total_part_name_len, + const int64_t part_num, + PartNameIdMap& part_name_id_map); + int build_temp_sub_part_name_id_map(const PART_NAME_BUF * const name_buf, + const int64_t * const name_len_buf, + const int64_t * const part_id_buf, + const int64_t part_num); private: common::ObPartDesc *first_part_desc_; common::ObPartDesc *sub_part_desc_; // may be we need a array here int64_t first_part_num_; int64_t *sub_part_num_; - ObPartNameIdPair* part_pair_array_; // first part name id pair array + int64_t all_sub_part_num_; + char * all_first_part_name_buf_; // first part name cancatenation string: "p1|p2|···|pn" + char * all_sub_part_name_buf_;// sub part name cancatenation string: "p1sp1|p1sp2|···|pnspn" + int64_t all_first_part_name_length_; + int64_t all_sub_part_name_length_; + PartNameIdMap first_part_name_id_map_; // map K(first part name) to V(first part id) + PartNameIdMap sub_part_name_id_map_; // map K(sub part name) to V(physical part id) common::ObIAllocator &allocator_; int64_t cluster_version_; }; +inline void ObProxyPartMgr::set_all_sub_part_num(int64_t all_sub_part_num) +{ + all_sub_part_num_ = all_sub_part_num; +} +inline int ObProxyPartMgr::init_first_part_map() +{ + return first_part_name_id_map_.create(first_part_num_ * 1, ObModIds::OB_HASH_BUCKET, ObModIds::OB_HASH_NODE);//default load factor = 1.0 +} +inline int ObProxyPartMgr::init_sub_part_map() +{ + return sub_part_name_id_map_.create(all_sub_part_num_ * 1, ObModIds::OB_HASH_BUCKET, ObModIds::OB_HASH_NODE);//default load factor = 1.0 +} + } // namespace proxy } // namespace obproxy } // namespace oceanbase diff --git a/src/obproxy/proxy/shard/obproxy_shard_utils.cpp b/src/obproxy/proxy/shard/obproxy_shard_utils.cpp index 0e7501dc7..a6d983cf7 100644 --- a/src/obproxy/proxy/shard/obproxy_shard_utils.cpp +++ b/src/obproxy/proxy/shard/obproxy_shard_utils.cpp @@ -94,6 +94,8 @@ int ObProxyShardUtils::check_logic_database(ObMysqlTransact::ObTransState &trans if (OB_SUCC(ret)) { session_info.set_group_id(OBPROXY_MAX_DBMESH_ID); + session_info.set_table_id(OBPROXY_MAX_DBMESH_ID); + session_info.set_es_id(OBPROXY_MAX_DBMESH_ID); session_info.set_logic_database_name(db_name); LOG_DEBUG("check logic database success", K(db_name)); } @@ -128,6 +130,7 @@ int ObProxyShardUtils::change_connector(ObDbConfigLogicDb &logic_db_info, LOG_WARN("not support distributed transaction", K(trans_state.current_.state_), K(trans_state.is_auth_request_), K(trans_state.is_hold_start_trans_), + K(trans_state.is_hold_xa_start_), KPC(prev_shard_conn), KPC(shard_conn), K(ret)); } else { @@ -231,27 +234,26 @@ void ObProxyShardUtils::replace_oracle_table(ObSqlString &new_sql, const ObStrin hava_quoto = false; } -int ObProxyShardUtils::do_rewrite_shard_select_request(const ObString &sql, - ObSqlParseResult &parse_result, - bool is_oracle_mode, - const ObHashMap &table_name_map, - const ObString &real_database_name, - bool is_single_shard_db_table, - ObSqlString &new_sql) +int ObProxyShardUtils::rewrite_shard_dml_request(const ObString &sql, + ObSqlString &new_sql, + ObSqlParseResult &parse_result, + bool is_oracle_mode, + const ObHashMap &table_name_map, + const ObString &real_database_name, + bool is_single_shard_db_table) { int ret = OB_SUCCESS; - const uint32_t PARSE_EXTRA_CHAR_NUM = 2; const char *sql_ptr = sql.ptr(); int64_t sql_len = sql.length(); int64_t copy_pos = 0; - ObProxySelectStmt *select_stmt = static_cast(parse_result.get_proxy_stmt()); - if (OB_ISNULL(select_stmt)) { + ObProxyDMLStmt *dml_stmt = static_cast(parse_result.get_proxy_stmt()); + if (OB_ISNULL(dml_stmt)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected null select stmt", K(ret)); } else { - ObProxySelectStmt::TablePosArray &table_pos_array = select_stmt->get_table_pos_array(); + ObProxyDMLStmt::TablePosArray &table_pos_array = dml_stmt->get_table_pos_array(); std::sort(table_pos_array.begin(), table_pos_array.end()); for (int64_t i = 0; OB_SUCC(ret) && i < table_pos_array.count(); i++) { @@ -284,48 +286,12 @@ int ObProxyShardUtils::do_rewrite_shard_select_request(const ObString &sql, if (OB_SUCC(ret)) { - new_sql.append(sql_ptr + copy_pos, sql_len - copy_pos - PARSE_EXTRA_CHAR_NUM); + new_sql.append(sql_ptr + copy_pos, sql_len - copy_pos); } return ret; } -int ObProxyShardUtils::rewrite_shard_select_request(ObClientSessionInfo &session_info, - ObProxyMysqlRequest &client_request, - ObIOBufferReader &client_buffer_reader, - const ObHashMap &table_name_map, - const ObString &real_database_name, - bool is_single_shard_db_table) -{ - int ret = OB_SUCCESS; - - ObSqlParseResult &parse_result = client_request.get_parse_result(); - ObSqlString new_sql; - - if (OB_FAIL(do_rewrite_shard_select_request(client_request.get_parse_sql(), parse_result, - session_info.is_oracle_mode(), table_name_map, - real_database_name, is_single_shard_db_table, - new_sql))) { - } else { - // 4. push reader forward by consuming old buffer and write new sql into buffer - if (OB_FAIL(client_buffer_reader.consume_all())) { - LOG_WARN("fail to consume all", K(ret)); - } else { - ObMIOBuffer *writer = client_buffer_reader.mbuf_; - if (OB_ISNULL(writer)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected null values ", K(writer), K(ret)); - // no need compress here, if server session support compress, it will compress later - } else if (OB_FAIL(ObMysqlRequestBuilder::build_mysql_request(*writer, obmysql::OB_MYSQL_COM_QUERY, new_sql.string(), false, false))) { - LOG_WARN("fail to build_mysql_request", K(new_sql), K(ret)); - } else if (OB_FAIL(ObProxySessionInfoHandler::rewrite_query_req_by_sharding(session_info, client_request, client_buffer_reader))) { - LOG_WARN("fail to rewrite_query_req_by_sharding", K(ret)); - } - } - } - - return ret; -} int ObProxyShardUtils::rewrite_shard_request_db(const char *sql_ptr, int64_t database_pos, int64_t table_pos, uint64_t database_len, @@ -373,6 +339,35 @@ int ObProxyShardUtils::rewrite_shard_request_db(const char *sql_ptr, int64_t dat return ret; } +int ObProxyShardUtils::rewrite_shard_request_table_no_db(const char *sql_ptr, + int64_t table_pos, uint64_t table_len, + const ObString &real_table_name, + bool is_oracle_mode, bool is_single_shard_db_table, + ObSqlString &new_sql, int64_t ©_pos) +{ + int ret = OB_SUCCESS; + + bool table_have_quoto = false; + + if (*(sql_ptr + table_pos - 1) == '`' || *(sql_ptr + table_pos - 1) == '"') { + table_have_quoto = true; + table_pos -= 1; + table_len += 2; + } + + new_sql.append(sql_ptr + copy_pos, table_pos - copy_pos); + if (is_oracle_mode) { + replace_oracle_table(new_sql, real_table_name, table_have_quoto, is_single_shard_db_table, false); + } else { + new_sql.append(real_table_name); + } + + copy_pos = table_pos + table_len; + + return ret; +} + + int ObProxyShardUtils::rewrite_shard_request_table(const char *sql_ptr, int64_t database_pos, uint64_t database_len, int64_t table_pos, uint64_t table_len, @@ -444,24 +439,22 @@ int ObProxyShardUtils::rewrite_shard_request_hint_table(const char *sql_ptr, int // if no quoto, not add quoto // if sharding mode, table from config, both add quoto int ObProxyShardUtils::rewrite_shard_request(ObClientSessionInfo &session_info, - ObProxyMysqlRequest &client_request, - ObIOBufferReader &client_buffer_reader, + ObSqlParseResult &parse_result, const ObString &table_name, const ObString &database_name, const ObString &real_table_name, const ObString &real_database_name, - bool is_single_shard_db_table) + bool is_single_shard_db_table, + const ObString& sql, + ObSqlString& new_sql) { int ret = OB_SUCCESS; - const uint32_t PARSE_EXTRA_CHAR_NUM = 2; uint64_t table_len = table_name.length(); uint64_t database_len = database_name.length(); uint64_t index_table_len = table_name.length(); - int64_t table_pos = client_request.get_parse_result().get_dbmesh_route_info().tb_pos_; - int64_t database_pos = client_request.get_parse_result().get_dbmesh_route_info().db_pos_; - int64_t index_table_pos = client_request.get_parse_result().get_dbmesh_route_info().index_tb_pos_; + int64_t table_pos = parse_result.get_dbmesh_route_info().tb_pos_; + int64_t database_pos = parse_result.get_dbmesh_route_info().db_pos_; + int64_t index_table_pos = parse_result.get_dbmesh_route_info().index_tb_pos_; - ObString sql = client_request.get_parse_sql(); - common::ObSqlString new_sql; const char *sql_ptr = sql.ptr(); int64_t sql_len = sql.length(); @@ -493,23 +486,8 @@ int ObProxyShardUtils::rewrite_shard_request(ObClientSessionInfo &session_info, } if (OB_SUCC(ret)) { - new_sql.append(sql_ptr + copy_pos, sql_len - copy_pos - PARSE_EXTRA_CHAR_NUM); - - // 4. push reader forward by consuming old buffer and write new sql into buffer - if (OB_FAIL(client_buffer_reader.consume_all())) { - LOG_WARN("fail to consume all", K(ret)); - } else { - ObMIOBuffer *writer = client_buffer_reader.mbuf_; - if (OB_ISNULL(writer)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected null values ", K(writer), K(ret)); - // no need compress here, if server session support compress, it will compress later - } else if (OB_FAIL(ObMysqlRequestBuilder::build_mysql_request(*writer, obmysql::OB_MYSQL_COM_QUERY, new_sql.string(), false, false))) { - LOG_WARN("fail to build_mysql_request", K(new_sql), K(ret)); - } else if (OB_FAIL(ObProxySessionInfoHandler::rewrite_query_req_by_sharding(session_info, client_request, client_buffer_reader))) { - LOG_WARN("fail to rewrite_query_req_by_sharding", K(ret)); - } - } + new_sql.append(sql_ptr + copy_pos, sql_len - copy_pos); + LOG_DEBUG("succ to rewrite sql", K(sql), K(new_sql)); } return ret; @@ -729,25 +707,21 @@ int ObProxyShardUtils::testload_check_and_rewrite_testload_hint_index(common::Ob * Args: * @param session_info : client session info * @param client_request : client request - * @param client_buffer_reader : buffer to rewrite request * @param is_single_shard_db_table: * @param real_database_name : real database name in Server * @param logic_db_info : config info for database * */ -int ObProxyShardUtils::testload_check_and_rewrite_testload_request(ObClientSessionInfo &session_info, - ObProxyMysqlRequest &client_request, - ObIOBufferReader &client_buffer_reader, +int ObProxyShardUtils::testload_check_and_rewrite_testload_request(ObSqlParseResult &parse_result, bool is_single_shard_db_table, const ObString &hint_table, const ObString &real_database_name, - ObDbConfigLogicDb &logic_db_info) + ObDbConfigLogicDb &logic_db_info, + const ObString& sql, + common::ObSqlString& new_sql) { int ret = OB_SUCCESS; UNUSED(is_single_shard_db_table); - ObSqlParseResult &parse_result = client_request.get_parse_result(); - ObString sql = client_request.get_sql(); - common::ObSqlString new_sql; //init by default const char *sql_ptr = sql.ptr(); int64_t sql_len = sql.length(); ObArenaAllocator allocator; @@ -878,30 +852,13 @@ int ObProxyShardUtils::testload_check_and_rewrite_testload_request(ObClientSessi } } LOG_DEBUG("ObProxyShardUtils::check_and_rewrite_testload_request all", K(ret), K(new_sql)); - //rewrite sql base on new_sql - if (OB_SUCC(ret)) { - if (OB_FAIL(client_buffer_reader.consume_all())) { - LOG_WARN("fail to consume all", K(ret)); - } else { - ObMIOBuffer *writer = client_buffer_reader.mbuf_; - if (OB_ISNULL(writer)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected null values ", K(writer), K(ret)); - // no need compress here, if server session support compress, it will compress later - } else if (OB_FAIL(ObMysqlRequestBuilder::build_mysql_request(*writer, obmysql::OB_MYSQL_COM_QUERY, new_sql.string(), false, false))) { - LOG_WARN("fail to build_mysql_request", K(new_sql), K(ret)); - } else if (OB_FAIL(ObProxySessionInfoHandler::rewrite_query_req_by_sharding(session_info, client_request, client_buffer_reader))) { - LOG_WARN("fail to rewrite_query_req_by_sharding", K(ret)); - } - } - } -//*/ + return ret; } -bool ObProxyShardUtils::is_special_db(ObMysqlTransact::ObTransState &s) +bool ObProxyShardUtils::is_special_db(obutils::ObSqlParseResult& parse_result) { - const ObString &database_name = s.trans_info_.client_request_.get_parse_result().get_origin_database_name(); + const ObString &database_name = parse_result.get_origin_database_name(); if (!database_name.empty() && 0 == database_name.case_compare("information_schema")) { return true; } @@ -984,19 +941,73 @@ int ObProxyShardUtils::check_shard_request(ObMysqlClientSession &client_session, return ret; } -int ObProxyShardUtils::get_shard_hint(ObDbConfigLogicDb &logic_db_info, +int ObProxyShardUtils::get_shard_hint(const ObString &table_name, + ObClientSessionInfo &session_info, + ObDbConfigLogicDb &logic_db_info, ObSqlParseResult &parse_result, int64_t &group_index, int64_t &tb_index, - int64_t &es_index, ObString &table_name, + int64_t &es_index, ObString &hint_table_name, ObTestLoadType &testload_type) { int ret = OB_SUCCESS; + + bool is_sticky_session = false; + + if (OB_FAIL(get_shard_hint(logic_db_info, parse_result, + group_index, tb_index, es_index, + hint_table_name, testload_type, + is_sticky_session))) { + LOG_WARN("fail to get shard hint", K(ret)); + } else if (is_sticky_session) { + group_index = session_info.get_group_id(); + tb_index = session_info.get_table_id(); + es_index = session_info.get_es_id(); + + if (group_index == OBPROXY_MAX_DBMESH_ID) { + group_index = 0; + } + + if (tb_index == OBPROXY_MAX_DBMESH_ID) { + tb_index = 0; + } + + if (es_index == OBPROXY_MAX_DBMESH_ID) { + es_index = 0; + } + + if (tb_index == 0 && group_index > 0) { + tb_index = group_index; + } + } + + if (OB_SUCC(ret) && !logic_db_info.is_single_shard_db_table()) { + ObShardRule *logic_tb_info = NULL; + if (OB_FAIL(logic_db_info.get_shard_rule(logic_tb_info, table_name))) { + LOG_WARN("fail to get shard rule", K(table_name), K(ret)); + } else if (group_index != OBPROXY_MAX_DBMESH_ID && group_index >= logic_tb_info->db_size_) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("sql with group hint and greater than db size", + "db_size", logic_tb_info->db_size_, K(group_index), K(ret)); + } + } + + return ret; +} + +int ObProxyShardUtils::get_shard_hint(ObDbConfigLogicDb &logic_db_info, + ObSqlParseResult &parse_result, + int64_t &group_index, int64_t &tb_index, + int64_t &es_index, ObString &hint_table_name, + ObTestLoadType &testload_type, + bool &is_sticky_session) +{ + int ret = OB_SUCCESS; DbMeshRouteInfo &odp_route_info = parse_result.get_dbmesh_route_info(); DbpRouteInfo &dbp_route_info = parse_result.get_dbp_route_info(); if (odp_route_info.is_valid()) { group_index = parse_result.get_dbmesh_route_info().group_idx_; - table_name = parse_result.get_dbmesh_route_info().table_name_; - if (table_name.empty()) { + hint_table_name = parse_result.get_dbmesh_route_info().table_name_; + if (hint_table_name.empty()) { tb_index = parse_result.get_dbmesh_route_info().tb_idx_; } es_index = parse_result.get_dbmesh_route_info().es_idx_; @@ -1011,7 +1022,9 @@ int ObProxyShardUtils::get_shard_hint(ObDbConfigLogicDb &logic_db_info, } else if (dbp_route_info.is_valid()) { if (parse_result.get_dbp_route_info().is_group_info_valid()) { group_index = dbp_route_info.group_idx_; - table_name = dbp_route_info.table_name_; + hint_table_name = dbp_route_info.table_name_; + } else if (parse_result.get_dbp_route_info().sticky_session_) { + is_sticky_session = true; } } return ret; @@ -1031,6 +1044,172 @@ bool ObProxyShardUtils::is_read_stmt(ObClientSessionInfo &session_info, ObMysqlT || parse_result.has_explain())); } +bool ObProxyShardUtils::is_unsupport_type_in_multi_stmt(ObSqlParseResult& parse_result) +{ + return parse_result.is_shard_special_cmd() + || ObProxyShardUtils::is_special_db(parse_result) + || parse_result.is_ddl_stmt() + || parse_result.is_multi_stmt() + || parse_result.is_show_tables_stmt() + || parse_result.is_show_full_tables_stmt() + || parse_result.is_show_table_status_stmt(); +} + +int ObProxyShardUtils::handle_information_schema_request(ObMysqlClientSession &client_session, + ObMysqlTransact::ObTransState &trans_state, + ObIOBufferReader &client_buffer_reader) +{ + int ret = OB_SUCCESS; + + ObProxyMysqlRequest &client_request = trans_state.trans_info_.client_request_; + ObSqlParseResult &parse_result = client_request.get_parse_result(); + SqlFieldResult& sql_result = parse_result.get_sql_filed_result(); + ObProxySqlParser sql_parser; + ObString sql = client_request.get_parse_sql(); + ObProxyDMLStmt *dml_stmt = NULL; + if (OB_FAIL(sql_parser.parse_sql_by_obparser(sql, NORMAL_PARSE_MODE, parse_result, true))) { + LOG_WARN("parse_sql_by_obparser failed", K(ret), K(sql)); + } else if (OB_ISNULL(dml_stmt = dynamic_cast(parse_result.get_proxy_stmt()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dml stmt is null, unexpected", K(ret)); + } else { + ObClientSessionInfo &cs_info = client_session.get_session_info(); + ObDbConfigLogicDb *logic_db_info = NULL; + ObShardConnector *shard_conn = NULL; + bool is_rewrite_sql = false; + bool is_single_shard_db_table = false; + + common::ObSqlString new_sql; + const char *sql_ptr = sql.ptr(); + int64_t sql_len = sql.length(); + int64_t copy_pos = 0; + + ObString last_database_name; + char real_database_name[OB_MAX_DATABASE_NAME_LENGTH]; + char real_table_name[OB_MAX_TABLE_NAME_LENGTH]; + + ObProxyDMLStmt::DbTablePosArray &db_table_pos_array = dml_stmt->get_db_table_pos_array(); + std::sort(db_table_pos_array.begin(), db_table_pos_array.end()); + + for (int64_t i = 0; OB_SUCC(ret) && i < db_table_pos_array.count(); i++) { + ObProxyDbTablePos &db_table_pos = db_table_pos_array.at(i); + if (SHARDING_POS_DB == db_table_pos.get_type()) { + const ObString &database_name = db_table_pos.get_name(); + + if (last_database_name.empty()) { + last_database_name = database_name; + } else if (0 != last_database_name.case_compare(database_name)) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("do not support two schema", K(database_name), K(last_database_name), K(ret)); + } + + if (OB_SUCC(ret) && NULL == shard_conn) { + ObShardConnector *prev_shard_conn = cs_info.get_shard_connector(); + ObString logic_tenant_name; + ObDbConfigCache &dbconfig_cache = get_global_dbconfig_cache(); + if (OB_ISNULL(prev_shard_conn)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("prev shard connector info is null", K(ret)); + } else if (OB_FAIL(cs_info.get_logic_tenant_name(logic_tenant_name))) { + ret = OB_ERR_UNEXPECTED; // no need response, just return ret and disconnect + LOG_ERROR("fail to get logic tenant name", K(ret)); + } else if (OB_ISNULL(logic_db_info = dbconfig_cache.get_exist_db_info(logic_tenant_name, database_name))) { + ret = OB_ERR_BAD_DATABASE; + LOG_WARN("database not exist", K(logic_tenant_name), K(database_name)); + } else if (OB_FAIL(logic_db_info->get_first_group_shard_connector(shard_conn, OBPROXY_MAX_DBMESH_ID, false, TESTLOAD_NON))) { + LOG_WARN("fail to get random shard connector", K(ret), KPC(logic_db_info)); + } else if (*prev_shard_conn != *shard_conn) { + if (OB_FAIL(change_connector(*logic_db_info, client_session, trans_state, prev_shard_conn, shard_conn))) { + LOG_WARN("fail to change connector", KPC(prev_shard_conn), KPC(shard_conn), K(ret)); + } + } + + if (OB_SUCC(ret)) { + snprintf(real_database_name, OB_MAX_DATABASE_NAME_LENGTH, "%.*s", + shard_conn->database_name_.length(), shard_conn->database_name_.ptr()); + is_single_shard_db_table = logic_db_info->is_single_shard_db_table(); + } + } + } + } + + if (OB_SUCC(ret) && last_database_name.empty()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("do not support zero schema", K(ret)); + } + + for (int64_t i = 0; OB_SUCC(ret) && i < db_table_pos_array.count(); i++) { + ObProxyDbTablePos &db_table_pos = db_table_pos_array.at(i); + if (SHARDING_POS_DB == db_table_pos.get_type()) { + const ObString &database_name = db_table_pos.get_name(); + int32_t database_pos = db_table_pos.get_pos(); + if (OB_FAIL(rewrite_shard_request_db(sql_ptr, database_pos, 0, database_name.length(), + real_database_name, cs_info.is_oracle_mode(), + is_single_shard_db_table, new_sql, copy_pos))) { + LOG_WARN("fail to rewrite db", K(ret)); + } else { + is_rewrite_sql = true; + } + } else if (!is_single_shard_db_table && SHARDING_POS_TABLE == db_table_pos.get_type()) { + int32_t table_pos = db_table_pos.get_pos(); + const ObString &table_name = db_table_pos.get_name(); + int64_t tb_index = 0; + ObTestLoadType testload_type = TESTLOAD_NON; + ObString hint_table; + if (OB_FAIL(logic_db_info->get_real_table_name(table_name, sql_result, + real_table_name, OB_MAX_TABLE_NAME_LENGTH, + tb_index, hint_table, testload_type))) { + if (OB_ENTRY_NOT_EXIST == ret) { + // If the table does not exist, ignore the table name + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to get real table name", K(table_name), K(tb_index), K(testload_type), K(ret)); + } + } else if (OB_FAIL(rewrite_shard_request_table_no_db(sql_ptr, table_pos, table_name.length(), real_table_name, + cs_info.is_oracle_mode(), is_single_shard_db_table, + new_sql, copy_pos))) { + LOG_WARN("fail to rewrite table", K(ret)); + } else { + is_rewrite_sql = true; + } + } + } + + if (OB_SUCC(ret) && is_rewrite_sql) { + const uint32_t PARSE_EXTRA_CHAR_NUM = 2; + new_sql.append(sql_ptr + copy_pos, sql_len - copy_pos - PARSE_EXTRA_CHAR_NUM); + + // 4. push reader forward by consuming old buffer and write new sql into buffer + if (OB_FAIL(client_buffer_reader.consume_all())) { + LOG_WARN("fail to consume all", K(ret)); + } else { + ObMIOBuffer *writer = client_buffer_reader.mbuf_; + if (OB_ISNULL(writer)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null values ", K(writer), K(ret)); + // no need compress here, if server session support compress, it will compress later + } else if (OB_FAIL(ObMysqlRequestBuilder::build_mysql_request(*writer, obmysql::OB_MYSQL_COM_QUERY, new_sql.string(), false, false))) { + LOG_WARN("fail to build_mysql_request", K(new_sql), K(ret)); + } else if (OB_FAIL(ObProxySessionInfoHandler::rewrite_query_req_by_sharding(cs_info, client_request, client_buffer_reader))) { + LOG_WARN("fail to rewrite_query_req_by_sharding", K(ret)); + } + } + } + + if (NULL != shard_conn) { + shard_conn->dec_ref(); + shard_conn = NULL; + } + + if (NULL != logic_db_info) { + logic_db_info->dec_ref(); + logic_db_info = NULL; + } + } + + return ret; +} + /* * if no table name * use last shard connector @@ -1049,8 +1228,13 @@ bool ObProxyShardUtils::is_read_stmt(ObClientSessionInfo &session_info, ObMysqlT */ int ObProxyShardUtils::do_handle_single_shard_request(ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, - ObIOBufferReader &client_buffer_reader, - ObDbConfigLogicDb &logic_db_info) + ObDbConfigLogicDb &logic_db_info, + const ObString& sql, + ObSqlString& new_sql, + ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index, + const int64_t last_es_index) { int ret = OB_SUCCESS; @@ -1060,30 +1244,19 @@ int ObProxyShardUtils::do_handle_single_shard_request(ObMysqlClientSession &clie ObShardConnector *shard_conn = NULL; ObShardConnector *prev_shard_conn = session_info.get_shard_connector(); - ObProxyMysqlRequest &client_request = trans_state.trans_info_.client_request_; - ObSqlParseResult &parse_result = client_request.get_parse_result(); - ObString table_name = client_request.get_parse_result().get_origin_table_name(); - int64_t group_index = OBPROXY_MAX_DBMESH_ID; + ObString table_name = parse_result.get_origin_table_name(); + es_index = OBPROXY_MAX_DBMESH_ID; + group_index = OBPROXY_MAX_DBMESH_ID; int64_t tb_index = OBPROXY_MAX_DBMESH_ID; - int64_t es_index = OBPROXY_MAX_DBMESH_ID; ObTestLoadType testload_type = TESTLOAD_NON; ObString hint_table; bool is_need_rewrite_sql = false; bool is_skip_rewrite_check = false; - bool is_need_skip_router = false; + bool is_sticky_session = false; if (OB_FAIL(get_shard_hint(logic_db_info, parse_result, - group_index, tb_index, es_index, hint_table, testload_type))) { + group_index, tb_index, es_index, hint_table, testload_type, is_sticky_session))) { LOG_WARN("fail to get shard hint", K(ret)); } else { - // some case can skip route: - // 1. if specify group_index, tb_index, es_index - // 2. if in trans, use last shard connector - // 3. special sql, use last shard connector - is_need_skip_router = (!(OBPROXY_MAX_DBMESH_ID != es_index && 0 != es_index) - && ((is_sharding_in_trans(session_info, trans_state)) - || parse_result.is_show_stmt() - || (parse_result.is_select_stmt() && parse_result.has_last_insert_id()))); - // some case can skip rewrite check: // 1. if sql have table name, can not skip // 2. if sql have no table name @@ -1101,7 +1274,7 @@ int ObProxyShardUtils::do_handle_single_shard_request(ObMysqlClientSession &clie // 1. sql have db // 2. have testload flag // 3. specify table in hint - is_need_rewrite_sql = (!is_skip_rewrite_check) && (!client_request.get_parse_result().get_origin_database_name().empty() + is_need_rewrite_sql = (!is_skip_rewrite_check) && (!parse_result.get_origin_database_name().empty() || TESTLOAD_NON != testload_type || !hint_table.empty()); @@ -1111,159 +1284,328 @@ int ObProxyShardUtils::do_handle_single_shard_request(ObMysqlClientSession &clie || (is_need_rewrite_sql && table_name.empty())) { ret = OB_NOT_SUPPORTED; LOG_WARN("sql with dbmesh route hint and no table name is unsupported", K(tb_index), K(group_index), K(is_need_rewrite_sql), K(ret)); - } + } } if (OB_SUCC(ret)) { char real_table_name[OB_MAX_TABLE_NAME_LENGTH]; char real_database_name[OB_MAX_DATABASE_NAME_LENGTH]; - if (!is_need_skip_router) { - bool is_read_stmt = ObProxyShardUtils::is_read_stmt(session_info, trans_state, parse_result); + // The write request takes the write weight, and the request in the transaction is considered to be write + // Read Request Walk Weight + bool is_read_stmt = ObProxyShardUtils::is_read_stmt(session_info, trans_state, parse_result); - if (OB_FAIL(logic_db_info.get_single_table_info(table_name, shard_conn, - real_database_name, OB_MAX_DATABASE_NAME_LENGTH, - real_table_name, OB_MAX_TABLE_NAME_LENGTH, - group_index, tb_index, es_index, - hint_table, testload_type, is_read_stmt))) { - LOG_WARN("shard tpo info is null", K(ret)); - } else if (OB_ISNULL(shard_conn) || OB_ISNULL(prev_shard_conn)) { - ret = OB_EXPR_CALC_ERROR; - LOG_WARN("shard connector info or prev shard connector info is null", KP(shard_conn), - KP(prev_shard_conn), K(ret)); - } else if (*prev_shard_conn != *shard_conn) { - if (OB_FAIL(change_connector(logic_db_info, client_session, trans_state, prev_shard_conn, shard_conn))) { - LOG_WARN("fail to change connector", KPC(prev_shard_conn), KPC(shard_conn), K(ret)); - } - } - if (OB_NOT_NULL(shard_conn)) { - shard_conn->dec_ref(); - shard_conn = NULL; - } - } else { // is_need_skip_router == true, write new table_name and database_name - if (OB_NOT_NULL(prev_shard_conn) && OB_FAIL(logic_db_info.get_single_real_table_info(table_name, *prev_shard_conn, - real_database_name, OB_MAX_DATABASE_NAME_LENGTH, - real_table_name, OB_MAX_TABLE_NAME_LENGTH, - hint_table))) { - LOG_WARN("fail to get real table info", K(table_name), K(ret)); - } else if (OB_ISNULL(prev_shard_conn)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("shard previous connection info is null to use", K(is_need_skip_router), K(ret)); + if (OB_FAIL(logic_db_info.get_single_table_info(table_name, shard_conn, + real_database_name, OB_MAX_DATABASE_NAME_LENGTH, + real_table_name, OB_MAX_TABLE_NAME_LENGTH, + group_index, tb_index, es_index, + hint_table, testload_type, is_read_stmt, last_es_index))) { + LOG_WARN("shard tpo info is null", K(ret)); + } else if (OB_ISNULL(shard_conn) || OB_ISNULL(prev_shard_conn)) { + ret = OB_EXPR_CALC_ERROR; + LOG_WARN("shard connector info or prev shard connector info is null", KP(shard_conn), + KP(prev_shard_conn), K(ret)); + } else if (*prev_shard_conn != *shard_conn) { + if (OB_FAIL(change_connector(logic_db_info, client_session, trans_state, prev_shard_conn, shard_conn))) { + LOG_WARN("fail to change connector", KPC(prev_shard_conn), KPC(shard_conn), K(ret)); } } + if (OB_NOT_NULL(shard_conn)) { + shard_conn->dec_ref(); + shard_conn = NULL; + } - if (!is_skip_rewrite_check) { - LOG_DEBUG("check_and_rewrite_testload_request", K(testload_type), K(ret)); - if (OB_SUCC(ret) && TESTLOAD_ALIPAY_COMPATIBLE == testload_type && hint_table.empty()) { /* testload = 8 */ - ret = OB_ERR_TESTLOAD_ALIPAY_COMPATIBLE; - LOG_WARN("not have table_name's hint for 'testload=8' (TESTLOAD_ALIPAY_COMPATIBLE)", K(ret)); - } else if (OB_SUCC(ret) && TESTLOAD_NON != testload_type) { //rewrite table name for testload - ObProxySqlParser sql_parser; - ObSqlParseResult &sql_parse_result = client_request.get_parse_result(); - ObString sql = client_request.get_parse_sql(); - if (OB_FAIL(sql_parser.parse_sql_by_obparser(sql, NORMAL_PARSE_MODE, sql_parse_result, false))) { - LOG_WARN("parse_sql_by_obparser failed", K(ret), K(sql)); - } else if (OB_FAIL(testload_check_and_rewrite_testload_request(session_info, client_request, client_buffer_reader, - false, hint_table, ObString::make_string(real_database_name), logic_db_info))) { - LOG_WARN("fail to check and rewrite testload request"); + if (OB_SUCC(ret)) { + if (!is_skip_rewrite_check) { + if (TESTLOAD_ALIPAY_COMPATIBLE == testload_type && hint_table.empty()) { /* testload = 8 */ + ret = OB_ERR_TESTLOAD_ALIPAY_COMPATIBLE; + LOG_WARN("not have table_name's hint for 'testload=8' (TESTLOAD_ALIPAY_COMPATIBLE)", K(ret)); + } else if (TESTLOAD_NON != testload_type) { //rewrite table name for testload + LOG_DEBUG("check_and_rewrite_testload_request", K(testload_type), K(ret)); + ObProxySqlParser sql_parser; + if (OB_FAIL(sql_parser.parse_sql_by_obparser(ObProxyMysqlRequest::get_parse_sql(sql), + NORMAL_PARSE_MODE, parse_result, false))) { + LOG_WARN("parse_sql_by_obparser failed", K(ret), K(sql)); + } else if (OB_FAIL(testload_check_and_rewrite_testload_request(parse_result, false, hint_table, + ObString::make_string(real_database_name), + logic_db_info, sql, new_sql))) { + LOG_WARN("fail to check and rewrite testload request"); + } + } else if (is_need_rewrite_sql) { + if (OB_FAIL(rewrite_shard_request(session_info, parse_result, table_name, + logic_db_info.db_name_.config_string_, ObString::make_string(real_table_name), + ObString::make_string(real_database_name), true, sql, new_sql))) { + LOG_WARN("fail to rewrite shard request", K(ret), K(table_name), + K(logic_db_info.db_name_), K(real_table_name), K(real_database_name)); + } } else { - is_need_rewrite_sql = false; - LOG_DEBUG("check and rewrite testload data"); - } - } - - if (OB_SUCC(ret) && is_need_rewrite_sql) { - if (OB_FAIL(rewrite_shard_request(session_info, client_request, client_buffer_reader, - table_name, logic_db_info.db_name_.config_string_, ObString::make_string(real_table_name), - ObString::make_string(real_database_name), true))) { - LOG_WARN("fail to rewrite shard request", K(ret), K(table_name), - K(logic_db_info.db_name_), K(real_table_name), K(real_database_name)); + //no need to rewrite sql, just append to new sql; + ret = new_sql.append(sql); + LOG_DEBUG("not need to rewrite sql by rules", K(real_database_name), K(real_table_name)); } + } else { + //no need to rewrite sql, just append to new sql; + ret = new_sql.append(sql); + LOG_DEBUG("not need to rewrite sql by rules", K(real_database_name), K(real_table_name)); } - } else { - LOG_DEBUG("not need to rewrite sql by rules", K(real_database_name), K(real_table_name)); - } + } } - return ret; } -int ObProxyShardUtils::handle_single_shard_request(ObMysqlSM *sm, - ObMysqlClientSession &client_session, +int ObProxyShardUtils::handle_single_shard_request(ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, ObIOBufferReader &client_buffer_reader, - ObDbConfigLogicDb &logic_db_info, - bool &need_wait_callback) + ObDbConfigLogicDb &logic_db_info) { int ret = OB_SUCCESS; + ObClientSessionInfo &session_info = client_session.get_session_info(); ObProxyMysqlRequest &client_request = trans_state.trans_info_.client_request_; - ObSqlParseResult &parse_result = client_request.get_parse_result(); - const ObString runtime_env = get_global_proxy_config().runtime_env.str(); - if (parse_result.is_ddl_stmt() && 0 == runtime_env.case_compare(OB_PROXY_DBP_RUNTIME_ENV)) { - if (OB_FAIL(handle_ddl_request(sm, client_session, trans_state, logic_db_info, need_wait_callback))) { - LOG_WARN("fail to handle ddl request", K(ret)); + ObSqlParseResult &origin_parse_result = client_request.get_parse_result(); + ObString origin_sql = client_request.get_sql();//should not use get_parse_sql() + ObSqlString new_sql; + ObSEArray sql_array; + ObArenaAllocator &allocator = origin_parse_result.allocator_; + char * multi_sql_buf = NULL; + int64_t es_index = OBPROXY_MAX_DBMESH_ID; + int64_t group_index = OBPROXY_MAX_DBMESH_ID; + int64_t last_es_index = OBPROXY_MAX_DBMESH_ID; + int64_t last_group_index = OBPROXY_MAX_DBMESH_ID; + if (OB_FAIL(ObProxySqlParser::split_multiple_stmt(origin_sql, sql_array))) { + LOG_WARN("fail to split sql", K(ret)); + } else if (OB_UNLIKELY(sql_array.count() <= 0)){ + ret = OB_ERR_PARSER_SYNTAX; + LOG_WARN("fail to split sql and the sql num is wrong", K(ret)); + } else if (OB_UNLIKELY((sql_array.count() > 1) + && OB_FAIL(ObProxySqlParser::preprocess_multi_stmt(allocator, + multi_sql_buf, + origin_sql.length(), + sql_array)))) { + LOG_WARN("fail to preprocess multi stmt", K(ret)); + } else { + bool is_multi_stmt = sql_array.count() > 1; + ObSqlParseResult parse_result; + ObSqlParseResult* real_parse_result = NULL; + ObProxySqlParser sql_parser; + for (int64_t i = 0; OB_SUCC(ret) && i < sql_array.count(); ++i) { + const ObString& sql = sql_array.at(i); + if (0 == i) { + real_parse_result = &origin_parse_result; + } else if (OB_FAIL(sql_parser.parse_sql(ObProxyMysqlRequest::get_parse_sql(sql), + NORMAL_PARSE_MODE/*parse_mode*/, parse_result, + false/*use_lower_case_name*/, + static_cast(client_session.get_session_info().get_collation_connection()), + false/*drop_origin_db_table_name*/, + true /*is sharding user*/))) { + LOG_WARN("fail to handle single shard request for single sql", K(ret), K(sql)); + } else { + real_parse_result = &parse_result; + } + + if (OB_SUCC(ret)) { + if (OB_UNLIKELY(real_parse_result->is_invalid_stmt() && real_parse_result->has_shard_comment())) { + ret = OB_ERR_PARSER_SYNTAX; + LOG_WARN("fail to parse shard sql with shard comment","sql", client_request.get_sql(), K(ret)); + } else if (OB_UNLIKELY(is_multi_stmt && ObProxyShardUtils::is_unsupport_type_in_multi_stmt(*real_parse_result))) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("unsupport type in multi stmt", K(ret), K(sql)); + } else if (OB_FAIL(do_handle_single_shard_request(client_session, trans_state, logic_db_info, sql, new_sql, + *real_parse_result, es_index, group_index, last_es_index))) { + LOG_WARN("fail to handle single shard request for single sql", K(ret), K(sql), K(new_sql)); + } else if (OB_UNLIKELY((i > 0) && ((es_index != last_es_index) || (group_index != last_group_index)))) { + ret = OB_ERR_DISTRIBUTED_NOT_SUPPORTED; + LOG_WARN("different elastic index or group index for multi stmt is not supported", K(es_index), K(last_es_index), K(group_index), + K(last_group_index), K(sql), K(new_sql), K(ret)); + } else { + last_es_index = es_index; + last_group_index = group_index; + if (i > 0) { + real_parse_result->reset(); + } + } + } + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(build_shard_request_packet(session_info, client_request, client_buffer_reader, new_sql.string()))) { + LOG_WARN("fail to build sharding request packet", K(ret)); } - } else if (OB_FAIL(do_handle_single_shard_request(client_session, trans_state, - client_buffer_reader, logic_db_info))) { - LOG_WARN("fail to handle single shard request", K(ret)); + } + + if(NULL != multi_sql_buf) { + allocator.free(multi_sql_buf); } return ret; } -int ObProxyShardUtils::handle_shard_request(ObMysqlSM *sm, - ObMysqlClientSession &client_session, - ObMysqlTransact::ObTransState &trans_state, - ObIOBufferReader &client_buffer_reader, - ObDbConfigLogicDb &db_info, - bool &need_wait_callback) +int ObProxyShardUtils::handle_shard_request(ObMysqlClientSession &client_session, + ObMysqlTransact::ObTransState &trans_state, + ObIOBufferReader &client_buffer_reader, + ObDbConfigLogicDb &logic_db_info) { int ret = OB_SUCCESS; + ObClientSessionInfo &session_info = client_session.get_session_info(); session_info.set_enable_reset_db(false); ObProxyMysqlRequest &client_request = trans_state.trans_info_.client_request_; - ObSqlParseResult &parse_result = client_request.get_parse_result(); - ObString table_name = client_request.get_parse_result().get_origin_table_name(); - if (parse_result.is_ddl_stmt()) { - const ObString runtime_env = get_global_proxy_config().runtime_env.str(); - if (0 == runtime_env.case_compare(OB_PROXY_DBP_RUNTIME_ENV)) { - if (OB_FAIL(handle_ddl_request(sm, client_session, trans_state, db_info, need_wait_callback))) { - LOG_WARN("fail to handle ddl request", K(ret)); + ObSqlParseResult &origin_parse_result = client_request.get_parse_result(); + ObString first_table_name = origin_parse_result.get_origin_table_name(); + ObString origin_sql = client_request.get_sql();//should not use get_parse_sql() + ObSqlString new_sql; + ObSEArray sql_array; + ObArenaAllocator &allocator = origin_parse_result.allocator_; + char * multi_sql_buf = NULL; + int64_t es_index = OBPROXY_MAX_DBMESH_ID; + int64_t group_index = OBPROXY_MAX_DBMESH_ID; + int64_t last_es_index = OBPROXY_MAX_DBMESH_ID; + int64_t last_group_index = OBPROXY_MAX_DBMESH_ID; + bool is_scan_all = false; + + if (OB_FAIL(ObProxySqlParser::split_multiple_stmt(origin_sql, sql_array))) { + LOG_WARN("fail to split sql", K(ret)); + } else if (OB_UNLIKELY(sql_array.count() <= 0)){ + ret = OB_ERR_PARSER_SYNTAX; + LOG_WARN("fail to split sql and the sql num is wrong", K(ret)); + } else if (OB_UNLIKELY((sql_array.count() > 1) + && OB_FAIL(ObProxySqlParser::preprocess_multi_stmt(allocator, + multi_sql_buf, + origin_sql.length(), + sql_array)))) { + LOG_WARN("fail to preprocess multi stmt", K(ret)); + } else { + bool is_multi_stmt = sql_array.count() > 1; + ObSqlParseResult parse_result; + ObSqlParseResult* real_parse_result = NULL; + ObProxySqlParser sql_parser; + for (int64_t i = 0; OB_SUCC(ret) && i < sql_array.count(); ++i) { + const ObString& sql = sql_array.at(i); + if (0 == i) { + real_parse_result = &origin_parse_result; + } else if (OB_FAIL(sql_parser.parse_sql(ObProxyMysqlRequest::get_parse_sql(sql), + NORMAL_PARSE_MODE/*parse_mode*/, parse_result, + false/*use_lower_case_name*/, + static_cast(client_session.get_session_info().get_collation_connection()), + false/*drop_origin_db_table_name*/, + true /*is sharding user*/))) { + LOG_WARN("fail to handle single shard request for single sql", K(ret), K(sql)); + } else { + real_parse_result = &parse_result; } - } else { - ret = OB_NOT_SUPPORTED; - LOG_WARN("ddl stmt is unsupported for sharding table", K(ret)); - } - } else if (parse_result.is_show_tables_stmt() - || parse_result.is_show_full_tables_stmt() - || parse_result.is_show_table_status_stmt() - || (table_name.empty() && !parse_result.is_dml_stmt())) { - //do nothing - } else if (table_name.empty()) { - // keep compatible, skip - } else if (parse_result.is_multi_stmt()) { - ret = OB_NOT_SUPPORTED; - LOG_WARN("multi stmt is unsupported for sharding table", "stmt type", parse_result.get_stmt_type(), K(ret)); + + if (OB_SUCC(ret)) { + if (OB_UNLIKELY(real_parse_result->is_invalid_stmt() && real_parse_result->has_shard_comment())) { + ret = OB_ERR_PARSER_SYNTAX; + LOG_WARN("fail to parse shard sql with shard comment","sql", client_request.get_sql(), K(ret)); + } else if (OB_UNLIKELY(is_multi_stmt && ObProxyShardUtils::is_unsupport_type_in_multi_stmt(*real_parse_result))) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("unsupport type in multi stmt", K(ret), K(sql)); + } else if (OB_FAIL(do_handle_shard_request(client_session, trans_state, logic_db_info, sql, new_sql, *real_parse_result, + es_index, group_index, last_es_index, is_scan_all))) { + LOG_WARN("fail to handle single shard request for single sql", K(ret), K(sql), K(new_sql)); + } else if (OB_UNLIKELY((i > 0) && ((es_index != last_es_index) || (group_index != last_group_index)))) { + ret = OB_ERR_DISTRIBUTED_NOT_SUPPORTED; + LOG_WARN("different elastic index or group index for multi stmt is not supported", K(es_index), K(last_es_index), K(group_index), + K(last_group_index), K(sql), K(new_sql), K(ret)); + } else if (OB_UNLIKELY(is_multi_stmt && is_scan_all)) { + ret = OB_ERR_DISTRIBUTED_NOT_SUPPORTED; + LOG_WARN("scan all sql in multi stmt is not supported", K(sql), K(new_sql), K(ret)); + } else { + last_es_index = es_index; + last_group_index = group_index; + if (i > 0) { + real_parse_result->reset(); + } + } + } + } + + if (OB_SUCC(ret)) { + if (is_scan_all) { + if (OB_FAIL(handle_scan_all_real_info(logic_db_info, client_session, trans_state, first_table_name))) { + LOG_WARN("fail to handle scan all real info", K(first_table_name), K(ret)); + } + } else { + if (OB_FAIL(build_shard_request_packet(session_info, client_request, client_buffer_reader, new_sql.string()))) { + LOG_WARN("fail to build sharding request packet", K(new_sql), K(ret)); + } + } + } + } + + if(NULL != multi_sql_buf) { + allocator.free(multi_sql_buf); + } + + return ret; +} + +int ObProxyShardUtils::do_handle_shard_request(ObMysqlClientSession &client_session, + ObMysqlTransact::ObTransState &trans_state, + ObDbConfigLogicDb &db_info, + const ObString& sql, + ObSqlString& new_sql, + ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index, + const int64_t last_es_index, + bool& is_scan_all) +{ + int ret = OB_SUCCESS; + + ObString table_name = parse_result.get_origin_table_name(); + if (OB_UNLIKELY(is_unsupport_type_in_multi_stmt(parse_result) + || table_name.empty())) { + // Let it go for now, keep compatible + new_sql.append(sql); } else if (parse_result.is_show_stmt() || parse_result.is_desc_table_stmt()) { - if (OB_FAIL(handle_other_request(client_session, trans_state, - client_buffer_reader, table_name, db_info))) { - LOG_WARN("fail to handle other request", K(ret), K(session_info), K(table_name)); + if (OB_FAIL(handle_other_request(client_session, trans_state, table_name, db_info, + sql, new_sql, parse_result, es_index, group_index))) { + LOG_WARN("fail to handle other request", K(ret), K(sql), K(new_sql), K(table_name)); } } else if (parse_result.is_select_stmt()) { - if (OB_FAIL(handle_select_request(client_session, trans_state, - client_buffer_reader, table_name, db_info))) { - LOG_WARN("fail to handle select request", K(ret), K(session_info), K(table_name)); + if (OB_FAIL(handle_select_request(client_session, trans_state, table_name, db_info, + sql, new_sql, parse_result, es_index, group_index, last_es_index, is_scan_all))) { + LOG_WARN("fail to handle select request", K(ret), K(sql), K(new_sql), K(table_name)); } } else if (parse_result.is_dml_stmt()) { - if (OB_FAIL(handle_dml_request(client_session, trans_state, - client_buffer_reader, table_name, db_info))) { - LOG_WARN("fail to handle dml request", K(table_name), K(ret)); + if (OB_FAIL(handle_dml_request(client_session, trans_state, table_name, db_info, + sql, new_sql, parse_result, es_index, group_index, last_es_index))) { + LOG_WARN("fail to handle dml request", K(table_name), K(sql), K(new_sql), K(ret)); } } else { ret = OB_NOT_SUPPORTED; LOG_WARN("stmt is unsupported for sharding table", "stmt type", parse_result.get_stmt_type(), K(ret)); + } + + return ret; } + +int ObProxyShardUtils::build_shard_request_packet(ObClientSessionInfo &session_info, + ObProxyMysqlRequest &client_request, + ObIOBufferReader &client_buffer_reader, + const ObString& sql) +{ + int ret = OB_SUCCESS; + + // 4. push reader forward by consuming old buffer and write new sql into buffer + if (OB_FAIL(client_buffer_reader.consume_all())) { + LOG_WARN("fail to consume all", K(ret)); + } else { + ObMIOBuffer *writer = client_buffer_reader.mbuf_; + if (OB_ISNULL(writer)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null values ", K(writer), K(ret)); + // no need compress here, if server session support compress, it will compress later + } else if (OB_FAIL(ObMysqlRequestBuilder::build_mysql_request(*writer, obmysql::OB_MYSQL_COM_QUERY, sql, false, false))) { + LOG_WARN("fail to build_mysql_request", K(sql), K(ret)); + } else if (OB_FAIL(ObProxySessionInfoHandler::rewrite_query_req_by_sharding(session_info, client_request, client_buffer_reader))) { + LOG_WARN("fail to rewrite_query_req_by_sharding", K(ret)); + } + } + return ret; } @@ -1314,25 +1656,29 @@ int ObProxyShardUtils::handle_ddl_request(ObMysqlSM *sm, int ObProxyShardUtils::handle_other_request(ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, - ObIOBufferReader &client_buffer_reader, const ObString &table_name, - ObDbConfigLogicDb &db_info) + ObDbConfigLogicDb &db_info, + const ObString& sql, + ObSqlString& new_sql, + ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index) { int ret = OB_SUCCESS; ObClientSessionInfo &session_info = client_session.get_session_info(); - ObProxyMysqlRequest &client_request = trans_state.trans_info_.client_request_; char real_table_name[OB_MAX_TABLE_NAME_LENGTH]; char real_database_name[OB_MAX_DATABASE_NAME_LENGTH]; if (OB_FAIL(handle_other_real_info(db_info, client_session, trans_state, table_name, real_database_name, OB_MAX_DATABASE_NAME_LENGTH, - real_table_name, OB_MAX_TABLE_NAME_LENGTH))) { + real_table_name, OB_MAX_TABLE_NAME_LENGTH, + parse_result, es_index, group_index))) { LOG_WARN("fail to handle other real info", K(ret), K(session_info), K(table_name)); - } else if (OB_FAIL(rewrite_shard_request(session_info, client_request, client_buffer_reader, + } else if (OB_FAIL(rewrite_shard_request(session_info, parse_result, table_name, db_info.db_name_.config_string_, ObString::make_string(real_table_name), - ObString::make_string(real_database_name), false))) { + ObString::make_string(real_database_name), false, sql, new_sql))) { LOG_WARN("fail to rewrite shard request", K(ret), K(table_name), K(db_info.db_name_), K(real_table_name), K(real_database_name)); } @@ -1342,19 +1688,20 @@ int ObProxyShardUtils::handle_other_request(ObMysqlClientSession &client_session int ObProxyShardUtils::handle_select_request(ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, - ObIOBufferReader &client_buffer_reader, const ObString &table_name, - ObDbConfigLogicDb &db_info) + ObDbConfigLogicDb &db_info, + const ObString& sql, + ObSqlString& new_sql, + ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index, + const int64_t last_es_index, + bool& is_scan_all) { int ret = OB_SUCCESS; - ObProxyMysqlRequest &client_request = trans_state.trans_info_.client_request_; - ObSqlParseResult &parse_result = client_request.get_parse_result(); SqlFieldResult& sql_result = parse_result.get_sql_filed_result(); - - bool is_scan_all = false; ObProxySqlParser sql_parser; - ObString sql = client_request.get_parse_sql(); - if (OB_FAIL(sql_parser.parse_sql_by_obparser(sql, NORMAL_PARSE_MODE, parse_result, true))) { + if (OB_FAIL(sql_parser.parse_sql_by_obparser(ObProxyMysqlRequest::get_parse_sql(sql), NORMAL_PARSE_MODE, parse_result, true))) { LOG_WARN("parse_sql_by_obparser failed", K(ret), K(sql)); } else if (FALSE_IT(is_scan_all = need_scan_all(parse_result))) { // impossible @@ -1366,12 +1713,10 @@ int ObProxyShardUtils::handle_select_request(ObMysqlClientSession &client_sessio if (OB_SUCC(ret)) { if (is_scan_all) { - if (OB_FAIL(handle_scan_all_real_info(db_info, client_session, trans_state, table_name))) { - LOG_WARN("fail to handle scan all real info", K(table_name), K(ret)); - } + //handle scan all later } else { - if (OB_FAIL(handle_select_real_info(db_info, client_session, trans_state, - table_name, client_buffer_reader))) { + if (OB_FAIL(handle_dml_real_info(db_info, client_session, trans_state, table_name, + sql, new_sql, parse_result, es_index, group_index, last_es_index))) { LOG_WARN("fail to handle dml real info", K(table_name), K(ret)); } } @@ -1382,37 +1727,22 @@ int ObProxyShardUtils::handle_select_request(ObMysqlClientSession &client_sessio int ObProxyShardUtils::handle_dml_request(ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, - ObIOBufferReader &client_buffer_reader, const ObString &table_name, - ObDbConfigLogicDb &db_info) + ObDbConfigLogicDb &db_info, + const ObString& sql, + ObSqlString& new_sql, + ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index, + const int64_t last_es_index) { int ret = OB_SUCCESS; - ObClientSessionInfo &session_info = client_session.get_session_info(); - ObProxyMysqlRequest &client_request = trans_state.trans_info_.client_request_; - ObSqlParseResult &parse_result = client_request.get_parse_result(); - char real_table_name[OB_MAX_TABLE_NAME_LENGTH]; - char real_database_name[OB_MAX_DATABASE_NAME_LENGTH]; - ObProxySqlParser sql_parser; - ObString sql = client_request.get_parse_sql(); - if (OB_FAIL(sql_parser.parse_sql_by_obparser(sql, NORMAL_PARSE_MODE, parse_result, true))) { + if (OB_FAIL(sql_parser.parse_sql_by_obparser(ObProxyMysqlRequest::get_parse_sql(sql), NORMAL_PARSE_MODE, parse_result, true))) { LOG_WARN("parse_sql_by_obparser failed", K(ret), K(sql)); - } - if(OB_FAIL(ret)) { - // doing nothing - } else if ((parse_result.is_insert_stmt() || parse_result.is_replace_stmt() - || parse_result.is_update_stmt()) && parse_result.get_batch_insert_values_count() > 1) { - ret = OB_ERR_BATCH_INSERT_FOUND; - LOG_WARN("batch insert not supported in sharding sql", K(ret), K(parse_result.get_batch_insert_values_count())); - } else if (OB_FAIL(handle_dml_real_info(db_info, client_session, trans_state, table_name, - real_database_name, OB_MAX_DATABASE_NAME_LENGTH, - real_table_name, OB_MAX_TABLE_NAME_LENGTH))) { - LOG_WARN("fail to handle dml real info", K(ret), K(session_info), K(table_name)); - } else if (OB_FAIL(rewrite_shard_request(session_info, client_request, client_buffer_reader, - table_name, db_info.db_name_.config_string_, ObString::make_string(real_table_name), - ObString::make_string(real_database_name), false))) { - LOG_WARN("fail to rewrite shard request", K(ret), K(table_name), - K(db_info.db_name_), K(real_table_name), K(real_database_name)); + } else if (OB_FAIL(handle_dml_real_info(db_info, client_session, trans_state, table_name, + sql, new_sql, parse_result, es_index, group_index, last_es_index))) { + LOG_WARN("fail to handle dml real info", K(table_name), K(ret)); } return ret; @@ -1423,16 +1753,16 @@ int ObProxyShardUtils::check_topology(ObSqlParseResult &parse_result, { int ret = OB_SUCCESS; - ObProxySelectStmt *select_stmt = static_cast(parse_result.get_proxy_stmt()); - if (OB_ISNULL(select_stmt)) { + ObProxyDMLStmt *dml_stmt = static_cast(parse_result.get_proxy_stmt()); + if (OB_ISNULL(dml_stmt)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("select stmt is null, unexpected", K(ret)); } else { int64_t last_db_size = -1; int64_t last_tb_size = -1; - ObProxySelectStmt::ExprMap &table_exprs_map = select_stmt->get_table_exprs_map(); - ObProxySelectStmt::ExprMap::iterator iter = table_exprs_map.begin(); - ObProxySelectStmt::ExprMap::iterator end = table_exprs_map.end(); + ObProxyDMLStmt::ExprMap &table_exprs_map = dml_stmt->get_table_exprs_map(); + ObProxyDMLStmt::ExprMap::iterator iter = table_exprs_map.begin(); + ObProxyDMLStmt::ExprMap::iterator end = table_exprs_map.end(); for (; OB_SUCC(ret) && iter != end; iter++) { ObProxyExpr *expr = iter->second; @@ -1802,6 +2132,10 @@ int ObProxyShardUtils::get_db_version(const ObString &logic_tenant_name, } else { db_version = logic_db_info->get_version(); } + if (NULL != logic_db_info) { + logic_db_info->dec_ref(); + logic_db_info = NULL; + } return ret; } @@ -1869,26 +2203,27 @@ int ObProxyShardUtils::handle_other_real_info(ObDbConfigLogicDb &logic_db_info, ObMysqlTransact::ObTransState &trans_state, const ObString &table_name, char *real_database_name, int64_t db_name_len, - char *real_table_name, int64_t tb_name_len) + char *real_table_name, int64_t tb_name_len, + ObSqlParseResult &parse_result, + int64_t& es_id, int64_t& group_id) { int ret = OB_SUCCESS; ObShardConnector *shard_conn = NULL; ObClientSessionInfo &cs_info = client_session.get_session_info(); ObShardConnector *prev_shard_conn = cs_info.get_shard_connector(); - ObSqlParseResult &parse_result = trans_state.trans_info_.client_request_.get_parse_result(); ObShardRule *logic_tb_info = NULL; - int64_t group_id = OBPROXY_MAX_DBMESH_ID; + group_id = OBPROXY_MAX_DBMESH_ID; int64_t table_id = OBPROXY_MAX_DBMESH_ID; - int64_t es_id = OBPROXY_MAX_DBMESH_ID; + es_id = OBPROXY_MAX_DBMESH_ID; ObTestLoadType testload_type = TESTLOAD_NON; ObString hint_table; if (OB_ISNULL(prev_shard_conn)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("shard connector info is null", K(ret)); - } else if (OB_FAIL(get_shard_hint(logic_db_info, parse_result, + } else if (OB_FAIL(get_shard_hint(table_name, cs_info, logic_db_info, parse_result, group_id, table_id, es_id, hint_table, testload_type))) { LOG_WARN("fail to get shard hint", K(ret)); // get group_id @@ -1896,21 +2231,24 @@ int ObProxyShardUtils::handle_other_real_info(ObDbConfigLogicDb &logic_db_info, LOG_WARN("fail to get shard rule", K(table_name), K(ret)); } else { int64_t last_group_id = cs_info.get_group_id(); - ObString saved_database_name; cs_info.get_logic_database_name(saved_database_name); bool is_not_saved_database = saved_database_name != logic_db_info.db_name_.config_string_; - // need to re-select a shard_conn condition, and any one of the conditions can be satisfied - // 1. SQL comes with database, and it is different from the current logic library - // 2. The group id is specified in the hint, and it is different from the last time - // 3. No group_id is specified, nor did the last one (for example, switch the library) - // 4. If the last group_id is greater than the db_size of the table of this SQL - // (for example, the table of the previous SQL is group_{00-99}, the table of this SQL is group_00) - if (is_not_saved_database - || (group_id != OBPROXY_MAX_DBMESH_ID && group_id != last_group_id) - || last_group_id == OBPROXY_MAX_DBMESH_ID - || last_group_id >= logic_tb_info->db_size_) { + // If group_id is specified, check if it exceeds db_size and use it + if (group_id != OBPROXY_MAX_DBMESH_ID) { + if (group_id >= logic_tb_info->db_size_) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("sql with group hint and greater than db size", + "db_size", logic_tb_info->db_size_, K(group_id), K(ret)); + } + // If no group_id is specified, and the database accessed by the current SQL is the session database, the last_group_id is used + } else if (!is_not_saved_database && last_group_id < logic_tb_info->db_size_) { + group_id = last_group_id; + es_id = cs_info.get_es_id(); + } + + if (OB_SUCC(ret)) { ObShardTpo *shard_tpo = NULL; ObGroupCluster *gc_info = NULL; if (OB_FAIL(logic_db_info.get_shard_tpo(shard_tpo))) { @@ -1963,15 +2301,6 @@ int ObProxyShardUtils::handle_other_real_info(ObDbConfigLogicDb &logic_db_info, } } } - - //If it is the logic library on the current session, you can reuse this group_id next time - if (OB_SUCC(ret) && !is_not_saved_database) { - cs_info.set_group_id(group_id); - } - } else { - prev_shard_conn->inc_ref(); - shard_conn = prev_shard_conn; - group_id = last_group_id; } if (OB_SUCC(ret)) { @@ -1996,6 +2325,13 @@ int ObProxyShardUtils::handle_other_real_info(ObDbConfigLogicDb &logic_db_info, } } } + + //If it is a logic library on the current session, this group_id can be reused next time + if (OB_SUCC(ret) && !is_not_saved_database) { + cs_info.set_group_id(group_id); + cs_info.set_table_id(table_id); + cs_info.set_es_id(es_id); + } } if (NULL != shard_conn) { @@ -2020,11 +2356,11 @@ int ObProxyShardUtils::handle_scan_all_real_info(ObDbConfigLogicDb &logic_db_inf ObSEArray, 4> table_name_map_array; ObIAllocator *allocator = NULL; - ObProxySelectStmt *select_stmt = static_cast(parse_result.get_proxy_stmt()); - if (OB_ISNULL(select_stmt)) { + ObProxyDMLStmt *dml_stmt = static_cast(parse_result.get_proxy_stmt()); + if (OB_ISNULL(dml_stmt)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("select stmt is null, unexpected", K(ret)); - } else if (select_stmt->has_unsupport_expr_type()) { + LOG_WARN("dml stmt is null, unexpected", K(ret)); + } else if (dml_stmt->has_unsupport_expr_type()) { ret = OB_ERROR_UNSUPPORT_EXPR_TYPE; LOG_WARN("unsupport sql", K(ret)); } else if (OB_FAIL(check_topology(parse_result, logic_db_info))) { @@ -2040,17 +2376,17 @@ int ObProxyShardUtils::handle_scan_all_real_info(ObDbConfigLogicDb &logic_db_inf table_name_map_array))) { LOG_WARN("fail to handle sharding select real info", K(ret), K(table_name)); } else { - LOG_DEBUG("proxy stmt", K(select_stmt->get_stmt_type()), K(select_stmt->limit_offset_), K(select_stmt->limit_size_)); + LOG_DEBUG("proxy stmt", K(dml_stmt->get_stmt_type()), K(dml_stmt->limit_offset_), K(dml_stmt->limit_size_)); LOG_DEBUG("select expr"); - for (int64_t i = 0; i < select_stmt->select_exprs_.count(); i++) { - ObProxyExpr::print_proxy_expr(select_stmt->select_exprs_.at(i)); + for (int64_t i = 0; i < dml_stmt->select_exprs_.count(); i++) { + ObProxyExpr::print_proxy_expr(dml_stmt->select_exprs_.at(i)); } LOG_DEBUG("group by expr"); - for (int64_t i = 0; i < select_stmt->group_by_exprs_.count(); i++) { - ObProxyExpr::print_proxy_expr(select_stmt->group_by_exprs_.at(i)); + for (int64_t i = 0; i < dml_stmt->group_by_exprs_.count(); i++) { + ObProxyExpr::print_proxy_expr(dml_stmt->group_by_exprs_.at(i)); } - for (int64_t i = 0; i < select_stmt->order_by_exprs_.count(); i++) { - ObProxyOrderItem *order_expr = select_stmt->order_by_exprs_.at(i); + for (int64_t i = 0; i < dml_stmt->order_by_exprs_.count(); i++) { + ObProxyOrderItem *order_expr = dml_stmt->order_by_exprs_.at(i); LOG_DEBUG("order by expr", K(order_expr->order_direction_)); ObProxyExpr::print_proxy_expr(order_expr); } @@ -2071,11 +2407,16 @@ int ObProxyShardUtils::handle_scan_all_real_info(ObDbConfigLogicDb &logic_db_inf return ret; } -int ObProxyShardUtils::handle_select_real_info(ObDbConfigLogicDb &logic_db_info, - ObMysqlClientSession &client_session, - ObMysqlTransact::ObTransState &trans_state, - const ObString &table_name, - ObIOBufferReader &client_buffer_reader) +int ObProxyShardUtils::handle_dml_real_info(ObDbConfigLogicDb &logic_db_info, + ObMysqlClientSession &client_session, + ObMysqlTransact::ObTransState &trans_state, + const ObString &table_name, + const ObString& sql, + ObSqlString& new_sql, + ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index, + const int64_t last_es_index) { int ret = OB_SUCCESS; @@ -2083,14 +2424,12 @@ int ObProxyShardUtils::handle_select_real_info(ObDbConfigLogicDb &logic_db_info, ObClientSessionInfo &session_info = client_session.get_session_info(); ObShardConnector *prev_shard_conn = session_info.get_shard_connector(); - ObProxyMysqlRequest &client_request = trans_state.trans_info_.client_request_; - ObSqlParseResult &parse_result = client_request.get_parse_result(); SqlFieldResult &sql_result = parse_result.get_sql_filed_result(); - ObProxySelectStmt *select_stmt = dynamic_cast(parse_result.get_proxy_stmt()); + ObProxyDMLStmt *dml_stmt = dynamic_cast(parse_result.get_proxy_stmt()); - int64_t group_index = OBPROXY_MAX_DBMESH_ID; + group_index = OBPROXY_MAX_DBMESH_ID; int64_t tb_index = OBPROXY_MAX_DBMESH_ID; - int64_t es_index = OBPROXY_MAX_DBMESH_ID; + es_index = OBPROXY_MAX_DBMESH_ID; ObTestLoadType testload_type = TESTLOAD_NON; ObString hint_table; ObArenaAllocator allocator; @@ -2103,22 +2442,22 @@ int ObProxyShardUtils::handle_select_real_info(ObDbConfigLogicDb &logic_db_info, // read request weight bool is_read_stmt = ObProxyShardUtils::is_read_stmt(session_info, trans_state, parse_result); - if (OB_ISNULL(select_stmt)) { + if (OB_ISNULL(dml_stmt)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("select stmt is null, unexpected", K(ret)); + LOG_WARN("dml stmt is null, unexpected", K(ret)); } else if (OB_FAIL(table_name_map.create(OB_ALIAS_TABLE_MAP_MAX_BUCKET_NUM, ObModIds::OB_HASH_ALIAS_TABLE_MAP))) { LOG_WARN("fail to create table name map", K(ret)); - } else if (OB_FAIL(get_shard_hint(logic_db_info, parse_result, + } else if (OB_FAIL(get_shard_hint(table_name, session_info, logic_db_info, parse_result, group_index, tb_index, es_index, hint_table, testload_type))) { LOG_WARN("fail to get shard hint", K(ret)); } if (OB_SUCC(ret)) { - ObProxySelectStmt::ExprMap &table_exprs_map = select_stmt->get_table_exprs_map(); - ObProxySelectStmt::ExprMap::iterator iter = table_exprs_map.begin(); - ObProxySelectStmt::ExprMap::iterator end = table_exprs_map.end(); + ObProxyDMLStmt::ExprMap &table_exprs_map = dml_stmt->get_table_exprs_map(); + ObProxyDMLStmt::ExprMap::iterator iter = table_exprs_map.begin(); + ObProxyDMLStmt::ExprMap::iterator end = table_exprs_map.end(); if (!hint_table.empty() && table_exprs_map.size() > 1) { ret = OB_ERR_MORE_TABLES_WITH_TABLE_HINT; @@ -2127,7 +2466,7 @@ int ObProxyShardUtils::handle_select_real_info(ObDbConfigLogicDb &logic_db_info, real_database_name, OB_MAX_DATABASE_NAME_LENGTH, real_table_name, OB_MAX_TABLE_NAME_LENGTH, group_index, tb_index, es_index, - hint_table, testload_type, is_read_stmt))) { + hint_table, testload_type, is_read_stmt, last_es_index))) { LOG_WARN("fail to get real info", K(table_name), K(group_index), K(tb_index), K(es_index), K(hint_table), K(testload_type), K(is_read_stmt), K(ret)); } else if (OB_ISNULL(shard_conn) || OB_ISNULL(prev_shard_conn)) { @@ -2160,8 +2499,9 @@ int ObProxyShardUtils::handle_select_real_info(ObDbConfigLogicDb &logic_db_info, } if (OB_SUCC(ret)) { - if (OB_FAIL(rewrite_shard_select_request(session_info, client_request, client_buffer_reader, - table_name_map, ObString::make_string(real_database_name), false))) { + if (OB_FAIL(rewrite_shard_dml_request(sql, new_sql, parse_result, + session_info.is_oracle_mode(), table_name_map, + ObString::make_string(real_database_name), false))) { LOG_WARN("fail to rewrite shard request", K(real_database_name), K(ret)); } } @@ -2179,6 +2519,8 @@ int ObProxyShardUtils::handle_select_real_info(ObDbConfigLogicDb &logic_db_info, bool is_not_saved_database = saved_database_name != logic_db_info.db_name_.config_string_; if (!is_not_saved_database) { session_info.set_group_id(group_index); + session_info.set_table_id(tb_index); + session_info.set_es_id(es_index); } } @@ -2189,58 +2531,8 @@ int ObProxyShardUtils::handle_select_real_info(ObDbConfigLogicDb &logic_db_info, return ret; } -int ObProxyShardUtils::handle_dml_real_info(ObDbConfigLogicDb &logic_db_info, - ObMysqlClientSession &client_session, - ObMysqlTransact::ObTransState &trans_state, - const ObString &table_name, - char *real_database_name, int64_t db_name_len, - char *real_table_name, int64_t tb_name_len) -{ - int ret = OB_SUCCESS; - - ObShardConnector *shard_conn = NULL; - ObClientSessionInfo &session_info = client_session.get_session_info(); - ObShardConnector *prev_shard_conn = session_info.get_shard_connector(); - ObSqlParseResult &parse_result = trans_state.trans_info_.client_request_.get_parse_result(); - int64_t group_id = OBPROXY_MAX_DBMESH_ID; - - bool is_read_stmt = ObProxyShardUtils::is_read_stmt(session_info, trans_state, parse_result); - - if (OB_FAIL(get_real_info(logic_db_info, table_name, parse_result, shard_conn, - real_database_name, db_name_len, - real_table_name, tb_name_len, - &group_id, NULL, NULL, is_read_stmt))) { - LOG_WARN("fail to get real db and tb", K(table_name), K(ret)); - } else if (OB_ISNULL(shard_conn) || OB_ISNULL(prev_shard_conn)) { - ret = OB_EXPR_CALC_ERROR; - LOG_WARN("shard connector info or prev shard connector info is null", KP(shard_conn), - KP(prev_shard_conn), K(ret)); - } - - if (OB_SUCC(ret) && *prev_shard_conn != *shard_conn) { - if (OB_FAIL(change_connector(logic_db_info, client_session, trans_state, prev_shard_conn, shard_conn))) { - LOG_WARN("fail to change connector", KPC(prev_shard_conn), KPC(shard_conn), K(ret)); - } - } - - //There may be a database in SQL, only the logical library saved on the session can save the group_id, and it can be reused next time - if (OB_SUCC(ret)) { - ObString saved_database_name; - session_info.get_logic_database_name(saved_database_name); - bool is_not_saved_database = saved_database_name != logic_db_info.db_name_.config_string_; - if (!is_not_saved_database) { - session_info.set_group_id(group_id); - } - } - - if (NULL != shard_conn) { - shard_conn->dec_ref(); - shard_conn = NULL; - } - return ret; -} - -int ObProxyShardUtils::get_real_info(ObDbConfigLogicDb &logic_db_info, +int ObProxyShardUtils::get_real_info(ObClientSessionInfo &session_info, + ObDbConfigLogicDb &logic_db_info, const ObString &table_name, ObSqlParseResult &parse_result, ObShardConnector *&shard_conn, @@ -2255,7 +2547,7 @@ int ObProxyShardUtils::get_real_info(ObDbConfigLogicDb &logic_db_info, int64_t es_index = OBPROXY_MAX_DBMESH_ID; ObTestLoadType testload_type = TESTLOAD_NON; ObString hint_table; - if (OB_FAIL(get_shard_hint(logic_db_info, parse_result, + if (OB_FAIL(get_shard_hint(table_name, session_info, logic_db_info, parse_result, group_index, tb_index, es_index, hint_table, testload_type))) { LOG_WARN("fail to get shard hint", K(ret)); } else if (OB_FAIL(logic_db_info.get_real_info(table_name, parse_result, shard_conn, @@ -2286,6 +2578,7 @@ int ObProxyShardUtils::is_sharding_in_trans(ObClientSessionInfo &session_info, O { return 0 == session_info.get_cached_variables().get_autocommit() || trans_state.is_hold_start_trans_ + || trans_state.is_hold_xa_start_ || ObMysqlTransact::is_in_trans(trans_state); } @@ -2409,7 +2702,7 @@ int ObProxyShardUtils::handle_sharding_select_real_info(ObDbConfigLogicDb &logic bool is_read_stmt = ObProxyShardUtils::is_read_stmt(session_info, trans_state, parse_result); - if (OB_FAIL(get_shard_hint(logic_db_info, parse_result, + if (OB_FAIL(get_shard_hint(table_name, session_info, logic_db_info, parse_result, group_index, tb_index, es_index, hint_table, testload_type))) { LOG_WARN("fail to get shard hint", K(ret)); diff --git a/src/obproxy/proxy/shard/obproxy_shard_utils.h b/src/obproxy/proxy/shard/obproxy_shard_utils.h index 4cc3c5b47..78518138b 100644 --- a/src/obproxy/proxy/shard/obproxy_shard_utils.h +++ b/src/obproxy/proxy/shard/obproxy_shard_utils.h @@ -46,12 +46,13 @@ class ObProxyShardUtils static int get_db_version(const ObString &logic_tenant_name, const ObString &logic_database_name, ObString &db_version); - static bool is_special_db(ObMysqlTransact::ObTransState &s); + static bool is_special_db(obutils::ObSqlParseResult& parse_result); static int get_logic_db_info(ObMysqlTransact::ObTransState &s, ObClientSessionInfo &session_info, dbconfig::ObDbConfigLogicDb *&logic_db_info); - static int get_real_info(dbconfig::ObDbConfigLogicDb &logic_db_info, + static int get_real_info(ObClientSessionInfo &session_info, + dbconfig::ObDbConfigLogicDb &logic_db_info, const common::ObString &table_name, obutils::ObSqlParseResult &parse_result, dbconfig::ObShardConnector *&shard_conn, @@ -64,33 +65,62 @@ class ObProxyShardUtils static bool check_shard_authority(const dbconfig::ObShardUserPrivInfo &up_info, const obutils::ObSqlParseResult &parse_result); - static int get_shard_hint(dbconfig::ObDbConfigLogicDb &logic_db_info, + static int get_shard_hint(const ObString &table_name, + ObClientSessionInfo &session_info, + dbconfig::ObDbConfigLogicDb &logic_db_info, obutils::ObSqlParseResult &parse_result, int64_t &group_index, int64_t &tb_index, - int64_t &es_index, ObString &table_name, + int64_t &es_index, ObString &hint_table_name, dbconfig::ObTestLoadType &testload_type); + static int get_shard_hint(dbconfig::ObDbConfigLogicDb &logic_db_info, + obutils::ObSqlParseResult &parse_result, + int64_t &group_index, int64_t &tb_index, + int64_t &es_index, ObString &hint_table_name, + dbconfig::ObTestLoadType &testload_type, + bool &is_sticky_session); + static int check_shard_request(ObMysqlClientSession &client_session, obutils::ObSqlParseResult &parse_result, dbconfig::ObDbConfigLogicDb &logic_db_info); - static int handle_shard_request(ObMysqlSM *sm, - ObMysqlClientSession &client_session, - ObMysqlTransact::ObTransState &trans_state, - ObIOBufferReader &client_buffer_reader, - dbconfig::ObDbConfigLogicDb &db_info, - bool &need_wait_callback); + static int do_handle_shard_request(ObMysqlClientSession &client_session, + ObMysqlTransact::ObTransState &trans_state, + dbconfig::ObDbConfigLogicDb &db_info, + const ObString& sql, + ObSqlString& new_sql, + obutils::ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index, + const int64_t last_es_index, + bool& is_scan_all); + static int handle_shard_request(ObMysqlClientSession &client_session, + ObMysqlTransact::ObTransState &trans_state, + ObIOBufferReader &client_buffer_reader, + dbconfig::ObDbConfigLogicDb &db_info); + static int handle_ddl_request(ObMysqlSM *sm, + ObMysqlClientSession &client_session, + ObMysqlTransact::ObTransState &trans_state, + dbconfig::ObDbConfigLogicDb &db_info, + bool &need_wait_callback); static int do_handle_single_shard_request(ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, - ObIOBufferReader &client_buffer_reader, - dbconfig::ObDbConfigLogicDb &logic_db_info); - static int handle_single_shard_request(ObMysqlSM *sm, - ObMysqlClientSession &client_session, + dbconfig::ObDbConfigLogicDb &logic_db_info, + const ObString& sql, + ObSqlString& new_sql, + obutils::ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index, + const int64_t last_es_index); + static int handle_single_shard_request(ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, ObIOBufferReader &client_buffer_reader, - dbconfig::ObDbConfigLogicDb &logic_db_info, - bool &need_wait_callback); - static int build_error_packet(int err_code, bool &need_response_for_dml, ObMysqlTransact::ObTransState &trans_state, + dbconfig::ObDbConfigLogicDb &logic_db_info); + static int build_error_packet(int err_code, bool &need_response_for_dml, + ObMysqlTransact::ObTransState &trans_state, ObMysqlClientSession *client_session); + static int handle_information_schema_request(ObMysqlClientSession &client_session, + ObMysqlTransact::ObTransState &trans_state, + ObIOBufferReader &client_buffer_reader); static int handle_sharding_select_real_info(dbconfig::ObDbConfigLogicDb &logic_db_info, ObMysqlClientSession &client_session, @@ -108,13 +138,13 @@ class ObProxyShardUtils static int check_topology(obutils::ObSqlParseResult &parse_result, dbconfig::ObDbConfigLogicDb &db_info); - static int do_rewrite_shard_select_request(const ObString &sql, - obutils::ObSqlParseResult &parse_result, - bool is_oracle_mode, - const common::hash::ObHashMap &table_name_map, - const ObString &real_database_name, - bool is_single_shard_db_table, - common::ObSqlString &new_sql); + static int rewrite_shard_dml_request(const ObString &sql, + ObSqlString &new_sql, + obutils::ObSqlParseResult &parse_result, + bool is_oracle_mode, + const common::hash::ObHashMap &table_name_map, + const ObString &real_database_name, + bool is_single_shard_db_table); static int add_table_name_to_map(ObIAllocator &allocator, hash::ObHashMap &table_name_map, const ObString &table_name, const ObString &real_table_name); @@ -123,32 +153,42 @@ class ObProxyShardUtils static bool is_read_stmt(ObClientSessionInfo &session_info, ObMysqlTransact::ObTransState &trans_state, obutils::ObSqlParseResult &parse_result); + static bool is_unsupport_type_in_multi_stmt(obutils::ObSqlParseResult& parse_result); static int change_connector(dbconfig::ObDbConfigLogicDb &logic_db_info, ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, const dbconfig::ObShardConnector *prev_shard_conn, dbconfig::ObShardConnector *shard_conn); - - static int handle_ddl_request(ObMysqlSM *sm, - ObMysqlClientSession &client_session, - ObMysqlTransact::ObTransState &trans_state, - dbconfig::ObDbConfigLogicDb &db_info, - bool &need_wait_callback); static int handle_dml_request(ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, - ObIOBufferReader &client_buffer_reader, - const common::ObString &table_name, - dbconfig::ObDbConfigLogicDb &db_info); + const ObString &table_name, + dbconfig::ObDbConfigLogicDb &db_info, + const ObString& sql, + ObSqlString& new_sql, + obutils::ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index, + const int64_t last_es_index); static int handle_other_request(ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, - ObIOBufferReader &client_buffer_reader, - const common::ObString &table_name, - dbconfig::ObDbConfigLogicDb &db_info); + const ObString &table_name, + dbconfig::ObDbConfigLogicDb &db_info, + const ObString& sql, + ObSqlString& new_sql, + obutils::ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index); static int handle_select_request(ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, - ObIOBufferReader &client_buffer_reader, - const common::ObString &table_name, - dbconfig::ObDbConfigLogicDb &db_info); + const ObString &table_name, + dbconfig::ObDbConfigLogicDb &db_info, + const ObString& sql, + ObSqlString& new_sql, + obutils::ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index, + const int64_t last_es_index, + bool& is_scan_all); static int check_logic_database(ObMysqlTransact::ObTransState &trans_state, ObMysqlClientSession &client_session, const ObString &db_name); static void replace_oracle_table(ObSqlString &new_sql, const ObString &real_name, @@ -164,21 +204,21 @@ class ObProxyShardUtils const ObString &real_table_name, const ObString &real_database_name, bool is_oracle_mode, bool is_single_shard_db_table, ObSqlString &new_sql, int64_t ©_pos); + static int rewrite_shard_request_table_no_db(const char *sql_ptr, + int64_t table_pos, uint64_t table_len, + const ObString &real_table_name, + bool is_oracle_mode, bool is_single_shard_db_table, + ObSqlString &new_sql, int64_t ©_pos); static int rewrite_shard_request_hint_table(const char *sql_ptr, int64_t index_table_pos, uint64_t index_table_len, const ObString &real_table_name, bool is_oracle_mode, bool is_single_shard_db_table, ObSqlString &new_sql, int64_t ©_pos); static int rewrite_shard_request(ObClientSessionInfo &session_info, - ObProxyMysqlRequest &client_request, - ObIOBufferReader &client_buffer_reader, + obutils::ObSqlParseResult &parse_result, const ObString &table_name, const ObString &database_name, const ObString &real_table_name, const ObString &real_database_name, - bool is_single_shard_db_table); - static int rewrite_shard_select_request(ObClientSessionInfo &session_info, - ObProxyMysqlRequest &client_request, - ObIOBufferReader &client_buffer_reader, - const common::hash::ObHashMap &table_name_map, - const ObString &real_database_name, - bool is_single_shard_db_table); + bool is_single_shard_db_table, + const ObString& sql, + common::ObSqlString& new_sql); static int testload_check_obparser_node_is_valid(const ParseNode *root, const ObItemType &type); static int testload_rewrite_name_base_on_parser_node(common::ObSqlString &new_sql, const char *new_name, @@ -189,13 +229,13 @@ class ObProxyShardUtils static int testload_get_obparser_db_and_table_node(const ParseNode *root, ParseNode *&db_node, ParseNode *&table_node); - static int testload_check_and_rewrite_testload_request(ObClientSessionInfo &session_info, - ObProxyMysqlRequest &client_request, - ObIOBufferReader &client_buffer_reader, + static int testload_check_and_rewrite_testload_request(obutils::ObSqlParseResult &parse_result, bool is_single_shard_db_table, const ObString &hint_table, const ObString &real_database_name, - dbconfig::ObDbConfigLogicDb &logic_db_info); + dbconfig::ObDbConfigLogicDb &logic_db_info, + const ObString& sql, + common::ObSqlString& new_sql); static int testload_check_and_rewrite_testload_hint_index(common::ObSqlString &new_sql, const char *sql_ptr, int64_t sql_len, @@ -215,27 +255,33 @@ class ObProxyShardUtils ObMysqlTransact::ObTransState &trans_state, const ObString &table_name, char *real_database_name, int64_t db_name_len, - char *real_table_name, int64_t tb_name_len); - static int handle_dml_real_info(dbconfig::ObDbConfigLogicDb &logic_db_info, - ObMysqlClientSession &client_session, - ObMysqlTransact::ObTransState &trans_state, - const ObString &table_name, - char *real_database_name, int64_t db_name_len, - char *real_table_name, int64_t tb_name_len); + char *real_table_name, int64_t tb_name_len, + obutils::ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index); static int handle_scan_all_real_info(dbconfig::ObDbConfigLogicDb &logic_db_info, ObMysqlClientSession &client_session, ObMysqlTransact::ObTransState &trans_state, const ObString &table_name); - static int handle_select_real_info(dbconfig::ObDbConfigLogicDb &logic_db_info, - ObMysqlClientSession &client_session, - ObMysqlTransact::ObTransState &trans_state, - const ObString &table_name, - ObIOBufferReader &client_buffer_reader); + static int handle_dml_real_info(dbconfig::ObDbConfigLogicDb &logic_db_info, + ObMysqlClientSession &client_session, + ObMysqlTransact::ObTransState &trans_state, + const ObString &table_name, + const ObString& sql, + ObSqlString& new_sql, + obutils::ObSqlParseResult &parse_result, + int64_t& es_index, + int64_t& group_index, + const int64_t last_es_index); static int handle_sys_read_consitency_prop(dbconfig::ObDbConfigLogicDb &logic_db_info, dbconfig::ObShardConnector& shard_conn, ObClientSessionInfo &session_info); static int is_sharding_in_trans(ObClientSessionInfo &session_info, ObMysqlTransact::ObTransState &trans_state); + static int build_shard_request_packet(ObClientSessionInfo &session_info, + ObProxyMysqlRequest &client_request, + ObIOBufferReader &client_buffer_reader, + const ObString& sql); }; diff --git a/src/obproxy/stat/ob_mysql_stats.cpp b/src/obproxy/stat/ob_mysql_stats.cpp index 0b096d7a7..eb8161e63 100644 --- a/src/obproxy/stat/ob_mysql_stats.cpp +++ b/src/obproxy/stat/ob_mysql_stats.cpp @@ -272,6 +272,9 @@ int init_mysql_stats() MYSQL_REGISTER_RAW_STAT(mysql_rsb, RECT_PROCESS, "send_changed_session_vars_requests", RECD_INT, SEND_CHANGED_SESSION_VARS_REQUESTS, SYNC_SUM, RECP_NULL); + MYSQL_REGISTER_RAW_STAT(mysql_rsb, RECT_PROCESS, "send_changed_session_user_vars_requests", + RECD_INT, SEND_CHANGED_SESSION_USER_VARS_REQUESTS, SYNC_SUM, RECP_NULL); + MYSQL_REGISTER_RAW_STAT(mysql_rsb, RECT_PROCESS, "send_last_insert_id_requests", RECD_INT, SEND_LAST_INSERT_ID_REQUESTS, SYNC_SUM, RECP_PERSISTENT); @@ -334,6 +337,9 @@ int init_mysql_stats() MYSQL_REGISTER_RAW_STAT(mysql_rsb, RECT_PROCESS, "total_send_changed_session_vars_time", RECD_INT, TOTAL_SEND_CHANGED_SESSION_VARS_TIME, SYNC_SUM, RECP_NULL); + MYSQL_REGISTER_RAW_STAT(mysql_rsb, RECT_PROCESS, "total_send_changed_session_user_vars_time", + RECD_INT, TOTAL_SEND_CHANGED_SESSION_USER_VARS_TIME, SYNC_SUM, RECP_NULL); + MYSQL_REGISTER_RAW_STAT(mysql_rsb, RECT_PROCESS, "total_send_last_insert_id_time", RECD_INT, TOTAL_SEND_LAST_INSERT_ID_TIME, SYNC_SUM, RECP_NULL); diff --git a/src/obproxy/stat/ob_mysql_stats.h b/src/obproxy/stat/ob_mysql_stats.h index 99c6b17a5..6dd867966 100644 --- a/src/obproxy/stat/ob_mysql_stats.h +++ b/src/obproxy/stat/ob_mysql_stats.h @@ -60,8 +60,10 @@ enum ObMysqlStats TOTAL_SEND_ALL_SESSION_VARS_TIME, TOTAL_SEND_USE_DATABASE_TIME, TOTAL_SEND_CHANGED_SESSION_VARS_TIME, + TOTAL_SEND_CHANGED_SESSION_USER_VARS_TIME, TOTAL_SEND_LAST_INSERT_ID_TIME, TOTAL_SEND_START_TRANS_TIME, + TOTAL_SEND_XA_START_TIME, TOTAL_PL_LOOKUP_TIME, TOTAL_CONGESTION_CONTROL_LOOKUP_TIME, @@ -132,8 +134,10 @@ enum ObMysqlStats SEND_ALL_SESSION_VARS_REQUESTS, SEND_USE_DATABASE_REQUESTS, SEND_CHANGED_SESSION_VARS_REQUESTS, + SEND_CHANGED_SESSION_USER_VARS_REQUESTS, SEND_LAST_INSERT_ID_REQUESTS, SEND_START_TRANS_REQUESTS, + SEND_XA_START_REQUESTS, VIP_TO_TENANT_CACHE_HIT, VIP_TO_TENANT_CACHE_MISS, diff --git a/src/obproxy/stat/ob_stat_processor.cpp b/src/obproxy/stat/ob_stat_processor.cpp index da5da8683..f1341f36e 100644 --- a/src/obproxy/stat/ob_stat_processor.cpp +++ b/src/obproxy/stat/ob_stat_processor.cpp @@ -92,7 +92,7 @@ int ObSessionStatTableSync::init(ObMysqlProxy &mysql_proxy, const char *cluster_ { int ret = OB_SUCCESS; ObAddr addr; - char ip_str[OB_IP_STR_BUFF]; + char ip_str[MAX_IP_ADDR_LENGTH]; ip_str[0] = '\0'; if (OB_ISNULL(cluster_name) @@ -101,7 +101,7 @@ int ObSessionStatTableSync::init(ObMysqlProxy &mysql_proxy, const char *cluster_ LOG_WARN("invalid parameter", K(cluster_name), K(stats), K(stat_names), K(ret)); } else if (OB_FAIL(ObProxyTableProcessorUtils::get_proxy_local_addr(addr))) { LOG_WARN("fail to get proxy local addr", K(addr), K(ret)); - } else if (!addr.ip_to_string(ip_str, OB_IP_STR_BUFF)) { + } else if (!addr.ip_to_string(ip_str, MAX_IP_ADDR_LENGTH)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to covert ip to string", K(addr), K(ret)); } else if (OB_FAIL(sql_.append_fmt(ObStatProcessor::INSERT_PROXY_STAT_SQL_HEAD, diff --git a/src/obproxy/stat/ob_stat_processor.h b/src/obproxy/stat/ob_stat_processor.h index 7d90c9ad4..c5d39815d 100644 --- a/src/obproxy/stat/ob_stat_processor.h +++ b/src/obproxy/stat/ob_stat_processor.h @@ -586,7 +586,7 @@ class ObStatProcessor ASLL(ObRecRawStatBlock, link_) all_blocks_; - char proxy_ip_[common::OB_IP_STR_BUFF]; // ip primary key + char proxy_ip_[common::MAX_IP_ADDR_LENGTH]; // ip primary key int32_t proxy_port_; // port primary key DISALLOW_COPY_AND_ASSIGN(ObStatProcessor); }; diff --git a/src/obproxy/utils/Makemodule.am b/src/obproxy/utils/Makemodule.am index 747c60513..72841d3f7 100644 --- a/src/obproxy/utils/Makemodule.am +++ b/src/obproxy/utils/Makemodule.am @@ -23,6 +23,8 @@ obproxy/utils/ob_cpu_affinity.cpp\ obproxy/utils/ob_proxy_blowfish.h\ obproxy/utils/ob_proxy_blowfish.cpp\ obproxy/utils/ob_proxy_monitor_utils.h\ -obproxy/utils/ob_proxy_monitor_utils.cpp +obproxy/utils/ob_proxy_monitor_utils.cpp\ +obproxy/utils/ob_target_db_server.h\ +obproxy/utils/ob_target_db_server.cpp utils_sources:= ${utils_common_sources} diff --git a/src/obproxy/utils/ob_layout.cpp b/src/obproxy/utils/ob_layout.cpp index d022801f1..a1be2ef82 100644 --- a/src/obproxy/utils/ob_layout.cpp +++ b/src/obproxy/utils/ob_layout.cpp @@ -11,8 +11,11 @@ */ #define USING_LOG_PREFIX PROXY -#include "utils/ob_layout.h" #include +#include "utils/ob_layout.h" +#include "ob_proxy_init.h" + +#define UNIX_PATH_LENGTH_MAX (sizeof(struct sockaddr_un) - sizeof(sa_family_t)) using namespace oceanbase::common; using namespace oceanbase::obproxy::event; @@ -22,6 +25,9 @@ namespace oceanbase namespace obproxy { +static const char* obproxy_domain = "obproxy.domain"; +static const char* obproxy_dir = "./.obproxy"; + ObLayout &get_global_layout() { static ObLayout g_layout; @@ -30,7 +36,8 @@ ObLayout &get_global_layout() ObLayout::ObLayout() : is_inited_(false), prefix_(NULL), bin_dir_(NULL), etc_dir_(NULL), - log_dir_(NULL), conf_dir_(NULL), control_config_dir_(NULL), dbconfig_dir_(NULL) + log_dir_(NULL), conf_dir_(NULL), control_config_dir_(NULL), + dbconfig_dir_(NULL), unix_domain_path_(NULL) { } @@ -60,6 +67,8 @@ int ObLayout::init(const char *start_cmd) MPRINT("fail to init proxy bin dir, ret=%d", ret); } else if (OB_FAIL(init_dir_prefix(cwd))) { MPRINT("fail to init proxy dir prefix, ret=%d", ret); + } else if (RUN_MODE_CLIENT == g_run_mode && OB_FAIL(handle_client_dirs())) { + MPRINT("fail to construct client dirs, ret=%d", ret); } else if (OB_FAIL(construct_dirs())) { MPRINT("fail to construct dirs, ret=%d", ret); } else { @@ -168,6 +177,42 @@ int ObLayout::init_bin_dir(const char *cwd, const char *start_cmd) } int ObLayout::init_dir_prefix(const char *cwd) +{ + int ret = OB_SUCCESS; + if (RUN_MODE_PROXY == g_run_mode) { + if (OB_FAIL(init_dir_prefix_proxy_mode(cwd))) { + LOG_WARN("init dir prefix proxy mode failed", K(ret)); + } + } else if (RUN_MODE_CLIENT == g_run_mode) { + if (OB_FAIL(init_dir_prefix_client_mode())) { + LOG_WARN("init_dir_prefix_client_mode", K(ret)); + } + } + + return ret; +} + +int ObLayout::init_dir_prefix_client_mode() +{ + int ret = OB_SUCCESS; + int64_t prefix_len = 0; + + prefix_len = strlen(obproxy_dir); + + if (OB_SUCC(ret)) { + if (OB_ISNULL(prefix_ = static_cast(allocator_.alloc(prefix_len + 1)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + MPRINT("fail to alloc memeory, prefix_len=%ld, ret=%d", prefix_len, ret); + } else { + MEMCPY(prefix_, obproxy_dir, prefix_len); + prefix_[prefix_len] = '\0'; + } + } + + return ret; +} + +int ObLayout::init_dir_prefix_proxy_mode(const char *cwd) { int ret = OB_SUCCESS; char *env_path = NULL; @@ -290,5 +335,56 @@ int ObLayout::construct_single_dir(const char *sub_dir, char *&full_path) return ret; } +int ObLayout::handle_client_dirs() +{ + int ret = OB_SUCCESS; + if (OB_FAIL(construct_client_obproxy_dirs())) { + LOG_WARN("construct_client_obproxy_dirs failed", K(ret)); + } else if (OB_FAIL(remove_unix_domain())) { + LOG_WARN("remove unix domain failed", K(ret)); + } + + return ret; +} + +int ObLayout::construct_client_obproxy_dirs() +{ + int ret = OB_SUCCESS; + char *actual_path = NULL; + // Create the .obproxy directory + if (OB_FAIL(extract_actual_path(prefix_, actual_path))) { + MPRINT("fail to extract_actual_path, prefix_path=%s, ret=%d", prefix_, ret); + } else if (OB_FAIL(FileDirectoryUtils::create_full_path(actual_path))) { + MPRINT("fail to create_full_path, actual_path=%s, ret=%d", actual_path, ret); + } + + if (NULL != actual_path && prefix_ != actual_path) { + allocator_.free(actual_path); + } + actual_path = NULL; + + + return ret; +} + +int ObLayout::remove_unix_domain() +{ + int ret = OB_SUCCESS; + char *actual_path = NULL; + + if (OB_FAIL(merge_file_path(prefix_, obproxy_domain, allocator_, unix_domain_path_))) { + MPRINT("fail to merge file path, sub_dir=%s, ret=%d", obproxy_domain, ret); + } else if (OB_FAIL(extract_actual_path(unix_domain_path_, actual_path))) { + MPRINT("fail to extract_actual_path, full_path=%s, ret=%d", unix_domain_path_, ret); + } else { + remove(actual_path); + if (NULL != actual_path && unix_domain_path_ != actual_path) { + allocator_.free(actual_path); + } + actual_path = NULL; + } + return ret; +} + }//end of namespace obproxy }//end of namespace oceanbase diff --git a/src/obproxy/utils/ob_layout.h b/src/obproxy/utils/ob_layout.h index beb15a3c5..527a97f96 100644 --- a/src/obproxy/utils/ob_layout.h +++ b/src/obproxy/utils/ob_layout.h @@ -36,14 +36,20 @@ class ObLayout const char *get_control_config_dir() const { return control_config_dir_; } const char *get_dbconfig_dir() const { return dbconfig_dir_; } const char *get_proxy_root_dir() const { return prefix_; } + const char *get_unix_domain_path() const { return unix_domain_path_; } static int merge_file_path(const char *root, const char *file, common::ObIAllocator &allocator, char *&buf); private: int init_bin_dir(const char *cwd, const char *start_cmd); int init_dir_prefix(const char *cwd); + int init_dir_prefix_proxy_mode(const char *cwd); + int init_dir_prefix_client_mode(); int construct_dirs(); int construct_single_dir(const char *sub_dir, char *&full_path); int extract_actual_path(const char * const full_path, char *&actual_path); + int handle_client_dirs(); + int construct_client_obproxy_dirs(); + int remove_unix_domain(); private: bool is_inited_; @@ -54,6 +60,7 @@ class ObLayout char *conf_dir_; char *control_config_dir_; char *dbconfig_dir_; + char *unix_domain_path_; event::ObFixedArenaAllocator allocator_; }; diff --git a/src/obproxy/utils/ob_proxy_hot_upgrader.cpp b/src/obproxy/utils/ob_proxy_hot_upgrader.cpp index 98fb1e944..600e97515 100644 --- a/src/obproxy/utils/ob_proxy_hot_upgrader.cpp +++ b/src/obproxy/utils/ob_proxy_hot_upgrader.cpp @@ -14,6 +14,7 @@ #include "utils/ob_proxy_hot_upgrader.h" #include "iocore/eventsystem/ob_event_processor.h" +#include "ob_proxy_init.h" using namespace oceanbase::common; using namespace oceanbase::obproxy::event; @@ -28,7 +29,8 @@ ObHotUpgraderInfo g_hot_upgrade_info; void ObHotUpgraderInfo::reset() { - fd_ = OB_INVALID_INDEX; + ipv4_fd_ = OB_INVALID_INDEX; + ipv6_fd_ = OB_INVALID_INDEX; received_sig_ = OB_INVALID_INDEX; sub_pid_ = OB_INVALID_INDEX; rc_status_ = RCS_NONE; @@ -67,9 +69,9 @@ DEF_TO_STRING(ObHotUpgraderInfo) { int64_t pos = 0; J_OBJ_START(); - J_KV(K_(is_inherited), K_(upgrade_version), K_(need_conn_accept), K_(user_rejected), K_(fd), - K_(received_sig), K_(sub_pid), K_(graceful_exit_end_time), K_(graceful_exit_start_time), - K_(active_client_vc_count), K_(local_addr), + J_KV(K_(is_inherited), K_(upgrade_version), K_(need_conn_accept), K_(user_rejected), K_(ipv4_fd), + K_(ipv6_fd), K_(received_sig), K_(sub_pid), K_(graceful_exit_end_time), + K_(graceful_exit_start_time), K_(active_client_vc_count), K_(local_addr), "rc_status", get_rc_status_string(rc_status_), "hu_cmd", get_cmd_string(cmd_), "state", get_state_string(state_), diff --git a/src/obproxy/utils/ob_proxy_hot_upgrader.h b/src/obproxy/utils/ob_proxy_hot_upgrader.h index 95398a390..cbc148877 100644 --- a/src/obproxy/utils/ob_proxy_hot_upgrader.h +++ b/src/obproxy/utils/ob_proxy_hot_upgrader.h @@ -20,7 +20,8 @@ namespace oceanbase { namespace obproxy { -#define OBPROXY_INHERITED_FD "OBPROXY_INHERITED_FD" +#define OBPROXY_INHERITED_IPV4_FD "OBPROXY_INHERITED_FD" +#define OBPROXY_INHERITED_IPV6_FD "OBPROXY_INHERITED_IPV6_FD" extern volatile int g_proxy_fatal_errcode; enum ObReloadConfigStatus @@ -196,7 +197,8 @@ class ObHotUpgraderInfo static const int64_t MAX_RESTART_BUF_SIZE = 64; static const int64_t OB_MAX_INHERITED_ARGC = 4; - int fd_; // listen fd, which to be passed to sub process + int ipv4_fd_; // listen fd, which to be passed to sub process + int ipv6_fd_; int received_sig_; ObReloadConfigStatus rc_status_; // identify the current status for reload config volatile pid_t sub_pid_; // sub process pid if fork succeed diff --git a/src/obproxy/utils/ob_proxy_lib.h b/src/obproxy/utils/ob_proxy_lib.h index 01af9b92e..987686735 100644 --- a/src/obproxy/utils/ob_proxy_lib.h +++ b/src/obproxy/utils/ob_proxy_lib.h @@ -200,6 +200,7 @@ static const uint64_t OBPROXY_DEFAULT_CAPABILITY_FLAG = | OB_CAP_PROXY_SESSION_SYNC | OB_CAP_PROXY_FULL_LINK_TRACING | OB_CAP_PROXY_NEW_EXTRA_INFO + | OB_CAP_PROXY_SESSION_VAR_SYNC ); #define OBPROXY_SYS_ERRNO_START -10000 diff --git a/src/obproxy/utils/ob_proxy_table_define.cpp b/src/obproxy/utils/ob_proxy_table_define.cpp index e98d559c0..4cd0107f1 100644 --- a/src/obproxy/utils/ob_proxy_table_define.cpp +++ b/src/obproxy/utils/ob_proxy_table_define.cpp @@ -98,11 +98,15 @@ const char *ObProxyTableInfo::PROXY_VIP_TENANT_VERSION_NAME = "o const char *ObProxyTableInfo::READ_ONLY_USERNAME_USER = "proxyro"; const char *ObProxyTableInfo::READ_ONLY_USERNAME = "proxyro@sys"; const char *ObProxyTableInfo::READ_ONLY_DATABASE = "oceanbase"; +const char *ObProxyTableInfo::OBSERVER_SYS_PASSWORD = "observer_sys_password"; +const char *ObProxyTableInfo::OBSERVER_SYS_PASSWORD1 = "observer_sys_password1"; const char *ObProxyTableInfo::TEST_MODE_USERNAME = "root@sys"; const char *ObProxyTableInfo::TEST_MODE_PASSWORD = ""; const char *ObProxyTableInfo::TEST_MODE_DATABASE = "oceanbase"; +const char *ObProxyTableInfo::DETECT_USERNAME_USER = "detect_user"; + const ObString ObProxyTableInfo::PROXY_ALL_PROXY_HEADER = ObString::make_string("all_proxy"); const ObString ObProxyTableInfo::PROXY_CONFIG_VERSION_NAME = ObString::make_string(".config_version"); const ObString ObProxyTableInfo::PROXY_UPGRADE_SWITCH_NAME = ObString::make_string(".upgrade_switch"); @@ -132,7 +136,7 @@ int ObProxyTableInfo::get_create_proxy_table_sql(char *buf, const int64_t len) } else { int64_t w_len = snprintf(buf, len, CREATE_PROXY_TABLE_SQL, PROXY_INFO_TABLE_NAME, - OB_IP_STR_BUFF, // ip + MAX_IP_ADDR_LENGTH, // ip OB_MAX_APP_NAME_LENGTH, // app_name OB_MAX_PROXY_BINARY_VERSION_LEN, // binary_version OB_MAX_UNAME_INFO_LEN, // system_info @@ -239,7 +243,7 @@ int ObProxyTableInfo::get_create_proxy_vip_tenant_table_sql(char *buf, const int } else { int64_t w_len = snprintf(buf, len, CREATE_PROXY_VIP_TENANT_TABLE_SQL, PROXY_VIP_TENANT_TABLE_NAME, // table name - OB_IP_STR_BUFF, // vip + MAX_IP_ADDR_LENGTH, // vip OB_MAX_TENANT_NAME_LENGTH, // tenant_name length OB_PROXY_MAX_CLUSTER_NAME_LENGTH, // cluster_name length OB_MAX_CONFIG_INFO_LEN // info length diff --git a/src/obproxy/utils/ob_proxy_table_define.h b/src/obproxy/utils/ob_proxy_table_define.h index f76915605..b0cfab63b 100644 --- a/src/obproxy/utils/ob_proxy_table_define.h +++ b/src/obproxy/utils/ob_proxy_table_define.h @@ -67,10 +67,16 @@ class ObProxyTableInfo static const char *READ_ONLY_USERNAME_USER; static const char *READ_ONLY_USERNAME; static const char *READ_ONLY_DATABASE; + static const char *READ_ONLY_PASSWD_STAGED1; + + static const char *OBSERVER_SYS_PASSWORD; + static const char *OBSERVER_SYS_PASSWORD1; static const char *TEST_MODE_USERNAME; static const char *TEST_MODE_PASSWORD; static const char *TEST_MODE_DATABASE; + + static const char *DETECT_USERNAME_USER; }; } // end of namespace obproxy diff --git a/src/obproxy/utils/ob_proxy_utils.cpp b/src/obproxy/utils/ob_proxy_utils.cpp index b4e624e1d..615bac67a 100644 --- a/src/obproxy/utils/ob_proxy_utils.cpp +++ b/src/obproxy/utils/ob_proxy_utils.cpp @@ -344,5 +344,39 @@ int paste_tenant_and_cluster_name(const ObString &tenant_name, const ObString &c return ret; } +// split str like 'val0,val1;val2;val3' to +// item: val0 val1 val2 val3 +// weight: 0 0 1 2 +int split_weight_group(ObString weight_group_str, + ObIArray &items, + ObIArray &weights) { + int ret = OB_SUCCESS; + int8_t weight = 0; + bool finish = false; + while (OB_SUCC(ret) && !weight_group_str.empty() && !finish) { + ObString group = weight_group_str.split_on(';'); + if (group.empty()) { + group = weight_group_str; + finish = true; + } + // split by ',' + bool group_finish = false; + while (OB_SUCC(ret) && !group.empty() && !group_finish) { + ObString item = group.split_on(','); + if (item.empty()) { + item = group; + group_finish = true; + } + if (OB_FAIL(items.push_back(item))) { + LOG_WARN("fail to push back item", K(item), K(ret)); + } else if (OB_FAIL(weights.push_back(weight))) { + LOG_WARN("fail to push back weight", K(weight), K(ret)); + } else { /* succ */} + } + weight++; + } + return ret; +} + } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/utils/ob_proxy_utils.h b/src/obproxy/utils/ob_proxy_utils.h index 300d7c9c3..62976d398 100644 --- a/src/obproxy/utils/ob_proxy_utils.h +++ b/src/obproxy/utils/ob_proxy_utils.h @@ -16,6 +16,7 @@ #include "common/ob_object.h" #include "lib/string/ob_fixed_length_string.h" #include "utils/ob_proxy_lib.h" +#include "iocore/net/ob_inet.h" namespace oceanbase { @@ -79,6 +80,12 @@ int convert_timestamp_to_version(int64_t time_us, char *buf, int64_t len); int paste_tenant_and_cluster_name(const common::ObString &tenant_name, const common::ObString &cluster_name, common::ObFixedLengthString &key_string); +// split str like val0,val1;val2;val3 into +// item: val0 val1 val2 val3 +// weight: 0 0 1 2 +int split_weight_group(common::ObString weight_group_str, + common::ObIArray &item, + common::ObIArray &weights); } // end of namespace obproxy } // end of namespace oceanbase diff --git a/src/obproxy/utils/ob_target_db_server.cpp b/src/obproxy/utils/ob_target_db_server.cpp new file mode 100644 index 000000000..8a0384d00 --- /dev/null +++ b/src/obproxy/utils/ob_target_db_server.cpp @@ -0,0 +1,147 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ +#define USING_LOG_PREFIX PROXY +#include "utils/ob_target_db_server.h" + + +namespace oceanbase +{ +namespace obproxy +{ +using namespace oceanbase::common; + +int ObTargetDbServer::init(const char* target_db_server_str, uint64_t target_db_server_str_len) +{ + int ret = OB_SUCCESS; + reset(); + if (OB_ISNULL(target_db_server_str)) { + ret = OB_INIT_FAIL; + LOG_WARN("fail to init target db server for NULL str", K(ret)); + } else if (target_db_server_str_len == 0) { + LOG_DEBUG("succ to init target db server with empty str"); + } else if (OB_ISNULL(target_db_server_buf_ = static_cast(op_fixed_mem_alloc(target_db_server_str_len + 1)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate mem for target db server", K(ret), K(target_db_server_str_len)); + } else { + target_db_server_buf_len_ = target_db_server_str_len + 1; + MEMSET(target_db_server_buf_, '\0', target_db_server_buf_len_); + MEMCPY(target_db_server_buf_, target_db_server_str, target_db_server_str_len); + + ObString target_db_server_str(target_db_server_str_len, target_db_server_buf_); + if (OB_FAIL(split_weight_group(target_db_server_str, target_db_server_, target_db_server_weight_))) { + LOG_WARN("fail to split target db server str", K(ret)); + } else { /* succ */ } + } + + if (OB_SUCC(ret)) { + is_init_ = true; + LOG_DEBUG("succ to init all target db server", K_(target_db_server), K_(target_db_server_weight)); + } else { + reset(); + } + return ret; +} + +int ObTargetDbServer::get(net::ObIpEndpoint &dest) +{ + int ret = OB_SUCCESS; + + // [weight_start, weight_end) + if (!is_init_) { + ret = OB_INIT_FAIL; + LOG_WARN("fail to get next, target db server not init", K(ret)); + } else if (last_failed_idx_ == target_db_server_.count() - 1) { + ret = OB_DATA_OUT_OF_RANGE; + LOG_WARN("fail to get next, all target db server has failed", K(ret)); + } else if (!is_rand_) { + ObTargetDbServerArray::iterator weight_begin = target_db_server_.begin(); + for (int64_t i = 0; i < target_db_server_.count(); i++) { + if (i == target_db_server_.count() - 1) { + std::random_shuffle(weight_begin, target_db_server_.end()); + } else if (target_db_server_weight_.at(i) != target_db_server_weight_.at(i + 1)) { + ObTargetDbServerArray::iterator weight_end = target_db_server_.begin() + (i + 1); + std::random_shuffle(weight_begin, weight_end); + weight_begin = weight_end; + } + } + is_rand_ = true; + } + if (OB_SUCC(ret)) { + ObString addr; + uint64_t idx = last_failed_idx_ + 1; + if (OB_FAIL(target_db_server_.at(idx, addr))) { + LOG_WARN("fail to access target db server array", K(ret), K(idx)); + } else if (OB_FAIL(ops_ip_pton(addr, dest))) { + LOG_WARN("fail to do ops_ip_pton on target db server", K(ret), K(addr)); + } else { + LOG_DEBUG("succ to get target db server", K(dest)); + } + } + return ret; +} + +int ObTargetDbServer::get_next(net::ObIpEndpoint &dest_addr) +{ + // mark previous one as failed + last_failed_idx_++; + return get(dest_addr); +} + +void ObTargetDbServer::reset() +{ + is_init_ = false; + is_rand_ = false; + last_failed_idx_ = -1; + if (OB_NOT_NULL(target_db_server_buf_)) { + op_fixed_mem_free(target_db_server_buf_, target_db_server_buf_len_); + target_db_server_buf_len_ = 0; + target_db_server_buf_ = NULL; + } + target_db_server_.reset(); + target_db_server_weight_.reset(); +} + +bool ObTargetDbServer::contains(net::ObIpEndpoint &addr) +{ + bool ret = false; + if (is_init_) { + char addr_buf[MAX_IP_ADDR_LENGTH]; + MEMSET(addr_buf, '\0', MAX_IP_ADDR_LENGTH); + // get like '{xxx.xxxx.xxx.xxx:xxxx}' + addr.to_string(addr_buf, sizeof(addr_buf)); + // remove the last '}' + addr_buf[strlen(addr_buf) - 1] = '\0'; + ObTargetDbServerArray::iterator it = target_db_server_.begin(); + while (it != target_db_server_.end()) { + // skip the first '{' + if (it->case_compare(addr_buf + 1) == 0) { + ret = true; + break; + } + it++; + } + } else { + LOG_DEBUG("target db server not init!"); + } + return ret; +} + +int64_t ObTargetDbServer::to_string(char *buf, const int64_t buf_len) const +{ + int64_t pos = 0; + J_OBJ_START(); + J_KV(K_(is_init), K_(is_rand), K_(last_failed_idx), K_(target_db_server)); + J_OBJ_END(); + return pos; +} +} // namespace obproxy +} // namespace oceanbase \ No newline at end of file diff --git a/src/obproxy/utils/ob_target_db_server.h b/src/obproxy/utils/ob_target_db_server.h new file mode 100644 index 000000000..54a3ef88f --- /dev/null +++ b/src/obproxy/utils/ob_target_db_server.h @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ +#ifndef OB_TARGET_DB_SERVER_H +#define OB_TARGET_DB_SERVER_H + +#include "lib/ob_define.h" +#include "lib/container/ob_se_array.h" +#include "lib/container/ob_se_array_iterator.h" +#include "lib/utility/ob_print_utils.h" +#include "iocore/net/ob_inet.h" +#include "lib/string/ob_string.h" +#include "utils/ob_proxy_utils.h" +#include "iocore/eventsystem/ob_buf_allocator.h" + +namespace oceanbase +{ +namespace obproxy +{ +typedef common::ObSEArray ObTargetDbServerArray; +class ObTargetDbServer +{ +public: + ObTargetDbServer() : + is_init_(false), is_rand_(false), last_failed_idx_(-1), + target_db_server_buf_(NULL), target_db_server_buf_len_(0) {} + + ObTargetDbServer& operator=(const ObTargetDbServer &other) { + if (this != &other) { + reset(); + // other.target_db_server_buf_len_ - 1 to minus last '\0' + init(other.target_db_server_buf_, other.target_db_server_buf_len_ - 1); + } + return *this; + } + + ~ObTargetDbServer() { + reset(); + } + + int init(const char* target_db_server_buf, uint64_t target_db_server_buf_len); + // get the server with the highest priority execpt failed servers + int get(net::ObIpEndpoint &dest_addr); + // mark the previous visit server as failed then call get() + int get_next(net::ObIpEndpoint &dest_addr); + // num of target db server + inline int64_t num() const { return is_init_? target_db_server_.count() : 0; } + void reset(); + int64_t to_string(char *buf, const int64_t buf_len) const; + bool contains(net::ObIpEndpoint &addr); + + inline bool is_init() const { return is_init_; } + inline bool is_empty() const { return is_init_? target_db_server_.empty() : true; } + inline void reuse() { is_rand_ = false; last_failed_idx_ = -1; } + +private: + bool is_init_; + bool is_rand_; + int64_t last_failed_idx_; + char* target_db_server_buf_; + uint64_t target_db_server_buf_len_; + + ObTargetDbServerArray target_db_server_; + common::ObSEArray target_db_server_weight_; +}; + +} // end of namespace obproxy +} // end of namespace oceanbase +#endif \ No newline at end of file diff --git a/src/rpc/Makemodule.am b/src/rpc/Makemodule.am index 50120c297..3b318e9fb 100644 --- a/src/rpc/Makemodule.am +++ b/src/rpc/Makemodule.am @@ -20,6 +20,10 @@ rpc/obmysql/packet/ompk_handshake_response.h\ rpc/obmysql/packet/ompk_handshake_response.cpp\ rpc/obmysql/packet/ompk_prepare.h\ rpc/obmysql/packet/ompk_prepare.cpp\ +rpc/obmysql/packet/ompk_prepare_execute.h\ +rpc/obmysql/packet/ompk_prepare_execute.cpp\ +rpc/obmysql/packet/ompk_prepare_execute_req.h\ +rpc/obmysql/packet/ompk_prepare_execute_req.cpp\ rpc/obmysql/packet/ompk_ping.h\ rpc/obmysql/packet/ompk_ssl_request.h\ rpc/obmysql/packet/ompk_ssl_request.cpp diff --git a/src/rpc/ob_request.cpp b/src/rpc/ob_request.cpp index f2e4c658e..4b692185a 100644 --- a/src/rpc/ob_request.cpp +++ b/src/rpc/ob_request.cpp @@ -24,8 +24,11 @@ char *ObRequest::easy_alloc(int64_t size) const if (NULL == ez_req_ || NULL == ez_req_->ms) { RPC_LOG(ERROR, "ez_req_ is not corret"); } else { - buf = easy_pool_alloc( - ez_req_->ms->pool, static_cast(size)); + /* this function is defined for c driver client compile */ + UNUSED(size); + buf = NULL; + // buf = easy_pool_alloc( + // ez_req_->ms->pool, static_cast(size)); } return static_cast(buf); } diff --git a/src/rpc/obmysql/ob_mysql_field.cpp b/src/rpc/obmysql/ob_mysql_field.cpp index dfd6198be..21d30995e 100644 --- a/src/rpc/obmysql/ob_mysql_field.cpp +++ b/src/rpc/obmysql/ob_mysql_field.cpp @@ -94,6 +94,15 @@ int ObMySQLField::serialize_pro41(char *buf, const int64_t len, int64_t &pos) co LOG_WARN("serialize 0 failed", K(ret)); } } + if (OB_SUCC(ret) && OB_MYSQL_TYPE_COMPLEX == type_) { + if (OB_FAIL(ObMySQLUtil::store_str_v(buf, len, type_info_.relation_name_.ptr(), type_info_.relation_name_.length(), pos))) { + LOG_WARN("serialize relation_name_ failed", K(ret)); + } else if (OB_FAIL(ObMySQLUtil::store_str_v(buf, len, type_info_.type_name_.ptr(), type_info_.type_name_.length(),pos))) { + LOG_WARN("serialize type_name_ failed", K(ret)); + } else if (OB_FAIL(ObMySQLUtil::store_length(buf, len, type_info_.version_, pos))) { + LOG_WARN("serialize type_name_ failed", K(ret)); + } else { /* succ to write complex type */ } + } return ret; } diff --git a/src/rpc/obmysql/ob_mysql_field.h b/src/rpc/obmysql/ob_mysql_field.h index 32cfc7ab7..e8001a6a9 100644 --- a/src/rpc/obmysql/ob_mysql_field.h +++ b/src/rpc/obmysql/ob_mysql_field.h @@ -22,6 +22,17 @@ namespace oceanbase { namespace obmysql { + +struct TypeInfo { + TypeInfo() : relation_name_(), type_name_(), version_(0), is_elem_type_(false) {} ; + common::ObString relation_name_; + common::ObString type_name_; + uint64_t version_; + ObObjType elem_type_; + bool is_elem_type_; + TO_STRING_KV(K_(relation_name), K_(type_name), K_(version), K_(elem_type), K_(is_elem_type)); +}; + class ObMySQLField { public: @@ -90,6 +101,7 @@ class ObMySQLField common::ObString org_cname_; // original column name common::ObAccuracy accuracy_; EMySQLFieldType type_; // value type + TypeInfo type_info_; // for complex type uint16_t flags_; // unsigned and so on... EMySQLFieldType default_value_; //default value, only effective when command was OB_MYSQL_COM_FIELD_LIST uint16_t charsetnr_; //character set of table diff --git a/src/rpc/obmysql/ob_mysql_global.h b/src/rpc/obmysql/ob_mysql_global.h index ff2cc80be..1acf42dca 100644 --- a/src/rpc/obmysql/ob_mysql_global.h +++ b/src/rpc/obmysql/ob_mysql_global.h @@ -100,6 +100,7 @@ enum EMySQLFieldType OB_MYSQL_TYPE_OB_TIMESTAMP_NANO = 202, OB_MYSQL_TYPE_OB_RAW = 203, OB_MYSQL_TYPE_OB_UROWID = 209, + OB_MYSQL_TYPE_JSON = 245, OB_MYSQL_TYPE_NEWDECIMAL = 246, OB_MYSQL_TYPE_ENUM = 247, OB_MYSQL_TYPE_SET = 248, @@ -219,6 +220,9 @@ inline const char *get_emysql_field_type_str(const obmysql::EMySQLFieldType &typ case obmysql::OB_MYSQL_TYPE_STRING: str = "OB_MYSQL_TYPE_STRING"; break; + case obmysql::OB_MYSQL_TYPE_JSON: + str = "OB_MYSQL_TYPE_JSON"; + break; case obmysql::OB_MYSQL_TYPE_GEOMETRY: str = "OB_MYSQL_TYPE_GEOMETRY"; break; diff --git a/src/rpc/obmysql/packet/ompk_handshake.cpp b/src/rpc/obmysql/packet/ompk_handshake.cpp index a24c89a73..e7aa4381f 100644 --- a/src/rpc/obmysql/packet/ompk_handshake.cpp +++ b/src/rpc/obmysql/packet/ompk_handshake.cpp @@ -69,11 +69,11 @@ OMPKHandshake::OMPKHandshake() auth_plugin_data_len_ = 0; } - server_language_ = 83;//utf8_bin - server_status_ = 0;// no this value in mysql protocol document + server_language_ = 46; // utf8mb4_bin + server_status_ = 0; // no this value in mysql protocol document //auth_plugin_data_len_ = 0; - memset(reserved_, 0, sizeof (reserved_)); - memset(auth_plugin_data2_, 'b', sizeof (auth_plugin_data2_) - 1); + memset(reserved_, 0, sizeof(reserved_)); + memset(auth_plugin_data2_, 'b', sizeof(auth_plugin_data2_) - 1); } OMPKHandshake::~OMPKHandshake() diff --git a/src/rpc/obmysql/packet/ompk_handshake_response.h b/src/rpc/obmysql/packet/ompk_handshake_response.h index ffbeb1cc0..ecb0a0c6c 100644 --- a/src/rpc/obmysql/packet/ompk_handshake_response.h +++ b/src/rpc/obmysql/packet/ompk_handshake_response.h @@ -49,7 +49,7 @@ class OMPKHandshakeResponse : public ObMySQLPacket inline const ObString &get_auth_response() const { return auth_response_; } inline const ObString &get_database() const { return database_; } inline const ObString &get_auth_plugin_name() const { return auth_plugin_name_; } - inline const common::ObIArray &get_connect_attrs() const { return connect_attrs_; } + inline common::ObIArray &get_connect_attrs() { return connect_attrs_; } bool is_obproxy_client_mod() const; inline void set_capability_flags(const ObMySQLCapabilityFlags &cap) { capability_ = cap; } diff --git a/src/rpc/obmysql/packet/ompk_prepare_execute.cpp b/src/rpc/obmysql/packet/ompk_prepare_execute.cpp new file mode 100644 index 000000000..23bdf666f --- /dev/null +++ b/src/rpc/obmysql/packet/ompk_prepare_execute.cpp @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#define USING_LOG_PREFIX RPC_OBMYSQL +#include "ompk_prepare_execute.h" +#include "lib/oblog/ob_log_module.h" +#include "rpc/obmysql/ob_mysql_util.h" + +using namespace oceanbase::common; +using namespace oceanbase::obmysql; + +namespace oceanbase +{ +using namespace common; +namespace obmysql +{ + +int OMPKPrepareExecute::decode() +{ + int ret = OB_SUCCESS; + const char *pos = cdata_; + if (NULL != cdata_) { + ObMySQLUtil::get_uint1(pos, status_); + ObMySQLUtil::get_uint4(pos, statement_id_); + ObMySQLUtil::get_uint2(pos, column_num_); + ObMySQLUtil::get_uint2(pos, param_num_); + ObMySQLUtil::get_uint1(pos, reserved_); + ObMySQLUtil::get_uint2(pos, warning_count_); + ObMySQLUtil::get_uint4(pos, extend_flag_); + ObMySQLUtil::get_uint1(pos, has_result_set_); + } else { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("null input", K(ret), K(cdata_)); + } + return ret; +} + +int OMPKPrepareExecute::serialize(char* buffer, int64_t length, int64_t& pos) const +{ + int ret = OB_SUCCESS; + if (NULL == buffer || 0 >= length || pos < 0 || length - pos < get_serialize_size()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(buffer), K(length), K(pos), "need_size", get_serialize_size()); + } else { + if (OB_SUCCESS != (ret = ObMySQLUtil::store_int1(buffer, length, status_, pos))) { + LOG_WARN("store failed", K(buffer), K(length), K_(status), K(pos)); + } else if (OB_FAIL(ObMySQLUtil::store_int4(buffer, length, statement_id_, pos))) { + LOG_WARN("store failed", K(buffer), K(length), K_(statement_id), K(pos)); + } else if (OB_FAIL(ObMySQLUtil::store_int2(buffer, length, column_num_, pos))) { + LOG_WARN("store failed", K(buffer), K(length), K_(column_num), K(pos)); + } else if (OB_FAIL(ObMySQLUtil::store_int2(buffer, length, param_num_, pos))) { + LOG_WARN("store failed", K(buffer), K(length), K_(param_num), K(pos)); + } else if (OB_FAIL(ObMySQLUtil::store_int1(buffer, length, reserved_, pos))) { + LOG_WARN("store failed", K(buffer), K(length), K_(reserved), K(pos)); + } else if (OB_FAIL(ObMySQLUtil::store_int2(buffer, length, warning_count_, pos))) { + LOG_WARN("store failed", K(buffer), K(length), K_(warning_count), K(pos)); + } else if (OB_FAIL(ObMySQLUtil::store_int4(buffer, length, extend_flag_, pos))) { + LOG_WARN("store failed", K(buffer), K(length), K_(extend_flag), K(pos)); + } else if (OB_FAIL(ObMySQLUtil::store_int1(buffer, length, has_result_set_, pos))) { + LOG_WARN("store failed", K(buffer), K(length), K_(has_result_set), K(pos)); + } + } + return ret; +} + +int64_t OMPKPrepareExecute::get_serialize_size() const +{ + int64_t len = 0; + len += 1; // status + len += 4; // statement id + len += 2; // column num + len += 2; // param num + len += 1; // reserved + len += 2; // warning count + len += 4; // extend flags + len += 1; // has result set + return len; +} + + + + +} //end of obmysql +} //end of oceanbase diff --git a/src/rpc/obmysql/packet/ompk_prepare_execute.h b/src/rpc/obmysql/packet/ompk_prepare_execute.h new file mode 100644 index 000000000..f33c6ce18 --- /dev/null +++ b/src/rpc/obmysql/packet/ompk_prepare_execute.h @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + + +#ifndef OCEANBASE_RPC_OBMYSQL_OMPK_PREPARE_EXECUTE_H_ +#define OCEANBASE_RPC_OBMYSQL_OMPK_PREPARE_EXECUTE_H_ + +#include "ompk_prepare_execute.h" +#include "rpc/obmysql/ob_mysql_packet.h" +#include "lib/utility/ob_macro_utils.h" + +namespace oceanbase +{ +namespace obmysql +{ + +/** + * This packet is response to OB_MYSQL_COM_STMT_PREPARE + * following with param desc && column desc packets + * + * status (1) -- [00] OK + * statement_id (4) -- statement-id + * num_columns (2) -- number of columns + * num_params (2) -- number of params + * reserved_ (1) -- [00] filler + * warning_count (2) -- number of warnings + */ + +class OMPKPrepareExecute: public ObMySQLPacket +{ +public: + OMPKPrepareExecute() : + status_(0), + statement_id_(0), + column_num_(0), + param_num_(0), + reserved_(0), + warning_count_(0), + extend_flag_(0), + has_result_set_(0) + {} + virtual ~OMPKPrepareExecute() {} + + int decode(); + virtual int serialize(char* buffer, int64_t length, int64_t& pos) const; + virtual int64_t get_serialize_size() const; + + inline void set_status(const uint8_t status) { status_ = status; } + inline void set_statement_id(const uint32_t id) { statement_id_ = id; } + inline void set_column_num(const uint16_t num) { column_num_ = num;} + inline void set_param_num(const uint16_t num) { param_num_ = num; } + inline void set_warning_count(const uint16_t count) { warning_count_ = count; } + inline void set_extend_flag(const uint32_t extend_flag) { extend_flag_ = extend_flag; } + inline void set_has_result_set(const uint8_t has_result_set) { has_result_set_ = has_result_set; } + + inline uint32_t get_statement_id() const { return statement_id_; } + inline uint16_t get_column_num() const { return column_num_;} + inline uint16_t get_param_num() const { return param_num_; } + inline uint16_t get_warning_count() const { return warning_count_; } + inline uint32_t get_extend_flag() const { return extend_flag_; } + inline uint8_t has_result_set() const { return has_result_set_; } + +private: + uint8_t status_; + uint32_t statement_id_; + uint16_t column_num_; + uint16_t param_num_; + uint8_t reserved_; + uint16_t warning_count_; + uint32_t extend_flag_; + uint8_t has_result_set_; + DISALLOW_COPY_AND_ASSIGN(OMPKPrepareExecute); +}; + +} //end of obmysql +} //end of oceanbase + + +#endif //OCEANBASE_RPC_OBMYSQL_OMPK_PREPARE_EXECUTE_H_ diff --git a/src/rpc/obmysql/packet/ompk_prepare_execute_req.cpp b/src/rpc/obmysql/packet/ompk_prepare_execute_req.cpp new file mode 100644 index 000000000..533ec01e5 --- /dev/null +++ b/src/rpc/obmysql/packet/ompk_prepare_execute_req.cpp @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#define USING_LOG_PREFIX RPC_OBMYSQL +#include "ompk_prepare_execute_req.h" + +using namespace oceanbase::common; +using namespace oceanbase::obmysql; +namespace oceanbase +{ +using namespace common; +using namespace obproxy; +using namespace proxy; + +namespace obmysql +{ + +int OMPKPrepareExecuteReq::decode() +{ + int ret = OB_SUCCESS; + const char *pos = cdata_; + int64_t data_len = hdr_.len_; + if (NULL != cdata_) { + uint64_t query_len = 0; + // skip cmd + if (OB_FAIL(ObMysqlPacketUtil::get_uint1(pos, data_len, cmd_))) { + LOG_WARN("fail to get uint1", K(data_len), K(ret)); + } else if (OB_FAIL(ObMysqlPacketUtil::get_uint4(pos, data_len, statement_id_))) { + LOG_WARN("fail to get uint4", K(data_len), K(ret)); + } else if (OB_FAIL(ObMysqlPacketUtil::get_uint1(pos, data_len, flags_))) { + LOG_WARN("fail to get uint1", K(data_len), K(ret)); + } else if (OB_FAIL(ObMysqlPacketUtil::get_uint4(pos, data_len, iteration_count_))) { + LOG_WARN("fail to get uint4", K(data_len), K(ret)); + } else if (OB_FAIL(ObMysqlPacketUtil::get_length(pos, data_len, query_len))) { + LOG_WARN("fail to get length", K(data_len), K(ret)); + // skip query + } else if (FALSE_IT(pos += query_len)) { + } else if (OB_FAIL(ObMysqlPacketUtil::get_uint4(pos, data_len, param_num_))) { + LOG_WARN("fail to get uint4", K(data_len), K(ret)); + // skip null bitmap + } else if (param_num_ <= 0) { + LOG_DEBUG("skip read param related", K(param_num_)); + } else if (FALSE_IT(pos += (param_num_ + 7)/8)) { + } else if (OB_FAIL(ObMysqlPacketUtil::get_uint1(pos, data_len, new_params_bound_flag_))) { + LOG_WARN("fail to get uint1", K(data_len), K(ret)); + } else if (new_params_bound_flag_ == 1 + && OB_FAIL(ObMysqlRequestAnalyzer::parse_param_type(param_num_, param_types_, type_infos_, pos, data_len))) { + LOG_WARN("fail to parse param type", K_(param_num), K(pos), K(data_len), K(ret)); + } else { /* do nothing */ } + // skip the rest of data + } else { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("null input", K(ret), K(cdata_)); + } + return ret; +} + +} //end of obmysql +} //end of oceanbase diff --git a/src/rpc/obmysql/packet/ompk_prepare_execute_req.h b/src/rpc/obmysql/packet/ompk_prepare_execute_req.h new file mode 100644 index 000000000..c1d148f83 --- /dev/null +++ b/src/rpc/obmysql/packet/ompk_prepare_execute_req.h @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase Database Proxy(ODP) is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + + +#ifndef OCEANBASE_RPC_OBMYSQL_OMPK_PREPARE_EXECUTE_REQ_H_ +#define OCEANBASE_RPC_OBMYSQL_OMPK_PREPARE_EXECUTE_REQ_H_ + +#include "rpc/obmysql/ob_mysql_util.h" +#include "lib/container/ob_se_array.h" +#include "lib/utility/ob_macro_utils.h" +#include "lib/oblog/ob_log_module.h" +#include "obproxy/proxy/mysqllib/ob_mysql_request_analyzer.h" +#include "obproxy/packet/ob_mysql_packet_util.h" +namespace oceanbase +{ + +namespace obmysql +{ + +/** + * This packet is request to OB_MYSQL_COM_STMT_PREPARE_EXECUTE + * following with param desc && column desc packets + * + */ + +class OMPKPrepareExecuteReq: public ObMySQLPacket +{ +public: + OMPKPrepareExecuteReq() : + cmd_(OB_MYSQL_COM_STMT_PREPARE_EXECUTE), + statement_id_(0), + flags_(0), + iteration_count_(0), + query_(NULL), + param_num_(0), + null_bitmap_(NULL), + new_params_bound_flag_(0) + {} + virtual ~OMPKPrepareExecuteReq() {} + + virtual int decode(); + + inline uint32_t get_statement_id() const { return statement_id_; } + inline uint32_t get_param_num() const { return param_num_; } + inline common::ObIArray& get_param_types() { return param_types_; } + inline common::ObIArray& get_type_infos() { return type_infos_; } + +private: + uint8_t cmd_; + uint32_t statement_id_; + uint8_t flags_; + uint32_t iteration_count_; + common::ObString query_; + uint32_t param_num_; + char* null_bitmap_; + uint8_t new_params_bound_flag_; + common::ObSEArray param_types_; + common::ObSEArray type_infos_; + // ingore value of eache parameter + uint32_t execute_mode_; + uint32_t num_close_stmt_count_; + uint32_t check_sum_; + uint32_t extend_flag_; + + DISALLOW_COPY_AND_ASSIGN(OMPKPrepareExecuteReq); +}; + +} //end of obmysql +} //end of oceanbase + + +#endif //OCEANBASE_RPC_OBMYSQL_OMPK_PREPARE_EXECUTE_REQ_H_ diff --git a/src/share/config/ob_common_config.cpp b/src/share/config/ob_common_config.cpp index f02b5d6d8..7f15540a4 100644 --- a/src/share/config/ob_common_config.cpp +++ b/src/share/config/ob_common_config.cpp @@ -15,6 +15,7 @@ #include "share/config/ob_server_config.h" #include "common/ob_record_header.h" +static const char *ignore_config_opt_str[] = {"target_db_server"}; namespace oceanbase { namespace common @@ -44,9 +45,26 @@ ObCommonConfig::~ObCommonConfig() { } +// tmp use for opt str +int ObCommonConfig::add_extra_config_from_opt(const char *config_str, + int64_t version /* = 0 */ , + bool check_name /* = false */) +{ + return add_config(config_str, version, check_name, ",\n", ignore_config_opt_str); +} + int ObCommonConfig::add_extra_config(const char *config_str, int64_t version /* = 0 */ , bool check_name /* = false */) +{ + return add_config(config_str, version, check_name, "\n", NULL); +} + +int ObCommonConfig::add_config(const char *config_str, + int64_t version /* = 0 */ , + bool check_name /* = false */, + const char* delim, + const char* ignore_conf[]) { int ret = OB_SUCCESS; const int64_t MAX_OPTS_LENGTH = sysconf(_SC_ARG_MAX); @@ -67,7 +85,7 @@ int ObCommonConfig::add_extra_config(const char *config_str, } else { MEMCPY(buf, config_str, config_str_length); buf[config_str_length] = '\0'; - token = STRTOK_R(buf, ",\n", &saveptr); + token = STRTOK_R(buf, delim, &saveptr); } while (OB_SUCC(ret) && OB_LIKELY(NULL != token)) { @@ -86,7 +104,21 @@ int ObCommonConfig::add_extra_config(const char *config_str, value = saveptr_one; } + bool ignore = false; + if (OB_SUCC(ret) && OB_NOT_NULL(ignore_conf)) { + int64_t ignore_conf_num = sizeof(ignore_config_opt_str)/sizeof(char*); + for (int64_t i = 0; i < ignore_conf_num; i++) { + ObString conf(ignore_conf[i]); + if (OB_NOT_NULL(ignore_conf[i]) && conf.case_compare(name) == 0) { + ignore = true; + break; + } + } + } + if (OB_FAIL(ret)) { + } else if (ignore) { + LOG_INFO("Ignore config", K(name), K(value)); } else if (OB_ISNULL(pp_item = container_.get(ObConfigStringKey(name)))) { /* make compatible with previous configuration */ ret = check_name ? OB_INVALID_CONFIG : OB_SUCCESS; @@ -101,7 +133,7 @@ int ObCommonConfig::add_extra_config(const char *config_str, (*pp_item)->set_version(version); LOG_INFO("Load config succ", K(name), K(value)); } - token = STRTOK_R(NULL, ",\n", &saveptr); + token = STRTOK_R(NULL, delim, &saveptr); } if (NULL != buf) { diff --git a/src/share/config/ob_common_config.h b/src/share/config/ob_common_config.h index d1a51b6cd..a34c9df02 100644 --- a/src/share/config/ob_common_config.h +++ b/src/share/config/ob_common_config.h @@ -77,6 +77,15 @@ class ObCommonConfig : public ObInitConfigContainer virtual int add_extra_config(const char *config_str, const int64_t version = 0, const bool check_name = false); + int add_extra_config_from_opt(const char *config_str, + const int64_t version = 0, + const bool check_name = false); + int add_config(const char *config_str, + int64_t version, + bool check_name, + const char* delim, + const char* ignore_conf[]); + virtual bool is_debug_sync_enabled() const { return false; } NEED_SERIALIZE_AND_DESERIALIZE; diff --git a/src/share/config/ob_config.h b/src/share/config/ob_config.h index 77d42d93e..bfe2042fd 100644 --- a/src/share/config/ob_config.h +++ b/src/share/config/ob_config.h @@ -349,7 +349,7 @@ class ObConfigIntegralItem virtual bool parse_range(const char *range); virtual void set_initial_value() { initial_value_ = value_; is_initial_value_set_ = true; } -protected: +public: //use current value to do input operation bool set(const char *str); virtual int64_t parse(const char *str, bool &valid) const = 0; diff --git a/src/share/config/ob_config_helper.cpp b/src/share/config/ob_config_helper.cpp index cc4a43d5a..5e9bca71f 100644 --- a/src/share/config/ob_config_helper.cpp +++ b/src/share/config/ob_config_helper.cpp @@ -17,11 +17,16 @@ namespace oceanbase { namespace common { + bool ObConfigIpChecker::check(const ObConfigItem &t) const { - struct sockaddr_in sa; - int result = inet_pton(AF_INET, t.str(), &(sa.sin_addr)); - return result != 0; + struct in_addr in; + int result = inet_pton(AF_INET, t.str(), &in); + if (result != 1) { + struct in6_addr in6; + result = inet_pton(AF_INET6, t.str(), &in6); + } + return result == 1; } ObConfigConsChecker:: ~ObConfigConsChecker() diff --git a/src/share/inner_table/ob_inner_table_schema_constants.h b/src/share/inner_table/ob_inner_table_schema_constants.h index c4df4b9f6..dbad5b7ae 100644 --- a/src/share/inner_table/ob_inner_table_schema_constants.h +++ b/src/share/inner_table/ob_inner_table_schema_constants.h @@ -298,6 +298,7 @@ const char *const OB_HELP_KEYWORD_TNAME = "help_keyw const char *const OB_HELP_RELATION_TNAME = "help_relation"; const char *const OB_ALL_LOCAL_INDEX_STATUS_TNAME = "__all_local_index_status"; const char *const OB_ALL_DUMMY_TNAME = "__all_dummy"; +const char *const OB_ALL_BINLOG_DUMMY_TNAME = "__all_binlog_dummy"; const char *const OB_ALL_FROZEN_MAP_TNAME = "__all_frozen_map"; const char *const OB_ALL_CLOG_HISTORY_INFO_TNAME = "__all_clog_history_info"; const char *const OB_ALL_CLOG_HISTORY_INFO_V2_TNAME = "__all_clog_history_info_v2"; diff --git a/src/share/part/ob_part_desc.cpp b/src/share/part/ob_part_desc.cpp index f0efb6915..58fdc09f6 100644 --- a/src/share/part/ob_part_desc.cpp +++ b/src/share/part/ob_part_desc.cpp @@ -13,6 +13,7 @@ #include "share/part/ob_part_desc.h" #include "common/ob_obj_cast.h" #include "obproxy/proxy/mysqllib/ob_proxy_session_info.h" +#include "obproxy/proxy/route/obproxy_expr_calculator.h" namespace oceanbase @@ -92,9 +93,47 @@ int ObPartDesc::build_dtc_params(obproxy::proxy::ObClientSessionInfo *session_in return ret; } -void ObPartDesc::set_accuracy(const ObProxyPartKeyAccuracy &accuracy) +int ObPartDesc::cast_obj(ObObj &src_obj, + ObObj &target_obj, + ObIAllocator &allocator, + ObPartDescCtx &ctx, + ObAccuracy &accuracy) { - accuracy_ = accuracy; + return cast_obj(src_obj, target_obj.get_type(), target_obj.get_collation_type(), allocator, ctx, accuracy); +} + +int ObPartDesc::cast_obj(ObObj &src_obj, + ObObjType obj_type, + ObCollationType cs_type, + ObIAllocator &allocator, + ObPartDescCtx &ctx, + ObAccuracy &accuracy) +{ + int ret = OB_SUCCESS; + COMMON_LOG(DEBUG, "begin to cast obj", K(src_obj), K(obj_type), K(cs_type)); + + ObTimeZoneInfo tz_info; + ObDataTypeCastParams dtc_params; + + if (OB_FAIL(obproxy::proxy::ObExprCalcTool::build_dtc_params_with_tz_info(ctx.get_session_info(), + obj_type, tz_info, dtc_params))) { + COMMON_LOG(WARN, "fail to build dtc params with ctx session", K(ret), K(obj_type)); + } else { + ObCastCtx cast_ctx(&allocator, &dtc_params, CM_NULL_ON_WARN, cs_type); + const ObObj *res_obj = &src_obj; + + // use src_obj as buf_obj + if (OB_FAIL(ObObjCasterV2::to_type(obj_type, cs_type, cast_ctx, src_obj, src_obj))) { + COMMON_LOG(WARN, "failed to cast obj", K(ret), K(src_obj), K(obj_type), K(cs_type)); + } else if (ctx.need_accurate() + && OB_FAIL(obj_accuracy_check(cast_ctx, accuracy, cs_type, *res_obj, src_obj, res_obj))) { + COMMON_LOG(WARN, "fail to obj accuracy check", K(ret), K(src_obj)); + } else { + COMMON_LOG(DEBUG, "end to cast obj for range", K(src_obj), K(obj_type), K(cs_type)); + } + } + + return ret; } } // end of common diff --git a/src/share/part/ob_part_desc.h b/src/share/part/ob_part_desc.h index b81027cd9..77e271e76 100644 --- a/src/share/part/ob_part_desc.h +++ b/src/share/part/ob_part_desc.h @@ -18,6 +18,7 @@ #include "lib/timezone/ob_time_convert.h" #include "share/part/ob_part_mgr_util.h" #include "obproxy/opsql/expr_parser/ob_expr_parse_result.h" +#include "common/ob_row.h" namespace oceanbase { @@ -82,12 +83,25 @@ class ObPartDesc int build_dtc_params(obproxy::proxy::ObClientSessionInfo *session_info, ObObjType obj_type, ObDataTypeCastParams &dtc_params); - void set_accuracy(const ObProxyPartKeyAccuracy &accuracy); - + ObIArray &get_accuracies() { return accuracies_; } + + int cast_obj(ObObj &src_obj, + ObObj &target_obj, + ObIAllocator &allocator, + ObPartDescCtx &ctx, + ObAccuracy &accuracy); + + int cast_obj(ObObj &src_obj, + ObObjType obj_type, + ObCollationType cs_type, + ObIAllocator &allocator, + ObPartDescCtx &ctx, + ObAccuracy &accuracy); + DECLARE_VIRTUAL_TO_STRING = 0; share::schema::ObPartitionLevel part_level_; share::schema::ObPartitionFuncType part_func_type_; - ObProxyPartKeyAccuracy accuracy_; + ObSEArray accuracies_; int64_t *tablet_id_array_; }; diff --git a/src/share/part/ob_part_desc_hash.cpp b/src/share/part/ob_part_desc_hash.cpp index d51014326..e90b14212 100644 --- a/src/share/part/ob_part_desc_hash.cpp +++ b/src/share/part/ob_part_desc_hash.cpp @@ -27,10 +27,15 @@ ObPartDescHash::ObPartDescHash() : is_oracle_mode_(false) { } -/* +/** GET PARTITION ID - - If input is not single int value, get all partition ids; otherwise, get the particular one. + Hash partition only route like 'by hash(c1,c2) ... where c1=xx and c2=xx', + only use range.start_key_ to calc, because when condition is like 'c1=xx', + start_key_[i] == end_key_[i] + @param range (xxx,yyy,min,min ; xxx,yyy,max,max) + @param allocator + @param part_ids[out] + @param ctx */ int ObPartDescHash::get_part(ObNewRange &range, ObIAllocator &allocator, @@ -38,30 +43,72 @@ int ObPartDescHash::get_part(ObNewRange &range, ObPartDescCtx &ctx, ObIArray &tablet_ids) { - int ret = OB_SUCCESS; - if (1 != range.get_start_key().get_obj_cnt()) { // single value - ret = OB_INVALID_ARGUMENT; - COMMON_LOG(DEBUG, "hash part should be single key", - "obj_cnt", range.get_start_key().get_obj_cnt(), K(ret)); - } else { - int64_t part_idx = -1; - ObObj &src_obj = const_cast(range.get_start_key().get_obj_ptr()[0]); - if (is_oracle_mode_) { - ret = calc_value_for_oracle(src_obj, allocator, part_idx, ctx); + int ret = OB_SUCCESS; + // 1. Cast obj + // provide all objs are valid. + // "valid" means the obj not min or max + int64_t valid_obj_cnt = range.start_key_.get_obj_cnt(); + for (int64_t i = 0; OB_SUCC(ret) && i < range.start_key_.get_obj_cnt(); i++) { + // if obj is min or max, means all valid obj has been casted + if (range.start_key_.get_obj_ptr()[i].is_max_value() || + range.start_key_.get_obj_ptr()[i].is_min_value()) { + // minus the number of invalid obj + valid_obj_cnt = valid_obj_cnt - (range.start_key_.get_obj_cnt() - i); + // not need to cast any more and break loop + if (valid_obj_cnt == 0) { + ret = OB_INVALID_ARGUMENT; + COMMON_LOG(WARN, "not support hash partition calc with range", K(range)); + } + break; } else { - ret = calc_value_for_mysql(src_obj, allocator, part_idx); + ObObj *src_obj = const_cast(&range.start_key_.get_obj_ptr()[i]); + if (OB_ISNULL(src_obj)) { + // here src_obj shouldn't be null + ret = OB_ERR_NULL_VALUE; + COMMON_LOG(ERROR, "unexpected null pointer src_obj"); + } else if (src_obj->is_null()) { + // here src_obj shouldn't be null type + ret = OB_OBJ_TYPE_ERROR; + COMMON_LOG(ERROR, "unexpected null type", K(src_obj)); + // oracle mode cast all valid objs to target type + } else if (is_oracle_mode_) { + if(OB_FAIL(cast_obj(*src_obj, obj_types_[i], cs_types_[i], allocator, ctx, accuracies_.at(i)))) { + COMMON_LOG(WARN, "cast obj failed", K(src_obj), "obj_type", obj_types_[i], "cs_type", cs_types_[i]); + // TODO: handle failure + } + // mysql mode only cast first valid obj to int type then break loop + } else /*if (is_mysql_mode_) */ { + ObCastCtx cast_ctx(&allocator, NULL, CM_NULL_ON_WARN, CS_TYPE_INVALID); + if (OB_FAIL(ObObjCasterV2::to_type(ObIntType, cs_types_[i], cast_ctx, *src_obj, *src_obj))) { + COMMON_LOG(WARN, "failed to cast to ObIntType", K(src_obj), K(ret)); + } + break; + } } + } - if (OB_SUCC(ret)) { - int64_t part_id = -1; - if (OB_FAIL(get_part_hash_idx(part_idx, part_id))) { - COMMON_LOG(WARN, "fail to get part hash id", K(ret)); - } else if (OB_FAIL(part_ids.push_back(part_id))) { - COMMON_LOG(WARN, "fail to push part_id", K(ret)); - } else if (NULL != tablet_id_array_ && OB_FAIL(tablet_ids.push_back(tablet_id_array_[part_idx]))) { - COMMON_LOG(WARN, "fail to push tablet_id", K(ret)); - } + // 2. Calc partition id + int64_t part_idx = -1; + if (OB_SUCC(ret)) { + // hash val + int64_t result = 0; + if (is_oracle_mode_) { + // oracle mode: use obj to calc hash val + ret = calc_value_for_oracle(range.start_key_.get_obj_ptr(), valid_obj_cnt, result, ctx); + } else { + // mysql mode: use single obj to calc hash val + ret = calc_value_for_mysql(range.start_key_.get_obj_ptr(), result); } + int64_t part_id = -1; + if (OB_SUCC(ret) && OB_FAIL(calc_hash_part_idx(result, part_num_, part_idx))) { + COMMON_LOG(WARN, "fail to cal hash part idx", K(ret), K(result), K(part_num_)); + } else if (OB_FAIL(get_part_hash_idx(part_idx, part_id))) { + COMMON_LOG(WARN, "fail to get part hash id", K(part_idx), K(ret)); + } else if (OB_FAIL(part_ids.push_back(part_id))) { + COMMON_LOG(WARN, "fail to push part_id", K(ret)); + } else if (NULL != tablet_id_array_ && OB_FAIL(tablet_ids.push_back(tablet_id_array_[part_idx]))) { + COMMON_LOG(WARN, "fail to push tablet_id", K(ret)); + } else {} } return ret; @@ -152,103 +199,91 @@ uint64_t ObPartDescHash::calc_hash_value_with_seed(const ObObj &obj, const int64 return hval; } - -int ObPartDescHash::calc_value_for_oracle(ObObj &src_obj, - ObIAllocator &allocator, - int64_t &part_idx, +int ObPartDescHash::calc_value_for_oracle(const ObObj *objs, + int64_t objs_cnt, + int64_t &result, ObPartDescCtx &ctx) { int ret = OB_SUCCESS; - - ObTimeZoneInfo tz_info; - ObDataTypeCastParams dtc_params; - - if (OB_FAIL(obproxy::proxy::ObExprCalcTool::build_dtc_params_with_tz_info(ctx.get_session_info(), - obj_type_, tz_info, dtc_params))) { - COMMON_LOG(WARN, "fail to build dtc params with tz info", K(ret)); - } else { - lib::set_oracle_mode(true); - - uint64_t hash_val = 0; - ObCastCtx cast_ctx(&allocator, &dtc_params, CM_NULL_ON_WARN, cs_type_); - const ObObj *res_obj = &src_obj; - - ObAccuracy accuracy(accuracy_.valid_, accuracy_.length_, accuracy_.precision_, accuracy_.scale_); - - // use src_obj as buf_obj - COMMON_LOG(DEBUG, "begin to cast value for hash oracle", K(src_obj), K(cs_type_)); - if (OB_FAIL(ObObjCasterV2::to_type(obj_type_, cs_type_, cast_ctx, src_obj, src_obj))) { - COMMON_LOG(WARN, "failed to cast obj", K(ret), K(src_obj), K(obj_type_), K(cs_type_)); - } else if (ctx.need_accurate() - && OB_FAIL(obj_accuracy_check(cast_ctx, accuracy, cs_type_, *res_obj, src_obj, res_obj))) { - COMMON_LOG(WARN, "fail to obj accuracy check", K(ret), K(src_obj), K(obj_type_)); + uint64_t hash_code = 0; + if (OB_ISNULL(objs) || 0 == objs_cnt) { + ret = OB_ERR_UNEXPECTED; + COMMON_LOG(WARN, "objs_stack is null or number incorrect", K(objs), K(objs_cnt), K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < objs_cnt; ++i) { + const ObObj &obj = objs[i]; + const ObObjType type = obj.get_type(); + if (ObNullType == type) { + //do nothing, hash_code not changed + } else if (!is_oracle_supported_type(type)) { + ret = OB_INVALID_ARGUMENT; + COMMON_LOG(WARN, "type is wrong", K(ret), K(obj), K(type)); } else { - COMMON_LOG(DEBUG, "finish to cast and accuracy values for hash oracle", K(src_obj), K(obj_type_), K(cs_type_)); - // calculate hash value - const ObObjType type = src_obj.get_type(); - if (ObNullType == type) { - //do nothing, hash_code not changed - } else if (!is_oracle_supported_type(type)) { - ret = OB_INVALID_ARGUMENT; - COMMON_LOG(WARN, "type is wrong", K(ret), K(src_obj), K(type)); - } else { - hash_val = calc_hash_value_with_seed(src_obj, ctx.get_cluster_version(), hash_val); - } + hash_code = calc_hash_value_with_seed(obj, ctx.get_cluster_version(), hash_code); } + } + result = static_cast(hash_code); + result = result < 0 ? -result : result; + if (OB_SUCC(ret)) { + COMMON_LOG(TRACE, "succ to calc hash value with oracle mode", KP(objs), K(objs[0]), K(objs_cnt), K(result), K(ret)); + } else { + COMMON_LOG(WARN, "fail to calc hash value with oracle mode", KP(objs), K(objs_cnt), K(result), K(ret)); + } + return ret; +} - lib::set_oracle_mode(false); - - // calculate logic partition - if (OB_SUCC(ret)) { - int64_t N = 0; - int64_t powN = 0; - const static int64_t max_part_num_log2 = 64; - - int64_t result_num = static_cast(hash_val); - result_num = result_num < 0 ? -result_num : result_num; - - N = static_cast(std::log(part_num_) / std::log(2)); - if (N >= max_part_num_log2) { - ret = OB_ERR_UNEXPECTED; - COMMON_LOG(WARN, "result is too big", K(N), K(part_num_), K(result_num)); +int ObPartDescHash::calc_value_for_mysql(const ObObj *obj, int64_t &result) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(obj)) { + ret = OB_ERR_UNEXPECTED; + COMMON_LOG(WARN, "unexpected null ptr", K(ret)); + } else if (OB_UNLIKELY(obj->is_null())) { + result = 0; + } else { + int64_t num = 0; + if (OB_FAIL(obj->get_int(num))) { + COMMON_LOG(WARN, "fail to get int", K(obj), K(ret)); + } else { + if (OB_UNLIKELY(INT64_MIN == num)) { + num = INT64_MAX; } else { - powN = (1ULL << N); - part_idx = result_num % powN; - if (part_idx + powN < part_num_ && (result_num & powN) == powN) { - part_idx += powN; - } + num = num < 0 ? -num : num; } - COMMON_LOG(DEBUG, "get hash part idx for oracle mode", - K(ret), K(result_num), K(part_num_), K(N), K(powN), K(part_idx)); + result = num; } } - + COMMON_LOG(TRACE, "calc hash value with mysql mode", K(ret)); return ret; } -int ObPartDescHash::calc_value_for_mysql(ObObj &src_obj, ObIAllocator &allocator, int64_t &part_idx) +int ObPartDescHash::calc_hash_part_idx(const uint64_t val, + const int64_t part_num, + int64_t &partition_idx) { int ret = OB_SUCCESS; - - ObCastCtx cast_ctx(&allocator, NULL, CM_NULL_ON_WARN, CS_TYPE_INVALID); - ObObjType target_type = ObIntType; - if (OB_FAIL(ObObjCasterV2::to_type(target_type, cs_type_, cast_ctx, src_obj, src_obj))) { - COMMON_LOG(INFO, "failed to cast to target type", K(target_type), K(src_obj), K(ret)); - } else { - int64_t val = 0; - if (OB_FAIL(src_obj.get_int(val))) { - COMMON_LOG(WARN, "fail to get int", K(src_obj), K(ret)); + int64_t N = 0; + int64_t powN = 0; + const static int64_t max_part_num_log2 = 64; + // This function is used by SQL. Should ensure SQL runs in MySQL mode when query sys table. + if (is_oracle_mode_) { + // It will not be a negative number, so use forced conversion instead of floor + N = static_cast(std::log(part_num) / std::log(2)); + if (N >= max_part_num_log2) { + ret = OB_ERR_UNEXPECTED; + COMMON_LOG(WARN, "result is too big", K(N), K(part_num), K(val)); } else { - if (OB_UNLIKELY(INT64_MIN == val)) { - val = INT64_MAX; - } else { - val = val < 0 ? -val : val; + powN = (1ULL << N); + partition_idx = val & (powN - 1); //pow(2, N)); + if (partition_idx + powN < part_num && (val & powN) == powN) { + partition_idx += powN; } - part_idx = val % part_num_; - COMMON_LOG(DEBUG, "get hash part idx for mysql mode", K(ret), K(val), K(part_num_), K(part_idx)); } + COMMON_LOG(DEBUG, "get hash part idx", K(lbt()), K(ret), K(val), K(part_num), K(N), K(powN), K(partition_idx)); + } else { + partition_idx = val % part_num; + COMMON_LOG(DEBUG, "get hash part idx", K(lbt()), K(ret), K(val), K(part_num), K(partition_idx)); } - return ret; } diff --git a/src/share/part/ob_part_desc_hash.h b/src/share/part/ob_part_desc_hash.h index ffe7b0a8b..2d5b10eef 100644 --- a/src/share/part/ob_part_desc_hash.h +++ b/src/share/part/ob_part_desc_hash.h @@ -16,6 +16,7 @@ //#include "common/ob_object.h" #include "share/part/ob_part_desc.h" #include "share/part/ob_part_mgr_util.h" +#include "proxy/route/obproxy_part_mgr.h" namespace oceanbase { @@ -38,11 +39,12 @@ class ObPartDescHash : public ObPartDesc void set_part_space(int64_t part_space) { part_space_ = part_space; } void set_first_part_id(int64_t first_part_id) { first_part_id_ = first_part_id; } int64_t get_first_part_id() { return first_part_id_; } - void set_part_key_type(const ObObjType obj_type) { obj_type_ = obj_type; } - void set_part_key_cs_type(const ObCollationType cs_type) { cs_type_ = cs_type; } void set_part_array(int64_t *part_array) { part_array_ = part_array; } void set_oracle_mode(bool is_oracle_mode) { is_oracle_mode_ = is_oracle_mode; } + ObIArray &get_obj_types() { return obj_types_; } + ObIArray &get_cs_types() { return cs_types_; } + VIRTUAL_TO_STRING_KV("part_type", "hash", K_(is_oracle_mode), K_(part_num), @@ -52,18 +54,19 @@ class ObPartDescHash : public ObPartDesc private: uint64_t calc_hash_value_with_seed(const ObObj &obj, const int64_t cluster_version, int64_t seed); bool is_oracle_supported_type(const ObObjType type); - int calc_value_for_oracle(ObObj &src_obj, ObIAllocator &allocator, int64_t &part_idx, ObPartDescCtx &ctx); - int calc_value_for_mysql(ObObj &src_obj, ObIAllocator &allocator, int64_t &part_idx); + int calc_value_for_oracle(const ObObj *objs, int64_t objs_cnt, int64_t &result, ObPartDescCtx &ctx); + int calc_value_for_mysql(const ObObj *obj, int64_t &result); int get_part_hash_idx(const int64_t part_idx, int64_t &part_id); + int calc_hash_part_idx(const uint64_t val, const int64_t part_num, int64_t &partition_idx); private: bool is_oracle_mode_; int64_t part_num_; int64_t part_space_; int64_t first_part_id_; - // TODO: add multiple key - ObObjType obj_type_; - ObCollationType cs_type_; + // multiple key + ObSEArray obj_types_; + ObSEArray cs_types_; int64_t *part_array_; }; } diff --git a/src/share/part/ob_part_desc_key.cpp b/src/share/part/ob_part_desc_key.cpp index fa027bb71..86127731a 100644 --- a/src/share/part/ob_part_desc_key.cpp +++ b/src/share/part/ob_part_desc_key.cpp @@ -22,16 +22,18 @@ namespace common ObPartDescKey::ObPartDescKey() : part_num_(0) , part_space_(0) , first_part_id_(0) - , obj_type_(ObMaxType) - , cs_type_(CS_TYPE_INVALID) , part_array_(NULL) { } - -/* +/** GET PARTITION ID - - If input is not single int value, return invalid argument; otherwise, get the particular one. + Hash partition only route like 'by key(c1,c2) ... where c1=xx and c2=xx', + only use range.start_key_ to calc, because when condition is like 'c1=xx', + start_key_[i] == end_key_[i] + @param range (xxx,yyy,min,min ; xxx,yyy,max,max) + @param allocator + @param part_ids[out] + @param ctx */ int ObPartDescKey::get_part(ObNewRange &range, ObIAllocator &allocator, @@ -40,69 +42,126 @@ int ObPartDescKey::get_part(ObNewRange &range, ObIArray &tablet_ids) { int ret = OB_SUCCESS; + // provide all objs are valid. + // "valid" means the obj not min or max + int64_t valid_obj_cnt = range.start_key_.get_obj_cnt(); + // cast objs store in range.start_key_ + for (int64_t i = 0; OB_SUCC(ret) && i < range.start_key_.get_obj_cnt(); i++) { + // if obj is min or max, means all valid obj has been casted + if (range.start_key_.get_obj_ptr()[i].is_max_value() || + range.start_key_.get_obj_ptr()[i].is_min_value()) { + // minus the number of invalid obj + valid_obj_cnt = valid_obj_cnt - (range.start_key_.get_obj_cnt() - i); + // not need to cast any more and break loop + if (valid_obj_cnt == 0) { + ret = OB_INVALID_ARGUMENT; + COMMON_LOG(WARN, "not support key partition calc with range", K(range)); + } + break; + } else { + ObObj *src_obj = const_cast(&range.start_key_.get_obj_ptr()[i]); + // here src_obj shouldn't be null + if (OB_ISNULL(src_obj)) { + ret = OB_ERR_NULL_VALUE; + COMMON_LOG(ERROR, "unexpected null pointer src_obj"); + break; + } else if (src_obj->is_null()) { + // here src_obj shouldn't be null type + ret = OB_OBJ_TYPE_ERROR; + COMMON_LOG(ERROR, "unexpected null type", K(src_obj)); + } else if(OB_FAIL(cast_obj(*src_obj, obj_types_[i], cs_types_[i], allocator, ctx, accuracies_.at(i)))) { + COMMON_LOG(WARN, "cast obj failed", K(src_obj), "obj_type", obj_types_[i], "cs_type", cs_types_[i]); + // TODO: handle failure + } + } - if (1 != range.get_start_key().get_obj_cnt()) { // single value - ret = OB_INVALID_ARGUMENT; - COMMON_LOG(WARN, "key part should be single key", - "obj_cnt", range.get_start_key().get_obj_cnt(), K(ret)); - } else { - ObTimeZoneInfo tz_info; - ObDataTypeCastParams dtc_params; - if (OB_FAIL(obproxy::proxy::ObExprCalcTool::build_dtc_params_with_tz_info(ctx.get_session_info(), - obj_type_, tz_info, dtc_params))) { - COMMON_LOG(WARN, "fail to build dtc params with ctx session", K(ret), K(obj_type_)); + } + + int64_t part_idx = -1; + if (OB_SUCC(ret)) { + // hash val + int64_t result = 0; + int64_t part_id = -1; + if (OB_FAIL(calc_value_for_mysql(range.start_key_.get_obj_ptr(), valid_obj_cnt, result, ctx))) { + COMMON_LOG(WARN, "fail to cal key val", K(ret), K(valid_obj_cnt)); + } else if (OB_FAIL(calc_key_part_idx(result, part_num_, part_idx))) { + COMMON_LOG(WARN, "fail to cal key part idx", K(ret), K(result), K(part_num_)); + } else if (OB_FAIL(get_part_hash_idx(part_idx, part_id))) { + COMMON_LOG(WARN, "fail to get part key id", K(part_idx), K(ret)); + } else if (OB_FAIL(part_ids.push_back(part_id))) { + COMMON_LOG(WARN, "fail to push part_id", K(ret)); + } else if (NULL != tablet_id_array_ && OB_FAIL(tablet_ids.push_back(tablet_id_array_[part_idx]))) { + COMMON_LOG(WARN, "fail to push tablet id", K(ret)); + } else {} + } + + return ret; +} + + +int ObPartDescKey::calc_value_for_mysql(const ObObj *objs, + int64_t objs_cnt, + int64_t &result, + ObPartDescCtx &ctx) +{ + int ret = OB_SUCCESS; + uint64_t hash_code = 0; + if (OB_ISNULL(objs) || 0 == objs_cnt) { + ret = OB_ERR_UNEXPECTED; + COMMON_LOG(WARN, "objs_stack is null or number incorrect", K(objs), K(objs_cnt), K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < objs_cnt; ++i) { + const ObObj &obj = objs[i]; + if (ObNullType == obj.get_type()) { + //do nothing, hash_code not changed } else { - ObCastCtx cast_ctx(&allocator, &dtc_params, CM_NULL_ON_WARN, cs_type_); - ObObj &src_obj = const_cast(range.get_start_key().get_obj_ptr()[0]); - const ObObj *res_obj = &src_obj; - ObAccuracy accuracy(accuracy_.valid_, accuracy_.length_, accuracy_.precision_, accuracy_.scale_); - - // use src_obj as buf_obj - if (OB_FAIL(ObObjCasterV2::to_type(obj_type_, cs_type_, cast_ctx, src_obj, src_obj))) { - COMMON_LOG(WARN, "fail to cast obj", K(ret), K(src_obj), K(obj_type_), K(cs_type_)); - } else if (ctx.need_accurate() - && OB_FAIL(obj_accuracy_check(cast_ctx, accuracy, cs_type_, *res_obj, src_obj, res_obj))) { - COMMON_LOG(WARN, "fail to obj accuracy check", K(ret), K(src_obj), K(obj_type_)); - } else { - int64_t result_num = 0; - if ((IS_CLUSTER_VERSION_LESS_THAN_V4(ctx.get_cluster_version()) - && (share::schema::PARTITION_FUNC_TYPE_KEY_V3 == part_func_type_ - || share::schema::PARTITION_FUNC_TYPE_KEY_IMPLICIT_V2 == part_func_type_)) - || (!IS_CLUSTER_VERSION_LESS_THAN_V4(ctx.get_cluster_version()))) { - result_num = static_cast(src_obj.hash_murmur()); - } else { - result_num = static_cast(src_obj.hash()); - } - result_num = result_num < 0 ? -result_num : result_num; - int64_t part_idx = result_num % part_num_; - int64_t part_id = part_idx; - if (share::schema::PARTITION_LEVEL_ONE == part_level_ && NULL != part_array_) { - part_id = part_array_[part_idx]; - } - part_id = part_space_ << OB_PART_IDS_BITNUM | part_id; - if (OB_FAIL(part_ids.push_back(part_id))) { - COMMON_LOG(WARN, "fail to push part_id", K(ret)); - } else if (NULL != tablet_id_array_ && OB_FAIL(tablet_ids.push_back(tablet_id_array_[part_idx]))) { - COMMON_LOG(WARN, "fail to push tablet id", K(ret)); - } - } + hash_code = calc_hash_value_with_seed(obj, ctx.get_cluster_version(), hash_code); } } + result = static_cast(hash_code); + result = result < 0 ? -result : result; + if (OB_SUCC(ret)) { + COMMON_LOG(TRACE, "succ to calc hash value with oracle mode", KP(objs), K(objs[0]), K(objs_cnt), K(result), K(ret)); + } else { + COMMON_LOG(WARN, "fail to calc hash value with oracle mode", KP(objs), K(objs_cnt), K(result), K(ret)); + } + return ret; +} + +uint64_t ObPartDescKey::calc_hash_value_with_seed(const ObObj &obj, const int64_t cluster_version, int64_t seed) +{ + int64_t hval = 0; + if ((IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version) + && (share::schema::PARTITION_FUNC_TYPE_KEY_V3 == part_func_type_ + || share::schema::PARTITION_FUNC_TYPE_KEY_IMPLICIT_V2 == part_func_type_)) + || (!IS_CLUSTER_VERSION_LESS_THAN_V4(cluster_version))) { + hval = static_cast(obj.hash_murmur(seed)); + } else { + hval = static_cast(obj.hash(seed)); + } + return hval; +} + +int ObPartDescKey::calc_key_part_idx(const uint64_t val, + const int64_t part_num, + int64_t &partition_idx) +{ + int ret = OB_SUCCESS; + partition_idx = val % part_num; + COMMON_LOG(DEBUG, "get hash part idx", K(lbt()), K(ret), K(val), K(part_num), K(partition_idx)); return ret; } int ObPartDescKey::get_part_by_num(const int64_t num, common::ObIArray &part_ids, common::ObIArray &tablet_ids) { int ret = OB_SUCCESS; + int64_t part_id = -1; int64_t part_idx = num % part_num_; - int64_t part_id = part_idx; - if (share::schema::PARTITION_LEVEL_ONE == part_level_ && part_array_ != NULL) { - part_id = part_array_[part_idx]; - } - part_id = part_space_ << OB_PART_IDS_BITNUM | part_id; - if (OB_FAIL(part_ids.push_back(part_id))) { + if (OB_FAIL(get_part_hash_idx(part_idx, part_id))) { + COMMON_LOG(WARN, "fail to get part hash id", K(num), K(ret)); + } else if (OB_FAIL(part_ids.push_back(part_id))) { COMMON_LOG(WARN, "fail to push part_id", K(ret)); } else if (NULL != tablet_id_array_ && OB_FAIL(tablet_ids.push_back(tablet_id_array_[part_idx]))) { COMMON_LOG(WARN, "fail to push tablet id", K(ret)); @@ -110,6 +169,22 @@ int ObPartDescKey::get_part_by_num(const int64_t num, common::ObIArray return ret; } +int ObPartDescKey::get_part_hash_idx(const int64_t part_idx, int64_t &part_id) +{ + int ret =OB_SUCCESS; + + part_id = part_idx; + if (share::schema::PARTITION_LEVEL_ONE == part_level_) { + if (part_idx >= 0 && NULL != part_array_) { + part_id = part_array_[part_idx]; + } + } + if (OB_SUCC(ret)) { + part_id = part_space_ << OB_PART_IDS_BITNUM | part_id; + COMMON_LOG(DEBUG, "get hash part id", K(ret), K(part_num_), K(part_id)); + } + return ret; +} } // end of common -} // end of oceanbase +} diff --git a/src/share/part/ob_part_desc_key.h b/src/share/part/ob_part_desc_key.h index ebc48a229..f1b66763c 100644 --- a/src/share/part/ob_part_desc_key.h +++ b/src/share/part/ob_part_desc_key.h @@ -15,7 +15,7 @@ #include "share/part/ob_part_desc.h" #include "share/part/ob_part_mgr_util.h" - +#include "proxy/route/obproxy_part_mgr.h" namespace oceanbase { namespace common @@ -36,23 +36,30 @@ class ObPartDescKey : public ObPartDesc void set_part_space(int64_t part_space) { part_space_ = part_space; } void set_first_part_id(int64_t first_part_id) { first_part_id_ = first_part_id; } int64_t get_first_part_id() { return first_part_id_; } - void set_part_key_type(const ObObjType obj_type) { obj_type_ = obj_type; } - void set_part_key_cs_type(const ObCollationType cs_type) { cs_type_ = cs_type; } void set_part_array(int64_t *part_array) { part_array_ = part_array; } + ObIArray &get_obj_types() { return obj_types_; } + ObIArray &get_cs_types() { return cs_types_; } + VIRTUAL_TO_STRING_KV("part_type", "key", K_(part_num), K_(part_space), K_(first_part_id), K_(part_level), K_(part_func_type)); +private: + int calc_value_for_mysql(const ObObj *objs, int64_t objs_cnt, int64_t &result, ObPartDescCtx &ctx); + uint64_t calc_hash_value_with_seed(const ObObj &obj, const int64_t cluster_version, int64_t seed); + int calc_key_part_idx(const uint64_t val, const int64_t part_num, int64_t &partition_idx); + int get_part_hash_idx(const int64_t part_idx, int64_t &part_id); + private: int64_t part_num_; int64_t part_space_; int64_t first_part_id_; - // TODO: add multiple key - ObObjType obj_type_; - ObCollationType cs_type_; + // multiple key + ObSEArray obj_types_; + ObSEArray cs_types_; int64_t *part_array_; }; diff --git a/src/share/part/ob_part_desc_list.cpp b/src/share/part/ob_part_desc_list.cpp index 44552d4a9..1f23817f1 100644 --- a/src/share/part/ob_part_desc_list.cpp +++ b/src/share/part/ob_part_desc_list.cpp @@ -53,50 +53,54 @@ int ObPartDescList::get_part(ObNewRange &range, ObIArray &tablet_ids) { int ret = OB_SUCCESS; - + ObNewRow src_row; + // for list partition, row in start_key_ + src_row.assign(const_cast(range.start_key_.get_obj_ptr()), range.start_key_.get_obj_cnt()); if (OB_ISNULL(part_array_) || OB_UNLIKELY(part_array_size_ <= 0)) { ret = OB_INVALID_ARGUMENT; COMMON_LOG(WARN, "invalid argument, ", K_(part_array), K_(part_array_size), K(ret)); // use the fisrt range as the type to cast - } else if (1 != range.get_start_key().get_obj_cnt()) { // single value - ret = OB_INVALID_ARGUMENT; - COMMON_LOG(DEBUG, "list part should be single key", - "obj_cnt", range.get_start_key().get_obj_cnt(), K(ret)); } else { - ObObj &src_obj = const_cast(range.get_start_key().get_obj_ptr()[0]); - // use the first row cell as target obj - ObObj &target_obj = const_cast(part_array_[0].rows_[0].get_cell(0)); - if (OB_FAIL(cast_obj(src_obj, target_obj, allocator, ctx))) { - COMMON_LOG(INFO, "fail to cast obj", K(src_obj), K(target_obj), K(ret)); - } else { - bool found = false; - for (int64_t i = 0; OB_SUCC(ret) && i < part_array_size_ && !found; ++i) { - if (i == default_part_array_idx_) { - continue; - } - for (int64_t j= 0; OB_SUCC(ret) && j < part_array_[i].rows_.count() && !found; ++j) { - if (part_array_[i].rows_[j].get_count() == 0) { - ret = OB_ERR_UNEXPECTED; - COMMON_LOG(WARN, "no cells in the row", K(part_array_[i].rows_[j]), K(ret)); - } else if (src_obj == part_array_[i].rows_[j].get_cell(0)) { + bool found = false; + bool casted = false; + // cast src_row and compare with part array + for (int64_t i = 0; i < part_array_size_ && !found; i++) { + if (i == default_part_array_idx_) { + continue; + } + for (int64_t j = 0; j < part_array_[i].rows_.count() && !found; j++) { + if (part_array_[i].rows_[j].get_count() == 0) { + ret = OB_ERR_UNEXPECTED; + COMMON_LOG(WARN, "no cells in the row", K(part_array_[i].rows_[j]), K(ret)); + } else { + // if not cast, cast first + if (!casted && OB_FAIL(cast_row(src_row, part_array_[i].rows_.at(j), allocator, ctx))) { + COMMON_LOG(WARN, "fail to cast row"); + continue; + } else { + casted = true; + } + // if casted, then compare + if (casted && src_row == part_array_[i].rows_.at(j)) { found = true; if (OB_FAIL(part_ids.push_back(part_array_[i].part_id_))) { COMMON_LOG(WARN, "fail to push part id", K(ret)); } else if (NULL != tablet_id_array_ && OB_FAIL(tablet_ids.push_back(tablet_id_array_[i]))) { COMMON_LOG(WARN, "fail to push tablet id", K(ret)); } - } // end found - } // end for rows - } // end for part_array - if (!found && OB_INVALID_INDEX != default_part_array_idx_) { - // if no row cell matches, use default partition - COMMON_LOG(DEBUG, "will use default partition id", K(src_obj), K(ret)); - if (OB_FAIL(part_ids.push_back(part_array_[default_part_array_idx_].part_id_))) { - COMMON_LOG(WARN, "fail to push part id", K(ret)); - } else if (NULL != tablet_id_array_ && OB_FAIL(tablet_ids.push_back(tablet_id_array_[default_part_array_idx_]))) { - COMMON_LOG(WARN, "fail to push tablet id", K(ret)); + } else {} } + } // end for rows + } // end for part_array + + if (!found && OB_INVALID_INDEX != default_part_array_idx_) { + // if no row matches, use default partition + COMMON_LOG(DEBUG, "will use default partition id", K(src_row), K(ret)); + if (OB_FAIL(part_ids.push_back(part_array_[default_part_array_idx_].part_id_))) { + COMMON_LOG(WARN, "fail to push part id", K(ret)); + } else if (NULL != tablet_id_array_ && OB_FAIL(tablet_ids.push_back(tablet_id_array_[default_part_array_idx_]))) { + COMMON_LOG(WARN, "fail to push tablet id", K(ret)); } } } @@ -115,34 +119,27 @@ int ObPartDescList::get_part_by_num(const int64_t num, common::ObIArray return ret; } -inline int ObPartDescList::cast_obj(ObObj &src_obj, - ObObj &target_obj, - ObIAllocator &allocator, - ObPartDescCtx &ctx) +int ObPartDescList::cast_row(ObNewRow &src_row, + ObNewRow &target_row, + ObIAllocator &allocator, + ObPartDescCtx &ctx) { int ret = OB_SUCCESS; - COMMON_LOG(DEBUG, "begin to cast obj for list", K(src_obj), K(target_obj)); - - ObTimeZoneInfo tz_info; - ObDataTypeCastParams dtc_params; - ObObjType obj_type = target_obj.get_type(); - - if (OB_FAIL(obproxy::proxy::ObExprCalcTool::build_dtc_params_with_tz_info(ctx.get_session_info(), - obj_type, tz_info, dtc_params))) { - COMMON_LOG(WARN, "fail to build dtc params with ctx session", K(ret), K(obj_type)); - } else { - ObCastCtx cast_ctx(&allocator, &dtc_params, CM_NULL_ON_WARN, target_obj.get_collation_type()); - const ObObj *res_obj = &src_obj; - ObAccuracy accuracy(accuracy_.valid_, accuracy_.length_, accuracy_.precision_, accuracy_.scale_); - - // use src_obj as buf_obj - if (OB_FAIL(ObObjCasterV2::to_type(obj_type, target_obj.get_collation_type(), cast_ctx, src_obj, src_obj))) { - COMMON_LOG(WARN, "failed to cast obj", K(ret), K(src_obj), K(target_obj)); - } else if (ctx.need_accurate() - && OB_FAIL(obj_accuracy_check(cast_ctx, accuracy, target_obj.get_collation_type(), *res_obj, src_obj, res_obj))) { - COMMON_LOG(WARN, "fail to obj accuracy check", K(ret), K(src_obj), K(obj_type)); + int64_t min_col_cnt = std::min(src_row.count_, target_row.count_); + for (int64_t i = 0; i < min_col_cnt && OB_SUCC(ret); ++i) { + if (src_row.get_cell(i).is_max_value() || + src_row.get_cell(i).is_min_value()) { + COMMON_LOG(DEBUG, "skip min/max obj"); + continue; + } + if (OB_FAIL(cast_obj(src_row.get_cell(i), + target_row.get_cell(i), + allocator, + ctx, + accuracies_.at(i)))) { + COMMON_LOG(INFO, "fail to cast obj", K(i), K(ret)); } else { - COMMON_LOG(DEBUG, "succ to cast obj for list", K(src_obj), K(target_obj)); + // do nothing } } diff --git a/src/share/part/ob_part_desc_list.h b/src/share/part/ob_part_desc_list.h index 13f5c3147..f324a5369 100644 --- a/src/share/part/ob_part_desc_list.h +++ b/src/share/part/ob_part_desc_list.h @@ -16,6 +16,7 @@ #include "share/part/ob_part_desc.h" #include "common/ob_row.h" #include "lib/container/ob_se_array.h" +#include "proxy/route/obproxy_part_mgr.h" namespace oceanbase { @@ -54,12 +55,13 @@ class ObPartDescList : public ObPartDesc return OB_SUCCESS; } - DECLARE_VIRTUAL_TO_STRING; -private: - int cast_obj(ObObj &src_obj, - ObObj &target_obj, + int cast_row(ObNewRow &src_row, + ObNewRow &target_row, ObIAllocator &allocator, ObPartDescCtx &ctx); + + DECLARE_VIRTUAL_TO_STRING; + private: ListPartition *part_array_; int64_t part_array_size_; diff --git a/src/share/part/ob_part_desc_range.cpp b/src/share/part/ob_part_desc_range.cpp index c8821ce6f..120049b04 100644 --- a/src/share/part/ob_part_desc_range.cpp +++ b/src/share/part/ob_part_desc_range.cpp @@ -173,17 +173,23 @@ int ObPartDescRange::get_part_by_num(const int64_t num, common::ObIArray(src_key.get_obj_ptr()[i]), const_cast(target_key.get_obj_ptr()[i]), allocator, - ctx))) { + ctx, + accuracies_.at(i)))) { COMMON_LOG(INFO, "fail to cast obj", K(i), K(ret)); } else { // do nothing @@ -192,39 +198,5 @@ int ObPartDescRange::cast_key(ObRowkey &src_key, return ret; } -inline int ObPartDescRange::cast_obj(ObObj &src_obj, - ObObj &target_obj, - ObIAllocator &allocator, - ObPartDescCtx &ctx) -{ - int ret = OB_SUCCESS; - COMMON_LOG(DEBUG, "begin to cast obj for range", K(src_obj), K(target_obj)); - - ObTimeZoneInfo tz_info; - ObDataTypeCastParams dtc_params; - ObObjType obj_type = target_obj.get_type(); - - if (OB_FAIL(obproxy::proxy::ObExprCalcTool::build_dtc_params_with_tz_info(ctx.get_session_info(), - obj_type, tz_info, dtc_params))) { - COMMON_LOG(WARN, "fail to build dtc params with ctx session", K(ret), K(obj_type)); - } else { - ObCastCtx cast_ctx(&allocator, &dtc_params, CM_NULL_ON_WARN, target_obj.get_collation_type()); - const ObObj *res_obj = &src_obj; - ObAccuracy accuracy(accuracy_.valid_, accuracy_.length_, accuracy_.precision_, accuracy_.scale_); - - // use src_obj as buf_obj - if (OB_FAIL(ObObjCasterV2::to_type(obj_type, target_obj.get_collation_type(), cast_ctx, src_obj, src_obj))) { - COMMON_LOG(WARN, "failed to cast obj", K(ret), K(src_obj), K(target_obj)); - } else if (ctx.need_accurate() - && OB_FAIL(obj_accuracy_check(cast_ctx, accuracy, target_obj.get_collation_type(), *res_obj, src_obj, res_obj))) { - COMMON_LOG(WARN, "fail to obj accuracy check", K(ret), K(src_obj)); - } else { - COMMON_LOG(DEBUG, "end to cast obj for range", K(src_obj), K(target_obj)); - } - } - - return ret; -} - } // end of common } // end of oceanbase diff --git a/src/share/part/ob_part_desc_range.h b/src/share/part/ob_part_desc_range.h index 24f343c17..6baabf8a8 100644 --- a/src/share/part/ob_part_desc_range.h +++ b/src/share/part/ob_part_desc_range.h @@ -15,6 +15,7 @@ #include "share/part/ob_part_desc.h" #include "lib/container/ob_se_array.h" +#include "proxy/route/obproxy_part_mgr.h" namespace oceanbase { @@ -54,6 +55,11 @@ class ObPartDescRange : public ObPartDesc return common::OB_SUCCESS; } + int cast_key(ObRowkey &src_key, + ObRowkey &target_key, + ObIAllocator &allocator, + ObPartDescCtx &ctx); + DECLARE_VIRTUAL_TO_STRING; private: int64_t get_start(const RangePartition *part_array, @@ -64,15 +70,6 @@ class ObPartDescRange : public ObPartDesc const int64_t size, const ObNewRange &range); - int cast_key(ObRowkey &src_key, - ObRowkey &target_key, - ObIAllocator &allocator, - ObPartDescCtx &ctx); - - int cast_obj(ObObj &src_obj, - ObObj &target_obj, - ObIAllocator &allocator, - ObPartDescCtx &ctx); private: RangePartition *part_array_; int64_t part_array_size_; diff --git a/unittest/obproxy/ob_expr_parser_checker.cpp b/unittest/obproxy/ob_expr_parser_checker.cpp index efe5218b1..c6d61cc46 100644 --- a/unittest/obproxy/ob_expr_parser_checker.cpp +++ b/unittest/obproxy/ob_expr_parser_checker.cpp @@ -124,7 +124,6 @@ void ObExprParserChecker::build_schema(std::string &extra_str, ObExprParseResult } result.part_key_info_.key_num_ = 0; - result.target_mask_ = 0; while (true) { ObProxyParseString part_key_name = get_value(extra_str, "part_key", pos); ObProxyParseString part_key_level = get_value(extra_str, "part_level", pos); @@ -143,11 +142,6 @@ void ObExprParserChecker::build_schema(std::string &extra_str, ObExprParseResult result.part_key_info_.part_keys_[result.part_key_info_.key_num_].idx_ = part_key_idx.str_[0] - '0'; } ++result.part_key_info_.key_num_; - if (PART_KEY_LEVEL_ONE == level) { - result.target_mask_ |= BOTH_BOUND_FLAG; - } else { - result.target_mask_ |= (BOTH_BOUND_FLAG << 2); - } } } } diff --git a/unittest/obproxy/obproxy_parser_test.cpp b/unittest/obproxy/obproxy_parser_test.cpp index 4e45de08c..0a8ab8d02 100755 --- a/unittest/obproxy/obproxy_parser_test.cpp +++ b/unittest/obproxy/obproxy_parser_test.cpp @@ -51,19 +51,19 @@ void show_sql_result(SqlFieldResult& sql_result) { fprintf(stdout, "========== sql_result is ===========\n"); for(int i = 0; i < sql_result.field_num_; i++) { char buf[256]; - printf("column_name:length:%d\t", sql_result.fields_[i].column_name_.string_.length()); + printf("column_name:length:%d\t", sql_result.fields_[i]->column_name_.config_string_.length()); snprintf(buf, 256, "column_name:%.*s", - sql_result.fields_[i].column_name_.string_.length(), - sql_result.fields_[i].column_name_.string_.ptr()); + sql_result.fields_[i]->column_name_.config_string_.length(), + sql_result.fields_[i]->column_name_.config_string_.ptr()); printf("%s\t", buf); //printf(" %s ", function_type_to_string(sql_result.fields_[i].type_).c_str()); - printf(" (%s) ", token_type_to_string(sql_result.fields_[i].value_type_).c_str()); - if(sql_result.fields_[i].value_type_ == TOKEN_INT_VAL) { - snprintf(buf, 256, "column_value:%ld", sql_result.fields_[i].column_int_value_); - } else if (sql_result.fields_[i].value_type_ == TOKEN_STR_VAL){ - snprintf(buf, sql_result.fields_[i].column_value_.config_string_.length()+1, "column_value:%.*s", - sql_result.fields_[i].column_value_.config_string_.length(), - sql_result.fields_[i].column_value_.config_string_.ptr()); + printf(" (%s) ", token_type_to_string(sql_result.fields_[i]->value_type_).c_str()); + if(sql_result.fields_[i]->value_type_ == TOKEN_INT_VAL) { + snprintf(buf, 256, "column_value:%ld", sql_result.fields_[i]->column_int_value_); + } else if (sql_result.fields_[i]->value_type_ == TOKEN_STR_VAL){ + snprintf(buf, sql_result.fields_[i]->column_value_.config_string_.length()+1, "column_value:%.*s", + sql_result.fields_[i]->column_value_.config_string_.length(), + sql_result.fields_[i]->column_value_.config_string_.ptr()); } printf("%s\n", buf); // fprintf(stdout, "%s %s %s\n", sql_result.fields_[i].column_name_, @@ -137,7 +137,6 @@ void build_schema(std::string &extra_str, ObExprParseResult &result) pos = 0; result.part_key_info_.key_num_ = 0; - result.target_mask_ = 0; while (true) { ObProxyParseString part_key_name = get_value(extra_str, "part_key", pos); ObProxyParseString part_key_level = get_value(extra_str, "part_level", pos); @@ -162,11 +161,6 @@ void build_schema(std::string &extra_str, ObExprParseResult &result) result.part_key_info_.part_keys_[result.part_key_info_.key_num_].idx_ = part_key_idx.str_[0] - '0'; } ++result.part_key_info_.key_num_; - if (PART_KEY_LEVEL_ONE == level) { - result.target_mask_ |= BOTH_BOUND_FLAG; - } else { - result.target_mask_ |= (BOTH_BOUND_FLAG << 2); - } } } } @@ -207,8 +201,8 @@ void extract_local_fileds(const ObExprParseResult& result, ObProxyMysqlRequest & printf("Got an empty relation_expr"); continue; } - SqlField field; - field.reset(); + SqlField *field = NULL; + SqlField::alloc_sql_field(field); //sql_result.fields_[sql_result.field_num_].type_ = relation_expr->type_; if(relation_expr->left_value_ != NULL && relation_expr->left_value_->head_ != NULL @@ -217,9 +211,9 @@ void extract_local_fileds(const ObExprParseResult& result, ObProxyMysqlRequest & ObString tmp_column(relation_expr->left_value_->head_->column_name_.str_len_, relation_expr->left_value_->head_->column_name_.str_); LOG_DEBUG("column_name is ", K(tmp_column)); - field.column_name_.set(tmp_column); + field->column_name_.set_value(tmp_column); - LOG_DEBUG("field.column", K(field.column_name_)); + LOG_DEBUG("field->column", K(field->column_name_)); // strncpy(sql_result.fields_[sql_result.field_num_].column_name_, // relation_expr->left_value_->head_->column_name_.str_, // relation_expr->left_value_->head_->column_name_.str_len_); @@ -234,19 +228,19 @@ void extract_local_fileds(const ObExprParseResult& result, ObProxyMysqlRequest & if(relation_expr->right_value_ != NULL && relation_expr->right_value_->head_ != NULL) { if(relation_expr->right_value_->head_->type_ == TOKEN_INT_VAL) { - field.value_type_ = TOKEN_INT_VAL; - field.column_int_value_ = relation_expr->right_value_->head_->int_value_; - LOG_DEBUG("field.value", K(field.column_int_value_)); + field->value_type_ = TOKEN_INT_VAL; + field->column_int_value_ = relation_expr->right_value_->head_->int_value_; + LOG_DEBUG("field->value", K(field->column_int_value_)); // snprintf(sql_result.fields_[sql_result.field_num_].column_value_, // 32, "%ld", relation_expr->right_value_->head_->int_value_); // sql_result.fields_[sql_result.field_num_].column_value_ = ""; // sql_result.fields_[sql_result.field_num_].column_value_ = std::string(buf); } else if(relation_expr->right_value_->head_->type_ == TOKEN_STR_VAL) { - field.value_type_ = TOKEN_STR_VAL; - field.column_value_.config_string_.assign_ptr( + field->value_type_ = TOKEN_STR_VAL; + field->column_value_.config_string_.assign_ptr( relation_expr->right_value_->head_->str_value_.str_, relation_expr->right_value_->head_->str_value_.str_len_); - LOG_DEBUG("field.column_value", K(field.column_value_)); + LOG_DEBUG("field->column_value", K(field->column_value_)); // strncpy(sql_result.fields_[sql_result.field_num_].column_value_, // relation_expr->right_value_->head_->str_value_.str_, diff --git a/unittest/obproxy/test_ldc_location.cpp b/unittest/obproxy/test_ldc_location.cpp index 78a2fe34e..cc2c69fd2 100644 --- a/unittest/obproxy/test_ldc_location.cpp +++ b/unittest/obproxy/test_ldc_location.cpp @@ -27,7 +27,7 @@ EXPECT_TRUE(is_partition_server == item->is_partition_server_);\ EXPECT_TRUE(item->is_used_);\ EXPECT_FALSE(item->is_force_congested_);\ - EXPECT_EQ(ObAddr::convert_ipv4_addr(addr), item->replica_->server_.get_ipv4());\ + EXPECT_EQ(convert_ipv4_addr_utils(addr), item->replica_->server_.get_ipv4());\ EXPECT_EQ(port, item->replica_->server_.get_port());\ EXPECT_EQ(type1, test_ldc_route.get_curr_route_type());\ EXPECT_TRUE(!test_ldc_route.is_reach_end()); @@ -41,6 +41,25 @@ namespace obproxy namespace proxy { +static uint32_t convert_ipv4_addr_utils(const char *ip) +{ + in_addr binary; + int iret = 0; + uint32_t result = 0; + + if (!OB_ISNULL(ip)) { + memset(&binary, 0, sizeof (binary)); + iret = inet_pton(AF_INET, ip, &binary); + if (iret == -1) { // no support family + binary.s_addr = 0; + } else if (iret == 0) { // invalid ip string + binary.s_addr = 0; + } + result = ntohl(binary.s_addr); + } + return result; +} + class TesLDCLocation : public ::testing::Test { @@ -182,7 +201,7 @@ void TesLDCLocation::test_get_next_item(ObLDCRoute &test_ldc_route, ASSERT_TRUE(test_ldc_route.disable_merge_status_check_ || is_merge == item->is_merging_); ASSERT_TRUE(zone_type == item->zone_type_); ASSERT_TRUE(is_partition == item->is_partition_server_); - ASSERT_EQ(ObAddr::convert_ipv4_addr(ip_str), item->replica_->server_.get_ipv4()); + ASSERT_EQ(convert_ipv4_addr_utils(ip_str), item->replica_->server_.get_ipv4()); ASSERT_EQ(port, item->replica_->server_.get_port()); ASSERT_EQ(route_type, test_ldc_route.get_curr_route_type()); ASSERT_TRUE(!test_ldc_route.is_reach_end()); @@ -206,7 +225,7 @@ void TesLDCLocation::test_get_next_item(ObLDCRoute &test_ldc_route, ASSERT_TRUE(role == item->replica_->role_); } ASSERT_TRUE(is_partition == item->is_partition_server_); - ASSERT_EQ(ObAddr::convert_ipv4_addr(ip_str), item->replica_->server_.get_ipv4()); + ASSERT_EQ(convert_ipv4_addr_utils(ip_str), item->replica_->server_.get_ipv4()); ASSERT_EQ(port, item->replica_->server_.get_port()); ASSERT_EQ(route_type, test_ldc_route.get_curr_route_type()); ASSERT_TRUE(!test_ldc_route.is_reach_end()); @@ -429,15 +448,15 @@ TEST_F(TesLDCLocation, assign) ObLDCItem *item_array = const_cast(test_ldc.get_item_array()); for (int64_t i = 0; i < 10; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = 10; i < 25; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = 25; i < 40; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); } //empty name treat as do not use @@ -459,15 +478,15 @@ TEST_F(TesLDCLocation, assign) item_array = const_cast(test_ldc.get_item_array()); for (int64_t i = 0; i < 10; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = 10; i < 25; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = 25; i < 40; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); } //right name, but congestion is not available @@ -489,19 +508,19 @@ TEST_F(TesLDCLocation, assign) item_array = const_cast(test_ldc.get_item_array()); for (int64_t i = 0; i < 15; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = 15; i < 30; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = 30; i < 45; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = 45; i < 60; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("4.4.4.4"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("4.4.4.4"), item_array[i].replica_->server_.get_ipv4()); } //right name @@ -522,15 +541,15 @@ TEST_F(TesLDCLocation, assign) item_array = const_cast(test_ldc.get_item_array()); for (int64_t i = site_start_index_array[SAME_IDC]; i < site_start_index_array[SAME_REGION]; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = site_start_index_array[SAME_REGION]; i < site_start_index_array[OTHER_REGION]; i++) { EXPECT_EQ(SAME_REGION, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = site_start_index_array[OTHER_REGION]; i < site_start_index_array[MAX_IDC_TYPE]; i++) { EXPECT_EQ(OTHER_REGION, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = site_start_index_array[SAME_IDC]; i < site_start_index_array[SAME_IDC] + 5; i++) { @@ -646,11 +665,11 @@ TEST_F(TesLDCLocation, assign_other_region) ObLDCItem *item_array = const_cast(test_ldc.get_item_array()); for (int64_t i = site_start_index_array[SAME_IDC]; i < site_start_index_array[SAME_REGION]; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = site_start_index_array[OTHER_REGION]; i < site_start_index_array[MAX_IDC_TYPE]; i++) { EXPECT_EQ(OTHER_REGION, item_array[i].idc_type_); - EXPECT_NE(ObAddr::convert_ipv4_addr("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_NE(convert_ipv4_addr_utils("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = site_start_index_array[SAME_IDC]; i < site_start_index_array[SAME_IDC] + 5; i++) { @@ -747,15 +766,15 @@ TEST_F(TesLDCLocation, assign_non_ldc) ObLDCItem *item_array = const_cast(test_ldc.get_item_array()); for (int64_t i = 0; i < 10; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = 10; i < 25; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = 25; i < 40; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); } for (int64_t i = 0; i < 10; i++) { @@ -836,7 +855,7 @@ TEST_F(TesLDCLocation, fill_strong_read_location) ObString proxy_primary_zone_name; bool need_skip_leader = false; bool is_random_route_mode = false; - ASSERT_EQ(OB_ERR_UNEXPECTED, ObLDCLocation::fill_strong_read_location(&pl, dummy_ldc, leader_item, target_ldc, + ASSERT_EQ(OB_ERR_UNEXPECTED, ObLDCLocation::fill_strong_read_location(&pl, dummy_ldc, leader_item, target_ldc, entry_need_update, is_only_readwrite_zone, need_use_dup_replica, need_skip_leader, is_random_route_mode, servers_info, region_names, proxy_primary_zone_name, ObString(), NULL)); @@ -1343,19 +1362,19 @@ TEST_F(TesLDCLocation, get_next_item) item_array = const_cast(test_ldc.get_item_array()); for (int64_t i = site_start_index_array[SAME_IDC]; i < site_start_index_array[SAME_REGION]; i++) { EXPECT_EQ(SAME_IDC, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("1.1.1.1"), item_array[i].replica_->server_.get_ipv4()); EXPECT_EQ((i < 10 ? ZONE_TYPE_READWRITE : ZONE_TYPE_READONLY), item_array[i].zone_type_); EXPECT_TRUE((i % 10 < 5) == item_array[i].is_merging_); } for (int64_t i = site_start_index_array[SAME_REGION]; i < site_start_index_array[OTHER_REGION]; i++) { EXPECT_EQ(SAME_REGION, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("2.2.2.2"), item_array[i].replica_->server_.get_ipv4()); EXPECT_EQ((i < (10 + site_start_index_array[SAME_REGION])? ZONE_TYPE_READWRITE : ZONE_TYPE_READONLY), item_array[i].zone_type_); EXPECT_TRUE((i % 10 < 5) == item_array[i].is_merging_); } for (int64_t i = site_start_index_array[OTHER_REGION]; i < site_start_index_array[MAX_IDC_TYPE]; i++) { EXPECT_EQ(OTHER_REGION, item_array[i].idc_type_); - EXPECT_EQ(ObAddr::convert_ipv4_addr("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); + EXPECT_EQ(convert_ipv4_addr_utils("3.3.3.3"), item_array[i].replica_->server_.get_ipv4()); EXPECT_EQ((i < (10 + site_start_index_array[OTHER_REGION]) ? ZONE_TYPE_READWRITE : ZONE_TYPE_READONLY), item_array[i].zone_type_); EXPECT_TRUE((i % 10 < 5) == item_array[i].is_merging_); } diff --git a/unittest/obproxy/test_proxy_table_processor_utils.cpp b/unittest/obproxy/test_proxy_table_processor_utils.cpp index 02953428d..4b5e07870 100644 --- a/unittest/obproxy/test_proxy_table_processor_utils.cpp +++ b/unittest/obproxy/test_proxy_table_processor_utils.cpp @@ -42,8 +42,8 @@ TEST_F(TestProxyTableProcessorUtils, test_get_proxy_local_addr) ASSERT_EQ(addr, addr_org); ObAddr my_addr; - char ip_str[OB_IP_STR_BUFF] = {'\0'}; - int ret = ObProxyTableProcessorUtils::get_one_local_addr(ip_str, OB_IP_STR_BUFF); + char ip_str[MAX_IP_ADDR_LENGTH] = {'\0'}; + int ret = ObProxyTableProcessorUtils::get_one_local_addr(ip_str, MAX_IP_ADDR_LENGTH); ASSERT_EQ(OB_SUCCESS, ret); my_addr.set_ipv4_addr(ip_str, static_cast(config.listen_port)); @@ -63,15 +63,15 @@ TEST_F(TestProxyTableProcessorUtils, test_get_proxy_local_addr_inherited) int ret = OB_SUCCESS; ObHotUpgraderInfo &info = get_global_hot_upgrade_info(); info.is_inherited_ = true; - info.fd_ = NO_FD; + info.ipv4_fd_ = NO_FD; ObAddr addr; ret = ObProxyTableProcessorUtils::get_proxy_local_addr(addr); ASSERT_EQ(OB_ERR_UNEXPECTED, ret); - char ip_str[OB_IP_STR_BUFF] = {'\0'}; - ret = ObProxyTableProcessorUtils::get_one_local_addr(ip_str, OB_IP_STR_BUFF); + char ip_str[MAX_IP_ADDR_LENGTH] = {'\0'}; + ret = ObProxyTableProcessorUtils::get_one_local_addr(ip_str, MAX_IP_ADDR_LENGTH); ASSERT_EQ(OB_SUCCESS, ret); struct sockaddr_in s_add; @@ -87,7 +87,7 @@ TEST_F(TestProxyTableProcessorUtils, test_get_proxy_local_addr_inherited) close(test_fd); } ASSERT_TRUE(-1 != bind_ret); - info.fd_ = test_fd; + info.ipv4_fd_ = test_fd; ret = ObProxyTableProcessorUtils::get_proxy_local_addr(addr); ASSERT_EQ(OB_SUCCESS, ret); ObAddr addr2(ObAddr::IPV4, ip_str, port); @@ -107,7 +107,7 @@ TEST_F(TestProxyTableProcessorUtils, test_get_proxy_local_addr_inherited) close(test_fd); } ASSERT_TRUE(-1 != bind_ret); - info.fd_ = test_fd; + info.ipv4_fd_ = test_fd; ret = ObProxyTableProcessorUtils::get_proxy_local_addr(addr); ASSERT_EQ(OB_SUCCESS, ret); addr2.reset(); diff --git a/unittest/obproxy/test_tenant_processor.cpp b/unittest/obproxy/test_tenant_processor.cpp index fdfad609a..70c486859 100644 --- a/unittest/obproxy/test_tenant_processor.cpp +++ b/unittest/obproxy/test_tenant_processor.cpp @@ -28,7 +28,6 @@ * limitations under the License. */ -//#define private public #define USING_LOG_PREFIX PROXY #include #include @@ -357,21 +356,25 @@ TEST_F(TestTenantProcessor, test_execute) SqlFieldResult sql_result; sql_result.field_num_ = 4; - SqlField sql_field; - sql_field.column_name_.set("cluster"); - sql_field.column_value_.set_value("ob_cluster"); + SqlField *sql_field = NULL; + SqlField::alloc_sql_field(sql_field); + sql_field->column_name_.set_value("cluster"); + sql_field->column_value_.set_value("ob_cluster"); sql_result.fields_.push_back(sql_field); - sql_field.column_name_.set("tenant"); - sql_field.column_value_.set_value("ob_tenant"); + SqlField::alloc_sql_field(sql_field); + sql_field->column_name_.set_value("tenant"); + sql_field->column_value_.set_value("ob_tenant"); sql_result.fields_.push_back(sql_field); - sql_field.column_name_.set("name"); - sql_field.column_value_.set_value("resource_max_connections"); + SqlField::alloc_sql_field(sql_field); + sql_field->column_name_.set_value("name"); + sql_field->column_value_.set_value("resource_max_connections"); sql_result.fields_.push_back(sql_field); - sql_field.column_name_.set("value"); - sql_field.column_value_.set_value("[{\"vip\": \"127.0.0.1\", \"value\": 5000}]"); + SqlField::alloc_sql_field(sql_field); + sql_field->column_name_.set_value("value"); + sql_field->column_value_.set_value("[{\"vip\": \"127.0.0.1\", \"value\": 5000}]"); sql_result.fields_.push_back(sql_field); ObCloudFnParams cloud_params; @@ -403,21 +406,25 @@ TEST_F(TestTenantProcessor, test_rollback) SqlFieldResult sql_result; sql_result.field_num_ = 4; - SqlField sql_field; - sql_field.column_name_.set("cluster"); - sql_field.column_value_.set_value("ob_cluster"); + SqlField *sql_field = NULL; + SqlField::alloc_sql_field(sql_field); + sql_field->column_name_.set_value("cluster"); + sql_field->column_value_.set_value("ob_cluster"); sql_result.fields_.push_back(sql_field); - sql_field.column_name_.set("tenant"); - sql_field.column_value_.set_value("ob_tenant"); + SqlField::alloc_sql_field(sql_field); + sql_field->column_name_.set_value("tenant"); + sql_field->column_value_.set_value("ob_tenant"); sql_result.fields_.push_back(sql_field); - sql_field.column_name_.set("name"); - sql_field.column_value_.set_value("resource_max_connections"); + SqlField::alloc_sql_field(sql_field); + sql_field->column_name_.set_value("name"); + sql_field->column_value_.set_value("resource_max_connections"); sql_result.fields_.push_back(sql_field); - sql_field.column_name_.set("value"); - sql_field.column_value_.set_value("[{\"vip\": \"127.0.0.1\", \"value\": 5000}]"); + SqlField::alloc_sql_field(sql_field); + sql_field->column_name_.set_value("value"); + sql_field->column_value_.set_value("[{\"vip\": \"127.0.0.1\", \"value\": 5000}]"); sql_result.fields_.push_back(sql_field); ObCloudFnParams cloud_params; @@ -452,21 +459,21 @@ TEST_F(TestTenantProcessor, test_execute_update_value) SqlFieldResult sql_result; sql_result.field_num_ = 4; SqlField sql_field[4]; - sql_field[0].column_name_.set("cluster"); + sql_field[0].column_name_.set_value("cluster"); sql_field[0].column_value_.set_value("ob_cluster"); - sql_result.fields_.push_back(sql_field[0]); + sql_result.fields_.push_back(&sql_field[0]); - sql_field[1].column_name_.set("tenant"); + sql_field[1].column_name_.set_value("tenant"); sql_field[1].column_value_.set_value("ob_tenant"); - sql_result.fields_.push_back(sql_field[1]); + sql_result.fields_.push_back(&sql_field[1]); - sql_field[2].column_name_.set("name"); + sql_field[2].column_name_.set_value("name"); sql_field[2].column_value_.set_value("resource_max_connections"); - sql_result.fields_.push_back(sql_field[2]); + sql_result.fields_.push_back(&sql_field[2]); - sql_field[3].column_name_.set("value"); - sql_field[3].column_value_.set_value("[{\"vip\": \"127.0.0.1\", \"value\": 5000}, {\"vip\": \"127.0.0.2\", \"value\": 6000}]"); - sql_result.fields_.push_back(sql_field[3]); + sql_field[3].column_name_.set_value("value"); + sql_field[3].column_value_.set_value("[{\"vip\": \"127.0.0.1\", \"value\": 5000}, {\"vip\": \"10.8.17.120\", \"value\": 6000}]"); + sql_result.fields_.push_back(&sql_field[3]); ObCloudFnParams cloud_params; cloud_params.stmt_type_ = OBPROXY_T_REPLACE; @@ -487,14 +494,19 @@ TEST_F(TestTenantProcessor, test_execute_update_value) ObResourceUnitTableProcessor::commit(&cloud_params, true); LOG_DEBUG("success1"); + SqlField tmp_field[4]; + tmp_field[0] = sql_field[0]; + tmp_field[1] = sql_field[1]; + tmp_field[2] = sql_field[2]; + tmp_field[3] = sql_field[3]; sql_result.reset(); sql_result.field_num_ = 4; - sql_result.fields_.push_back(sql_field[0]); - sql_result.fields_.push_back(sql_field[1]); - sql_result.fields_.push_back(sql_field[2]); - sql_field[3].column_name_.set("value"); - sql_field[3].column_value_.set_value("[{\"vip\": \"127.0.0.3\", \"value\": 4000}, {\"vip\": \"127.0.0.2\", \"value\": 7777}]"); - sql_result.fields_.push_back(sql_field[3]); + sql_result.fields_.push_back(&tmp_field[0]); + sql_result.fields_.push_back(&tmp_field[1]); + sql_result.fields_.push_back(&tmp_field[2]); + sql_field[3].column_name_.set_value("value"); + sql_field[3].column_value_.set_value("[{\"vip\": \"127.0.0.3\", \"value\": 4000}, {\"vip\": \"10.8.17.120\", \"value\": 7777}]"); + sql_result.fields_.push_back(&tmp_field[3]); cloud_params.fields_ = &sql_result; ASSERT_EQ(0, ObResourceUnitTableProcessor::execute(&cloud_params)); @@ -527,21 +539,21 @@ TEST_F(TestTenantProcessor, test_delete_tenant) SqlFieldResult sql_result; sql_result.field_num_ = 4; SqlField sql_field[4]; - sql_field[0].column_name_.set("cluster"); + sql_field[0].column_name_.set_value("cluster"); sql_field[0].column_value_.set_value("ob_cluster"); - sql_result.fields_.push_back(sql_field[0]); + sql_result.fields_.push_back(&sql_field[0]); - sql_field[1].column_name_.set("tenant"); + sql_field[1].column_name_.set_value("tenant"); sql_field[1].column_value_.set_value("ob_tenant"); - sql_result.fields_.push_back(sql_field[1]); + sql_result.fields_.push_back(&sql_field[1]); - sql_field[2].column_name_.set("name"); + sql_field[2].column_name_.set_value("name"); sql_field[2].column_value_.set_value("resource_max_connections"); - sql_result.fields_.push_back(sql_field[2]); + sql_result.fields_.push_back(&sql_field[2]); - sql_field[3].column_name_.set("value"); - sql_field[3].column_value_.set_value("[{\"vip\": \"127.0.0.1\", \"value\": 5000}, {\"vip\": \"127.0.0.2\", \"value\": 6000}]"); - sql_result.fields_.push_back(sql_field[3]); + sql_field[3].column_name_.set_value("value"); + sql_field[3].column_value_.set_value("[{\"vip\": \"127.0.0.1\", \"value\": 5000}, {\"vip\": \"10.8.17.120\", \"value\": 6000}]"); + sql_result.fields_.push_back(&sql_field[3]); ObCloudFnParams cloud_params; cloud_params.stmt_type_ = OBPROXY_T_REPLACE; @@ -561,16 +573,21 @@ TEST_F(TestTenantProcessor, test_delete_tenant) ASSERT_EQ(0, check_map_value(conn_map, 2)); LOG_DEBUG("success1"); + SqlField tmp_field[4]; + tmp_field[0] = sql_field[0]; + tmp_field[1] = sql_field[1]; + tmp_field[2] = sql_field[2]; + tmp_field[3] = sql_field[3]; sql_result.reset(); sql_result.field_num_ = 4; - sql_result.fields_.push_back(sql_field[0]); - sql_field[1].column_name_.set("tenant"); + sql_result.fields_.push_back(&tmp_field[0]); + sql_field[1].column_name_.set_value("tenant"); sql_field[1].column_value_.set_value("ob_tenant_1"); - sql_result.fields_.push_back(sql_field[1]); - sql_result.fields_.push_back(sql_field[2]); - sql_field[3].column_name_.set("value"); - sql_field[3].column_value_.set_value("[{\"vip\": \"127.0.0.3\", \"value\": 4000}, {\"vip\": \"127.0.0.2\", \"value\": 7777}]"); - sql_result.fields_.push_back(sql_field[3]); + sql_result.fields_.push_back(&tmp_field[1]); + sql_result.fields_.push_back(&tmp_field[2]); + sql_field[3].column_name_.set_value("value"); + sql_field[3].column_value_.set_value("[{\"vip\": \"127.0.0.1\", \"value\": 4000}, {\"vip\": \"10.8.17.120\", \"value\": 7777}]"); + sql_result.fields_.push_back(&tmp_field[3]); cloud_params.fields_ = &sql_result; cloud_params.tenant_name_ = "ob_tenant_1"; diff --git a/unittest/obproxy/test_white_list_processor.cpp b/unittest/obproxy/test_white_list_processor.cpp index aec7a7281..564247a3b 100644 --- a/unittest/obproxy/test_white_list_processor.cpp +++ b/unittest/obproxy/test_white_list_processor.cpp @@ -53,19 +53,33 @@ TEST_F(TestWhiteListProcessor, test_ip_net) char ip2[32] = "127.0.0.3"; char ip3[32] = "127.0.0.4"; char ip4[32] = "127.0.0.5"; - ASSERT_EQ(true, white_list_processor_.can_ip_pass(cluster_name, tenant_name, user_name, ip1)); - ASSERT_EQ(true, white_list_processor_.can_ip_pass(cluster_name, tenant_name, user_name, ip2)); - ASSERT_EQ(false, white_list_processor_.can_ip_pass(cluster_name, tenant_name, user_name, ip3)); - ASSERT_EQ(false, white_list_processor_.can_ip_pass(cluster_name, tenant_name, user_name, ip4)); + ObAddr addr1(ObAddr::VER::IPV4, ip1, 0); + ObAddr addr2(ObAddr::VER::IPV4, ip2, 0); + ObAddr addr3(ObAddr::VER::IPV4, ip3, 0); + ObAddr addr4(ObAddr::VER::IPV4, ip4, 0); + struct sockaddr_storage ss = addr1.get_sockaddr(); + ASSERT_EQ(true, white_list_processor_.can_ip_pass(cluster_name, tenant_name, user_name, *reinterpret_cast(&ss))); + ss = addr2.get_sockaddr(); + ASSERT_EQ(true, white_list_processor_.can_ip_pass(cluster_name, tenant_name, user_name, *reinterpret_cast(&ss))); + ss = addr3.get_sockaddr(); + ASSERT_EQ(false, white_list_processor_.can_ip_pass(cluster_name, tenant_name, user_name, *reinterpret_cast(&ss))); + ss = addr4.get_sockaddr(); + ASSERT_EQ(false, white_list_processor_.can_ip_pass(cluster_name, tenant_name, user_name, *reinterpret_cast(&ss))); ObString cluster_name2 = "cluster2"; ObString tenant_name2 = "tenant2"; ObString user_name2 = "user2"; char ip5[32] = "127.0.0.1"; char ip6[32] = "127.0.0.2"; char ip7[32] = "127.0.0.3"; - ASSERT_EQ(true, white_list_processor_.can_ip_pass(cluster_name2, tenant_name2, user_name2, ip5)); - ASSERT_EQ(false, white_list_processor_.can_ip_pass(cluster_name2, tenant_name2, user_name2, ip6)); - ASSERT_EQ(true, white_list_processor_.can_ip_pass(cluster_name2, tenant_name2, user_name2, ip7)); + ObAddr addr5(ObAddr::VER::IPV4, ip5, 0); + ObAddr addr6(ObAddr::VER::IPV4, ip6, 0); + ObAddr addr7(ObAddr::VER::IPV4, ip7, 0); + ss = addr5.get_sockaddr(); + ASSERT_EQ(true, white_list_processor_.can_ip_pass(cluster_name2, tenant_name2, user_name2, *reinterpret_cast(&ss))); + ss = addr6.get_sockaddr(); + ASSERT_EQ(false, white_list_processor_.can_ip_pass(cluster_name2, tenant_name2, user_name2, *reinterpret_cast(&ss))); + ss = addr7.get_sockaddr(); + ASSERT_EQ(true, white_list_processor_.can_ip_pass(cluster_name2, tenant_name2, user_name2, *reinterpret_cast(&ss))); } int main(int argc, char **argv)