diff --git a/be/src/agent/agent_server.cpp b/be/src/agent/agent_server.cpp index fc63c1ff8372171..ea44c673e3c4f67 100644 --- a/be/src/agent/agent_server.cpp +++ b/be/src/agent/agent_server.cpp @@ -205,6 +205,10 @@ void AgentServer::cloud_start_workers(CloudStorageEngine& engine, ExecEnv* exec_ _report_workers.push_back(std::make_unique( "REPORT_TASK", _master_info, config::report_task_interval_seconds, [&master_info = _master_info] { report_task_callback(master_info); })); + + _report_workers.push_back(std::make_unique( + "REPORT_DISK_STATE", _master_info, config::report_disk_state_interval_seconds, + [&engine, &master_info = _master_info] { report_disk_callback(engine, master_info); })); } // TODO(lingbin): each task in the batch may have it own status or FE must check and diff --git a/be/src/agent/task_worker_pool.cpp b/be/src/agent/task_worker_pool.cpp index 2d01d54fa98f8de..7fc5b436c2581c6 100644 --- a/be/src/agent/task_worker_pool.cpp +++ b/be/src/agent/task_worker_pool.cpp @@ -999,6 +999,31 @@ void report_disk_callback(StorageEngine& engine, const TMasterInfo& master_info) } } +void report_disk_callback(CloudStorageEngine& engine, const TMasterInfo& master_info) { + // Random sleep 1~5 seconds before doing report. + // In order to avoid the problem that the FE receives many report requests at the same time + // and can not be processed. + if (config::report_random_wait) { + random_sleep(5); + } + (void)engine; // To be used in the future + + TReportRequest request; + request.__set_backend(BackendOptions::get_local_backend()); + request.__isset.disks = true; + + // TODO(deardeng): report disk info in cloud mode. And make it more clear + // that report CPU by using a separte report procedure + // or abstracting disk report as "host info report" + request.__set_num_cores(CpuInfo::num_cores()); + request.__set_pipeline_executor_size(config::pipeline_executor_size > 0 + ? config::pipeline_executor_size + : CpuInfo::num_cores()); + bool succ = handle_report(request, master_info, "disk"); + report_disk_total << 1; + report_disk_failed << !succ; +} + void report_tablet_callback(StorageEngine& engine, const TMasterInfo& master_info) { if (config::report_random_wait) { random_sleep(5); diff --git a/be/src/agent/task_worker_pool.h b/be/src/agent/task_worker_pool.h index 5c546582576c899..840a9a9335f00c4 100644 --- a/be/src/agent/task_worker_pool.h +++ b/be/src/agent/task_worker_pool.h @@ -178,6 +178,8 @@ void report_task_callback(const TMasterInfo& master_info); void report_disk_callback(StorageEngine& engine, const TMasterInfo& master_info); +void report_disk_callback(CloudStorageEngine& engine, const TMasterInfo& master_info); + void report_tablet_callback(StorageEngine& engine, const TMasterInfo& master_info); void calc_delete_bimtap_callback(CloudStorageEngine& engine, const TAgentTaskRequest& req); diff --git a/be/src/exprs/bloom_filter_func.h b/be/src/exprs/bloom_filter_func.h index 397f86a3693e65f..a0cf45cf7759270 100644 --- a/be/src/exprs/bloom_filter_func.h +++ b/be/src/exprs/bloom_filter_func.h @@ -94,13 +94,16 @@ class BloomFilterFuncBase : public RuntimeFilterFuncBase { public: virtual ~BloomFilterFuncBase() = default; - void set_length(int64_t bloom_filter_length) { _bloom_filter_length = bloom_filter_length; } - - void set_build_bf_exactly(bool build_bf_exactly) { _build_bf_exactly = build_bf_exactly; } + void init_params(const RuntimeFilterParams* params) { + _bloom_filter_length = params->bloom_filter_size; + _build_bf_exactly = params->build_bf_exactly; + _null_aware = params->null_aware; + _bloom_filter_size_calculated_by_ndv = params->bloom_filter_size_calculated_by_ndv; + } Status init_with_fixed_length() { return init_with_fixed_length(_bloom_filter_length); } - Status init_with_cardinality(const size_t build_bf_cardinality) { + Status init_with_cardinality(const size_t build_bf_cardinality, int id = 0) { if (_build_bf_exactly) { // Use the same algorithm as org.apache.doris.planner.RuntimeFilter#calculateFilterSize constexpr double fpp = 0.05; @@ -110,7 +113,14 @@ class BloomFilterFuncBase : public RuntimeFilterFuncBase { // Handle case where ndv == 1 => ceil(log2(m/8)) < 0. int log_filter_size = std::max(0, (int)(std::ceil(std::log(m / 8) / std::log(2)))); - _bloom_filter_length = (((int64_t)1) << log_filter_size); + auto be_calculate_size = (((int64_t)1) << log_filter_size); + // if FE do use ndv stat to predict the bf size, BE only use the row count. FE have more + // exactly row count stat. which one is min is more correctly. + if (_bloom_filter_size_calculated_by_ndv) { + _bloom_filter_length = std::min(be_calculate_size, _bloom_filter_length); + } else { + _bloom_filter_length = be_calculate_size; + } } return init_with_fixed_length(_bloom_filter_length); } @@ -214,6 +224,7 @@ class BloomFilterFuncBase : public RuntimeFilterFuncBase { std::mutex _lock; int64_t _bloom_filter_length; bool _build_bf_exactly = false; + bool _bloom_filter_size_calculated_by_ndv = false; }; template diff --git a/be/src/exprs/runtime_filter.cpp b/be/src/exprs/runtime_filter.cpp index cbb5d9b06eb0445..babf807ec95dad0 100644 --- a/be/src/exprs/runtime_filter.cpp +++ b/be/src/exprs/runtime_filter.cpp @@ -317,18 +317,14 @@ class RuntimePredicateWrapper { case RuntimeFilterType::BLOOM_FILTER: { _is_bloomfilter = true; _context.bloom_filter_func.reset(create_bloom_filter(_column_return_type)); - _context.bloom_filter_func->set_length(params->bloom_filter_size); - _context.bloom_filter_func->set_build_bf_exactly(params->build_bf_exactly); - _context.bloom_filter_func->set_null_aware(params->null_aware); + _context.bloom_filter_func->init_params(params); return Status::OK(); } case RuntimeFilterType::IN_OR_BLOOM_FILTER: { _context.hybrid_set.reset(create_set(_column_return_type)); _context.hybrid_set->set_null_aware(params->null_aware); _context.bloom_filter_func.reset(create_bloom_filter(_column_return_type)); - _context.bloom_filter_func->set_length(params->bloom_filter_size); - _context.bloom_filter_func->set_build_bf_exactly(params->build_bf_exactly); - _context.bloom_filter_func->set_null_aware(params->null_aware); + _context.bloom_filter_func->init_params(params); return Status::OK(); } case RuntimeFilterType::BITMAP_FILTER: { @@ -1276,12 +1272,11 @@ Status IRuntimeFilter::init_with_desc(const TRuntimeFilterDesc* desc, const TQue // 1. Only 1 join key // 2. Do not have remote target (e.g. do not need to merge), or broadcast join // 3. Bloom filter - // 4. FE do not use ndv stat to predict the bf size, only the row count. BE have more - // exactly row count stat - params.build_bf_exactly = build_bf_exactly && !desc->bloom_filter_size_calculated_by_ndv && - (!_has_remote_target || _is_broadcast_join) && + params.build_bf_exactly = build_bf_exactly && (!_has_remote_target || _is_broadcast_join) && (_runtime_filter_type == RuntimeFilterType::BLOOM_FILTER || _runtime_filter_type == RuntimeFilterType::IN_OR_BLOOM_FILTER); + params.bloom_filter_size_calculated_by_ndv = desc->bloom_filter_size_calculated_by_ndv; + if (desc->__isset.bloom_filter_size_bytes) { params.bloom_filter_size = desc->bloom_filter_size_bytes; } diff --git a/be/src/exprs/runtime_filter.h b/be/src/exprs/runtime_filter.h index fe5ddd68da65f68..2dd95a0260eed21 100644 --- a/be/src/exprs/runtime_filter.h +++ b/be/src/exprs/runtime_filter.h @@ -131,6 +131,8 @@ struct RuntimeFilterParams { int32_t filter_id; bool bitmap_filter_not_in; bool build_bf_exactly; + + bool bloom_filter_size_calculated_by_ndv = false; bool null_aware = false; }; diff --git a/be/src/http/action/http_stream.cpp b/be/src/http/action/http_stream.cpp index 8c62b95a43e8d7b..c46198ad92d9c9c 100644 --- a/be/src/http/action/http_stream.cpp +++ b/be/src/http/action/http_stream.cpp @@ -341,15 +341,19 @@ Status HttpStreamAction::process_put(HttpRequest* http_req, ctx->label = ctx->put_result.params.import_label; ctx->put_result.params.__set_wal_id(ctx->wal_id); if (http_req != nullptr && http_req->header(HTTP_GROUP_COMMIT) == "async_mode") { - size_t content_length = std::stol(http_req->header(HttpHeaders::CONTENT_LENGTH)); - if (ctx->format == TFileFormatType::FORMAT_CSV_GZ || - ctx->format == TFileFormatType::FORMAT_CSV_LZO || - ctx->format == TFileFormatType::FORMAT_CSV_BZ2 || - ctx->format == TFileFormatType::FORMAT_CSV_LZ4FRAME || - ctx->format == TFileFormatType::FORMAT_CSV_LZOP || - ctx->format == TFileFormatType::FORMAT_CSV_LZ4BLOCK || - ctx->format == TFileFormatType::FORMAT_CSV_SNAPPYBLOCK) { - content_length *= 3; + // FIXME find a way to avoid chunked stream load write large WALs + size_t content_length = 0; + if (!http_req->header(HttpHeaders::CONTENT_LENGTH).empty()) { + content_length = std::stol(http_req->header(HttpHeaders::CONTENT_LENGTH)); + if (ctx->format == TFileFormatType::FORMAT_CSV_GZ || + ctx->format == TFileFormatType::FORMAT_CSV_LZO || + ctx->format == TFileFormatType::FORMAT_CSV_BZ2 || + ctx->format == TFileFormatType::FORMAT_CSV_LZ4FRAME || + ctx->format == TFileFormatType::FORMAT_CSV_LZOP || + ctx->format == TFileFormatType::FORMAT_CSV_LZ4BLOCK || + ctx->format == TFileFormatType::FORMAT_CSV_SNAPPYBLOCK) { + content_length *= 3; + } } ctx->put_result.params.__set_content_length(content_length); } @@ -394,11 +398,19 @@ Status HttpStreamAction::_handle_group_commit(HttpRequest* req, LOG(WARNING) << ss.str(); return Status::InternalError(ss.str()); } - if (group_commit_mode.empty() || iequal(group_commit_mode, "off_mode") || content_length == 0) { + // allow chunked stream load in flink + auto is_chunk = + !req->header(HttpHeaders::TRANSFER_ENCODING).empty() && + req->header(HttpHeaders::TRANSFER_ENCODING).find("chunked") != std::string::npos; + if (group_commit_mode.empty() || iequal(group_commit_mode, "off_mode") || + (content_length == 0 && !is_chunk)) { // off_mode and empty ctx->group_commit = false; return Status::OK(); } + if (is_chunk) { + ctx->label = ""; + } auto partial_columns = !req->header(HTTP_PARTIAL_COLUMNS).empty() && iequal(req->header(HTTP_PARTIAL_COLUMNS), "true"); diff --git a/be/src/http/action/pipeline_task_action.cpp b/be/src/http/action/pipeline_task_action.cpp index c3b49b57136c746..b19b42c94685630 100644 --- a/be/src/http/action/pipeline_task_action.cpp +++ b/be/src/http/action/pipeline_task_action.cpp @@ -38,4 +38,22 @@ void PipelineTaskAction::handle(HttpRequest* req) { ExecEnv::GetInstance()->fragment_mgr()->dump_pipeline_tasks()); } +void LongPipelineTaskAction::handle(HttpRequest* req) { + req->add_output_header(HttpHeaders::CONTENT_TYPE, "text/plain; version=0.0.4"); + int64_t duration = 0; + try { + duration = std::stoll(req->param("duration")); + } catch (const std::exception& e) { + fmt::memory_buffer debug_string_buffer; + fmt::format_to(debug_string_buffer, "invalid argument.duration: {}, meet error: {}", + req->param("duration"), e.what()); + LOG(WARNING) << fmt::to_string(debug_string_buffer); + HttpChannel::send_reply(req, HttpStatus::INTERNAL_SERVER_ERROR, + fmt::to_string(debug_string_buffer)); + return; + } + HttpChannel::send_reply(req, HttpStatus::OK, + ExecEnv::GetInstance()->fragment_mgr()->dump_pipeline_tasks(duration)); +} + } // end namespace doris diff --git a/be/src/http/action/pipeline_task_action.h b/be/src/http/action/pipeline_task_action.h index 00c1c062cad8ef6..553ac856e6f1c94 100644 --- a/be/src/http/action/pipeline_task_action.h +++ b/be/src/http/action/pipeline_task_action.h @@ -32,4 +32,13 @@ class PipelineTaskAction : public HttpHandler { void handle(HttpRequest* req) override; }; +class LongPipelineTaskAction : public HttpHandler { +public: + LongPipelineTaskAction() = default; + + ~LongPipelineTaskAction() override = default; + + void handle(HttpRequest* req) override; +}; + } // end namespace doris diff --git a/be/src/http/action/stream_load.cpp b/be/src/http/action/stream_load.cpp index 92f78c440ad0618..67a063e1c32b3c8 100644 --- a/be/src/http/action/stream_load.cpp +++ b/be/src/http/action/stream_load.cpp @@ -647,15 +647,19 @@ Status StreamLoadAction::_process_put(HttpRequest* http_req, return plan_status; } if (http_req->header(HTTP_GROUP_COMMIT) == "async_mode") { - size_t content_length = std::stol(http_req->header(HttpHeaders::CONTENT_LENGTH)); - if (ctx->format == TFileFormatType::FORMAT_CSV_GZ || - ctx->format == TFileFormatType::FORMAT_CSV_LZO || - ctx->format == TFileFormatType::FORMAT_CSV_BZ2 || - ctx->format == TFileFormatType::FORMAT_CSV_LZ4FRAME || - ctx->format == TFileFormatType::FORMAT_CSV_LZOP || - ctx->format == TFileFormatType::FORMAT_CSV_LZ4BLOCK || - ctx->format == TFileFormatType::FORMAT_CSV_SNAPPYBLOCK) { - content_length *= 3; + // FIXME find a way to avoid chunked stream load write large WALs + size_t content_length = 0; + if (!http_req->header(HttpHeaders::CONTENT_LENGTH).empty()) { + content_length = std::stol(http_req->header(HttpHeaders::CONTENT_LENGTH)); + if (ctx->format == TFileFormatType::FORMAT_CSV_GZ || + ctx->format == TFileFormatType::FORMAT_CSV_LZO || + ctx->format == TFileFormatType::FORMAT_CSV_BZ2 || + ctx->format == TFileFormatType::FORMAT_CSV_LZ4FRAME || + ctx->format == TFileFormatType::FORMAT_CSV_LZOP || + ctx->format == TFileFormatType::FORMAT_CSV_LZ4BLOCK || + ctx->format == TFileFormatType::FORMAT_CSV_SNAPPYBLOCK) { + content_length *= 3; + } } ctx->put_result.params.__set_content_length(content_length); } @@ -723,11 +727,18 @@ Status StreamLoadAction::_handle_group_commit(HttpRequest* req, LOG(WARNING) << ss.str(); return Status::InternalError(ss.str()); } - if (group_commit_mode.empty() || iequal(group_commit_mode, "off_mode") || content_length == 0) { + // allow chunked stream load in flink + auto is_chunk = !req->header(HttpHeaders::TRANSFER_ENCODING).empty() && + req->header(HttpHeaders::TRANSFER_ENCODING).find(CHUNK) != std::string::npos; + if (group_commit_mode.empty() || iequal(group_commit_mode, "off_mode") || + (content_length == 0 && !is_chunk)) { // off_mode and empty ctx->group_commit = false; return Status::OK(); } + if (is_chunk) { + ctx->label = ""; + } auto partial_columns = !req->header(HTTP_PARTIAL_COLUMNS).empty() && iequal(req->header(HTTP_PARTIAL_COLUMNS), "true"); diff --git a/be/src/io/cache/block_file_cache.cpp b/be/src/io/cache/block_file_cache.cpp index f8d97cbe69d235a..2e16227c613c647 100644 --- a/be/src/io/cache/block_file_cache.cpp +++ b/be/src/io/cache/block_file_cache.cpp @@ -27,6 +27,7 @@ #endif #include // IWYU pragma: keep +#include #include "common/config.h" #include "common/logging.h" @@ -1507,5 +1508,7 @@ Status BlockFileCache::clear_file_cache_directly() { .tag("use_time", static_cast(use_time.count())); return Status::OK(); } - +template void BlockFileCache::remove(FileBlockSPtr file_block, + std::lock_guard& cache_lock, + std::lock_guard& block_lock); } // namespace doris::io diff --git a/be/src/io/cache/block_file_cache.h b/be/src/io/cache/block_file_cache.h index 17dc8387ba7406e..36aa94acacfc308 100644 --- a/be/src/io/cache/block_file_cache.h +++ b/be/src/io/cache/block_file_cache.h @@ -29,10 +29,8 @@ namespace doris::io { template -concept IsXLock = requires { - std::same_as> || - std::same_as>; -}; +concept IsXLock = std::same_as> || + std::same_as>; class FSFileCacheStorage; diff --git a/be/src/olap/rowset/segment_v2/column_reader.cpp b/be/src/olap/rowset/segment_v2/column_reader.cpp index f9082323674f6d7..0506250f2470ee4 100644 --- a/be/src/olap/rowset/segment_v2/column_reader.cpp +++ b/be/src/olap/rowset/segment_v2/column_reader.cpp @@ -1508,8 +1508,7 @@ Status VariantRootColumnIterator::next_batch(size_t* n, vectorized::MutableColum } } // fill nullmap - if (root_column->is_nullable()) { - DCHECK(dst->is_nullable()); + if (root_column->is_nullable() && dst->is_nullable()) { vectorized::ColumnUInt8& dst_null_map = assert_cast(*dst).get_null_map_column(); vectorized::ColumnUInt8& src_null_map = @@ -1542,8 +1541,7 @@ Status VariantRootColumnIterator::read_by_rowids(const rowid_t* rowids, const si } } // fill nullmap - if (root_column->is_nullable()) { - DCHECK(dst->is_nullable()); + if (root_column->is_nullable() && dst->is_nullable()) { vectorized::ColumnUInt8& dst_null_map = assert_cast(*dst).get_null_map_column(); vectorized::ColumnUInt8& src_null_map = diff --git a/be/src/pipeline/pipeline_x/pipeline_x_task.cpp b/be/src/pipeline/pipeline_x/pipeline_x_task.cpp index f80302d6b4826b8..e9fbccbeb771280 100644 --- a/be/src/pipeline/pipeline_x/pipeline_x_task.cpp +++ b/be/src/pipeline/pipeline_x/pipeline_x_task.cpp @@ -373,11 +373,11 @@ std::string PipelineXTask::debug_string() { fmt::format_to(debug_string_buffer, "InstanceId: {}\n", print_id(_state->fragment_instance_id())); + auto elapsed = (MonotonicNanos() - _fragment_context->create_time()) / 1000000000.0; fmt::format_to(debug_string_buffer, "PipelineTask[this = {}, state = {}, dry run = {}, elapse time " - "= {}ns], block dependency = {}, is running = {}\noperators: ", - (void*)this, get_state_name(_cur_state), _dry_run, - MonotonicNanos() - _fragment_context->create_time(), + "= {}s], block dependency = {}, is running = {}\noperators: ", + (void*)this, get_state_name(_cur_state), _dry_run, elapsed, _blocked_dep ? _blocked_dep->debug_string() : "NULL", is_running()); for (size_t i = 0; i < _operators.size(); i++) { fmt::format_to( diff --git a/be/src/runtime/fragment_mgr.cpp b/be/src/runtime/fragment_mgr.cpp index 6402369ed09a9f0..c1d0f37e64d7a7c 100644 --- a/be/src/runtime/fragment_mgr.cpp +++ b/be/src/runtime/fragment_mgr.cpp @@ -646,7 +646,6 @@ Status FragmentMgr::_get_query_ctx(const Params& params, TUniqueId query_id, boo } query_ctx->get_shared_hash_table_controller()->set_pipeline_engine_enabled(pipeline); - _set_scan_concurrency(params, query_ctx.get()); const bool is_pipeline = std::is_same_v; if (params.__isset.workload_groups && !params.workload_groups.empty()) { @@ -765,7 +764,7 @@ Status FragmentMgr::exec_plan_fragment(const TExecPlanFragmentParams& params, return Status::OK(); } -std::string FragmentMgr::dump_pipeline_tasks() { +std::string FragmentMgr::dump_pipeline_tasks(int64_t duration) { fmt::memory_buffer debug_string_buffer; auto t = MonotonicNanos(); size_t i = 0; @@ -774,9 +773,13 @@ std::string FragmentMgr::dump_pipeline_tasks() { fmt::format_to(debug_string_buffer, "{} pipeline fragment contexts are still running!\n", _pipeline_map.size()); for (auto& it : _pipeline_map) { - fmt::format_to( - debug_string_buffer, "No.{} (elapse time = {}ns, InstanceId = {}) : {}\n", i, - t - it.second->create_time(), print_id(it.first), it.second->debug_string()); + auto elapsed = (t - it.second->create_time()) / 1000000000.0; + if (elapsed < duration) { + // Only display tasks which has been running for more than {duration} seconds. + continue; + } + fmt::format_to(debug_string_buffer, "No.{} (elapse time = {}s, InstanceId = {}) : {}\n", + i, elapsed, print_id(it.first), it.second->debug_string()); i++; } } @@ -960,18 +963,6 @@ Status FragmentMgr::exec_plan_fragment(const TPipelineFragmentParams& params, return Status::OK(); } -template -void FragmentMgr::_set_scan_concurrency(const Param& params, QueryContext* query_ctx) { -#ifndef BE_TEST - // If the token is set, the scan task will use limited_scan_pool in scanner scheduler. - // Otherwise, the scan task will use local/remote scan pool in scanner scheduler - if (params.query_options.__isset.resource_limit && - params.query_options.resource_limit.__isset.cpu_limit) { - query_ctx->set_thread_token(params.query_options.resource_limit.cpu_limit, false); - } -#endif -} - void FragmentMgr::cancel_query(const TUniqueId& query_id, const PPlanFragmentCancelReason& reason, const std::string& msg) { std::unique_lock state_lock(_lock); diff --git a/be/src/runtime/fragment_mgr.h b/be/src/runtime/fragment_mgr.h index 6f5b981d09c56c5..1c97856a53612bb 100644 --- a/be/src/runtime/fragment_mgr.h +++ b/be/src/runtime/fragment_mgr.h @@ -148,7 +148,7 @@ class FragmentMgr : public RestMonitorIface { return _query_ctx_map.size(); } - std::string dump_pipeline_tasks(); + std::string dump_pipeline_tasks(int64_t duration = 0); void get_runtime_query_info(std::vector* _query_info_list); @@ -160,9 +160,6 @@ class FragmentMgr : public RestMonitorIface { void _exec_actual(std::shared_ptr fragment_executor, const FinishCallback& cb); - template - void _set_scan_concurrency(const Param& params, QueryContext* query_ctx); - void _setup_shared_hashtable_for_broadcast_join(const TExecPlanFragmentParams& params, QueryContext* query_ctx); diff --git a/be/src/runtime/query_context.cpp b/be/src/runtime/query_context.cpp index b2f578a2a75318a..1f6fe67b190a915 100644 --- a/be/src/runtime/query_context.cpp +++ b/be/src/runtime/query_context.cpp @@ -110,14 +110,6 @@ QueryContext::~QueryContext() { _exec_env->runtime_query_statistics_mgr()->set_query_finished(print_id(_query_id)); LOG_INFO("Query {} deconstructed, {}", print_id(_query_id), mem_tracker_msg); - // Not release the the thread token in query context's dector method, because the query - // conext may be dectored in the thread token it self. It is very dangerous and may core. - // And also thread token need shutdown, it may take some time, may cause the thread that - // release the token hang, the thread maybe a pipeline task scheduler thread. - if (_thread_token) { - static_cast(ExecEnv::GetInstance()->lazy_release_obj_pool()->submit( - std::make_shared(std::move(_thread_token)))); - } //TODO: check if pipeline and tracing both enabled if (_is_pipeline && ExecEnv::GetInstance()->pipeline_tracer_context()->enabled()) [[unlikely]] { diff --git a/be/src/runtime/query_context.h b/be/src/runtime/query_context.h index 1551af46c95ac17..a13f687ecbf7a72 100644 --- a/be/src/runtime/query_context.h +++ b/be/src/runtime/query_context.h @@ -95,15 +95,6 @@ class QueryContext { int64_t query_time(VecDateTimeValue& now) { return now.second_diff(_start_time); } - void set_thread_token(int concurrency, bool is_serial) { - _thread_token = _exec_env->scanner_scheduler()->new_limited_scan_pool_token( - is_serial ? ThreadPool::ExecutionMode::SERIAL - : ThreadPool::ExecutionMode::CONCURRENT, - concurrency); - } - - ThreadPoolToken* get_token() { return _thread_token.get(); } - void set_ready_to_execute(bool is_cancelled); [[nodiscard]] bool is_cancelled() const { return _is_cancelled.load(); } @@ -281,13 +272,6 @@ class QueryContext { bool _is_pipeline = false; bool _is_nereids = false; - // A token used to submit olap scanner to the "_limited_scan_thread_pool", - // This thread pool token is created from "_limited_scan_thread_pool" from exec env. - // And will be shared by all instances of this query. - // So that we can control the max thread that a query can be used to execute. - // If this token is not set, the scanner will be executed in "_scan_thread_pool" in exec env. - std::unique_ptr _thread_token; - std::mutex _start_lock; std::condition_variable _start_cond; // Only valid when _need_wait_execution_trigger is set to true in PlanFragmentExecutor. diff --git a/be/src/service/http_service.cpp b/be/src/service/http_service.cpp index 8eea3a74a7205e7..7837f72ca0c7a11 100644 --- a/be/src/service/http_service.cpp +++ b/be/src/service/http_service.cpp @@ -149,11 +149,16 @@ Status HttpService::start() { HealthAction* health_action = _pool.add(new HealthAction()); _ev_http_server->register_handler(HttpMethod::GET, "/api/health", health_action); - // Register BE health action + // Dump all running pipeline tasks PipelineTaskAction* pipeline_task_action = _pool.add(new PipelineTaskAction()); _ev_http_server->register_handler(HttpMethod::GET, "/api/running_pipeline_tasks", pipeline_task_action); + // Dump all running pipeline tasks which has been running for more than {duration} seconds + LongPipelineTaskAction* long_pipeline_task_action = _pool.add(new LongPipelineTaskAction()); + _ev_http_server->register_handler(HttpMethod::GET, "/api/running_pipeline_tasks/{duration}", + long_pipeline_task_action); + // Register Tablets Info action TabletsInfoAction* tablets_info_action = _pool.add(new TabletsInfoAction(_env, TPrivilegeHier::GLOBAL, TPrivilegeType::ADMIN)); diff --git a/be/src/vec/aggregate_functions/aggregate_function_collect.h b/be/src/vec/aggregate_functions/aggregate_function_collect.h index 7e3c7207a7d27c9..e85288bc91d7072 100644 --- a/be/src/vec/aggregate_functions/aggregate_function_collect.h +++ b/be/src/vec/aggregate_functions/aggregate_function_collect.h @@ -390,7 +390,7 @@ struct AggregateFunctionArrayAggData { void deserialize_and_merge(const IColumn& column, size_t row_num) { auto& to_arr = assert_cast(column); auto& to_nested_col = to_arr.get_data(); - auto col_null = reinterpret_cast(&to_nested_col); + auto col_null = assert_cast(&to_nested_col); const auto& vec = assert_cast(col_null->get_nested_column()); auto start = to_arr.get_offsets()[row_num - 1]; auto end = start + to_arr.get_offsets()[row_num] - to_arr.get_offsets()[row_num - 1]; @@ -556,8 +556,8 @@ class AggregateFunctionCollect const size_t num_rows) const override { if constexpr (ShowNull::value) { for (size_t i = 0; i != num_rows; ++i) { - this->data(places[i]).deserialize_and_merge(*assert_cast(column), - i); + this->data(places[i] + offset) + .deserialize_and_merge(*assert_cast(column), i); } } else { return BaseHelper::deserialize_and_merge_vec(places, offset, rhs, column, arena, @@ -596,9 +596,9 @@ class AggregateFunctionCollect Arena* arena, const size_t num_rows) const override { if constexpr (ShowNull::value) { for (size_t i = 0; i != num_rows; ++i) { - if (places[i]) { - this->data(places[i]).deserialize_and_merge( - *assert_cast(column), i); + if (places[i] + offset) { + this->data(places[i] + offset) + .deserialize_and_merge(*assert_cast(column), i); } } } else { @@ -671,4 +671,4 @@ class AggregateFunctionCollect using IAggregateFunction::argument_types; }; -} // namespace doris::vectorized \ No newline at end of file +} // namespace doris::vectorized diff --git a/be/src/vec/exec/format/parquet/parquet_column_convert.h b/be/src/vec/exec/format/parquet/parquet_column_convert.h index 39ee29f663f9ed4..1d6cfd63515366a 100644 --- a/be/src/vec/exec/format/parquet/parquet_column_convert.h +++ b/be/src/vec/exec/format/parquet/parquet_column_convert.h @@ -318,12 +318,13 @@ struct Int96toTimestamp : public ColumnConvert { auto& data = static_cast*>(dst_col.get())->get_data(); for (int i = 0; i < rows; i++) { - ParquetInt96 x = ParquetInt96_data[i]; - auto& num = data[start_idx + i]; - auto& value = reinterpret_cast&>(num); - int64_t micros = x.to_timestamp_micros(); - value.from_unixtime(micros / 1000000, *_convert_params->ctz); - value.set_microsecond(micros % 1000000); + ParquetInt96 src_cell_data = ParquetInt96_data[i]; + auto& dst_value = + reinterpret_cast&>(data[start_idx + i]); + + int64_t timestamp_with_micros = src_cell_data.to_timestamp_micros(); + dst_value.from_unixtime(timestamp_with_micros / 1000000, *_convert_params->ctz); + dst_value.set_microsecond(timestamp_with_micros % 1000000); } return Status::OK(); } diff --git a/be/src/vec/exec/format/parquet/parquet_common.cpp b/be/src/vec/exec/format/parquet/parquet_common.cpp index cbef2a0f286d480..33e9f11242b46de 100644 --- a/be/src/vec/exec/format/parquet/parquet_common.cpp +++ b/be/src/vec/exec/format/parquet/parquet_common.cpp @@ -24,9 +24,9 @@ namespace doris::vectorized { -const uint32_t ParquetInt96::JULIAN_EPOCH_OFFSET_DAYS = 2440588; -const uint64_t ParquetInt96::MICROS_IN_DAY = 86400000000; -const uint64_t ParquetInt96::NANOS_PER_MICROSECOND = 1000; +const int32_t ParquetInt96::JULIAN_EPOCH_OFFSET_DAYS = 2440588; +const int64_t ParquetInt96::MICROS_IN_DAY = 86400000000; +const int64_t ParquetInt96::NANOS_PER_MICROSECOND = 1000; ColumnSelectVector::ColumnSelectVector(const uint8_t* filter_map, size_t filter_map_size, bool filter_all) { diff --git a/be/src/vec/exec/format/parquet/parquet_common.h b/be/src/vec/exec/format/parquet/parquet_common.h index 6667ab2c1016376..2cf745882ee1392 100644 --- a/be/src/vec/exec/format/parquet/parquet_common.h +++ b/be/src/vec/exec/format/parquet/parquet_common.h @@ -48,10 +48,10 @@ struct RowRange { #pragma pack(1) struct ParquetInt96 { - uint64_t lo; // time of nanoseconds in a day - uint32_t hi; // days from julian epoch + int64_t lo; // time of nanoseconds in a day + int32_t hi; // days from julian epoch - inline uint64_t to_timestamp_micros() const { + inline int64_t to_timestamp_micros() const { return (hi - JULIAN_EPOCH_OFFSET_DAYS) * MICROS_IN_DAY + lo / NANOS_PER_MICROSECOND; } inline __int128 to_int128() const { @@ -60,9 +60,9 @@ struct ParquetInt96 { return ans; } - static const uint32_t JULIAN_EPOCH_OFFSET_DAYS; - static const uint64_t MICROS_IN_DAY; - static const uint64_t NANOS_PER_MICROSECOND; + static const int32_t JULIAN_EPOCH_OFFSET_DAYS; + static const int64_t MICROS_IN_DAY; + static const int64_t NANOS_PER_MICROSECOND; }; #pragma pack() static_assert(sizeof(ParquetInt96) == 12, "The size of ParquetInt96 is not 12."); diff --git a/be/src/vec/exec/scan/scanner_context.cpp b/be/src/vec/exec/scan/scanner_context.cpp index 3058708b2d99b27..a55e4725e1c4fba 100644 --- a/be/src/vec/exec/scan/scanner_context.cpp +++ b/be/src/vec/exec/scan/scanner_context.cpp @@ -124,7 +124,6 @@ Status ScannerContext::init() { #ifndef BE_TEST // 3. get thread token if (_state->get_query_ctx()) { - thread_token = _state->get_query_ctx()->get_token(); _simple_scan_scheduler = _state->get_query_ctx()->get_scan_scheduler(); if (_simple_scan_scheduler) { _should_reset_thread_name = false; @@ -135,12 +134,10 @@ Status ScannerContext::init() { if (_parent) { COUNTER_SET(_parent->_max_scanner_thread_num, (int64_t)_max_thread_num); - _parent->_runtime_profile->add_info_string("UseSpecificThreadToken", - thread_token == nullptr ? "False" : "True"); + _parent->_runtime_profile->add_info_string("UseSpecificThreadToken", "False"); } else { COUNTER_SET(_local_state->_max_scanner_thread_num, (int64_t)_max_thread_num); - _local_state->_runtime_profile->add_info_string("UseSpecificThreadToken", - thread_token == nullptr ? "False" : "True"); + _local_state->_runtime_profile->add_info_string("UseSpecificThreadToken", "False"); } // submit `_max_thread_num` running scanners to `ScannerScheduler` diff --git a/be/src/vec/exec/scan/scanner_context.h b/be/src/vec/exec/scan/scanner_context.h index 24889054094ca1a..1eba6f66e26228c 100644 --- a/be/src/vec/exec/scan/scanner_context.h +++ b/be/src/vec/exec/scan/scanner_context.h @@ -157,7 +157,6 @@ class ScannerContext : public std::enable_shared_from_this, std::string ctx_id; TUniqueId _query_id; int32_t queue_idx = -1; - ThreadPoolToken* thread_token = nullptr; bool _should_reset_thread_name = true; diff --git a/be/src/vec/exec/scan/scanner_scheduler.cpp b/be/src/vec/exec/scan/scanner_scheduler.cpp index f5dfbe4724acaf8..212576f1aa0a85b 100644 --- a/be/src/vec/exec/scan/scanner_scheduler.cpp +++ b/be/src/vec/exec/scan/scanner_scheduler.cpp @@ -133,72 +133,50 @@ void ScannerScheduler::submit(std::shared_ptr ctx, // Submit scanners to thread pool // TODO(cmy): How to handle this "nice"? int nice = 1; - if (ctx->thread_token != nullptr) { - std::shared_ptr scanner_delegate = scan_task->scanner.lock(); - if (scanner_delegate == nullptr) { - return; - } + std::shared_ptr scanner_delegate = scan_task->scanner.lock(); + if (scanner_delegate == nullptr) { + return; + } - scanner_delegate->_scanner->start_wait_worker_timer(); - auto s = ctx->thread_token->submit_func( - [this, scanner_ref = scan_task, ctx]() { this->_scanner_scan(ctx, scanner_ref); }); - if (!s.ok()) { - scan_task->set_status(s); - ctx->append_block_to_queue(scan_task); - return; + scanner_delegate->_scanner->start_wait_worker_timer(); + TabletStorageType type = scanner_delegate->_scanner->get_storage_type(); + bool ret = false; + if (type == TabletStorageType::STORAGE_TYPE_LOCAL) { + if (auto* scan_sched = ctx->get_simple_scan_scheduler()) { + auto work_func = [this, scanner_ref = scan_task, ctx]() { + this->_scanner_scan(ctx, scanner_ref); + }; + SimplifiedScanTask simple_scan_task = {work_func, ctx}; + ret = scan_sched->submit_scan_task(simple_scan_task); + } else { + PriorityThreadPool::Task task; + task.work_function = [this, scanner_ref = scan_task, ctx]() { + this->_scanner_scan(ctx, scanner_ref); + }; + task.priority = nice; + ret = _local_scan_thread_pool->offer(task); } } else { - std::shared_ptr scanner_delegate = scan_task->scanner.lock(); - if (scanner_delegate == nullptr) { - return; - } - - scanner_delegate->_scanner->start_wait_worker_timer(); - TabletStorageType type = scanner_delegate->_scanner->get_storage_type(); - bool ret = false; - if (type == TabletStorageType::STORAGE_TYPE_LOCAL) { - if (auto* scan_sched = ctx->get_simple_scan_scheduler()) { - auto work_func = [this, scanner_ref = scan_task, ctx]() { - this->_scanner_scan(ctx, scanner_ref); - }; - SimplifiedScanTask simple_scan_task = {work_func, ctx}; - ret = scan_sched->submit_scan_task(simple_scan_task); - } else { - PriorityThreadPool::Task task; - task.work_function = [this, scanner_ref = scan_task, ctx]() { - this->_scanner_scan(ctx, scanner_ref); - }; - task.priority = nice; - ret = _local_scan_thread_pool->offer(task); - } + if (auto* remote_scan_sched = ctx->get_remote_scan_scheduler()) { + auto work_func = [this, scanner_ref = scan_task, ctx]() { + this->_scanner_scan(ctx, scanner_ref); + }; + SimplifiedScanTask simple_scan_task = {work_func, ctx}; + ret = remote_scan_sched->submit_scan_task(simple_scan_task); } else { - if (auto* remote_scan_sched = ctx->get_remote_scan_scheduler()) { - auto work_func = [this, scanner_ref = scan_task, ctx]() { - this->_scanner_scan(ctx, scanner_ref); - }; - SimplifiedScanTask simple_scan_task = {work_func, ctx}; - ret = remote_scan_sched->submit_scan_task(simple_scan_task); - } else { - PriorityThreadPool::Task task; - task.work_function = [this, scanner_ref = scan_task, ctx]() { - this->_scanner_scan(ctx, scanner_ref); - }; - task.priority = nice; - ret = _remote_scan_thread_pool->offer(task); - } - } - if (!ret) { - scan_task->set_status( - Status::InternalError("Failed to submit scanner to scanner pool")); - ctx->append_block_to_queue(scan_task); - return; + PriorityThreadPool::Task task; + task.work_function = [this, scanner_ref = scan_task, ctx]() { + this->_scanner_scan(ctx, scanner_ref); + }; + task.priority = nice; + ret = _remote_scan_thread_pool->offer(task); } } -} - -std::unique_ptr ScannerScheduler::new_limited_scan_pool_token( - ThreadPool::ExecutionMode mode, int max_concurrency) { - return _limited_scan_thread_pool->new_token(mode, max_concurrency); + if (!ret) { + scan_task->set_status(Status::InternalError("Failed to submit scanner to scanner pool")); + ctx->append_block_to_queue(scan_task); + return; + } } void ScannerScheduler::_scanner_scan(std::shared_ptr ctx, diff --git a/be/src/vec/exec/scan/scanner_scheduler.h b/be/src/vec/exec/scan/scanner_scheduler.h index f3f9caaa4d3dc97..f54e8993b4367cc 100644 --- a/be/src/vec/exec/scan/scanner_scheduler.h +++ b/be/src/vec/exec/scan/scanner_scheduler.h @@ -60,9 +60,6 @@ class ScannerScheduler { void stop(); - std::unique_ptr new_limited_scan_pool_token(ThreadPool::ExecutionMode mode, - int max_concurrency); - int remote_thread_pool_max_size() const { return _remote_thread_pool_max_size; } private: diff --git a/be/src/vec/exprs/vruntimefilter_wrapper.cpp b/be/src/vec/exprs/vruntimefilter_wrapper.cpp index 8589463664a4f64..e0753103b001d82 100644 --- a/be/src/vec/exprs/vruntimefilter_wrapper.cpp +++ b/be/src/vec/exprs/vruntimefilter_wrapper.cpp @@ -120,12 +120,15 @@ Status VRuntimeFilterWrapper::execute(VExprContext* context, Block* block, int* ColumnWithTypeAndName& result_column = block->get_by_position(*result_column_id); if (is_column_const(*result_column.column)) { auto* constant_val = const_cast(result_column.column->get_data_at(0).data); - auto filter = constant_val == nullptr && reinterpret_cast(constant_val); + auto filter = + (constant_val == nullptr) || (!reinterpret_cast(constant_val)); // if _null_aware is true, we should check the first args column is nullable. if value in // column is null. we should set it to true if (_null_aware) { DCHECK(!args.empty()); - DCHECK(is_column_const(*block->get_by_position(args[0]).column)); + // if args is only null, result may be const null column + DCHECK(is_column_const(*block->get_by_position(args[0]).column) || + constant_val == nullptr); if (filter && block->get_by_position(args[0]).column->get_data_at(0).data == nullptr) { auto res_col = ColumnVector::create(1, 1); diff --git a/be/src/vec/functions/function_string.h b/be/src/vec/functions/function_string.h index 4dc68eecc83ffc3..75d8c8d4997f54e 100644 --- a/be/src/vec/functions/function_string.h +++ b/be/src/vec/functions/function_string.h @@ -948,7 +948,7 @@ class FunctionRightOld : public IFunction { temp_arguments[0] = arguments[0]; temp_arguments[1] = num_columns_without_result; temp_arguments[2] = num_columns_without_result + 1; - SubstringUtil::substring_execute(block, temp_arguments, result, input_rows_count); + SubstringUtilOld::substring_execute(block, temp_arguments, result, input_rows_count); return Status::OK(); } }; diff --git a/be/src/vec/functions/like.cpp b/be/src/vec/functions/like.cpp index 752c2c206785ad1..cacf97f954e06dd 100644 --- a/be/src/vec/functions/like.cpp +++ b/be/src/vec/functions/like.cpp @@ -60,6 +60,130 @@ static const re2::RE2 LIKE_STARTS_WITH_RE(R"((((\\%)|(\\_)|([^%_\\]))+)(?:%+))") static const re2::RE2 LIKE_EQUALS_RE("(((\\\\_)|([^%_]))+)"); static const re2::RE2 LIKE_ALLPASS_RE("%+"); +struct VectorAllpassSearchState : public VectorPatternSearchState { + VectorAllpassSearchState() : VectorPatternSearchState(FunctionLikeBase::vector_allpass_fn) {} + + ~VectorAllpassSearchState() override = default; + + void like_pattern_match(const std::string& pattern_str) override { + if (!pattern_str.empty() && RE2::FullMatch(pattern_str, LIKE_ALLPASS_RE)) { + _search_strings->insert_default(); + } else { + _pattern_matched = false; + } + } + + void regexp_pattern_match(const std::string& pattern_str) override { + if (RE2::FullMatch(pattern_str, ALLPASS_RE)) { + _search_strings->insert_default(); + } else { + _pattern_matched = false; + } + } +}; + +struct VectorEqualSearchState : public VectorPatternSearchState { + VectorEqualSearchState() : VectorPatternSearchState(FunctionLikeBase::vector_equals_fn) {} + + ~VectorEqualSearchState() override = default; + + void like_pattern_match(const std::string& pattern_str) override { + _search_string.clear(); + if (pattern_str.empty() || RE2::FullMatch(pattern_str, LIKE_EQUALS_RE, &_search_string)) { + FunctionLike::remove_escape_character(&_search_string); + _search_strings->insert_data(_search_string.c_str(), _search_string.size()); + } else { + _pattern_matched = false; + } + } + + void regexp_pattern_match(const std::string& pattern_str) override { + _search_string.clear(); + if (RE2::FullMatch(pattern_str, EQUALS_RE, &_search_string)) { + _search_strings->insert_data(_search_string.c_str(), _search_string.size()); + } else { + _pattern_matched = false; + } + } +}; + +struct VectorSubStringSearchState : public VectorPatternSearchState { + VectorSubStringSearchState() + : VectorPatternSearchState(FunctionLikeBase::vector_substring_fn) {} + + ~VectorSubStringSearchState() override = default; + + void like_pattern_match(const std::string& pattern_str) override { + _search_string.clear(); + if (RE2::FullMatch(pattern_str, LIKE_SUBSTRING_RE, &_search_string)) { + FunctionLike::remove_escape_character(&_search_string); + _search_strings->insert_data(_search_string.c_str(), _search_string.size()); + } else { + _pattern_matched = false; + } + } + + void regexp_pattern_match(const std::string& pattern_str) override { + _search_string.clear(); + if (RE2::FullMatch(pattern_str, SUBSTRING_RE, &_search_string)) { + _search_strings->insert_data(_search_string.c_str(), _search_string.size()); + } else { + _pattern_matched = false; + } + } +}; + +struct VectorStartsWithSearchState : public VectorPatternSearchState { + VectorStartsWithSearchState() + : VectorPatternSearchState(FunctionLikeBase::vector_starts_with_fn) {} + + ~VectorStartsWithSearchState() override = default; + + void like_pattern_match(const std::string& pattern_str) override { + _search_string.clear(); + if (RE2::FullMatch(pattern_str, LIKE_STARTS_WITH_RE, &_search_string)) { + FunctionLike::remove_escape_character(&_search_string); + _search_strings->insert_data(_search_string.c_str(), _search_string.size()); + } else { + _pattern_matched = false; + } + } + + void regexp_pattern_match(const std::string& pattern_str) override { + _search_string.clear(); + if (RE2::FullMatch(pattern_str, STARTS_WITH_RE, &_search_string)) { + _search_strings->insert_data(_search_string.c_str(), _search_string.size()); + } else { + _pattern_matched = false; + } + } +}; + +struct VectorEndsWithSearchState : public VectorPatternSearchState { + VectorEndsWithSearchState() : VectorPatternSearchState(FunctionLikeBase::vector_ends_with_fn) {} + + ~VectorEndsWithSearchState() override = default; + + void like_pattern_match(const std::string& pattern_str) override { + _search_string.clear(); + if (RE2::FullMatch(pattern_str, LIKE_ENDS_WITH_RE, &_search_string)) { + FunctionLike::remove_escape_character(&_search_string); + _search_strings->insert_data(_search_string.c_str(), _search_string.size()); + } else { + _pattern_matched = false; + } + } + + void regexp_pattern_match(const std::string& pattern_str) override { + _search_string.clear(); + if (RE2::FullMatch(pattern_str, ENDS_WITH_RE, &_search_string)) { + _search_strings->insert_data(_search_string.c_str(), _search_string.size()); + } else { + _pattern_matched = false; + } + } +}; + Status LikeSearchState::clone(LikeSearchState& cloned) { cloned.escape_char = escape_char; cloned.set_search_string(search_string); @@ -89,13 +213,26 @@ Status LikeSearchState::clone(LikeSearchState& cloned) { return Status::OK(); } -Status FunctionLikeBase::constant_allpass_fn(LikeSearchState* state, const ColumnString& val, +Status FunctionLikeBase::constant_allpass_fn(LikeSearchState* state, const ColumnString& vals, const StringRef& pattern, ColumnUInt8::Container& result) { - auto sz = val.size(); - for (size_t i = 0; i < sz; i++) { - result[i] = 1; - } + memset(result.data(), 1, vals.size()); + return Status::OK(); +} + +Status FunctionLikeBase::constant_allpass_fn_scalar(LikeSearchState* state, const StringRef& val, + const StringRef& pattern, + unsigned char* result) { + *result = 1; + return Status::OK(); +} + +Status FunctionLikeBase::vector_allpass_fn(const ColumnString& vals, + const ColumnString& search_strings, + ColumnUInt8::Container& result) { + DCHECK(vals.size() == search_strings.size()); + DCHECK(vals.size() == result.size()); + memset(result.data(), 1, vals.size()); return Status::OK(); } @@ -111,6 +248,29 @@ Status FunctionLikeBase::constant_starts_with_fn(LikeSearchState* state, const C return Status::OK(); } +Status FunctionLikeBase::constant_starts_with_fn_scalar(LikeSearchState* state, + const StringRef& val, + const StringRef& pattern, + unsigned char* result) { + *result = (val.size >= state->search_string_sv.size) && + (state->search_string_sv == val.substring(0, state->search_string_sv.size)); + return Status::OK(); +} + +Status FunctionLikeBase::vector_starts_with_fn(const ColumnString& vals, + const ColumnString& search_strings, + ColumnUInt8::Container& result) { + DCHECK(vals.size() == search_strings.size()); + DCHECK(vals.size() == result.size()); + auto sz = vals.size(); + for (size_t i = 0; i < sz; ++i) { + const auto& str_sv = vals.get_data_at(i); + const auto& search_string_sv = search_strings.get_data_at(i); + result[i] = (str_sv.size >= search_string_sv.size) && str_sv.start_with(search_string_sv); + } + return Status::OK(); +} + Status FunctionLikeBase::constant_ends_with_fn(LikeSearchState* state, const ColumnString& val, const StringRef& pattern, ColumnUInt8::Container& result) { @@ -123,6 +283,29 @@ Status FunctionLikeBase::constant_ends_with_fn(LikeSearchState* state, const Col return Status::OK(); } +Status FunctionLikeBase::constant_ends_with_fn_scalar(LikeSearchState* state, const StringRef& val, + const StringRef& pattern, + unsigned char* result) { + *result = (val.size >= state->search_string_sv.size) && + (state->search_string_sv == val.substring(val.size - state->search_string_sv.size, + state->search_string_sv.size)); + return Status::OK(); +} + +Status FunctionLikeBase::vector_ends_with_fn(const ColumnString& vals, + const ColumnString& search_strings, + ColumnUInt8::Container& result) { + DCHECK(vals.size() == search_strings.size()); + DCHECK(vals.size() == result.size()); + auto sz = vals.size(); + for (size_t i = 0; i < sz; ++i) { + const auto& str_sv = vals.get_data_at(i); + const auto& search_string_sv = search_strings.get_data_at(i); + result[i] = (str_sv.size >= search_string_sv.size) && str_sv.end_with(search_string_sv); + } + return Status::OK(); +} + Status FunctionLikeBase::constant_equals_fn(LikeSearchState* state, const ColumnString& val, const StringRef& pattern, ColumnUInt8::Container& result) { @@ -133,6 +316,27 @@ Status FunctionLikeBase::constant_equals_fn(LikeSearchState* state, const Column return Status::OK(); } +Status FunctionLikeBase::constant_equals_fn_scalar(LikeSearchState* state, const StringRef& val, + const StringRef& pattern, + unsigned char* result) { + *result = (val == state->search_string_sv); + return Status::OK(); +} + +Status FunctionLikeBase::vector_equals_fn(const ColumnString& vals, + const ColumnString& search_strings, + ColumnUInt8::Container& result) { + DCHECK(vals.size() == search_strings.size()); + DCHECK(vals.size() == result.size()); + auto sz = vals.size(); + for (size_t i = 0; i < sz; ++i) { + const auto& str_sv = vals.get_data_at(i); + const auto& search_string_sv = search_strings.get_data_at(i); + result[i] = str_sv == search_string_sv; + } + return Status::OK(); +} + Status FunctionLikeBase::constant_substring_fn(LikeSearchState* state, const ColumnString& val, const StringRef& pattern, ColumnUInt8::Container& result) { @@ -140,44 +344,13 @@ Status FunctionLikeBase::constant_substring_fn(LikeSearchState* state, const Col for (size_t i = 0; i < sz; i++) { if (state->search_string_sv.size == 0) { result[i] = true; + continue; } result[i] = state->substring_pattern.search(val.get_data_at(i)) != -1; } return Status::OK(); } -Status FunctionLikeBase::constant_allpass_fn_scalar(LikeSearchState* state, const StringRef& val, - const StringRef& pattern, - unsigned char* result) { - *result = 1; - return Status::OK(); -} - -Status FunctionLikeBase::constant_starts_with_fn_scalar(LikeSearchState* state, - const StringRef& val, - const StringRef& pattern, - unsigned char* result) { - *result = (val.size >= state->search_string_sv.size) && - (state->search_string_sv == val.substring(0, state->search_string_sv.size)); - return Status::OK(); -} - -Status FunctionLikeBase::constant_ends_with_fn_scalar(LikeSearchState* state, const StringRef& val, - const StringRef& pattern, - unsigned char* result) { - *result = (val.size >= state->search_string_sv.size) && - (state->search_string_sv == val.substring(val.size - state->search_string_sv.size, - state->search_string_sv.size)); - return Status::OK(); -} - -Status FunctionLikeBase::constant_equals_fn_scalar(LikeSearchState* state, const StringRef& val, - const StringRef& pattern, - unsigned char* result) { - *result = (val == state->search_string_sv); - return Status::OK(); -} - Status FunctionLikeBase::constant_substring_fn_scalar(LikeSearchState* state, const StringRef& val, const StringRef& pattern, unsigned char* result) { @@ -189,6 +362,25 @@ Status FunctionLikeBase::constant_substring_fn_scalar(LikeSearchState* state, co return Status::OK(); } +Status FunctionLikeBase::vector_substring_fn(const ColumnString& vals, + const ColumnString& search_strings, + ColumnUInt8::Container& result) { + DCHECK(vals.size() == search_strings.size()); + DCHECK(vals.size() == result.size()); + auto sz = vals.size(); + for (size_t i = 0; i < sz; ++i) { + const auto& str_sv = vals.get_data_at(i); + const auto& search_string_sv = search_strings.get_data_at(i); + if (search_string_sv.size == 0) { + result[i] = true; + continue; + } + doris::StringSearch substring_search(&search_string_sv); + result[i] = substring_search.search(str_sv) != -1; + } + return Status::OK(); +} + Status FunctionLikeBase::constant_regex_fn_scalar(LikeSearchState* state, const StringRef& val, const StringRef& pattern, unsigned char* result) { if (state->hs_database) { // use hyperscan @@ -341,15 +533,9 @@ Status FunctionLikeBase::execute_impl(FunctionContext* context, Block& block, &state->search_state)); } else { const auto pattern_col = block.get_by_position(arguments[1]).column; - if (const auto* str_patterns = check_and_get_column(pattern_col.get())) { - for (int i = 0; i < input_rows_count; i++) { - const auto pattern_val = str_patterns->get_data_at(i); - const auto value_val = values->get_data_at(i); - RETURN_IF_ERROR((state->scalar_function)( - const_cast(&state->search_state), value_val, - pattern_val, &vec_res[i])); - } + RETURN_IF_ERROR( + vector_non_const(*values, *str_patterns, vec_res, state, input_rows_count)); } else if (const auto* const_patterns = check_and_get_column(pattern_col.get())) { const auto& pattern_val = const_patterns->get_data_at(0); @@ -416,11 +602,102 @@ Status FunctionLikeBase::vector_const(const ColumnString& values, const StringRe return Status::OK(); } +template +VPatternSearchStateSPtr FunctionLikeBase::pattern_type_recognition(const ColumnString& patterns) { + VPatternSearchStateSPtr allpass_state = std::make_shared(); + VPatternSearchStateSPtr equal_state = std::make_shared(); + VPatternSearchStateSPtr substring_state = std::make_shared(); + VPatternSearchStateSPtr starts_with_state = std::make_shared(); + VPatternSearchStateSPtr ends_with_state = std::make_shared(); + size_t size = patterns.size(); + + for (size_t i = 0; i < size; ++i) { + if (!allpass_state->_pattern_matched && !equal_state->_pattern_matched && + !substring_state->_pattern_matched && !starts_with_state->_pattern_matched && + !ends_with_state->_pattern_matched) { + return nullptr; + } + std::string pattern_str = patterns.get_data_at(i).to_string(); + if (allpass_state->_pattern_matched) { + if constexpr (LIKE_PATTERN) { + allpass_state->like_pattern_match(pattern_str); + } else { + allpass_state->regexp_pattern_match(pattern_str); + } + } + if (equal_state->_pattern_matched) { + if constexpr (LIKE_PATTERN) { + equal_state->like_pattern_match(pattern_str); + } else { + equal_state->regexp_pattern_match(pattern_str); + } + } + if (substring_state->_pattern_matched) { + if constexpr (LIKE_PATTERN) { + substring_state->like_pattern_match(pattern_str); + } else { + substring_state->regexp_pattern_match(pattern_str); + } + } + if (starts_with_state->_pattern_matched) { + if constexpr (LIKE_PATTERN) { + starts_with_state->like_pattern_match(pattern_str); + } else { + starts_with_state->regexp_pattern_match(pattern_str); + } + } + if (ends_with_state->_pattern_matched) { + if constexpr (LIKE_PATTERN) { + ends_with_state->like_pattern_match(pattern_str); + } else { + ends_with_state->regexp_pattern_match(pattern_str); + } + } + } + + if (allpass_state->_pattern_matched) { + return allpass_state; + } else if (equal_state->_pattern_matched) { + return equal_state; + } else if (substring_state->_pattern_matched) { + return substring_state; + } else if (starts_with_state->_pattern_matched) { + return starts_with_state; + } else if (ends_with_state->_pattern_matched) { + return ends_with_state; + } else { + return nullptr; + } +} + +Status FunctionLikeBase::vector_non_const(const ColumnString& values, const ColumnString& patterns, + ColumnUInt8::Container& result, LikeState* state, + size_t input_rows_count) const { + VPatternSearchStateSPtr vector_search_state; + if (state->is_like_pattern) { + vector_search_state = pattern_type_recognition(patterns); + } else { + vector_search_state = pattern_type_recognition(patterns); + } + if (vector_search_state == nullptr) { + // pattern type recognition failed, use default case + for (int i = 0; i < input_rows_count; ++i) { + const auto pattern_val = patterns.get_data_at(i); + const auto value_val = values.get_data_at(i); + RETURN_IF_ERROR((state->scalar_function)(&state->search_state, value_val, pattern_val, + &result[i])); + } + return Status::OK(); + } + const auto* search_strings = + static_cast(vector_search_state->_search_strings.get()); + return (vector_search_state->_vector_function)(values, *search_strings, result); +} + Status FunctionLike::like_fn(LikeSearchState* state, const ColumnString& val, const StringRef& pattern, ColumnUInt8::Container& result) { std::string re_pattern; convert_like_pattern(state, std::string(pattern.data, pattern.size), &re_pattern); - return regexp_fn(state, val, {re_pattern.c_str(), re_pattern.size()}, result); } @@ -545,6 +822,7 @@ Status FunctionLike::open(FunctionContext* context, FunctionContext::FunctionSta } std::shared_ptr state = std::make_shared(); context->set_function_state(scope, state); + state->is_like_pattern = true; state->function = like_fn; state->scalar_function = like_fn_scalar; if (context->is_col_constant(1)) { @@ -660,6 +938,7 @@ Status FunctionRegexp::open(FunctionContext* context, FunctionContext::FunctionS } std::shared_ptr state = std::make_shared(); context->set_function_state(scope, state); + state->is_like_pattern = false; state->function = regexp_fn; state->scalar_function = regexp_fn_scalar; if (context->is_col_constant(1)) { diff --git a/be/src/vec/functions/like.h b/be/src/vec/functions/like.h index 5cf1024dd400873..1e9cb2e4fad4d76 100644 --- a/be/src/vec/functions/like.h +++ b/be/src/vec/functions/like.h @@ -118,12 +118,36 @@ using LikeFn = std::function; +using VectorLikeFn = std::function; + struct LikeState { + bool is_like_pattern; LikeSearchState search_state; LikeFn function; ScalarLikeFn scalar_function; }; +struct VectorPatternSearchState { + MutableColumnPtr _search_strings; + std::string _search_string; + VectorLikeFn _vector_function; + bool _pattern_matched; + + VectorPatternSearchState(VectorLikeFn vector_function) + : _search_strings(ColumnString::create()), + _vector_function(vector_function), + _pattern_matched(true) {} + + virtual ~VectorPatternSearchState() = default; + + virtual void like_pattern_match(const std::string& pattern_str) = 0; + + virtual void regexp_pattern_match(const std::string& pattern_str) = 0; +}; + +using VPatternSearchStateSPtr = std::shared_ptr; + class FunctionLikeBase : public IFunction { public: size_t get_number_of_arguments() const override { return 2; } @@ -137,54 +161,83 @@ class FunctionLikeBase : public IFunction { Status close(FunctionContext* context, FunctionContext::FunctionStateScope scope) override; + friend struct VectorAllpassSearchState; + friend struct VectorEqualSearchState; + friend struct VectorSubStringSearchState; + friend struct VectorStartsWithSearchState; + friend struct VectorEndsWithSearchState; + protected: Status vector_const(const ColumnString& values, const StringRef* pattern_val, ColumnUInt8::Container& result, const LikeFn& function, LikeSearchState* search_state) const; + Status vector_non_const(const ColumnString& values, const ColumnString& patterns, + ColumnUInt8::Container& result, LikeState* state, + size_t input_rows_count) const; + Status execute_substring(const ColumnString::Chars& values, const ColumnString::Offsets& value_offsets, ColumnUInt8::Container& result, LikeSearchState* search_state) const; + template + static VPatternSearchStateSPtr pattern_type_recognition(const ColumnString& patterns); + static Status constant_allpass_fn(LikeSearchState* state, const ColumnString& val, const StringRef& pattern, ColumnUInt8::Container& result); + static Status constant_allpass_fn_scalar(LikeSearchState* state, const StringRef& val, + const StringRef& pattern, unsigned char* result); + + static Status vector_allpass_fn(const ColumnString& vals, const ColumnString& search_strings, + ColumnUInt8::Container& result); + static Status constant_starts_with_fn(LikeSearchState* state, const ColumnString& val, const StringRef& pattern, ColumnUInt8::Container& result); - static Status constant_ends_with_fn(LikeSearchState* state, const ColumnString& val, - const StringRef& pattern, ColumnUInt8::Container& result); + static Status constant_starts_with_fn_scalar(LikeSearchState* state, const StringRef& val, + const StringRef& pattern, unsigned char* result); - static Status constant_equals_fn(LikeSearchState* state, const ColumnString& val, - const StringRef& pattern, ColumnUInt8::Container& result); + static Status vector_starts_with_fn(const ColumnString& vals, + const ColumnString& search_strings, + ColumnUInt8::Container& result); - static Status constant_substring_fn(LikeSearchState* state, const ColumnString& val, + static Status constant_ends_with_fn(LikeSearchState* state, const ColumnString& val, const StringRef& pattern, ColumnUInt8::Container& result); - static Status constant_regex_fn(LikeSearchState* state, const ColumnString& val, - const StringRef& pattern, ColumnUInt8::Container& result); - - static Status regexp_fn(LikeSearchState* state, const ColumnString& val, - const StringRef& pattern, ColumnUInt8::Container& result); - - static Status constant_allpass_fn_scalar(LikeSearchState* state, const StringRef& val, - const StringRef& pattern, unsigned char* result); - - static Status constant_starts_with_fn_scalar(LikeSearchState* state, const StringRef& val, - const StringRef& pattern, unsigned char* result); - static Status constant_ends_with_fn_scalar(LikeSearchState* state, const StringRef& val, const StringRef& pattern, unsigned char* result); + static Status vector_ends_with_fn(const ColumnString& vals, const ColumnString& search_strings, + ColumnUInt8::Container& result); + + static Status constant_equals_fn(LikeSearchState* state, const ColumnString& val, + const StringRef& pattern, ColumnUInt8::Container& result); + static Status constant_equals_fn_scalar(LikeSearchState* state, const StringRef& val, const StringRef& pattern, unsigned char* result); + static Status vector_equals_fn(const ColumnString& vals, const ColumnString& search_strings, + ColumnUInt8::Container& result); + + static Status constant_substring_fn(LikeSearchState* state, const ColumnString& val, + const StringRef& pattern, ColumnUInt8::Container& result); + static Status constant_substring_fn_scalar(LikeSearchState* state, const StringRef& val, const StringRef& pattern, unsigned char* result); + static Status vector_substring_fn(const ColumnString& vals, const ColumnString& search_strings, + ColumnUInt8::Container& result); + + static Status constant_regex_fn(LikeSearchState* state, const ColumnString& val, + const StringRef& pattern, ColumnUInt8::Container& result); + static Status constant_regex_fn_scalar(LikeSearchState* state, const StringRef& val, const StringRef& pattern, unsigned char* result); + static Status regexp_fn(LikeSearchState* state, const ColumnString& val, + const StringRef& pattern, ColumnUInt8::Container& result); + static Status regexp_fn_scalar(LikeSearchState* state, const StringRef& val, const StringRef& pattern, unsigned char* result); @@ -204,6 +257,11 @@ class FunctionLike : public FunctionLikeBase { Status open(FunctionContext* context, FunctionContext::FunctionStateScope scope) override; friend struct LikeSearchState; + friend struct VectorAllpassSearchState; + friend struct VectorEqualSearchState; + friend struct VectorSubStringSearchState; + friend struct VectorStartsWithSearchState; + friend struct VectorEndsWithSearchState; private: static Status like_fn(LikeSearchState* state, const ColumnString& val, const StringRef& pattern, diff --git a/cloud/src/meta-service/meta_service.cpp b/cloud/src/meta-service/meta_service.cpp index 3921a2f5deaa348..5f2a0d390666735 100644 --- a/cloud/src/meta-service/meta_service.cpp +++ b/cloud/src/meta-service/meta_service.cpp @@ -631,7 +631,7 @@ void MetaServiceImpl::update_tablet(::google::protobuf::RpcController* controlle } else if (tablet_meta_info.has_group_commit_interval_ms()) { tablet_meta.set_group_commit_interval_ms(tablet_meta_info.group_commit_interval_ms()); } else if (tablet_meta_info.has_group_commit_data_bytes()) { - tablet_meta.set_group_commit_data_bytes(tablet_meta_info.has_group_commit_data_bytes()); + tablet_meta.set_group_commit_data_bytes(tablet_meta_info.group_commit_data_bytes()); } int64_t table_id = tablet_meta.table_id(); int64_t index_id = tablet_meta.index_id(); diff --git a/docker/thirdparties/docker-compose/hive/scripts/preinstalled_data/parquet_table/parquet_all_types/.test_hidden_dir/wrong_file b/docker/thirdparties/docker-compose/hive/scripts/preinstalled_data/parquet_table/parquet_all_types/.test_hidden_dir/wrong_file new file mode 100644 index 000000000000000..d37af4bbc510b4e --- /dev/null +++ b/docker/thirdparties/docker-compose/hive/scripts/preinstalled_data/parquet_table/parquet_all_types/.test_hidden_dir/wrong_file @@ -0,0 +1 @@ +wrong file diff --git a/docker/thirdparties/docker-compose/hive/scripts/preinstalled_data/parquet_table/parquet_all_types/test_hidden_file/.hidden_file b/docker/thirdparties/docker-compose/hive/scripts/preinstalled_data/parquet_table/parquet_all_types/test_hidden_file/.hidden_file new file mode 100644 index 000000000000000..136c05e0d0290e2 --- /dev/null +++ b/docker/thirdparties/docker-compose/hive/scripts/preinstalled_data/parquet_table/parquet_all_types/test_hidden_file/.hidden_file @@ -0,0 +1 @@ +hidden diff --git a/fe/fe-common/src/main/java/org/apache/doris/common/Config.java b/fe/fe-common/src/main/java/org/apache/doris/common/Config.java index daa9c8b1d359261..53f5a220bde1c8b 100644 --- a/fe/fe-common/src/main/java/org/apache/doris/common/Config.java +++ b/fe/fe-common/src/main/java/org/apache/doris/common/Config.java @@ -2248,9 +2248,6 @@ public class Config extends ConfigBase { @ConfField(mutable = false) public static boolean allow_analyze_statistics_info_polluting_file_cache = true; - @ConfField - public static int cpu_resource_limit_per_analyze_task = 1; - @ConfField(mutable = true) public static boolean force_sample_analyze = false; // avoid full analyze for performance reason diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateJobStmt.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateJobStmt.java index d8618caae84a594..367d03fa867b492 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateJobStmt.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateJobStmt.java @@ -83,6 +83,8 @@ public class CreateJobStmt extends DdlStmt { private final String comment; + private String jobName; + public static final String CURRENT_TIMESTAMP_STRING = "current_timestamp"; private JobExecuteType executeType; @@ -155,11 +157,11 @@ public void analyze(Analyzer analyzer) throws UserException { timerDefinition.setEndTimeMs(TimeUtils.timeStringToLong(endsTimeStamp)); } checkJobName(labelName.getLabelName()); + this.jobName = labelName.getLabelName(); jobExecutionConfiguration.setTimerDefinition(timerDefinition); String originStmt = getOrigStmt().originStmt; - String executeSql = parseExecuteSql(originStmt); + String executeSql = parseExecuteSql(originStmt, jobName, comment); // create job use label name as its job name - String jobName = labelName.getLabelName(); InsertJob job = new InsertJob(jobName, JobStatus.RUNNING, labelName.getDbName(), @@ -208,10 +210,24 @@ private void analyzerSqlStmt() throws UserException { * parse execute sql from create job stmt * Some stmt not implement toSql method,so we need to parse sql from originStmt */ - private String parseExecuteSql(String sql) throws AnalysisException { + private static String parseExecuteSql(String sql, String jobName, String comment) throws AnalysisException { String lowerCaseSql = sql.toLowerCase(); - int executeSqlIndex = lowerCaseSql.indexOf(" do "); - String executeSql = sql.substring(executeSqlIndex + 4).trim(); + String lowerCaseJobName = jobName.toLowerCase(); + // Find the end position of the job name in the SQL statement. + int jobNameEndIndex = lowerCaseSql.indexOf(lowerCaseJobName) + lowerCaseJobName.length(); + String subSqlStmt = lowerCaseSql.substring(jobNameEndIndex); + String originSubSqlStmt = sql.substring(jobNameEndIndex); + // If the comment is not empty, extract the SQL statement from the end position of the comment. + if (StringUtils.isNotBlank(comment)) { + + String lowerCaseComment = comment.toLowerCase(); + int splitDoIndex = subSqlStmt.indexOf(lowerCaseComment) + lowerCaseComment.length(); + subSqlStmt = subSqlStmt.substring(splitDoIndex); + originSubSqlStmt = originSubSqlStmt.substring(splitDoIndex); + } + // Find the position of the "do" keyword and extract the execution SQL statement from this position. + int executeSqlIndex = subSqlStmt.indexOf("do"); + String executeSql = originSubSqlStmt.substring(executeSqlIndex + 2).trim(); if (StringUtils.isBlank(executeSql)) { throw new AnalysisException("execute sql has invalid format"); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/cloud/catalog/CloudReplica.java b/fe/fe-core/src/main/java/org/apache/doris/cloud/catalog/CloudReplica.java index e49ff6cafa819fa..a51e332a7842183 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/cloud/catalog/CloudReplica.java +++ b/fe/fe-core/src/main/java/org/apache/doris/cloud/catalog/CloudReplica.java @@ -133,7 +133,7 @@ public long getBackendId() { LOG.debug("get cluster by session context cluster: {}", cluster); } } else { - cluster = context.getCloudCluster(); + cluster = context.getCloudCluster(false); if (LOG.isDebugEnabled()) { LOG.debug("get cluster by context {}", cluster); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/cloud/system/CloudSystemInfoService.java b/fe/fe-core/src/main/java/org/apache/doris/cloud/system/CloudSystemInfoService.java index 6e7ca874f6ea9f1..8d852c1109714b7 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/cloud/system/CloudSystemInfoService.java +++ b/fe/fe-core/src/main/java/org/apache/doris/cloud/system/CloudSystemInfoService.java @@ -19,7 +19,6 @@ import org.apache.doris.catalog.Env; import org.apache.doris.catalog.ReplicaAllocation; -import org.apache.doris.cloud.catalog.CloudEnv; import org.apache.doris.cloud.proto.Cloud; import org.apache.doris.cloud.proto.Cloud.ClusterPB; import org.apache.doris.cloud.proto.Cloud.InstanceInfoPB; @@ -324,7 +323,7 @@ public List getBackendsByCurrentCluster() throws UserException { throw new UserException("cluster name is empty"); } - ((CloudEnv) Env.getCurrentEnv()).checkCloudClusterPriv(cluster); + //((CloudEnv) Env.getCurrentEnv()).checkCloudClusterPriv(cluster); return getBackendsByClusterName(cluster); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HiveMetaStoreCache.java b/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HiveMetaStoreCache.java index f2a7019709d0fb9..23c9de3be1f5317 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HiveMetaStoreCache.java +++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/hive/HiveMetaStoreCache.java @@ -50,6 +50,7 @@ import org.apache.doris.planner.ListPartitionPrunerV2; import org.apache.doris.planner.PartitionPrunerV2Base.UniqueId; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.base.Strings; import com.google.common.cache.CacheBuilder; @@ -63,7 +64,6 @@ import com.google.common.collect.Streams; import com.google.common.collect.TreeRangeMap; import lombok.Data; -import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.BlockLocation; @@ -1035,14 +1035,16 @@ public void setAcidInfo(AcidInfo acidInfo) { this.acidInfo = acidInfo; } - private boolean isFileVisible(Path path) { - if (path == null || StringUtils.isEmpty(path.toString())) { + @VisibleForTesting + public static boolean isFileVisible(Path path) { + if (path == null) { return false; } - if (path.getName().startsWith(".") || path.getName().startsWith("_")) { + String pathStr = path.toUri().toString(); + if (containsHiddenPath(pathStr) || path.getName().startsWith("_")) { return false; } - for (String name : path.toString().split("/")) { + for (String name : pathStr.split("/")) { if (isGeneratedPath(name)) { return false; } @@ -1050,6 +1052,18 @@ private boolean isFileVisible(Path path) { return true; } + private static boolean containsHiddenPath(String path) { + if (path.startsWith(".")) { + return true; + } + for (int i = 0; i < path.length() - 1; i++) { + if (path.charAt(i) == '/' && path.charAt(i + 1) == '.') { + return true; + } + } + return false; + } + private static boolean isGeneratedPath(String name) { return "_temporary".equals(name) // generated by spark || "_imapala_insert_staging".equals(name) // generated by impala diff --git a/fe/fe-core/src/main/java/org/apache/doris/load/routineload/ScheduleRule.java b/fe/fe-core/src/main/java/org/apache/doris/load/routineload/ScheduleRule.java index 4064229fa26a463..2b4ef7b297a8c22 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/load/routineload/ScheduleRule.java +++ b/fe/fe-core/src/main/java/org/apache/doris/load/routineload/ScheduleRule.java @@ -66,7 +66,7 @@ public static boolean isNeedAutoSchedule(RoutineLoadJob jobRoutine) { if (jobRoutine.pauseReason != null && jobRoutine.pauseReason.getCode() != InternalErrorCode.MANUAL_PAUSE_ERR && jobRoutine.pauseReason.getCode() != InternalErrorCode.TOO_MANY_FAILURE_ROWS_ERR - && jobRoutine.pauseReason.getCode() != InternalErrorCode.TOO_MANY_FAILURE_ROWS_ERR) { + && jobRoutine.pauseReason.getCode() != InternalErrorCode.CANNOT_RESUME_ERR) { int dead = deadBeCount(); if (dead > Config.max_tolerable_backend_down_num) { if (LOG.isDebugEnabled()) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/PushDownToProjectionFunction.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/PushDownToProjectionFunction.java index 362a84bc943bd02..81678153cd62066 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/PushDownToProjectionFunction.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/PushDownToProjectionFunction.java @@ -71,9 +71,10 @@ public static Expression rewriteToSlot(PushDownToProjectionFunction pushedFuncti // avoid duplicated slots return targetColumnSlot; } + boolean nullable = true; // always nullable at present SlotReference slotRef = new SlotReference(StatementScopeIdGenerator.newExprId(), topColumnSlot.getName(), topColumnSlot.getDataType(), - topColumnSlot.nullable(), topColumnSlot.getQualifier(), topColumnSlot.getTable().get(), + nullable, topColumnSlot.getQualifier(), topColumnSlot.getTable().get(), topColumnSlot.getColumn().get(), Optional.of(topColumnSlot.getInternalName()), fullPaths); ctx.addPathSlotRef(topColumnSlot, fullPaths, slotRef, pushedFunction); diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/Coordinator.java b/fe/fe-core/src/main/java/org/apache/doris/qe/Coordinator.java index b1d591bbdd472eb..9984889a3bb6065 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/Coordinator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/Coordinator.java @@ -101,7 +101,6 @@ import org.apache.doris.thrift.TQueryOptions; import org.apache.doris.thrift.TQueryType; import org.apache.doris.thrift.TReportExecStatusParams; -import org.apache.doris.thrift.TResourceLimit; import org.apache.doris.thrift.TRuntimeFilterParams; import org.apache.doris.thrift.TRuntimeFilterTargetParams; import org.apache.doris.thrift.TRuntimeFilterTargetParamsV2; @@ -358,14 +357,6 @@ public Coordinator(Long jobId, TUniqueId queryId, DescriptorTable descTable, Lis private void setFromUserProperty(ConnectContext connectContext) { String qualifiedUser = connectContext.getQualifiedUser(); - // set cpu resource limit - int cpuLimit = Env.getCurrentEnv().getAuth().getCpuResourceLimit(qualifiedUser); - if (cpuLimit > 0) { - // overwrite the cpu resource limit from session variable; - TResourceLimit resourceLimit = new TResourceLimit(); - resourceLimit.setCpuLimit(cpuLimit); - this.queryOptions.setResourceLimit(resourceLimit); - } // set exec mem limit long maxExecMemByte = connectContext.getSessionVariable().getMaxExecMemByte(); long memLimit = maxExecMemByte > 0 ? maxExecMemByte : @@ -3608,7 +3599,10 @@ public FragmentExecParams(PlanFragment fragment) { List toThrift(int backendNum) { List paramsList = Lists.newArrayList(); - + Set topnFilterSources = scanNodes.stream() + .filter(scanNode -> scanNode instanceof OlapScanNode) + .flatMap(scanNode -> ((OlapScanNode) scanNode).getTopnFilterSortNodes().stream()) + .map(sort -> sort.getId().asInt()).collect(Collectors.toSet()); for (int i = 0; i < instanceExecParams.size(); ++i) { final FInstanceExecParam instanceExecParam = instanceExecParams.get(i); TExecPlanFragmentParams params = new TExecPlanFragmentParams(); @@ -3620,11 +3614,17 @@ List toThrift(int backendNum) { params.setBuildHashTableForBroadcastJoin(instanceExecParam.buildHashTableForBroadcastJoin); params.params.setQueryId(queryId); params.params.setFragmentInstanceId(instanceExecParam.instanceId); + Map> scanRanges = instanceExecParam.perNodeScanRanges; if (scanRanges == null) { scanRanges = Maps.newHashMap(); } - + if (!topnFilterSources.isEmpty()) { + // topn_filter_source_node_ids is used by nereids not by legacy planner. + // if there is no topnFilterSources, do not set it. + // topn_filter_source_node_ids=null means legacy planner + params.params.topn_filter_source_node_ids = Lists.newArrayList(topnFilterSources); + } params.params.setPerNodeScanRanges(scanRanges); params.params.setPerExchNumSenders(perExchNumSenders); @@ -3695,7 +3695,6 @@ List toThrift(int backendNum) { rf.getFilterId().asInt(), rf.toThrift()); } } - params.setFileScanParams(fileScanRangeParamsMap); paramsList.add(params); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/MasterOpExecutor.java b/fe/fe-core/src/main/java/org/apache/doris/qe/MasterOpExecutor.java index f0cd170d2675a9e..cdf588eaebf8315 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/MasterOpExecutor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/MasterOpExecutor.java @@ -20,7 +20,6 @@ import org.apache.doris.analysis.RedirectStatus; import org.apache.doris.catalog.Env; import org.apache.doris.common.ClientPool; -import org.apache.doris.common.Config; import org.apache.doris.common.DdlException; import org.apache.doris.common.ErrorCode; import org.apache.doris.thrift.FrontendService; @@ -161,8 +160,9 @@ private TMasterOpRequest buildStmtForwardParams() { params.setStmtId(ctx.getStmtId()); params.setCurrentUserIdent(ctx.getCurrentUserIdentity().toThrift()); - if (Config.isCloudMode() && !Strings.isNullOrEmpty(ctx.getCloudCluster())) { - params.setCloudCluster(ctx.getCloudCluster()); + String cluster = ctx.getCloudCluster(false); + if (!Strings.isNullOrEmpty(cluster)) { + params.setCloudCluster(cluster); } // query options diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java b/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java index 8bfd0d7f1a4d994..081a619f0aeb06b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java +++ b/fe/fe-core/src/main/java/org/apache/doris/qe/SessionVariable.java @@ -34,7 +34,6 @@ import org.apache.doris.qe.VariableMgr.VarAttr; import org.apache.doris.thrift.TGroupCommitMode; import org.apache.doris.thrift.TQueryOptions; -import org.apache.doris.thrift.TResourceLimit; import org.apache.doris.thrift.TRuntimeFilterType; import com.google.common.base.Joiner; @@ -2613,10 +2612,6 @@ public boolean isGroupByAndHavingUseAliasFirst() { return groupByAndHavingUseAliasFirst; } - public int getCpuResourceLimit() { - return cpuResourceLimit; - } - public int getSendBatchParallelism() { return sendBatchParallelism; } @@ -2993,12 +2988,6 @@ public TQueryOptions toThrift() { tResult.setRuntimeFilterMaxInNum(runtimeFilterMaxInNum); tResult.setRuntimeFilterWaitInfinitely(runtimeFilterWaitInfinitely); - if (cpuResourceLimit > 0) { - TResourceLimit resourceLimit = new TResourceLimit(); - resourceLimit.setCpuLimit(cpuResourceLimit); - tResult.setResourceLimit(resourceLimit); - } - tResult.setEnableFunctionPushdown(enableFunctionPushdown); tResult.setEnableCommonExprPushdown(enableCommonExprPushdown); tResult.setCheckOverflowForDecimal(checkOverflowForDecimal); diff --git a/fe/fe-core/src/main/java/org/apache/doris/statistics/util/StatisticsUtil.java b/fe/fe-core/src/main/java/org/apache/doris/statistics/util/StatisticsUtil.java index f56aa0db607a3c1..47cd932678e6d68 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/statistics/util/StatisticsUtil.java +++ b/fe/fe-core/src/main/java/org/apache/doris/statistics/util/StatisticsUtil.java @@ -191,7 +191,6 @@ public static AutoCloseConnectContext buildConnectContext(boolean limitScan, boo SessionVariable sessionVariable = connectContext.getSessionVariable(); sessionVariable.internalSession = true; sessionVariable.setMaxExecMemByte(Config.statistics_sql_mem_limit_in_bytes); - sessionVariable.cpuResourceLimit = Config.cpu_resource_limit_per_analyze_task; sessionVariable.setEnableInsertStrict(true); sessionVariable.enablePageCache = false; sessionVariable.enableProfile = Config.enable_profile_when_analyze; diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/CreateJobStmtTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/CreateJobStmtTest.java index fd4edeb0a8621ae..190ff15375862fb 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/analysis/CreateJobStmtTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/CreateJobStmtTest.java @@ -24,6 +24,8 @@ import org.junit.jupiter.api.Test; import java.io.StringReader; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; public class CreateJobStmtTest { @@ -75,4 +77,28 @@ public void createCycleJob() throws Exception { sqlParse(badSql); }); } + + @Test + public void testParseExecuteSql() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + Method method = CreateJobStmt.class.getDeclaredMethod("parseExecuteSql", String.class, String.class, String.class); + method.setAccessible(true); + String executeSql = "insert into table.B select * from table.A ;"; + String comment = "do do do do "; + String jobName = "do"; + String doKeywordJobSql = "Create job " + jobName + + "on Scheduler every second comment " + comment + "\n" + + "do" + + executeSql; + + String result = (String) method.invoke(null, doKeywordJobSql, jobName, comment); + Assertions.assertEquals(executeSql, result.trim()); + executeSql = "insert into table.do select * from do.B ;"; + comment = "do starts end do \n \b \r "; + jobName = "do"; + doKeywordJobSql = "Create job " + jobName + + "on Scheduler every second comment " + comment + "do\n" + + executeSql; + result = (String) method.invoke(null, doKeywordJobSql, jobName, comment); + Assertions.assertEquals(executeSql, result.trim()); + } } diff --git a/fe/fe-core/src/test/java/org/apache/doris/datasource/PathVisibleTest.java b/fe/fe-core/src/test/java/org/apache/doris/datasource/PathVisibleTest.java new file mode 100644 index 000000000000000..0937bbc3cc856cb --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/datasource/PathVisibleTest.java @@ -0,0 +1,47 @@ +// 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. + +package org.apache.doris.datasource; + +import org.apache.doris.datasource.hive.HiveMetaStoreCache.FileCacheValue; + +import org.apache.hadoop.fs.Path; +import org.junit.Assert; +import org.junit.Test; + +public class PathVisibleTest { + @Test + public void shouldReturnFalseWhenPathIsNull() { + Assert.assertFalse(FileCacheValue.isFileVisible(null)); + Assert.assertFalse(FileCacheValue.isFileVisible(new Path("s3://visible/.hidden/path"))); + Assert.assertFalse(FileCacheValue.isFileVisible(new Path("/visible/.hidden/path"))); + Assert.assertFalse(FileCacheValue.isFileVisible(new Path("hdfs://visible/path/.file"))); + Assert.assertFalse(FileCacheValue.isFileVisible(new Path("/visible/path/_temporary_xx"))); + Assert.assertFalse(FileCacheValue.isFileVisible(new Path("/visible/path/_imapala_insert_staging"))); + + Assert.assertFalse(FileCacheValue.isFileVisible(new Path("/visible//.hidden/path"))); + Assert.assertFalse(FileCacheValue.isFileVisible(new Path("s3://visible/.hidden/path"))); + Assert.assertFalse(FileCacheValue.isFileVisible(new Path("///visible/path/.file"))); + Assert.assertFalse(FileCacheValue.isFileVisible(new Path("/visible/path///_temporary_xx"))); + Assert.assertFalse(FileCacheValue.isFileVisible(new Path("hdfs://visible//path/_imapala_insert_staging"))); + + Assert.assertTrue(FileCacheValue.isFileVisible(new Path("s3://visible/path"))); + Assert.assertTrue(FileCacheValue.isFileVisible(new Path("path"))); + Assert.assertTrue(FileCacheValue.isFileVisible(new Path("hdfs://visible/path./1.txt"))); + Assert.assertTrue(FileCacheValue.isFileVisible(new Path("/1.txt"))); + } +} diff --git a/regression-test/data/correctness_p0/test_like_predicate_with_concat.out b/regression-test/data/correctness_p0/test_like_predicate_with_concat.out new file mode 100644 index 000000000000000..37f9dd42cd287fe --- /dev/null +++ b/regression-test/data/correctness_p0/test_like_predicate_with_concat.out @@ -0,0 +1,101 @@ +-- This file is automatically generated. You should know what you did if you want to edit this +-- !sql1 -- +0 prefix0_infix0_suffix0 prefix0 +2 prefix2_$infix2$_suffix2 infix2 +3 prefix3_^infix3_suffix3 infix3 +5 prefix5%%$__infix5$_^^^%%$suffix5 suffix5 +6 prefix6__^^_%%%__infix6_%^suffix6% prefix6__^^_%%%__infix6_%^suffix6% +8 prefix8_^^%%%infix8%%$^^___suffix8 +9 prefix9$%%%^^__infix9__&&%%$suffix9 \N + +-- !sql2 -- +0 prefix0_infix0_suffix0 prefix0 +1 %prefix1_infix1_suffix1 prefix1 +2 prefix2_$infix2$_suffix2 infix2 +3 prefix3_^infix3_suffix3 infix3 +4 $prefix4_$infix4%%%_^^suffix4 suffix4 +5 prefix5%%$__infix5$_^^^%%$suffix5 suffix5 +8 prefix8_^^%%%infix8%%$^^___suffix8 +9 prefix9$%%%^^__infix9__&&%%$suffix9 \N + +-- !sql3 -- +0 prefix0_infix0_suffix0 prefix0 +1 %prefix1_infix1_suffix1 prefix1 +2 prefix2_$infix2$_suffix2 infix2 +3 prefix3_^infix3_suffix3 infix3 +4 $prefix4_$infix4%%%_^^suffix4 suffix4 +5 prefix5%%$__infix5$_^^^%%$suffix5 suffix5 +6 prefix6__^^_%%%__infix6_%^suffix6% prefix6__^^_%%%__infix6_%^suffix6% +7 %%%^^^$prefix7_infix7_suffix7%%%^^^$ prefix7_infix7_suffix7 +8 prefix8_^^%%%infix8%%$^^___suffix8 +9 prefix9$%%%^^__infix9__&&%%$suffix9 \N + +-- !sql4 -- +6 prefix6__^^_%%%__infix6_%^suffix6% prefix6__^^_%%%__infix6_%^suffix6% + +-- !sql5 -- +0 prefix0_infix0_suffix0 prefix0 +1 %prefix1_infix1_suffix1 prefix1 +2 prefix2_$infix2$_suffix2 infix2 +3 prefix3_^infix3_suffix3 infix3 +4 $prefix4_$infix4%%%_^^suffix4 suffix4 +5 prefix5%%$__infix5$_^^^%%$suffix5 suffix5 +6 prefix6__^^_%%%__infix6_%^suffix6% prefix6__^^_%%%__infix6_%^suffix6% +7 %%%^^^$prefix7_infix7_suffix7%%%^^^$ prefix7_infix7_suffix7 +8 prefix8_^^%%%infix8%%$^^___suffix8 + +-- !sql6 -- +0 prefix0_infix0_suffix0 prefix0 +6 prefix6__^^_%%%__infix6_%^suffix6% prefix6__^^_%%%__infix6_%^suffix6% +8 prefix8_^^%%%infix8%%$^^___suffix8 + +-- !sql7 -- +4 $prefix4_$infix4%%%_^^suffix4 suffix4 +5 prefix5%%$__infix5$_^^^%%$suffix5 suffix5 +6 prefix6__^^_%%%__infix6_%^suffix6% prefix6__^^_%%%__infix6_%^suffix6% +8 prefix8_^^%%%infix8%%$^^___suffix8 + +-- !sql8 -- +0 prefix0_infix0_suffix0 prefix0 + +-- !sql9 -- +0 prefix0_infix0_suffix0 prefix0 +2 prefix2_$infix2$_suffix2 infix2 +3 prefix3_^infix3_suffix3 infix3 +5 prefix5%%$__infix5$_^^^%%$suffix5 suffix5 +6 prefix6__^^_%%%__infix6_%^suffix6% prefix6__^^_%%%__infix6_%^suffix6% +8 prefix8_^^%%%infix8%%$^^___suffix8 +9 prefix9$%%%^^__infix9__&&%%$suffix9 \N + +-- !sql10 -- +0 prefix0_infix0_suffix0 prefix0 +1 %prefix1_infix1_suffix1 prefix1 +2 prefix2_$infix2$_suffix2 infix2 +3 prefix3_^infix3_suffix3 infix3 +4 $prefix4_$infix4%%%_^^suffix4 suffix4 +5 prefix5%%$__infix5$_^^^%%$suffix5 suffix5 +8 prefix8_^^%%%infix8%%$^^___suffix8 +9 prefix9$%%%^^__infix9__&&%%$suffix9 \N + +-- !sql13 -- +0 prefix0_infix0_suffix0 prefix0 +1 %prefix1_infix1_suffix1 prefix1 +2 prefix2_$infix2$_suffix2 infix2 +3 prefix3_^infix3_suffix3 infix3 +4 $prefix4_$infix4%%%_^^suffix4 suffix4 +5 prefix5%%$__infix5$_^^^%%$suffix5 suffix5 +7 %%%^^^$prefix7_infix7_suffix7%%%^^^$ prefix7_infix7_suffix7 +8 prefix8_^^%%%infix8%%$^^___suffix8 + +-- !sql14 -- +0 prefix0_infix0_suffix0 prefix0 +8 prefix8_^^%%%infix8%%$^^___suffix8 + +-- !sql15 -- +4 $prefix4_$infix4%%%_^^suffix4 suffix4 +5 prefix5%%$__infix5$_^^^%%$suffix5 suffix5 +8 prefix8_^^%%%infix8%%$^^___suffix8 + +-- !sql16 -- +0 prefix0_infix0_suffix0 prefix0 + diff --git a/regression-test/data/insert_p2/test_group_commit_http_stream_lineitem_schema_change.out b/regression-test/data/insert_p2/test_group_commit_http_stream_lineitem_schema_change.out index 2abf38b9beffc30..3306df4d7fef3b0 100644 --- a/regression-test/data/insert_p2/test_group_commit_http_stream_lineitem_schema_change.out +++ b/regression-test/data/insert_p2/test_group_commit_http_stream_lineitem_schema_change.out @@ -6,8 +6,11 @@ 6001215 -- !sql -- -6001215 +4601523 -- !sql -- 6001215 +-- !sql -- +12002430 + diff --git a/regression-test/data/insert_p2/test_group_commit_insert_into_lineitem_scheme_change.out b/regression-test/data/insert_p2/test_group_commit_insert_into_lineitem_scheme_change.out index f2cd979eb49cf79..50925c7d15d384d 100644 --- a/regression-test/data/insert_p2/test_group_commit_insert_into_lineitem_scheme_change.out +++ b/regression-test/data/insert_p2/test_group_commit_insert_into_lineitem_scheme_change.out @@ -6,7 +6,7 @@ 300000 -- !sql -- -240065 +189965 -- !sql -- 300000 diff --git a/regression-test/data/insert_p2/test_group_commit_stream_load_lineitem_schema_change.out b/regression-test/data/insert_p2/test_group_commit_stream_load_lineitem_schema_change.out index 50a4e09f4e23181..3306df4d7fef3b0 100644 --- a/regression-test/data/insert_p2/test_group_commit_stream_load_lineitem_schema_change.out +++ b/regression-test/data/insert_p2/test_group_commit_stream_load_lineitem_schema_change.out @@ -6,7 +6,7 @@ 6001215 -- !sql -- -6001215 +4601523 -- !sql -- 6001215 diff --git a/regression-test/data/nereids_tpch_p0/tpch/topn-filter.out b/regression-test/data/nereids_tpch_p0/tpch/topn-filter.out index be88d829f254404..56ebfba87f0db26 100644 --- a/regression-test/data/nereids_tpch_p0/tpch/topn-filter.out +++ b/regression-test/data/nereids_tpch_p0/tpch/topn-filter.out @@ -27,3 +27,7 @@ 0 50 1 47 +-- !groupingsets2 -- +0 50 +1 47 + diff --git a/regression-test/data/query_p0/aggregate/array_agg.out b/regression-test/data/query_p0/aggregate/array_agg.out index f79368e1d0189da..5f019f755e0e952 100644 --- a/regression-test/data/query_p0/aggregate/array_agg.out +++ b/regression-test/data/query_p0/aggregate/array_agg.out @@ -1,30 +1,30 @@ -- This file is automatically generated. You should know what you did if you want to edit this -- !sql1 -- -["LC", "LB", "alex"] -["LC", "LB", "LA"] -["LC", null, "LA"] -["LC", "LB", "LA"] -[null, "LC", "LB", "LA"] -[null, "LC", "LC", "LC", "LC"] -[null, "LC", "LC", "LC", "LC"] +3 ["LC", "LB", "LA"] +3 ["LC", "LB", "LA"] +3 ["LC", "LB", "alex"] +3 ["LC", null, "LA"] +4 [null, "LC", "LB", "LA"] +5 [null, "LC", "LC", "LC", "LC"] +5 [null, "LC", "LC", "LC", "LC"] -- !sql2 -- -["alex", null, "LC", "LC", "LC", "LC"] -["LB"] -["LC"] -["LA"] -["LB"] -["LC"] -["LA"] -["LC"] -["LA"] -["LB"] -["LC"] -["LA"] -["LB"] -[null, "LC"] -[null, "LC", "LC"] -[null, "LC", "LC"] +0 ["alex", null, "LC", "LC", "LC", "LC"] +1 ["LA"] +1 ["LA"] +1 ["LA"] +1 ["LA"] +1 ["LB"] +1 ["LB"] +1 ["LB"] +1 ["LB"] +1 ["LC"] +1 ["LC"] +1 ["LC"] +1 ["LC"] +2 [null, "LC"] +3 [null, "LC", "LC"] +3 [null, "LC", "LC"] -- !sql3 -- ["LC", "LB", "alex", "LC", "LB", "LA", "LC", null, "LA", "LC", "LB", "LA", null, "LC", "LB", "LA", null, "LC", "LC", "LC", "LC", null, "LC", "LC", "LC", "LC"] @@ -44,14 +44,17 @@ -- !sql6 -- [""] +-- !sql6_1 -- +\N [""] + -- !sql7 -- -["LC", "LB", "alex"] +[""] +[""] ["LC", "LB", "LA"] -["LC", null, "LA"] ["LC", "LB", "LA"] ["LC", "LB", "LA"] -[""] -[""] +["LC", "LB", "alex"] +["LC", null, "LA"] -- !sql8 -- [null] @@ -65,3 +68,30 @@ 7 [null] 8 [null] +-- !sql11 -- +3 3 +3 3 +3 3 +3 3 +4 4 +5 5 +5 5 + +-- !sql21 -- +0 6 +1 1 +1 1 +1 1 +1 1 +1 1 +1 1 +1 1 +1 1 +1 1 +1 1 +1 1 +1 1 +2 2 +3 3 +3 3 + diff --git a/regression-test/data/variant_github_events_p0/load.out b/regression-test/data/variant_github_events_p0/load.out index 13ce3dfca084cbd..d9e328f3733056c 100644 --- a/regression-test/data/variant_github_events_p0/load.out +++ b/regression-test/data/variant_github_events_p0/load.out @@ -5,3 +5,9 @@ \N 4748 +-- !sql -- +5995 {"actor":{"avatar_url":"https://avatars.githubusercontent.com/u/3437916?","gravatar_id":"","id":3437916,"login":"misol","url":"https://api.github.com/users/misol"},"created_at":"2015-01-01T01:47:44Z","id":"2489414108","org":{"avatar_url":"https://avatars.githubusercontent.com/u/1429259?","gravatar_id":"","id":1429259,"login":"xpressengine","url":"https://api.github.com/orgs/xpressengine"},"payload":{"action":"opened","number":1120,"pull_request":{"_links":{"comments":{"href":"https://api.github.com/repos/xpressengine/xe-core/issues/1120/comments"},"commits":{"href":"https://api.github.com/repos/xpressengine/xe-core/pulls/1120/commits"},"html":{"href":"https://github.com/xpressengine/xe-core/pull/1120"},"issue":{"href":"https://api.github.com/repos/xpressengine/xe-core/issues/1120"},"review_comment":{"href":"https://api.github.com/repos/xpressengine/xe-core/pulls/comments/{number}"},"review_comments":{"href":"https://api.github.com/repos/xpressengine/xe-core/pulls/1120/comments"},"self":{"href":"https://api.github.com/repos/xpressengine/xe-core/pulls/1120"},"statuses":{"href":"https://api.github.com/repos/xpressengine/xe-core/statuses/d2b05732abfd85020335ce272abd37c0ad1c6654"}},"additions":4748,"base":{"label":"xpressengine:develop","ref":"develop","repo":{"archive_url":"https://api.github.com/repos/xpressengine/xe-core/{archive_format}{/ref}","assignees_url":"https://api.github.com/repos/xpressengine/xe-core/assignees{/user}","blobs_url":"https://api.github.com/repos/xpressengine/xe-core/git/blobs{/sha}","branches_url":"https://api.github.com/repos/xpressengine/xe-core/branches{/branch}","clone_url":"https://github.com/xpressengine/xe-core.git","collaborators_url":"https://api.github.com/repos/xpressengine/xe-core/collaborators{/collaborator}","comments_url":"https://api.github.com/repos/xpressengine/xe-core/comments{/number}","commits_url":"https://api.github.com/repos/xpressengine/xe-core/commits{/sha}","compare_url":"https://api.github.com/repos/xpressengine/xe-core/compare/{base}...{head}","contents_url":"https://api.github.com/repos/xpressengine/xe-core/contents/{+path}","contributors_url":"https://api.github.com/repos/xpressengine/xe-core/contributors","created_at":"2013-02-01T07:16:05Z","default_branch":"master","description":"PHP Open Source CMS","downloads_url":"https://api.github.com/repos/xpressengine/xe-core/downloads","events_url":"https://api.github.com/repos/xpressengine/xe-core/events","fork":0,"forks":143,"forks_count":143,"forks_url":"https://api.github.com/repos/xpressengine/xe-core/forks","full_name":"xpressengine/xe-core","git_commits_url":"https://api.github.com/repos/xpressengine/xe-core/git/commits{/sha}","git_refs_url":"https://api.github.com/repos/xpressengine/xe-core/git/refs{/sha}","git_tags_url":"https://api.github.com/repos/xpressengine/xe-core/git/tags{/sha}","git_url":"git://github.com/xpressengine/xe-core.git","has_downloads":1,"has_issues":1,"has_pages":0,"has_wiki":1,"homepage":"http://www.xpressengine.com","hooks_url":"https://api.github.com/repos/xpressengine/xe-core/hooks","html_url":"https://github.com/xpressengine/xe-core","id":7953576,"issue_comment_url":"https://api.github.com/repos/xpressengine/xe-core/issues/comments/{number}","issue_events_url":"https://api.github.com/repos/xpressengine/xe-core/issues/events{/number}","issues_url":"https://api.github.com/repos/xpressengine/xe-core/issues{/number}","keys_url":"https://api.github.com/repos/xpressengine/xe-core/keys{/key_id}","labels_url":"https://api.github.com/repos/xpressengine/xe-core/labels{/name}","language":"PHP","languages_url":"https://api.github.com/repos/xpressengine/xe-core/languages","merges_url":"https://api.github.com/repos/xpressengine/xe-core/merges","milestones_url":"https://api.github.com/repos/xpressengine/xe-core/milestones{/number}","name":"xe-core","notifications_url":"https://api.github.com/repos/xpressengine/xe-core/notifications{?since,all,participating}","open_issues":156,"open_issues_count":156,"owner":{"avatar_url":"https://avatars.githubusercontent.com/u/1429259?v=3","events_url":"https://api.github.com/users/xpressengine/events{/privacy}","followers_url":"https://api.github.com/users/xpressengine/followers","following_url":"https://api.github.com/users/xpressengine/following{/other_user}","gists_url":"https://api.github.com/users/xpressengine/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/xpressengine","id":1429259,"login":"xpressengine","organizations_url":"https://api.github.com/users/xpressengine/orgs","received_events_url":"https://api.github.com/users/xpressengine/received_events","repos_url":"https://api.github.com/users/xpressengine/repos","site_admin":0,"starred_url":"https://api.github.com/users/xpressengine/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xpressengine/subscriptions","type":"Organization","url":"https://api.github.com/users/xpressengine"},"private":0,"pulls_url":"https://api.github.com/repos/xpressengine/xe-core/pulls{/number}","pushed_at":"2014-12-31T08:52:46Z","releases_url":"https://api.github.com/repos/xpressengine/xe-core/releases{/id}","size":90250,"ssh_url":"git@github.com:xpressengine/xe-core.git","stargazers_count":149,"stargazers_url":"https://api.github.com/repos/xpressengine/xe-core/stargazers","statuses_url":"https://api.github.com/repos/xpressengine/xe-core/statuses/{sha}","subscribers_url":"https://api.github.com/repos/xpressengine/xe-core/subscribers","subscription_url":"https://api.github.com/repos/xpressengine/xe-core/subscription","svn_url":"https://github.com/xpressengine/xe-core","tags_url":"https://api.github.com/repos/xpressengine/xe-core/tags","teams_url":"https://api.github.com/repos/xpressengine/xe-core/teams","trees_url":"https://api.github.com/repos/xpressengine/xe-core/git/trees{/sha}","updated_at":"2014-12-30T00:05:52Z","url":"https://api.github.com/repos/xpressengine/xe-core","watchers":149,"watchers_count":149},"sha":"c3430d1c724f42154ca5dd648637c4df796d1708","user":{"avatar_url":"https://avatars.githubusercontent.com/u/1429259?v=3","events_url":"https://api.github.com/users/xpressengine/events{/privacy}","followers_url":"https://api.github.com/users/xpressengine/followers","following_url":"https://api.github.com/users/xpressengine/following{/other_user}","gists_url":"https://api.github.com/users/xpressengine/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/xpressengine","id":1429259,"login":"xpressengine","organizations_url":"https://api.github.com/users/xpressengine/orgs","received_events_url":"https://api.github.com/users/xpressengine/received_events","repos_url":"https://api.github.com/users/xpressengine/repos","site_admin":0,"starred_url":"https://api.github.com/users/xpressengine/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xpressengine/subscriptions","type":"Organization","url":"https://api.github.com/users/xpressengine"}},"body":"https://github.com/xpressengine/xe-core/issues/634\\r\\n\\r\\n# Internet Explorer send punycode URL(ASCII) URL and non-alphabet\\r\\nUnicode URL URL as a referer. 인터넷 익스플로러는 리퍼러 주소로 퓨니코드 주소와 유니코드 URL을 섞어\\r\\n쓰고 있습니다. AJAX 통신에는 리퍼러로 Unicode를 사용하고 요청 호스트로는 퓨니코드 URL을 사용(이건 다국어 주소\\r\\n형식으로 접속하려면 이렇게 했어야 할 것)합니다.\\r\\n- XE strictly compare referer and server host for denying CSRF, but\\r\\npunycode URL and Unicode URL should be dealt as a same one. 그런데 XE는 리퍼러의\\r\\n호스트와 서버 호스트를 비교합니다. punycode로 쓰인 주소와 Unicode로 쓰인 주소는 같은 주소를 지시하더라도 문자열이\\r\\n다릅니다. 같은 주소를 지칭하는 다른 문자열을 punycode로 변환해서 같은 주소라고 인식할 수 있게 수정했습니다.\\r\\n- Fix checkCSRF function to deal both form as a same one.\\r\\n- Convert Unicode URL input to punycode URL on the Admin Default URL\\r\\nSettings. 관리자가 유니코드 형식으로 기본 주소를 입력하더라도, 퓨니코드로 변환해 저장하도록 했습니다. 퓨니코드로 저장하는\\r\\n것이 여러모로 유용하기 때문입니다.\\r\\n- For converting punycode URL, include IDNA coverting class. 퓨니코드와 유니코드\\r\\n간 변환을 위해서 IDNA 변환 클래스(LGPL사용권)를 포함시켰습니다.\\r\\n\\r\\n**이 수정을 하면 *한글 도메인에서 글 작성이 가능*합니다. 하지만, *파일 업로드의 경우는 SWF Uploader 이슈로 파일 업로드가 불가능*합니다. 이 문제는, HTML5를 지원하는 파일 업로더를 이용하면 해결됩니다. (워드 프레스 등의 해결법) HTML5를 지원하는 파일 업로더는 AXISJ 업로더 등을 포함해서 XE 공식 홈페이지 자료실에서 다운받아 사용할 수 있습니다.(에디터 변경)**","changed_files":8,"comments":0,"comments_url":"https://api.github.com/repos/xpressengine/xe-core/issues/1120/comments","commits":1,"commits_url":"https://api.github.com/repos/xpressengine/xe-core/pulls/1120/commits","created_at":"2015-01-01T01:47:43Z","deletions":1,"diff_url":"https://github.com/xpressengine/xe-core/pull/1120.diff","head":{"label":"misol:support_punycode_domain","ref":"support_punycode_domain","repo":{"archive_url":"https://api.github.com/repos/misol/xe-core/{archive_format}{/ref}","assignees_url":"https://api.github.com/repos/misol/xe-core/assignees{/user}","blobs_url":"https://api.github.com/repos/misol/xe-core/git/blobs{/sha}","branches_url":"https://api.github.com/repos/misol/xe-core/branches{/branch}","clone_url":"https://github.com/misol/xe-core.git","collaborators_url":"https://api.github.com/repos/misol/xe-core/collaborators{/collaborator}","comments_url":"https://api.github.com/repos/misol/xe-core/comments{/number}","commits_url":"https://api.github.com/repos/misol/xe-core/commits{/sha}","compare_url":"https://api.github.com/repos/misol/xe-core/compare/{base}...{head}","contents_url":"https://api.github.com/repos/misol/xe-core/contents/{+path}","contributors_url":"https://api.github.com/repos/misol/xe-core/contributors","created_at":"2014-12-31T14:41:05Z","default_branch":"master","description":"PHP Open Source CMS","downloads_url":"https://api.github.com/repos/misol/xe-core/downloads","events_url":"https://api.github.com/repos/misol/xe-core/events","fork":1,"forks":0,"forks_count":0,"forks_url":"https://api.github.com/repos/misol/xe-core/forks","full_name":"misol/xe-core","git_commits_url":"https://api.github.com/repos/misol/xe-core/git/commits{/sha}","git_refs_url":"https://api.github.com/repos/misol/xe-core/git/refs{/sha}","git_tags_url":"https://api.github.com/repos/misol/xe-core/git/tags{/sha}","git_url":"git://github.com/misol/xe-core.git","has_downloads":1,"has_issues":0,"has_pages":0,"has_wiki":1,"homepage":"http://www.xpressengine.com","hooks_url":"https://api.github.com/repos/misol/xe-core/hooks","html_url":"https://github.com/misol/xe-core","id":28667946,"issue_comment_url":"https://api.github.com/repos/misol/xe-core/issues/comments/{number}","issue_events_url":"https://api.github.com/repos/misol/xe-core/issues/events{/number}","issues_url":"https://api.github.com/repos/misol/xe-core/issues{/number}","keys_url":"https://api.github.com/repos/misol/xe-core/keys{/key_id}","labels_url":"https://api.github.com/repos/misol/xe-core/labels{/name}","language":"PHP","languages_url":"https://api.github.com/repos/misol/xe-core/languages","merges_url":"https://api.github.com/repos/misol/xe-core/merges","milestones_url":"https://api.github.com/repos/misol/xe-core/milestones{/number}","name":"xe-core","notifications_url":"https://api.github.com/repos/misol/xe-core/notifications{?since,all,participating}","open_issues":0,"open_issues_count":0,"owner":{"avatar_url":"https://avatars.githubusercontent.com/u/3437916?v=3","events_url":"https://api.github.com/users/misol/events{/privacy}","followers_url":"https://api.github.com/users/misol/followers","following_url":"https://api.github.com/users/misol/following{/other_user}","gists_url":"https://api.github.com/users/misol/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/misol","id":3437916,"login":"misol","organizations_url":"https://api.github.com/users/misol/orgs","received_events_url":"https://api.github.com/users/misol/received_events","repos_url":"https://api.github.com/users/misol/repos","site_admin":0,"starred_url":"https://api.github.com/users/misol/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/misol/subscriptions","type":"User","url":"https://api.github.com/users/misol"},"private":0,"pulls_url":"https://api.github.com/repos/misol/xe-core/pulls{/number}","pushed_at":"2015-01-01T01:36:28Z","releases_url":"https://api.github.com/repos/misol/xe-core/releases{/id}","size":90250,"ssh_url":"git@github.com:misol/xe-core.git","stargazers_count":0,"stargazers_url":"https://api.github.com/repos/misol/xe-core/stargazers","statuses_url":"https://api.github.com/repos/misol/xe-core/statuses/{sha}","subscribers_url":"https://api.github.com/repos/misol/xe-core/subscribers","subscription_url":"https://api.github.com/repos/misol/xe-core/subscription","svn_url":"https://github.com/misol/xe-core","tags_url":"https://api.github.com/repos/misol/xe-core/tags","teams_url":"https://api.github.com/repos/misol/xe-core/teams","trees_url":"https://api.github.com/repos/misol/xe-core/git/trees{/sha}","updated_at":"2014-12-31T14:41:10Z","url":"https://api.github.com/repos/misol/xe-core","watchers":0,"watchers_count":0},"sha":"d2b05732abfd85020335ce272abd37c0ad1c6654","user":{"avatar_url":"https://avatars.githubusercontent.com/u/3437916?v=3","events_url":"https://api.github.com/users/misol/events{/privacy}","followers_url":"https://api.github.com/users/misol/followers","following_url":"https://api.github.com/users/misol/following{/other_user}","gists_url":"https://api.github.com/users/misol/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/misol","id":3437916,"login":"misol","organizations_url":"https://api.github.com/users/misol/orgs","received_events_url":"https://api.github.com/users/misol/received_events","repos_url":"https://api.github.com/users/misol/repos","site_admin":0,"starred_url":"https://api.github.com/users/misol/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/misol/subscriptions","type":"User","url":"https://api.github.com/users/misol"}},"html_url":"https://github.com/xpressengine/xe-core/pull/1120","id":26739793,"issue_url":"https://api.github.com/repos/xpressengine/xe-core/issues/1120","locked":0,"mergeable_state":"unknown","merged":0,"number":1120,"patch_url":"https://github.com/xpressengine/xe-core/pull/1120.patch","review_comment_url":"https://api.github.com/repos/xpressengine/xe-core/pulls/comments/{number}","review_comments":0,"review_comments_url":"https://api.github.com/repos/xpressengine/xe-core/pulls/1120/comments","state":"open","statuses_url":"https://api.github.com/repos/xpressengine/xe-core/statuses/d2b05732abfd85020335ce272abd37c0ad1c6654","title":"fix for Not-Alphabet URL document writing (#634)","updated_at":"2015-01-01T01:47:43Z","url":"https://api.github.com/repos/xpressengine/xe-core/pulls/1120","user":{"avatar_url":"https://avatars.githubusercontent.com/u/3437916?v=3","events_url":"https://api.github.com/users/misol/events{/privacy}","followers_url":"https://api.github.com/users/misol/followers","following_url":"https://api.github.com/users/misol/following{/other_user}","gists_url":"https://api.github.com/users/misol/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/misol","id":3437916,"login":"misol","organizations_url":"https://api.github.com/users/misol/orgs","received_events_url":"https://api.github.com/users/misol/received_events","repos_url":"https://api.github.com/users/misol/repos","site_admin":0,"starred_url":"https://api.github.com/users/misol/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/misol/subscriptions","type":"User","url":"https://api.github.com/users/misol"}}},"public":1,"repo":{"id":7953576,"name":"xpressengine/xe-core","url":"https://api.github.com/repos/xpressengine/xe-core"},"type":"PullRequestEvent"} +864 {"actor":{"avatar_url":"https://avatars.githubusercontent.com/u/4381756?","gravatar_id":"","id":4381756,"login":"qw5414","url":"https://api.github.com/users/qw5414"},"created_at":"2015-01-01T02:06:41Z","id":"2489420466","org":{"avatar_url":"https://avatars.githubusercontent.com/u/1429259?","gravatar_id":"","id":1429259,"login":"xpressengine","url":"https://api.github.com/orgs/xpressengine"},"payload":{"action":"created","comment":{"body":"乃\\r\\n","created_at":"2015-01-01T02:06:40Z","html_url":"https://github.com/xpressengine/xe-core/pull/1120#issuecomment-68478485","id":68478485,"issue_url":"https://api.github.com/repos/xpressengine/xe-core/issues/1120","updated_at":"2015-01-01T02:06:40Z","url":"https://api.github.com/repos/xpressengine/xe-core/issues/comments/68478485","user":{"avatar_url":"https://avatars.githubusercontent.com/u/4381756?v=3","events_url":"https://api.github.com/users/qw5414/events{/privacy}","followers_url":"https://api.github.com/users/qw5414/followers","following_url":"https://api.github.com/users/qw5414/following{/other_user}","gists_url":"https://api.github.com/users/qw5414/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/qw5414","id":4381756,"login":"qw5414","organizations_url":"https://api.github.com/users/qw5414/orgs","received_events_url":"https://api.github.com/users/qw5414/received_events","repos_url":"https://api.github.com/users/qw5414/repos","site_admin":0,"starred_url":"https://api.github.com/users/qw5414/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/qw5414/subscriptions","type":"User","url":"https://api.github.com/users/qw5414"}},"issue":{"body":"https://github.com/xpressengine/xe-core/issues/634\\r\\n\\r\\n# Internet Explorer send punycode URL(ASCII) URL and non-alphabet\\r\\nUnicode URL URL as a referer. 인터넷 익스플로러는 리퍼러 주소로 퓨니코드 주소와 유니코드 URL을 섞어\\r\\n쓰고 있습니다. AJAX 통신에는 리퍼러로 Unicode를 사용하고 요청 호스트로는 퓨니코드 URL을 사용(이건 다국어 주소\\r\\n형식으로 접속하려면 이렇게 했어야 할 것)합니다.\\r\\n- XE strictly compare referer and server host for denying CSRF, but\\r\\npunycode URL and Unicode URL should be dealt as a same one. 그런데 XE는 리퍼러의\\r\\n호스트와 서버 호스트를 비교합니다. punycode로 쓰인 주소와 Unicode로 쓰인 주소는 같은 주소를 지시하더라도 문자열이\\r\\n다릅니다. 같은 주소를 지칭하는 다른 문자열을 punycode로 변환해서 같은 주소라고 인식할 수 있게 수정했습니다.\\r\\n- Fix checkCSRF function to deal both form as a same one.\\r\\n- Convert Unicode URL input to punycode URL on the Admin Default URL\\r\\nSettings. 관리자가 유니코드 형식으로 기본 주소를 입력하더라도, 퓨니코드로 변환해 저장하도록 했습니다. 퓨니코드로 저장하는\\r\\n것이 여러모로 유용하기 때문입니다.\\r\\n- For converting punycode URL, include IDNA coverting class. 퓨니코드와 유니코드\\r\\n간 변환을 위해서 IDNA 변환 클래스(LGPL사용권)를 포함시켰습니다.\\r\\n\\r\\n**이 수정을 하면 *한글 도메인에서 글 작성이 가능*합니다. 하지만, *파일 업로드의 경우는 SWF Uploader 이슈로 파일 업로드가 불가능*합니다. 이 문제는, HTML5를 지원하는 파일 업로더를 이용하면 해결됩니다. (워드 프레스 등의 해결법) HTML5를 지원하는 파일 업로더는 AXISJ 업로더 등을 포함해서 XE 공식 홈페이지 자료실에서 다운받아 사용할 수 있습니다.(에디터 변경)**","comments":1,"comments_url":"https://api.github.com/repos/xpressengine/xe-core/issues/1120/comments","created_at":"2015-01-01T01:47:43Z","events_url":"https://api.github.com/repos/xpressengine/xe-core/issues/1120/events","html_url":"https://github.com/xpressengine/xe-core/pull/1120","id":53211000,"labels_url":"https://api.github.com/repos/xpressengine/xe-core/issues/1120/labels{/name}","locked":0,"number":1120,"pull_request":{"diff_url":"https://github.com/xpressengine/xe-core/pull/1120.diff","html_url":"https://github.com/xpressengine/xe-core/pull/1120","patch_url":"https://github.com/xpressengine/xe-core/pull/1120.patch","url":"https://api.github.com/repos/xpressengine/xe-core/pulls/1120"},"state":"open","title":"fix for Not-Alphabet URL document writing (#634)","updated_at":"2015-01-01T02:06:40Z","url":"https://api.github.com/repos/xpressengine/xe-core/issues/1120","user":{"avatar_url":"https://avatars.githubusercontent.com/u/3437916?v=3","events_url":"https://api.github.com/users/misol/events{/privacy}","followers_url":"https://api.github.com/users/misol/followers","following_url":"https://api.github.com/users/misol/following{/other_user}","gists_url":"https://api.github.com/users/misol/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/misol","id":3437916,"login":"misol","organizations_url":"https://api.github.com/users/misol/orgs","received_events_url":"https://api.github.com/users/misol/received_events","repos_url":"https://api.github.com/users/misol/repos","site_admin":0,"starred_url":"https://api.github.com/users/misol/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/misol/subscriptions","type":"User","url":"https://api.github.com/users/misol"}}},"public":1,"repo":{"id":7953576,"name":"xpressengine/xe-core","url":"https://api.github.com/repos/xpressengine/xe-core"},"type":"IssueCommentEvent"} +5451 {"actor":{"avatar_url":"https://avatars.githubusercontent.com/u/3437916?","gravatar_id":"","id":3437916,"login":"misol","url":"https://api.github.com/users/misol"},"created_at":"2015-01-01T02:48:28Z","id":"2489433218","org":{"avatar_url":"https://avatars.githubusercontent.com/u/1429259?","gravatar_id":"","id":1429259,"login":"xpressengine","url":"https://api.github.com/orgs/xpressengine"},"payload":{"action":"created","comment":{"body":"Html5 도 같이 지원하는 업로더였으면 좋겠어요! 구글링 해보면 꽤 나와요 :)","created_at":"2015-01-01T02:48:27Z","html_url":"https://github.com/xpressengine/xe-core/issues/1086#issuecomment-68479093","id":68479093,"issue_url":"https://api.github.com/repos/xpressengine/xe-core/issues/1086","updated_at":"2015-01-01T02:48:27Z","url":"https://api.github.com/repos/xpressengine/xe-core/issues/comments/68479093","user":{"avatar_url":"https://avatars.githubusercontent.com/u/3437916?v=3","events_url":"https://api.github.com/users/misol/events{/privacy}","followers_url":"https://api.github.com/users/misol/followers","following_url":"https://api.github.com/users/misol/following{/other_user}","gists_url":"https://api.github.com/users/misol/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/misol","id":3437916,"login":"misol","organizations_url":"https://api.github.com/users/misol/orgs","received_events_url":"https://api.github.com/users/misol/received_events","repos_url":"https://api.github.com/users/misol/repos","site_admin":0,"starred_url":"https://api.github.com/users/misol/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/misol/subscriptions","type":"User","url":"https://api.github.com/users/misol"}},"issue":{"comments":4,"comments_url":"https://api.github.com/repos/xpressengine/xe-core/issues/1086/comments","created_at":"2014-12-12T11:48:03Z","events_url":"https://api.github.com/repos/xpressengine/xe-core/issues/1086/events","html_url":"https://github.com/xpressengine/xe-core/issues/1086","id":51797879,"labels_url":"https://api.github.com/repos/xpressengine/xe-core/issues/1086/labels{/name}","locked":0,"number":1086,"state":"open","title":"파일 업로더 교체","updated_at":"2015-01-01T02:48:27Z","url":"https://api.github.com/repos/xpressengine/xe-core/issues/1086","user":{"avatar_url":"https://avatars.githubusercontent.com/u/53764?v=3","events_url":"https://api.github.com/users/bnu/events{/privacy}","followers_url":"https://api.github.com/users/bnu/followers","following_url":"https://api.github.com/users/bnu/following{/other_user}","gists_url":"https://api.github.com/users/bnu/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/bnu","id":53764,"login":"bnu","organizations_url":"https://api.github.com/users/bnu/orgs","received_events_url":"https://api.github.com/users/bnu/received_events","repos_url":"https://api.github.com/users/bnu/repos","site_admin":0,"starred_url":"https://api.github.com/users/bnu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bnu/subscriptions","type":"User","url":"https://api.github.com/users/bnu"}}},"public":1,"repo":{"id":7953576,"name":"xpressengine/xe-core","url":"https://api.github.com/repos/xpressengine/xe-core"},"type":"IssueCommentEvent"} +4842 {"actor":{"avatar_url":"https://avatars.githubusercontent.com/u/53764?","gravatar_id":"","id":53764,"login":"bnu","url":"https://api.github.com/users/bnu"},"created_at":"2015-01-01T03:47:41Z","id":"2489448854","org":{"avatar_url":"https://avatars.githubusercontent.com/u/1429259?","gravatar_id":"","id":1429259,"login":"xpressengine","url":"https://api.github.com/orgs/xpressengine"},"payload":{"action":"created","comment":{"body":"@misol 고르기가 어렵네요.\\r\\nplup가 좋은데 GPL이네요^^;","created_at":"2015-01-01T03:47:41Z","html_url":"https://github.com/xpressengine/xe-core/issues/1086#issuecomment-68479786","id":68479786,"issue_url":"https://api.github.com/repos/xpressengine/xe-core/issues/1086","updated_at":"2015-01-01T03:47:41Z","url":"https://api.github.com/repos/xpressengine/xe-core/issues/comments/68479786","user":{"avatar_url":"https://avatars.githubusercontent.com/u/53764?v=3","events_url":"https://api.github.com/users/bnu/events{/privacy}","followers_url":"https://api.github.com/users/bnu/followers","following_url":"https://api.github.com/users/bnu/following{/other_user}","gists_url":"https://api.github.com/users/bnu/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/bnu","id":53764,"login":"bnu","organizations_url":"https://api.github.com/users/bnu/orgs","received_events_url":"https://api.github.com/users/bnu/received_events","repos_url":"https://api.github.com/users/bnu/repos","site_admin":0,"starred_url":"https://api.github.com/users/bnu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bnu/subscriptions","type":"User","url":"https://api.github.com/users/bnu"}},"issue":{"comments":5,"comments_url":"https://api.github.com/repos/xpressengine/xe-core/issues/1086/comments","created_at":"2014-12-12T11:48:03Z","events_url":"https://api.github.com/repos/xpressengine/xe-core/issues/1086/events","html_url":"https://github.com/xpressengine/xe-core/issues/1086","id":51797879,"labels_url":"https://api.github.com/repos/xpressengine/xe-core/issues/1086/labels{/name}","locked":0,"number":1086,"state":"open","title":"파일 업로더 교체","updated_at":"2015-01-01T03:47:41Z","url":"https://api.github.com/repos/xpressengine/xe-core/issues/1086","user":{"avatar_url":"https://avatars.githubusercontent.com/u/53764?v=3","events_url":"https://api.github.com/users/bnu/events{/privacy}","followers_url":"https://api.github.com/users/bnu/followers","following_url":"https://api.github.com/users/bnu/following{/other_user}","gists_url":"https://api.github.com/users/bnu/gists{/gist_id}","gravatar_id":"","html_url":"https://github.com/bnu","id":53764,"login":"bnu","organizations_url":"https://api.github.com/users/bnu/orgs","received_events_url":"https://api.github.com/users/bnu/received_events","repos_url":"https://api.github.com/users/bnu/repos","site_admin":0,"starred_url":"https://api.github.com/users/bnu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bnu/subscriptions","type":"User","url":"https://api.github.com/users/bnu"}}},"public":1,"repo":{"id":7953576,"name":"xpressengine/xe-core","url":"https://api.github.com/repos/xpressengine/xe-core"},"type":"IssueCommentEvent"} + diff --git a/regression-test/suites/correctness_p0/test_like_predicate_with_concat.groovy b/regression-test/suites/correctness_p0/test_like_predicate_with_concat.groovy new file mode 100644 index 000000000000000..a918bdff3a33c59 --- /dev/null +++ b/regression-test/suites/correctness_p0/test_like_predicate_with_concat.groovy @@ -0,0 +1,112 @@ +// 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. + +suite("test_like_predicate_with_concat") { + sql """ DROP TABLE IF EXISTS `test_like_predicate_with_concat` """ + + sql """ + CREATE TABLE IF NOT EXISTS `test_like_predicate_with_concat` ( + `id` int, + `value_col` string, + `pattern_col` string + ) ENGINE=OLAP + DISTRIBUTED BY HASH(`id`) BUCKETS 4 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1" + ); + """ + + sql """ + INSERT INTO `test_like_predicate_with_concat` VALUES + (0, 'prefix0_infix0_suffix0', 'prefix0'), + (1, '%prefix1_infix1_suffix1', 'prefix1'), + (2, 'prefix2_\$infix2\$_suffix2', 'infix2'), + (3, 'prefix3_^infix3_suffix3', 'infix3'), + (4, '\$prefix4_\$infix4%%%_^^suffix4', 'suffix4'), + (5, 'prefix5%%\$__infix5\$_^^^%%\$suffix5', 'suffix5'), + (6, 'prefix6__^^_%%%__infix6_%^suffix6%', 'prefix6__^^_%%%__infix6_%^suffix6%'), + (7, '%%%^^^\$prefix7_infix7_suffix7%%%^^^\$', 'prefix7_infix7_suffix7'), + (8, 'prefix8_^^%%%infix8%%\$^^___suffix8', ''), + (9, 'prefix9\$%%%^^__infix9__&&%%\$suffix9', NULL); + """ + + qt_sql1 """ + SELECT * FROM `test_like_predicate_with_concat` WHERE `value_col` LIKE 'prefix_%' ORDER BY `id`; + """ + + qt_sql2 """ + SELECT * FROM `test_like_predicate_with_concat` WHERE `value_col` LIKE '%suffix_' ORDER BY `id`; + """ + + qt_sql3 """ + SELECT * FROM `test_like_predicate_with_concat` WHERE `value_col` LIKE CONCAT('%', '%') ORDER BY `id`; + """ + + qt_sql4 """ + SELECT * FROM `test_like_predicate_with_concat` WHERE `value_col` LIKE CONCAT(pattern_col) ORDER BY `id`; + """ + + qt_sql5 """ + SELECT * FROM `test_like_predicate_with_concat` WHERE `value_col` LIKE CONCAT('%', pattern_col, '%') ORDER BY `id`; + """ + + qt_sql6 """ + SELECT * FROM `test_like_predicate_with_concat` WHERE `value_col` LIKE CONCAT(pattern_col, '%') ORDER BY `id`; + """ + + qt_sql7 """ + SELECT * FROM `test_like_predicate_with_concat` WHERE `value_col` LIKE CONCAT('%', pattern_col) ORDER BY `id`; + """ + + qt_sql8 """ + SELECT * FROM `test_like_predicate_with_concat` WHERE `value_col` LIKE CONCAT('prefix0_', 'infix0', '_suffix0') ORDER BY `id`; + """ + + qt_sql9 """ + SELECT * FROM `test_like_predicate_with_concat` WHERE `value_col` REGEXP '^prefix' ORDER BY `id`; + """ + + qt_sql10 """ + SELECT * FROM `test_like_predicate_with_concat` WHERE `value_col` REGEXP '.*suffix.\$' ORDER BY `id`; + """ + + // TODO: fix bug in master branch + // qt_sql11 """ + // SELECT * FROM `test_like_predicate_with_concat` WHERE `value_col` REGEXP '.*' ORDER BY `id`; + // """ + + // TODO: fix bug in master branch + // qt_sql12 """ + // SELECT * FROM `test_like_predicate_with_concat` WHERE `value_col` REGEXP CONCAT('.', '*') ORDER BY `id`; + // """ + + qt_sql13 """ + SELECT * FROM `test_like_predicate_with_concat` WHERE `value_col` REGEXP CONCAT('.*', pattern_col, '.*') ORDER BY `id`; + """ + + qt_sql14 """ + SELECT * FROM `test_like_predicate_with_concat` WHERE `value_col` REGEXP CONCAT('^', pattern_col, '.*') ORDER BY `id`; + """ + + qt_sql15 """ + SELECT * FROM `test_like_predicate_with_concat` WHERE `value_col` REGEXP CONCAT(pattern_col, '\$') ORDER BY `id`; + """ + + qt_sql16 """ + SELECT * FROM `test_like_predicate_with_concat` WHERE `value_col` REGEXP CONCAT('prefix0_', 'infix0', '_suffix0') ORDER BY `id`; + """ +} diff --git a/regression-test/suites/external_table_p0/paimon/test_paimon_catalog.groovy b/regression-test/suites/external_table_p0/paimon/test_paimon_catalog.groovy index ad7f04ee40b7faa..e0be9e581a45f3b 100644 --- a/regression-test/suites/external_table_p0/paimon/test_paimon_catalog.groovy +++ b/regression-test/suites/external_table_p0/paimon/test_paimon_catalog.groovy @@ -173,7 +173,7 @@ suite("test_paimon_catalog", "p0,external,doris,external_docker,external_docker_ def c100= """select * from array_nested order by c1;""" String hdfs_port = context.config.otherConfigs.get("hdfs_port") - String catalog_name = "paimon1" + String catalog_name = "ctl_test_paimon_catalog" String externalEnvIp = context.config.otherConfigs.get("externalEnvIp") sql """drop catalog if exists ${catalog_name}""" diff --git a/regression-test/suites/external_table_p0/paimon/test_paimon_statistics.groovy b/regression-test/suites/external_table_p0/paimon/test_paimon_statistics.groovy index c75e7b797d9381d..6457a1ab3f47d62 100644 --- a/regression-test/suites/external_table_p0/paimon/test_paimon_statistics.groovy +++ b/regression-test/suites/external_table_p0/paimon/test_paimon_statistics.groovy @@ -20,7 +20,7 @@ suite("test_paimon_statistics", "p0,external,doris,external_docker,external_dock if (enabled != null && enabled.equalsIgnoreCase("true")) { try { String hdfs_port = context.config.otherConfigs.get("hdfs_port") - String catalog_name = "paimon1" + String catalog_name = "ctl_test_paimon_statistics" String externalEnvIp = context.config.otherConfigs.get("externalEnvIp") sql """drop catalog if exists ${catalog_name}""" diff --git a/regression-test/suites/external_table_p0/paimon/test_paimon_table_stats.groovy b/regression-test/suites/external_table_p0/paimon/test_paimon_table_stats.groovy index 006969bba45c882..2a4acf32b34fb19 100644 --- a/regression-test/suites/external_table_p0/paimon/test_paimon_table_stats.groovy +++ b/regression-test/suites/external_table_p0/paimon/test_paimon_table_stats.groovy @@ -20,7 +20,7 @@ suite("test_paimon_table_stats", "p0,external,doris,external_docker,external_doc if (enabled != null && enabled.equalsIgnoreCase("true")) { try { String hdfs_port = context.config.otherConfigs.get("hdfs_port") - String catalog_name = "paimon1" + String catalog_name = "ctl_test_paimon_table_stats" String externalEnvIp = context.config.otherConfigs.get("externalEnvIp") sql """drop catalog if exists ${catalog_name}""" diff --git a/regression-test/suites/insert_p0/prepare_insert.groovy b/regression-test/suites/insert_p0/prepare_insert.groovy index 85e94791d4f05ac..305758170d7a305 100644 --- a/regression-test/suites/insert_p0/prepare_insert.groovy +++ b/regression-test/suites/insert_p0/prepare_insert.groovy @@ -46,6 +46,28 @@ suite("prepare_insert") { ); """ + // Parse url + String url = getServerPrepareJdbcUrl(context.config.jdbcUrl, realDb) + + def check_is_master_fe = { + // check if executed on master fe + // observer fe will forward the insert statements to master and forward does not support prepare statement + def fes = sql_return_maparray "show frontends" + logger.info("frontends: ${fes}") + def is_master_fe = true + for (def fe : fes) { + if (url.contains(fe.Host + ":")) { + if (fe.IsMaster == "false") { + is_master_fe = false + } + break + } + } + logger.info("is master fe: ${is_master_fe}") + return is_master_fe + } + def is_master_fe = check_is_master_fe() + def getServerInfo = { stmt -> def serverInfo = (((StatementImpl) stmt).results).getServerInfo() logger.info("server info: " + serverInfo) @@ -53,6 +75,9 @@ suite("prepare_insert") { } def getStmtId = { stmt -> + if (!is_master_fe) { + return 0 + } ConnectionImpl connection = (ConnectionImpl) stmt.getConnection() Field field = ConnectionImpl.class.getDeclaredField("openStatements") field.setAccessible(true) @@ -69,12 +94,16 @@ suite("prepare_insert") { return serverStatementIds } - // Parse url - String url = getServerPrepareJdbcUrl(context.config.jdbcUrl, realDb) + def check = { Closure c -> { + if (is_master_fe) { + c() + } + } + } def result1 = connect(user = user, password = password, url = url) { def stmt = prepareStatement "insert into ${tableName} values(?, ?, ?)" - assertEquals(com.mysql.cj.jdbc.ServerPreparedStatement, stmt.class) + check {assertEquals(com.mysql.cj.jdbc.ServerPreparedStatement, stmt.class)} stmt.setInt(1, 1) stmt.setString(2, "a") stmt.setInt(3, 90) @@ -130,7 +159,7 @@ suite("prepare_insert") { url += "&rewriteBatchedStatements=true" result1 = connect(user = user, password = password, url = url) { def stmt = prepareStatement "insert into ${tableName} values(?, ?, ?)" - assertEquals(com.mysql.cj.jdbc.ServerPreparedStatement, stmt.class) + check {assertEquals(com.mysql.cj.jdbc.ServerPreparedStatement, stmt.class)} stmt.setInt(1, 10) stmt.setString(2, "a") stmt.setInt(3, 90) @@ -170,7 +199,7 @@ suite("prepare_insert") { url += "&cachePrepStmts=true" result1 = connect(user = user, password = password, url = url) { def stmt = prepareStatement "insert into ${tableName} values(?, ?, ?)" - assertEquals(com.mysql.cj.jdbc.ServerPreparedStatement, stmt.class) + check {assertEquals(com.mysql.cj.jdbc.ServerPreparedStatement, stmt.class)} stmt.setInt(1, 10) stmt.setString(2, "a") stmt.setInt(3, 90) @@ -203,7 +232,7 @@ suite("prepare_insert") { assertEquals(result[1], -2) getServerInfo(stmt) def stmtId2 = getStmtId(stmt) - assertEquals(2, stmtId2.size()) + check {assertEquals(2, stmtId2.size())} stmt.close() } diff --git a/regression-test/suites/insert_p2/test_group_commit_http_stream_lineitem_schema_change.groovy b/regression-test/suites/insert_p2/test_group_commit_http_stream_lineitem_schema_change.groovy index 7d43f0c91e74e42..e813f378bcd67df 100644 --- a/regression-test/suites/insert_p2/test_group_commit_http_stream_lineitem_schema_change.groovy +++ b/regression-test/suites/insert_p2/test_group_commit_http_stream_lineitem_schema_change.groovy @@ -255,6 +255,7 @@ l_comment) select c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c14, c15, c for (int i = 1; i <= 10; i++) { logger.info("process file:" + i) if (i == 5) { + getRowCount(total, table_name) def retry = 0 while (retry < 10) { try { diff --git a/regression-test/suites/insert_p2/test_group_commit_insert_into_lineitem_normal.groovy b/regression-test/suites/insert_p2/test_group_commit_insert_into_lineitem_normal.groovy index a47784e7d517e90..f0714ba7f39ef47 100644 --- a/regression-test/suites/insert_p2/test_group_commit_insert_into_lineitem_normal.groovy +++ b/regression-test/suites/insert_p2/test_group_commit_insert_into_lineitem_normal.groovy @@ -111,6 +111,10 @@ PROPERTIES ( break } catch (Exception e) { logger.info("got exception:" + e) + Thread.sleep(5000) + context.reconnectFe() + sql """ set group_commit = async_mode; """ + sql """ set enable_nereids_dml = false; """ } i++; if (i >= 30) { diff --git a/regression-test/suites/insert_p2/test_group_commit_insert_into_lineitem_scheme_change.groovy b/regression-test/suites/insert_p2/test_group_commit_insert_into_lineitem_scheme_change.groovy index 1c77dcbeb5b028a..f95197ce76d37f2 100644 --- a/regression-test/suites/insert_p2/test_group_commit_insert_into_lineitem_scheme_change.groovy +++ b/regression-test/suites/insert_p2/test_group_commit_insert_into_lineitem_scheme_change.groovy @@ -313,6 +313,7 @@ PROPERTIES ( String fileName = file_array[i] logger.info("process file:" + fileName) if (i == (int) (file_array.length / 2)) { + getRowCount(total, table_name) def retry = 0 while (retry < 10) { try { diff --git a/regression-test/suites/insert_p2/test_group_commit_stream_load_lineitem_schema_change.groovy b/regression-test/suites/insert_p2/test_group_commit_stream_load_lineitem_schema_change.groovy index a3e362ea321dcf1..2c30476b732f294 100644 --- a/regression-test/suites/insert_p2/test_group_commit_stream_load_lineitem_schema_change.groovy +++ b/regression-test/suites/insert_p2/test_group_commit_stream_load_lineitem_schema_change.groovy @@ -231,6 +231,7 @@ PROPERTIES ( for (int i = 1; i <= 10; i++) { logger.info("process file:" + i) if (i == 5) { + getRowCount(total, table_name) def retry = 0 while (retry < 10) { try { diff --git a/regression-test/suites/load_p0/routine_load/test_routine_load_error.groovy b/regression-test/suites/load_p0/routine_load/test_routine_load_error.groovy index 5b42e84be000788..825752941d5b91b 100644 --- a/regression-test/suites/load_p0/routine_load/test_routine_load_error.groovy +++ b/regression-test/suites/load_p0/routine_load/test_routine_load_error.groovy @@ -97,7 +97,7 @@ suite("test_routine_load_error","p0") { continue; } log.info("reason of state changed: ${res[0][17].toString()}".toString()) - assertEquals(res[0][17].toString(), "ErrorReason{code=errCode = 100, msg='failed to get stream load plan, errCode = 7, detailMessage = table not found, table name is routine_load_invalid_table'}") + assertTrue(res[0][17].toString().contains("table not found")) break; } } finally { diff --git a/regression-test/suites/nereids_tpch_p0/tpch/topn-filter.groovy b/regression-test/suites/nereids_tpch_p0/tpch/topn-filter.groovy index 23e742fba158bd5..14733d1303f8355 100644 --- a/regression-test/suites/nereids_tpch_p0/tpch/topn-filter.groovy +++ b/regression-test/suites/nereids_tpch_p0/tpch/topn-filter.groovy @@ -117,4 +117,7 @@ suite("topn-filter") { qt_groupingsets "select n_regionkey, sum(n_nationkey) from nation group by grouping sets((n_regionkey)) order by n_regionkey limit 2;" + sql "set enable_pipeline_engine=false;" + sql "set enable_pipeline_x_engine=false;" + qt_groupingsets2 "select n_regionkey, sum(n_nationkey) from nation group by grouping sets((n_regionkey)) order by n_regionkey limit 2;" } \ No newline at end of file diff --git a/regression-test/suites/query_p0/aggregate/array_agg.groovy b/regression-test/suites/query_p0/aggregate/array_agg.groovy index ee4fcb9d455ad0d..1484125d0da6cc4 100644 --- a/regression-test/suites/query_p0/aggregate/array_agg.groovy +++ b/regression-test/suites/query_p0/aggregate/array_agg.groovy @@ -17,6 +17,7 @@ suite("array_agg") { sql "DROP TABLE IF EXISTS `test_array_agg`;" + sql "DROP TABLE IF EXISTS `test_array_agg1`;" sql "DROP TABLE IF EXISTS `test_array_agg_int`;" sql "DROP TABLE IF EXISTS `test_array_agg_decimal`;" sql """ @@ -157,39 +158,100 @@ suite("array_agg") { (8, "", NULL,0,NULL,"alexcoco2"); """ - qt_sql1 """ - SELECT array_agg(`label_name`) FROM `test_array_agg` GROUP BY `id` order by id; + order_qt_sql1 """ + SELECT count(id), array_agg(`label_name`) FROM `test_array_agg` GROUP BY `id` order by id; """ - qt_sql2 """ - SELECT array_agg(label_name) FROM `test_array_agg` GROUP BY value_field order by value_field; + order_qt_sql2 """ + SELECT count(value_field), array_agg(label_name) FROM `test_array_agg` GROUP BY value_field order by value_field; """ - qt_sql3 """ + order_qt_sql3 """ SELECT array_agg(`label_name`) FROM `test_array_agg`; """ - qt_sql4 """ + order_qt_sql4 """ SELECT array_agg(`value_field`) FROM `test_array_agg`; """ - qt_sql5 """ + order_qt_sql5 """ SELECT id, array_agg(age) FROM test_array_agg_int GROUP BY id order by id; """ - qt_sql6 """ + order_qt_sql6 """ select array_agg(label_name) from test_array_agg_decimal where id=7; """ - qt_sql7 """ + order_qt_sql6_1 """ + select sum(o_totalprice), array_agg(label_name) from test_array_agg_decimal where id=7; + """ + + order_qt_sql7 """ select array_agg(label_name) from test_array_agg_decimal group by id order by id; """ - qt_sql8 """ + order_qt_sql8 """ select array_agg(age) from test_array_agg_decimal where id=7; """ - qt_sql9 """ + order_qt_sql9 """ select id,array_agg(o_totalprice) from test_array_agg_decimal group by id order by id; """ + + // test for bucket 10 + sql """ CREATE TABLE `test_array_agg1` ( + `id` int(11) NOT NULL, + `label_name` varchar(32) default null, + `value_field` string default null + ) ENGINE=OLAP + DUPLICATE KEY(`id`) + COMMENT 'OLAP' + DISTRIBUTED BY HASH(`id`) BUCKETS 10 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1", + "storage_format" = "V2", + "light_schema_change" = "true", + "disable_auto_compaction" = "false", + "enable_single_replica_compaction" = "false" + ); """ + + sql """ + insert into `test_array_agg1` values + (1, "alex",NULL), + (1, "LB", "V1_2"), + (1, "LC", "V1_3"), + (2, "LA", "V2_1"), + (2, "LB", "V2_2"), + (2, "LC", "V2_3"), + (3, "LA", "V3_1"), + (3, NULL, NULL), + (3, "LC", "V3_3"), + (4, "LA", "V4_1"), + (4, "LB", "V4_2"), + (4, "LC", "V4_3"), + (5, "LA", "V5_1"), + (5, "LB", "V5_2"), + (5, "LC", "V5_3"), + (5, NULL, "V5_3"), + (6, "LC", "V6_3"), + (6, "LC", NULL), + (6, "LC", "V6_3"), + (6, "LC", NULL), + (6, NULL, "V6_3"), + (7, "LC", "V7_3"), + (7, "LC", NULL), + (7, "LC", "V7_3"), + (7, "LC", NULL), + (7, NULL, "V7_3"); + """ + + order_qt_sql11 """ + SELECT count(id), size(array_agg(`label_name`)) FROM `test_array_agg` GROUP BY `id` order by id; + """ + order_qt_sql21 """ + SELECT count(value_field), size(array_agg(label_name)) FROM `test_array_agg` GROUP BY value_field order by value_field; + """ + + sql "DROP TABLE `test_array_agg`" + sql "DROP TABLE `test_array_agg1`" sql "DROP TABLE `test_array_agg_int`" sql "DROP TABLE `test_array_agg_decimal`" } diff --git a/regression-test/suites/query_p0/sql_functions/string_functions/test_string_function_regexp.groovy b/regression-test/suites/query_p0/sql_functions/string_functions/test_string_function_regexp.groovy index d25c995ea488b86..5926492ac4d6aac 100644 --- a/regression-test/suites/query_p0/sql_functions/string_functions/test_string_function_regexp.groovy +++ b/regression-test/suites/query_p0/sql_functions/string_functions/test_string_function_regexp.groovy @@ -154,5 +154,4 @@ suite("test_string_function_regexp") { qt_sql_field4 "SELECT FIELD('21','2130', '2131', '21');" qt_sql_field5 "SELECT FIELD(21, 2130, 21, 2131);" -} - +} \ No newline at end of file diff --git a/regression-test/suites/variant_github_events_p0/load.groovy b/regression-test/suites/variant_github_events_p0/load.groovy index ec1272cfb32cd41..35c05af8a9eb081 100644 --- a/regression-test/suites/variant_github_events_p0/load.groovy +++ b/regression-test/suites/variant_github_events_p0/load.groovy @@ -59,7 +59,7 @@ suite("regression_test_variant_github_events_p0", "nonConcurrent"){ sql """ CREATE TABLE IF NOT EXISTS ${table_name} ( k bigint, - v variant, + v variant not null, INDEX idx_var(v) USING INVERTED PROPERTIES("parser" = "english") COMMENT '' ) DUPLICATE KEY(`k`) @@ -79,5 +79,6 @@ suite("regression_test_variant_github_events_p0", "nonConcurrent"){ load_json_data.call(table_name, """${getS3Url() + '/regression/gharchive.m/2022-11-07-23.json'}""") // TODO fix compaction issue, this case could be stable qt_sql """select cast(v["payload"]["pull_request"]["additions"] as int) from github_events where cast(v["repo"]["name"] as string) = 'xpressengine/xe-core' order by 1;""" + qt_sql """select * from github_events where cast(v["repo"]["name"] as string) = 'xpressengine/xe-core' limit 10""" // TODO add test case that some certain columns are materialized in some file while others are not materilized(sparse) } \ No newline at end of file