Address some usability issues with INTO OUTFILE usage.

This commit is contained in:
Manas Alekar 2023-06-13 01:18:36 -07:00
parent 9a3cea379f
commit bf69755ada
4 changed files with 29 additions and 0 deletions

View File

@ -568,6 +568,13 @@ try
CompressionMethod compression_method = chooseCompressionMethod(out_file, compression_method_string);
UInt64 compression_level = 3;
if (query_with_output->is_outfile_append && query_with_output->is_outfile_truncate)
{
throw Exception(
ErrorCodes::BAD_ARGUMENTS,
"Cannot use INTO OUTFILE with APPEND and TRUNCATE simultaneously.");
}
if (query_with_output->is_outfile_append && compression_method != CompressionMethod::None)
{
throw Exception(
@ -589,9 +596,22 @@ try
range.second);
}
std::error_code ec;
if (std::filesystem::is_regular_file(out_file, ec))
{
if (!query_with_output->is_outfile_append && !query_with_output->is_outfile_truncate)
{
throw Exception(
ErrorCodes::CANNOT_OPEN_FILE,
"File {} exists, consider using 'INTO OUTFILE ... APPEND' or 'INTO OUTFILE ... TRUNCATE' if appropriate.",
out_file);
}
}
auto flags = O_WRONLY | O_EXCL;
if (query_with_output->is_outfile_append)
flags |= O_APPEND;
else if (query_with_output->is_outfile_truncate)
flags |= O_TRUNC;
else
flags |= O_CREAT;

View File

@ -39,6 +39,8 @@ void ASTQueryWithOutput::formatImpl(const FormatSettings & s, FormatState & stat
s.ostr << (s.hilite ? hilite_keyword : "");
if (is_outfile_append)
s.ostr << " APPEND";
if (is_outfile_truncate)
s.ostr << " TRUNCATE";
if (is_into_outfile_with_stdout)
s.ostr << " AND STDOUT";
s.ostr << (s.hilite ? hilite_none : "");

View File

@ -17,6 +17,7 @@ public:
ASTPtr out_file;
bool is_into_outfile_with_stdout = false;
bool is_outfile_append = false;
bool is_outfile_truncate = false;
ASTPtr format;
ASTPtr settings_ast;
ASTPtr compression;

View File

@ -109,6 +109,12 @@ bool ParserQueryWithOutput::parseImpl(Pos & pos, ASTPtr & node, Expected & expec
query_with_output.is_outfile_append = true;
}
ParserKeyword s_truncate("TRUNCATE");
if (s_truncate.ignore(pos, expected))
{
query_with_output.is_outfile_truncate = true;
}
ParserKeyword s_stdout("AND STDOUT");
if (s_stdout.ignore(pos, expected))
{