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