mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 16:50:48 +00:00
External dictionaries: MySQL source: Allow columns with names from reserved words [#CLICKHOUSE-2717].
This commit is contained in:
parent
b16c9a3e12
commit
4fe2a4432a
@ -11,7 +11,7 @@ struct DictionaryStructure;
|
||||
class WriteBuffer;
|
||||
|
||||
|
||||
/** Генерирует запрос для загрузки данных из внешней БД.
|
||||
/** Builds a query to load data from external database.
|
||||
*/
|
||||
struct ExternalQueryBuilder
|
||||
{
|
||||
@ -20,21 +20,33 @@ struct ExternalQueryBuilder
|
||||
const std::string & table;
|
||||
const std::string & where;
|
||||
|
||||
/// Method to quote identifiers.
|
||||
/// NOTE There could be differences in escaping rules inside quotes. Escaping rules may not match that required by specific external DBMS.
|
||||
enum QuotingStyle
|
||||
{
|
||||
None, /// Write as-is, without quotes.
|
||||
Backticks, /// `mysql` style
|
||||
DoubleQuotes /// "postgres" style
|
||||
};
|
||||
|
||||
QuotingStyle quoting_style;
|
||||
|
||||
|
||||
ExternalQueryBuilder(
|
||||
const DictionaryStructure & dict_struct,
|
||||
const std::string & db,
|
||||
const std::string & table,
|
||||
const std::string & where);
|
||||
const std::string & where,
|
||||
QuotingStyle quoting_style);
|
||||
|
||||
/** Получить запрос на загрузку всех данных. */
|
||||
/** Generate a query to load all data. */
|
||||
std::string composeLoadAllQuery() const;
|
||||
|
||||
/** Получить запрос на загрузку данных по множеству простых ключей. */
|
||||
/** Generate a query to load data by set of UInt64 keys. */
|
||||
std::string composeLoadIdsQuery(const std::vector<UInt64> & ids);
|
||||
|
||||
/** Получить запрос на загрузку данных по множеству сложных ключей.
|
||||
* Есть два метода их указания в секции WHERE:
|
||||
/** Generate a query to load data by set of composite keys.
|
||||
* There are two methods of specification of composite keys in WHERE:
|
||||
* 1. (x = c11 AND y = c12) OR (x = c21 AND y = c22) ...
|
||||
* 2. (x, y) IN ((c11, c12), (c21, c22), ...)
|
||||
*/
|
||||
@ -51,14 +63,17 @@ struct ExternalQueryBuilder
|
||||
|
||||
|
||||
private:
|
||||
/// Выражение вида (x = c1 AND y = c2 ...)
|
||||
/// Expression in form (x = c1 AND y = c2 ...)
|
||||
void composeKeyCondition(const ConstColumnPlainPtrs & key_columns, const size_t row, WriteBuffer & out) const;
|
||||
|
||||
/// Выражение вида (x, y, ...)
|
||||
/// Expression in form (x, y, ...)
|
||||
std::string composeKeyTupleDefinition() const;
|
||||
|
||||
/// Выражение вида (c1, c2, ...)
|
||||
/// Expression in form (c1, c2, ...)
|
||||
void composeKeyTuple(const ConstColumnPlainPtrs & key_columns, const size_t row, WriteBuffer & out) const;
|
||||
|
||||
/// Write string with specified quoting style.
|
||||
void writeQuoted(const std::string & s, WriteBuffer & out) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ ClickHouseDictionarySource::ClickHouseDictionarySource(const DictionaryStructure
|
||||
db{config.getString(config_prefix + ".db", "")},
|
||||
table{config.getString(config_prefix + ".table")},
|
||||
where{config.getString(config_prefix + ".where", "")},
|
||||
query_builder{dict_struct, db, table, where},
|
||||
query_builder{dict_struct, db, table, where, ExternalQueryBuilder::Backticks},
|
||||
sample_block{sample_block}, context(context),
|
||||
is_local{isLocalAddress({ host, port })},
|
||||
pool{is_local ? nullptr : std::make_shared<ConnectionPool>(
|
||||
@ -49,7 +49,7 @@ ClickHouseDictionarySource::ClickHouseDictionarySource(const ClickHouseDictionar
|
||||
host{other.host}, port{other.port}, user{other.user}, password{other.password},
|
||||
db{other.db}, table{other.table},
|
||||
where{other.where},
|
||||
query_builder{dict_struct, db, table, where},
|
||||
query_builder{dict_struct, db, table, where, ExternalQueryBuilder::Backticks},
|
||||
sample_block{other.sample_block}, context(other.context),
|
||||
is_local{other.is_local},
|
||||
pool{is_local ? nullptr : std::make_shared<ConnectionPool>(
|
||||
|
@ -21,12 +21,32 @@ ExternalQueryBuilder::ExternalQueryBuilder(
|
||||
const DictionaryStructure & dict_struct,
|
||||
const std::string & db,
|
||||
const std::string & table,
|
||||
const std::string & where)
|
||||
: dict_struct(dict_struct), db(db), table(table), where(where)
|
||||
const std::string & where,
|
||||
QuotingStyle quoting_style)
|
||||
: dict_struct(dict_struct), db(db), table(table), where(where), quoting_style(quoting_style)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ExternalQueryBuilder::writeQuoted(const std::string & s, WriteBuffer & out) const
|
||||
{
|
||||
switch (quoting_style)
|
||||
{
|
||||
case None:
|
||||
writeString(s, out);
|
||||
break;
|
||||
|
||||
case Backticks:
|
||||
writeBackQuotedString(s, out);
|
||||
break;
|
||||
|
||||
case DoubleQuotes:
|
||||
writeDoubleQuotedString(s, out);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string ExternalQueryBuilder::composeLoadAllQuery() const
|
||||
{
|
||||
std::string query;
|
||||
@ -43,7 +63,7 @@ std::string ExternalQueryBuilder::composeLoadAllQuery() const
|
||||
writeString(" AS ", out);
|
||||
}
|
||||
|
||||
writeProbablyBackQuotedString(dict_struct.id.value().name, out);
|
||||
writeQuoted(dict_struct.id.value().name, out);
|
||||
|
||||
if (dict_struct.range_min && dict_struct.range_max)
|
||||
{
|
||||
@ -55,7 +75,7 @@ std::string ExternalQueryBuilder::composeLoadAllQuery() const
|
||||
writeString(" AS ", out);
|
||||
}
|
||||
|
||||
writeProbablyBackQuotedString(dict_struct.range_min.value().name, out);
|
||||
writeQuoted(dict_struct.range_min.value().name, out);
|
||||
|
||||
writeString(", ", out);
|
||||
|
||||
@ -65,7 +85,7 @@ std::string ExternalQueryBuilder::composeLoadAllQuery() const
|
||||
writeString(" AS ", out);
|
||||
}
|
||||
|
||||
writeProbablyBackQuotedString(dict_struct.range_max.value().name, out);
|
||||
writeQuoted(dict_struct.range_max.value().name, out);
|
||||
}
|
||||
}
|
||||
else if (dict_struct.key)
|
||||
@ -84,7 +104,7 @@ std::string ExternalQueryBuilder::composeLoadAllQuery() const
|
||||
writeString(" AS ", out);
|
||||
}
|
||||
|
||||
writeProbablyBackQuotedString(key.name, out);
|
||||
writeQuoted(key.name, out);
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,16 +118,16 @@ std::string ExternalQueryBuilder::composeLoadAllQuery() const
|
||||
writeString(" AS ", out);
|
||||
}
|
||||
|
||||
writeProbablyBackQuotedString(attr.name, out);
|
||||
writeQuoted(attr.name, out);
|
||||
}
|
||||
|
||||
writeString(" FROM ", out);
|
||||
if (!db.empty())
|
||||
{
|
||||
writeProbablyBackQuotedString(db, out);
|
||||
writeQuoted(db, out);
|
||||
writeChar('.', out);
|
||||
}
|
||||
writeProbablyBackQuotedString(table, out);
|
||||
writeQuoted(table, out);
|
||||
|
||||
if (!where.empty())
|
||||
{
|
||||
@ -139,7 +159,7 @@ std::string ExternalQueryBuilder::composeLoadIdsQuery(const std::vector<UInt64>
|
||||
writeString(" AS ", out);
|
||||
}
|
||||
|
||||
writeProbablyBackQuotedString(dict_struct.id.value().name, out);
|
||||
writeQuoted(dict_struct.id.value().name, out);
|
||||
|
||||
for (const auto & attr : dict_struct.attributes)
|
||||
{
|
||||
@ -151,16 +171,16 @@ std::string ExternalQueryBuilder::composeLoadIdsQuery(const std::vector<UInt64>
|
||||
writeString(" AS ", out);
|
||||
}
|
||||
|
||||
writeProbablyBackQuotedString(attr.name, out);
|
||||
writeQuoted(attr.name, out);
|
||||
}
|
||||
|
||||
writeString(" FROM ", out);
|
||||
if (!db.empty())
|
||||
{
|
||||
writeProbablyBackQuotedString(db, out);
|
||||
writeQuoted(db, out);
|
||||
writeChar('.', out);
|
||||
}
|
||||
writeProbablyBackQuotedString(table, out);
|
||||
writeQuoted(table, out);
|
||||
|
||||
writeString(" WHERE ", out);
|
||||
|
||||
@ -170,7 +190,7 @@ std::string ExternalQueryBuilder::composeLoadIdsQuery(const std::vector<UInt64>
|
||||
writeString(" AND ", out);
|
||||
}
|
||||
|
||||
writeProbablyBackQuotedString(dict_struct.id.value().name, out);
|
||||
writeQuoted(dict_struct.id.value().name, out);
|
||||
writeString(" IN (", out);
|
||||
|
||||
auto first = true;
|
||||
@ -218,16 +238,16 @@ std::string ExternalQueryBuilder::composeLoadKeysQuery(
|
||||
writeString(" AS ", out);
|
||||
}
|
||||
|
||||
writeProbablyBackQuotedString(key_or_attribute.name, out);
|
||||
writeQuoted(key_or_attribute.name, out);
|
||||
}
|
||||
|
||||
writeString(" FROM ", out);
|
||||
if (!db.empty())
|
||||
{
|
||||
writeProbablyBackQuotedString(db, out);
|
||||
writeQuoted(db, out);
|
||||
writeChar('.', out);
|
||||
}
|
||||
writeProbablyBackQuotedString(table, out);
|
||||
writeQuoted(table, out);
|
||||
|
||||
writeString(" WHERE ", out);
|
||||
|
||||
|
@ -18,7 +18,7 @@ MySQLDictionarySource::MySQLDictionarySource(const DictionaryStructure & dict_st
|
||||
dont_check_update_time{config.getBool(config_prefix + ".dont_check_update_time", false)},
|
||||
sample_block{sample_block},
|
||||
pool{config, config_prefix},
|
||||
query_builder{dict_struct, db, table, where},
|
||||
query_builder{dict_struct, db, table, where, ExternalQueryBuilder::Backticks},
|
||||
load_all_query{query_builder.composeLoadAllQuery()}
|
||||
{
|
||||
}
|
||||
@ -32,7 +32,7 @@ MySQLDictionarySource::MySQLDictionarySource(const MySQLDictionarySource & other
|
||||
dont_check_update_time{other.dont_check_update_time},
|
||||
sample_block{other.sample_block},
|
||||
pool{other.pool},
|
||||
query_builder{dict_struct, db, table, where},
|
||||
query_builder{dict_struct, db, table, where, ExternalQueryBuilder::Backticks},
|
||||
load_all_query{other.load_all_query}, last_modification{other.last_modification}
|
||||
{
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ ODBCDictionarySource::ODBCDictionarySource(const DictionaryStructure & dict_stru
|
||||
pool{std::make_shared<Poco::Data::SessionPool>(
|
||||
config.getString(config_prefix + ".connector", "ODBC"),
|
||||
config.getString(config_prefix + ".connection_string"))},
|
||||
query_builder{dict_struct, db, table, where},
|
||||
query_builder{dict_struct, db, table, where, ExternalQueryBuilder::None}, /// NOTE Better to obtain quoting style via ODBC interface.
|
||||
load_all_query{query_builder.composeLoadAllQuery()}
|
||||
{
|
||||
}
|
||||
@ -35,7 +35,7 @@ ODBCDictionarySource::ODBCDictionarySource(const ODBCDictionarySource & other)
|
||||
where{other.where},
|
||||
sample_block{other.sample_block},
|
||||
pool{other.pool},
|
||||
query_builder{dict_struct, db, table, where},
|
||||
query_builder{dict_struct, db, table, where, ExternalQueryBuilder::None},
|
||||
load_all_query{other.load_all_query}
|
||||
{
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user