Unverified 提交 f0aa081b authored 作者: Noel Grandin's avatar Noel Grandin 提交者: GitHub

Merge pull request #1270 from grandinj/drop_tableview_persistent

drop TableView isPersistent field
......@@ -1147,7 +1147,7 @@ public class Parser {
queryAlias, querySQLOutput[0],
columnTemplateList, false/* no recursion */,
false/* do not add to session */,
false /* isPersistent */,
true /* isTemporary */,
session);
TableFilter sourceTableFilter = new TableFilter(session,
temporarySourceTableView, queryAlias,
......@@ -5166,25 +5166,19 @@ public class Parser {
List<TableView> viewsCreated = new ArrayList<>();
readIf("RECURSIVE");
// this WITH statement might not be a temporary view - allow optional keyword to
// tell us that this keyword. This feature will not be documented - H2 internal use only.
boolean isPersistent = readIf("PERSISTENT");
// this WITH statement is not a temporary view - it is part of a persistent view
// as in CREATE VIEW abc AS WITH my_cte - this auto detects that condition
if (session.isParsingCreateView()) {
isPersistent = true;
}
// This WITH statement is not a temporary view - it is part of a persistent view
// as in CREATE VIEW abc AS WITH my_cte - this auto detects that condition.
final boolean isTemporary = !session.isParsingCreateView();
do {
viewsCreated.add(parseSingleCommonTableExpression(isPersistent));
viewsCreated.add(parseSingleCommonTableExpression(isTemporary));
} while (readIf(","));
Prepared p;
// reverse the order of constructed CTE views - as the destruction order
// Reverse the order of constructed CTE views - as the destruction order
// (since later created view may depend on previously created views -
// we preserve that dependency order in the destruction sequence )
// used in setCteCleanups
// used in setCteCleanups.
Collections.reverse(viewsCreated);
if (isToken("SELECT")) {
......@@ -5217,15 +5211,15 @@ public class Parser {
WITH_STATEMENT_SUPPORTS_LIMITED_SUB_STATEMENTS);
}
// clean up temporary views starting with last to first (in case of
// dependencies) - but only if they are not persistent
if (!isPersistent) {
// Clean up temporary views starting with last to first (in case of
// dependencies) - but only if they are not persistent.
if (isTemporary) {
p.setCteCleanups(viewsCreated);
}
return p;
}
private TableView parseSingleCommonTableExpression(boolean isPersistent) {
private TableView parseSingleCommonTableExpression(boolean isTemporary) {
String cteViewName = readIdentifierWithSchema();
Schema schema = getSchema();
ArrayList<Column> columns = Utils.newSmallArrayList();
......@@ -5243,7 +5237,7 @@ public class Parser {
}
Table oldViewFound;
if (isPersistent) {
if (!isTemporary) {
oldViewFound = getSchema().findTableOrView(session, cteViewName);
} else {
oldViewFound = session.findLocalTempTable(cteViewName);
......@@ -5259,7 +5253,7 @@ public class Parser {
throw DbException.get(ErrorCode.TABLE_OR_VIEW_ALREADY_EXISTS_1,
cteViewName);
}
if (isPersistent) {
if (!isTemporary) {
oldViewFound.lock(session, true, true);
database.removeSchemaObject(session, oldViewFound);
......@@ -5275,33 +5269,33 @@ public class Parser {
* data and table if we don't have a working CTE already.
*/
Table recursiveTable = TableView.createShadowTableForRecursiveTableExpression(
isPersistent, session, cteViewName, schema, columns, database);
isTemporary, session, cteViewName, schema, columns, database);
List<Column> columnTemplateList;
String[] querySQLOutput = {null};
try {
read("AS");
read("(");
Query withQuery = parseSelect();
if (isPersistent) {
if (!isTemporary) {
withQuery.session = session;
}
read(")");
columnTemplateList = TableView.createQueryColumnTemplateList(cols, withQuery, querySQLOutput);
} finally {
TableView.destroyShadowTableForRecursiveExpression(isPersistent, session, recursiveTable);
TableView.destroyShadowTableForRecursiveExpression(isTemporary, session, recursiveTable);
}
return createCTEView(cteViewName,
querySQLOutput[0], columnTemplateList,
true/* allowRecursiveQueryDetection */,
true/* add to session */,
isPersistent, session);
isTemporary, session);
}
private TableView createCTEView(String cteViewName, String querySQL,
List<Column> columnTemplateList, boolean allowRecursiveQueryDetection,
boolean addViewToSession, boolean isPersistent, Session targetSession) {
boolean addViewToSession, boolean isTemporary, Session targetSession) {
Database db = targetSession.getDatabase();
Schema schema = getSchemaWithDefault();
int id = db.allocateObjectId();
......@@ -5315,9 +5309,9 @@ public class Parser {
view = new TableView(schema, id, cteViewName, querySQL,
parameters, columnTemplateArray, targetSession,
allowRecursiveQueryDetection, false /* literalsChecked */, true /* isTableExpression */,
isPersistent);
isTemporary);
if (!view.isRecursiveQueryDetected() && allowRecursiveQueryDetection) {
if (isPersistent) {
if (!isTemporary) {
db.addSchemaObject(targetSession, view);
view.lock(targetSession, true, true);
db.removeSchemaObject(targetSession, view);
......@@ -5327,17 +5321,17 @@ public class Parser {
view = new TableView(schema, id, cteViewName, querySQL, parameters,
columnTemplateArray, targetSession,
false/* assume recursive */, false /* literalsChecked */, true /* isTableExpression */,
isPersistent);
isTemporary);
}
// both removeSchemaObject and removeLocalTempTable hold meta locks
db.unlockMeta(targetSession);
}
view.setTableExpression(true);
view.setTemporary(!isPersistent);
view.setTemporary(isTemporary);
view.setHidden(true);
view.setOnCommitDrop(false);
if (addViewToSession) {
if (isPersistent) {
if (!isTemporary) {
db.addSchemaObject(targetSession, view);
view.unlock(targetSession);
db.unlockMeta(targetSession);
......
......@@ -119,10 +119,10 @@ public class CreateView extends SchemaCommand {
if (isTableExpression) {
view = TableView.createTableViewMaybeRecursive(getSchema(), id, viewName, querySQL, null,
columnTemplatesAsStrings, session, false /* literalsChecked */, isTableExpression,
true /* isPersistent */, db);
false/*isTemporary*/, db);
} else {
view = new TableView(getSchema(), id, viewName, querySQL, null, columnTemplatesAsUnknowns, session,
false/* allow recursive */, false/* literalsChecked */, isTableExpression, true);
false/* allow recursive */, false/* literalsChecked */, isTableExpression, false/*temporary*/);
}
} else {
// TODO support isTableExpression in replace function...
......
......@@ -1150,7 +1150,7 @@ public class Select extends Query {
TableView tableView = t.isView() ? (TableView) t : null;
if (tableView != null && tableView.isRecursive() && tableView.isTableExpression()) {
if (tableView.isPersistent()) {
if (!tableView.isTemporary()) {
// skip the generation of plan SQL for this already recursive persistent CTEs,
// since using a with statement will re-create the common table expression
// views.
......
......@@ -63,14 +63,13 @@ public class TableView extends Table {
private ResultInterface recursiveResult;
private boolean isRecursiveQueryDetected;
private boolean isTableExpression;
private boolean isPersistent;
public TableView(Schema schema, int id, String name, String querySQL,
ArrayList<Parameter> params, Column[] columnTemplates, Session session,
boolean allowRecursive, boolean literalsChecked, boolean isTableExpression, boolean isPersistent) {
boolean allowRecursive, boolean literalsChecked, boolean isTableExpression, boolean isTemporary) {
super(schema, id, name, false, true);
init(querySQL, params, columnTemplates, session, allowRecursive, literalsChecked, isTableExpression,
isPersistent);
setTemporary(isTemporary);
init(querySQL, params, columnTemplates, session, allowRecursive, literalsChecked, isTableExpression);
}
/**
......@@ -92,11 +91,11 @@ public class TableView extends Table {
init(querySQL, null,
newColumnTemplates == null ? this.columnTemplates
: newColumnTemplates,
session, recursive, literalsChecked, isTableExpression, isPersistent);
session, recursive, literalsChecked, isTableExpression);
DbException e = recompile(session, force, true);
if (e != null) {
init(oldQuerySQL, null, oldColumnTemplates, session, oldRecursive,
literalsChecked, isTableExpression, isPersistent);
literalsChecked, isTableExpression);
recompile(session, true, false);
throw e;
}
......@@ -104,13 +103,12 @@ public class TableView extends Table {
private synchronized void init(String querySQL, ArrayList<Parameter> params,
Column[] columnTemplates, Session session, boolean allowRecursive, boolean literalsChecked,
boolean isTableExpression, boolean isPersistent) {
boolean isTableExpression) {
this.querySQL = querySQL;
this.columnTemplates = columnTemplates;
this.allowRecursive = allowRecursive;
this.isRecursiveQueryDetected = false;
this.isTableExpression = isTableExpression;
this.isPersistent = isPersistent;
index = new ViewIndex(this, querySQL, params, allowRecursive);
initColumnsAndTables(session, literalsChecked);
}
......@@ -568,7 +566,7 @@ public class TableView extends Table {
TableView v = new TableView(mainSchema, 0, name,
querySQL, query.getParameters(), null /* column templates */, session,
false/* allow recursive */, true /* literals have already been checked when parsing original query */,
false /* is table expression */, false/* is persistent*/);
false /* is table expression */, true/*temporary*/);
if (v.createException != null) {
throw v.createException;
}
......@@ -716,10 +714,6 @@ public class TableView extends Table {
return tables;
}
public boolean isPersistent() {
return isPersistent;
}
/**
* Create a view.
*
......@@ -732,16 +726,16 @@ public class TableView extends Table {
* @param session the session
* @param literalsChecked whether literals in the query are checked
* @param isTableExpression if this is a table expression
* @param isPersistent whether the view is persisted
* @param isTemporary whether the view is persisted
* @param db the database
* @return the view
*/
public static TableView createTableViewMaybeRecursive(Schema schema, int id, String name, String querySQL,
ArrayList<Parameter> parameters, Column[] columnTemplates, Session session,
boolean literalsChecked, boolean isTableExpression, boolean isPersistent, Database db) {
boolean literalsChecked, boolean isTableExpression, boolean isTemporary, Database db) {
Table recursiveTable = TableView.createShadowTableForRecursiveTableExpression(isPersistent, session, name,
Table recursiveTable = createShadowTableForRecursiveTableExpression(isTemporary, session, name,
schema, Arrays.asList(columnTemplates), db);
List<Column> columnTemplateList;
......@@ -753,25 +747,25 @@ public class TableView extends Table {
try {
Prepared withQuery = session.prepare(querySQL, false, false);
if (isPersistent) {
if (!isTemporary) {
withQuery.setSession(session);
}
columnTemplateList = TableView.createQueryColumnTemplateList(columnNames.toArray(new String[1]),
(Query) withQuery, querySQLOutput);
} finally {
TableView.destroyShadowTableForRecursiveExpression(isPersistent, session, recursiveTable);
destroyShadowTableForRecursiveExpression(isTemporary, session, recursiveTable);
}
// build with recursion turned on
TableView view = new TableView(schema, id, name, querySQL,
parameters, columnTemplateList.toArray(columnTemplates), session,
true/* try recursive */, literalsChecked, isTableExpression, isPersistent);
true/* try recursive */, literalsChecked, isTableExpression, isTemporary);
// is recursion really detected ? if not - recreate it without recursion flag
// and no recursive index
if (!view.isRecursiveQueryDetected()) {
if (isPersistent) {
if (!isTemporary) {
db.addSchemaObject(session, view);
view.lock(session, true, true);
session.getDatabase().removeSchemaObject(session, view);
......@@ -785,7 +779,7 @@ public class TableView extends Table {
}
view = new TableView(schema, id, name, querySQL, parameters,
columnTemplates, session,
false/* detected not recursive */, literalsChecked, isTableExpression, isPersistent);
false/* detected not recursive */, literalsChecked, isTableExpression, isTemporary);
}
return view;
......@@ -829,7 +823,7 @@ public class TableView extends Table {
/**
* Create a table for a recursive query.
*
* @param isPersistent whether the table is persisted
* @param isTemporary whether the table is persisted
* @param targetSession the session
* @param cteViewName the name
* @param schema the schema
......@@ -837,7 +831,7 @@ public class TableView extends Table {
* @param db the database
* @return the table
*/
public static Table createShadowTableForRecursiveTableExpression(boolean isPersistent, Session targetSession,
public static Table createShadowTableForRecursiveTableExpression(boolean isTemporary, Session targetSession,
String cteViewName, Schema schema, List<Column> columns, Database db) {
// create table data object
......@@ -845,16 +839,16 @@ public class TableView extends Table {
recursiveTableData.id = db.allocateObjectId();
recursiveTableData.columns = new ArrayList<>(columns);
recursiveTableData.tableName = cteViewName;
recursiveTableData.temporary = !isPersistent;
recursiveTableData.temporary = isTemporary;
recursiveTableData.persistData = true;
recursiveTableData.persistIndexes = isPersistent;
recursiveTableData.persistIndexes = !isTemporary;
recursiveTableData.create = true;
recursiveTableData.session = targetSession;
// this gets a meta table lock that is not released
Table recursiveTable = schema.createTable(recursiveTableData);
if (isPersistent) {
if (!isTemporary) {
// this unlock is to prevent lock leak from schema.createTable()
db.unlockMeta(targetSession);
synchronized (targetSession) {
......@@ -869,14 +863,14 @@ public class TableView extends Table {
/**
* Remove a table for a recursive query.
*
* @param isPersistent whether the table is persisted
* @param isTemporary whether the table is persisted
* @param targetSession the session
* @param recursiveTable the table
*/
public static void destroyShadowTableForRecursiveExpression(boolean isPersistent, Session targetSession,
public static void destroyShadowTableForRecursiveExpression(boolean isTemporary, Session targetSession,
Table recursiveTable) {
if (recursiveTable != null) {
if (isPersistent) {
if (!isTemporary) {
recursiveTable.lock(targetSession, true, true);
targetSession.getDatabase().removeSchemaObject(targetSession, recursiveTable);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论