ResultTempTable(Session session, Expression[] expressions, boolean distinct, SortOrder sort) { this.session = session; this.distinct = distinct; this.sort = sort; this.columnCount = expressions.length; Schema schema = session.getDatabase().getSchema(Constants.SCHEMA_MAIN); CreateTableData data = new CreateTableData(); for (int i = 0; i < expressions.length; i++) { int type = expressions[i].getType(); Column col = new Column(COLUMN_NAME + i, type); if (type == Value.CLOB || type == Value.BLOB) { containsLob = true; } data.columns.add(col); } data.id = session.getDatabase().allocateObjectId(); data.tableName = "TEMP_RESULT_SET_" + data.id; data.temporary = true; data.persistIndexes = false; data.persistData = true; data.create = true; data.session = session; table = schema.createTable(data); if (sort != null || distinct) { createIndex(); } parent = null; }
/** * Construct a new row list for this session. * * @param session the session */ public RowList(Session session) { this.session = session; if (session.getDatabase().isPersistent()) { maxMemory = session.getDatabase().getMaxOperationMemory(); } else { maxMemory = 0; } }
private void createIndex() { IndexColumn[] indexCols = null; if (sort != null) { int[] colIndex = sort.getQueryColumnIndexes(); indexCols = new IndexColumn[colIndex.length]; for (int i = 0; i < colIndex.length; i++) { IndexColumn indexColumn = new IndexColumn(); indexColumn.column = table.getColumn(colIndex[i]); indexColumn.sortType = sort.getSortTypes()[i]; indexColumn.columnName = COLUMN_NAME + i; indexCols[i] = indexColumn; } } else { indexCols = new IndexColumn[columnCount]; for (int i = 0; i < columnCount; i++) { IndexColumn indexColumn = new IndexColumn(); indexColumn.column = table.getColumn(i); indexColumn.columnName = COLUMN_NAME + i; indexCols[i] = indexColumn; } } String indexName = table.getSchema().getUniqueIndexName(session, table, Constants.PREFIX_INDEX); int indexId = session.getDatabase().allocateObjectId(); IndexType indexType = IndexType.createNonUnique(true); index = table.addIndex(session, indexName, indexId, indexCols, indexType, true, null); }
@Override public Value[] next() { if (resultCursor == null) { Index idx; if (distinct || sort != null) { idx = index; } else { idx = table.getScanIndex(session); } if (session.getDatabase().getMvStore() != null) { // sometimes the transaction is already committed, // in which case we can't use the session if (idx.getRowCount(session) == 0 && rowCount > 0) { // this means querying is not transactional resultCursor = idx.find((Session) null, null, null); } else { // the transaction is still open resultCursor = idx.find(session, null, null); } } else { resultCursor = idx.find(session, null, null); } } if (!resultCursor.next()) { return null; } Row row = resultCursor.get(); return row.getValueList(); }
private boolean sameResultAsLast(Session s, Value[] params, Value[] lastParams, long lastEval) { if (!cacheableChecked) { long max = getMaxDataModificationId(); noCache = max == Long.MAX_VALUE; cacheableChecked = true; } if (noCache) { return false; } Database db = s.getDatabase(); for (int i = 0; i < params.length; i++) { Value a = lastParams[i], b = params[i]; if (a.getType() != b.getType() || !db.areEqual(a, b)) { return false; } } if (!isEverything(ExpressionVisitor.DETERMINISTIC_VISITOR) || !isEverything(ExpressionVisitor.INDEPENDENT_VISITOR)) { return false; } if (db.getModificationDataId() > lastEval && getMaxDataModificationId() > lastEval) { return false; } return true; }
private void writeAllRows() { if (file == null) { Database db = session.getDatabase(); String fileName = db.createTempFile(); file = db.openFile(fileName, "rw", false); file.setCheckedWriting(false); file.seek(FileStore.HEADER_LENGTH); rowBuff = Data.create(db, Constants.DEFAULT_PAGE_SIZE); file.seek(FileStore.HEADER_LENGTH); } Data buff = rowBuff; initBuffer(buff); for (int i = 0, size = list.size(); i < size; i++) { if (i > 0 && buff.length() > Constants.IO_BUFFER_SIZE) { flushBuffer(buff); initBuffer(buff); } Row r = list.get(i); writeRow(buff, r); } flushBuffer(buff); file.autoDelete(); list.clear(); memory = 0; }
@Override public Expression[] getExpressionColumns(Session session) { ExpressionColumn[] expr = new ExpressionColumn[list.length]; for (int i = 0; i < list.length; i++) { Expression e = list[i]; Column col = new Column( "C" + (i + 1), e.getType(), e.getPrecision(), e.getScale(), e.getDisplaySize()); expr[i] = new ExpressionColumn(session.getDatabase(), col); } return expr; }
public void createIndexConditions(Session session, TableFilter filter) { if (!(this.left instanceof ExpressionColumn)) { return; } ExpressionColumn l = (ExpressionColumn) this.left; if (filter != l.getTableFilter()) { return; } if (session.getDatabase().getSettings().optimizeInList) { filter.addIndexCondition(IndexCondition.getInList(l, this.valueList)); return; } }
/** * 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; }
private void dropTable() { if (table == null) { return; } if (containsLob) { // contains BLOB or CLOB: can not truncate now, // otherwise the BLOB and CLOB entries are removed return; } try { Database database = session.getDatabase(); // Need to lock because not all of the code-paths // that reach here have already taken this lock, // notably via the close() paths. synchronized (session) { synchronized (database) { table.truncate(session); } } // This session may not lock the sys table (except if it already has // locked it) because it must be committed immediately, otherwise // other threads can not access the sys table. If the table is not // removed now, it will be when the database is opened the next // time. (the table is truncated, so this is just one record) if (!database.isSysTableLocked()) { Session sysSession = database.getSystemSession(); table.removeChildrenAndResources(sysSession); if (index != null) { // need to explicitly do this, // as it's not registered in the system session session.removeLocalTempTableIndex(index); } // the transaction must be committed immediately // TODO this synchronization cascade is very ugly synchronized (session) { synchronized (sysSession) { synchronized (database) { sysSession.commit(false); } } } } } finally { table = null; } }
ResultDiskBuffer(Session session, SortOrder sort, int columnCount) { this.parent = null; this.sort = sort; this.columnCount = columnCount; Database db = session.getDatabase(); rowBuff = Data.create(db, Constants.DEFAULT_PAGE_SIZE); String fileName = db.createTempFile(); file = db.openFile(fileName, "rw", false); file.setCheckedWriting(false); file.seek(FileStore.HEADER_LENGTH); if (sort != null) { tapes = New.arrayList(); mainTape = null; } else { tapes = null; mainTape = new ResultDiskTape(); mainTape.pos = FileStore.HEADER_LENGTH; } this.maxBufferSize = db.getSettings().largeResultBufferSize; }
@Override public void createIndexConditions(Session session, TableFilter filter) { if (!(left instanceof ExpressionColumn)) { return; } ExpressionColumn l = (ExpressionColumn) left; if (filter != l.getTableFilter()) { return; } if (session.getDatabase().getSettings().optimizeInList) { ExpressionVisitor visitor = ExpressionVisitor.getNotFromResolverVisitor(filter); for (Expression e : valueList) { if (!e.isEverything(visitor)) { return; } } filter.addIndexCondition(IndexCondition.getInList(l, valueList)); return; } }
/** * @param conn Connection. * @param qry Query. * @param explain Explain. * @return Table. * @throws IgniteCheckedException */ private GridMergeTable createMergeTable( JdbcConnection conn, GridCacheSqlQuery qry, boolean explain) throws IgniteCheckedException { try { Session ses = (Session) conn.getSession(); CreateTableData data = new CreateTableData(); data.tableName = "T___"; data.schema = ses.getDatabase().getSchema(ses.getCurrentSchemaName()); data.create = true; if (!explain) { LinkedHashMap<String, ?> colsMap = qry.columns(); assert colsMap != null; ArrayList<Column> cols = new ArrayList<>(colsMap.size()); for (Map.Entry<String, ?> e : colsMap.entrySet()) { String alias = e.getKey(); GridSqlType t = (GridSqlType) e.getValue(); assert !F.isEmpty(alias); Column c = new Column(alias, t.type(), t.precision(), t.scale(), t.displaySize()); cols.add(c); } data.columns = cols; } else data.columns = planColumns(); return new GridMergeTable(data, ctx); } catch (Exception e) { U.closeQuiet(conn); throw new IgniteCheckedException(e); } }
private Cursor find(Row row) { if (index == null) { // for the case "in(select ...)", the query might // use an optimization and not create the index // up front createIndex(); } Cursor cursor = index.find(session, row, row); while (cursor.next()) { SearchRow found = cursor.getSearchRow(); boolean ok = true; Database db = session.getDatabase(); for (int i = 0; i < row.getColumnCount(); i++) { if (!db.areEqual(row.getValue(i), found.getValue(i))) { ok = false; break; } } if (ok) { return cursor; } } return null; }
public void remove(Session session) throws SQLException { mainIndex.setMainIndexColumn(-1); session.getDatabase().getPageStore().removeMeta(this, session); }
/** * Initialize the order by list. This call may extend the expressions list. * * @param session the session * @param expressions the select list expressions * @param expressionSQL the select list SQL snippets * @param orderList the order by list * @param visible the number of visible columns in the select list * @param mustBeInResult all order by expressions must be in the select list * @param filters the table filters */ static void initOrder( Session session, ArrayList<Expression> expressions, ArrayList<String> expressionSQL, ArrayList<SelectOrderBy> orderList, int visible, boolean mustBeInResult, ArrayList<TableFilter> filters) { Database db = session.getDatabase(); for (SelectOrderBy o : orderList) { Expression e = o.expression; if (e == null) { continue; } // special case: SELECT 1 AS A FROM DUAL ORDER BY A // (oracle supports it, but only in order by, not in group by and // not in having): // SELECT 1 AS A FROM DUAL ORDER BY -A boolean isAlias = false; int idx = expressions.size(); if (e instanceof ExpressionColumn) { // order by expression ExpressionColumn exprCol = (ExpressionColumn) e; String tableAlias = exprCol.getOriginalTableAliasName(); String col = exprCol.getOriginalColumnName(); for (int j = 0; j < visible; j++) { boolean found = false; Expression ec = expressions.get(j); if (ec instanceof ExpressionColumn) { // select expression ExpressionColumn c = (ExpressionColumn) ec; found = db.equalsIdentifiers(col, c.getColumnName()); if (found && tableAlias != null) { String ca = c.getOriginalTableAliasName(); if (ca == null) { found = false; if (filters != null) { // select id from test order by test.id for (int i = 0, size = filters.size(); i < size; i++) { TableFilter f = filters.get(i); if (db.equalsIdentifiers(f.getTableAlias(), tableAlias)) { found = true; break; } } } } else { found = db.equalsIdentifiers(ca, tableAlias); } } } else if (!(ec instanceof Alias)) { continue; } else if (tableAlias == null && db.equalsIdentifiers(col, ec.getAlias())) { found = true; } else { Expression ec2 = ec.getNonAliasExpression(); if (ec2 instanceof ExpressionColumn) { ExpressionColumn c2 = (ExpressionColumn) ec2; String ta = exprCol.getSQL(); String tb = c2.getSQL(); String s2 = c2.getColumnName(); found = db.equalsIdentifiers(col, s2); if (!db.equalsIdentifiers(ta, tb)) { found = false; } } } if (found) { idx = j; isAlias = true; break; } } } else { String s = e.getSQL(); if (expressionSQL != null) { for (int j = 0, size = expressionSQL.size(); j < size; j++) { String s2 = expressionSQL.get(j); if (db.equalsIdentifiers(s2, s)) { idx = j; isAlias = true; break; } } } } if (!isAlias) { if (mustBeInResult) { throw DbException.get(ErrorCode.ORDER_BY_NOT_IN_RESULT, e.getSQL()); } expressions.add(e); String sql = e.getSQL(); expressionSQL.add(sql); } o.columnIndexExpr = ValueExpression.get(ValueInt.get(idx + 1)); Expression expr = expressions.get(idx).getNonAliasExpression(); o.expression = expr; } }