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

BNF auto-completion failed with unquoted identifiers.

上级 26d0db53
......@@ -20,7 +20,10 @@ Change Log
<h1>Change Log</h1>
<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>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.
......
......@@ -57,6 +57,17 @@ public class 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) {
Rule rule = new RuleFixed(fixedType);
addRule(name, "Fixed", rule);
......
......@@ -44,6 +44,7 @@ public class RuleFixed implements Rule {
sentence.stopIfRequired();
String query = sentence.getQuery();
String s = query;
boolean removeTrailingSpaces = false;
switch(type) {
case YMD:
while (s.length() > 0 && "0123456789-".indexOf(s.charAt(0)) >= 0) {
......@@ -52,6 +53,8 @@ public class RuleFixed implements Rule {
if (s.length() == 0) {
sentence.add("2006-01-01", "1", Sentence.KEYWORD);
}
// needed for timestamps
removeTrailingSpaces = true;
break;
case HMS:
while (s.length() > 0 && "0123456789:".indexOf(s.charAt(0)) >= 0) {
......@@ -68,6 +71,7 @@ public class RuleFixed implements Rule {
if (s.length() == 0) {
sentence.add("nanoseconds", "0", Sentence.KEYWORD);
}
removeTrailingSpaces = true;
break;
case ANY_EXCEPT_SINGLE_QUOTE:
while (true) {
......@@ -135,6 +139,7 @@ public class RuleFixed implements Rule {
} else if (s.length() == 0) {
sentence.add("||", "||", Sentence.KEYWORD);
}
removeTrailingSpaces = true;
break;
case AZ_UNDERSCORE:
if (s.length() > 0 &&
......@@ -170,6 +175,7 @@ public class RuleFixed implements Rule {
} else if (s.charAt(0) == '[') {
s = s.substring(1);
}
removeTrailingSpaces = true;
break;
case CLOSE_BRACKET:
if (s.length() == 0) {
......@@ -177,6 +183,7 @@ public class RuleFixed implements Rule {
} else if (s.charAt(0) == ']') {
s = s.substring(1);
}
removeTrailingSpaces = true;
break;
// no autocomplete support for comments
// (comments are not reachable in the bnf tree)
......@@ -186,8 +193,14 @@ public class RuleFixed implements Rule {
throw new AssertionError("type="+type);
}
if (!s.equals(query)) {
while (Bnf.startWithSpace(s)) {
s = s.substring(1);
// 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)) {
s = s.substring(1);
}
}
sentence.setQuery(s);
return true;
......
......@@ -36,6 +36,11 @@ public class RuleRepeat implements Rule {
while (rule.autoComplete(sentence)) {
// nothing to do
}
String s = sentence.getQuery();
while (Bnf.startWithSpace(s)) {
s = s.substring(1);
}
sentence.setQuery(s);
return true;
}
......
......@@ -711,6 +711,7 @@ value
| ?[ int ]
| NEXT VALUE FOR sequenceName
| function
| procedure
| { - | + } term
| ( expression )
| select
......
......@@ -29,6 +29,7 @@ public class BnfRandom implements BnfVisitor {
public BnfRandom() throws Exception {
Bnf config = Bnf.getInstance(null);
config.addAlias("procedure", "@func@");
config.linkStatements();
ArrayList<RuleHead> all = config.getStatements();
......
......@@ -140,11 +140,31 @@ public class TestBnf extends TestBase {
DbContextRule(dbContents, DbContextRule.PROCEDURE));
bnf.linkStatements();
// 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"));
// Test built-in function
tokens = bnf.getNextTokenList("SELECT LEAS");
// Test identifiers are working
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"));
// Test parameters
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论