Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags and
* the COPYRIGHT.txt file distributed with this work.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teiid.query.tempdata;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
import javax.transaction.RollbackException;
import javax.transaction.Status;
import javax.transaction.Synchronization;
import javax.transaction.SystemException;
import org.teiid.api.exception.query.QueryProcessingException;
import org.teiid.common.buffer.BlockedException;
import org.teiid.common.buffer.BufferManager;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
import org.teiid.core.types.DataTypeManager;
import org.teiid.core.types.TransformationException;
import org.teiid.dqp.service.TransactionContext;
import org.teiid.dqp.service.TransactionContext.Scope;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.metadata.FunctionMethod.Determinism;
import org.teiid.metadata.Table;
import org.teiid.query.QueryPlugin;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.metadata.TempMetadataID;
import org.teiid.query.metadata.TempMetadataStore;
import org.teiid.query.processor.BatchCollector.BatchProducerTupleSource;
import org.teiid.query.processor.ProcessorPlan;
import org.teiid.query.processor.QueryProcessor;
import org.teiid.query.resolver.command.TempTableResolver;
import org.teiid.query.sql.lang.Command;
import org.teiid.query.sql.lang.Create;
import org.teiid.query.sql.lang.Insert;
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.GroupSymbol;
import org.teiid.query.util.CommandContext;
/**
* TempTableStores are transactional, but do not act as full resource manager.
* This means we are effectively 1PC and don't allow any heuristic exceptions
* on commit.
*
* Table state snapshoting and a {@link Synchronization} are used to
* perform the appropriate commit/rollback actions.
*
* Full row level MVCC would be a good next step as it would remove the
* cost of state cloning and would allow for concurrent read/write transactions.
*/
public class TempTableStore {
public static final String TEIID_MAX_RECURSION = "teiid.maxRecursion"; //$NON-NLS-1$
public interface TransactionCallback {
void commit();
void rollback();
}
public enum TransactionMode {
ISOLATE_READS, //for matviews that have atomic updates
ISOLATE_WRITES, //for session/procedure stores that need rollback support - this is effectively READ_UNCOMMITTED
NONE
}
public static class TableProcessor {
QueryProcessor queryProcessor;
List columns;
BatchProducerTupleSource iterator;
public TableProcessor(QueryProcessor queryProcessor,
List columns) {
this.queryProcessor = queryProcessor;
this.columns = columns;
this.iterator = new BatchProducerTupleSource(queryProcessor);
}
public void close() {
iterator.closeSource();
queryProcessor.closeProcessing();
}
/**
* 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, false, null);
tempTable.setUpdatable(false);
tempTable.setAllowImplicitIndexing(true);
close();
return tempTable;
}
/**
* Alter the create if needed
* @param create
*/
public void alterCreate(Create create) {
}
}
public static class RecursiveTableProcessor extends TableProcessor {
private ProcessorPlan recursive;
private boolean all;
private boolean initial = true;
private TempTable working;
private TempTable intermediate;
private QueryProcessor workingQp;
private boolean building;
private int iterations;
private int maxIterations = 10000; //Default to 10000
public RecursiveTableProcessor(QueryProcessor queryProcessor,
List columns, ProcessorPlan processorPlan, boolean all) throws TransformationException {
super(queryProcessor, columns);
this.recursive = processorPlan;
this.all = all;
if (queryProcessor.getContext() != null) {
Object value = queryProcessor.getContext().getSessionVariable(TEIID_MAX_RECURSION);
if (value != null) {
value = DataTypeManager.convertToRuntimeType(value, false);
DataTypeManager.transformValue(value, value.getClass(), DataTypeManager.DefaultDataClasses.INTEGER);
if (value instanceof Number) {
maxIterations = ((Number)value).intValue();
}
}
}
}
@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().clone(),
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);
tempTable.setAllowImplicitIndexing(true);
return tempTable;
}
private void processPlan(TempTable tempTable, TempTable target)
throws TeiidComponentException, TeiidProcessingException {
List