提交 b28ee4f9 authored 作者: Owner's avatar Owner

Issue#479 Made column names optional

上级 9c0dfc7a
...@@ -17,6 +17,7 @@ import java.util.Collections; ...@@ -17,6 +17,7 @@ import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.api.Trigger; import org.h2.api.Trigger;
...@@ -4854,70 +4855,6 @@ public class Parser { ...@@ -4854,70 +4855,6 @@ public class Parser {
return command; return command;
} }
private Query parseWithOriginal() {
readIf("RECURSIVE");
String tempViewName = readIdentifierWithSchema();
Schema schema = getSchema();
Table recursiveTable;
read("(");
ArrayList<Column> columns = New.arrayList();
String[] cols = parseColumnList();
for (String c : cols) {
columns.add(new Column(c, Value.STRING));
}
Table old = session.findLocalTempTable(tempViewName);
if (old != null) {
if (!(old instanceof TableView)) {
throw DbException.get(ErrorCode.TABLE_OR_VIEW_ALREADY_EXISTS_1,
tempViewName);
}
TableView tv = (TableView) old;
if (!tv.isTableExpression()) {
throw DbException.get(ErrorCode.TABLE_OR_VIEW_ALREADY_EXISTS_1,
tempViewName);
}
session.removeLocalTempTable(old);
}
CreateTableData data = new CreateTableData();
data.id = database.allocateObjectId();
data.columns = columns;
data.tableName = tempViewName;
data.temporary = true;
data.persistData = true;
data.persistIndexes = false;
data.create = true;
data.session = session;
recursiveTable = schema.createTable(data);
session.addLocalTempTable(recursiveTable);
String querySQL;
Column[] columnTemplates = new Column[cols.length];
try {
read("AS");
read("(");
Query withQuery = parseSelect();
read(")");
withQuery.prepare();
querySQL = StringUtils.cache(withQuery.getPlanSQL());
ArrayList<Expression> withExpressions = withQuery.getExpressions();
for (int i = 0; i < cols.length; ++i) {
columnTemplates[i] = new Column(cols[i], withExpressions.get(i).getType());
}
} finally {
session.removeLocalTempTable(recursiveTable);
}
int id = database.allocateObjectId();
TableView view = new TableView(schema, id, tempViewName, querySQL,
parameters, columnTemplates, session, true);
view.setTableExpression(true);
view.setTemporary(true);
session.addLocalTempTable(view);
view.setOnCommitDrop(true);
Query q = parseSelectUnion();
q.setPrepareAlways(true);
return q;
}
// SBM THis is where we work !
private Query parseWith() { private Query parseWith() {
readIf("RECURSIVE"); readIf("RECURSIVE");
...@@ -4925,11 +4862,14 @@ public class Parser { ...@@ -4925,11 +4862,14 @@ public class Parser {
String tempViewName = readIdentifierWithSchema(); String tempViewName = readIdentifierWithSchema();
Schema schema = getSchema(); Schema schema = getSchema();
Table recursiveTable; Table recursiveTable;
read("(");
ArrayList<Column> columns = New.arrayList(); ArrayList<Column> columns = New.arrayList();
String[] cols = parseColumnList(); String[] cols = null;
for (String c : cols) { // column names are now optiona;
columns.add(new Column(c, Value.STRING)); if(readIf("(")){
cols = parseColumnList();
for (String c : cols) {
columns.add(new Column(c, Value.STRING));
}
} }
Table old = session.findLocalTempTable(tempViewName); Table old = session.findLocalTempTable(tempViewName);
if (old != null) { if (old != null) {
...@@ -4956,7 +4896,7 @@ public class Parser { ...@@ -4956,7 +4896,7 @@ public class Parser {
recursiveTable = schema.createTable(data); recursiveTable = schema.createTable(data);
session.addLocalTempTable(recursiveTable); session.addLocalTempTable(recursiveTable);
String querySQL; String querySQL;
Column[] columnTemplates = new Column[cols.length]; List<Column> columnTemplateList = new ArrayList<Column>();
try { try {
read("AS"); read("AS");
read("("); read("(");
...@@ -4965,15 +4905,22 @@ public class Parser { ...@@ -4965,15 +4905,22 @@ public class Parser {
withQuery.prepare(); withQuery.prepare();
querySQL = StringUtils.cache(withQuery.getPlanSQL()); querySQL = StringUtils.cache(withQuery.getPlanSQL());
ArrayList<Expression> withExpressions = withQuery.getExpressions(); ArrayList<Expression> withExpressions = withQuery.getExpressions();
for (int i = 0; i < cols.length; ++i) { for (int i = 0; i < withExpressions.size(); ++i) {
columnTemplates[i] = new Column(cols[i], withExpressions.get(i).getType()); String columnName = cols !=null ? cols[i] : withExpressions.get(i).getColumnName();
columnTemplateList.add(new Column(columnName, withExpressions.get(i).getType()));
} }
} finally { } finally {
session.removeLocalTempTable(recursiveTable); session.removeLocalTempTable(recursiveTable);
} }
int id = database.allocateObjectId(); int id = database.allocateObjectId();
boolean isRecursive = RecursiveQuery.isRecursive(tempViewName,querySQL);
System.out.println("tempViewName=>"+tempViewName+"<");
System.out.println("columnTemplateList="+columnTemplateList);
System.out.println("isRecursive="+isRecursive);
System.out.println("querySQL="+querySQL);
TableView view = new TableView(schema, id, tempViewName, querySQL, TableView view = new TableView(schema, id, tempViewName, querySQL,
parameters, columnTemplates, session, RecursiveQuery.isRecursive(tempViewName,querySQL)); parameters, columnTemplateList.toArray(new Column[0]), session,
isRecursive);
view.setTableExpression(true); view.setTableExpression(true);
view.setTemporary(true); view.setTemporary(true);
session.addLocalTempTable(view); session.addLocalTempTable(view);
......
package org.h2.command.dml; package org.h2.command.dml;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class RecursiveQuery { public class RecursiveQuery {
// A query is recursive if it references it's own name in its definition // A query is recursive if it references it's own name in its definition
public static boolean isRecursive(String tempViewName, String querySQL) { public static boolean isRecursive(String tempViewName, String querySQL) {
return Pattern.matches("\\b"+tempViewName+"\\b",querySQL); // ?i is case insensitive
// ?m is multi-line search
// ?d is Unix line endings
String pattern = "(?i)(?m)(?d).*\\b("+tempViewName+")\\b";
System.out.println("pattern="+pattern);
boolean stringContains = querySQL.contains(tempViewName);
System.out.println("stringContains="+stringContains);
boolean foundAny = RecursiveQuery.foundAny(tempViewName,querySQL);
System.out.println("foundAny="+foundAny);
boolean patternMatch = Pattern.matches(pattern,querySQL);
System.out.println("patternMatch="+patternMatch);
return patternMatch||stringContains|| foundAny;
} }
private static boolean foundAny(String tempViewName, String querySQL){
Pattern p = Pattern.compile("(?i)(?m)(?d)\\b("+tempViewName+")\\b");
Matcher m = p.matcher(querySQL);
while (m.find()) {
return true;
}
return false;
}
} }
...@@ -47,8 +47,6 @@ public class TestGeneralCommonTableQueries extends TestBase { ...@@ -47,8 +47,6 @@ public class TestGeneralCommonTableQueries extends TestBase {
testSimple(); testSimple();
} }
private void testSimple() throws Exception { private void testSimple() throws Exception {
deleteDb("commonTableExpressionQueries"); deleteDb("commonTableExpressionQueries");
Connection conn = getConnection("commonTableExpressionQueries"); Connection conn = getConnection("commonTableExpressionQueries");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论