@Override public synchronized void afterCompletion(int status) { completed = true; synchronizations.remove(id); if (transactionMode == TransactionMode.ISOLATE_READS) { for (TempTable table : tables.values()) { table.getActive().decrementAndGet(); } } else { HashSet<TempTable> current = new HashSet<TempTable>(tempTables.values()); current.retainAll(tables.values()); for (TempTable table : current) { table.getActive().set(0); table.getTree().clearClonedFlags(); } } for (TransactionCallback callback : callbacks) { if (status == Status.STATUS_COMMITTED) { callback.commit(); } else { callback.rollback(); } } callbacks.clear(); }
// Ranjay public static ExpressionInstruction generateTile(TempIR temp, TempTable tTable) { ExpressionInstruction inst = new ExpressionInstruction(); String funcname = tTable.getCurrentFunction().label(); int lastindex = funcname.lastIndexOf("_"); String letter = funcname.substring(lastindex + 1, lastindex + 2); String id = temp.getId(); if (id.startsWith("_ret")) { Integer offset = Integer.parseInt((id.substring(4, id.length()))); offset = 1 * (offset) * 8; inst.setAddr(new AddressingMode(offset, "rax")); } else if (id.startsWith("_rret")) { Integer offset = Integer.parseInt((id.substring(5, id.length()))); offset = 1 * (offset) * 8; inst.setAddr(new AddressingMode(offset, "rcx")); } else if (!(letter.equals("t"))) { if (id.startsWith("_args0")) inst.setAddr(new AddressingMode("rcx")); else if (id.startsWith("_args1")) inst.setAddr(new AddressingMode("rdx")); else if (id.startsWith("_args2")) inst.setAddr(new AddressingMode("r8")); else if (id.startsWith("_args3")) inst.setAddr(new AddressingMode("r9")); else if (id.startsWith("_args")) inst.setAddr( new AddressingMode((Integer.parseInt(id.substring(5, id.length())) - 5) * 8, "rbp")); else { // DANIEL!!, FIX line 203 & 226 so that HashMap<String, String> regs = tTable.getCurrentFunction().getRegAlloc(); // we can have more than 10 arguments HashMap<String, Integer> stack = tTable.getCurrentFunction().getStackLocation(); if (regs.containsKey(id)) { inst.setAddr(new AddressingMode(regs.get(id))); } else { // System.out.println(id); int offset = stack.get(id); inst.setAddr(new AddressingMode(-offset, "rbp")); } } } else { if (id.startsWith("_args0")) { inst.setAddr(new AddressingMode("rdx")); } else if (id.startsWith("_args1")) { inst.setAddr(new AddressingMode("r8")); } else if (id.startsWith("_args2")) { inst.setAddr(new AddressingMode("r9")); } else if (id.startsWith("_args")) { inst.setAddr( new AddressingMode((Integer.parseInt(id.substring(5, id.length())) - 3) * 8, "rbp")); } else { HashMap<String, String> regs = tTable.getCurrentFunction().getRegAlloc(); if (regs.containsKey(id)) { inst.setAddr(new AddressingMode(regs.get(id))); } else { HashMap<String, Integer> stack = tTable.getCurrentFunction().getStackLocation(); int offset = stack.get(id); inst.setAddr(new AddressingMode(-offset, "rbp")); } } } return inst; }
@Override public void close() { super.close(); if (workingQp != null) { workingQp.closeProcessing(); } if (working != null) { working.remove(); } if (intermediate != null) { intermediate.remove(); } }
public TempTableSynchronization(final String id) { this.id = id; for (TempTable tempTable : tempTables.values()) { existingTables.add(tempTable.getId()); } if (transactionMode == TransactionMode.ISOLATE_WRITES) { addCallback( new TransactionCallback() { private Map<String, TempMetadataID> clonedMetadata = new ConcurrentHashMap<String, TempMetadataID>(tempMetadataStore.getData()); private Map<String, TempTable> clonedTables = new ConcurrentHashMap<String, TempTable>(tempTables); @Override public void rollback() { LogManager.logDetail( LogConstants.CTX_DQP, "Rolling back txn", id, "restoring", clonedTables.keySet(), "using rollback tables", tables); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ // remove any tables created in the scope of this txn tempTables.values().removeAll(clonedTables.values()); for (TempTable table : tempTables.values()) { table.remove(); } // restore the state tempMetadataStore.getData().clear(); tempMetadataStore.getData().putAll(clonedMetadata); tempTables.clear(); tempTables.putAll(clonedTables); // overlay the rollback tables tempTables.putAll(tables); } @Override public void commit() { // remove any original tables that were removed in this txn clonedTables.values().removeAll(tempTables.values()); for (TempTable table : clonedTables.values()) { table.remove(); } } }); } }
public void removeTempTableByName(final String tempTableName, CommandContext context) throws TeiidProcessingException { TempTableSynchronization synch = getSynchronization(context); tempMetadataStore.removeTempGroup(tempTableName); final TempTable table = this.tempTables.remove(tempTableName); if (table == null) { return; } if (transactionMode != TransactionMode.ISOLATE_WRITES || synch == null || !synch.existingTables.contains(table.getId())) { table.remove(); } }
/** * Ensure the temp table is ready for use. If a temp table other than the one passed in is * returned it should be used instead. * * @param tempTable * @param context * @param bufferManager * @param dataMgr * @throws TeiidComponentException * @throws TeiidProcessingException */ public TempTable process(TempTable tempTable) throws TeiidComponentException, TeiidProcessingException { if (!tempTable.getColumnMap().keySet().containsAll(columns)) { // sanity check to make sure that we haven't inappropriately redefined the common table throw new TeiidComponentException( "failed to plan common table appropriately " + columns + " " + tempTable.getColumns()); // $NON-NLS-1$ //$NON-NLS-2$ } tempTable.insert(iterator, columns, false, null); tempTable.setUpdatable(false); close(); return tempTable; }
// Ranjay public static Instruction generateTile(ReturnIR ret, TempTable tTable) { Instruction inst = new Instruction(); if (ret.getChildren().size() > 1) { inst.add(new Tile(1, "movq", new AddressingMode("rdi"), new AddressingMode("rax"))); /*int i = 0; for(VisualizableIRNode child: ret.getChildren()){ ExpressionInstruction childInst = (ExpressionInstruction) generateTile((SyntaxIR) child,tTable); inst.addAll(childInst.getTiles()); Tile t = new Tile(1, "movq", childInst.getAddr(), new AddressingMode(i*8, "rdi")); inst.add(t); i++; }*/ } if (ret.getChildren().size() == 1) { Instruction retVal = generateTile((SyntaxIR) ret.getChildren().get(0), tTable); inst.addAll(retVal.getTiles()); Tile t = new Tile( 1, "movq", ((ExpressionInstruction) retVal).getAddr(), new AddressingMode("rax")); inst.add(t); } // Before we return we need to pop all the local variables and throw them away AddressingMode rbp = new AddressingMode("rbp"); AddressingMode rsp = new AddressingMode("rsp"); Integer newLabel = tTable.getNewJumpLabel(); inst.add(new Tile(1, "ret" + newLabel + ": ", null, null)); inst.add(new Tile(1, "cmp", rbp, rsp)); inst.add(new Tile(1, "je", new AddressingMode("retend" + newLabel, true), null)); inst.add(new Tile(1, "popq", new AddressingMode("r12"), null)); inst.add(new Tile(1, "jmp", new AddressingMode("ret" + newLabel, true), null)); inst.add(new Tile(1, "retend" + newLabel + ": ", null, null)); inst.add(new Tile(1, "ret", null, null)); return inst; }
private void processPlan(TempTable tempTable, TempTable target) throws TeiidComponentException, TeiidProcessingException { List<Object> row = null; List tuple = null; while ((tuple = this.iterator.nextTuple()) != null) { if (all) { row = new ArrayList<Object>(tuple); row.add(0, tempTable.getRowCount()); } else { row = tuple; } if (tempTable.insertTuple(row, false, false)) { target.insertTuple(row, false, true); } } iterator.closeSource(); }
@Override public TempTable process(TempTable tempTable) throws TeiidComponentException, TeiidProcessingException { if (initial) { // process initial plan if (working == null) { working = tempTable.clone(); intermediate = tempTable.clone(); } processPlan(tempTable, working); initial = false; } // continue to build the result while (working.getRowCount() > 0) { if (building) { return working; } building = true; try { if (workingQp == null) { recursive.reset(); workingQp = new QueryProcessor( recursive, this.queryProcessor.getContext(), this.queryProcessor.getBufferManager(), this.queryProcessor.getProcessorDataManager()); this.iterator = new BatchProducerTupleSource(workingQp); } processPlan(tempTable, intermediate); iterations++; if (maxIterations > 0 && iterations > maxIterations) { throw new TeiidProcessingException( QueryPlugin.Event.TEIID31158, QueryPlugin.Util.gs( QueryPlugin.Event.TEIID31158, maxIterations, tempTable.getMetadataId().getName())); } this.workingQp.closeProcessing(); this.workingQp = null; // swap the intermediate to be the working working.truncate(true); TempTable temp = working; working = intermediate; intermediate = temp; } finally { building = false; } } // we truncate rater than remove because we are cloned off of the original this.working.truncate(true); this.intermediate.truncate(true); tempTable.setUpdatable(false); return tempTable; }
// Ranjay, public static Instruction generateTile(LabelIR label, TempTable tTable) { ArrayList<Tile> result = new ArrayList<Tile>(); if (label.getName().startsWith("_I")) { Tile globl = new Tile(0, ".globl " + label.getName(), null, null); result.add(globl); Tile t = new Tile(0, label.getName() + ": ", null, null); result.add(t); tTable.setCurrentFunction(label); result.add(new Tile(1, "movq", new AddressingMode("rsp"), new AddressingMode("rbp"))); result.add( new Tile( 1, "sub", new AddressingMode(label.getStackLocation().size() * 8), new AddressingMode("rsp"))); } else { result.add(new Tile(0, label.getName() + ": ", null, null)); } Instruction inst = new Instruction(); inst.setTiles(result); return inst; }
public void setUpdatable(String name, boolean updatable) { TempTable table = tempTables.get(name); if (table != null) { table.setUpdatable(updatable); } }
private TupleSource handleSystemProcedures(final CommandContext context, StoredProcedure proc) throws TeiidComponentException, QueryMetadataException, QueryProcessingException, QueryResolverException, QueryValidatorException, TeiidProcessingException, ExpressionEvaluationException { final QueryMetadataInterface metadata = context.getMetadata(); if (StringUtil.endsWithIgnoreCase(proc.getProcedureCallableName(), REFRESHMATVIEW)) { Object groupID = validateMatView( metadata, (String) ((Constant) proc.getParameter(2).getExpression()).getValue()); TempMetadataID matTableId = context.getGlobalTableStore().getGlobalTempTableMetadataId(groupID); final GlobalTableStore globalStore = getGlobalStore(context, matTableId); String matViewName = metadata.getFullName(groupID); String matTableName = metadata.getFullName(matTableId); LogManager.logDetail( LogConstants.CTX_MATVIEWS, "processing refreshmatview for", matViewName); // $NON-NLS-1$ boolean invalidate = Boolean.TRUE.equals(((Constant) proc.getParameter(3).getExpression()).getValue()); boolean needsLoading = globalStore.needsLoading(matTableName, globalStore.getAddress(), true, true, invalidate); if (!needsLoading) { return CollectionTupleSource.createUpdateCountTupleSource(-1); } GroupSymbol matTable = new GroupSymbol(matTableName); matTable.setMetadataID(matTableId); return loadGlobalTable(context, matTable, matTableName, globalStore); } else if (StringUtil.endsWithIgnoreCase(proc.getProcedureCallableName(), REFRESHMATVIEWROW)) { final Object groupID = validateMatView( metadata, (String) ((Constant) proc.getParameter(2).getExpression()).getValue()); TempMetadataID matTableId = context.getGlobalTableStore().getGlobalTempTableMetadataId(groupID); final GlobalTableStore globalStore = getGlobalStore(context, matTableId); Object pk = metadata.getPrimaryKey(groupID); String matViewName = metadata.getFullName(groupID); if (pk == null) { throw new QueryProcessingException( QueryPlugin.Event.TEIID30230, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30230, matViewName)); } List<?> ids = metadata.getElementIDsInKey(pk); Constant key = (Constant) proc.getParameter(3).getExpression(); Object initialValue = key.getValue(); SPParameter keyOther = proc.getParameter(4); Object[] otherCols = null; int length = 1; if (keyOther != null) { otherCols = ((ArrayImpl) ((Constant) keyOther.getExpression()).getValue()).getValues(); if (otherCols != null) { length += otherCols.length; } } if (ids.size() != length) { throw new QueryProcessingException( QueryPlugin.Event.TEIID30231, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30231, matViewName, ids.size(), length)); } final String matTableName = RelationalPlanner.MAT_PREFIX + matViewName.toUpperCase(); MatTableInfo info = globalStore.getMatTableInfo(matTableName); if (!info.isValid()) { return CollectionTupleSource.createUpdateCountTupleSource(-1); } TempTable tempTable = globalStore.getTempTable(matTableName); if (!tempTable.isUpdatable()) { throw new QueryProcessingException( QueryPlugin.Event.TEIID30232, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30232, matViewName)); } Iterator<?> iter = ids.iterator(); final Object[] params = new Object[length]; StringBuilder criteria = new StringBuilder(); for (int i = 0; i < length; i++) { Object id = iter.next(); String targetTypeName = metadata.getElementType(id); Object value = i == 0 ? initialValue : otherCols[i - 1]; value = DataTypeManager.transformValue(value, DataTypeManager.getDataTypeClass(targetTypeName)); params[i] = value; if (i != 0) { criteria.append(" AND "); // $NON-NLS-1$ } criteria.append(metadata.getFullName(id)).append(" = ?"); // $NON-NLS-1$ } LogManager.logInfo( LogConstants.CTX_MATVIEWS, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30012, matViewName, Arrays.toString(params))); String queryString = Reserved.SELECT + " * " + Reserved.FROM + ' ' + matViewName + ' ' + Reserved.WHERE + ' ' + //$NON-NLS-1$ criteria.toString() + ' ' + Reserved.OPTION + ' ' + Reserved.NOCACHE; final QueryProcessor qp = context .getQueryProcessorFactory() .createQueryProcessor(queryString, matViewName.toUpperCase(), context, params); final TupleSource ts = new BatchCollector.BatchProducerTupleSource(qp); return new ProxyTupleSource() { @Override protected TupleSource createTupleSource() throws TeiidComponentException, TeiidProcessingException { List<?> tuple = ts.nextTuple(); boolean delete = false; if (tuple == null) { delete = true; tuple = Arrays.asList(params); } else { tuple = new ArrayList<Object>(tuple); // ensure the list is serializable } List<?> result = globalStore.updateMatViewRow(matTableName, tuple, delete); if (eventDistributor != null) { eventDistributor.updateMatViewRow( context.getVdbName(), context.getVdbVersion(), metadata.getName(metadata.getModelID(groupID)), metadata.getName(groupID), tuple, delete); } return CollectionTupleSource.createUpdateCountTupleSource(result != null ? 1 : 0); } @Override public void closeSource() { super.closeSource(); qp.closeProcessing(); } }; } return null; }
private TupleSource loadGlobalTable( final CommandContext context, final GroupSymbol group, final String tableName, final GlobalTableStore globalStore) throws TeiidComponentException, TeiidProcessingException { LogManager.logInfo( LogConstants.CTX_MATVIEWS, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30013, tableName)); final QueryMetadataInterface metadata = context.getMetadata(); final List<ElementSymbol> allColumns = ResolverUtil.resolveElementsInGroup(group, metadata); final TempTable table = globalStore.createMatTable(tableName, group); table.setUpdatable(false); return new ProxyTupleSource() { TupleSource insertTupleSource; boolean success; QueryProcessor qp; boolean closed; boolean errored; @Override protected TupleSource createTupleSource() throws TeiidComponentException, TeiidProcessingException { int rowCount = -1; try { if (insertTupleSource == null) { String fullName = metadata.getFullName(group.getMetadataID()); String transformation = metadata.getVirtualPlan(group.getMetadataID()).getQuery(); qp = context .getQueryProcessorFactory() .createQueryProcessor(transformation, fullName, context); insertTupleSource = new BatchCollector.BatchProducerTupleSource(qp); } table.insert(insertTupleSource, allColumns, false, null); table.getTree().compact(); rowCount = table.getRowCount(); Determinism determinism = qp.getContext().getDeterminismLevel(); context.setDeterminismLevel(determinism); // TODO: could pre-process indexes to remove overlap for (Object index : metadata.getIndexesInGroup(group.getMetadataID())) { List<ElementSymbol> columns = GlobalTableStoreImpl.resolveIndex(metadata, allColumns, index); table.addIndex(columns, false); } for (Object key : metadata.getUniqueKeysInGroup(group.getMetadataID())) { List<ElementSymbol> columns = GlobalTableStoreImpl.resolveIndex(metadata, allColumns, key); table.addIndex(columns, true); } CacheHint hint = table.getCacheHint(); if (hint != null && table.getPkLength() > 0) { table.setUpdatable(hint.isUpdatable(false)); } if (determinism.compareTo(Determinism.VDB_DETERMINISTIC) < 0 && (hint == null || hint.getScope() == null || Scope.VDB.compareTo(hint.getScope()) <= 0)) { LogManager.logInfo( LogConstants.CTX_DQP, QueryPlugin.Util.gs( QueryPlugin.Event.TEIID31143, determinism, tableName)); // $NON-NLS-1$ } globalStore.loaded(tableName, table); success = true; LogManager.logInfo( LogConstants.CTX_MATVIEWS, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30014, tableName, rowCount)); return CollectionTupleSource.createUpdateCountTupleSource(rowCount); } catch (BlockedException e) { throw e; } catch (Exception e) { errored = true; LogManager.logError( LogConstants.CTX_MATVIEWS, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30015, tableName)); closeSource(); rethrow(e); throw new AssertionError(); } } @Override public void closeSource() { if (closed) { return; } if (!errored) { LogManager.logInfo( LogConstants.CTX_MATVIEWS, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31153, tableName)); } closed = true; if (!success) { globalStore.failedLoad(tableName); table.remove(); } if (qp != null) { qp.closeProcessing(); } super.closeSource(); } }; }
// Colin check that this is correct private static Instruction makeCall(CallIR call, TempTable tTable) { Instruction inst = new Instruction(); // Now we can finally make the call AddressingMode func = new AddressingMode(((NameIR) call.getChildren().get(0)).getLabel(), true); // if the stack isn't 16 bit aligned, we need to do this AddressingMode rbp = new AddressingMode("rbp"); AddressingMode rsp = new AddressingMode("rsp"); AddressingMode r12 = new AddressingMode("r12"); AddressingMode r13 = new AddressingMode("r13"); // Check if the 3rd bit is 1 or zero and set the carry bit accordingly inst.add(new Tile(0, "movq", new AddressingMode(0), new AddressingMode("rbx"))); inst.add(new Tile(1, "bt", new AddressingMode(3), rsp)); Integer callInt = tTable.getNewJumpLabel(); // jump to rspJmp if stack pointer is even inst.add(new Tile(1, "jnc", new AddressingMode("rspJmp" + callInt, true), null)); // stack pointer was odd inst.add(new Tile(1, "movq", new AddressingMode(1), r12)); inst.add(new Tile(1, "jmp", new AddressingMode("rspend" + callInt, true), null)); inst.add(new Tile(1, "rspJmp" + callInt + ": ", null, null)); // save that stack pointer was even in r12 inst.add(new Tile(1, "movq", new AddressingMode(0), r12)); inst.add(new Tile(1, "rspend" + callInt + ": ", null, null)); // check rbp for being divisible by 8(odd) or 16(even) inst.add(new Tile(1, "bt", new AddressingMode(3), rbp)); inst.add(new Tile(1, "jnc", new AddressingMode("rbpJmp" + callInt, true), null)); // didn't jump since base pointer is odd inst.add(new Tile(1, "movq", new AddressingMode(1), r13)); inst.add(new Tile(1, "jmp", new AddressingMode("rbpend" + callInt, true), null)); inst.add(new Tile(1, "rbpJmp" + callInt + ": ", null, null)); // base pointer is even inst.add(new Tile(1, "movq", new AddressingMode(0), r13)); inst.add(new Tile(1, "rbpend" + callInt + ": ", null, null)); // Now we just need to logically xnor r12 and r13, i.e. if they are both zero or both one // Test r1,r2 sets the parity flag to the xnor so we will use that inst.add(new Tile(1, "test", r12, r13)); // jump to extraPush(which doesn't make an extra Push) if they were equal inst.add(new Tile(1, "jnp", new AddressingMode("extraPush" + callInt, true), null)); // ret.add(new Tile(1, "sub", r12, r13)); // ret.add(new Tile(1, "jne", new AddressingMode("extraPush" + callInt, true), null)); inst.add(new Tile(1, "pushq", new AddressingMode(0), null)); // also store value in rbx(a callee saved register) so we can know we were odd after return inst.add(new Tile(1, "movq", new AddressingMode(1), new AddressingMode("rbx"))); inst.add(new Tile(1, "extraPush" + callInt + ": ", null, null)); // otherwise store 0 in rbx // windows requires 32 bytes of ghost space inst.add(new Tile(1, "pushq", new AddressingMode(0), null)); inst.add(new Tile(1, "pushq", new AddressingMode(0), null)); inst.add(new Tile(1, "pushq", new AddressingMode(0), null)); inst.add(new Tile(1, "pushq", new AddressingMode(0), null)); inst.add(new Tile(1, "call", func, null)); inst.add(new Tile(1, "popq", r13, null)); inst.add(new Tile(1, "popq", r13, null)); inst.add(new Tile(1, "popq", r13, null)); inst.add(new Tile(1, "popq", r13, null)); inst.add(new Tile(1, "cmp", new AddressingMode(1), new AddressingMode("rbx"))); // if rbx is 1 then we had to push an extra frame before so pop it off if rbx = 1 inst.add(new Tile(1, "jne", new AddressingMode("extraPop" + callInt, true), null)); inst.add(new Tile(1, "popq", r13, null)); inst.add(new Tile(1, "extraPop" + callInt + ": ", null, null)); inst.add(new Tile(1, "movq", new AddressingMode(0), new AddressingMode("rbx"))); // assuming the ret call moves the stack pointer back to before the arguments we should if (call.getretsize() > 1) { inst.add(new Tile(1, "movq", new AddressingMode("rcx"), new AddressingMode("rax"))); } // now we need to pop off extra arguments that we moved onto the stack int argumentsize = call.getChildren().size() - 1; if (call.getretsize() > 1 && argumentsize > 3) { for (int i = argumentsize; i > 3; i--) { inst.add(new Tile(1, "popq", new AddressingMode("r12"), null)); } } else if (argumentsize > 4) { for (int i = argumentsize; i > 4; i--) { inst.add(new Tile(1, "popq", new AddressingMode("r12"), null)); } } return inst; }
// Ranjay public static Instruction generateTile(CallIR call, TempTable tTable) { ExpressionInstruction inst = new ExpressionInstruction(); // Push caller saved: rcx,rdx,rsp,rsi,rdi,r8,r9,r10,r11 inst.add( new Tile( 1, "movq", new AddressingMode("rcx"), new AddressingMode( -1 * tTable.getCurrentFunction().getStackLocation().get("rcx"), "rbp"))); inst.add( new Tile( 1, "movq", new AddressingMode("rdx"), new AddressingMode( -1 * tTable.getCurrentFunction().getStackLocation().get("rdx"), "rbp"))); inst.add( new Tile( 1, "movq", new AddressingMode("rsp"), new AddressingMode( -1 * tTable.getCurrentFunction().getStackLocation().get("rsp"), "rbp"))); inst.add( new Tile( 1, "movq", new AddressingMode("rsi"), new AddressingMode( -1 * tTable.getCurrentFunction().getStackLocation().get("rsi"), "rbp"))); inst.add( new Tile( 1, "movq", new AddressingMode("rdi"), new AddressingMode( -1 * tTable.getCurrentFunction().getStackLocation().get("rdi"), "rbp"))); inst.add( new Tile( 1, "movq", new AddressingMode("r8"), new AddressingMode( -1 * tTable.getCurrentFunction().getStackLocation().get("r8"), "rbp"))); inst.add( new Tile( 1, "movq", new AddressingMode("r9"), new AddressingMode( -1 * tTable.getCurrentFunction().getStackLocation().get("r9"), "rbp"))); inst.add( new Tile( 1, "movq", new AddressingMode("r10"), new AddressingMode( -1 * tTable.getCurrentFunction().getStackLocation().get("r10"), "rbp"))); inst.add( new Tile( 1, "movq", new AddressingMode("r11"), new AddressingMode( -1 * tTable.getCurrentFunction().getStackLocation().get("r11"), "rbp"))); inst.add( new Tile( 1, "movq", new AddressingMode("r15"), new AddressingMode( -1 * tTable.getCurrentFunction().getStackLocation().get("r15"), "rbp"))); inst.add(new Tile(1, "pushq", new AddressingMode("rbx"), null)); inst.add(new Tile(1, "pushq", new AddressingMode("rbp"), null)); // handle arguments Instruction args = handleArguments(call, tTable); inst.addAll(args.getTiles()); // make call Instruction ooo = makeCall(call, tTable); inst.addAll(ooo.getTiles()); // pop caller saved inst.add(new Tile(1, "popq", new AddressingMode("rbp"), null)); inst.add(new Tile(1, "popq", new AddressingMode("rbx"), null)); inst.add( new Tile( 1, "movq", new AddressingMode( -1 * tTable.getCurrentFunction().getStackLocation().get("r15"), "rbp"), new AddressingMode("r15"))); inst.add( new Tile( 1, "movq", new AddressingMode( -1 * tTable.getCurrentFunction().getStackLocation().get("r11"), "rbp"), new AddressingMode("r11"))); inst.add( new Tile( 1, "movq", new AddressingMode( -1 * tTable.getCurrentFunction().getStackLocation().get("r10"), "rbp"), new AddressingMode("r10"))); inst.add( new Tile( 1, "movq", new AddressingMode( -1 * tTable.getCurrentFunction().getStackLocation().get("r9"), "rbp"), new AddressingMode("r9"))); inst.add( new Tile( 1, "movq", new AddressingMode( -1 * tTable.getCurrentFunction().getStackLocation().get("r8"), "rbp"), new AddressingMode("r8"))); inst.add( new Tile( 1, "movq", new AddressingMode( -1 * tTable.getCurrentFunction().getStackLocation().get("rdi"), "rbp"), new AddressingMode("rdi"))); inst.add( new Tile( 1, "movq", new AddressingMode( -1 * tTable.getCurrentFunction().getStackLocation().get("rsi"), "rbp"), new AddressingMode("rsi"))); inst.add( new Tile( 1, "movq", new AddressingMode( -1 * tTable.getCurrentFunction().getStackLocation().get("rsp"), "rbp"), new AddressingMode("rsp"))); inst.add( new Tile( 1, "movq", new AddressingMode( -1 * tTable.getCurrentFunction().getStackLocation().get("rdx"), "rbp"), new AddressingMode("rdx"))); inst.add( new Tile( 1, "movq", new AddressingMode( -1 * tTable.getCurrentFunction().getStackLocation().get("rcx"), "rbp"), new AddressingMode("rcx"))); inst.setAddr(new AddressingMode("rax")); return inst; }
// Ranjay public static ExpressionInstruction generateTile(OpIR op, TempTable tTable) { ExpressionInstruction inst = new ExpressionInstruction(); if (op.getChildren().size() > 1) { ExpressionInstruction child1 = (ExpressionInstruction) generateTile((SyntaxIR) op.getChildren().get(0), tTable); ExpressionInstruction child2 = (ExpressionInstruction) generateTile((SyntaxIR) op.getChildren().get(1), tTable); inst.addAll(child1.getTiles()); inst.add(new Tile(1, "pushq", child1.getAddr(), null)); inst.addAll(child2.getTiles()); inst.add(new Tile(1, "movq", child2.getAddr(), new AddressingMode("r12"))); inst.add(new Tile(1, "popq", new AddressingMode("r13"), null)); if (op.getOp() == opEnum.DIVIDE || op.getOp() == opEnum.MODULO) { inst.add(new Tile(1, "pushq", new AddressingMode("rdx"), null)); inst.add(new Tile(1, "pushq", new AddressingMode("rax"), null)); inst.add(new Tile(1, "movq", new AddressingMode("r13"), new AddressingMode("rax"))); // we need to sign extend r13 into rdx inst.add(new Tile(1, "cmp", new AddressingMode(0), new AddressingMode("r13"))); // if r12 is less than 0 we move FFFFFFFFFFFFFFFF to rdx otherwise move zero int div = tTable.getNewJumpLabel(); inst.add(new Tile(1, "jl", new AddressingMode("div" + div, true), null)); // fall through to moving zero inst.add(new Tile(1, "movq", new AddressingMode(0), new AddressingMode("rdx"))); inst.add(new Tile(1, "jmp", new AddressingMode("divEnd" + div, true), null)); inst.add(new Tile(1, "div" + div + ":", null, null)); inst.add(new Tile(1, "movq", new AddressingMode(-1), new AddressingMode("rdx"))); inst.add(new Tile(1, "divEnd" + div + ":", null, null)); inst.add(new Tile(1, "idiv", new AddressingMode("r12"), null)); // The result is put in RAX so we need to push that on the stack if (op.getOp() == opEnum.DIVIDE) inst.add(new Tile(1, "movq", new AddressingMode("rax"), new AddressingMode("r12"))); else inst.add(new Tile(1, "movq", new AddressingMode("rdx"), new AddressingMode("r12"))); inst.add(new Tile(1, "popq", new AddressingMode("rax"), null)); inst.add(new Tile(1, "popq", new AddressingMode("rdx"), null)); inst.setAddr(new AddressingMode("r12")); } else if (op.returnsBool() && op.getOp() != opEnum.AND && op.getOp() != opEnum.OR) { int x = tTable.getNewJumpLabel(); inst.add(new Tile(1, "cmp", new AddressingMode("r12"), new AddressingMode("r13"))); inst.add(new Tile(1, op.opToAssembly(), new AddressingMode("_true" + x, true), null)); inst.add(new Tile(1, "movq", new AddressingMode(0), new AddressingMode("r12"))); inst.add(new Tile(1, "jmp", new AddressingMode("_end" + x, true), null)); inst.add(new Tile(1, "_true" + x + ": ", null, null)); inst.add(new Tile(1, "movq", new AddressingMode(1), new AddressingMode("r12"))); inst.add(new Tile(1, "_end" + x + ": ", null, null)); inst.setAddr(new AddressingMode("r12")); } else if (op.getOp() == opEnum.LSHIFT || op.getOp() == opEnum.RSHIFT) { inst.add(new Tile(1, op.opToAssembly(), new AddressingMode(3), new AddressingMode("r13"))); inst.setAddr(new AddressingMode("r13")); } else { inst.add( new Tile(1, op.opToAssembly(), new AddressingMode("r12"), new AddressingMode("r13"))); inst.setAddr(new AddressingMode("r13")); } } else { ExpressionInstruction child = (ExpressionInstruction) generateTile((SyntaxIR) op.getChildren().get(0), tTable); inst.addAll(child.getTiles()); switch (op.getOp()) { case NOT: inst.add(new Tile(1, "btc", new AddressingMode(0), child.getAddr())); inst.setAddr(child.getAddr()); break; case UNARY_MINUS: inst.add(new Tile(1, "neg", child.getAddr(), null)); inst.setAddr(child.getAddr()); break; } } return inst; }
TupleSource registerRequest(final CommandContext context, String modelName, final Command command) throws TeiidComponentException, TeiidProcessingException { final TempTableStore contextStore = context.getTempTableStore(); if (command instanceof Query) { Query query = (Query) command; if (modelName != null && !modelName.equals(TempMetadataAdapter.TEMP_MODEL.getID())) { return null; } return registerQuery(context, contextStore, query); } if (command instanceof ProcedureContainer) { if (command instanceof StoredProcedure) { StoredProcedure proc = (StoredProcedure) command; if (CoreConstants.SYSTEM_ADMIN_MODEL.equals(modelName)) { TupleSource result = handleSystemProcedures(context, proc); if (result != null) { return result; } } else if (proc.getGroup().isGlobalTable()) { return handleCachedProcedure(context, proc); } return null; // it's not a stored procedure we want to handle } final GroupSymbol group = ((ProcedureContainer) command).getGroup(); if (!modelName.equals(TempMetadataAdapter.TEMP_MODEL.getID()) || !group.isTempGroupSymbol()) { return null; } return new ProxyTupleSource() { @Override protected TupleSource createTupleSource() throws TeiidComponentException, TeiidProcessingException { final String groupKey = group.getNonCorrelationName(); final TempTable table = contextStore.getOrCreateTempTable( groupKey, command, bufferManager, true, true, context, group); if (command instanceof Insert) { Insert insert = (Insert) command; TupleSource ts = insert.getTupleSource(); if (ts == null) { Evaluator eval = new Evaluator(Collections.emptyMap(), TempTableDataManager.this, context); List<Object> values = new ArrayList<Object>(insert.getValues().size()); for (Expression expr : (List<Expression>) insert.getValues()) { values.add(eval.evaluate(expr, null)); } ts = new CollectionTupleSource(Arrays.asList(values).iterator()); } return table.insert(ts, insert.getVariables(), true, context); } if (command instanceof Update) { final Update update = (Update) command; final Criteria crit = update.getCriteria(); return table.update(crit, update.getChangeList()); } if (command instanceof Delete) { final Delete delete = (Delete) command; final Criteria crit = delete.getCriteria(); if (crit == null) { // TODO: we'll add a real truncate later int rows = table.truncate(false); return CollectionTupleSource.createUpdateCountTupleSource(rows); } return table.delete(crit); } throw new AssertionError("unknown command " + command); // $NON-NLS-1$ } }; } if (command instanceof Create) { Create create = (Create) command; String tempTableName = create.getTable().getName(); if (contextStore.hasTempTable(tempTableName)) { throw new QueryProcessingException( QueryPlugin.Event.TEIID30229, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30229, tempTableName)); } if (create.getTableMetadata() != null) { contextStore.addForeignTempTable(tempTableName, create); } else { contextStore.addTempTable(tempTableName, create, bufferManager, true, context); } return CollectionTupleSource.createUpdateCountTupleSource(0); } if (command instanceof Drop) { String tempTableName = ((Drop) command).getTable().getName(); contextStore.removeTempTableByName(tempTableName, context); return CollectionTupleSource.createUpdateCountTupleSource(0); } if (command instanceof AlterTempTable) { AlterTempTable att = (AlterTempTable) command; TempTable tt = contextStore.getTempTable(att.getTempTable()); Assertion.isNotNull(tt, "Table doesn't exist"); // $NON-NLS-1$ tt.setUpdatable(false); if (att.getIndexColumns() != null && tt.getRowCount() > 2 * tt.getTree().getPageSize(true)) { for (List<ElementSymbol> cols : att.getIndexColumns()) { tt.addIndex(cols, false); } } return CollectionTupleSource.createUpdateCountTupleSource(0); } return null; }
private void buildWithTable(String tempTableID, TableProcessor withProcessor, TempTable tempTable) throws TeiidComponentException, ExpressionEvaluationException, TeiidProcessingException { tempTable.insert(new BatchIterator(withProcessor.queryProcessor), withProcessor.columns, false); tempTable.setUpdatable(false); processors.remove(tempTableID); }
private TempTable getTempTable( String tempTableID, Command command, BufferManager buffer, boolean delegate, boolean forUpdate, CommandContext context) throws TeiidProcessingException { final TempTable tempTable = tempTables.get(tempTableID); if (tempTable != null) { // isolate if needed if (forUpdate) { if (transactionMode == TransactionMode.ISOLATE_WRITES) { TransactionContext tc = context.getTransactionContext(); if (tc != null) { TempTableSynchronization synch = getSynchronization(context); if (synch != null && synch.existingTables.contains(tempTable.getId())) { TempTable result = synch.tables.get(tempTableID); if (result == null) { synchronized (synch) { if (synch.isCompleted()) { throw new AssertionError("Expected active transaction"); // $NON-NLS-1$ } if (!tempTable.getActive().compareAndSet(0, 1)) { throw new TeiidProcessingException( QueryPlugin.Event.TEIID30227, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30227, tempTableID)); } synch.tables.put(tempTableID, tempTable.clone()); } } return tempTable; } } else if (tempTable.getActive().get() != 0) { throw new TeiidProcessingException( QueryPlugin.Event.TEIID30227, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30227, tempTableID)); } } } else if (transactionMode == TransactionMode.ISOLATE_READS) { TransactionContext tc = context.getTransactionContext(); if (tc != null && tc.getIsolationLevel() > Connection.TRANSACTION_READ_COMMITTED) { TempTableSynchronization synch = getSynchronization(context); if (synch != null) { TempTable result = synch.tables.get(tempTableID); if (result == null) { result = tempTable; synchronized (synch) { if (!synch.isCompleted()) { synch.tables.put(tempTableID, tempTable); result.getActive().getAndIncrement(); } } } return result; } } } return tempTable; } if (delegate && this.parentTempTableStore != null) { return this.parentTempTableStore.getTempTable( tempTableID, command, buffer, delegate, forUpdate, context); } return null; }
private TupleSource updateMatviewRows( final CommandContext context, final QueryMetadataInterface metadata, final Object groupID, final GlobalTableStore globalStore, final String matViewName, List<?> ids, Object[][] params) throws QueryProcessingException, TeiidComponentException, QueryMetadataException, TransformationException { final String matTableName = RelationalPlanner.MAT_PREFIX + matViewName.toUpperCase(); MatTableInfo info = globalStore.getMatTableInfo(matTableName); if (!info.isValid()) { return CollectionTupleSource.createUpdateCountTupleSource(-1); } TempTable tempTable = globalStore.getTempTable(matTableName); if (!tempTable.isUpdatable()) { throw new QueryProcessingException( QueryPlugin.Event.TEIID30232, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30232, matViewName)); } List<Object[]> converted = new ArrayList<Object[]>(); for (Object[] param : params) { if (param == null || ids.size() != param.length) { throw new QueryProcessingException( QueryPlugin.Event.TEIID30231, QueryPlugin.Util.gs( QueryPlugin.Event.TEIID30231, matViewName, ids.size(), param == null ? 0 : param.length)); } final Object[] vals = new Object[param.length]; for (int i = 0; i < ids.size(); i++) { Object value = param[i]; String targetTypeName = metadata.getElementType(ids.get(i)); value = DataTypeManager.transformValue(value, DataTypeManager.getDataTypeClass(targetTypeName)); vals[i] = value; } converted.add(vals); } final Iterator<Object[]> paramIter = converted.iterator(); Iterator<?> iter = ids.iterator(); StringBuilder criteria = new StringBuilder(); for (int i = 0; i < ids.size(); i++) { Object id = iter.next(); String targetTypeName = metadata.getElementType(id); if (i != 0) { criteria.append(" AND "); // $NON-NLS-1$ } criteria.append(metadata.getFullName(id)).append(" = ?"); // $NON-NLS-1$ } final String queryString = Reserved.SELECT + " * " + Reserved.FROM + ' ' + matViewName + ' ' + Reserved.WHERE + ' ' + //$NON-NLS-1$ criteria.toString() + ' ' + Reserved.OPTION + ' ' + Reserved.NOCACHE; return new ProxyTupleSource() { private QueryProcessor qp; private TupleSource ts; private Object[] params; private int count; @Override protected TupleSource createTupleSource() throws TeiidComponentException, TeiidProcessingException { while (true) { if (qp == null) { params = paramIter.next(); LogManager.logInfo( LogConstants.CTX_MATVIEWS, QueryPlugin.Util.gs( QueryPlugin.Event.TEIID30012, matViewName, Arrays.toString(params))); qp = context .getQueryProcessorFactory() .createQueryProcessor(queryString, matViewName.toUpperCase(), context, params); ts = new BatchCollector.BatchProducerTupleSource(qp); } List<?> tuple = ts.nextTuple(); boolean delete = false; if (tuple == null) { delete = true; tuple = Arrays.asList(params); } else { tuple = new ArrayList<Object>(tuple); // ensure the list is serializable } List<?> result = globalStore.updateMatViewRow(matTableName, tuple, delete); if (result != null) { count++; } if (eventDistributor != null) { eventDistributor.updateMatViewRow( context.getVdbName(), context.getVdbVersion(), metadata.getName(metadata.getModelID(groupID)), metadata.getName(groupID), tuple, delete); } qp.closeProcessing(); qp = null; ts = null; if (!paramIter.hasNext()) { break; } } return CollectionTupleSource.createUpdateCountTupleSource(count); } @Override public void closeSource() { super.closeSource(); if (qp != null) { qp.closeProcessing(); } } }; }