2010-06-28 13:44:42 +00:00
|
|
|
|
#include <sstream>
|
|
|
|
|
|
|
|
|
|
#include <boost/variant/static_visitor.hpp>
|
|
|
|
|
|
2011-03-29 17:56:51 +00:00
|
|
|
|
#include <mysqlxx/Manip.h>
|
2010-06-28 13:44:42 +00:00
|
|
|
|
|
2011-11-06 20:47:07 +00:00
|
|
|
|
#include <DB/IO/WriteBufferFromOStream.h>
|
2012-08-20 20:28:34 +00:00
|
|
|
|
#include <DB/IO/WriteBufferFromString.h>
|
2011-11-06 20:47:07 +00:00
|
|
|
|
#include <DB/IO/WriteHelpers.h>
|
|
|
|
|
|
2010-06-28 13:44:42 +00:00
|
|
|
|
#include <DB/Core/Exception.h>
|
|
|
|
|
#include <DB/Core/ErrorCodes.h>
|
2014-02-26 19:50:04 +00:00
|
|
|
|
#include <DB/Core/NamesAndTypes.h>
|
2010-06-28 13:44:42 +00:00
|
|
|
|
|
|
|
|
|
#include <DB/Parsers/formatAST.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
2011-11-07 02:10:34 +00:00
|
|
|
|
static const char * hilite_keyword = "\033[1;37m";
|
|
|
|
|
static const char * hilite_identifier = "\033[0;36m";
|
|
|
|
|
static const char * hilite_function = "\033[0;33m";
|
2014-03-10 18:01:26 +00:00
|
|
|
|
static const char * hilite_operator = "\033[1;33m";
|
2011-11-07 02:10:34 +00:00
|
|
|
|
static const char * hilite_alias = "\033[0;32m";
|
|
|
|
|
static const char * hilite_none = "\033[0m";
|
|
|
|
|
|
|
|
|
|
|
2012-08-20 20:28:34 +00:00
|
|
|
|
/// Квотировать идентификатор обратными кавычками, если это требуется.
|
2014-03-03 20:22:39 +00:00
|
|
|
|
String backQuoteIfNeed(const String & x)
|
2012-08-20 20:28:34 +00:00
|
|
|
|
{
|
|
|
|
|
String res(x.size(), '\0');
|
|
|
|
|
{
|
|
|
|
|
WriteBufferFromString wb(res);
|
|
|
|
|
writeProbablyBackQuotedString(x, wb);
|
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
2012-06-18 07:49:19 +00:00
|
|
|
|
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const IAST & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2010-06-28 13:44:42 +00:00
|
|
|
|
{
|
2012-06-18 07:49:19 +00:00
|
|
|
|
|
2012-08-02 19:03:32 +00:00
|
|
|
|
#define DISPATCH(NAME) \
|
|
|
|
|
else if (const AST ## NAME * concrete = dynamic_cast<const AST ## NAME *>(&ast)) \
|
2014-03-10 18:01:26 +00:00
|
|
|
|
formatAST(*concrete, s, indent, hilite, one_line, need_parens);
|
2012-08-02 19:03:32 +00:00
|
|
|
|
|
|
|
|
|
if (false) {}
|
|
|
|
|
DISPATCH(SelectQuery)
|
|
|
|
|
DISPATCH(InsertQuery)
|
|
|
|
|
DISPATCH(CreateQuery)
|
|
|
|
|
DISPATCH(DropQuery)
|
|
|
|
|
DISPATCH(RenameQuery)
|
|
|
|
|
DISPATCH(ShowTablesQuery)
|
|
|
|
|
DISPATCH(UseQuery)
|
|
|
|
|
DISPATCH(SetQuery)
|
|
|
|
|
DISPATCH(OptimizeQuery)
|
2012-12-15 03:09:04 +00:00
|
|
|
|
DISPATCH(ExistsQuery)
|
2013-02-21 10:45:00 +00:00
|
|
|
|
DISPATCH(ShowCreateQuery)
|
|
|
|
|
DISPATCH(DescribeQuery)
|
2012-08-02 19:03:32 +00:00
|
|
|
|
DISPATCH(ExpressionList)
|
|
|
|
|
DISPATCH(Function)
|
|
|
|
|
DISPATCH(Identifier)
|
|
|
|
|
DISPATCH(Literal)
|
|
|
|
|
DISPATCH(NameTypePair)
|
|
|
|
|
DISPATCH(Asterisk)
|
|
|
|
|
DISPATCH(OrderByElement)
|
2012-08-22 18:46:09 +00:00
|
|
|
|
DISPATCH(Subquery)
|
2013-08-07 13:07:42 +00:00
|
|
|
|
DISPATCH(AlterQuery)
|
2013-09-03 20:21:28 +00:00
|
|
|
|
DISPATCH(ShowProcesslistQuery)
|
2012-08-02 19:03:32 +00:00
|
|
|
|
else
|
2013-10-26 03:20:51 +00:00
|
|
|
|
throw Exception("Unknown element in AST: " + ast.getID() + " '" + std::string(ast.range.first, ast.range.second - ast.range.first) + "'",
|
2012-08-02 19:03:32 +00:00
|
|
|
|
ErrorCodes::UNKNOWN_ELEMENT_IN_AST);
|
2010-06-28 13:44:42 +00:00
|
|
|
|
|
2012-08-02 19:03:32 +00:00
|
|
|
|
#undef DISPATCH
|
2010-06-28 13:44:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-08-02 19:03:32 +00:00
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const ASTExpressionList & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
|
|
|
|
{
|
|
|
|
|
for (ASTs::const_iterator it = ast.children.begin(); it != ast.children.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
if (it != ast.children.begin())
|
|
|
|
|
s << ", ";
|
|
|
|
|
|
|
|
|
|
formatAST(**it, s, indent, hilite, one_line, need_parens);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Вывести список выражений в секциях запроса SELECT - по одному выражению на строку.
|
|
|
|
|
*/
|
|
|
|
|
static void formatExpressionListMultiline(const ASTExpressionList & ast, std::ostream & s, size_t indent, bool hilite)
|
|
|
|
|
{
|
|
|
|
|
std::string indent_str = "\n" + std::string(4 * (indent + 1), ' ');
|
|
|
|
|
|
|
|
|
|
for (ASTs::const_iterator it = ast.children.begin(); it != ast.children.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
if (it != ast.children.begin())
|
|
|
|
|
s << ", ";
|
|
|
|
|
|
|
|
|
|
if (ast.children.size() > 1)
|
|
|
|
|
s << indent_str;
|
|
|
|
|
|
|
|
|
|
formatAST(**it, s, indent + 1, hilite, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void formatAST(const ASTSelectQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2010-06-28 13:44:42 +00:00
|
|
|
|
{
|
2012-08-22 18:46:09 +00:00
|
|
|
|
std::string nl_or_nothing = one_line ? "" : "\n";
|
|
|
|
|
|
2012-05-30 01:38:02 +00:00
|
|
|
|
std::string indent_str = one_line ? "" : std::string(4 * indent, ' ');
|
|
|
|
|
std::string nl_or_ws = one_line ? " " : "\n";
|
2012-08-22 18:46:09 +00:00
|
|
|
|
|
2013-06-01 07:43:57 +00:00
|
|
|
|
s << (hilite ? hilite_keyword : "") << indent_str << "SELECT " << (ast.distinct ? "DISTINCT " : "") << (hilite ? hilite_none : "");
|
2014-03-10 18:01:26 +00:00
|
|
|
|
one_line
|
|
|
|
|
? formatAST(*ast.select_expression_list, s, indent, hilite, one_line)
|
|
|
|
|
: formatExpressionListMultiline(dynamic_cast<const ASTExpressionList &>(*ast.select_expression_list), s, indent, hilite);
|
2011-08-28 00:31:30 +00:00
|
|
|
|
|
|
|
|
|
if (ast.table)
|
|
|
|
|
{
|
2012-05-30 01:38:02 +00:00
|
|
|
|
s << (hilite ? hilite_keyword : "") << nl_or_ws << indent_str << "FROM " << (hilite ? hilite_none : "");
|
2011-08-28 00:31:30 +00:00
|
|
|
|
if (ast.database)
|
|
|
|
|
{
|
2012-05-30 01:38:02 +00:00
|
|
|
|
formatAST(*ast.database, s, indent, hilite, one_line);
|
2011-08-28 00:31:30 +00:00
|
|
|
|
s << ".";
|
|
|
|
|
}
|
2011-11-07 02:10:34 +00:00
|
|
|
|
|
|
|
|
|
if (dynamic_cast<const ASTSelectQuery *>(&*ast.table))
|
|
|
|
|
{
|
2012-05-30 01:38:02 +00:00
|
|
|
|
if (one_line)
|
|
|
|
|
s << " (";
|
|
|
|
|
else
|
|
|
|
|
s << "\n" << indent_str << "(\n";
|
|
|
|
|
|
|
|
|
|
formatAST(*ast.table, s, indent + 1, hilite, one_line);
|
|
|
|
|
|
|
|
|
|
if (one_line)
|
|
|
|
|
s << ")";
|
|
|
|
|
else
|
|
|
|
|
s << "\n" << indent_str << ")";
|
2011-11-07 02:10:34 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
2012-05-30 01:38:02 +00:00
|
|
|
|
formatAST(*ast.table, s, indent, hilite, one_line);
|
2011-08-28 00:31:30 +00:00
|
|
|
|
}
|
2012-12-12 16:49:08 +00:00
|
|
|
|
|
2013-10-17 13:32:32 +00:00
|
|
|
|
if (ast.array_join_expression_list)
|
2013-07-22 16:49:19 +00:00
|
|
|
|
{
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << nl_or_ws << indent_str << "ARRAY JOIN " << (hilite ? hilite_none : "");
|
2014-03-10 18:01:26 +00:00
|
|
|
|
one_line
|
|
|
|
|
? formatAST(*ast.array_join_expression_list, s, indent, hilite, one_line)
|
|
|
|
|
: formatExpressionListMultiline(dynamic_cast<const ASTExpressionList &>(*ast.array_join_expression_list), s, indent, hilite);
|
2013-07-22 16:49:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-04-29 11:34:28 +00:00
|
|
|
|
if (ast.final)
|
|
|
|
|
{
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << nl_or_ws << indent_str << "FINAL" << (hilite ? hilite_none : "");
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-12 16:49:08 +00:00
|
|
|
|
if (ast.sample_size)
|
|
|
|
|
{
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << nl_or_ws << indent_str << "SAMPLE " << (hilite ? hilite_none : "");
|
|
|
|
|
formatAST(*ast.sample_size, s, indent, hilite, one_line);
|
|
|
|
|
}
|
2011-08-28 00:31:30 +00:00
|
|
|
|
|
2013-12-05 13:07:55 +00:00
|
|
|
|
if (ast.prewhere_expression)
|
|
|
|
|
{
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << nl_or_ws << indent_str << "PREWHERE " << (hilite ? hilite_none : "");
|
2014-03-10 18:01:26 +00:00
|
|
|
|
one_line
|
|
|
|
|
? formatAST(*ast.prewhere_expression, s, indent, hilite, one_line)
|
|
|
|
|
: formatExpressionListMultiline(dynamic_cast<const ASTExpressionList &>(*ast.prewhere_expression), s, indent, hilite);
|
2013-12-05 13:07:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2011-08-28 00:31:30 +00:00
|
|
|
|
if (ast.where_expression)
|
|
|
|
|
{
|
2012-05-30 01:38:02 +00:00
|
|
|
|
s << (hilite ? hilite_keyword : "") << nl_or_ws << indent_str << "WHERE " << (hilite ? hilite_none : "");
|
|
|
|
|
formatAST(*ast.where_expression, s, indent, hilite, one_line);
|
2011-08-28 00:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ast.group_expression_list)
|
|
|
|
|
{
|
2012-05-30 01:38:02 +00:00
|
|
|
|
s << (hilite ? hilite_keyword : "") << nl_or_ws << indent_str << "GROUP BY " << (hilite ? hilite_none : "");
|
2014-03-10 18:01:26 +00:00
|
|
|
|
one_line
|
|
|
|
|
? formatAST(*ast.group_expression_list, s, indent, hilite, one_line)
|
|
|
|
|
: formatExpressionListMultiline(dynamic_cast<const ASTExpressionList &>(*ast.group_expression_list), s, indent, hilite);
|
2013-05-04 15:46:50 +00:00
|
|
|
|
|
|
|
|
|
if (ast.group_by_with_totals)
|
2014-03-10 18:01:26 +00:00
|
|
|
|
s << (hilite ? hilite_keyword : "") << nl_or_ws << indent_str << (one_line ? "" : " ") << "WITH TOTALS" << (hilite ? hilite_none : "");
|
2011-08-28 00:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ast.having_expression)
|
|
|
|
|
{
|
2012-05-30 01:38:02 +00:00
|
|
|
|
s << (hilite ? hilite_keyword : "") << nl_or_ws << indent_str << "HAVING " << (hilite ? hilite_none : "");
|
|
|
|
|
formatAST(*ast.having_expression, s, indent, hilite, one_line);
|
2011-08-28 00:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ast.order_expression_list)
|
|
|
|
|
{
|
2012-05-30 01:38:02 +00:00
|
|
|
|
s << (hilite ? hilite_keyword : "") << nl_or_ws << indent_str << "ORDER BY " << (hilite ? hilite_none : "");
|
2014-03-10 18:01:26 +00:00
|
|
|
|
one_line
|
|
|
|
|
? formatAST(*ast.order_expression_list, s, indent, hilite, one_line)
|
|
|
|
|
: formatExpressionListMultiline(dynamic_cast<const ASTExpressionList &>(*ast.order_expression_list), s, indent, hilite);
|
2011-08-28 00:31:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ast.limit_length)
|
|
|
|
|
{
|
2012-05-30 01:38:02 +00:00
|
|
|
|
s << (hilite ? hilite_keyword : "") << nl_or_ws << indent_str << "LIMIT " << (hilite ? hilite_none : "");
|
2011-08-28 00:31:30 +00:00
|
|
|
|
if (ast.limit_offset)
|
|
|
|
|
{
|
2012-05-30 01:38:02 +00:00
|
|
|
|
formatAST(*ast.limit_offset, s, indent, hilite, one_line);
|
2011-08-28 00:31:30 +00:00
|
|
|
|
s << ", ";
|
|
|
|
|
}
|
2012-05-30 01:38:02 +00:00
|
|
|
|
formatAST(*ast.limit_length, s, indent, hilite, one_line);
|
2011-08-28 00:31:30 +00:00
|
|
|
|
}
|
2011-10-30 05:19:41 +00:00
|
|
|
|
|
|
|
|
|
if (ast.format)
|
|
|
|
|
{
|
2012-05-30 01:38:02 +00:00
|
|
|
|
s << (hilite ? hilite_keyword : "") << nl_or_ws << indent_str << "FORMAT " << (hilite ? hilite_none : "");
|
|
|
|
|
formatAST(*ast.format, s, indent, hilite, one_line);
|
2011-10-30 05:19:41 +00:00
|
|
|
|
}
|
2010-06-28 13:44:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const ASTSubquery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2012-08-22 18:46:09 +00:00
|
|
|
|
{
|
2014-03-12 17:12:09 +00:00
|
|
|
|
std::string indent_str = one_line ? "" : std::string(4 * indent, ' ');
|
2012-08-22 18:46:09 +00:00
|
|
|
|
std::string nl_or_nothing = one_line ? "" : "\n";
|
|
|
|
|
|
2014-03-12 17:12:09 +00:00
|
|
|
|
s << nl_or_nothing << indent_str << "(" << nl_or_nothing;
|
2012-08-22 18:46:09 +00:00
|
|
|
|
formatAST(*ast.children[0], s, indent + 1, hilite, one_line);
|
2014-03-12 17:12:09 +00:00
|
|
|
|
s << nl_or_nothing << indent_str << ")";
|
2012-08-22 18:46:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const ASTCreateQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2011-08-18 18:48:00 +00:00
|
|
|
|
{
|
2012-05-30 01:38:02 +00:00
|
|
|
|
std::string nl_or_ws = one_line ? " " : "\n";
|
|
|
|
|
|
2011-12-26 07:07:30 +00:00
|
|
|
|
if (!ast.database.empty() && ast.table.empty())
|
|
|
|
|
{
|
2012-05-21 20:38:34 +00:00
|
|
|
|
s << (hilite ? hilite_keyword : "") << (ast.attach ? "ATTACH DATABASE " : "CREATE DATABASE ") << (ast.if_not_exists ? "IF NOT EXISTS " : "") << (hilite ? hilite_none : "")
|
2012-08-20 20:28:34 +00:00
|
|
|
|
<< backQuoteIfNeed(ast.database);
|
2011-12-26 07:07:30 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-24 17:01:50 +00:00
|
|
|
|
{
|
|
|
|
|
std::string what = "TABLE";
|
|
|
|
|
if (ast.is_view)
|
|
|
|
|
what = "VIEW";
|
|
|
|
|
if (ast.is_materialized_view)
|
|
|
|
|
what = "MATERIALIZED VIEW";
|
|
|
|
|
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << (ast.attach ? "ATTACH " : "CREATE ") << what << " " << (ast.if_not_exists ? "IF NOT EXISTS " : "") << (hilite ? hilite_none : "")
|
2012-08-20 20:28:34 +00:00
|
|
|
|
<< (!ast.database.empty() ? backQuoteIfNeed(ast.database) + "." : "") << backQuoteIfNeed(ast.table);
|
2013-12-24 17:01:50 +00:00
|
|
|
|
}
|
2011-12-26 07:07:30 +00:00
|
|
|
|
|
|
|
|
|
if (!ast.as_table.empty())
|
|
|
|
|
{
|
2012-05-21 20:38:34 +00:00
|
|
|
|
s << (hilite ? hilite_keyword : "") << " AS " << (hilite ? hilite_none : "")
|
2012-08-20 20:28:34 +00:00
|
|
|
|
<< (!ast.as_database.empty() ? backQuoteIfNeed(ast.as_database) + "." : "") << backQuoteIfNeed(ast.as_table);
|
2011-12-26 07:07:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ast.columns)
|
|
|
|
|
{
|
2012-08-21 15:14:04 +00:00
|
|
|
|
s << (one_line ? " (" : "\n(");
|
2012-05-30 01:38:02 +00:00
|
|
|
|
formatAST(*ast.columns, s, indent + 1, hilite, one_line);
|
2012-08-21 15:14:04 +00:00
|
|
|
|
s << (one_line ? ")" : "\n)");
|
2011-12-26 07:07:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-12-24 17:01:50 +00:00
|
|
|
|
if (ast.storage && !ast.is_materialized_view && !ast.is_view)
|
2011-12-26 07:07:30 +00:00
|
|
|
|
{
|
2012-05-21 20:38:34 +00:00
|
|
|
|
s << (hilite ? hilite_keyword : "") << " ENGINE" << (hilite ? hilite_none : "") << " = ";
|
2012-05-30 01:38:02 +00:00
|
|
|
|
formatAST(*ast.storage, s, indent, hilite, one_line);
|
2011-12-26 07:07:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-12-24 17:01:50 +00:00
|
|
|
|
if (ast.inner_storage)
|
|
|
|
|
{
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << " ENGINE" << (hilite ? hilite_none : "") << " = ";
|
|
|
|
|
formatAST(*ast.inner_storage, s, indent, hilite, one_line);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ast.is_populate)
|
|
|
|
|
{
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << " POPULATE" << (hilite ? hilite_none : "");
|
|
|
|
|
}
|
|
|
|
|
|
2011-12-26 07:07:30 +00:00
|
|
|
|
if (ast.select)
|
|
|
|
|
{
|
2012-05-30 01:38:02 +00:00
|
|
|
|
s << (hilite ? hilite_keyword : "") << " AS" << nl_or_ws << (hilite ? hilite_none : "");
|
|
|
|
|
formatAST(*ast.select, s, indent, hilite, one_line);
|
2011-12-26 07:07:30 +00:00
|
|
|
|
}
|
2011-08-18 18:48:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const ASTDropQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2012-01-09 19:20:48 +00:00
|
|
|
|
{
|
2012-06-18 06:19:13 +00:00
|
|
|
|
if (ast.table.empty() && !ast.database.empty())
|
2012-01-09 19:20:48 +00:00
|
|
|
|
{
|
2012-08-20 20:28:34 +00:00
|
|
|
|
s << (hilite ? hilite_keyword : "") << (ast.detach ? "DETACH DATABASE " : "DROP DATABASE ") << (ast.if_exists ? "IF EXISTS " : "") << (hilite ? hilite_none : "") << backQuoteIfNeed(ast.database);
|
2012-01-09 19:20:48 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2012-06-18 06:19:13 +00:00
|
|
|
|
s << (hilite ? hilite_keyword : "") << (ast.detach ? "DETACH TABLE " : "DROP TABLE ") << (ast.if_exists ? "IF EXISTS " : "") << (hilite ? hilite_none : "")
|
2012-08-20 20:28:34 +00:00
|
|
|
|
<< (!ast.database.empty() ? backQuoteIfNeed(ast.database) + "." : "") << backQuoteIfNeed(ast.table);
|
2012-06-18 06:19:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const ASTOptimizeQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2012-07-31 19:08:49 +00:00
|
|
|
|
{
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << "OPTIMIZE TABLE " << (hilite ? hilite_none : "")
|
2012-08-20 20:28:34 +00:00
|
|
|
|
<< (!ast.database.empty() ? backQuoteIfNeed(ast.database) + "." : "") << backQuoteIfNeed(ast.table);
|
2012-07-31 19:08:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const ASTQueryWithTableAndOutput & ast, std::string name, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2013-02-21 10:02:33 +00:00
|
|
|
|
{
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << name << " " << (hilite ? hilite_none : "")
|
|
|
|
|
<< (!ast.database.empty() ? backQuoteIfNeed(ast.database) + "." : "") << backQuoteIfNeed(ast.table);
|
|
|
|
|
|
|
|
|
|
if (ast.format)
|
|
|
|
|
{
|
|
|
|
|
std::string indent_str = one_line ? "" : std::string(4 * indent, ' ');
|
|
|
|
|
std::string nl_or_ws = one_line ? " " : "\n";
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << nl_or_ws << indent_str << "FORMAT " << (hilite ? hilite_none : "");
|
|
|
|
|
formatAST(*ast.format, s, indent, hilite, one_line);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const ASTExistsQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2012-12-15 03:09:04 +00:00
|
|
|
|
{
|
2013-02-21 11:08:29 +00:00
|
|
|
|
formatAST(static_cast<const ASTQueryWithTableAndOutput &>(ast), "EXISTS TABLE", s, indent, hilite, one_line);
|
2013-02-21 10:02:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const ASTDescribeQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2013-02-21 10:02:33 +00:00
|
|
|
|
{
|
2013-02-21 11:08:29 +00:00
|
|
|
|
formatAST(static_cast<const ASTQueryWithTableAndOutput &>(ast), "DESCRIBE TABLE", s, indent, hilite, one_line);
|
2013-02-21 10:02:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const ASTShowCreateQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2013-02-21 10:02:33 +00:00
|
|
|
|
{
|
2013-02-21 11:08:29 +00:00
|
|
|
|
formatAST(static_cast<const ASTQueryWithTableAndOutput &>(ast), "SHOW CREATE TABLE", s, indent, hilite, one_line);
|
2012-12-15 03:09:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const ASTRenameQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2012-06-18 06:19:13 +00:00
|
|
|
|
{
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << "RENAME TABLE " << (hilite ? hilite_none : "");
|
|
|
|
|
|
|
|
|
|
for (ASTRenameQuery::Elements::const_iterator it = ast.elements.begin(); it != ast.elements.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
if (it != ast.elements.begin())
|
|
|
|
|
s << ", ";
|
|
|
|
|
|
2012-08-20 20:28:34 +00:00
|
|
|
|
s << (!it->from.database.empty() ? backQuoteIfNeed(it->from.database) + "." : "") << backQuoteIfNeed(it->from.table)
|
2012-06-18 06:19:13 +00:00
|
|
|
|
<< (hilite ? hilite_keyword : "") << " TO " << (hilite ? hilite_none : "")
|
2012-08-20 20:28:34 +00:00
|
|
|
|
<< (!it->to.database.empty() ? backQuoteIfNeed(it->to.database) + "." : "") << backQuoteIfNeed(it->to.table);
|
2012-06-18 06:19:13 +00:00
|
|
|
|
}
|
2012-01-09 19:20:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const ASTSetQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2012-08-02 19:03:32 +00:00
|
|
|
|
{
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << "SET " << (ast.global ? "GLOBAL " : "") << (hilite ? hilite_none : "");
|
|
|
|
|
|
|
|
|
|
for (ASTSetQuery::Changes::const_iterator it = ast.changes.begin(); it != ast.changes.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
if (it != ast.changes.begin())
|
|
|
|
|
s << ", ";
|
|
|
|
|
|
2013-01-05 20:03:19 +00:00
|
|
|
|
s << it->name << " = " << apply_visitor(FieldVisitorToString(), it->value);
|
2012-08-02 19:03:32 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const ASTShowTablesQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2012-06-18 07:49:19 +00:00
|
|
|
|
{
|
|
|
|
|
if (ast.databases)
|
|
|
|
|
{
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << "SHOW DATABASES" << (hilite ? hilite_none : "");
|
|
|
|
|
}
|
2013-02-21 10:51:25 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << "SHOW TABLES" << (hilite ? hilite_none : "");
|
2012-06-18 07:49:19 +00:00
|
|
|
|
|
2013-02-21 10:51:25 +00:00
|
|
|
|
if (!ast.from.empty())
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << " FROM " << (hilite ? hilite_none : "")
|
|
|
|
|
<< backQuoteIfNeed(ast.from);
|
2012-06-18 07:49:19 +00:00
|
|
|
|
|
2013-02-21 10:51:25 +00:00
|
|
|
|
if (!ast.like.empty())
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << " LIKE " << (hilite ? hilite_none : "")
|
|
|
|
|
<< mysqlxx::quote << ast.like;
|
|
|
|
|
}
|
2013-02-21 10:02:33 +00:00
|
|
|
|
|
|
|
|
|
if (ast.format)
|
|
|
|
|
{
|
|
|
|
|
std::string indent_str = one_line ? "" : std::string(4 * indent, ' ');
|
|
|
|
|
std::string nl_or_ws = one_line ? " " : "\n";
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << nl_or_ws << indent_str << "FORMAT " << (hilite ? hilite_none : "");
|
|
|
|
|
formatAST(*ast.format, s, indent, hilite, one_line);
|
|
|
|
|
}
|
2012-06-18 07:49:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const ASTUseQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2012-07-12 19:49:22 +00:00
|
|
|
|
{
|
2012-08-20 20:28:34 +00:00
|
|
|
|
s << (hilite ? hilite_keyword : "") << "USE " << (hilite ? hilite_none : "") << backQuoteIfNeed(ast.database);
|
2012-07-12 19:49:22 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const ASTShowProcesslistQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2013-09-03 20:21:28 +00:00
|
|
|
|
{
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << "SHOW PROCESSLIST" << (hilite ? hilite_none : "");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const ASTInsertQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2011-10-30 05:19:41 +00:00
|
|
|
|
{
|
2012-08-20 20:28:34 +00:00
|
|
|
|
s << (hilite ? hilite_keyword : "") << "INSERT INTO " << (hilite ? hilite_none : "")
|
|
|
|
|
<< (!ast.database.empty() ? backQuoteIfNeed(ast.database) + "." : "") << backQuoteIfNeed(ast.table);
|
2011-10-30 05:19:41 +00:00
|
|
|
|
|
|
|
|
|
if (ast.columns)
|
|
|
|
|
{
|
|
|
|
|
s << " (";
|
2012-05-30 01:38:02 +00:00
|
|
|
|
formatAST(*ast.columns, s, indent, hilite, one_line);
|
2011-10-30 05:19:41 +00:00
|
|
|
|
s << ")";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ast.select)
|
|
|
|
|
{
|
|
|
|
|
s << " ";
|
2012-05-30 01:38:02 +00:00
|
|
|
|
formatAST(*ast.select, s, indent, hilite, one_line);
|
2011-10-30 05:19:41 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (!ast.format.empty())
|
|
|
|
|
{
|
2012-05-21 20:38:34 +00:00
|
|
|
|
s << (hilite ? hilite_keyword : "") << " FORMAT " << (hilite ? hilite_none : "") << ast.format;
|
2011-10-30 05:19:41 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2012-05-21 20:38:34 +00:00
|
|
|
|
s << (hilite ? hilite_keyword : "") << " VALUES" << (hilite ? hilite_none : "");
|
2011-10-30 05:19:41 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-30 01:38:02 +00:00
|
|
|
|
static void writeAlias(const String & name, std::ostream & s, bool hilite, bool one_line)
|
2011-11-06 20:47:07 +00:00
|
|
|
|
{
|
2012-05-21 20:38:34 +00:00
|
|
|
|
s << (hilite ? hilite_keyword : "") << " AS " << (hilite ? hilite_alias : "");
|
2013-11-18 01:35:24 +00:00
|
|
|
|
|
|
|
|
|
WriteBufferFromOStream wb(s, 32);
|
|
|
|
|
writeProbablyBackQuotedString(name, wb);
|
|
|
|
|
wb.next();
|
|
|
|
|
|
2012-05-21 20:38:34 +00:00
|
|
|
|
s << (hilite ? hilite_none : "");
|
2011-11-06 20:47:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const ASTFunction & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2010-06-28 13:44:42 +00:00
|
|
|
|
{
|
2014-03-13 17:30:58 +00:00
|
|
|
|
/// Если есть алиас, то требуются скобки вокруг всего выражения, включая алиас. Потому что запись вида 0 AS x + 0 синтаксически некорректна.
|
|
|
|
|
if (need_parens && !ast.alias.empty())
|
|
|
|
|
s << '(';
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
/// Стоит ли записать эту функцию в виде оператора?
|
|
|
|
|
bool written = false;
|
|
|
|
|
if (ast.arguments && !ast.parameters)
|
2011-08-18 18:48:00 +00:00
|
|
|
|
{
|
2014-03-10 18:01:26 +00:00
|
|
|
|
if (ast.arguments->children.size() == 1)
|
|
|
|
|
{
|
|
|
|
|
const char * operators[] =
|
|
|
|
|
{
|
|
|
|
|
"negate", "-",
|
|
|
|
|
"not", "NOT ",
|
|
|
|
|
nullptr
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (const char ** func = operators; *func; func += 2)
|
|
|
|
|
{
|
|
|
|
|
if (0 == strcmp(ast.name.c_str(), func[0]))
|
|
|
|
|
{
|
|
|
|
|
s << (hilite ? hilite_operator : "") << func[1] << (hilite ? hilite_none : "");
|
|
|
|
|
formatAST(*ast.arguments, s, indent, hilite, one_line, true);
|
|
|
|
|
written = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** need_parens - нужны ли скобки вокруг выражения с оператором.
|
|
|
|
|
* Они нужны, только если это выражение входит в другое выражение с оператором.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
if (!written && ast.arguments->children.size() == 2)
|
|
|
|
|
{
|
|
|
|
|
const char * operators[] =
|
|
|
|
|
{
|
|
|
|
|
"multiply", " * ",
|
|
|
|
|
"divide", " / ",
|
|
|
|
|
"modulo", " % ",
|
|
|
|
|
"plus", " + ",
|
|
|
|
|
"minus", " - ",
|
|
|
|
|
"notEquals", " != ",
|
|
|
|
|
"lessOrEquals", " <= ",
|
|
|
|
|
"greaterOrEquals", " >= ",
|
|
|
|
|
"less", " < ",
|
|
|
|
|
"greater", " > ",
|
|
|
|
|
"equals", " = ",
|
2014-03-17 19:56:37 +00:00
|
|
|
|
"lambda", " -> ",
|
2014-03-10 18:01:26 +00:00
|
|
|
|
"like", " LIKE ",
|
|
|
|
|
"notLike", " NOT LIKE ",
|
|
|
|
|
"in", " IN ",
|
|
|
|
|
"notIn", " NOT IN ",
|
|
|
|
|
nullptr
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (const char ** func = operators; *func; func += 2)
|
|
|
|
|
{
|
|
|
|
|
if (0 == strcmp(ast.name.c_str(), func[0]))
|
|
|
|
|
{
|
|
|
|
|
if (need_parens)
|
|
|
|
|
s << '(';
|
|
|
|
|
formatAST(*ast.arguments->children[0], s, indent, hilite, one_line, true);
|
|
|
|
|
s << (hilite ? hilite_operator : "") << func[1] << (hilite ? hilite_none : "");
|
|
|
|
|
formatAST(*ast.arguments->children[1], s, indent, hilite, one_line, true);
|
|
|
|
|
if (need_parens)
|
|
|
|
|
s << ')';
|
|
|
|
|
written = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!written && 0 == strcmp(ast.name.c_str(), "arrayElement"))
|
|
|
|
|
{
|
|
|
|
|
formatAST(*ast.arguments->children[0], s, indent, hilite, one_line, true);
|
|
|
|
|
s << (hilite ? hilite_operator : "") << '[' << (hilite ? hilite_none : "");
|
|
|
|
|
formatAST(*ast.arguments->children[1], s, indent, hilite, one_line, true);
|
|
|
|
|
s << (hilite ? hilite_operator : "") << ']' << (hilite ? hilite_none : "");
|
|
|
|
|
written = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!written && 0 == strcmp(ast.name.c_str(), "tupleElement"))
|
|
|
|
|
{
|
|
|
|
|
formatAST(*ast.arguments->children[0], s, indent, hilite, one_line, true);
|
|
|
|
|
s << (hilite ? hilite_operator : "") << "." << (hilite ? hilite_none : "");
|
|
|
|
|
formatAST(*ast.arguments->children[1], s, indent, hilite, one_line, true);
|
|
|
|
|
written = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!written && ast.arguments->children.size() >= 2)
|
|
|
|
|
{
|
|
|
|
|
const char * operators[] =
|
|
|
|
|
{
|
|
|
|
|
"and", " AND ",
|
|
|
|
|
"or", " OR ",
|
|
|
|
|
nullptr
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (const char ** func = operators; *func; func += 2)
|
|
|
|
|
{
|
|
|
|
|
if (0 == strcmp(ast.name.c_str(), func[0]))
|
|
|
|
|
{
|
|
|
|
|
if (need_parens)
|
|
|
|
|
s << '(';
|
|
|
|
|
for (size_t i = 0; i < ast.arguments->children.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
if (i != 0)
|
|
|
|
|
s << (hilite ? hilite_operator : "") << func[1] << (hilite ? hilite_none : "");
|
|
|
|
|
formatAST(*ast.arguments->children[i], s, indent, hilite, one_line, true);
|
|
|
|
|
}
|
|
|
|
|
if (need_parens)
|
|
|
|
|
s << ')';
|
|
|
|
|
written = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-03-13 17:30:58 +00:00
|
|
|
|
}
|
2014-03-10 18:10:44 +00:00
|
|
|
|
|
2014-03-13 17:30:58 +00:00
|
|
|
|
if (!written && ast.arguments->children.size() >= 1)
|
|
|
|
|
{
|
2014-03-10 18:10:44 +00:00
|
|
|
|
if (!written && 0 == strcmp(ast.name.c_str(), "array"))
|
|
|
|
|
{
|
2014-03-13 17:30:58 +00:00
|
|
|
|
s << (hilite ? hilite_operator : "") << '[' << (hilite ? hilite_none : "");
|
2014-03-10 18:10:44 +00:00
|
|
|
|
for (size_t i = 0; i < ast.arguments->children.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
if (i != 0)
|
|
|
|
|
s << ", ";
|
|
|
|
|
formatAST(*ast.arguments->children[i], s, indent, hilite, one_line, false);
|
|
|
|
|
}
|
2014-03-13 17:30:58 +00:00
|
|
|
|
s << (hilite ? hilite_operator : "") << ']' << (hilite ? hilite_none : "");
|
2014-03-10 18:10:44 +00:00
|
|
|
|
written = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!written && 0 == strcmp(ast.name.c_str(), "tuple"))
|
|
|
|
|
{
|
2014-03-13 17:30:58 +00:00
|
|
|
|
s << (hilite ? hilite_operator : "") << '(' << (hilite ? hilite_none : "");
|
2014-03-10 18:10:44 +00:00
|
|
|
|
for (size_t i = 0; i < ast.arguments->children.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
if (i != 0)
|
|
|
|
|
s << ", ";
|
|
|
|
|
formatAST(*ast.arguments->children[i], s, indent, hilite, one_line, false);
|
|
|
|
|
}
|
2014-03-13 17:30:58 +00:00
|
|
|
|
s << (hilite ? hilite_operator : "") << ')' << (hilite ? hilite_none : "");
|
2014-03-10 18:10:44 +00:00
|
|
|
|
written = true;
|
|
|
|
|
}
|
2014-03-10 18:01:26 +00:00
|
|
|
|
}
|
2011-08-18 18:48:00 +00:00
|
|
|
|
}
|
2012-10-29 04:54:46 +00:00
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
if (!written)
|
2012-10-29 05:29:34 +00:00
|
|
|
|
{
|
2014-03-10 18:01:26 +00:00
|
|
|
|
s << (hilite ? hilite_function : "") << ast.name;
|
|
|
|
|
|
|
|
|
|
if (ast.parameters)
|
|
|
|
|
{
|
|
|
|
|
s << '(' << (hilite ? hilite_none : "");
|
|
|
|
|
formatAST(*ast.parameters, s, indent, hilite, one_line);
|
|
|
|
|
s << (hilite ? hilite_function : "") << ')';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ast.arguments)
|
|
|
|
|
{
|
|
|
|
|
s << '(' << (hilite ? hilite_none : "");
|
|
|
|
|
formatAST(*ast.arguments, s, indent, hilite, one_line);
|
|
|
|
|
s << (hilite ? hilite_function : "") << ')';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s << (hilite ? hilite_none : "");
|
2012-10-29 05:29:34 +00:00
|
|
|
|
}
|
2011-11-06 20:47:07 +00:00
|
|
|
|
|
|
|
|
|
if (!ast.alias.empty())
|
2014-03-13 17:30:58 +00:00
|
|
|
|
{
|
2012-05-30 01:38:02 +00:00
|
|
|
|
writeAlias(ast.alias, s, hilite, one_line);
|
2014-03-13 17:30:58 +00:00
|
|
|
|
if (need_parens)
|
|
|
|
|
s << ')';
|
|
|
|
|
}
|
2010-06-28 13:44:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const ASTIdentifier & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2010-06-28 13:44:42 +00:00
|
|
|
|
{
|
2014-03-13 17:30:58 +00:00
|
|
|
|
if (need_parens && !ast.alias.empty())
|
|
|
|
|
s << '(';
|
|
|
|
|
|
2012-05-21 20:38:34 +00:00
|
|
|
|
s << (hilite ? hilite_identifier : "");
|
2013-11-18 01:35:24 +00:00
|
|
|
|
|
|
|
|
|
WriteBufferFromOStream wb(s, 32);
|
|
|
|
|
writeProbablyBackQuotedString(ast.name, wb);
|
|
|
|
|
wb.next();
|
|
|
|
|
|
2012-05-21 20:38:34 +00:00
|
|
|
|
s << (hilite ? hilite_none : "");
|
2011-11-06 20:47:07 +00:00
|
|
|
|
|
|
|
|
|
if (!ast.alias.empty())
|
2014-03-13 17:30:58 +00:00
|
|
|
|
{
|
2012-05-30 01:38:02 +00:00
|
|
|
|
writeAlias(ast.alias, s, hilite, one_line);
|
2014-03-13 17:30:58 +00:00
|
|
|
|
if (need_parens)
|
|
|
|
|
s << ')';
|
|
|
|
|
}
|
2010-06-28 13:44:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const ASTLiteral & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2010-06-28 13:44:42 +00:00
|
|
|
|
{
|
2014-03-13 17:30:58 +00:00
|
|
|
|
if (need_parens && !ast.alias.empty())
|
|
|
|
|
s << '(';
|
|
|
|
|
|
2013-01-05 20:03:19 +00:00
|
|
|
|
s << apply_visitor(FieldVisitorToString(), ast.value);
|
2011-11-06 20:47:07 +00:00
|
|
|
|
|
|
|
|
|
if (!ast.alias.empty())
|
2014-03-13 17:30:58 +00:00
|
|
|
|
{
|
2012-05-30 01:38:02 +00:00
|
|
|
|
writeAlias(ast.alias, s, hilite, one_line);
|
2014-03-13 17:30:58 +00:00
|
|
|
|
if (need_parens)
|
|
|
|
|
s << ')';
|
|
|
|
|
}
|
2010-06-28 13:44:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const ASTNameTypePair & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2011-08-18 18:48:00 +00:00
|
|
|
|
{
|
2012-05-30 01:38:02 +00:00
|
|
|
|
std::string indent_str = one_line ? "" : std::string(4 * indent, ' ');
|
|
|
|
|
std::string nl_or_ws = one_line ? " " : "\n";
|
|
|
|
|
|
2012-08-21 15:14:04 +00:00
|
|
|
|
s << nl_or_ws << indent_str << backQuoteIfNeed(ast.name) << " ";
|
2012-05-30 01:38:02 +00:00
|
|
|
|
formatAST(*ast.type, s, indent, hilite, one_line);
|
2011-08-18 18:48:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const ASTAsterisk & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2011-08-28 08:50:27 +00:00
|
|
|
|
{
|
|
|
|
|
s << "*";
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const ASTOrderByElement & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2011-09-04 05:14:52 +00:00
|
|
|
|
{
|
2012-05-30 01:38:02 +00:00
|
|
|
|
formatAST(*ast.children.front(), s, indent, hilite, one_line);
|
2012-05-21 20:38:34 +00:00
|
|
|
|
s << (hilite ? hilite_keyword : "") << (ast.direction == -1 ? " DESC" : " ASC") << (hilite ? hilite_none : "");
|
2013-05-29 12:38:20 +00:00
|
|
|
|
if (!ast.collator.isNull())
|
|
|
|
|
{
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << " COLLATE " << (hilite ? hilite_none : "")
|
|
|
|
|
<< "'" << ast.collator->getLocale() << "'";
|
|
|
|
|
}
|
2011-09-04 05:14:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-03-10 18:01:26 +00:00
|
|
|
|
void formatAST(const ASTAlterQuery & ast, std::ostream & s, size_t indent, bool hilite, bool one_line, bool need_parens)
|
2013-08-07 13:07:42 +00:00
|
|
|
|
{
|
|
|
|
|
std::string nl_or_nothing = one_line ? "" : "\n";
|
|
|
|
|
|
|
|
|
|
std::string indent_str = one_line ? "" : std::string(4 * indent, ' ');
|
|
|
|
|
std::string nl_or_ws = one_line ? " " : "\n";
|
|
|
|
|
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << indent_str << "ALTER TABLE " << (hilite ? hilite_none : "");
|
|
|
|
|
|
|
|
|
|
if (!ast.table.empty())
|
|
|
|
|
{
|
|
|
|
|
if (!ast.database.empty())
|
|
|
|
|
{
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << indent_str << ast.database << (hilite ? hilite_none : "");
|
|
|
|
|
s << ".";
|
|
|
|
|
}
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << indent_str << ast.table << (hilite ? hilite_none : "");
|
|
|
|
|
}
|
|
|
|
|
s << nl_or_ws;
|
|
|
|
|
|
|
|
|
|
for( std::size_t i = 0; i < ast.parameters.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
const ASTAlterQuery::Parameters &p = ast.parameters[i];
|
|
|
|
|
|
|
|
|
|
if (p.type == ASTAlterQuery::ADD)
|
|
|
|
|
{
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << indent_str << "ADD COLUMN " << (hilite ? hilite_none : "");
|
|
|
|
|
formatAST(*p.name_type, s, indent, hilite, true);
|
|
|
|
|
|
|
|
|
|
/// AFTER
|
|
|
|
|
if (p.column)
|
|
|
|
|
{
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << indent_str << " AFTER " << (hilite ? hilite_none : "");
|
|
|
|
|
formatAST(*p.column, s, indent, hilite, one_line);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (p.type == ASTAlterQuery::DROP)
|
|
|
|
|
{
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << indent_str << "DROP COLUMN " << (hilite ? hilite_none : "");
|
|
|
|
|
formatAST(*p.column, s, indent, hilite, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string comma = (i < (ast.parameters.size() -1) ) ? "," : "";
|
|
|
|
|
s << (hilite ? hilite_keyword : "") << indent_str << comma << (hilite ? hilite_none : "");
|
|
|
|
|
|
|
|
|
|
s << nl_or_ws;
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-02-26 19:50:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
String formatColumnsForCreateQuery(NamesAndTypesList & columns)
|
|
|
|
|
{
|
|
|
|
|
std::string res;
|
|
|
|
|
res += "(";
|
|
|
|
|
for (NamesAndTypesList::iterator it = columns.begin(); it != columns.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
if (it != columns.begin())
|
|
|
|
|
res += ", ";
|
|
|
|
|
res += backQuoteIfNeed(it->first);
|
|
|
|
|
res += " ";
|
|
|
|
|
res += it->second->getName();
|
|
|
|
|
}
|
|
|
|
|
res += ")";
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-28 13:44:42 +00:00
|
|
|
|
}
|
|
|
|
|
|