@Override public CloneableRecord get( ExecutionContext context, CloneableRecord key, IndexMeta indexMeta, String dbName) { DatabaseEntry keyEntry = new DatabaseEntry(); DatabaseEntry valueEntry = new DatabaseEntry(); keyEntry.setData(indexCodecMap.get(indexMeta.getName()).getKey_codec().encode(key)); OperationStatus status = getDatabase(dbName) .get( context.getTransaction() == null ? null : ((JE_Transaction) context.getTransaction()).txn, keyEntry, valueEntry, LockMode.DEFAULT); if (OperationStatus.SUCCESS != status) { return null; } if (valueEntry.getSize() != 0) { return indexCodecMap.get(indexMeta.getName()).getValue_codec().decode(valueEntry.getData()); } else { return null; } }
@Override public Object scalarCalucate(IRowSet kvPair, ExecutionContext ec) throws TddlRuntimeException { IQueryTree query = this.getQueryPlan(); if (query.isCorrelatedSubquery()) { QueryTreeNode ast = OptimizerUtils.convertPlanToAst(query); // 获取correlated column List<ISelectable> columnsCorrelated = ast.getColumnsCorrelated(); Map<Long, Object> correlatedValues = new HashMap(); // 从rowset中找到对应的column进行替换 for (ISelectable column : columnsCorrelated) { Object value = getValueByIColumnWithException(kvPair, column); correlatedValues.put(column.getCorrelateOnFilterId(), value); } // 替换correlated column OptimizerContext.getContext() .getOptimizer() .assignmentSubquery(ast, correlatedValues, ec.getExtraCmds()); // 重新生成执行计划 query = (IQueryTree) OptimizerContext.getContext() .getOptimizer() .optimizePlan(ast, ec.getParams(), ec.getExtraCmds()); } return this.compute(new Object[] {query}, ec); }
@Override public ISchematicCursor getCursor( ExecutionContext executionContext, IndexMeta meta, IQuery iQuery) throws TddlException { String actualTable = iQuery.getTableName(); return getCursor( executionContext.getTransaction(), meta, executionContext.getIsolation(), actualTable); }
@Override public ITempTableSortCursor tempTableSortCursor( ExecutionContext executionContext, ISchematicCursor cursor, List<IOrderBy> orderBys, boolean sortedDuplicates, long requestID) throws TddlException { try { if (GeneralUtil.getExtraCmdBoolean( executionContext.getExtraCmds(), ConnectionProperties.ALLOW_TEMPORARY_TABLE, false)) { IRepository bdbRepo = ExecutorContext.getContext() .getRepositoryHolder() .getOrCreateRepository( Group.GroupType.BDB_JE.name(), Collections.EMPTY_MAP, executionContext.getExtraCmds()); return new TempTableSortCursor( this, bdbRepo, cursor, orderBys, sortedDuplicates, requestID, executionContext); } throw new IllegalStateException("not allow to use temporary table . allow first"); } catch (Exception e) { closeParentCursor(cursor); throw new TddlException(e); } }
@Override public ISchematicCursor getCursor( ExecutionContext executionContext, IndexMeta indexMeta, String actualTableName) throws TddlException { Database db = getDatabase(actualTableName); if (db == null) { throw new TddlException("table don't contains indexName:" + actualTableName); } ITransaction txn = executionContext.getTransaction(); CursorConfig cc = CursorConfig.DEFAULT; LockMode lm = LockMode.DEFAULT; if (txn != null) { com.sleepycat.je.TransactionConfig _config = ((JE_Transaction) txn).config; if (_config.getReadUncommitted()) { cc = CursorConfig.READ_UNCOMMITTED; lm = LockMode.READ_UNCOMMITTED; } else if (_config.getReadCommitted()) { cc = CursorConfig.READ_COMMITTED; // lm = LockMode.READ_COMMITTED; } } else { cc = CursorConfig.READ_COMMITTED; } JE_Cursor je_cursor = new JE_Cursor( indexMeta, db.openCursor(txn == null ? null : ((JE_Transaction) txn).txn, cc), lm); if (txn != null) { ((JE_Transaction) txn).addCursor(je_cursor); } return new SchematicCursor( je_cursor, je_cursor.getiCursorMeta(), ExecUtils.getOrderBy(indexMeta)); }
@Override public TempTableCursor tempTableCursor( ExecutionContext executionContext, ISchematicCursor cursor, List<IOrderBy> orderBys, boolean sortedDuplicates, long requestID) throws TddlException { try { IRepository bdbRepo = ExecutorContext.getContext() .getRepositoryHolder() .getOrCreateRepository( Group.GroupType.BDB_JE.name(), Collections.EMPTY_MAP, executionContext.getExtraCmds()); return new TempTableCursor( bdbRepo, cursor, orderBys, sortedDuplicates, requestID, executionContext); } catch (Exception e) { closeParentCursor(cursor); throw new TddlException(e); } }
@Override public void delete( ExecutionContext context, CloneableRecord key, IndexMeta indexMeta, String dbName) throws TddlException { DatabaseEntry keyEntry = new DatabaseEntry(); keyEntry.setData(indexCodecMap.get(indexMeta.getName()).getKey_codec().encode(key)); try { getDatabase(dbName) .delete( context.getTransaction() == null ? null : ((JE_Transaction) context.getTransaction()).txn, keyEntry); } catch (LockTimeoutException ex) { throw ex; } catch (ReplicaWriteException ex) { throw new TddlException(ExceptionErrorCodeUtils.Read_only, ex); } }
@Override public TempTableCursor tempTableCursor( ExecutionContext executionContext, IQueryTree plan, List<IOrderBy> orderBys, boolean sortedDuplicates, long requestID) throws TddlException { IRepository bdbRepo = ExecutorContext.getContext() .getRepositoryHolder() .getOrCreateRepository( Group.GroupType.BDB_JE.name(), Collections.EMPTY_MAP, executionContext.getExtraCmds()); return new TempTableCursor(bdbRepo, plan, sortedDuplicates, requestID, executionContext); }
/** * todo:触发更新二级索引 * * @param key * @param value * @throws TddlException */ @Override public void put( ExecutionContext context, CloneableRecord key, CloneableRecord value, IndexMeta indexMeta, String dbName) throws TddlException { DatabaseEntry keyEntry = new DatabaseEntry(); DatabaseEntry valueEntry = new DatabaseEntry(); keyEntry.setData(indexCodecMap.get(indexMeta.getName()).getKey_codec().encode(key)); // 当临时表排序时候可能会用到临时表join,主键插入值为null // if (keyEntry.getData().length == 1 && !isTempTable) { // throw new RuntimeException("pk must not null."); // } if (value != null) { valueEntry.setData(indexCodecMap.get(indexMeta.getName()).getValue_codec().encode(value)); } else { valueEntry = emptyValueEntry; } try { ITransaction transaction = context.getTransaction(); com.sleepycat.je.Transaction txn = null; if (transaction != null && transaction instanceof JE_Transaction) { txn = ((JE_Transaction) transaction).txn; } OperationStatus operationStatus = getDatabase(dbName).put(txn, keyEntry, valueEntry); if (operationStatus.equals(OperationStatus.SUCCESS)) { return; } } catch (LockTimeoutException ex) { throw ex; } catch (ReplicaWriteException ex) { throw new TddlException(ExceptionErrorCodeUtils.Read_only, ex); } }