提交 94e79df5 authored 作者: Owner's avatar Owner

Issue#479 Ready for final fix to testCTE

上级 8ca2feb0
......@@ -76,7 +76,6 @@ import org.h2.command.dml.Insert;
import org.h2.command.dml.Merge;
import org.h2.command.dml.NoOperation;
import org.h2.command.dml.Query;
import org.h2.command.dml.RecursiveQueryHeuristic;
import org.h2.command.dml.Replace;
import org.h2.command.dml.RunScriptCommand;
import org.h2.command.dml.ScriptCommand;
......@@ -126,7 +125,6 @@ import org.h2.expression.Variable;
import org.h2.expression.Wildcard;
import org.h2.index.Index;
import org.h2.message.DbException;
import org.h2.message.DbNotRecursiveException;
import org.h2.result.SortOrder;
import org.h2.schema.Schema;
import org.h2.schema.Sequence;
......@@ -4862,7 +4860,7 @@ public class Parser {
List<TableView> viewsCreated = new ArrayList<TableView>();
readIf("RECURSIVE");
do{
viewsCreated.add(parseSingleCommonTableExression());
viewsCreated.add(parseSingleCommonTableExpression());
} while(readIf(","));
Query q = parseSelectUnion();
......@@ -4870,7 +4868,7 @@ public class Parser {
return q;
}
private TableView parseSingleCommonTableExression() {
private TableView parseSingleCommonTableExpression() {
String tempViewName = readIdentifierWithSchema();
Schema schema = getSchema();
Table recursiveTable;
......@@ -4931,34 +4929,15 @@ public class Parser {
session.removeLocalTempTable(recursiveTable);
}
int id = database.allocateObjectId();
boolean isRecursive = true;//RecursiveQueryHeuristic.isRecursive(tempViewName,querySQL);
boolean isRecursive = true;
TableView view = null;
do{
try{
view = new TableView(schema, id, tempViewName, querySQL,
parameters, columnTemplateList.toArray(new Column[0]), session,
isRecursive);
}catch(DbNotRecursiveException e){
if(isRecursive==false){
throw e;
}
isRecursive = false;
view=null;
System.out.println("repeat new table by exeception");
continue;
}
HashSet<DbObject> subDependencies = new HashSet<DbObject>();
view.addStrictSubDependencies(subDependencies,false);
System.out.println("tempViewName="+tempViewName);
System.out.println("subDependencies="+subDependencies);
System.out.println("isRecursiveQueryDetected="+view.isRecursiveQueryDetected());
boolean isRecursiveByDeepAnalysis = subDependencies.contains(recursiveTable);
System.out.println("isRecursiveByDeepAnalysis="+isRecursiveByDeepAnalysis);
if(view.isRecursiveQueryDetected()!=isRecursive){
isRecursive = view.isRecursiveQueryDetected();
view = null;
System.out.println("repeat new table creation by view.isRecursiveQueryDetected()");
continue;
}
......
package org.h2.command.dml;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RecursiveQueryHeuristic {
// A query is recursive if it references it's own name in its definition
public static boolean isRecursive(String tempViewName, String querySQL) {
boolean foundAny = RecursiveQueryHeuristic.foundAny(tempViewName,querySQL);
//System.out.println("foundAny="+foundAny);
return foundAny;
}
private static boolean foundAny(String tempViewName, String querySQL){
// ?i is case insensitive
// ?m is multi-line search
// ?d is Unix line endings
Pattern p = Pattern.compile("(?i)(?m)(?d)\\b("+tempViewName+")\\b");
Matcher m = p.matcher(querySQL);
while (m.find()) {
return true;
}
return false;
}
}
......@@ -19,7 +19,6 @@ import org.h2.engine.Session;
import org.h2.expression.Comparison;
import org.h2.expression.Parameter;
import org.h2.message.DbException;
import org.h2.message.DbNotRecursiveException;
import org.h2.result.LocalResult;
import org.h2.result.ResultInterface;
import org.h2.result.Row;
......@@ -196,12 +195,12 @@ public class ViewIndex extends BaseIndex implements SpatialIndex {
query.setNeverLazy(true);
}
if (!query.isUnion()) {
throw DbNotRecursiveException.get(ErrorCode.SYNTAX_ERROR_2,
throw DbException.get(ErrorCode.SYNTAX_ERROR_2,
"recursive queries without UNION ALL");
}
SelectUnion union = (SelectUnion) query;
if (union.getUnionType() != SelectUnion.UNION_ALL) {
throw DbNotRecursiveException.get(ErrorCode.SYNTAX_ERROR_2,
throw DbException.get(ErrorCode.SYNTAX_ERROR_2,
"recursive queries without UNION ALL");
}
Query left = union.getLeft();
......
......@@ -70,11 +70,11 @@ public class DbException extends RuntimeException {
}
}
protected DbException(SQLException e) {
private DbException(SQLException e) {
super(e.getMessage(), e);
}
protected static String translate(String key, String... params) {
private static String translate(String key, String... params) {
String message = null;
if (MESSAGES != null) {
// Tomcat sets final static fields to null sometimes
......
package org.h2.message;
import java.sql.SQLException;
import org.h2.api.ErrorCode;
import org.h2.jdbc.JdbcSQLException;
public class DbNotRecursiveException extends DbException {
private static final long serialVersionUID = -5941745175474148318L;
public static DbNotRecursiveException get(int errorCode, String p1) {
return get(errorCode, new String[] { p1 });
}
public static DbNotRecursiveException get(int errorCode, String... params) {
return new DbNotRecursiveException(getJdbcSQLException(errorCode, null, params));
}
private static JdbcSQLException getJdbcSQLException(int errorCode,
Throwable cause, String... params) {
String sqlstate = ErrorCode.getState(errorCode);
String message = translate(sqlstate, params);
return new JdbcSQLException(message, null, sqlstate, errorCode, cause, null);
}
private DbNotRecursiveException(SQLException e) {
super(e);
}
}
......@@ -145,7 +145,6 @@ public class RangeTable extends Table {
@Override
public TableType getTableType() {
return TableType.SYSTEM_TABLE;
//throw DbException.throwInternalError(toString());
}
@Override
......
......@@ -352,22 +352,11 @@ public abstract class Table extends SchemaObjectBase {
}
/**
* Add all objects that this table depends on to the hash set, including this object.
* Add all objects that this table depends on to the hash set.
*
* @param dependencies the current set of dependencies
*/
public void addDependencies(HashSet<DbObject> dependencies) {
addStrictSubDependencies(dependencies,false);
dependencies.add(this);
}
/**
* Add all objects that this table depends on to the hash set, excluding
* this object (unless it is has recursive references).
*
* @param dependencies the current set of dependencies
*/
public void addStrictSubDependencies(HashSet<DbObject> dependencies, boolean visitColumnTables) {
if (dependencies.contains(this)) {
// avoid endless recursion
return;
......@@ -381,15 +370,13 @@ public abstract class Table extends SchemaObjectBase {
dependencies);
for (Column col : columns) {
col.isEverything(visitor);
if(visitColumnTables && col.getTable()!=null){
dependencies.add(col.getTable());
}
}
if (constraints != null) {
for (Constraint c : constraints) {
c.isEverything(visitor);
}
}
dependencies.add(this);
}
@Override
......
......@@ -8,9 +8,7 @@ package org.h2.table;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import org.h2.api.ErrorCode;
import org.h2.command.Prepared;
import org.h2.command.dml.Query;
......@@ -210,6 +208,8 @@ public class TableView extends Table {
// if it can't be compiled, then it's a 'zero column table'
// this avoids problems when creating the view when opening the
// database
// if it can not be compiled - it could also be a recursive common table expression query
if(isRecursiveQueryExceptionDetected(createException)){
this.isRecursiveQueryDetected = true;
}
......@@ -674,19 +674,17 @@ public class TableView extends Table {
}
/**
* Get a list of the tables used by this query (for recursion detection)
* @return
* If query recursion is detected (for recursion detection)
* @return is Recursive Query Flag Set
*/
public List<Table> getTables(){
return tables;
}
public boolean isRecursiveQueryDetected(){
return isRecursiveQueryDetected;
}
/**
* If query an exception indicates query recursion
* @return is Recursive Query Exception Detected
*/
private boolean isRecursiveQueryExceptionDetected(DbException exception){
if (exception==null){
return false;
......
......@@ -51,9 +51,7 @@ public class TestGeneralCommonTableQueries extends TestBase {
* @param a ignored
*/
public static void main(String... a) throws Exception {
System.out.println("Testing starting");
TestBase.createCaller().init().test();
System.out.println("Testing done");
}
@Override
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论