[bug](jdbc) fix jdbc external table with char type length error (#15386)

Now have test pg and oracle with char(100), if data='abc'
but read string data length is 100, so need trim extral spaces
This commit is contained in:
zhangstar333
2022-12-29 11:19:03 +08:00
committed by GitHub
parent 1f98dd2c74
commit 3146fc8189
8 changed files with 29 additions and 8 deletions

View File

@ -25,7 +25,8 @@ NewJdbcScanNode::NewJdbcScanNode(ObjectPool* pool, const TPlanNode& tnode,
: VScanNode(pool, tnode, descs),
_table_name(tnode.jdbc_scan_node.table_name),
_tuple_id(tnode.jdbc_scan_node.tuple_id),
_query_string(tnode.jdbc_scan_node.query_string) {
_query_string(tnode.jdbc_scan_node.query_string),
_table_type(tnode.jdbc_scan_node.table_type) {
_output_tuple_id = tnode.jdbc_scan_node.tuple_id;
}
@ -49,8 +50,8 @@ Status NewJdbcScanNode::_init_scanners(std::list<VScanner*>* scanners) {
if (_eos == true) {
return Status::OK();
}
NewJdbcScanner* scanner =
new NewJdbcScanner(_state, this, _limit_per_scanner, _tuple_id, _query_string);
NewJdbcScanner* scanner = new NewJdbcScanner(_state, this, _limit_per_scanner, _tuple_id,
_query_string, _table_type);
_scanner_pool.add(scanner);
RETURN_IF_ERROR(scanner->prepare(_state, _vconjunct_ctx_ptr.get()));
scanners->push_back(static_cast<VScanner*>(scanner));

View File

@ -37,6 +37,7 @@ private:
std::string _table_name;
TupleId _tuple_id;
std::string _query_string;
TOdbcTableType::type _table_type;
};
} // namespace vectorized
} // namespace doris

View File

@ -19,13 +19,15 @@
namespace doris::vectorized {
NewJdbcScanner::NewJdbcScanner(RuntimeState* state, NewJdbcScanNode* parent, int64_t limit,
const TupleId& tuple_id, const std::string& query_string)
const TupleId& tuple_id, const std::string& query_string,
TOdbcTableType::type table_type)
: VScanner(state, static_cast<VScanNode*>(parent), limit),
_is_init(false),
_jdbc_eos(false),
_tuple_id(tuple_id),
_query_string(query_string),
_tuple_desc(nullptr) {}
_tuple_desc(nullptr),
_table_type(table_type) {}
Status NewJdbcScanner::prepare(RuntimeState* state, VExprContext** vconjunct_ctx_ptr) {
VLOG_CRITICAL << "NewJdbcScanner::Prepare";
@ -63,6 +65,7 @@ Status NewJdbcScanner::prepare(RuntimeState* state, VExprContext** vconjunct_ctx
_jdbc_param.passwd = jdbc_table->jdbc_passwd();
_jdbc_param.tuple_desc = _tuple_desc;
_jdbc_param.query_string = std::move(_query_string);
_jdbc_param.table_type = _table_type;
_jdbc_connector.reset(new (std::nothrow) JdbcConnector(_jdbc_param));
if (_jdbc_connector == nullptr) {

View File

@ -26,12 +26,12 @@ namespace vectorized {
class NewJdbcScanner : public VScanner {
public:
NewJdbcScanner(RuntimeState* state, NewJdbcScanNode* parent, int64_t limit,
const TupleId& tuple_id, const std::string& query_string);
const TupleId& tuple_id, const std::string& query_string,
TOdbcTableType::type table_type);
Status open(RuntimeState* state) override;
Status close(RuntimeState* state) override;
public:
Status prepare(RuntimeState* state, VExprContext** vconjunct_ctx_ptr);
protected:
@ -48,6 +48,8 @@ private:
std::string _query_string;
// Descriptor of tuples read from JDBC table.
const TupleDescriptor* _tuple_desc;
// the sql query database type: like mysql, PG...
TOdbcTableType::type _table_type;
// Scanner of JDBC.
std::unique_ptr<JdbcConnector> _jdbc_connector;
JdbcConnectorParam _jdbc_param;

View File

@ -417,8 +417,19 @@ Status JdbcConnector::_convert_column_data(JNIEnv* env, jobject jobj,
M(TYPE_FLOAT, float, vectorized::ColumnVector<vectorized::Float32>)
M(TYPE_DOUBLE, double, vectorized::ColumnVector<vectorized::Float64>)
#undef M
case TYPE_CHAR: {
std::string data = _jobject_to_string(env, jobj);
// Now have test pg and oracle with char(100), if data='abc'
// but read string data length is 100, so need trim extra spaces
if ((_conn_param.table_type == TOdbcTableType::POSTGRESQL) ||
(_conn_param.table_type == TOdbcTableType::ORACLE)) {
data = data.erase(data.find_last_not_of(' ') + 1);
}
reinterpret_cast<vectorized::ColumnString*>(col_ptr)->insert_data(data.c_str(),
data.length());
break;
}
case TYPE_STRING:
case TYPE_CHAR:
case TYPE_VARCHAR: {
std::string data = _jobject_to_string(env, jobj);
reinterpret_cast<vectorized::ColumnString*>(col_ptr)->insert_data(data.c_str(),

View File

@ -33,6 +33,7 @@ struct JdbcConnectorParam {
std::string user;
std::string passwd;
std::string query_string;
TOdbcTableType::type table_type;
const TupleDescriptor* tuple_desc;
};

View File

@ -195,6 +195,7 @@ public class JdbcScanNode extends ScanNode {
msg.jdbc_scan_node.setTupleId(desc.getId().asInt());
msg.jdbc_scan_node.setTableName(tableName);
msg.jdbc_scan_node.setQueryString(getJdbcQueryStr());
msg.jdbc_scan_node.setTableType(jdbcType);
}
@Override

View File

@ -406,6 +406,7 @@ struct TJdbcScanNode {
1: optional Types.TTupleId tuple_id
2: optional string table_name
3: optional string query_string
4: optional Types.TOdbcTableType table_type
}