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

First round of investigations, column namer added, noticed duplicate tableView…

First round of investigations, column namer added, noticed duplicate tableView not being cleaned down correctly
上级 b311beca
...@@ -102,6 +102,7 @@ public class CommandContainer extends Command { ...@@ -102,6 +102,7 @@ public class CommandContainer extends Command {
int updateCount = prepared.update(); int updateCount = prepared.update();
prepared.trace(startTimeNanos, updateCount); prepared.trace(startTimeNanos, updateCount);
setProgress(DatabaseEventListener.STATE_STATEMENT_END); setProgress(DatabaseEventListener.STATE_STATEMENT_END);
System.out.println("CommandContainer.update.end");
return updateCount; return updateCount;
} }
...@@ -114,11 +115,13 @@ public class CommandContainer extends Command { ...@@ -114,11 +115,13 @@ public class CommandContainer extends Command {
ResultInterface result = prepared.query(maxrows); ResultInterface result = prepared.query(maxrows);
prepared.trace(startTimeNanos, result.isLazy() ? 0 : result.getRowCount()); prepared.trace(startTimeNanos, result.isLazy() ? 0 : result.getRowCount());
setProgress(DatabaseEventListener.STATE_STATEMENT_END); setProgress(DatabaseEventListener.STATE_STATEMENT_END);
System.out.println("CommandContainer.query.end");
return result; return result;
} }
@Override @Override
public void stop() { public void stop() {
System.out.println("CommandContainer.stop.stop");
super.stop(); super.stop();
// Clean up after the command was run in the session. // Clean up after the command was run in the session.
// Must restart query (and dependency construction) to reuse. // Must restart query (and dependency construction) to reuse.
...@@ -127,8 +130,12 @@ public class CommandContainer extends Command { ...@@ -127,8 +130,12 @@ public class CommandContainer extends Command {
// check if view was previously deleted as their name is set to // check if view was previously deleted as their name is set to
// null // null
if (view.getName() != null) { if (view.getName() != null) {
System.out.println("!!!!!!!removeLocalTempTable.worked="+view.getName());
session.removeLocalTempTable(view); session.removeLocalTempTable(view);
} }
else{
System.out.println("!!!!!!!removeLocalTempTable=(null local name)"+view.toString());
}
} }
} }
} }
......
...@@ -140,6 +140,7 @@ import org.h2.table.Table; ...@@ -140,6 +140,7 @@ import org.h2.table.Table;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.table.TableFilter.TableFilterVisitor; import org.h2.table.TableFilter.TableFilterVisitor;
import org.h2.table.TableView; import org.h2.table.TableView;
import org.h2.util.ColumnNamer;
import org.h2.util.MathUtils; import org.h2.util.MathUtils;
import org.h2.util.New; import org.h2.util.New;
import org.h2.util.StatementBuilder; import org.h2.util.StatementBuilder;
...@@ -4937,6 +4938,7 @@ public class Parser { ...@@ -4937,6 +4938,7 @@ public class Parser {
Query query = parseSelectUnion(); Query query = parseSelectUnion();
query.setPrepareAlways(true); query.setPrepareAlways(true);
query.setNeverLazy(true); query.setNeverLazy(true);
System.out.println("class="+query.getClass());
p = query; p = query;
} }
else if(readIf("INSERT")) { else if(readIf("INSERT")) {
...@@ -4988,7 +4990,7 @@ public class Parser { ...@@ -4988,7 +4990,7 @@ public class Parser {
if (readIf("(")) { if (readIf("(")) {
cols = parseColumnList(); cols = parseColumnList();
for (String c : cols) { for (String c : cols) {
// we dont really know the type of the column, so string will // we don't really know the type of the column, so string will
// have to do // have to do
columns.add(new Column(c, Value.STRING)); columns.add(new Column(c, Value.STRING));
} }
...@@ -5035,15 +5037,7 @@ public class Parser { ...@@ -5035,15 +5037,7 @@ public class Parser {
Expression columnExp = withExpressions.get(i); Expression columnExp = withExpressions.get(i);
// use the passed in column name if supplied, otherwise use alias (if used) otherwise use column name // use the passed in column name if supplied, otherwise use alias (if used) otherwise use column name
// derived from column expression // derived from column expression
String columnName; String columnName = ColumnNamer.getColumnName(columnExp,i,cols);
if (cols != null){
columnName = cols[i];
} else if (columnExp.getAlias()!=null){
columnName = columnExp.getAlias();
}
else{
columnName = columnExp.getColumnName();
}
columnTemplateList.add(new Column(columnName, columnTemplateList.add(new Column(columnName,
columnExp.getType())); columnExp.getType()));
} }
...@@ -5054,6 +5048,7 @@ public class Parser { ...@@ -5054,6 +5048,7 @@ public class Parser {
// No easy way to determine if this is a recursive query up front, so we just compile // No easy way to determine if this is a recursive query up front, so we just compile
// it twice - once without the flag set, and if we didn't see a recursive term, // it twice - once without the flag set, and if we didn't see a recursive term,
// then we just compile it again. // then we just compile it again.
System.out.println("parseSingleCommonTableExpression.querySQL="+querySQL);
TableView view = new TableView(schema, id, tempViewName, querySQL, TableView view = new TableView(schema, id, tempViewName, querySQL,
parameters, columnTemplateList.toArray(new Column[0]), session, parameters, columnTemplateList.toArray(new Column[0]), session,
true/* recursive */, false); true/* recursive */, false);
......
...@@ -445,6 +445,10 @@ public abstract class Prepared { ...@@ -445,6 +445,10 @@ public abstract class Prepared {
* Get the temporary views created for CTE's. * Get the temporary views created for CTE's.
*/ */
public List<TableView> getCteCleanups() { public List<TableView> getCteCleanups() {
System.out.println("getCteCleanups:"+cteCleanups);
if(cteCleanups!=null){
System.out.println("getCteCleanups:"+cteCleanups.size());
}
return cteCleanups; return cteCleanups;
} }
......
...@@ -23,6 +23,7 @@ import org.h2.schema.Sequence; ...@@ -23,6 +23,7 @@ import org.h2.schema.Sequence;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.IndexColumn; import org.h2.table.IndexColumn;
import org.h2.table.Table; import org.h2.table.Table;
import org.h2.util.ColumnNamer;
import org.h2.util.New; import org.h2.util.New;
import org.h2.value.DataType; import org.h2.value.DataType;
import org.h2.value.Value; import org.h2.value.Value;
...@@ -233,7 +234,7 @@ public class CreateTable extends SchemaCommand { ...@@ -233,7 +234,7 @@ public class CreateTable extends SchemaCommand {
for (int i = 0; i < columnCount; i++) { for (int i = 0; i < columnCount; i++) {
Expression expr = expressions.get(i); Expression expr = expressions.get(i);
int type = expr.getType(); int type = expr.getType();
String name = expr.getAlias(); String name = ColumnNamer.getColumnName(expr,i,null);
long precision = expr.getPrecision(); long precision = expr.getPrecision();
int displaySize = expr.getDisplaySize(); int displaySize = expr.getDisplaySize();
DataType dt = DataType.getDataType(type); DataType dt = DataType.getDataType(type);
......
...@@ -16,6 +16,7 @@ import org.h2.engine.Constants; ...@@ -16,6 +16,7 @@ import org.h2.engine.Constants;
import org.h2.engine.Database; import org.h2.engine.Database;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.engine.SysProperties; import org.h2.engine.SysProperties;
import org.h2.expression.Alias;
import org.h2.expression.Comparison; import org.h2.expression.Comparison;
import org.h2.expression.ConditionAndOr; import org.h2.expression.ConditionAndOr;
import org.h2.expression.Expression; import org.h2.expression.Expression;
...@@ -40,6 +41,7 @@ import org.h2.table.JoinBatch; ...@@ -40,6 +41,7 @@ import org.h2.table.JoinBatch;
import org.h2.table.Table; import org.h2.table.Table;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.table.TableView; import org.h2.table.TableView;
import org.h2.util.ColumnNamer;
import org.h2.util.New; import org.h2.util.New;
import org.h2.util.StatementBuilder; import org.h2.util.StatementBuilder;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
...@@ -836,6 +838,14 @@ public class Select extends Query { ...@@ -836,6 +838,14 @@ public class Select extends Query {
} }
for (int i = 0; i < expressions.size(); i++) { for (int i = 0; i < expressions.size(); i++) {
Expression e = expressions.get(i); Expression e = expressions.get(i);
String columnName = ColumnNamer.getColumnName(e,i,null);
if(!ColumnNamer.isReasonableColumnName(e.getAlias())){
System.out.println("Added alias="+columnName);
e = new Alias(e,columnName,true);
}
else{
System.out.println("Acceptable column name="+columnName);
}
expressions.set(i, e.optimize(session)); expressions.set(i, e.optimize(session));
} }
if (condition != null) { if (condition != null) {
......
...@@ -37,6 +37,10 @@ public class SelectListColumnResolver implements ColumnResolver { ...@@ -37,6 +37,10 @@ public class SelectListColumnResolver implements ColumnResolver {
ArrayList<Expression> columnList = select.getExpressions(); ArrayList<Expression> columnList = select.getExpressions();
for (int i = 0; i < columnCount; i++) { for (int i = 0; i < columnCount; i++) {
Expression expr = columnList.get(i); Expression expr = columnList.get(i);
String columnName = expr.getAlias();
if(columnName==null){
columnName = "_col_"+(i+1);
}
Column column = new Column(expr.getAlias(), Value.NULL); Column column = new Column(expr.getAlias(), Value.NULL);
column.setTable(null, i); column.setTable(null, i);
columns[i] = column; columns[i] = column;
......
...@@ -26,6 +26,7 @@ import org.h2.table.Column; ...@@ -26,6 +26,7 @@ import org.h2.table.Column;
import org.h2.table.ColumnResolver; import org.h2.table.ColumnResolver;
import org.h2.table.Table; import org.h2.table.Table;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.util.ColumnNamer;
import org.h2.util.New; import org.h2.util.New;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.value.Value; import org.h2.value.Value;
...@@ -336,7 +337,8 @@ public class SelectUnion extends Query { ...@@ -336,7 +337,8 @@ public class SelectUnion extends Query {
long prec = Math.max(l.getPrecision(), r.getPrecision()); long prec = Math.max(l.getPrecision(), r.getPrecision());
int scale = Math.max(l.getScale(), r.getScale()); int scale = Math.max(l.getScale(), r.getScale());
int displaySize = Math.max(l.getDisplaySize(), r.getDisplaySize()); int displaySize = Math.max(l.getDisplaySize(), r.getDisplaySize());
Column col = new Column(l.getAlias(), type, prec, scale, displaySize); String columnName = ColumnNamer.getColumnName(l,i,null);
Column col = new Column(columnName, type, prec, scale, displaySize);
Expression e = new ExpressionColumn(session.getDatabase(), col); Expression e = new ExpressionColumn(session.getDatabase(), col);
expressions.add(e); expressions.add(e);
} }
......
...@@ -364,6 +364,7 @@ public class Session extends SessionWithState { ...@@ -364,6 +364,7 @@ public class Session extends SessionWithState {
table.getSQL()); table.getSQL());
} }
modificationId++; modificationId++;
System.out.println("addLocalTempTable.worked="+table.getName()+table.toString());
localTempTables.put(table.getName(), table); localTempTables.put(table.getName(), table);
} }
......
...@@ -30,6 +30,7 @@ import org.h2.result.ResultInterface; ...@@ -30,6 +30,7 @@ import org.h2.result.ResultInterface;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.SortOrder; import org.h2.result.SortOrder;
import org.h2.schema.Schema; import org.h2.schema.Schema;
import org.h2.util.ColumnNamer;
import org.h2.util.New; import org.h2.util.New;
import org.h2.util.StatementBuilder; import org.h2.util.StatementBuilder;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
...@@ -168,7 +169,7 @@ public class TableView extends Table { ...@@ -168,7 +169,7 @@ public class TableView extends Table {
type = columnTemplates[i].getType(); type = columnTemplates[i].getType();
} }
if (name == null) { if (name == null) {
name = expr.getAlias(); name = ColumnNamer.getColumnName(expr,i,null);
} }
if (type == Value.UNKNOWN) { if (type == Value.UNKNOWN) {
type = expr.getType(); type = expr.getType();
...@@ -416,6 +417,13 @@ public class TableView extends Table { ...@@ -416,6 +417,13 @@ public class TableView extends Table {
@Override @Override
public void removeChildrenAndResources(Session session) { public void removeChildrenAndResources(Session session) {
System.out.println("invalidating="+getName());
try{
throw new RuntimeException("snapshot");
}
catch(RuntimeException e){
e.printStackTrace();
}
removeViewFromTables(); removeViewFromTables();
super.removeChildrenAndResources(session); super.removeChildrenAndResources(session);
database.removeMeta(session, getId()); database.removeMeta(session, getId());
...@@ -439,6 +447,8 @@ public class TableView extends Table { ...@@ -439,6 +447,8 @@ public class TableView extends Table {
@Override @Override
public String getSQL() { public String getSQL() {
if (isTemporary()) { if (isTemporary()) {
System.out.println("table view name="+getName());
System.out.println(this.toString()+".getSQL().querySQL="+querySQL);
return "(\n" + StringUtils.indent(querySQL) + ")"; return "(\n" + StringUtils.indent(querySQL) + ")";
} }
return super.getSQL(); return super.getSQL();
...@@ -502,8 +512,11 @@ public class TableView extends Table { ...@@ -502,8 +512,11 @@ public class TableView extends Table {
private void removeViewFromTables() { private void removeViewFromTables() {
if (tables != null) { if (tables != null) {
System.out.println("removeViewFromTables.tables="+tables);
System.out.println("removeViewFromTables.this="+this);
for (Table t : tables) { for (Table t : tables) {
t.removeView(this); t.removeView(this);
System.out.println("removeViewFromTables.tables."+t.getName()+"="+t.getViews());
} }
tables.clear(); tables.clear();
} }
......
package org.h2.util;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.h2.expression.Expression;
public class ColumnNamer {
public static String getColumnName(Expression columnExp, int indexOfColumn, String[] columnNameOverides){
String columnName = null;
if (columnNameOverides != null && columnNameOverides.length > indexOfColumn){
columnName = columnNameOverides[indexOfColumn];
}
if (columnName==null && columnExp.getAlias()!=null){
columnName = columnExp.getAlias();
if(!isReasonableColumnName(columnName)){
columnName = null;
}
}
if (columnName==null && columnExp.getColumnName()!=null){
columnName = columnExp.getColumnName();
if(!isReasonableColumnName(columnName)){
columnName = null;
}
}
if (columnName==null){
columnName = "_unnamed_column_"+(indexOfColumn+1)+"_";
}
return columnName;
}
private static Pattern reasonableNamePatternRE = Pattern.compile("[A-Z_][A-Z0-9_]*");
public static boolean isReasonableColumnName(String proposedName){
if (proposedName == null){
return false;
}
Matcher m = reasonableNamePatternRE.matcher(proposedName.toUpperCase());
boolean isReasonableName = m.matches();
return isReasonableName;
}
}
...@@ -42,6 +42,7 @@ public class TestGeneralCommonTableQueries extends TestBase { ...@@ -42,6 +42,7 @@ public class TestGeneralCommonTableQueries extends TestBase {
testMerge(); testMerge();
testCreateTable(); testCreateTable();
testNestedSQL(); testNestedSQL();
testRecursiveTable();
} }
private void testSimpleSelect() throws Exception { private void testSimpleSelect() throws Exception {
...@@ -218,7 +219,7 @@ public class TestGeneralCommonTableQueries extends TestBase { ...@@ -218,7 +219,7 @@ public class TestGeneralCommonTableQueries extends TestBase {
assertEquals(n, rs.getInt(1)); assertEquals(n, rs.getInt(1));
} }
assertEquals("X",rs.getMetaData().getColumnLabel(1)); assertEquals("X",rs.getMetaData().getColumnLabel(1));
assertEquals("'T1'",rs.getMetaData().getColumnLabel(2)); assertEquals("_unnamed_column_2_",rs.getMetaData().getColumnLabel(2));
assertFalse(rs.next()); assertFalse(rs.next());
...@@ -469,4 +470,73 @@ public class TestGeneralCommonTableQueries extends TestBase { ...@@ -469,4 +470,73 @@ public class TestGeneralCommonTableQueries extends TestBase {
conn.close(); conn.close();
deleteDb("commonTableExpressionQueries"); deleteDb("commonTableExpressionQueries");
} }
private void testRecursiveTable() throws Exception {
deleteDb("commonTableExpressionQueries");
Connection conn = getConnection("commonTableExpressionQueries");
PreparedStatement prep;
ResultSet rs;
String SETUP_SQL =
"DROP TABLE IF EXISTS A; "
+"DROP TABLE IF EXISTS B; "
+"DROP TABLE IF EXISTS C; "
+"CREATE TABLE A(VAL VARCHAR(255)); "
+"CREATE TABLE B(A VARCHAR(255), VAL VARCHAR(255)); "
+"CREATE TABLE C(B VARCHAR(255), VAL VARCHAR(255)); "
+" "
+"INSERT INTO A VALUES('fruit'); "
+"INSERT INTO B VALUES('fruit','apple'); "
+"INSERT INTO B VALUES('fruit','banana'); "
+"INSERT INTO C VALUES('apple', 'golden delicious');"
+"INSERT INTO C VALUES('apple', 'granny smith'); "
+"INSERT INTO C VALUES('apple', 'pippin'); "
+"INSERT INTO A VALUES('veg'); "
+"INSERT INTO B VALUES('veg', 'carrot'); "
+"INSERT INTO C VALUES('carrot', 'nantes'); "
+"INSERT INTO C VALUES('carrot', 'imperator'); "
+"INSERT INTO C VALUES(null, 'banapple'); "
+"INSERT INTO A VALUES('meat'); "
;
String WITH_QUERY =
"WITH BB as (SELECT \n"
+"sum(1) as X, \n"
+"a \n"
+"FROM B \n"
+"JOIN C ON B.val=C.b \n"
+"GROUP BY a) \n"
+"SELECT \n"
+"A.val, \n"
+"sum(SELECT X FROM BB WHERE BB.a IS A.val)\n"//AS SUM_X
+"FROM A \n"
+"GROUP BY A.val";
for(int queryTries: new int[]{1,2,3}){
System.out.println("Try#"+queryTries);
Statement stat = conn.createStatement();
stat.execute(SETUP_SQL);
prep = conn.prepareStatement(WITH_QUERY);
rs = prep.executeQuery();
for(int columnIndex = 1; columnIndex <= rs.getMetaData().getColumnCount(); columnIndex++){
System.out.print("|"+rs.getMetaData().getColumnLabel(columnIndex));
}
System.out.println();
while (rs.next()) {
//assertTrue(rs.next());
//assertContains("ab",rs.getString(1));
//assertEquals(rs.getString(1),keyLetter);
//assertTrue(rs.getInt(2)!=0);
for(int columnIndex = 1; columnIndex <= rs.getMetaData().getColumnCount(); columnIndex++){
System.out.print("|"+rs.getString(columnIndex));
}
System.out.println();
}
}
conn.close();
deleteDb("commonTableExpressionQueries");
}
} }
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论