Repository: calcite Updated Branches: refs/heads/master 76a8cfd18 -> c2ae9f0d5
[CALCITE-2479] SqlAdvisor: automatically quote identifiers that look like SQL keywords Project: http://git-wip-us.apache.org/repos/asf/calcite/repo Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/c2ae9f0d Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/c2ae9f0d Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/c2ae9f0d Branch: refs/heads/master Commit: c2ae9f0d5b518ea702b4000958b0460e8ef167e1 Parents: 67923a2 Author: Vladimir Sitnikov <sitnikov.vladi...@gmail.com> Authored: Sun Aug 19 18:48:16 2018 +0300 Committer: Vladimir Sitnikov <sitnikov.vladi...@gmail.com> Committed: Wed Sep 5 15:24:24 2018 +0300 ---------------------------------------------------------------------- .../apache/calcite/sql/advise/SqlAdvisor.java | 30 ++++++++++++++++++-- .../apache/calcite/sql/test/SqlAdvisorTest.java | 7 +++++ 2 files changed, 35 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/calcite/blob/c2ae9f0d/core/src/main/java/org/apache/calcite/sql/advise/SqlAdvisor.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/sql/advise/SqlAdvisor.java b/core/src/main/java/org/apache/calcite/sql/advise/SqlAdvisor.java index 2da1ca4..25949ab 100644 --- a/core/src/main/java/org/apache/calcite/sql/advise/SqlAdvisor.java +++ b/core/src/main/java/org/apache/calcite/sql/advise/SqlAdvisor.java @@ -47,6 +47,8 @@ import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Objects; +import java.util.Set; +import java.util.TreeSet; /** * An assistant which offers hints and corrections to a partially-formed SQL @@ -70,6 +72,10 @@ public class SqlAdvisor { private String prevWord; private Casing prevPreferredCasing; + // Reserved words cache + private Set<String> reservedWordsSet; + private List<String> reservedWordsList; + //~ Constructors ----------------------------------------------------------- /** @@ -244,7 +250,8 @@ public class SqlAdvisor { public String getReplacement(SqlMoniker hint, String word) { Casing preferredCasing = getPreferredCasing(word); - return getReplacement(hint, !word.isEmpty() && word.charAt(0) == quoteStart(), preferredCasing); + boolean quoted = !word.isEmpty() && word.charAt(0) == quoteStart(); + return getReplacement(hint, quoted, preferredCasing); } public String getReplacement(SqlMoniker hint, boolean quoted, Casing preferredCasing) { @@ -254,6 +261,10 @@ public class SqlAdvisor { // on quotedCasing/unquotedCasing quoted &= !isKeyword; + if (!quoted && !isKeyword && getReservedAndKeyWordsSet().contains(name)) { + quoted = true; + } + StringBuilder sb = new StringBuilder(name.length() + (quoted ? 2 : 0)); @@ -514,6 +525,19 @@ public class SqlAdvisor { * @return an of SQL reserved and keywords */ public List<String> getReservedAndKeyWords() { + ensureReservedAndKeyWords(); + return reservedWordsList; + } + + private Set<String> getReservedAndKeyWordsSet() { + ensureReservedAndKeyWords(); + return reservedWordsSet; + } + + private void ensureReservedAndKeyWords() { + if (reservedWordsSet != null) { + return; + } Collection<String> c = SqlAbstractParserImpl.getSql92ReservedWords(); List<String> l = Arrays.asList( @@ -521,7 +545,9 @@ public class SqlAdvisor { List<String> al = new ArrayList<String>(); al.addAll(c); al.addAll(l); - return al; + reservedWordsList = al; + reservedWordsSet = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); + reservedWordsSet.addAll(reservedWordsList); } /** http://git-wip-us.apache.org/repos/asf/calcite/blob/c2ae9f0d/core/src/test/java/org/apache/calcite/sql/test/SqlAdvisorTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/calcite/sql/test/SqlAdvisorTest.java b/core/src/test/java/org/apache/calcite/sql/test/SqlAdvisorTest.java index a2b0d4f..148d22e 100644 --- a/core/src/test/java/org/apache/calcite/sql/test/SqlAdvisorTest.java +++ b/core/src/test/java/org/apache/calcite/sql/test/SqlAdvisorTest.java @@ -1392,6 +1392,13 @@ public class SqlAdvisorTest extends SqlValidatorTestCase { ImmutableMap.of("COLUMN(isOne)", "isOne")); } + @Test @WithLex(Lex.JAVA) public void testAdviceExpression() { + String sql; + sql = "select s.`count`+s.co^ from (select 1 `count` from emp) s"; + assertComplete(sql, "COLUMN(count)\n", "co", + ImmutableMap.of("COLUMN(count)", "`count`")); + } + @Test @WithLex(Lex.JAVA) public void testAdviceEmptyFrom() { String sql; sql = "select * from^";