Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
public class SQLUtils {
/**
* Escapes and quotes a string literal for use in SQL queries.
* ClickHouse honours backslash escape sequences inside single-quoted strings, so a backslash
* is escaped by doubling it before the single quotes are doubled. Without that, a literal
* backslash-t in the input would reach the server as a TAB, and a trailing backslash would
* escape the closing quote.
*
* @param str the string to be quoted, cannot be null
* @return the quoted and escaped string
Expand All @@ -15,12 +19,14 @@ public static String enquoteLiteral(String str) {
if (str == null) {
throw new IllegalArgumentException("Input string cannot be null");
}
return "'" + str.replace("'", "''") + "'";
return "'" + str.replace("\\", "\\\\").replace("'", "''") + "'";
}

/**
* Escapes and quotes an SQL identifier (e.g., table or column name) by enclosing it in double quotes.
* Any existing double quotes in the identifier are escaped by doubling them.
* Any existing double quotes in the identifier are escaped by doubling them, and backslashes are
* escaped by doubling them as well, since ClickHouse also honours backslash escapes inside
* double-quoted identifiers.
*
* @param identifier the identifier to be quoted, cannot be null
* @param quotesRequired if false, the identifier will only be quoted if it contains special characters
Expand All @@ -35,7 +41,7 @@ public static String enquoteIdentifier(String identifier, boolean quotesRequired
if (!quotesRequired && !needsQuoting(identifier)) {
return identifier;
}
return "\"" + identifier.replace("\"", "\"\"") + "\"";
return "\"" + identifier.replace("\\", "\\\\").replace("\"", "\"\"") + "\"";
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ public Object[][] enquoteLiteralTestData() {
{"O'Reilly", "'O''Reilly'"},
{"😊👍", "'😊👍'"},
{"", "''"},
{"single'quote'double''quote\"", "'single''quote''double''''quote\"'"}
{"single'quote'double''quote\"", "'single''quote''double''''quote\"'"},
// backslash is an escape character inside ClickHouse single-quoted strings
{"C:\\temp", "'C:\\\\temp'"},
{"ends with backslash\\", "'ends with backslash\\\\'"},
{"double\\\\backslash", "'double\\\\\\\\backslash'"},
{"quote and slash \\'", "'quote and slash \\\\'''"}
};
}

Expand All @@ -35,7 +40,11 @@ public Object[][] enquoteIdentifierTestData() {
{"1column", "\"1column\""},
{"column-with-hyphen", "\"column-with-hyphen\""},
{"😊👍", "\"😊👍\""},
{"", "\"\""}
{"", "\"\""},
// backslash is also an escape character inside double-quoted identifiers
{"col\\tname", "\"col\\\\tname\""},
{"ends with backslash\\", "\"ends with backslash\\\\\""},
{"quote\\\"and\\slash", "\"quote\\\\\"\"and\\\\slash\""}
};
}

Expand Down