Skip to content

Commit 7eee7a6

Browse files
authored
pg_query_normalize: Fix handling of special strings in DefElem (#325)
Fixes #254.
1 parent b2217bf commit 7eee7a6

File tree

3 files changed

+15
-1
lines changed

3 files changed

+15
-1
lines changed

src/pg_query_normalize.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,10 +336,20 @@ static void RecordConstLocation(pgssConstLocations *jstate, int location)
336336
}
337337
}
338338

339+
static bool is_string_delimiter(char c)
340+
{
341+
return c == '\'' || c == '$';
342+
}
343+
344+
static bool is_special_string_start(char c)
345+
{
346+
return c == 'b' || c == 'B' || c == 'x' || c == 'X' || c == 'n' || c == 'N' || c == 'e' || c == 'E';
347+
}
348+
339349
static void record_defelem_arg_location(pgssConstLocations *jstate, int location)
340350
{
341351
for (int i = location; i < jstate->query_len; i++) {
342-
if (jstate->query[i] == '\'' || jstate->query[i] == '$') {
352+
if (is_string_delimiter(jstate->query[i]) || (i + 1 < jstate->query_len && is_special_string_start(jstate->query[i]) && is_string_delimiter(jstate->query[i + 1]))) {
343353
RecordConstLocation(jstate, i);
344354
break;
345355
}

test/normalize_tests.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ const char* tests[] = {
4040
"ALTER USER MAPPING FOR bob SERVER foo OPTIONS (SET password $1)",
4141
"MERGE into measurement m USING new_measurement nm ON (m.city_id = nm.city_id and m.logdate=nm.logdate) WHEN MATCHED AND nm.peaktemp IS NULL THEN DELETE WHEN MATCHED THEN UPDATE SET peaktemp = greatest(m.peaktemp, nm.peaktemp), unitsales = m.unitsales + coalesce(nm.unitsales, 0) WHEN NOT MATCHED THEN INSERT (city_id, logdate, peaktemp, unitsales) VALUES (city_id, logdate, peaktemp, unitsales)",
4242
"MERGE into measurement m USING new_measurement nm ON (m.city_id = nm.city_id and m.logdate=nm.logdate) WHEN MATCHED AND nm.peaktemp IS NULL THEN DELETE WHEN MATCHED THEN UPDATE SET peaktemp = greatest(m.peaktemp, nm.peaktemp), unitsales = m.unitsales + coalesce(nm.unitsales, $1) WHEN NOT MATCHED THEN INSERT (city_id, logdate, peaktemp, unitsales) VALUES (city_id, logdate, peaktemp, unitsales)",
43+
"DO language E'plpgsql' 'BEGIN PERFORM 1; END'",
44+
"DO language $1 $2",
4345
// These below are as expected, though questionable if upstream shouldn't be
4446
// fixed as this could bloat pg_stat_statements
4547
"DECLARE cursor_b CURSOR FOR SELECT * FROM x WHERE id = 123",

test/normalize_utility_tests.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ const char* tests[] = {
4141
"ALTER USER MAPPING FOR bob SERVER foo OPTIONS (SET password $1)",
4242
"MERGE into measurement m USING new_measurement nm ON (m.city_id = nm.city_id and m.logdate=nm.logdate) WHEN MATCHED AND nm.peaktemp IS NULL THEN DELETE WHEN MATCHED THEN UPDATE SET peaktemp = greatest(m.peaktemp, nm.peaktemp), unitsales = m.unitsales + coalesce(nm.unitsales, 0) WHEN NOT MATCHED THEN INSERT (city_id, logdate, peaktemp, unitsales) VALUES (city_id, logdate, peaktemp, unitsales)",
4343
"MERGE into measurement m USING new_measurement nm ON (m.city_id = nm.city_id and m.logdate=nm.logdate) WHEN MATCHED AND nm.peaktemp IS NULL THEN DELETE WHEN MATCHED THEN UPDATE SET peaktemp = greatest(m.peaktemp, nm.peaktemp), unitsales = m.unitsales + coalesce(nm.unitsales, 0) WHEN NOT MATCHED THEN INSERT (city_id, logdate, peaktemp, unitsales) VALUES (city_id, logdate, peaktemp, unitsales)",
44+
"DO language E'plpgsql' 'BEGIN PERFORM 1; END'",
45+
"DO language E'plpgsql' 'BEGIN PERFORM 1; END'",
4446
// These below are as expected, though questionable if upstream shouldn't be
4547
// fixed as this could bloat pg_stat_statements
4648
"DECLARE cursor_b CURSOR FOR SELECT * FROM x WHERE id = 123",

0 commit comments

Comments
 (0)