提交 bf51efce authored 作者: Thomas Mueller's avatar Thomas Mueller

BNF auto-completion failed with unquoted identifiers.

上级 26d0db53
...@@ -20,7 +20,10 @@ Change Log ...@@ -20,7 +20,10 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>Oracle compatibility: empty strings were not converted to NULL when using prepared statements. <ul>
<li>BNF auto-completion failed with unquoted identifiers.
</li>
<li>Oracle compatibility: empty strings were not converted to NULL when using prepared statements.
</li><li>PostgreSQL compatibility: new syntax "create index ... using ...". </li><li>PostgreSQL compatibility: new syntax "create index ... using ...".
</li><li>There was a bug in DataType.convertToValue when reading a ResultSet from a ResultSet. </li><li>There was a bug in DataType.convertToValue when reading a ResultSet from a ResultSet.
</li><li>Pull request #116: Improved concurrency in the trace system. </li><li>Pull request #116: Improved concurrency in the trace system.
......
...@@ -57,6 +57,17 @@ public class Bnf { ...@@ -57,6 +57,17 @@ public class Bnf {
return bnf; return bnf;
} }
/**
* Add an alias for a rule.
*
* @param name for example "procedure"
* @param replacement for example "@func@"
*/
public void addAlias(String name, String replacement) {
RuleHead head = ruleMap.get(replacement);
ruleMap.put(name, head);
}
private void addFixedRule(String name, int fixedType) { private void addFixedRule(String name, int fixedType) {
Rule rule = new RuleFixed(fixedType); Rule rule = new RuleFixed(fixedType);
addRule(name, "Fixed", rule); addRule(name, "Fixed", rule);
......
...@@ -44,6 +44,7 @@ public class RuleFixed implements Rule { ...@@ -44,6 +44,7 @@ public class RuleFixed implements Rule {
sentence.stopIfRequired(); sentence.stopIfRequired();
String query = sentence.getQuery(); String query = sentence.getQuery();
String s = query; String s = query;
boolean removeTrailingSpaces = false;
switch(type) { switch(type) {
case YMD: case YMD:
while (s.length() > 0 && "0123456789-".indexOf(s.charAt(0)) >= 0) { while (s.length() > 0 && "0123456789-".indexOf(s.charAt(0)) >= 0) {
...@@ -52,6 +53,8 @@ public class RuleFixed implements Rule { ...@@ -52,6 +53,8 @@ public class RuleFixed implements Rule {
if (s.length() == 0) { if (s.length() == 0) {
sentence.add("2006-01-01", "1", Sentence.KEYWORD); sentence.add("2006-01-01", "1", Sentence.KEYWORD);
} }
// needed for timestamps
removeTrailingSpaces = true;
break; break;
case HMS: case HMS:
while (s.length() > 0 && "0123456789:".indexOf(s.charAt(0)) >= 0) { while (s.length() > 0 && "0123456789:".indexOf(s.charAt(0)) >= 0) {
...@@ -68,6 +71,7 @@ public class RuleFixed implements Rule { ...@@ -68,6 +71,7 @@ public class RuleFixed implements Rule {
if (s.length() == 0) { if (s.length() == 0) {
sentence.add("nanoseconds", "0", Sentence.KEYWORD); sentence.add("nanoseconds", "0", Sentence.KEYWORD);
} }
removeTrailingSpaces = true;
break; break;
case ANY_EXCEPT_SINGLE_QUOTE: case ANY_EXCEPT_SINGLE_QUOTE:
while (true) { while (true) {
...@@ -135,6 +139,7 @@ public class RuleFixed implements Rule { ...@@ -135,6 +139,7 @@ public class RuleFixed implements Rule {
} else if (s.length() == 0) { } else if (s.length() == 0) {
sentence.add("||", "||", Sentence.KEYWORD); sentence.add("||", "||", Sentence.KEYWORD);
} }
removeTrailingSpaces = true;
break; break;
case AZ_UNDERSCORE: case AZ_UNDERSCORE:
if (s.length() > 0 && if (s.length() > 0 &&
...@@ -170,6 +175,7 @@ public class RuleFixed implements Rule { ...@@ -170,6 +175,7 @@ public class RuleFixed implements Rule {
} else if (s.charAt(0) == '[') { } else if (s.charAt(0) == '[') {
s = s.substring(1); s = s.substring(1);
} }
removeTrailingSpaces = true;
break; break;
case CLOSE_BRACKET: case CLOSE_BRACKET:
if (s.length() == 0) { if (s.length() == 0) {
...@@ -177,6 +183,7 @@ public class RuleFixed implements Rule { ...@@ -177,6 +183,7 @@ public class RuleFixed implements Rule {
} else if (s.charAt(0) == ']') { } else if (s.charAt(0) == ']') {
s = s.substring(1); s = s.substring(1);
} }
removeTrailingSpaces = true;
break; break;
// no autocomplete support for comments // no autocomplete support for comments
// (comments are not reachable in the bnf tree) // (comments are not reachable in the bnf tree)
...@@ -186,9 +193,15 @@ public class RuleFixed implements Rule { ...@@ -186,9 +193,15 @@ public class RuleFixed implements Rule {
throw new AssertionError("type="+type); throw new AssertionError("type="+type);
} }
if (!s.equals(query)) { if (!s.equals(query)) {
// can not always remove spaces here, because a repeat
// rule for a-z would remove multiple words
// but we have to remove spaces after '||'
// and after ']'
if (removeTrailingSpaces) {
while (Bnf.startWithSpace(s)) { while (Bnf.startWithSpace(s)) {
s = s.substring(1); s = s.substring(1);
} }
}
sentence.setQuery(s); sentence.setQuery(s);
return true; return true;
} }
......
...@@ -36,6 +36,11 @@ public class RuleRepeat implements Rule { ...@@ -36,6 +36,11 @@ public class RuleRepeat implements Rule {
while (rule.autoComplete(sentence)) { while (rule.autoComplete(sentence)) {
// nothing to do // nothing to do
} }
String s = sentence.getQuery();
while (Bnf.startWithSpace(s)) {
s = s.substring(1);
}
sentence.setQuery(s);
return true; return true;
} }
......
...@@ -711,6 +711,7 @@ value ...@@ -711,6 +711,7 @@ value
| ?[ int ] | ?[ int ]
| NEXT VALUE FOR sequenceName | NEXT VALUE FOR sequenceName
| function | function
| procedure
| { - | + } term | { - | + } term
| ( expression ) | ( expression )
| select | select
......
...@@ -29,6 +29,7 @@ public class BnfRandom implements BnfVisitor { ...@@ -29,6 +29,7 @@ public class BnfRandom implements BnfVisitor {
public BnfRandom() throws Exception { public BnfRandom() throws Exception {
Bnf config = Bnf.getInstance(null); Bnf config = Bnf.getInstance(null);
config.addAlias("procedure", "@func@");
config.linkStatements(); config.linkStatements();
ArrayList<RuleHead> all = config.getStatements(); ArrayList<RuleHead> all = config.getStatements();
......
...@@ -140,11 +140,31 @@ public class TestBnf extends TestBase { ...@@ -140,11 +140,31 @@ public class TestBnf extends TestBase {
DbContextRule(dbContents, DbContextRule.PROCEDURE)); DbContextRule(dbContents, DbContextRule.PROCEDURE));
bnf.linkStatements(); bnf.linkStatements();
// Test partial // Test partial
Map<String, String> tokens = bnf.getNextTokenList("SELECT CUSTOM_PR"); Map<String, String> tokens;
tokens = bnf.getNextTokenList("SELECT CUSTOM_PR");
assertTrue(tokens.values().contains("INT")); assertTrue(tokens.values().contains("INT"));
// Test built-in function // Test identifiers are working
tokens = bnf.getNextTokenList("SELECT LEAS"); tokens = bnf.getNextTokenList("create table \"test\" as sel");
assertTrue(tokens.values().contains("ECT"));
tokens = bnf.getNextTokenList("create table test as sel");
assertTrue(tokens.values().contains("ECT"));
// Test || with and without spaces
tokens = bnf.getNextTokenList("select 1||f");
assertFalse(tokens.values().contains("ROM"));
tokens = bnf.getNextTokenList("select 1 || f");
assertFalse(tokens.values().contains("ROM"));
tokens = bnf.getNextTokenList("select 1 || 2 ");
assertTrue(tokens.values().contains("FROM"));
tokens = bnf.getNextTokenList("select 1||2");
assertTrue(tokens.values().contains("FROM"));
tokens = bnf.getNextTokenList("select 1 || 2");
assertTrue(tokens.values().contains("FROM"));
// Test keyword
tokens = bnf.getNextTokenList("SELECT LE" + "AS");
assertTrue(tokens.values().contains("T")); assertTrue(tokens.values().contains("T"));
// Test parameters // Test parameters
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论