Пример #1
0
 /**
  * Prepare a transaction.
  *
  * @param session the session
  * @param transaction the name of the transaction
  */
 void prepareCommit(Session session, String transaction) {
   if (trace.isDebugEnabled()) {
     trace.debug("log prepare commit s: " + session.getId() + ", " + transaction);
   }
   if (store.getDatabase().getPageStore() == null) {
     // database already closed
     return;
   }
   // store it on a separate log page
   int pageSize = store.getPageSize();
   pageOut.flush();
   pageOut.fillPage();
   Data buffer = getBuffer();
   buffer.writeByte((byte) PREPARE_COMMIT);
   buffer.writeVarInt(session.getId());
   buffer.writeString(transaction);
   if (buffer.length() >= PageStreamData.getCapacity(pageSize)) {
     throw DbException.getInvalidValueException("transaction name (too long)", transaction);
   }
   write(buffer);
   // store it on a separate log page
   flushOut();
   pageOut.fillPage();
   if (store.getDatabase().getFlushOnEachCommit()) {
     flush();
   }
 }
Пример #2
0
 private void closeSession() {
   if (session != null) {
     RuntimeException closeError = null;
     try {
       Command rollback = session.prepareLocal("ROLLBACK");
       rollback.executeUpdate();
     } catch (RuntimeException e) {
       closeError = e;
       server.traceError(e);
     } catch (Exception e) {
       server.traceError(e);
     }
     try {
       session.close();
       server.removeConnection(threadId);
     } catch (RuntimeException e) {
       if (closeError == null) {
         closeError = e;
         server.traceError(e);
       }
     } catch (Exception e) {
       server.traceError(e);
     } finally {
       session = null;
     }
     if (closeError != null) {
       throw closeError;
     }
   }
 }
Пример #3
0
 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;
 }
Пример #4
0
 /**
  * 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;
   }
 }
Пример #5
0
 /**
  * A table is truncated.
  *
  * @param session the session
  * @param tableId the table id
  */
 void logTruncate(Session session, int tableId) {
   if (trace.isDebugEnabled()) {
     trace.debug("log truncate s: " + session.getId() + " table: " + tableId);
   }
   session.addLogPos(logSectionId, logPos);
   logPos++;
   Data buffer = getBuffer();
   buffer.writeByte((byte) TRUNCATE);
   buffer.writeVarInt(session.getId());
   buffer.writeVarInt(tableId);
   write(buffer);
 }
Пример #6
0
 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;
 }
Пример #7
0
 @Override
 public SessionInterface reconnect(boolean write) {
   readSessionState();
   close();
   Session newSession = Engine.getInstance().createSession(connectionInfo);
   newSession.sessionState = sessionState;
   newSession.recreateSessionState();
   if (write) {
     while (!newSession.database.beforeWriting()) {
       // wait until we are allowed to write
     }
   }
   return newSession;
 }
Пример #8
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);
 }
Пример #9
0
 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;
 }
Пример #10
0
 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;
 }
Пример #11
0
 /**
  * Flush the current value, including the margin, to disk.
  *
  * @param session the session
  */
 public synchronized void flush(Session session) {
   if (session == null || !database.isSysTableLocked()) {
     // 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.
     Session sysSession = database.getSystemSession();
     synchronized (sysSession) {
       flushInternal(sysSession);
       sysSession.commit(false);
     }
   } else {
     synchronized (session) {
       flushInternal(session);
     }
   }
 }
Пример #12
0
 @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();
 }
Пример #13
0
 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;
 }
Пример #14
0
 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;
   }
 }
Пример #15
0
 /**
  * A record is added to a table, or removed from a table.
  *
  * @param session the session
  * @param tableId the table id
  * @param row the row to add
  * @param add true if the row is added, false if it is removed
  */
 void logAddOrRemoveRow(Session session, int tableId, Row row, boolean add) {
   if (trace.isDebugEnabled()) {
     trace.debug(
         "log "
             + (add ? "+" : "-")
             + " s: "
             + session.getId()
             + " table: "
             + tableId
             + " row: "
             + row);
   }
   session.addLogPos(logSectionId, logPos);
   logPos++;
   Data data = dataBuffer;
   data.reset();
   int columns = row.getColumnCount();
   data.writeVarInt(columns);
   data.checkCapacity(row.getByteCount(data));
   if (session.isRedoLogBinaryEnabled()) {
     for (int i = 0; i < columns; i++) {
       data.writeValue(row.getValue(i));
     }
   } else {
     for (int i = 0; i < columns; i++) {
       Value v = row.getValue(i);
       if (v.getType() == Value.BYTES) {
         data.writeValue(ValueNull.INSTANCE);
       } else {
         data.writeValue(v);
       }
     }
   }
   Data buffer = getBuffer();
   buffer.writeByte((byte) (add ? ADD : REMOVE));
   buffer.writeVarInt(session.getId());
   buffer.writeVarInt(tableId);
   buffer.writeVarLong(row.getKey());
   if (add) {
     buffer.writeVarInt(data.length());
     buffer.checkCapacity(data.length());
     buffer.write(data.getBytes(), 0, data.length());
   }
   write(buffer);
 }
Пример #16
0
 @Override
 public Row getRow(Session session, long key) {
   TransactionMap<Value, Value> map = getMap(session);
   Value v = map.get(ValueLong.get(key));
   ValueArray array = (ValueArray) v;
   Row row = session.createRow(array.getList(), 0);
   row.setKey(key);
   return row;
 }
Пример #17
0
 /**
  * Re-compile the query, updating the SQL statement.
  *
  * @param session the session
  * @return the query
  */
 public Query recompileQuery(Session session) {
   Prepared p = session.prepare(querySQL);
   if (!(p instanceof Query)) {
     throw DbException.getSyntaxError(querySQL, 0);
   }
   Query query = (Query) p;
   querySQL = query.getPlanSQL();
   return query;
 }
Пример #18
0
 @Override
 public Row get() {
   if (row == null) {
     if (current != null) {
       ValueArray array = (ValueArray) current.getValue();
       row = session.createRow(array.getList(), 0);
       row.setKey(current.getKey().getLong());
     }
   }
   return row;
 }
Пример #19
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;
 }
Пример #20
0
  /**
   * @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);
    }
  }
Пример #21
0
 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;
   }
 }
Пример #22
0
 /**
  * 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;
 }
Пример #23
0
  @Override
  public void add(Session session, Row row) {
    if (mainIndexColumn == -1) {
      if (row.getKey() == 0) {
        row.setKey(++lastKey);
      }
    } else {
      long c = row.getValue(mainIndexColumn).getLong();
      row.setKey(c);
    }

    if (mvTable.getContainsLargeObject()) {
      for (int i = 0, len = row.getColumnCount(); i < len; i++) {
        Value v = row.getValue(i);
        Value v2 = v.link(database, getId());
        if (v2.isLinked()) {
          session.unlinkAtCommitStop(v2);
        }
        if (v != v2) {
          row.setValue(i, v2);
        }
      }
    }

    TransactionMap<Value, Value> map = getMap(session);
    Value key = ValueLong.get(row.getKey());
    Value old = map.getLatest(key);
    if (old != null) {
      String sql = "PRIMARY KEY ON " + table.getSQL();
      if (mainIndexColumn >= 0 && mainIndexColumn < indexColumns.length) {
        sql += "(" + indexColumns[mainIndexColumn].getSQL() + ")";
      }
      DbException e = DbException.get(ErrorCode.DUPLICATE_KEY_1, sql);
      e.setSource(this);
      throw e;
    }
    try {
      map.put(key, ValueArray.get(row.getValueList()));
    } catch (IllegalStateException e) {
      throw DbException.get(ErrorCode.CONCURRENT_UPDATE_1, table.getName());
    }
    lastKey = Math.max(lastKey, row.getKey());
  }
Пример #24
0
 @Override
 public Expression optimize(Session session) {
   userConnection = session.createConnection(false);
   int len = args.length;
   argTypes = new int[len];
   for (int i = 0; i < len; i++) {
     Expression expr = args[i];
     args[i] = expr.optimize(session);
     int type = expr.getType();
     argTypes[i] = type;
   }
   try {
     Aggregate aggregate = getInstance();
     dataType = aggregate.getInternalType(argTypes);
   } catch (SQLException e) {
     throw DbException.convert(e);
   }
   return this;
 }
Пример #25
0
 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;
 }
Пример #26
0
 @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;
   }
 }
Пример #27
0
 @Override
 public void remove(Session session, Row row) {
   if (mvTable.getContainsLargeObject()) {
     for (int i = 0, len = row.getColumnCount(); i < len; i++) {
       Value v = row.getValue(i);
       if (v.isLinked()) {
         session.unlinkAtCommit(v);
       }
     }
   }
   TransactionMap<Value, Value> map = getMap(session);
   try {
     Value old = map.remove(ValueLong.get(row.getKey()));
     if (old == null) {
       throw DbException.get(
           ErrorCode.ROW_NOT_FOUND_WHEN_DELETING_1, getSQL() + ": " + row.getKey());
     }
   } catch (IllegalStateException e) {
     throw DbException.get(ErrorCode.CONCURRENT_UPDATE_1, table.getName());
   }
 }
Пример #28
0
 private Row readRow(Data buff) {
   if (buff.readByte() == 0) {
     return null;
   }
   int mem = buff.readInt();
   int columnCount = buff.readInt();
   long key = buff.readLong();
   int version = buff.readInt();
   if (readUncached) {
     key = 0;
   }
   boolean deleted = buff.readInt() == 1;
   int sessionId = buff.readInt();
   Value[] values = new Value[columnCount];
   for (int i = 0; i < columnCount; i++) {
     Value v;
     if (buff.readByte() == 0) {
       v = null;
     } else {
       v = buff.readValue();
       if (v.isLinked()) {
         // the table id is 0 if it was linked when writing
         // a temporary entry
         if (v.getTableId() == 0) {
           session.unlinkAtCommit(v);
         }
       }
     }
     values[i] = v;
   }
   Row row = new Row(values, mem);
   row.setKey(key);
   row.setVersion(version);
   row.setDeleted(deleted);
   row.setSessionId(sessionId);
   return row;
 }
Пример #29
0
 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;
 }
Пример #30
0
 private int getState(int oldModificationId) {
   if (session.getModificationId() == oldModificationId) {
     return SessionRemote.STATUS_OK;
   }
   return SessionRemote.STATUS_OK_STATE_CHANGED;
 }