private void copyData() { if (table.isTemporary()) { throw DbException.getUnsupportedException("TEMP TABLE"); } Database db = session.getDatabase(); String baseName = table.getName(); String tempName = db.getTempTableName(baseName, session); Column[] columns = table.getColumns(); ArrayList<Column> newColumns = New.arrayList(); Table newTable = cloneTableStructure(columns, db, tempName, newColumns); try { // check if a view would become invalid // (because the column to drop is referenced or so) checkViews(table, newTable); } catch (DbException e) { execute("DROP TABLE " + newTable.getName(), true); throw DbException.get(ErrorCode.VIEW_IS_INVALID_2, e, getSQL(), e.getMessage()); } String tableName = table.getName(); ArrayList<TableView> views = table.getViews(); if (views != null) { views = New.arrayList(views); for (TableView view : views) { table.removeView(view); } } execute("DROP TABLE " + table.getSQL() + " IGNORE", true); db.renameSchemaObject(session, newTable, tableName); for (DbObject child : newTable.getChildren()) { if (child instanceof Sequence) { continue; } String name = child.getName(); if (name == null || child.getCreateSQL() == null) { continue; } if (name.startsWith(tempName + "_")) { name = name.substring(tempName.length() + 1); SchemaObject so = (SchemaObject) child; if (so instanceof Constraint) { if (so.getSchema().findConstraint(session, name) != null) { name = so.getSchema().getUniqueConstraintName(session, newTable); } } else if (so instanceof Index) { if (so.getSchema().findIndex(session, name) != null) { name = so.getSchema().getUniqueIndexName(session, newTable, name); } } db.renameSchemaObject(session, so, name); } } if (views != null) { for (TableView view : views) { String sql = view.getCreateSQL(true, true); execute(sql, true); } } }
/** * 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, session, false); v.setTopQuery(topQuery); if (v.createException != null) { throw v.createException; } v.setOwner(owner); v.setTemporary(true); return v; }
public double getCost(Session session, int[] masks) { if (recursive) { return 1000; } IntArray masksArray = new IntArray(masks == null ? Utils.EMPTY_INT_ARRAY : masks); CostElement cachedCost = costCache.get(masksArray); if (cachedCost != null) { long time = System.currentTimeMillis(); if (time < cachedCost.evaluatedAt + Constants.VIEW_COST_CACHE_MAX_AGE) { return cachedCost.cost; } } Query q = (Query) session.prepare(querySQL, true); if (masks != null) { IntArray paramIndex = new IntArray(); for (int i = 0; i < masks.length; i++) { int mask = masks[i]; if (mask == 0) { continue; } paramIndex.add(i); } int len = paramIndex.size(); for (int i = 0; i < len; i++) { int idx = paramIndex.get(i); int mask = masks[idx]; int nextParamIndex = q.getParameters().size() + view.getParameterOffset(); if ((mask & IndexCondition.EQUALITY) != 0) { Parameter param = new Parameter(nextParamIndex); q.addGlobalCondition(param, idx, Comparison.EQUAL_NULL_SAFE); } else { if ((mask & IndexCondition.START) != 0) { Parameter param = new Parameter(nextParamIndex); q.addGlobalCondition(param, idx, Comparison.BIGGER_EQUAL); } if ((mask & IndexCondition.END) != 0) { Parameter param = new Parameter(nextParamIndex); q.addGlobalCondition(param, idx, Comparison.SMALLER_EQUAL); } } } String sql = q.getPlanSQL(); q = (Query) session.prepare(sql, true); } double cost = q.getCost(); cachedCost = new CostElement(); cachedCost.evaluatedAt = System.currentTimeMillis(); cachedCost.cost = cost; costCache.put(masksArray, cachedCost); return cost; }
private Query getQuery(Session session, int[] masks) { Query q = (Query) session.prepare(querySQL, true); if (masks == null) { return q; } int firstIndexParam = originalParameters == null ? 0 : originalParameters.size(); firstIndexParam += view.getParameterOffset(); IntArray paramIndex = new IntArray(); for (int i = 0; i < masks.length; i++) { int mask = masks[i]; if (mask == 0) { continue; } paramIndex.add(i); if ((mask & IndexCondition.RANGE) == IndexCondition.RANGE) { // two parameters for range queries: >= x AND <= y paramIndex.add(i); } } int len = paramIndex.size(); columns = new Column[len]; for (int i = 0; i < len; ) { int idx = paramIndex.get(i); Column col = table.getColumn(idx); columns[i] = col; int mask = masks[idx]; if ((mask & IndexCondition.EQUALITY) == IndexCondition.EQUALITY) { Parameter param = new Parameter(firstIndexParam + i); q.addGlobalCondition(param, idx, Comparison.EQUAL_NULL_SAFE); i++; } else { if ((mask & IndexCondition.START) == IndexCondition.START) { Parameter param = new Parameter(firstIndexParam + i); q.addGlobalCondition(param, idx, Comparison.BIGGER_EQUAL); i++; } if ((mask & IndexCondition.END) == IndexCondition.END) { Parameter param = new Parameter(firstIndexParam + i); q.addGlobalCondition(param, idx, Comparison.SMALLER_EQUAL); i++; } } } String sql = q.getPlanSQL(); q = (Query) session.prepare(sql, true); return q; }
@Override public int update() { session.commit(true); session.getUser().checkAdmin(); Database db = session.getDatabase(); TableView view = null; Table old = getSchema().findTableOrView(session, viewName); if (old != null) { if (ifNotExists) { return 0; } if (!orReplace || !Table.VIEW.equals(old.getTableType())) { throw DbException.get(ErrorCode.VIEW_ALREADY_EXISTS_1, viewName); } view = (TableView) old; } int id = getObjectId(); String querySQL; if (select == null) { querySQL = selectSQL; } else { ArrayList<Parameter> params = select.getParameters(); if (params != null && params.size() > 0) { throw DbException.getUnsupportedException("parameters in views"); } querySQL = select.getPlanSQL(); } // The view creates a Prepared command object, which belongs to a // session, so we pass the system session down. Session sysSession = db.getSystemSession(); synchronized (sysSession) { try { if (view == null) { Schema schema = session.getDatabase().getSchema(session.getCurrentSchemaName()); sysSession.setCurrentSchema(schema); Column[] columnTemplates = null; if (columnNames != null) { columnTemplates = new Column[columnNames.length]; for (int i = 0; i < columnNames.length; ++i) { columnTemplates[i] = new Column(columnNames[i], Value.UNKNOWN); } } view = new TableView( getSchema(), id, viewName, querySQL, null, columnTemplates, sysSession, false); } else { view.replace(querySQL, columnNames, sysSession, false, force); view.setModified(); } } finally { sysSession.setCurrentSchema(db.getSchema(Constants.SCHEMA_MAIN)); } } if (comment != null) { view.setComment(comment); } if (old == null) { db.addSchemaObject(session, view); } else { db.updateMeta(session, view); } return 0; }
public Cursor find(Session session, SearchRow first, SearchRow last) { if (recursive) { if (view.getRecursiveResult() != null) { ResultInterface r = view.getRecursiveResult(); r.reset(); return new ViewCursor(table, r); } if (query == null) { query = (Query) createSession.prepare(querySQL, true); planSQL = query.getPlanSQL(); } if (!(query instanceof SelectUnion)) { throw DbException.get(ErrorCode.SYNTAX_ERROR_2, "recursive queries without UNION ALL"); } SelectUnion union = (SelectUnion) query; if (union.getUnionType() != SelectUnion.UNION_ALL) { throw DbException.get(ErrorCode.SYNTAX_ERROR_2, "recursive queries without UNION ALL"); } Query left = union.getLeft(); ResultInterface r = left.query(0); LocalResult result = union.getEmptyResult(); while (r.next()) { result.addRow(r.currentRow()); } Query right = union.getRight(); r.reset(); view.setRecursiveResult(r); while (true) { r = right.query(0); if (r.getRowCount() == 0) { break; } while (r.next()) { result.addRow(r.currentRow()); } r.reset(); view.setRecursiveResult(r); } return new ViewCursor(table, result); } ArrayList<Parameter> paramList = query.getParameters(); for (int i = 0; originalParameters != null && i < originalParameters.size(); i++) { Parameter orig = originalParameters.get(i); int idx = orig.getIndex(); Value value = orig.getValue(session); setParameter(paramList, idx, value); } int len; if (first != null) { len = first.getColumnCount(); } else if (last != null) { len = last.getColumnCount(); } else { len = 0; } int idx = originalParameters == null ? 0 : originalParameters.size(); idx += view.getParameterOffset(); for (int i = 0; i < len; i++) { if (first != null) { Value v = first.getValue(i); if (v != null) { int x = idx++; setParameter(paramList, x, v); } } // for equality, only one parameter is used (first == last) if (last != null && indexMasks[i] != IndexCondition.EQUALITY) { Value v = last.getValue(i); if (v != null) { int x = idx++; setParameter(paramList, x, v); } } } ResultInterface result = query.query(0); return new ViewCursor(table, result); }