From b28ee4f93bea16fea8ab64421ba1d5c744ab7939 Mon Sep 17 00:00:00 2001 From: Owner Date: Wed, 31 May 2017 18:20:43 -0400 Subject: [PATCH] Issue#479 Made column names optional --- h2/src/main/org/h2/command/Parser.java | 91 ++++--------------- .../org/h2/command/dml/RecursiveQuery.java | 22 ++++- .../db/TestGeneralCommonTableQueries.java | 2 - 3 files changed, 40 insertions(+), 75 deletions(-) diff --git a/h2/src/main/org/h2/command/Parser.java b/h2/src/main/org/h2/command/Parser.java index 1feb5cd232..644e67ecfc 100644 --- a/h2/src/main/org/h2/command/Parser.java +++ b/h2/src/main/org/h2/command/Parser.java @@ -17,6 +17,7 @@ import java.util.Comparator; import java.util.HashSet; import java.util.LinkedHashSet; +import java.util.List; import org.h2.api.ErrorCode; import org.h2.api.Trigger; @@ -4854,70 +4855,6 @@ private CreateFunctionAlias parseCreateFunctionAlias(boolean force) { return command; } - private Query parseWithOriginal() { - readIf("RECURSIVE"); - String tempViewName = readIdentifierWithSchema(); - Schema schema = getSchema(); - Table recursiveTable; - read("("); - ArrayList 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 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() { readIf("RECURSIVE"); @@ -4925,11 +4862,14 @@ private Query parseWith() { String tempViewName = readIdentifierWithSchema(); Schema schema = getSchema(); Table recursiveTable; - read("("); ArrayList columns = New.arrayList(); - String[] cols = parseColumnList(); - for (String c : cols) { - columns.add(new Column(c, Value.STRING)); + String[] cols = null; + // column names are now optiona; + if(readIf("(")){ + cols = parseColumnList(); + for (String c : cols) { + columns.add(new Column(c, Value.STRING)); + } } Table old = session.findLocalTempTable(tempViewName); if (old != null) { @@ -4956,7 +4896,7 @@ private Query parseWith() { recursiveTable = schema.createTable(data); session.addLocalTempTable(recursiveTable); String querySQL; - Column[] columnTemplates = new Column[cols.length]; + List columnTemplateList = new ArrayList(); try { read("AS"); read("("); @@ -4965,15 +4905,22 @@ private Query parseWith() { withQuery.prepare(); querySQL = StringUtils.cache(withQuery.getPlanSQL()); ArrayList withExpressions = withQuery.getExpressions(); - for (int i = 0; i < cols.length; ++i) { - columnTemplates[i] = new Column(cols[i], withExpressions.get(i).getType()); + for (int i = 0; i < withExpressions.size(); ++i) { + String columnName = cols !=null ? cols[i] : withExpressions.get(i).getColumnName(); + columnTemplateList.add(new Column(columnName, withExpressions.get(i).getType())); } } finally { session.removeLocalTempTable(recursiveTable); } 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, - parameters, columnTemplates, session, RecursiveQuery.isRecursive(tempViewName,querySQL)); + parameters, columnTemplateList.toArray(new Column[0]), session, + isRecursive); view.setTableExpression(true); view.setTemporary(true); session.addLocalTempTable(view); diff --git a/h2/src/main/org/h2/command/dml/RecursiveQuery.java b/h2/src/main/org/h2/command/dml/RecursiveQuery.java index b2d7ecb3a3..30b376310f 100755 --- a/h2/src/main/org/h2/command/dml/RecursiveQuery.java +++ b/h2/src/main/org/h2/command/dml/RecursiveQuery.java @@ -1,12 +1,32 @@ package org.h2.command.dml; +import java.util.regex.Matcher; import java.util.regex.Pattern; public class RecursiveQuery { // A query is recursive if it references it's own name in its definition 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; + } } diff --git a/h2/src/test/org/h2/test/db/TestGeneralCommonTableQueries.java b/h2/src/test/org/h2/test/db/TestGeneralCommonTableQueries.java index b94991b417..e71652c93a 100755 --- a/h2/src/test/org/h2/test/db/TestGeneralCommonTableQueries.java +++ b/h2/src/test/org/h2/test/db/TestGeneralCommonTableQueries.java @@ -47,8 +47,6 @@ public void test() throws Exception { testSimple(); } - - private void testSimple() throws Exception { deleteDb("commonTableExpressionQueries"); Connection conn = getConnection("commonTableExpressionQueries");