/*
* JBoss, Home of Professional Open Source.
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership. Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
package org.teiid.dqp.internal.process;
import static org.junit.Assert.*;
import java.util.ArrayList;
import org.junit.BeforeClass;
import org.junit.Test;
import org.teiid.api.exception.query.QueryParserException;
import org.teiid.cache.CacheConfiguration;
import org.teiid.cache.DefaultCacheFactory;
import org.teiid.dqp.internal.process.SessionAwareCache.CacheID;
import org.teiid.metadata.FunctionMethod.Determinism;
import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.parser.ParseInfo;
import org.teiid.query.parser.QueryParser;
import org.teiid.query.processor.relational.ProjectNode;
import org.teiid.query.processor.relational.RelationalPlan;
import org.teiid.query.sql.lang.Command;
import org.teiid.query.sql.symbol.Reference;
import org.teiid.query.util.CommandContext;
@SuppressWarnings("nls")
public class TestPreparedPlanCache {
private static final String EXAMPLE_QUERY = "SELECT * FROM table"; //$NON-NLS-1$
private final static DQPWorkContext token = new DQPWorkContext();
private final static DQPWorkContext token2 = new DQPWorkContext();
private final static ParseInfo pi = new ParseInfo();
@BeforeClass public static void setUpOnce() {
token.getSession().setVDBName("foo"); //$NON-NLS-1$
token.getSession().setVDBVersion(1);
token2.getSession().setVDBName("foo"); //$NON-NLS-1$
token2.getSession().setVDBVersion(2);
}
//====Tests====//
@Test public void testPutPreparedPlan(){
SessionAwareCache<PreparedPlan> cache = new SessionAwareCache<PreparedPlan>("preparedplan", DefaultCacheFactory.INSTANCE, SessionAwareCache.Type.PREPAREDPLAN, 0);
CacheID id = new CacheID(token, pi, EXAMPLE_QUERY + 1);
//No PreparedPlan at the begining
assertNull(cache.get(id));
//create one
cache.put(id, Determinism.SESSION_DETERMINISTIC, new PreparedPlan(), null);
//should have one now
assertNotNull("Unable to get prepared plan from cache", cache.get(id)); //$NON-NLS-1$
}
@Test public void testGet(){
SessionAwareCache<PreparedPlan> cache = new SessionAwareCache<PreparedPlan>("preparedplan", DefaultCacheFactory.INSTANCE, SessionAwareCache.Type.PREPAREDPLAN, 0);
helpPutPreparedPlans(cache, token, 0, 10);
helpPutPreparedPlans(cache, token2, 0, 15);
//read an entry for session2 (token2)
PreparedPlan pPlan = cache.get(new CacheID(token2, pi, EXAMPLE_QUERY + 12));
assertNotNull("Unable to get prepared plan from cache", pPlan); //$NON-NLS-1$
assertEquals("Error getting plan from cache", new RelationalPlan(new ProjectNode(12)).toString(), pPlan.getPlan().toString()); //$NON-NLS-1$
assertEquals("Error getting command from cache", EXAMPLE_QUERY + 12, pPlan.getCommand().toString()); //$NON-NLS-1$
assertNotNull("Error getting plan description from cache", pPlan.getAnalysisRecord()); //$NON-NLS-1$
assertEquals("Error gettting reference from cache", new Reference(1), pPlan.getReferences().get(0)); //$NON-NLS-1$
}
@Test public void testClearAll(){
SessionAwareCache<PreparedPlan> cache = new SessionAwareCache<PreparedPlan>("preparedplan", DefaultCacheFactory.INSTANCE, SessionAwareCache.Type.PREPAREDPLAN, 0);
//create one for each session token
helpPutPreparedPlans(cache, token, 1, 1);
helpPutPreparedPlans(cache, token2, 1, 1);
//should have one
assertNotNull("Unable to get prepared plan from cache for token", cache.get(new CacheID(token, pi, EXAMPLE_QUERY + 1))); //$NON-NLS-1$
cache.clearAll();
//should not exist for token
assertNull("Failed remove from cache", cache.get(new CacheID(token, pi, EXAMPLE_QUERY + 1))); //$NON-NLS-1$
//should not exist for token2
assertNull("Unable to get prepared plan from cache for token2", cache.get(new CacheID(token2, pi, EXAMPLE_QUERY + 1))); //$NON-NLS-1$
}
// set init size to negative number, which should default to max
@Test public void testNegativeSizeCacheUsesDefault() {
CacheConfiguration config = new CacheConfiguration();
config.setMaxEntries(-1);
new SessionAwareCache<PreparedPlan>("preparedplan", new DefaultCacheFactory(config), SessionAwareCache.Type.PREPAREDPLAN, 0);
// -1 means unlimited in the infinispan
}
//====Help methods====//
private void helpPutPreparedPlans(SessionAwareCache<PreparedPlan> cache, DQPWorkContext session, int start, int count){
for(int i=0; i<count; i++){
Command dummy;
try {
dummy = QueryParser.getQueryParser().parseCommand(EXAMPLE_QUERY + (start + i));
} catch (QueryParserException e) {
throw new RuntimeException(e);
}
CacheID id = new CacheID(session, pi, dummy.toString());
PreparedPlan pPlan = new PreparedPlan();
cache.put(id, Determinism.SESSION_DETERMINISTIC, pPlan, null);
pPlan.setCommand(dummy);
pPlan.setPlan(new RelationalPlan(new ProjectNode(i)), new CommandContext());
AnalysisRecord analysisRecord = new AnalysisRecord(true, false);
pPlan.setAnalysisRecord(analysisRecord);
ArrayList<Reference> refs = new ArrayList<Reference>();
refs.add(new Reference(1));
pPlan.setReferences(refs);
}
}
}