use of org.h2.table.TableView in project h2database by h2database.
the class Parser method parseWith.
private Prepared parseWith() {
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");
// as in CREATE VIEW abc AS WITH my_cte - this auto detects that condition
if (session.isParsingCreateView()) {
isPersistent = true;
}
do {
viewsCreated.add(parseSingleCommonTableExpression(isPersistent));
} while (readIf(","));
Prepared p = null;
// 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
Collections.reverse(viewsCreated);
if (isToken("SELECT")) {
Query query = parseSelectUnion();
query.setPrepareAlways(true);
query.setNeverLazy(true);
p = query;
} else if (readIf("INSERT")) {
p = parseInsert();
p.setPrepareAlways(true);
} else if (readIf("UPDATE")) {
p = parseUpdate();
p.setPrepareAlways(true);
} else if (readIf("MERGE")) {
p = parseMerge();
p.setPrepareAlways(true);
} else if (readIf("DELETE")) {
p = parseDelete();
p.setPrepareAlways(true);
} else if (readIf("CREATE")) {
if (!isToken("TABLE")) {
throw DbException.get(ErrorCode.SYNTAX_ERROR_1, WITH_STATEMENT_SUPPORTS_LIMITED_SUB_STATEMENTS);
}
p = parseCreate();
p.setPrepareAlways(true);
} else {
throw DbException.get(ErrorCode.SYNTAX_ERROR_1, WITH_STATEMENT_SUPPORTS_LIMITED_SUB_STATEMENTS);
}
// dependencies) - but only if they are not persistent
if (!isPersistent) {
p.setCteCleanups(viewsCreated);
}
return p;
}
use of org.h2.table.TableView in project h2database by h2database.
the class Database method recompileInvalidViews.
private void recompileInvalidViews(Session session) {
boolean atLeastOneRecompiledSuccessfully;
do {
atLeastOneRecompiledSuccessfully = false;
for (Table obj : getAllTablesAndViews(false)) {
if (obj instanceof TableView) {
TableView view = (TableView) obj;
if (view.isInvalid()) {
view.recompile(session, true, false);
if (!view.isInvalid()) {
atLeastOneRecompiledSuccessfully = true;
}
}
}
}
} while (atLeastOneRecompiledSuccessfully);
TableView.clearIndexCaches(session.getDatabase());
}
use of org.h2.table.TableView in project h2database by h2database.
the class DropTable method prepareDrop.
private void prepareDrop() {
table = getSchema().findTableOrView(session, tableName);
if (table == null) {
if (!ifExists) {
throw DbException.get(ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1, tableName);
}
} else {
session.getUser().checkRight(table, Right.ALL);
if (!table.canDrop()) {
throw DbException.get(ErrorCode.CANNOT_DROP_TABLE_1, tableName);
}
if (dropAction == ConstraintActionType.RESTRICT) {
StatementBuilder buff = new StatementBuilder();
CopyOnWriteArrayList<TableView> dependentViews = table.getDependentViews();
if (dependentViews != null && !dependentViews.isEmpty()) {
for (TableView v : dependentViews) {
buff.appendExceptFirst(", ");
buff.append(v.getName());
}
}
if (session.getDatabase().getSettings().standardDropTableRestrict) {
final List<Constraint> constraints = table.getConstraints();
if (constraints != null && !constraints.isEmpty()) {
for (Constraint c : constraints) {
if (c.getTable() != table) {
buff.appendExceptFirst(", ");
buff.append(c.getName());
}
}
}
}
if (buff.length() > 0) {
throw DbException.get(ErrorCode.CANNOT_DROP_2, tableName, buff.toString());
}
}
table.lock(session, true, true);
}
if (next != null) {
next.prepareDrop();
}
}
use of org.h2.table.TableView in project h2database by h2database.
the class TableFilter method getPlanSQL.
/**
* Get the query execution plan text to use for this table filter.
*
* @param isJoin if this is a joined table
* @return the SQL statement snippet
*/
public String getPlanSQL(boolean isJoin) {
StringBuilder buff = new StringBuilder();
if (isJoin) {
if (joinOuter) {
buff.append("LEFT OUTER JOIN ");
} else {
buff.append("INNER JOIN ");
}
}
if (nestedJoin != null) {
StringBuilder buffNested = new StringBuilder();
TableFilter n = nestedJoin;
do {
buffNested.append(n.getPlanSQL(n != nestedJoin));
buffNested.append('\n');
n = n.getJoin();
} while (n != null);
String nested = buffNested.toString();
boolean enclose = !nested.startsWith("(");
if (enclose) {
buff.append("(\n");
}
buff.append(StringUtils.indent(nested, 4, false));
if (enclose) {
buff.append(')');
}
if (isJoin) {
buff.append(" ON ");
if (joinCondition == null) {
// need to have a ON expression,
// otherwise the nesting is unclear
buff.append("1=1");
} else {
buff.append(StringUtils.unEnclose(joinCondition.getSQL()));
}
}
return buff.toString();
}
if (table.isView() && ((TableView) table).isRecursive()) {
buff.append(table.getName());
} else {
buff.append(table.getSQL());
}
if (table.isView() && ((TableView) table).isInvalid()) {
throw DbException.get(ErrorCode.VIEW_IS_INVALID_2, table.getName(), "not compiled");
}
if (alias != null) {
buff.append(' ').append(Parser.quoteIdentifier(alias));
}
if (indexHints != null) {
buff.append(" USE INDEX (");
boolean first = true;
for (String index : indexHints.getAllowedIndexes()) {
if (!first) {
buff.append(", ");
} else {
first = false;
}
buff.append(Parser.quoteIdentifier(index));
}
buff.append(")");
}
if (index != null) {
buff.append('\n');
StatementBuilder planBuff = new StatementBuilder();
if (joinBatch != null) {
IndexLookupBatch lookupBatch = joinBatch.getLookupBatch(joinFilterId);
if (lookupBatch == null) {
if (joinFilterId != 0) {
throw DbException.throwInternalError("" + joinFilterId);
}
} else {
planBuff.append("batched:");
String batchPlan = lookupBatch.getPlanSQL();
planBuff.append(batchPlan);
planBuff.append(" ");
}
}
planBuff.append(index.getPlanSQL());
if (!indexConditions.isEmpty()) {
planBuff.append(": ");
for (IndexCondition condition : indexConditions) {
planBuff.appendExceptFirst("\n AND ");
planBuff.append(condition.getSQL());
}
}
String plan = StringUtils.quoteRemarkSQL(planBuff.toString());
if (plan.indexOf('\n') >= 0) {
plan += "\n";
}
buff.append(StringUtils.indent("/* " + plan + " */", 4, false));
}
if (isJoin) {
buff.append("\n ON ");
if (joinCondition == null) {
// need to have a ON expression, otherwise the nesting is
// unclear
buff.append("1=1");
} else {
buff.append(StringUtils.unEnclose(joinCondition.getSQL()));
}
}
if (filterCondition != null) {
buff.append('\n');
String condition = StringUtils.unEnclose(filterCondition.getSQL());
condition = "/* WHERE " + StringUtils.quoteRemarkSQL(condition) + "\n*/";
buff.append(StringUtils.indent(condition, 4, false));
}
if (scanCount > 0) {
buff.append("\n /* scanCount: ").append(scanCount).append(" */");
}
return buff.toString();
}
use of org.h2.table.TableView in project h2database by h2database.
the class TableView method createTempView.
/**
* Create a temporary view out of the given query.
*
* @param session the session
* @param owner the owner of the query
* @param name the view name
* @param query the query
* @param topQuery the top level query
* @return the view table
*/
public static TableView createTempView(Session session, User owner, String name, Query query, Query topQuery) {
Schema mainSchema = session.getDatabase().getSchema(Constants.SCHEMA_MAIN);
String querySQL = query.getPlanSQL();
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);
if (v.createException != null) {
throw v.createException;
}
v.setTopQuery(topQuery);
v.setOwner(owner);
v.setTemporary(true);
return v;
}
Aggregations