Skip to content

Commit

Permalink
Quote potentially ambiguous symbol references in EXPLAIN
Browse files Browse the repository at this point in the history
  • Loading branch information
findepi committed Mar 25, 2024
1 parent f6bc957 commit 3901cea
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
*/
package io.trino.sql.ir;

import com.google.common.base.CharMatcher;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import io.trino.sql.planner.Symbol;
Expand All @@ -26,6 +27,13 @@

public final class ExpressionFormatter
{
private static final CharMatcher UNAMBIGUOUS_REFERENCE_NAME_CHARACTERS =
CharMatcher.inRange('a', 'z')
.or(CharMatcher.inRange('A', 'Z'))
.or(CharMatcher.inRange('0', '9'))
.or(CharMatcher.anyOf("_$"))
.precomputed();

private ExpressionFormatter() {}

public static String formatExpression(Expression expression)
Expand Down Expand Up @@ -105,7 +113,11 @@ protected String visitReference(Reference node, Void context)
if (symbolReferenceFormatter.isPresent()) {
return symbolReferenceFormatter.get().apply(node);
}
return node.name();
String name = node.name();
if (UNAMBIGUOUS_REFERENCE_NAME_CHARACTERS.matchesAllOf(name)) {
return name;
}
return "\"" + name.replace("\"", "\"\"") + "\"";
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.trino.sql.ir;

import org.junit.jupiter.api.Test;

import static io.trino.spi.type.BigintType.BIGINT;
import static org.assertj.core.api.Assertions.assertThat;

public class TestExpressionFormatter
{
@Test
public void testReference()
{
assertFormattedExpression(
new Reference(BIGINT, "abc"),
"abc");
assertFormattedExpression(
new Reference(BIGINT, "with a space"),
"\"with a space\"");
assertFormattedExpression(
new Reference(BIGINT, "with \" quote, $ dollar and ' apostrophe"),
"\"with \"\" quote, $ dollar and ' apostrophe\"");
}

private void assertFormattedExpression(Expression expression, String expected)
{
assertThat(ExpressionFormatter.formatExpression(expression)).as("formatted expression")
.isEqualTo(expected);
}
}

0 comments on commit 3901cea

Please sign in to comment.