From bfaf1b684a3c8649d74f9a5e38935dc2c1266d18 Mon Sep 17 00:00:00 2001 From: pengxianyu Date: Thu, 22 Oct 2020 15:27:17 +0800 Subject: [PATCH 1/5] Error happened when open a view in DBeaver --- .../schema_scanner/schema_views_scanner.cpp | 288 ++++++++++++++++++ .../schema_scanner/schema_views_scanner.h | 47 +++ 2 files changed, 335 insertions(+) create mode 100644 be/src/exec/schema_scanner/schema_views_scanner.cpp create mode 100644 be/src/exec/schema_scanner/schema_views_scanner.h diff --git a/be/src/exec/schema_scanner/schema_views_scanner.cpp b/be/src/exec/schema_scanner/schema_views_scanner.cpp new file mode 100644 index 00000000000000..95fb9c6944797e --- /dev/null +++ b/be/src/exec/schema_scanner/schema_views_scanner.cpp @@ -0,0 +1,288 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +#include "exec/schema_scanner/schema_helper.h" +#include "exec/schema_scanner/schema_views_scanner.h" +#include "runtime/primitive_type.h" +#include "runtime/string_value.h" +//#include "runtime/datetime_value.h" + +namespace doris +{ + +SchemaScanner::ColumnDesc SchemaViewsScanner::_s_tbls_columns[] = { + // name, type, size, is_null + { "TABLE_CATALOG", TYPE_VARCHAR, sizeof(StringValue), true}, + { "TABLE_SCHEMA", TYPE_VARCHAR, sizeof(StringValue), false}, + { "TABLE_NAME", TYPE_VARCHAR, sizeof(StringValue), false}, + { "TABLE_TYPE", TYPE_VARCHAR, sizeof(StringValue), false}, + { "ENGINE", TYPE_VARCHAR, sizeof(StringValue), true}, + { "VERSION", TYPE_BIGINT, sizeof(int64_t), true}, + { "ROW_FORMAT", TYPE_VARCHAR, sizeof(StringValue), true}, + { "TABLE_ROWS", TYPE_BIGINT, sizeof(int64_t), true}, + { "AVG_ROW_LENGTH", TYPE_BIGINT, sizeof(int64_t), true}, + { "DATA_LENGTH", TYPE_BIGINT, sizeof(int64_t), true}, + { "MAX_DATA_LENGTH", TYPE_BIGINT, sizeof(int64_t), true}, + { "INDEX_LENGTH", TYPE_BIGINT, sizeof(int64_t), true}, + { "DATA_FREE", TYPE_BIGINT, sizeof(int64_t), true}, + { "AUTO_INCREMENT", TYPE_BIGINT, sizeof(int64_t), true}, + { "CREATE_TIME", TYPE_DATETIME, sizeof(DateTimeValue), true}, + { "UPDATE_TIME", TYPE_DATETIME, sizeof(DateTimeValue), true}, + { "CHECK_TIME", TYPE_DATETIME, sizeof(DateTimeValue), true}, + { "TABLE_COLLATION", TYPE_VARCHAR, sizeof(StringValue), true}, + { "CHECKSUM", TYPE_BIGINT, sizeof(int64_t), true}, + { "CREATE_OPTIONS", TYPE_VARCHAR, sizeof(StringValue), true}, + { "TABLE_COMMENT", TYPE_VARCHAR, sizeof(StringValue), false}, +}; + +SchemaViewsScanner::SchemaViewsScanner() + : SchemaScanner(_s_tbls_columns, + sizeof(_s_tbls_columns) / sizeof(SchemaScanner::ColumnDesc)), + _db_index(0), + _table_index(0) { +} + +SchemaViewsScanner::~SchemaViewsScanner() { +} + +Status SchemaViewsScanner::start(RuntimeState *state) { + if (!_is_init) { + return Status::InternalError("used before initialized."); + } + TGetDbsParams db_params; + if (NULL != _param->db) { + db_params.__set_pattern(*(_param->db)); + } + if (NULL != _param->current_user_ident) { + db_params.__set_current_user_ident(*(_param->current_user_ident)); + } else { + if (NULL != _param->user) { + db_params.__set_user(*(_param->user)); + } + if (NULL != _param->user_ip) { + db_params.__set_user_ip(*(_param->user_ip)); + } + } + + if (NULL != _param->ip && 0 != _param->port) { + RETURN_IF_ERROR(SchemaHelper::get_db_names(*(_param->ip), + _param->port, db_params, &_db_result)); + } else { + return Status::InternalError("IP or port doesn't exists"); + } + return Status::OK(); +} + +Status SchemaViewsScanner::fill_one_row(Tuple *tuple, MemPool *pool) { + // set all bit to not null + memset((void *)tuple, 0, _tuple_desc->num_null_bytes()); + const TTableStatus& tbl_status = _table_result.tables[_table_index]; + // catalog + { + tuple->set_null(_tuple_desc->slots()[0]->null_indicator_offset()); + } + // schema + { + void *slot = tuple->get_slot(_tuple_desc->slots()[1]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + std::string db_name = SchemaHelper::extract_db_name(_db_result.dbs[_db_index - 1]); + str_slot->ptr = (char *)pool->allocate(db_name.size()); + str_slot->len = db_name.size(); + memcpy(str_slot->ptr, db_name.c_str(), str_slot->len); + } + // name + { + void *slot = tuple->get_slot(_tuple_desc->slots()[2]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + const std::string* src = &tbl_status.name; + str_slot->len = src->length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, src->c_str(), str_slot->len); + } + // type + { + void *slot = tuple->get_slot(_tuple_desc->slots()[3]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + const std::string* src = &tbl_status.type; + str_slot->len = src->length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, src->c_str(), str_slot->len); + } + // engine + if (tbl_status.__isset.engine) { + void *slot = tuple->get_slot(_tuple_desc->slots()[4]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + const std::string* src = &tbl_status.engine; + str_slot->len = src->length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, src->c_str(), str_slot->len); + } else { + tuple->set_null(_tuple_desc->slots()[4]->null_indicator_offset()); + } + // version + { + tuple->set_null(_tuple_desc->slots()[5]->null_indicator_offset()); + } + // row_format + { + tuple->set_null(_tuple_desc->slots()[6]->null_indicator_offset()); + } + // rows + { + tuple->set_null(_tuple_desc->slots()[7]->null_indicator_offset()); + } + // avg_row_length + { + tuple->set_null(_tuple_desc->slots()[8]->null_indicator_offset()); + } + // data_length + { + tuple->set_null(_tuple_desc->slots()[9]->null_indicator_offset()); + } + // max_data_length + { + tuple->set_null(_tuple_desc->slots()[10]->null_indicator_offset()); + } + // index_length + { + tuple->set_null(_tuple_desc->slots()[11]->null_indicator_offset()); + } + // data_free + { + tuple->set_null(_tuple_desc->slots()[12]->null_indicator_offset()); + } + // auto_increment + { + tuple->set_null(_tuple_desc->slots()[13]->null_indicator_offset()); + } + // creation_time + if (tbl_status.__isset.create_time) { + int64_t create_time = tbl_status.create_time; + if (create_time <= 0) { + tuple->set_null(_tuple_desc->slots()[14]->null_indicator_offset()); + } else { + tuple->set_not_null(_tuple_desc->slots()[14]->null_indicator_offset()); + void *slot = tuple->get_slot(_tuple_desc->slots()[14]->tuple_offset()); + DateTimeValue *time_slot = reinterpret_cast(slot); + time_slot->from_unixtime(create_time, TimezoneUtils::default_time_zone); + } + + } + // update_time + { + tuple->set_null(_tuple_desc->slots()[15]->null_indicator_offset()); + } + // check_time + if (tbl_status.__isset.last_check_time) { + int64_t check_time = tbl_status.last_check_time; + if (check_time <= 0) { + tuple->set_null(_tuple_desc->slots()[16]->null_indicator_offset()); + } else { + tuple->set_not_null(_tuple_desc->slots()[16]->null_indicator_offset()); + void *slot = tuple->get_slot(_tuple_desc->slots()[16]->tuple_offset()); + DateTimeValue *time_slot = reinterpret_cast(slot); + time_slot->from_unixtime(check_time, TimezoneUtils::default_time_zone); + } + } + // collation + { + tuple->set_null(_tuple_desc->slots()[17]->null_indicator_offset()); + } + // checksum + { + tuple->set_null(_tuple_desc->slots()[18]->null_indicator_offset()); + } + // create_options + { + tuple->set_null(_tuple_desc->slots()[19]->null_indicator_offset()); + } + // create_comment + { + void *slot = tuple->get_slot(_tuple_desc->slots()[20]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + const std::string* src = &tbl_status.comment; + str_slot->len = src->length(); + if (str_slot->len == 0) { + str_slot->ptr = nullptr; + } else { + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, src->c_str(), str_slot->len); + } + } + _table_index++; + return Status::OK(); +} + +Status SchemaViewsScanner::get_new_table() { + TGetTablesParams table_params; + table_params.__set_db(_db_result.dbs[_db_index++]); + if (NULL != _param->wild) { + table_params.__set_pattern(*(_param->wild)); + } + if (NULL != _param->current_user_ident) { + table_params.__set_current_user_ident(*(_param->current_user_ident)); + } else { + if (NULL != _param->user) { + table_params.__set_user(*(_param->user)); + } + if (NULL != _param->user_ip) { + table_params.__set_user_ip(*(_param->user_ip)); + } + } + + if (NULL != _param->ip && 0 != _param->port) { + RETURN_IF_ERROR(SchemaHelper::list_table_status(*(_param->ip), + _param->port, table_params, &_table_result)); + } else { + return Status::InternalError("IP or port doesn't exists"); + } + _table_index = 0; + return Status::OK(); +} + +Status SchemaViewsScanner::get_next_row(Tuple *tuple, MemPool *pool, bool *eos) { + if (!_is_init) { + return Status::InternalError("Used before initialized."); + } + if (NULL == tuple || NULL == pool || NULL == eos) { + return Status::InternalError("input pointer is NULL."); + } + while (_table_index >= _table_result.tables.size()) { + if (_db_index < _db_result.dbs.size()) { + RETURN_IF_ERROR(get_new_table()); + } else { + *eos = true; + return Status::OK(); + } + } + *eos = false; + return fill_one_row(tuple, pool); +} + +} diff --git a/be/src/exec/schema_scanner/schema_views_scanner.h b/be/src/exec/schema_scanner/schema_views_scanner.h new file mode 100644 index 00000000000000..e674d5227a53a1 --- /dev/null +++ b/be/src/exec/schema_scanner/schema_views_scanner.h @@ -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. + +#ifndef DORIS_BE_SRC_QUERY_EXEC_SCHEMA_SCANNER_SCHEMA_VIEWS_SCANNER_H +#define DORIS_BE_SRC_QUERY_EXEC_SCHEMA_SCANNER_SCHEMA_VIEWS_SCANNER_H + +#include "exec/schema_scanner.h" +#include "gen_cpp/FrontendService_types.h" + +namespace doris { + +class SchemaViewsScanner : public SchemaScanner { +public: + SchemaViewsScanner(); + virtual ~SchemaViewsScanner(); + + virtual Status start(RuntimeState *state); + virtual Status get_next_row(Tuple *tuple, MemPool *pool, bool *eos); + +private: + Status get_new_table(); + Status fill_one_row(Tuple *tuple, MemPool *pool); + + int _db_index; + int _table_index; + TGetDbsResult _db_result; + TListTableStatusResult _table_result; + static SchemaScanner::ColumnDesc _s_tbls_columns[]; +}; + +} + +#endif From bff46c5e55d6117b1e4c27a3abd74d3d42548a3c Mon Sep 17 00:00:00 2001 From: pengxianyu Date: Thu, 22 Oct 2020 16:00:10 +0800 Subject: [PATCH 2/5] Fix bug: Error happened when open a view in DBeaver --- be/src/exec/CMakeLists.txt | 1 + be/src/exec/schema_scanner.cpp | 3 + .../schema_scanner/schema_views_scanner.cpp | 159 ++++++------------ .../org/apache/doris/catalog/Database.java | 10 ++ .../org/apache/doris/catalog/SchemaTable.java | 17 ++ .../java/org/apache/doris/catalog/Table.java | 6 + .../java/org/apache/doris/catalog/View.java | 5 + .../doris/service/FrontendServiceImpl.java | 15 +- gensrc/thrift/FrontendService.thrift | 2 + 9 files changed, 107 insertions(+), 111 deletions(-) diff --git a/be/src/exec/CMakeLists.txt b/be/src/exec/CMakeLists.txt index 916b3d5ce72392..044f82d507c370 100644 --- a/be/src/exec/CMakeLists.txt +++ b/be/src/exec/CMakeLists.txt @@ -84,6 +84,7 @@ set(EXEC_FILES schema_scanner/schema_charsets_scanner.cpp schema_scanner/schema_collations_scanner.cpp schema_scanner/schema_helper.cpp + schema_scanner/schema_views_scanner.cpp partitioned_hash_table.cc partitioned_hash_table_ir.cc partitioned_aggregation_node.cc diff --git a/be/src/exec/schema_scanner.cpp b/be/src/exec/schema_scanner.cpp index c2b99da6b13c8f..4c25f9c0c0dfbd 100644 --- a/be/src/exec/schema_scanner.cpp +++ b/be/src/exec/schema_scanner.cpp @@ -23,6 +23,7 @@ #include "exec/schema_scanner/schema_variables_scanner.h" #include "exec/schema_scanner/schema_charsets_scanner.h" #include "exec/schema_scanner/schema_collations_scanner.h" +#include "exec/schema_scanner/schema_views_scanner.h" namespace doris { @@ -93,6 +94,8 @@ SchemaScanner* SchemaScanner::create(TSchemaTableType::type type) { case TSchemaTableType::SCH_SESSION_VARIABLES: case TSchemaTableType::SCH_VARIABLES: return new(std::nothrow) SchemaVariablesScanner(TVarType::SESSION); + case TSchemaTableType::SCH_VIEWS: + return new(std::nothrow) SchemaViewsScanner(); default: return new(std::nothrow) SchemaDummyScanner(); break; diff --git a/be/src/exec/schema_scanner/schema_views_scanner.cpp b/be/src/exec/schema_scanner/schema_views_scanner.cpp index 95fb9c6944797e..f96a10121bd547 100644 --- a/be/src/exec/schema_scanner/schema_views_scanner.cpp +++ b/be/src/exec/schema_scanner/schema_views_scanner.cpp @@ -29,24 +29,13 @@ SchemaScanner::ColumnDesc SchemaViewsScanner::_s_tbls_columns[] = { { "TABLE_CATALOG", TYPE_VARCHAR, sizeof(StringValue), true}, { "TABLE_SCHEMA", TYPE_VARCHAR, sizeof(StringValue), false}, { "TABLE_NAME", TYPE_VARCHAR, sizeof(StringValue), false}, - { "TABLE_TYPE", TYPE_VARCHAR, sizeof(StringValue), false}, - { "ENGINE", TYPE_VARCHAR, sizeof(StringValue), true}, - { "VERSION", TYPE_BIGINT, sizeof(int64_t), true}, - { "ROW_FORMAT", TYPE_VARCHAR, sizeof(StringValue), true}, - { "TABLE_ROWS", TYPE_BIGINT, sizeof(int64_t), true}, - { "AVG_ROW_LENGTH", TYPE_BIGINT, sizeof(int64_t), true}, - { "DATA_LENGTH", TYPE_BIGINT, sizeof(int64_t), true}, - { "MAX_DATA_LENGTH", TYPE_BIGINT, sizeof(int64_t), true}, - { "INDEX_LENGTH", TYPE_BIGINT, sizeof(int64_t), true}, - { "DATA_FREE", TYPE_BIGINT, sizeof(int64_t), true}, - { "AUTO_INCREMENT", TYPE_BIGINT, sizeof(int64_t), true}, - { "CREATE_TIME", TYPE_DATETIME, sizeof(DateTimeValue), true}, - { "UPDATE_TIME", TYPE_DATETIME, sizeof(DateTimeValue), true}, - { "CHECK_TIME", TYPE_DATETIME, sizeof(DateTimeValue), true}, - { "TABLE_COLLATION", TYPE_VARCHAR, sizeof(StringValue), true}, - { "CHECKSUM", TYPE_BIGINT, sizeof(int64_t), true}, - { "CREATE_OPTIONS", TYPE_VARCHAR, sizeof(StringValue), true}, - { "TABLE_COMMENT", TYPE_VARCHAR, sizeof(StringValue), false}, + { "VIEW_DEFINITION", TYPE_VARCHAR, sizeof(StringValue), true}, + { "CHECK_OPTION", TYPE_VARCHAR, sizeof(StringValue), true}, + { "IS_UPDATABLE", TYPE_VARCHAR, sizeof(StringValue), true}, + { "DEFINER", TYPE_VARCHAR, sizeof(StringValue), true}, + { "SECURITY_TYPE", TYPE_VARCHAR, sizeof(StringValue), true}, + { "CHARACTER_SET_CLIENT", TYPE_VARCHAR, sizeof(StringValue), true}, + { "COLLATION_CONNECTION", TYPE_VARCHAR, sizeof(StringValue), true}, }; SchemaViewsScanner::SchemaViewsScanner() @@ -116,124 +105,73 @@ Status SchemaViewsScanner::fill_one_row(Tuple *tuple, MemPool *pool) { } memcpy(str_slot->ptr, src->c_str(), str_slot->len); } - // type + // definition { void *slot = tuple->get_slot(_tuple_desc->slots()[3]->tuple_offset()); StringValue* str_slot = reinterpret_cast(slot); - const std::string* src = &tbl_status.type; - str_slot->len = src->length(); + const std::string* ddl_sql = &tbl_status.ddl_sql; + str_slot->len = ddl_sql->length(); str_slot->ptr = (char *)pool->allocate(str_slot->len); if (NULL == str_slot->ptr) { return Status::InternalError("Allocate memcpy failed."); } - memcpy(str_slot->ptr, src->c_str(), str_slot->len); + memcpy(str_slot->ptr, ddl_sql->c_str(), str_slot->len); } - // engine - if (tbl_status.__isset.engine) { + // check_option + { void *slot = tuple->get_slot(_tuple_desc->slots()[4]->tuple_offset()); StringValue* str_slot = reinterpret_cast(slot); - const std::string* src = &tbl_status.engine; - str_slot->len = src->length(); + const std::string check_option = "NONE"; + str_slot->len = check_option.length(); str_slot->ptr = (char *)pool->allocate(str_slot->len); if (NULL == str_slot->ptr) { return Status::InternalError("Allocate memcpy failed."); } - memcpy(str_slot->ptr, src->c_str(), str_slot->len); - } else { - tuple->set_null(_tuple_desc->slots()[4]->null_indicator_offset()); + memcpy(str_slot->ptr, check_option.c_str(), str_slot->len); } - // version + // is_updatable { - tuple->set_null(_tuple_desc->slots()[5]->null_indicator_offset()); - } - // row_format - { - tuple->set_null(_tuple_desc->slots()[6]->null_indicator_offset()); - } - // rows - { - tuple->set_null(_tuple_desc->slots()[7]->null_indicator_offset()); - } - // avg_row_length - { - tuple->set_null(_tuple_desc->slots()[8]->null_indicator_offset()); - } - // data_length - { - tuple->set_null(_tuple_desc->slots()[9]->null_indicator_offset()); - } - // max_data_length - { - tuple->set_null(_tuple_desc->slots()[10]->null_indicator_offset()); - } - // index_length - { - tuple->set_null(_tuple_desc->slots()[11]->null_indicator_offset()); - } - // data_free - { - tuple->set_null(_tuple_desc->slots()[12]->null_indicator_offset()); - } - // auto_increment - { - tuple->set_null(_tuple_desc->slots()[13]->null_indicator_offset()); - } - // creation_time - if (tbl_status.__isset.create_time) { - int64_t create_time = tbl_status.create_time; - if (create_time <= 0) { - tuple->set_null(_tuple_desc->slots()[14]->null_indicator_offset()); - } else { - tuple->set_not_null(_tuple_desc->slots()[14]->null_indicator_offset()); - void *slot = tuple->get_slot(_tuple_desc->slots()[14]->tuple_offset()); - DateTimeValue *time_slot = reinterpret_cast(slot); - time_slot->from_unixtime(create_time, TimezoneUtils::default_time_zone); + void *slot = tuple->get_slot(_tuple_desc->slots()[5]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + const std::string is_updatable = "YES"; + str_slot->len = is_updatable.length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); } - + memcpy(str_slot->ptr, is_updatable.c_str(), str_slot->len); } - // update_time + // definer { - tuple->set_null(_tuple_desc->slots()[15]->null_indicator_offset()); - } - // check_time - if (tbl_status.__isset.last_check_time) { - int64_t check_time = tbl_status.last_check_time; - if (check_time <= 0) { - tuple->set_null(_tuple_desc->slots()[16]->null_indicator_offset()); - } else { - tuple->set_not_null(_tuple_desc->slots()[16]->null_indicator_offset()); - void *slot = tuple->get_slot(_tuple_desc->slots()[16]->tuple_offset()); - DateTimeValue *time_slot = reinterpret_cast(slot); - time_slot->from_unixtime(check_time, TimezoneUtils::default_time_zone); + void *slot = tuple->get_slot(_tuple_desc->slots()[6]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + const std::string definer = "root@%"; + str_slot->len = definer.length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); } + memcpy(str_slot->ptr, definer.c_str(), str_slot->len); } - // collation + // security_type { - tuple->set_null(_tuple_desc->slots()[17]->null_indicator_offset()); - } - // checksum - { - tuple->set_null(_tuple_desc->slots()[18]->null_indicator_offset()); + void *slot = tuple->get_slot(_tuple_desc->slots()[7]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + const std::string security_type = "DEFINER"; + str_slot->len = security_type.length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, security_type.c_str(), str_slot->len); } - // create_options + // character_set_client { - tuple->set_null(_tuple_desc->slots()[19]->null_indicator_offset()); + tuple->set_null(_tuple_desc->slots()[8]->null_indicator_offset()); } - // create_comment + // collation_connection { - void *slot = tuple->get_slot(_tuple_desc->slots()[20]->tuple_offset()); - StringValue* str_slot = reinterpret_cast(slot); - const std::string* src = &tbl_status.comment; - str_slot->len = src->length(); - if (str_slot->len == 0) { - str_slot->ptr = nullptr; - } else { - str_slot->ptr = (char *)pool->allocate(str_slot->len); - if (NULL == str_slot->ptr) { - return Status::InternalError("Allocate memcpy failed."); - } - memcpy(str_slot->ptr, src->c_str(), str_slot->len); - } + tuple->set_null(_tuple_desc->slots()[9]->null_indicator_offset()); } _table_index++; return Status::OK(); @@ -255,6 +193,7 @@ Status SchemaViewsScanner::get_new_table() { table_params.__set_user_ip(*(_param->user_ip)); } } + table_params.__set_type("VIEW"); if (NULL != _param->ip && 0 != _param->port) { RETURN_IF_ERROR(SchemaHelper::list_table_status(*(_param->ip), diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Database.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/Database.java index bf3ed7a551f4e4..8db36e74562b0e 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Database.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Database.java @@ -342,6 +342,16 @@ public List getTables() { return new ArrayList
(idToTable.values()); } + public List
getViews() { + List
views = new ArrayList<>(); + for (Table table : idToTable.values()) { + if (table.getType() == TableType.VIEW) { + views.add(table); + } + } + return views; + } + public Set getTableNamesWithLock() { readLock(); try { diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/SchemaTable.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/SchemaTable.java index a3788e20c28093..0ffe3d11f40479 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/SchemaTable.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/SchemaTable.java @@ -281,6 +281,23 @@ public static Builder builder() { .column("XA", ScalarType.createVarchar(3)) .column("SAVEPOINTS", ScalarType.createVarchar(3)) .build())) + .put("views", + new SchemaTable( + SystemIdGenerator.getNextId(), + "views", + TableType.SCHEMA, + builder() + .column("TABLE_CATALOG", ScalarType.createVarchar(512)) + .column("TABLE_SCHEMA", ScalarType.createVarchar(64)) + .column("TABLE_NAME", ScalarType.createVarchar(64)) + .column("VIEW_DEFINITION", ScalarType.createVarchar(8096)) + .column("CHECK_OPTION", ScalarType.createVarchar(8)) + .column("IS_UPDATABLE", ScalarType.createVarchar(3)) + .column("DEFINER", ScalarType.createVarchar(77)) + .column("SECURITY_TYPE", ScalarType.createVarchar(7)) + .column("CHARACTER_SET_CLIENT", ScalarType.createVarchar(32)) + .column("COLLATION_CONNECTION", ScalarType.createVarchar(32)) + .build())) .build(); public static class Builder { diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Table.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/Table.java index 59c741432e948e..fa2cbc95158814 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Table.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Table.java @@ -95,6 +95,8 @@ public enum TableType { // table(view)'s comment protected String comment = ""; + protected String ddlSql = ""; + public Table(TableType type) { this.type = type; this.fullSchema = Lists.newArrayList(); @@ -145,6 +147,10 @@ public List getFullSchema() { return fullSchema; } + public String getDdlSql() { + return ddlSql; + } + // should override in subclass if necessary public List getBaseSchema() { return getBaseSchema(Util.showHiddenColumns()); diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/View.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/View.java index 24a7c6a6f8e4a1..19f1efd4217cfc 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/View.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/View.java @@ -140,6 +140,11 @@ public String getInlineViewDef() { return inlineViewDef; } + @Override + public String getDdlSql() { + return inlineViewDef; + } + /** * Initializes the originalViewDef, inlineViewDef, and queryStmt members * by parsing the expanded view definition SQL-string. diff --git a/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java b/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java index 0f1a46770980e5..5ff844f3770965 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java +++ b/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java @@ -248,7 +248,19 @@ public TListTableStatusResult listTableStatus(TGetTablesParams params) throws TE if (db != null) { db.readLock(); try { - for (Table table : db.getTables()) { + List
tables = null; + if (!params.isSetType() || params.getType() == null || params.getType().isEmpty()) { + tables = db.getTables(); + } else { + switch (params.getType()) { + case "VIEW": + tables = db.getViews(); + break; + default: + tables = db.getTables(); + } + } + for (Table table : tables) { if (!Catalog.getCurrentCatalog().getAuth().checkTblPriv(currentUser, params.db, table.getName(), PrivPredicate.SHOW)) { continue; @@ -264,6 +276,7 @@ public TListTableStatusResult listTableStatus(TGetTablesParams params) throws TE status.setComment(table.getComment()); status.setCreateTime(table.getCreateTime()); status.setLastCheckTime(table.getLastCheckTime()); + status.setDdlSql(table.getDdlSql()); tablesResult.add(status); } diff --git a/gensrc/thrift/FrontendService.thrift b/gensrc/thrift/FrontendService.thrift index 69dccc5faad00b..71b969c79bb798 100644 --- a/gensrc/thrift/FrontendService.thrift +++ b/gensrc/thrift/FrontendService.thrift @@ -302,6 +302,7 @@ struct TGetTablesParams { 3: optional string user // deprecated 4: optional string user_ip // deprecated 5: optional Types.TUserIdentity current_user_ident // to replace the user and user ip + 6: optional string type } struct TTableStatus { @@ -311,6 +312,7 @@ struct TTableStatus { 4: optional string engine 5: optional i64 last_check_time 6: optional i64 create_time + 7: optional string ddl_sql } struct TListTableStatusResult { From c58f31bfa130c6a9ebb2ca0c85fa85fc2d4174e7 Mon Sep 17 00:00:00 2001 From: pengxianyu Date: Tue, 27 Oct 2020 17:08:43 +0800 Subject: [PATCH 3/5] Fix bug: Error happened when open a view in DBeaver --- fe/fe-core/src/main/java/org/apache/doris/catalog/Table.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Table.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/Table.java index fa2cbc95158814..cda8491d31b04c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Table.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Table.java @@ -94,7 +94,7 @@ public enum TableType { protected boolean isTypeRead = false; // table(view)'s comment protected String comment = ""; - + // sql for creating this table, default is ""; protected String ddlSql = ""; public Table(TableType type) { From 79be4f098fbffb793193aac8246cedd48cff56bf Mon Sep 17 00:00:00 2001 From: pengxianyu Date: Tue, 27 Oct 2020 17:18:41 +0800 Subject: [PATCH 4/5] Fix bug: Error happened when open a view in DBeaver --- be/src/exec/schema_scanner/schema_views_scanner.cpp | 4 ++++ .../src/main/java/org/apache/doris/catalog/SchemaTable.java | 1 + 2 files changed, 5 insertions(+) diff --git a/be/src/exec/schema_scanner/schema_views_scanner.cpp b/be/src/exec/schema_scanner/schema_views_scanner.cpp index f96a10121bd547..68b4707be0e658 100644 --- a/be/src/exec/schema_scanner/schema_views_scanner.cpp +++ b/be/src/exec/schema_scanner/schema_views_scanner.cpp @@ -121,6 +121,7 @@ Status SchemaViewsScanner::fill_one_row(Tuple *tuple, MemPool *pool) { { void *slot = tuple->get_slot(_tuple_desc->slots()[4]->tuple_offset()); StringValue* str_slot = reinterpret_cast(slot); + // This is from views in mysql const std::string check_option = "NONE"; str_slot->len = check_option.length(); str_slot->ptr = (char *)pool->allocate(str_slot->len); @@ -133,6 +134,7 @@ Status SchemaViewsScanner::fill_one_row(Tuple *tuple, MemPool *pool) { { void *slot = tuple->get_slot(_tuple_desc->slots()[5]->tuple_offset()); StringValue* str_slot = reinterpret_cast(slot); + // This is from views in mysql const std::string is_updatable = "YES"; str_slot->len = is_updatable.length(); str_slot->ptr = (char *)pool->allocate(str_slot->len); @@ -145,6 +147,7 @@ Status SchemaViewsScanner::fill_one_row(Tuple *tuple, MemPool *pool) { { void *slot = tuple->get_slot(_tuple_desc->slots()[6]->tuple_offset()); StringValue* str_slot = reinterpret_cast(slot); + // This is from views in mysql const std::string definer = "root@%"; str_slot->len = definer.length(); str_slot->ptr = (char *)pool->allocate(str_slot->len); @@ -157,6 +160,7 @@ Status SchemaViewsScanner::fill_one_row(Tuple *tuple, MemPool *pool) { { void *slot = tuple->get_slot(_tuple_desc->slots()[7]->tuple_offset()); StringValue* str_slot = reinterpret_cast(slot); + // This is from views in mysql const std::string security_type = "DEFINER"; str_slot->len = security_type.length(); str_slot->ptr = (char *)pool->allocate(str_slot->len); diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/SchemaTable.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/SchemaTable.java index 0ffe3d11f40479..97ec5be3144b0c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/SchemaTable.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/SchemaTable.java @@ -299,6 +299,7 @@ public static Builder builder() { .column("COLLATION_CONNECTION", ScalarType.createVarchar(32)) .build())) .build(); + // views column is from show create table views in mysql: 5.5.6 public static class Builder { List columns; From 59066ea666b95e753bd92869a5ea361e9c65c916 Mon Sep 17 00:00:00 2001 From: pengxianyu Date: Thu, 29 Oct 2020 10:14:11 +0800 Subject: [PATCH 5/5] Fix bug: Error happened when open a view in DBeaver --- be/src/exec/schema_scanner/schema_views_scanner.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/be/src/exec/schema_scanner/schema_views_scanner.cpp b/be/src/exec/schema_scanner/schema_views_scanner.cpp index 68b4707be0e658..ac41a45bc7f05c 100644 --- a/be/src/exec/schema_scanner/schema_views_scanner.cpp +++ b/be/src/exec/schema_scanner/schema_views_scanner.cpp @@ -135,7 +135,7 @@ Status SchemaViewsScanner::fill_one_row(Tuple *tuple, MemPool *pool) { void *slot = tuple->get_slot(_tuple_desc->slots()[5]->tuple_offset()); StringValue* str_slot = reinterpret_cast(slot); // This is from views in mysql - const std::string is_updatable = "YES"; + const std::string is_updatable = "NO"; str_slot->len = is_updatable.length(); str_slot->ptr = (char *)pool->allocate(str_slot->len); if (NULL == str_slot->ptr) { @@ -171,7 +171,16 @@ Status SchemaViewsScanner::fill_one_row(Tuple *tuple, MemPool *pool) { } // character_set_client { - tuple->set_null(_tuple_desc->slots()[8]->null_indicator_offset()); + void *slot = tuple->get_slot(_tuple_desc->slots()[8]->tuple_offset()); + StringValue* str_slot = reinterpret_cast(slot); + // This is from views in mysql + const std::string encoding = "utf8"; + str_slot->len = encoding.length(); + str_slot->ptr = (char *)pool->allocate(str_slot->len); + if (NULL == str_slot->ptr) { + return Status::InternalError("Allocate memcpy failed."); + } + memcpy(str_slot->ptr, encoding.c_str(), str_slot->len); } // collation_connection {