Skip to content

Commit 53694e6

Browse files
authored
Merge pull request #469 from slabko/fix-locate-start-pos
Fix issues with the locate function call
2 parents 9f9bca8 + ea5e300 commit 53694e6

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

driver/escaping/escape_sequences.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,9 +234,19 @@ string processFunction(const StringView seq, Lexer & lex) {
234234
lex.Consume();
235235

236236
auto offset = processIdentOrFunction(seq, lex /*, false */);
237-
lex.Consume();
237+
if (offset.empty()) {
238+
offset = "1";
239+
} else {
240+
lex.Consume();
241+
}
238242

239-
result = "position(" + haystack + "," + needle + ")";
243+
// ClickHouse requires `start_pos` to be an unsigned integer,
244+
// whereas ODBC clients map it as a signed integer. This results in
245+
// a named parameter such as `{odbc_positional_:Int32}`, which does not
246+
// match the type required by `locate`. To avoid the illegal type argument
247+
// error, we cast the offset parameter to UInt64. The `accurateCast` function
248+
// ensures that the parameter value is never negative.
249+
result = "locate(" + needle + "," + haystack + ",accurateCast(" + offset + ",'UInt64'))";
240250

241251
return result;
242252

driver/test/escape_sequences_ut.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,21 @@ TEST(EscapeSequencesCase, DateTime) {
298298
}
299299

300300
TEST(EscapeSequencesCase, LOCATE) {
301-
ASSERT_EQ(replaceEscapeSequences("{fn LOCATE('Xsell',`dm_ExperimentsData`.`ProductLevel`,1)}"),
302-
"position(`dm_ExperimentsData`.`ProductLevel`,'Xsell')");
301+
ASSERT_EQ(replaceEscapeSequences(
302+
"SELECT {fn LOCATE('needle', `haystack`, 42)}"),
303+
"SELECT locate('needle',`haystack`,accurateCast(42,'UInt64'))");
304+
ASSERT_EQ(replaceEscapeSequences(
305+
"SELECT {fn LOCATE(?, `haystack`, 42)}"),
306+
"SELECT locate(?,`haystack`,accurateCast(42,'UInt64'))");
307+
ASSERT_EQ(replaceEscapeSequences(
308+
"SELECT {fn LOCATE('needle', `haystack`, ?)}"),
309+
"SELECT locate('needle',`haystack`,accurateCast(?,'UInt64'))");
310+
ASSERT_EQ(replaceEscapeSequences(
311+
"SELECT {fn LOCATE('needle', `haystack`)}"),
312+
"SELECT locate('needle',`haystack`,accurateCast(1,'UInt64'))");
313+
ASSERT_EQ(replaceEscapeSequences(
314+
"SELECT {fn LOCATE(?, `haystack`)}"),
315+
"SELECT locate(?,`haystack`,accurateCast(1,'UInt64'))");
303316
}
304317

305318
TEST(EscapeSequencesCase, LCASE) {

0 commit comments

Comments
 (0)