use of org.teiid.query.sql.lang.CacheHint in project teiid by teiid.
the class GlobalTableStoreImpl method getCodeTableMetadataId.
@Override
public TempMetadataID getCodeTableMetadataId(String codeTableName, String returnElementName, String keyElementName, String matTableName) throws TeiidComponentException, QueryMetadataException {
ElementSymbol keyElement = new ElementSymbol(matTableName + ElementSymbol.SEPARATOR + keyElementName);
ElementSymbol returnElement = new ElementSymbol(matTableName + ElementSymbol.SEPARATOR + returnElementName);
keyElement.setType(DataTypeManager.getDataTypeClass(metadata.getElementRuntimeTypeName(metadata.getElementID(codeTableName + ElementSymbol.SEPARATOR + keyElementName))));
returnElement.setType(DataTypeManager.getDataTypeClass(metadata.getElementRuntimeTypeName(metadata.getElementID(codeTableName + ElementSymbol.SEPARATOR + returnElementName))));
TempMetadataID id = this.tableStore.getMetadataStore().getTempGroupID(matTableName);
if (id == null) {
synchronized (this) {
id = this.tableStore.getMetadataStore().addTempGroup(matTableName, Arrays.asList(keyElement, returnElement), false, true);
// $NON-NLS-1$
String queryString = Reserved.SELECT + ' ' + new ElementSymbol(keyElementName) + " ," + new ElementSymbol(returnElementName) + ' ' + Reserved.FROM + ' ' + new GroupSymbol(codeTableName);
id.setQueryNode(new QueryNode(queryString));
id.setPrimaryKey(id.getElements().subList(0, 1));
CacheHint hint = new CacheHint(true, null);
id.setCacheHint(hint);
}
}
return id;
}
use of org.teiid.query.sql.lang.CacheHint in project teiid by teiid.
the class GlobalTableStoreImpl method updateCacheHint.
private void updateCacheHint(Object viewId, GroupSymbol group, TempMetadataID id) throws TeiidComponentException, QueryMetadataException, QueryResolverException, QueryValidatorException {
if (id.getCacheHint() != null && !id.getTableData().updateCacheHint(((Table) viewId).getLastModified())) {
return;
}
// TODO: be stricter about the update strategy (needs synchronized or something better than ms resolution)
Command c = QueryResolver.resolveView(group, metadata.getVirtualPlan(viewId), SQLConstants.Reserved.SELECT, metadata, false).getCommand();
CacheHint hint = c.getCacheHint();
if (hint != null) {
hint = hint.clone();
} else {
hint = new CacheHint();
}
// overlay the properties
String ttlString = metadata.getExtensionProperty(viewId, MaterializationMetadataRepository.MATVIEW_TTL, false);
if (Boolean.valueOf(metadata.getExtensionProperty(viewId, MaterializationMetadataRepository.ALLOW_MATVIEW_MANAGEMENT, false))) {
// will be managed by the scheduler
hint.setTtl(null);
} else if (ttlString != null) {
hint.setTtl(Long.parseLong(ttlString));
}
String memString = metadata.getExtensionProperty(viewId, MaterializationMetadataRepository.MATVIEW_PREFER_MEMORY, false);
if (memString != null) {
hint.setPrefersMemory(Boolean.valueOf(memString));
}
String updatableString = metadata.getExtensionProperty(viewId, MaterializationMetadataRepository.MATVIEW_UPDATABLE, false);
if (updatableString != null) {
hint.setUpdatable(Boolean.valueOf(updatableString));
}
String scope = metadata.getExtensionProperty(viewId, MaterializationMetadataRepository.MATVIEW_SCOPE, false);
if (scope != null) {
hint.setScope(scope);
}
id.setCacheHint(hint);
}
use of org.teiid.query.sql.lang.CacheHint in project teiid by teiid.
the class MetadataValidator method validate.
private void validate(VDBMetaData vdb, ModelMetaData model, AbstractMetadataRecord record, ValidatorReport report, QueryMetadataInterface metadata, MetadataFactory mf) {
ValidatorReport resolverReport = null;
try {
if (record instanceof Procedure) {
Procedure p = (Procedure) record;
Command command = parser.parseProcedure(p.getQueryPlan(), false);
validateNoReferences(command, report, model);
QueryResolver.resolveCommand(command, new GroupSymbol(p.getFullName()), Command.TYPE_STORED_PROCEDURE, metadata, false);
resolverReport = Validator.validate(command, metadata);
determineDependencies(p, command);
} else if (record instanceof Table) {
Table t = (Table) record;
GroupSymbol symbol = new GroupSymbol(t.getFullName());
ResolverUtil.resolveGroup(symbol, metadata);
String selectTransformation = t.getSelectTransformation();
QueryNode node = null;
if (t.isVirtual()) {
QueryCommand command = (QueryCommand) parser.parseCommand(selectTransformation);
validateNoReferences(command, report, model);
QueryResolver.resolveCommand(command, metadata);
resolverReport = Validator.validate(command, metadata);
if (!resolverReport.hasItems() && (t.getColumns() == null || t.getColumns().isEmpty())) {
List<Expression> symbols = command.getProjectedSymbols();
for (Expression column : symbols) {
try {
addColumn(Symbol.getShortName(column), column.getType(), t, mf);
} catch (TranslatorException e) {
log(report, model, e.getMessage());
}
}
}
node = QueryResolver.resolveView(symbol, new QueryNode(selectTransformation), SQLConstants.Reserved.SELECT, metadata, true);
if (t.getColumns() != null && !t.getColumns().isEmpty()) {
determineDependencies(t, command);
if (t.getInsertPlan() != null && t.isInsertPlanEnabled()) {
validateUpdatePlan(model, report, metadata, t, t.getInsertPlan(), Command.TYPE_INSERT);
}
if (t.getUpdatePlan() != null && t.isUpdatePlanEnabled()) {
validateUpdatePlan(model, report, metadata, t, t.getUpdatePlan(), Command.TYPE_UPDATE);
}
if (t.getDeletePlan() != null && t.isDeletePlanEnabled()) {
validateUpdatePlan(model, report, metadata, t, t.getDeletePlan(), Command.TYPE_DELETE);
}
}
}
boolean addCacheHint = false;
if (t.isVirtual() && t.isMaterialized() && t.getMaterializedTable() == null) {
List<KeyRecord> fbis = t.getFunctionBasedIndexes();
List<GroupSymbol> groups = Arrays.asList(symbol);
if (fbis != null && !fbis.isEmpty()) {
for (KeyRecord fbi : fbis) {
for (int j = 0; j < fbi.getColumns().size(); j++) {
Column c = fbi.getColumns().get(j);
if (c.getParent() != fbi) {
continue;
}
String exprString = c.getNameInSource();
try {
Expression ex = parser.parseExpression(exprString);
validateNoReferences(ex, report, model);
ResolverVisitor.resolveLanguageObject(ex, groups, metadata);
if (!ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(ex).isEmpty()) {
log(report, model, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31114, exprString, fbi.getFullName()));
}
EvaluatableVisitor ev = new EvaluatableVisitor();
PreOrPostOrderNavigator.doVisit(ex, ev, PreOrPostOrderNavigator.PRE_ORDER);
if (ev.getDeterminismLevel().compareTo(Determinism.VDB_DETERMINISTIC) < 0) {
log(report, model, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31115, exprString, fbi.getFullName()));
}
} catch (QueryResolverException e) {
log(report, model, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31116, exprString, fbi.getFullName(), e.getMessage()));
}
}
}
}
} else {
addCacheHint = true;
}
if (node != null && addCacheHint && t.isMaterialized()) {
CacheHint cacheHint = node.getCommand().getCacheHint();
Long ttl = -1L;
if (cacheHint != null) {
if (cacheHint.getTtl() != null && t.getProperty(MaterializationMetadataRepository.MATVIEW_TTL, false) == null) {
ttl = cacheHint.getTtl();
t.setProperty(MaterializationMetadataRepository.MATVIEW_TTL, String.valueOf(ttl));
}
if (cacheHint.getUpdatable() != null && t.getProperty(MaterializationMetadataRepository.MATVIEW_UPDATABLE, false) == null) {
t.setProperty(MaterializationMetadataRepository.MATVIEW_UPDATABLE, String.valueOf(cacheHint.getUpdatable()));
}
if (cacheHint.getPrefersMemory() != null && t.getProperty(MaterializationMetadataRepository.MATVIEW_PREFER_MEMORY, false) == null) {
t.setProperty(MaterializationMetadataRepository.MATVIEW_PREFER_MEMORY, String.valueOf(cacheHint.getPrefersMemory()));
}
if (cacheHint.getScope() != null && t.getProperty(MaterializationMetadataRepository.MATVIEW_SHARE_SCOPE, false) == null) {
log(report, model, Severity.WARNING, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31252, t.getName(), cacheHint.getScope().name()));
t.setProperty(MaterializationMetadataRepository.MATVIEW_SHARE_SCOPE, MaterializationMetadataRepository.Scope.IMPORTED.name());
}
}
}
}
processReport(model, record, report, resolverReport);
} catch (TeiidException e) {
log(report, model, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31080, record.getFullName(), e.getMessage()));
}
}
use of org.teiid.query.sql.lang.CacheHint in project teiid by teiid.
the class GlobalTableStoreImpl method createMatTable.
@Override
public TempTable createMatTable(final String tableName, GroupSymbol group) throws TeiidComponentException, QueryMetadataException, TeiidProcessingException {
Create create = getCreateCommand(group, true, metadata);
TempTable table = tableStore.addTempTable(tableName, create, bufferManager, false, null);
table.setUpdatable(false);
CacheHint hint = table.getCacheHint();
if (hint != null) {
table.setPreferMemory(hint.isPrefersMemory());
if (hint.getTtl() != null) {
getMatTableInfo(tableName).setTtl(hint.getTtl());
}
if (!create.getPrimaryKey().isEmpty()) {
table.setUpdatable(hint.isUpdatable(false));
}
}
return table;
}
use of org.teiid.query.sql.lang.CacheHint in project teiid by teiid.
the class LocalClient method executeSQL.
@Override
public void executeSQL(Query query, List<SQLParameter> parameters, boolean calculateTotalSize, Integer skipOption, Integer topOption, String nextOption, int pageSize, final QueryResponse response) throws SQLException {
boolean cache = pageSize > 0;
if (cache) {
CacheHint hint = new CacheHint();
hint.setTtl(getCacheTime());
hint.setScope(CacheDirective.Scope.USER);
query.setCacheHint(hint);
}
boolean getCount = false;
getCount = calculateTotalSize;
boolean skipAndTopApplied = false;
if (!getCount && (topOption != null || skipOption != null)) {
query.setLimit(new Limit(skipOption != null ? new Constant(skipOption) : null, topOption != null ? new Constant(topOption) : null));
skipAndTopApplied = true;
}
String sessionId = getConnection().getServerConnection().getLogonResult().getSessionID();
String nextToken = null;
Integer savedEntityCount = null;
if (nextOption != null) {
nextToken = nextOption;
if (cache) {
StringTokenizer st = new StringTokenizer(nextOption, DELIMITER);
sessionId = st.nextToken();
nextToken = st.nextToken();
if (st.hasMoreTokens()) {
savedEntityCount = Integer.parseInt(st.nextToken());
}
}
// the URL might have $count=true, but ignore it.
getCount = false;
}
String sql = query.toString();
if (cache) {
// $NON-NLS-1$ //$NON-NLS-2$
sql += " /* " + sessionId + " */";
}
// $NON-NLS-1$
LogManager.logDetail(LogConstants.CTX_ODATA, "Teiid-Query:", sql);
final PreparedStatement stmt = getConnection().prepareStatement(sql, cache ? ResultSet.TYPE_SCROLL_INSENSITIVE : ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
if (parameters != null && !parameters.isEmpty()) {
List<Reference> references = ReferenceCollectorVisitor.getReferences(query);
for (int i = 0; i < references.size(); i++) {
int index = references.get(i).getIndex();
stmt.setObject(i + 1, parameters.get(index).getValue(), parameters.get(index).getSqlType());
}
}
final ResultSet rs = stmt.executeQuery();
// skip to the initial position
int count = 0;
int entityCount = 0;
int skipSize = 0;
// skip based upon the skip value
if (nextToken == null && skipOption != null && !skipAndTopApplied) {
if (skipOption > 0) {
int s = skipEntities(rs, skipOption);
count += s;
entityCount = s;
skipSize = count;
}
}
// skip based upon the skipToken
if (nextToken != null) {
skipSize += Integer.parseInt(nextToken);
if (skipSize > 0) {
count += skip(cache, rs, skipSize);
}
}
// determine the number of records to return
int size = pageSize;
int top = Integer.MAX_VALUE;
if (getCount && topOption != null) {
top = topOption;
size = top;
if (pageSize > 0) {
size = Math.min(pageSize, size);
}
} else if (size < 1) {
size = Integer.MAX_VALUE;
}
// build the results
int i = 0;
int nextCount = count;
while (true) {
if (!rs.next()) {
break;
}
count++;
i++;
entityCount++;
if (i > size) {
break;
}
nextCount++;
response.addRow(rs);
}
// set the count
if (getCount) {
while (rs.next()) {
count++;
entityCount++;
}
}
if (savedEntityCount != null) {
response.setCount(savedEntityCount);
} else {
response.setCount(entityCount);
}
// set the skipToken if needed
if (cache && response.size() == pageSize) {
long end = nextCount;
if (getCount) {
if (end < Math.min(top, count)) {
response.setNextToken(nextToken(cache, sessionId, end, entityCount));
}
} else if (count != nextCount) {
response.setNextToken(nextToken(cache, sessionId, end, null));
// will force the entry to cache or is effectively a no-op when already cached
rs.last();
}
}
}
Aggregations