teiid SVN: r4361 - in trunk: connectors/translator-olap/src/main/java/org/teiid/translator/olap and 21 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-08-23 12:43:06 -0400 (Thu, 23 Aug 2012)
New Revision: 4361
Added:
trunk/engine/src/main/java/org/teiid/query/processor/relational/ObjectTableNode.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/ObjectTable.java
Modified:
trunk/api/src/main/java/org/teiid/language/SQLConstants.java
trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourceMetadataWrapper.java
trunk/engine/src/main/java/org/teiid/query/QueryPlugin.java
trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java
trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadata.java
trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadataWrapper.java
trunk/engine/src/main/java/org/teiid/query/metadata/MetadataValidator.java
trunk/engine/src/main/java/org/teiid/query/metadata/QueryMetadataInterface.java
trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataAdapter.java
trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java
trunk/engine/src/main/java/org/teiid/query/processor/relational/RelationalPlan.java
trunk/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java
trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java
trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverUtil.java
trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java
trunk/engine/src/main/java/org/teiid/query/sql/lang/XMLTable.java
trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java
trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
trunk/engine/src/main/java/org/teiid/query/xquery/saxon/XQueryEvaluator.java
trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
trunk/engine/src/main/resources/org/teiid/query/i18n.properties
trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java
trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBDeployer.java
Log:
TEIID-2141 adding initial support for an object table and a few minor fixes
Modified: trunk/api/src/main/java/org/teiid/language/SQLConstants.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/SQLConstants.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/api/src/main/java/org/teiid/language/SQLConstants.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -119,6 +119,7 @@
public static final String TRIM = "TRIM"; //$NON-NLS-1$
public static final String RESULT = "RESULT"; //$NON-NLS-1$
+ public static final Object OBJECTTABLE = "OBJECTTABLE"; //$NON-NLS-1$
}
public interface Reserved {
Modified: trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java
===================================================================
--- trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -127,7 +127,7 @@
Cell cell = cellSet.getCell(colPos, rowPosition);
result[i++] = cell.getValue();
}
- ArrayList<Object[]> results = new ArrayList<Object[]>();
+ ArrayList<Object[]> results = new ArrayList<Object[]>(1);
results.add(result);
return results;
}
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourceMetadataWrapper.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourceMetadataWrapper.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/multisource/MultiSourceMetadataWrapper.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -373,7 +373,7 @@
}
@Override
- public QueryMetadataInterface getDesignTimeMetadata() {
+ protected QueryMetadataInterface createDesignTimeMetadata() {
return new MultiSourceMetadataWrapper(actualMetadata.getDesignTimeMetadata(), multiSourceModels);
}
Modified: trunk/engine/src/main/java/org/teiid/query/QueryPlugin.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/QueryPlugin.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/QueryPlugin.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -526,5 +526,7 @@
TEIID31106, //duplicate param name
TEIID31107, //too many result params
TEIID31108, //datasource not available
+ TEIID31109, //invalid scripting language
+ TEIID31110, //invalid script
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/eval/Evaluator.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -879,7 +879,7 @@
* Evaluate the parameters and return the context item if it exists
*/
public Object evaluateParameters(List<DerivedColumn> cols, List<?> tuple,
- HashMap<String, Object> parameters)
+ Map<String, Object> parameters)
throws ExpressionEvaluationException, BlockedException,
TeiidComponentException {
Object contextItem = null;
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadata.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadata.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadata.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -28,8 +28,11 @@
import java.util.Properties;
import java.util.Set;
+import javax.script.ScriptEngine;
+
import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidProcessingException;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.mapping.relational.QueryNode;
import org.teiid.query.mapping.xml.MappingNode;
@@ -519,5 +522,10 @@
public Set<String> getImportedModels() {
return Collections.emptySet();
}
-
+
+ @Override
+ public ScriptEngine getScriptEngine(String langauge) throws TeiidProcessingException {
+ return null;
+ }
+
}
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadataWrapper.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadataWrapper.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/BasicQueryMetadataWrapper.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -27,8 +27,11 @@
import java.util.Properties;
import java.util.Set;
+import javax.script.ScriptEngine;
+
import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidProcessingException;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.mapping.relational.QueryNode;
import org.teiid.query.mapping.xml.MappingNode;
@@ -37,6 +40,8 @@
public class BasicQueryMetadataWrapper implements QueryMetadataInterface {
protected QueryMetadataInterface actualMetadata;
+ protected QueryMetadataInterface designTimeMetadata;
+ protected boolean designTime;
public BasicQueryMetadataWrapper(QueryMetadataInterface actualMetadata) {
this.actualMetadata = actualMetadata;
@@ -355,6 +360,19 @@
@Override
public QueryMetadataInterface getDesignTimeMetadata() {
+ if (designTime) {
+ return this;
+ }
+ if (designTimeMetadata == null) {
+ designTimeMetadata = createDesignTimeMetadata();
+ if (designTimeMetadata instanceof BasicQueryMetadataWrapper) {
+ ((BasicQueryMetadataWrapper)designTimeMetadata).designTime = true;
+ }
+ }
+ return designTimeMetadata;
+ }
+
+ protected QueryMetadataInterface createDesignTimeMetadata() {
return actualMetadata.getDesignTimeMetadata();
}
@@ -378,5 +396,10 @@
public Set<String> getImportedModels() {
return actualMetadata.getImportedModels();
}
-
+
+ @Override
+ public ScriptEngine getScriptEngine(String langauge) throws TeiidProcessingException {
+ return actualMetadata.getScriptEngine(langauge);
+ }
+
}
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/MetadataValidator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/MetadataValidator.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/MetadataValidator.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -147,6 +147,8 @@
static class ResolveQueryPlans implements MetadataRule {
@Override
public void execute(VDBMetaData vdb, MetadataStore store, ValidatorReport report, MetadataValidator metadataValidator) {
+ QueryMetadataInterface metadata = vdb.getAttachment(QueryMetadataInterface.class);
+ metadata = new TempMetadataAdapter(metadata, new TempMetadataStore());
for (Schema schema:store.getSchemaList()) {
ModelMetaData model = vdb.getModel(schema.getName());
@@ -163,7 +165,7 @@
metadataValidator.log(report, model, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31079, t.getName(), model.getName()));
}
else {
- metadataValidator.validate(vdb, model, t, report);
+ metadataValidator.validate(vdb, model, t, report, metadata);
}
}
}
@@ -174,7 +176,7 @@
metadataValidator.log(report, model, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31081, p.getName(), model.getName()));
}
else {
- metadataValidator.validate(vdb, model, p, report);
+ metadataValidator.validate(vdb, model, p, report, metadata);
}
}
}
@@ -198,9 +200,7 @@
LogManager.log(messageLevel, LogConstants.CTX_QUERY_RESOLVER, msg);
}
- private void validate(VDBMetaData vdb, ModelMetaData model, AbstractMetadataRecord record, ValidatorReport report) {
- QueryMetadataInterface metadata = vdb.getAttachment(QueryMetadataInterface.class);
- metadata = new TempMetadataAdapter(metadata, new TempMetadataStore()); //TODO: optimize this
+ private void validate(VDBMetaData vdb, ModelMetaData model, AbstractMetadataRecord record, ValidatorReport report, QueryMetadataInterface metadata) {
ValidatorReport resolverReport = null;
try {
if (record instanceof Procedure) {
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/QueryMetadataInterface.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/QueryMetadataInterface.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/QueryMetadataInterface.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -27,8 +27,11 @@
import java.util.Properties;
import java.util.Set;
+import javax.script.ScriptEngine;
+
import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidProcessingException;
import org.teiid.query.function.FunctionLibrary;
import org.teiid.query.mapping.relational.QueryNode;
import org.teiid.query.mapping.xml.MappingNode;
@@ -623,6 +626,14 @@
FunctionLibrary getFunctionLibrary();
+ /**
+ *
+ * @param langauge null is treated as the default of 'javascript'
+ * @return the ScriptEngine or null if the ScriptEngine is not available
+ * @throws TeiidProcessingException if the ScriptEngine is required
+ */
+ ScriptEngine getScriptEngine(String langauge) throws TeiidProcessingException;
+
Object getPrimaryKey(Object metadataID);
boolean isMultiSource(Object modelId) throws QueryMetadataException, TeiidComponentException;
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataAdapter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataAdapter.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/TempMetadataAdapter.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -95,9 +95,14 @@
if (isSession()) {
return this.actualMetadata.getDesignTimeMetadata();
}
- return new TempMetadataAdapter(this.actualMetadata.getDesignTimeMetadata(), tempStore, materializationTables, queryNodes);
+ return super.getDesignTimeMetadata();
}
+ @Override
+ protected QueryMetadataInterface createDesignTimeMetadata() {
+ return new TempMetadataAdapter(this.actualMetadata.getDesignTimeMetadata(), tempStore, materializationTables, queryNodes);
+ }
+
public TempMetadataStore getMetadataStore() {
return this.tempStore;
}
Modified: trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/metadata/TransformationMetadata.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -26,20 +26,17 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
+import java.util.*;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptEngineManager;
+
import org.jboss.vfs.VirtualFile;
import org.teiid.adminapi.impl.VDBMetaData;
import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidProcessingException;
import org.teiid.core.types.BlobImpl;
import org.teiid.core.types.ClobImpl;
import org.teiid.core.types.DataTypeManager;
@@ -68,6 +65,7 @@
import org.teiid.query.mapping.xml.MappingDocument;
import org.teiid.query.mapping.xml.MappingLoader;
import org.teiid.query.mapping.xml.MappingNode;
+import org.teiid.query.sql.lang.ObjectTable;
import org.teiid.query.sql.lang.SPParameter;
@@ -159,6 +157,8 @@
private Map<String, Resource> vdbEntries;
private FunctionLibrary functionLibrary;
private VDBMetaData vdbMetaData;
+ private ScriptEngineManager scriptEngineManager;
+ private Set<String> importedModels;
/*
* TODO: move caching to jboss cache structure
@@ -174,6 +174,12 @@
public TransformationMetadata(VDBMetaData vdbMetadata, final CompositeMetadataStore store, Map<String, Resource> vdbEntries, FunctionTree systemFunctions, Collection<FunctionTree> functionTrees) {
ArgCheck.isNotNull(store);
this.vdbMetaData = vdbMetadata;
+ if (this.vdbMetaData !=null) {
+ this.scriptEngineManager = vdbMetadata.getAttachment(ScriptEngineManager.class);
+ this.importedModels = this.vdbMetaData.getImportedModels();
+ } else {
+ this.importedModels = Collections.emptySet();
+ }
this.store = store;
if (vdbEntries == null) {
this.vdbEntries = Collections.emptyMap();
@@ -188,7 +194,6 @@
}
private TransformationMetadata(final CompositeMetadataStore store, FunctionLibrary functionLibrary) {
- ArgCheck.isNotNull(store);
this.store = store;
this.vdbEntries = Collections.emptyMap();
this.functionLibrary = functionLibrary;
@@ -1089,14 +1094,37 @@
tm.metadataCache = this.metadataCache;
tm.partialNameToFullNameCache = this.partialNameToFullNameCache;
tm.procedureCache = this.procedureCache;
+ tm.scriptEngineManager = this.scriptEngineManager;
+ tm.importedModels = this.importedModels;
return tm;
}
@Override
public Set<String> getImportedModels() {
- if (this.vdbMetaData == null) {
- return Collections.emptySet();
+ return this.importedModels;
+ }
+
+ @Override
+ public ScriptEngine getScriptEngine(String language) throws TeiidProcessingException {
+ if (this.scriptEngineManager == null) {
+ this.scriptEngineManager = new ScriptEngineManager();
}
- return this.vdbMetaData.getImportedModels();
+ if (language == null) {
+ language = ObjectTable.DEFAULT_LANGUAGE;
+ }
+ /*
+ * because of state caching in the engine, we'll return a new instance for each
+ * usage. we can pool if needed and add a returnEngine method
+ */
+ ScriptEngine engine = this.scriptEngineManager.getEngineByName(language);
+ if (engine == null) {
+ Set<String> names = new LinkedHashSet<String>();
+ for (ScriptEngineFactory factory : this.scriptEngineManager.getEngineFactories()) {
+ names.addAll(factory.getNames());
+ }
+ throw new TeiidProcessingException(QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31109, language, names));
+ }
+ return engine;
}
+
}
\ No newline at end of file
Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -60,6 +60,7 @@
import org.teiid.query.processor.relational.SortUtility.Mode;
import org.teiid.query.resolver.util.ResolverUtil;
import org.teiid.query.sql.lang.*;
+import org.teiid.query.sql.lang.ObjectTable.ObjectColumn;
import org.teiid.query.sql.lang.SetQuery.Operation;
import org.teiid.query.sql.lang.XMLTable.XMLColumn;
import org.teiid.query.sql.symbol.ElementSymbol;
@@ -421,7 +422,7 @@
//we handle the projection filtering once here rather than repeating the
//path analysis on a per plan basis
updateGroupName(node, xt);
- Map elementMap = RelationalNode.createLookupMap(xt.getProjectedSymbols());
+ Map<Expression, Integer> elementMap = RelationalNode.createLookupMap(xt.getProjectedSymbols());
List cols = (List) node.getProperty(NodeConstants.Info.OUTPUT_COLS);
int[] projectionIndexes = RelationalNode.getProjectionIndexes(elementMap, cols);
ArrayList<XMLColumn> filteredColumns = new ArrayList<XMLColumn>(projectionIndexes.length);
@@ -434,6 +435,24 @@
processNode = xtn;
break;
}
+ if (source instanceof ObjectTable) {
+ ObjectTable ot = (ObjectTable)source;
+ ObjectTableNode otn = new ObjectTableNode(getID());
+ //we handle the projection filtering once here rather than repeating the
+ //path analysis on a per plan basis
+ updateGroupName(node, ot);
+ Map<Expression, Integer> elementMap = RelationalNode.createLookupMap(ot.getProjectedSymbols());
+ List<Expression> cols = (List<Expression>) node.getProperty(NodeConstants.Info.OUTPUT_COLS);
+ int[] projectionIndexes = RelationalNode.getProjectionIndexes(elementMap, cols);
+ ArrayList<ObjectColumn> filteredColumns = new ArrayList<ObjectColumn>(projectionIndexes.length);
+ for (int col : projectionIndexes) {
+ filteredColumns.add(ot.getColumns().get(col));
+ }
+ otn.setProjectedColumns(filteredColumns);
+ otn.setTable(ot);
+ processNode = otn;
+ break;
+ }
if (source instanceof TextTable) {
TextTableNode ttn = new TextTableNode(getID());
TextTable tt = (TextTable)source;
Added: trunk/engine/src/main/java/org/teiid/query/processor/relational/ObjectTableNode.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/ObjectTableNode.java (rev 0)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/ObjectTableNode.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -0,0 +1,194 @@
+/*
+ * 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.query.processor.relational;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.script.CompiledScript;
+import javax.script.ScriptContext;
+import javax.script.ScriptException;
+import javax.script.SimpleScriptContext;
+
+import org.teiid.api.exception.query.ExpressionEvaluationException;
+import org.teiid.common.buffer.BlockedException;
+import org.teiid.common.buffer.TupleBatch;
+import org.teiid.core.TeiidComponentException;
+import org.teiid.core.TeiidProcessingException;
+import org.teiid.query.QueryPlugin;
+import org.teiid.query.eval.Evaluator;
+import org.teiid.query.function.FunctionDescriptor;
+import org.teiid.query.sql.LanguageObject;
+import org.teiid.query.sql.lang.ObjectTable;
+import org.teiid.query.sql.lang.ObjectTable.ObjectColumn;
+
+/**
+ * Handles object table processing.
+ */
+public class ObjectTableNode extends SubqueryAwareRelationalNode {
+
+ private static final String TEIID_ROW_COUNT = "teiid_rowcount"; //$NON-NLS-1$
+ private static final String TEIID_ROW = "teiid_row"; //$NON-NLS-1$
+ private static final String TEIID_CONTEXT = "teiid_context"; //$NON-NLS-1$
+
+ private ObjectTable table;
+ private List<ObjectColumn> projectedColumns;
+
+ //processing state
+ private int rowCount = 0;
+ private Object item;
+ private Iterator<?> result;
+ private SimpleScriptContext scriptContext;
+
+ public ObjectTableNode(int nodeID) {
+ super(nodeID);
+ }
+
+ @Override
+ public void open() throws TeiidComponentException, TeiidProcessingException {
+ super.open();
+ if (table.getScriptEngine() == null) {
+ table.setScriptEngine(getContext().getMetadata().getScriptEngine(table.getScriptingLanguage()));
+ }
+ scriptContext = new SimpleScriptContext();
+ this.scriptContext.setAttribute(TEIID_CONTEXT, this.getContext(), ScriptContext.ENGINE_SCOPE);
+ }
+
+ @Override
+ public synchronized void closeDirect() {
+ super.closeDirect();
+ reset();
+ }
+
+ @Override
+ public void reset() {
+ super.reset();
+ item = null;
+ result = null;
+ rowCount = 0;
+ this.scriptContext = null;
+ }
+
+ public void setTable(ObjectTable table) {
+ this.table = table;
+ }
+
+ public void setProjectedColumns(List<ObjectColumn> projectedColumns) {
+ this.projectedColumns = projectedColumns;
+ }
+
+ @Override
+ public ObjectTableNode clone() {
+ ObjectTableNode clone = new ObjectTableNode(getID());
+ this.copyTo(clone);
+ clone.setTable(table);
+ clone.setProjectedColumns(projectedColumns);
+ return clone;
+ }
+
+ @Override
+ protected synchronized TupleBatch nextBatchDirect() throws BlockedException,
+ TeiidComponentException, TeiidProcessingException {
+
+ evaluate();
+
+ while (!isBatchFull() && result.hasNext()) {
+ if (item == null) {
+ item = result.next();
+ if (item == null) {
+ continue;
+ }
+ rowCount++;
+ }
+ addBatchRow(processRow());
+ }
+ if (!result.hasNext()) {
+ terminateBatches();
+ }
+ return pullBatch();
+ }
+
+ private void evaluate() throws TeiidComponentException,
+ ExpressionEvaluationException, BlockedException,
+ TeiidProcessingException {
+ if (result != null) {
+ return;
+ }
+ setReferenceValues(this.table);
+ Evaluator eval = getEvaluator(Collections.emptyMap());
+ Object context = eval.evaluateParameters(this.table.getPassing(), null, scriptContext.getBindings(ScriptContext.ENGINE_SCOPE));
+ assert context == null;
+
+ Object value = evalScript(this.table.getCompiledScript(), this.table.getRowScript());
+ if (value instanceof Iterable<?>) {
+ result = ((Iterable<?>)value).iterator();
+ } else if (value instanceof Iterator<?>) {
+ result = (Iterator<?>)value;
+ } else {
+ result = Arrays.asList(value).iterator();
+ }
+ }
+
+ private Object evalScript(CompiledScript compiledScript, String script) throws TeiidProcessingException {
+ try {
+ if (compiledScript != null) {
+ return compiledScript.eval(this.scriptContext);
+ }
+ return this.table.getScriptEngine().eval(script, this.scriptContext);
+ } catch (ScriptException e) {
+ throw new TeiidProcessingException(QueryPlugin.Event.TEIID31110, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31110, script, e.getMessage()));
+ }
+ }
+
+ private List<?> processRow() throws ExpressionEvaluationException,
+ TeiidComponentException, TeiidProcessingException {
+ List<Object> tuple = new ArrayList<Object>(projectedColumns.size());
+ this.scriptContext.setAttribute(TEIID_ROW, this.item, ScriptContext.ENGINE_SCOPE);
+ this.scriptContext.setAttribute(TEIID_ROW_COUNT, this.rowCount, ScriptContext.ENGINE_SCOPE);
+ for (ObjectColumn proColumn : projectedColumns) {
+ Object value = evalScript(proColumn.getCompiledScript(), proColumn.getPath());
+ if (value == null) {
+ if (proColumn.getDefaultExpression() != null) {
+ tuple.add(getEvaluator(Collections.emptyMap()).evaluate(proColumn.getDefaultExpression(), null));
+ } else {
+ tuple.add(null);
+ }
+ continue;
+ }
+ value = FunctionDescriptor.importValue(value, proColumn.getSymbol().getType());
+ tuple.add(value);
+ }
+ item = null;
+ return tuple;
+ }
+
+ @Override
+ protected Collection<? extends LanguageObject> getObjects() {
+ return this.table.getPassing();
+ }
+
+}
\ No newline at end of file
Property changes on: trunk/engine/src/main/java/org/teiid/query/processor/relational/ObjectTableNode.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/engine/src/main/java/org/teiid/query/processor/relational/RelationalPlan.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/RelationalPlan.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/RelationalPlan.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -125,6 +125,7 @@
return this.outputCols;
}
+ @Override
public void open()
throws TeiidComponentException, TeiidProcessingException {
if (with != null) {
Modified: trunk/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/processor/relational/XMLTableNode.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -321,7 +321,7 @@
Calendar cal = cv.getCalendar();
Date d = cal.getTime();
cal.setTimeZone(getContext().getServerTimeZone());
- return TimestampWithTimezone.createTimestamp(d, TimeZone.getTimeZone("GMT"), cal);
+ return TimestampWithTimezone.createTimestamp(d, TimeZone.getTimeZone("GMT"), cal); //$NON-NLS-1$
}
}
return Value.convertToJava(value);
Modified: trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/command/SimpleQueryResolver.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -328,6 +328,26 @@
}
}
+ @Override
+ public void visit(ObjectTable obj) {
+ LinkedHashSet<GroupSymbol> saved = preTableFunctionReference(obj);
+ visitNodes(obj.getPassing());
+ postTableFunctionReference(obj, saved);
+ try {
+ ResolverUtil.setDesiredType(obj.getPassing(), obj, DataTypeManager.DefaultDataClasses.OBJECT);
+ for (ObjectTable.ObjectColumn column : obj.getColumns()) {
+ if (column.getDefaultExpression() == null) {
+ continue;
+ }
+ visitNode(column.getDefaultExpression());
+ Expression ex = ResolverUtil.convertExpression(column.getDefaultExpression(), DataTypeManager.getDataTypeName(column.getSymbol().getType()), metadata);
+ column.setDefaultExpression(ex);
+ }
+ } catch (TeiidException e) {
+ throw new TeiidRuntimeException(e);
+ }
+ }
+
/**
* @param tfr
*/
Modified: trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverUtil.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverUtil.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/util/ResolverUtil.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -252,13 +252,14 @@
return conversion;
}
+
+ public static void setDesiredType(List<DerivedColumn> passing, LanguageObject obj) throws QueryResolverException {
+ setDesiredType(passing, obj, DataTypeManager.DefaultDataClasses.XML);
+ }
- public static void setDesiredType(List<DerivedColumn> passing, LanguageObject obj) throws QueryResolverException {
+ public static void setDesiredType(List<DerivedColumn> passing, LanguageObject obj, Class<?> type) throws QueryResolverException {
for (DerivedColumn dc : passing) {
- if (dc.getAlias() == null) {
- ResolverUtil.setDesiredType(dc.getExpression(), DataTypeManager.DefaultDataClasses.XML, obj);
- break;
- }
+ ResolverUtil.setDesiredType(dc.getExpression(), type, obj);
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -703,9 +703,9 @@
TextTable tt = (TextTable)clause;
tt.setFile(rewriteExpressionDirect(tt.getFile()));
} else if (clause instanceof XMLTable) {
- XMLTable xt = (XMLTable)clause;
- xt.rewriteDefaultColumn();
rewriteExpressions(clause);
+ } else if (clause instanceof ObjectTable) {
+ rewriteExpressions(clause);
} else if (clause instanceof ArrayTable) {
ArrayTable at = (ArrayTable)clause;
at.setArrayValue(rewriteExpressionDirect(at.getArrayValue()));
Modified: trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/sql/LanguageVisitor.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -144,4 +144,5 @@
public void visit(WindowSpecification windowSpecification) {}
public void visit(Array array) {}
+ public void visit(ObjectTable objectTable) {}
}
Added: trunk/engine/src/main/java/org/teiid/query/sql/lang/ObjectTable.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/ObjectTable.java (rev 0)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/ObjectTable.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -0,0 +1,197 @@
+/*
+ * 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.query.sql.lang;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.script.CompiledScript;
+import javax.script.ScriptEngine;
+
+import org.teiid.core.util.EquivalenceUtil;
+import org.teiid.query.sql.LanguageVisitor;
+import org.teiid.query.sql.symbol.DerivedColumn;
+import org.teiid.query.sql.symbol.Expression;
+
+public class ObjectTable extends TableFunctionReference {
+
+ public static final String DEFAULT_LANGUAGE = "javascript"; //$NON-NLS-1$
+
+ public static class ObjectColumn extends ProjectedColumn {
+ private String path;
+ private Expression defaultExpression;
+ private CompiledScript compiledScript;
+
+ public ObjectColumn(String name, String type, String path, Expression defaultExpression) {
+ super(name, type);
+ this.path = path;
+ this.defaultExpression = defaultExpression;
+ }
+
+ protected ObjectColumn() {
+
+ }
+
+ public Expression getDefaultExpression() {
+ return defaultExpression;
+ }
+
+ public void setDefaultExpression(Expression defaultExpression) {
+ this.defaultExpression = defaultExpression;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ public CompiledScript getCompiledScript() {
+ return compiledScript;
+ }
+
+ public void setCompiledScript(CompiledScript compiledScript) {
+ this.compiledScript = compiledScript;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!super.equals(obj) || !(obj instanceof ObjectColumn)) {
+ return false;
+ }
+ ObjectColumn other = (ObjectColumn)obj;
+ return EquivalenceUtil.areEqual(this.path, other.path)
+ && EquivalenceUtil.areEqual(this.defaultExpression, other.defaultExpression);
+ }
+
+ @Override
+ public ObjectColumn clone() {
+ ObjectColumn clone = new ObjectColumn();
+ super.copyTo(clone);
+ clone.path = this.path;
+ if (this.defaultExpression != null) {
+ clone.defaultExpression = (Expression)this.defaultExpression.clone();
+ }
+ clone.compiledScript = this.compiledScript;
+ return clone;
+ }
+ }
+
+ private List<ObjectColumn> columns = new ArrayList<ObjectColumn>();
+ private String rowScript;
+ private List<DerivedColumn> passing = new ArrayList<DerivedColumn>();
+ private String scriptingLanguage;
+
+ private CompiledScript compiledScript;
+ private ScriptEngine scriptEngine;
+
+ public CompiledScript getCompiledScript() {
+ return compiledScript;
+ }
+
+ public void setCompiledScript(CompiledScript compiledScript) {
+ this.compiledScript = compiledScript;
+ }
+
+ public String getScriptingLanguage() {
+ return scriptingLanguage;
+ }
+
+ public void setScriptingLanguage(String scriptingLanguage) {
+ this.scriptingLanguage = scriptingLanguage;
+ }
+
+ public List<DerivedColumn> getPassing() {
+ return passing;
+ }
+
+ public void setPassing(List<DerivedColumn> passing) {
+ this.passing = passing;
+ }
+
+ public String getRowScript() {
+ return rowScript;
+ }
+
+ public void setRowScript(String query) {
+ this.rowScript = query;
+ }
+
+ public List<ObjectColumn> getColumns() {
+ return columns;
+ }
+
+ public void setColumns(List<ObjectColumn> columns) {
+ this.columns = columns;
+ }
+
+ @Override
+ public void acceptVisitor(LanguageVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ protected ObjectTable cloneDirect() {
+ ObjectTable clone = new ObjectTable();
+ this.copy(clone);
+ for (ObjectColumn column : columns) {
+ clone.getColumns().add(column.clone());
+ }
+ if (this.passing != null) {
+ for (DerivedColumn col : this.passing) {
+ clone.passing.add(col.clone());
+ }
+ }
+ clone.rowScript = this.rowScript;
+ clone.compiledScript = this.compiledScript;
+ return clone;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!super.equals(obj) || !(obj instanceof ObjectTable)) {
+ return false;
+ }
+ ObjectTable other = (ObjectTable)obj;
+ return this.columns.equals(other.columns)
+ && this.rowScript.equals(other.rowScript)
+ && this.passing.equals(other.passing);
+ }
+
+ public ScriptEngine getScriptEngine() {
+ return scriptEngine;
+ }
+
+ public void setScriptEngine(ScriptEngine scriptEngine) {
+ this.scriptEngine = scriptEngine;
+ }
+
+}
Property changes on: trunk/engine/src/main/java/org/teiid/query/sql/lang/ObjectTable.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/XMLTable.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/XMLTable.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/XMLTable.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -1,7 +1,6 @@
package org.teiid.query.sql.lang;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import net.sf.saxon.sxpath.XPathExpression;
@@ -11,7 +10,6 @@
import org.teiid.core.util.EquivalenceUtil;
import org.teiid.query.sql.LanguageVisitor;
import org.teiid.query.sql.symbol.DerivedColumn;
-import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.Expression;
import org.teiid.query.sql.symbol.XMLNamespaces;
import org.teiid.query.xquery.saxon.SaxonXQueryExpression;
@@ -104,7 +102,7 @@
private XMLNamespaces namespaces;
private String xquery;
private List<DerivedColumn> passing = new ArrayList<DerivedColumn>();
- private XMLColumn defaultColumn;
+ private boolean usingDefaultColumn;
private SaxonXQueryExpression xqueryExpression;
@@ -113,11 +111,7 @@
}
public void compileXqueryExpression() throws TeiidProcessingException {
- List<XMLColumn> cols = this.columns;
- if (cols.isEmpty()) {
- cols = Arrays.asList(defaultColumn);
- }
- this.xqueryExpression = new SaxonXQueryExpression(xquery, namespaces, passing, cols);
+ this.xqueryExpression = new SaxonXQueryExpression(xquery, namespaces, passing, this.columns);
}
public SaxonXQueryExpression getXQueryExpression() {
@@ -141,9 +135,17 @@
}
public void setColumns(List<XMLColumn> columns) {
+ if (columns.isEmpty()) {
+ usingDefaultColumn = true;
+ columns.add(new XMLColumn("OBJECT_VALUE", DataTypeManager.DefaultDataTypes.XML, ".", null)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
this.columns = columns;
}
+ public boolean isUsingDefaultColumn() {
+ return usingDefaultColumn;
+ }
+
public XMLNamespaces getNamespaces() {
return namespaces;
}
@@ -152,17 +154,6 @@
this.namespaces = namespaces;
}
- @Override
- public List<ElementSymbol> getProjectedSymbols() {
- if (!columns.isEmpty()) {
- return super.getProjectedSymbols();
- }
- if (defaultColumn == null) {
- defaultColumn = new XMLColumn("OBJECT_VALUE", DataTypeManager.DefaultDataTypes.XML, ".", null); //$NON-NLS-1$ //$NON-NLS-2$
- }
- return Arrays.asList(defaultColumn.getSymbol());
- }
-
@Override
public void acceptVisitor(LanguageVisitor visitor) {
visitor.visit(this);
@@ -175,9 +166,6 @@
for (XMLColumn column : columns) {
clone.getColumns().add(column.clone());
}
- if (defaultColumn != null) {
- clone.defaultColumn = this.defaultColumn;
- }
if (this.namespaces != null) {
clone.namespaces = this.namespaces.clone();
}
@@ -190,6 +178,7 @@
if (this.xqueryExpression != null) {
clone.xqueryExpression = this.xqueryExpression.clone();
}
+ clone.usingDefaultColumn = usingDefaultColumn;
return clone;
}
@@ -208,11 +197,4 @@
&& this.passing.equals(other.passing);
}
- public void rewriteDefaultColumn() {
- if (this.columns.isEmpty() && defaultColumn != null) {
- this.columns.add(defaultColumn);
- defaultColumn = null;
- }
- }
-
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/sql/navigator/PreOrPostOrderNavigator.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -503,6 +503,17 @@
}
@Override
+ public void visit(ObjectTable obj) {
+ preVisitVisitor(obj);
+ visitNodes(obj.getPassing());
+ for (ObjectTable.ObjectColumn column : obj.getColumns()) {
+ visitNode(column.getDefaultExpression());
+ }
+ visitNode(obj.getGroupSymbol());
+ postVisitVisitor(obj);
+ }
+
+ @Override
public void visit(XMLQuery obj) {
preVisitVisitor(obj);
visitNode(obj.getNamespaces());
Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/ExpressionMappingVisitor.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -34,6 +34,7 @@
import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.LanguageVisitor;
import org.teiid.query.sql.lang.*;
+import org.teiid.query.sql.lang.ObjectTable.ObjectColumn;
import org.teiid.query.sql.lang.XMLTable.XMLColumn;
import org.teiid.query.sql.navigator.PreOrPostOrderNavigator;
import org.teiid.query.sql.navigator.PreOrderNavigator;
@@ -111,6 +112,16 @@
}
@Override
+ public void visit(ObjectTable obj) {
+ for (ObjectColumn col : obj.getColumns()) {
+ Expression exp = col.getDefaultExpression();
+ if (exp != null) {
+ col.setDefaultExpression(replaceExpression(exp));
+ }
+ }
+ }
+
+ @Override
public void visit(XMLSerialize obj) {
obj.setExpression(replaceExpression(obj.getExpression()));
}
Modified: trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/sql/visitor/SQLStringVisitor.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -41,6 +41,7 @@
import org.teiid.query.sql.LanguageVisitor;
import org.teiid.query.sql.lang.*;
import org.teiid.query.sql.lang.ExistsCriteria.SubqueryHint;
+import org.teiid.query.sql.lang.ObjectTable.ObjectColumn;
import org.teiid.query.sql.lang.TableFunctionReference.ProjectedColumn;
import org.teiid.query.sql.lang.TextTable.TextColumn;
import org.teiid.query.sql.lang.XMLTable.XMLColumn;
@@ -1778,7 +1779,7 @@
append(SPACE);
registerNodes(obj.getPassing(), 0);
}
- if (!obj.getColumns().isEmpty()) {
+ if (!obj.getColumns().isEmpty() && !obj.isUsingDefaultColumn()) {
append(SPACE);
append(NonReserved.COLUMNS);
for (Iterator<XMLColumn> cols = obj.getColumns().iterator(); cols.hasNext();) {
@@ -1818,6 +1819,50 @@
}
@Override
+ public void visit( ObjectTable obj ) {
+ addHintComment(obj);
+ append("OBJECTTABLE("); //$NON-NLS-1$
+ if (obj.getScriptingLanguage() != null) {
+ append(LANGUAGE);
+ append(SPACE);
+ visitNode(new Constant(obj.getScriptingLanguage()));
+ append(SPACE);
+ }
+ visitNode(new Constant(obj.getRowScript()));
+ if (!obj.getPassing().isEmpty()) {
+ append(SPACE);
+ append(NonReserved.PASSING);
+ append(SPACE);
+ registerNodes(obj.getPassing(), 0);
+ }
+ append(SPACE);
+ append(NonReserved.COLUMNS);
+ for (Iterator<ObjectColumn> cols = obj.getColumns().iterator(); cols.hasNext();) {
+ ObjectColumn col = cols.next();
+ append(SPACE);
+ outputDisplayName(col.getName());
+ append(SPACE);
+ append(col.getType());
+ append(SPACE);
+ visitNode(new Constant(col.getPath()));
+ if (col.getDefaultExpression() != null) {
+ append(SPACE);
+ append(DEFAULT);
+ append(SPACE);
+ visitNode(col.getDefaultExpression());
+ }
+ if (cols.hasNext()) {
+ append(","); //$NON-NLS-1$
+ }
+ }
+ append(")");//$NON-NLS-1$
+ append(SPACE);
+ append(AS);
+ append(SPACE);
+ outputDisplayName(obj.getName());
+ }
+
+ @Override
public void visit( XMLQuery obj ) {
append("XMLQUERY("); //$NON-NLS-1$
if (obj.getNamespaces() != null) {
Modified: trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -31,7 +31,12 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
+import java.util.TreeSet;
+import javax.script.Compilable;
+import javax.script.ScriptEngine;
+import javax.script.ScriptException;
+
import net.sf.saxon.om.Name11Checker;
import net.sf.saxon.om.QNameException;
import net.sf.saxon.trans.XPathException;
@@ -44,6 +49,7 @@
import org.teiid.core.TeiidProcessingException;
import org.teiid.core.types.DataTypeManager;
import org.teiid.core.util.EquivalenceUtil;
+import org.teiid.language.SQLConstants;
import org.teiid.metadata.AggregateAttributes;
import org.teiid.query.QueryPlugin;
import org.teiid.query.eval.Evaluator;
@@ -57,6 +63,7 @@
import org.teiid.query.resolver.util.ResolverUtil;
import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.lang.*;
+import org.teiid.query.sql.lang.ObjectTable.ObjectColumn;
import org.teiid.query.sql.lang.SetQuery.Operation;
import org.teiid.query.sql.lang.XMLTable.XMLColumn;
import org.teiid.query.sql.navigator.PreOrPostOrderNavigator;
@@ -1191,6 +1198,45 @@
}
@Override
+ public void visit(ObjectTable obj) {
+ List<DerivedColumn> passing = obj.getPassing();
+ TreeSet<String> names = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
+ for (DerivedColumn dc : passing) {
+ if (dc.getAlias() == null) {
+ handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.context_item_not_allowed"), obj); //$NON-NLS-1$
+ } else if (!names.add(dc.getAlias())) {
+ handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.duplicate_passing", dc.getAlias()), obj); //$NON-NLS-1$
+ }
+ }
+ Compilable scriptCompiler = null;
+ try {
+ ScriptEngine engine = this.getMetadata().getScriptEngine(obj.getScriptingLanguage());
+ obj.setScriptEngine(engine);
+ if (engine instanceof Compilable) {
+ scriptCompiler = (Compilable)engine;
+ engine.put(ScriptEngine.FILENAME, SQLConstants.NonReserved.OBJECTTABLE);
+ obj.setCompiledScript(scriptCompiler.compile(obj.getRowScript()));
+ }
+ } catch (TeiidProcessingException e) {
+ handleValidationError(e.getMessage(), obj);
+ } catch (ScriptException e) {
+ handleValidationError(QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31110, obj.getRowScript(), e.getMessage()), obj); //$NON-NLS
+ }
+ for (ObjectColumn xc : obj.getColumns()) {
+ if (scriptCompiler != null) {
+ try {
+ xc.setCompiledScript(scriptCompiler.compile(xc.getPath()));
+ } catch (ScriptException e) {
+ handleValidationError(QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31110, xc.getPath(), e.getMessage()), obj); //$NON-NLS
+ }
+ }
+ if (xc.getDefaultExpression() != null && !EvaluatableVisitor.isFullyEvaluatable(xc.getDefaultExpression(), false)) {
+ handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.invalid_default", xc.getDefaultExpression()), obj); //$NON-NLS-1$
+ }
+ }
+ }
+
+ @Override
public void visit(XMLQuery obj) {
validatePassing(obj, obj.getXQueryExpression(), obj.getPassing());
}
@@ -1198,7 +1244,7 @@
private void validatePassing(LanguageObject obj, SaxonXQueryExpression xqe, List<DerivedColumn> passing) {
boolean context = false;
boolean hadError = false;
- HashSet<String> names = new HashSet<String>();
+ TreeSet<String> names = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
for (DerivedColumn dc : passing) {
if (dc.getAlias() == null) {
Class<?> type = dc.getExpression().getType();
@@ -1212,7 +1258,7 @@
context = true;
} else {
validateXMLContentTypes(dc.getExpression(), obj);
- if (!names.add(dc.getAlias().toUpperCase())) {
+ if (!names.add(dc.getAlias())) {
handleValidationError(QueryPlugin.Util.getString("ValidationVisitor.duplicate_passing", dc.getAlias()), obj); //$NON-NLS-1$
}
}
Modified: trunk/engine/src/main/java/org/teiid/query/xquery/saxon/XQueryEvaluator.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/xquery/saxon/XQueryEvaluator.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/java/org/teiid/query/xquery/saxon/XQueryEvaluator.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -41,6 +41,7 @@
import net.sf.saxon.om.NodeInfo;
import net.sf.saxon.query.DynamicQueryContext;
import net.sf.saxon.trans.XPathException;
+import net.sf.saxon.value.HexBinaryValue;
import nu.xom.Builder;
import nu.xom.DocType;
import nu.xom.Element;
@@ -53,6 +54,7 @@
import org.teiid.core.TeiidComponentException;
import org.teiid.core.TeiidProcessingException;
import org.teiid.core.TeiidRuntimeException;
+import org.teiid.core.types.BinaryType;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.logging.MessageLevel;
@@ -90,6 +92,8 @@
value = wrapStax((Source)value, xquery.getConfig());
} else if (value instanceof java.util.Date) {
value = XMLSystemFunctions.convertToAtomicValue(value);
+ } else if (value instanceof BinaryType) {
+ value = new HexBinaryValue(((BinaryType)value).getBytesDirect());
}
dynamicContext.setParameter(entry.getKey(), value);
}
Modified: trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj
===================================================================
--- trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/javacc/org/teiid/query/parser/SQLParser.jj 2012-08-23 16:43:06 UTC (rev 4361)
@@ -449,6 +449,7 @@
| <QUOTE: "quote">
| <HEADER: "header">
| <NULLS: "nulls">
+| <OBJECTTABLE: "objecttable">
}
/*
@@ -551,7 +552,7 @@
{
}
{
- (<INSTEAD>|<VIEW>|<ENABLED>|<DISABLED>|<KEY>|<SERIAL>|<TEXTAGG>|<COUNT>|<ROW_NUMBER>|<RANK>|<DENSE_RANK>|<SUM>|<AVG>|<MIN>|<MAX>|<EVERY>|<STDDEV_POP>|<STDDEV_SAMP>|<VAR_SAMP>|<VAR_POP>|<DOCUMENT>|<CONTENT>|<TRIM>|<EMPTY>|<ORDINALITY>|<PATH>|<FIRST>|<LAST>|<NEXT>|<SUBSTRING>|<EXTRACT>|<TO_CHARS>|<TO_BYTES>|<TIMESTAMPADD>|<TIMESTAMPDIFF>|<QUERYSTRING>|<NAMESPACE>|<RESULT>|<INDEX>|<ACCESSPATTERN>|<AUTO_INCREMENT>|<WELLFORMED>|<SQL_TSI_FRAC_SECOND>|<SQL_TSI_SECOND>|<SQL_TSI_MINUTE>|<SQL_TSI_HOUR>|<SQL_TSI_DAY>|<SQL_TSI_WEEK>|<SQL_TSI_MONTH>|<SQL_TSI_QUARTER>|<SQL_TSI_YEAR>|<TEXTTABLE>|<ARRAYTABLE>|<SELECTOR>|<SKIP_KEYWORD>|<WIDTH>|<PASSING>|<NAME>|<ENCODING>|<COLUMNS>|<DELIMITER>|<QUOTE>|<HEADER>|<NULLS>)
+ (<INSTEAD>|<VIEW>|<ENABLED>|<DISABLED>|<KEY>|<SERIAL>|<TEXTAGG>|<COUNT>|<ROW_NUMBER>|<RANK>|<DENSE_RANK>|<SUM>|<AVG>|<MIN>|<MAX>|<EVERY>|<STDDEV_POP>|<STDDEV_SAMP>|<VAR_SAMP>|<VAR_POP>|<DOCUMENT>|<CONTENT>|<TRIM>|<EMPTY>|<ORDINALITY>|<PATH>|<FIRST>|<LAST>|<NEXT>|<SUBSTRING>|<EXTRACT>|<TO_CHARS>|<TO_BYTES>|<TIMESTAMPADD>|<TIMESTAMPDIFF>|<QUERYSTRING>|<NAMESPACE>|<RESULT>|<INDEX>|<ACCESSPATTERN>|<AUTO_INCREMENT>|<WELLFORMED>|<SQL_TSI_FRAC_SECOND>|<SQL_TSI_SECOND>|<SQL_TSI_MINUTE>|<SQL_TSI_HOUR>|<SQL_TSI_DAY>|<SQL_TSI_WEEK>|<SQL_TSI_MONTH>|<SQL_TSI_QUARTER>|<SQL_TSI_YEAR>|<TEXTTABLE>|<ARRAYTABLE>|<SELECTOR>|<SKIP_KEYWORD>|<WIDTH>|<PASSING>|<NAME>|<ENCODING>|<COLUMNS>|<DELIMITER>|<QUOTE>|<HEADER>|<NULLS>|<OBJECTTABLE>)
{
return getToken(0);
}
@@ -2294,6 +2295,8 @@
|
clause = xmlTable(info)
|
+ LOOKAHEAD(2) clause = objectTable(info)
+ |
clause = unaryFromClause(info)
|
LOOKAHEAD(subqueryFromClause(info)) clause = subqueryFromClause(info)
@@ -2555,6 +2558,89 @@
}
/*
+name=object table
+description=Returns table results by processing a script.
+example={code:sql}OBJECTTABLE('z' PASSING val AS z COLUMNS col OBJECT 'teiid_row') AS X{code}
+*/
+ObjectTable objectTable(ParseInfo info) :
+{
+ String rowScript = null;
+ String lang = null;
+ DerivedColumn passing = null;
+ ArrayList<DerivedColumn> passingValues = new ArrayList<DerivedColumn>();
+ ObjectTable.ObjectColumn column = null;
+ ArrayList<ObjectTable.ObjectColumn> columns = new ArrayList<ObjectTable.ObjectColumn>();
+ String aliasID = null;
+}
+{
+ <OBJECTTABLE> <LPAREN>
+ [<LANGUAGE> lang = stringVal()]
+ rowScript = stringVal()
+ [
+ <PASSING>
+ passing = derivedColumn(info)
+ {
+ passingValues.add(passing);
+ passing.setPropagateName(false);
+ }
+ (<COMMA>
+ passing = derivedColumn(info)
+ {
+ passingValues.add(passing);
+ passing.setPropagateName(false);
+ }
+ )*
+ ]
+ <COLUMNS>
+ column = objectColumn(info)
+ {
+ columns.add(column);
+ }
+ (<COMMA>
+ column = objectColumn(info)
+ {
+ columns.add(column);
+ }
+ )*
+ <RPAREN>
+ [<AS>] aliasID=id()
+ {
+ ObjectTable result = new ObjectTable();
+ result.setScriptingLanguage(lang);
+ result.setRowScript(rowScript);
+ result.setPassing(passingValues);
+ result.setColumns(columns);
+ result.setName(validateAlias(aliasID));
+ return result;
+ }
+}
+
+/*
+name=object table column
+description=object table column.
+example={code:sql}y integer 'teiid_rowcount'{code}
+*/
+ObjectTable.ObjectColumn objectColumn(ParseInfo info):
+{
+ String name = null;
+ ParsedDataType datatype = null;
+ String path = null;
+ Expression defaultExpr = null;
+}
+{
+ name = id()
+ datatype = parseDataType()
+ path = stringVal()
+ [
+ <DEFAULT_KEYWORD> defaultExpr = expression(info)
+ ]
+ {
+ return new ObjectTable.ObjectColumn(name, datatype.type, path, defaultExpr);
+ }
+}
+
+
+/*
name=xml table
description=Returns table results by processing an XQuery.
example={code:sql}XMLTABLE('/a/b' PASSING doc COLUMNS col XML PATH '.') AS X{code}
Modified: trunk/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/main/resources/org/teiid/query/i18n.properties 2012-08-23 16:43:06 UTC (rev 4361)
@@ -719,9 +719,10 @@
ValidationVisitor.xml_invalid_qname=The qname "{0}" is invalid.
ValidationVisitor.context_item_type=XMLTABLE or XMLQUERY PASSING context item must be an XML value.
ValidationVisitor.passing_requires_name=XMLTABLE or XMLQUERY PASSING clause can only contain at most 1 unnamed item.
-ValidationVisitor.duplicate_passing=XMLTABLE or XMLQUERY PASSING clause duplicate item name "{0}".
+ValidationVisitor.duplicate_passing=XMLTABLE, XMLQUERY, or OBJECTTABLE PASSING clause duplicate item name "{0}".
+ValidationVisitor.ValidationVisitor.context_item_not_allowed=OBJECTTABLE does not support passing unnamed items.
ValidationVisitor.one_ordinal=Only one FOR ORDINALITY column is allowed for an XMLTABLE.
-ValidationVisitor.invalid_default=XMLTABLE DEFAULT expression is invalid: "{0}"
+ValidationVisitor.invalid_default=XMLTABLE or OBJECTTABLE DEFAULT expression is invalid: "{0}"
ValidationVisitor.context_required=The XQuery requires a context item, but none exists in the PASSING clause.
ValidationVisitor.xmlparse_type=XMLPARSE expects a STRING, CLOB, or BLOB value.
ValidationVisitor.invalid_encoding=Encoding {0} is not valid.
@@ -1022,6 +1023,8 @@
TEIID31105=Returing warning to client: {0}
TEIID31106=Duplicate parameter {1} defined on {0}
TEIID31107=Procedure {0} can only have 1 RESULT/return value
+TEIID31109=Invalid language {0}. Supported language names are {1}.
+TEIID31109=Invalid script {0}. Scrpting engine reported: {1}.
SQLParser.proc_type_conflict=Result type {1} conflicts with return type {2} for procedure {0}
SQLParser.param_out=Procedure {0} RESULT param {1} must be of type OUT.
Modified: trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/test/java/org/teiid/query/parser/TestParser.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -5068,6 +5068,11 @@
helpTest(sql, "SELECT * FROM XMLTABLE(XMLNAMESPACES(NO DEFAULT), '/' COLUMNS x FOR ORDINALITY, y date DEFAULT {d'2000-01-01'} PATH '@date') AS x", query);
}
+ @Test public void testObjectTable() throws Exception {
+ Query actualCommand = (Query)QueryParser.getQueryParser().parseCommand("SELECT * from objecttable(LANGUAGE 'foo' 'x' columns y date 'row.date' default {d'2000-01-01'}) as x", new ParseInfo());
+ assertEquals("SELECT * FROM OBJECTTABLE(LANGUAGE 'foo' 'x' COLUMNS y date 'row.date' DEFAULT {d'2000-01-01'}) AS x", actualCommand.toString());
+ }
+
@Test public void testXmlSerialize() throws Exception {
XMLSerialize f = new XMLSerialize();
f.setDocument(true);
Modified: trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/test/java/org/teiid/query/resolver/TestResolver.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -169,27 +169,11 @@
CheckSymbolsAreResolvedVisitor vis = new CheckSymbolsAreResolvedVisitor();
DeepPreOrderNavigator.doVisit(command, vis);
- Collection unresolvedSymbols = vis.getUnresolvedSymbols();
+ Collection<LanguageObject> unresolvedSymbols = vis.getUnresolvedSymbols();
assertTrue("Found unresolved symbols: " + unresolvedSymbols, unresolvedSymbols.isEmpty()); //$NON-NLS-1$
return command;
}
- /**
- * Expect a QueryResolverException (not any other kind of Throwable)
- */
- private void helpResolveFails(Command command) {
- // resolve
- QueryResolverException exception = null;
- try {
- QueryResolver.resolveCommand(command, metadata);
- } catch(QueryResolverException e) {
- exception = e;
- } catch(TeiidException e) {
- fail("Exception during resolution (" + e.getClass().getName() + "): " + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
- }
- assertNotNull("Expected a QueryResolverException but got none.", exception); //$NON-NLS-1$
- }
-
private Criteria helpResolveCriteria(String sql) {
Criteria criteria = null;
@@ -211,7 +195,7 @@
CheckSymbolsAreResolvedVisitor vis = new CheckSymbolsAreResolvedVisitor();
DeepPreOrderNavigator.doVisit(criteria, vis);
- Collection unresolvedSymbols = vis.getUnresolvedSymbols();
+ Collection<LanguageObject> unresolvedSymbols = vis.getUnresolvedSymbols();
assertTrue("Found unresolved symbols: " + unresolvedSymbols, unresolvedSymbols.isEmpty()); //$NON-NLS-1$
return criteria;
}
@@ -229,7 +213,7 @@
CheckSymbolsAreResolvedVisitor vis = new CheckSymbolsAreResolvedVisitor();
DeepPreOrderNavigator.doVisit(command, vis);
- Collection unresolvedSymbols = vis.getUnresolvedSymbols();
+ Collection<LanguageObject> unresolvedSymbols = vis.getUnresolvedSymbols();
assertTrue("Found unresolved symbols: " + unresolvedSymbols, unresolvedSymbols.isEmpty()); //$NON-NLS-1$
return command;
}
@@ -331,27 +315,22 @@
StoredProcedure proc = (StoredProcedure)helpResolve(sql);
- List params = proc.getParameters();
+ List<SPParameter> params = proc.getParameters();
- // Remove all but IN and IN/OUT params
- Iterator paramIter = params.iterator();
- while (paramIter.hasNext()) {
- final SPParameter param = (SPParameter)paramIter.next();
- if (param.getParameterType() != ParameterInfo.IN && param.getParameterType() != ParameterInfo.INOUT) {
- paramIter.remove();
- }
- }
-
// Check remaining params against expected expressions
- assertEquals(expectedParameterExpressions.length, params.size());
- for (int i=0; i<expectedParameterExpressions.length; i++) {
- SPParameter param = (SPParameter)params.get(i);
+ int i = 0;
+ for (SPParameter param : params) {
+ if (param.getParameterType() != SPParameter.IN && param.getParameterType() != SPParameter.INOUT) {
+ continue;
+ }
if (expectedParameterExpressions[i] == null) {
assertNull(param.getExpression());
} else {
assertEquals(expectedParameterExpressions[i], param.getExpression());
}
+ i++;
}
+ assertEquals(expectedParameterExpressions.length, i);
return proc;
}
@@ -932,13 +911,13 @@
Query resolvedQuery = (Query) helpResolve("select * from (EXEC pm1.sq2('abc')) as x"); //$NON-NLS-1$
helpCheckFrom(resolvedQuery, new String[] { "x" }); //$NON-NLS-1$
- List elements = (List) ElementCollectorVisitor.getElements(resolvedQuery.getSelect(), false);
+ List<ElementSymbol> elements = (List<ElementSymbol>) ElementCollectorVisitor.getElements(resolvedQuery.getSelect(), false);
- ElementSymbol elem1 = (ElementSymbol)elements.get(0);
+ ElementSymbol elem1 = elements.get(0);
assertEquals("Did not get expected element", "x.e1", elem1.getName() ); //$NON-NLS-1$ //$NON-NLS-2$
assertEquals("Did not get expected type", DataTypeManager.DefaultDataClasses.STRING, elem1.getType()); //$NON-NLS-1$
- ElementSymbol elem2 = (ElementSymbol)elements.get(1);
+ ElementSymbol elem2 = elements.get(1);
assertEquals("Did not get expected element", "x.e2", elem2.getName() ); //$NON-NLS-1$ //$NON-NLS-2$
assertEquals("Did not get expected type", DataTypeManager.DefaultDataClasses.INTEGER, elem2.getType()); //$NON-NLS-1$
}
@@ -2355,7 +2334,7 @@
String update1 = "update pm1.g1 set e1 =1"; //$NON-NLS-1$
String update2 = "update pm2.g1 set e1 =1"; //$NON-NLS-1$
- List commands = new ArrayList();
+ List<Command> commands = new ArrayList<Command>();
commands.add(QueryParser.getQueryParser().parseCommand(update1));
commands.add(QueryParser.getQueryParser().parseCommand(update2));
BatchedUpdateCommand command = new BatchedUpdateCommand(commands);
@@ -2438,11 +2417,11 @@
StoredProcedure proc = (StoredProcedure)helpResolve(query);
- List projected = proc.getProjectedSymbols();
+ List<Expression> projected = proc.getProjectedSymbols();
assertEquals(2, projected.size());
- for (Iterator i = projected.iterator(); i.hasNext();) {
+ for (Iterator<Expression> i = projected.iterator(); i.hasNext();) {
ElementSymbol symbol = (ElementSymbol)i.next();
assertNotNull(symbol.getGroupSymbol());
}
@@ -2923,6 +2902,10 @@
helpResolve("select * from xmltable('/a' passing ?) as x");
}
+ @Test public void testObjectTableWithParam() {
+ helpResolve("select * from objecttable('x + 1' passing ? as x columns obj OBJECT '') as y");
+ }
+
@Test public void testXmlQueryWithParam() {
Query q = (Query)helpResolve("select xmlquery('/a' passing ?)");
XMLQuery ex = (XMLQuery) SymbolMap.getExpression(q.getSelect().getSymbols().get(0));
Modified: trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/engine/src/test/java/org/teiid/query/validator/TestValidator.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -1576,6 +1576,22 @@
@Test public void testXMLTableContextRequired() {
helpValidate("select * from xmltable('/a/b' passing convert('<a/>', xml) as a columns x for ordinality, c integer path '.') as x", new String[] {"XMLTABLE('/a/b' PASSING convert('<a/>', xml) AS a COLUMNS x FOR ORDINALITY, c integer PATH '.') AS x"}, RealMetadataFactory.example1Cached());
}
+
+ @Test public void testObjectTablePassing() {
+ helpValidate("select * from objecttable('x' passing 'a' columns c integer 'row') as x", new String[] {"OBJECTTABLE('x' PASSING 'a' COLUMNS c integer 'row') AS x"}, RealMetadataFactory.example1Cached());
+ }
+
+ @Test public void testObjectTablePassingSameName() {
+ helpValidate("select * from objecttable('x' passing 'a' AS X, 'b' AS x columns c integer 'row') as x", new String[] {"OBJECTTABLE('x' PASSING 'a' AS X, 'b' AS x COLUMNS c integer 'row') AS x"}, RealMetadataFactory.example1Cached());
+ }
+
+ @Test public void testObjectTableLanguage() {
+ helpValidate("select * from objecttable(language 'foo!' 'x' columns c integer 'row') as x", new String[] {"OBJECTTABLE(LANGUAGE 'foo!' 'x' COLUMNS c integer 'row') AS x"}, RealMetadataFactory.example1Cached());
+ }
+
+ @Test public void testObjectTableScript() {
+ helpValidate("select * from objecttable('this is not valid' columns c integer 'row') as x", new String[] {"OBJECTTABLE('this is not valid' COLUMNS c integer 'row') AS x"}, RealMetadataFactory.example1Cached());
+ }
@Test public void testXMLQueryPassingContextType() {
helpValidate("select xmlquery('/' passing 2)", new String[] {"XMLQUERY('/' PASSING 2)"}, RealMetadataFactory.example1Cached());
Modified: trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBDeployer.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBDeployer.java 2012-08-23 15:03:42 UTC (rev 4360)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBDeployer.java 2012-08-23 16:43:06 UTC (rev 4361)
@@ -29,6 +29,8 @@
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
+import javax.script.ScriptEngineManager;
+
import org.jboss.as.controller.ModelController;
import org.jboss.as.naming.deployment.ContextNames;
import org.jboss.as.server.Services;
@@ -38,7 +40,16 @@
import org.jboss.as.server.deployment.DeploymentUnitProcessingException;
import org.jboss.as.server.deployment.DeploymentUnitProcessor;
import org.jboss.modules.Module;
-import org.jboss.msc.service.*;
+import org.jboss.modules.ModuleClassLoader;
+import org.jboss.msc.service.AbstractServiceListener;
+import org.jboss.msc.service.Service;
+import org.jboss.msc.service.ServiceBuilder;
+import org.jboss.msc.service.ServiceController;
+import org.jboss.msc.service.ServiceName;
+import org.jboss.msc.service.ServiceTarget;
+import org.jboss.msc.service.StartContext;
+import org.jboss.msc.service.StartException;
+import org.jboss.msc.service.StopContext;
import org.jboss.msc.service.ServiceBuilder.DependencyType;
import org.jboss.msc.service.ServiceController.Mode;
import org.jboss.msc.service.ServiceController.State;
@@ -121,7 +132,9 @@
}
// add VDB module's classloader as an attachment
- deployment.addAttchment(ClassLoader.class, deploymentUnit.getAttachment(Attachments.MODULE).getClassLoader());
+ ModuleClassLoader classLoader = deploymentUnit.getAttachment(Attachments.MODULE).getClassLoader();
+ deployment.addAttchment(ClassLoader.class, classLoader);
+ deployment.addAttchment(ScriptEngineManager.class, new ScriptEngineManager(classLoader));
// check if this is a VDB with index files, if there are then build the TransformationMetadata
UDFMetaData udf = deploymentUnit.removeAttachment(TeiidAttachments.UDF_METADATA);
13 years, 4 months
teiid SVN: r4360 - in trunk: runtime/src/main/java/org/teiid/deployers and 1 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-08-23 11:03:42 -0400 (Thu, 23 Aug 2012)
New Revision: 4360
Modified:
trunk/admin/src/main/java/org/teiid/adminapi/impl/AdminObjectImpl.java
trunk/runtime/src/main/java/org/teiid/deployers/CompositeVDB.java
trunk/runtime/src/test/java/org/teiid/deployers/TestCompositeVDB.java
Log:
TEIID-2162 ensuring that attachments are copied
Modified: trunk/admin/src/main/java/org/teiid/adminapi/impl/AdminObjectImpl.java
===================================================================
--- trunk/admin/src/main/java/org/teiid/adminapi/impl/AdminObjectImpl.java 2012-08-23 14:07:39 UTC (rev 4359)
+++ trunk/admin/src/main/java/org/teiid/adminapi/impl/AdminObjectImpl.java 2012-08-23 15:03:42 UTC (rev 4360)
@@ -22,7 +22,6 @@
package org.teiid.adminapi.impl;
import java.io.Serializable;
-import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
@@ -38,8 +37,8 @@
private String serverName;
private String hostName;
- private Properties properties = new Properties();
- private transient Map<String, Object> attachments = Collections.synchronizedMap(new HashMap<String, Object>());
+ private Map<String, String> properties = new HashMap<String, String>(2);
+ private transient Map<Class<?>, Object> attachments;
@Override
public String getName() {
@@ -77,28 +76,30 @@
@Override
public Properties getProperties() {
Properties props = new Properties();
- for (String key:this.properties.stringPropertyNames()) {
- props.setProperty(key, this.properties.getProperty(key));
+ synchronized (properties) {
+ props.putAll(this.properties);
}
return props;
}
public void setProperties(Properties props) {
this.properties.clear();
- if (props != null) {
- for (String key:props.stringPropertyNames()) {
- addProperty(key, props.getProperty(key));
+ if (props != null && !props.isEmpty()) {
+ synchronized (properties) {
+ for (String key:props.stringPropertyNames()) {
+ addProperty(key, props.getProperty(key));
+ }
}
}
}
@Override
- public String getPropertyValue(String name) {
- return this.properties.getProperty(name);
+ public String getPropertyValue(String key) {
+ return this.properties.get(key);
}
public void addProperty(String key, String value) {
- this.properties.setProperty(key, value);
+ this.properties.put(key, value);
}
/**
@@ -112,23 +113,25 @@
* @throws UnsupportedOperationException when not supported by the implementation
*/
public <T> T addAttchment(Class<T> type, T attachment) {
- if (type == null)
- throw new IllegalArgumentException("Null type"); //$NON-NLS-1$
- Object result = this.attachments.put(type.getName(), attachment);
- if (result == null)
- return null;
- return type.cast(result);
-
+ synchronized (properties) {
+ if (type == null)
+ throw new IllegalArgumentException("Null type"); //$NON-NLS-1$
+ if (this.attachments == null) {
+ this.attachments = new HashMap<Class<?>, Object>();
+ }
+ Object result = this.attachments.put(type, attachment);
+ return type.cast(result);
+ }
}
- public Object addAttchment(String key, Object attachment) {
- if (key == null)
- throw new IllegalArgumentException("Null type"); //$NON-NLS-1$
- Object result = this.attachments.put(key, attachment);
- if (result == null)
- return null;
- return result;
- }
+ public Map<Class<?>, Object> getAttachments() {
+ synchronized (properties) {
+ if (this.attachments == null) {
+ this.attachments = new HashMap<Class<?>, Object>();
+ }
+ return attachments;
+ }
+ }
/**
* Remove attachment
@@ -139,22 +142,17 @@
* @throws IllegalArgumentException for a null name or type
*/
public <T> T removeAttachment(Class<T> type) {
- if (type == null)
- throw new IllegalArgumentException("Null type"); //$NON-NLS-1$
- Object result = this.attachments.remove(type.getName());
- if (result == null)
- return null;
- return type.cast(result);
+ synchronized (properties) {
+ if (type == null)
+ throw new IllegalArgumentException("Null type"); //$NON-NLS-1$
+ if (this.attachments == null) {
+ return null;
+ }
+ Object result = this.attachments.remove(type);
+ return type.cast(result);
+ }
}
- public Object removeAttachment(String key) {
- if (key == null)
- throw new IllegalArgumentException("Null type"); //$NON-NLS-1$
- Object result = this.attachments.remove(key);
- if (result == null)
- return null;
- return result;
- }
/**
* Get attachment
*
@@ -164,21 +162,16 @@
* @throws IllegalArgumentException for a null name or type
*/
public <T> T getAttachment(Class<T> type) {
- if (type == null)
- throw new IllegalArgumentException("Null type"); //$NON-NLS-1$
- Object result = this.attachments.get(type.getName());
- if (result == null)
- return null;
- return type.cast(result);
+ synchronized (properties) {
+ if (type == null)
+ throw new IllegalArgumentException("Null type"); //$NON-NLS-1$
+ if (this.attachments == null) {
+ return null;
+ }
+ Object result = this.attachments.get(type);
+ return type.cast(result);
+ }
}
- public Object getAttachment(String key) {
- if (key == null)
- throw new IllegalArgumentException("Null type"); //$NON-NLS-1$
- Object result = this.attachments.get(key);
- if (result == null)
- return null;
- return result;
- }
}
Modified: trunk/runtime/src/main/java/org/teiid/deployers/CompositeVDB.java
===================================================================
--- trunk/runtime/src/main/java/org/teiid/deployers/CompositeVDB.java 2012-08-23 14:07:39 UTC (rev 4359)
+++ trunk/runtime/src/main/java/org/teiid/deployers/CompositeVDB.java 2012-08-23 15:03:42 UTC (rev 4360)
@@ -118,6 +118,7 @@
newMergedVDB.setDescription(this.vdb.getDescription());
newMergedVDB.setStatus(this.vdb.getStatus());
newMergedVDB.setProperties(this.vdb.getProperties());
+ newMergedVDB.getAttachments().putAll(this.vdb.getAttachments());
newMergedVDB.setConnectionType(this.vdb.getConnectionType());
ConnectorManagerRepository mergedRepo = new ConnectorManagerRepository();
mergedRepo.getConnectorManagers().putAll(this.cmr.getConnectorManagers());
Modified: trunk/runtime/src/test/java/org/teiid/deployers/TestCompositeVDB.java
===================================================================
--- trunk/runtime/src/test/java/org/teiid/deployers/TestCompositeVDB.java 2012-08-23 14:07:39 UTC (rev 4359)
+++ trunk/runtime/src/test/java/org/teiid/deployers/TestCompositeVDB.java 2012-08-23 15:03:42 UTC (rev 4360)
@@ -52,16 +52,21 @@
VDBMetaData vdb = cvdb.getVDB();
return vdb.getAttachment(TransformationMetadata.class);
}
+
+ public static class Foo {
+
+ }
private static CompositeVDB createCompositeVDB(MetadataStore metadataStore, String vdbName) throws VirtualDatabaseException {
VDBMetaData vdbMetaData = createVDBMetadata(metadataStore, vdbName);
-
+ vdbMetaData.addAttchment(Foo.class, new Foo());
ConnectorManagerRepository cmr = new ConnectorManagerRepository();
cmr.addConnectorManager("source", getConnectorManager("FakeTranslator", "FakeConnection", getFuncsOne()));
cmr.addConnectorManager("source2", getConnectorManager("FakeTranslator2", "FakeConnection2", getFuncsTwo()));
CompositeVDB cvdb = new CompositeVDB(vdbMetaData, metadataStore, null, null, RealMetadataFactory.SFM.getSystemFunctions(),cmr, null);
cvdb.metadataLoadFinished();
+ assertNotNull(cvdb.getVDB().getAttachment(Foo.class));
return cvdb;
}
13 years, 4 months
teiid SVN: r4359 - in trunk: build/kits/jboss-as7/docs/teiid and 12 other directories.
by teiid-commits@lists.jboss.org
Author: rareddy
Date: 2012-08-23 10:07:39 -0400 (Thu, 23 Aug 2012)
New Revision: 4359
Added:
trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/
trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/RestASMBasedWebArchiveBuilder.java
trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/ResteasyEnabler.java
trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/TeiidRSProvider.java
trunk/jboss-integration/src/main/resources/rest-war/
trunk/jboss-integration/src/main/resources/rest-war/MANIFEST.MF
trunk/jboss-integration/src/main/resources/rest-war/jboss-web.xml
trunk/jboss-integration/src/main/resources/rest-war/web.xml
trunk/jboss-integration/src/test/java/org/teiid/jboss/rest/
trunk/jboss-integration/src/test/java/org/teiid/jboss/rest/TestRestWebArchiveBuilder.java
trunk/jboss-integration/src/test/resources/sample-vdb.xml
trunk/test-integration/common/src/test/java/org/teiid/arquillian/IntegrationTestRestWebserviceGeneration.java
trunk/test-integration/common/src/test/resources/sample-vdb.xml
Modified:
trunk/admin/src/main/java/org/teiid/adminapi/AdminFactory.java
trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html
trunk/build/kits/jboss-as7/modules/org/jboss/teiid/main/module.xml
trunk/jboss-integration/pom.xml
trunk/jboss-integration/src/main/java/org/teiid/jboss/IntegrationPlugin.java
trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBDeployer.java
trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBService.java
trunk/jboss-integration/src/main/resources/org/teiid/jboss/i18n.properties
Log:
TEIID-2158 - Initial implementation of generating REST based services based on a extension metadata provided on the virtual procedures.
Modified: trunk/admin/src/main/java/org/teiid/adminapi/AdminFactory.java
===================================================================
--- trunk/admin/src/main/java/org/teiid/adminapi/AdminFactory.java 2012-08-22 22:50:26 UTC (rev 4358)
+++ trunk/admin/src/main/java/org/teiid/adminapi/AdminFactory.java 2012-08-23 14:07:39 UTC (rev 4359)
@@ -148,7 +148,7 @@
}
- private class AdminImpl implements Admin{
+ public class AdminImpl implements Admin{
private static final String CLASS_NAME = "class-name";
private static final String JAVA_CONTEXT = "java:/";
private ModelControllerClient connection;
@@ -750,6 +750,10 @@
}
return templates;
}
+
+ public List<String> getDeployments(){
+ return Util.getDeployments(this.connection);
+ }
@Override
public Set<String> getDataSourceTemplateNames() throws AdminProcessingException {
Modified: trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html 2012-08-22 22:50:26 UTC (rev 4358)
+++ trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html 2012-08-23 14:07:39 UTC (rev 4359)
@@ -27,8 +27,9 @@
<H2><A NAME="Highlights"></A>Highlights</H2>
<ul>
<li>TEIID-2150 <b>Positional procedure defaults</b> - a procedure now may be called positionally with just the leading input parameters as long as all trailing parameters are out or defaultable.
- <li>TEIID-2148 <b>Streaming Improvements</b> - the ws translator invoke/invokeHttp procedures now execpt a stream parameter to indicate that the result should be streamed directly without an intermediate copy being created.
+ <li>TEIID-2148 <b>Streaming Improvements</b> - the ws translator invoke/invokeHttp procedures now accept a "stream"" parameter to indicate that the result should be streamed directly without an intermediate copy being created.
Also intermediate document/blob copies are made concurrently with reading to reduce latency.
+ <li>TEIID-2158 <b>Rest Services</b> - when required extension metadata defined on the virtual procedure, a REST based service on that procedure is automatically generated and deployed upon VDB deployment.
</ul>
<h2><a name="Compatibility">Compatibility Issues</a></h2>
Modified: trunk/build/kits/jboss-as7/modules/org/jboss/teiid/main/module.xml
===================================================================
--- trunk/build/kits/jboss-as7/modules/org/jboss/teiid/main/module.xml 2012-08-22 22:50:26 UTC (rev 4358)
+++ trunk/build/kits/jboss-as7/modules/org/jboss/teiid/main/module.xml 2012-08-23 14:07:39 UTC (rev 4359)
@@ -37,6 +37,7 @@
<module name="javax.activation.api"/>
<module name="org.jboss.as.clustering.jgroups"/>
<module name="org.infinispan"/>
+ <module name="asm.asm"/>
<!-- These dependencies here for ra.xml description -->
<module name="org.jboss.as.connector"/>
<module name="org.jboss.ironjacamar.api"/>
Modified: trunk/jboss-integration/pom.xml
===================================================================
--- trunk/jboss-integration/pom.xml 2012-08-22 22:50:26 UTC (rev 4358)
+++ trunk/jboss-integration/pom.xml 2012-08-23 14:07:39 UTC (rev 4359)
@@ -69,6 +69,13 @@
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>asm</groupId>
+ <artifactId>asm</artifactId>
+ <version>3.3.1</version>
+ <scope>provided</scope>
+ </dependency>
+
<!-- This dependency is to read the ra.xml file details -->
<dependency>
<groupId>org.jboss.as</groupId>
@@ -105,6 +112,13 @@
<type>test-jar</type>
<scope>test</scope>
</dependency>
+
+ <dependency>
+ <groupId>org.jboss.teiid</groupId>
+ <artifactId>teiid-engine</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.jboss.teiid.connectors</groupId>
Modified: trunk/jboss-integration/src/main/java/org/teiid/jboss/IntegrationPlugin.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/IntegrationPlugin.java 2012-08-22 22:50:26 UTC (rev 4358)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/IntegrationPlugin.java 2012-08-23 14:07:39 UTC (rev 4359)
@@ -98,5 +98,7 @@
TEIID50088,
TEIID50089,
TEIID50090, //Missing context
+ TEIID50091, // rest different # of param count
+ TEIID50092, // rest procedure execution
}
}
Modified: trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBDeployer.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBDeployer.java 2012-08-22 22:50:26 UTC (rev 4358)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBDeployer.java 2012-08-23 14:07:39 UTC (rev 4359)
@@ -29,22 +29,16 @@
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
+import org.jboss.as.controller.ModelController;
import org.jboss.as.naming.deployment.ContextNames;
+import org.jboss.as.server.Services;
import org.jboss.as.server.deployment.Attachments;
import org.jboss.as.server.deployment.DeploymentPhaseContext;
import org.jboss.as.server.deployment.DeploymentUnit;
import org.jboss.as.server.deployment.DeploymentUnitProcessingException;
import org.jboss.as.server.deployment.DeploymentUnitProcessor;
import org.jboss.modules.Module;
-import org.jboss.msc.service.AbstractServiceListener;
-import org.jboss.msc.service.Service;
-import org.jboss.msc.service.ServiceBuilder;
-import org.jboss.msc.service.ServiceController;
-import org.jboss.msc.service.ServiceName;
-import org.jboss.msc.service.ServiceTarget;
-import org.jboss.msc.service.StartContext;
-import org.jboss.msc.service.StartException;
-import org.jboss.msc.service.StopContext;
+import org.jboss.msc.service.*;
import org.jboss.msc.service.ServiceBuilder.DependencyType;
import org.jboss.msc.service.ServiceController.Mode;
import org.jboss.msc.service.ServiceController.State;
@@ -187,6 +181,9 @@
vdbService.addDependency(vdbSwitchServiceName, CountDownLatch.class, new InjectedValue<CountDownLatch>());
vdbService.addDependency(DependencyType.OPTIONAL, TeiidServiceNames.OBJECT_REPLICATOR, ObjectReplicator.class, vdb.objectReplicatorInjector);
+ // REST dependencies
+ vdbService.addDependency(Services.JBOSS_SERVER_CONTROLLER, ModelController.class, vdb.controllerValue);
+
// VDB restart switch, control the vdbservice by adding removing the switch service. If you
// remove the service by setting status remove, there is no way start it back up if vdbservice used alone
installVDBSwitchService(context.getServiceTarget(), vdbSwitchServiceName);
Modified: trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBService.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBService.java 2012-08-22 22:50:26 UTC (rev 4358)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/VDBService.java 2012-08-23 14:07:39 UTC (rev 4359)
@@ -37,6 +37,7 @@
import javax.xml.stream.XMLStreamException;
+import org.jboss.as.controller.ModelController;
import org.jboss.modules.Module;
import org.jboss.modules.ModuleIdentifier;
import org.jboss.modules.ModuleLoadException;
@@ -52,10 +53,10 @@
import org.teiid.adminapi.AdminProcessingException;
import org.teiid.adminapi.Translator;
import org.teiid.adminapi.impl.ModelMetaData;
+import org.teiid.adminapi.impl.ModelMetaData.Message.Severity;
import org.teiid.adminapi.impl.VDBMetaData;
import org.teiid.adminapi.impl.VDBMetadataParser;
import org.teiid.adminapi.impl.VDBTranslatorMetaData;
-import org.teiid.adminapi.impl.ModelMetaData.Message.Severity;
import org.teiid.common.buffer.BufferManager;
import org.teiid.core.TeiidException;
import org.teiid.deployers.CompositeVDB;
@@ -68,8 +69,9 @@
import org.teiid.deployers.VirtualDatabaseException;
import org.teiid.dqp.internal.datamgr.ConnectorManager;
import org.teiid.dqp.internal.datamgr.ConnectorManagerRepository;
+import org.teiid.dqp.internal.datamgr.ConnectorManagerRepository.ConnectorManagerException;
import org.teiid.dqp.internal.datamgr.TranslatorRepository;
-import org.teiid.dqp.internal.datamgr.ConnectorManagerRepository.ConnectorManagerException;
+import org.teiid.jboss.rest.ResteasyEnabler;
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.metadata.Datatype;
@@ -97,6 +99,9 @@
protected final InjectedValue<ObjectReplicator> objectReplicatorInjector = new InjectedValue<ObjectReplicator>();
protected final InjectedValue<VDBStatusChecker> vdbStatusCheckInjector = new InjectedValue<VDBStatusChecker>();
+ // for REST deployment
+ protected final InjectedValue<ModelController> controllerValue = new InjectedValue<ModelController>();
+
private VDBLifeCycleListener vdbListener;
private LinkedHashMap<String, Resource> visibilityMap;
@@ -166,6 +171,7 @@
};
getVDBRepository().addListener(this.vdbListener);
+ getVDBRepository().addListener(new ResteasyEnabler(controllerValue.getValue(), executorInjector.getValue()));
MetadataStore store = new MetadataStore();
Added: trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/RestASMBasedWebArchiveBuilder.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/RestASMBasedWebArchiveBuilder.java (rev 0)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/RestASMBasedWebArchiveBuilder.java 2012-08-23 14:07:39 UTC (rev 4359)
@@ -0,0 +1,410 @@
+/*
+ * 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.jboss.rest;
+
+import static org.objectweb.asm.Opcodes.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Properties;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.teiid.adminapi.impl.ModelMetaData;
+import org.teiid.adminapi.impl.VDBMetaData;
+import org.teiid.core.types.DataTypeManager;
+import org.teiid.core.util.FileUtils;
+import org.teiid.core.util.ObjectConverterUtil;
+import org.teiid.core.util.StringUtil;
+import org.teiid.jboss.IntegrationPlugin;
+import org.teiid.logging.LogConstants;
+import org.teiid.logging.LogManager;
+import org.teiid.metadata.Column;
+import org.teiid.metadata.ColumnSet;
+import org.teiid.metadata.MetadataStore;
+import org.teiid.metadata.Procedure;
+import org.teiid.metadata.ProcedureParameter;
+import org.teiid.metadata.Schema;
+import org.teiid.query.metadata.TransformationMetadata;
+
+
+
+@SuppressWarnings("nls")
+public class RestASMBasedWebArchiveBuilder {
+
+
+ public byte[] createRestArchive(VDBMetaData vdb) throws FileNotFoundException, IOException {
+ MetadataStore metadataStore = vdb.getAttachment(TransformationMetadata.class).getMetadataStore();
+
+ Properties props = new Properties();
+ props.setProperty("${context-name}", vdb.getName() + "_" + vdb.getVersion());
+ props.setProperty("${vdb-name}", vdb.getName());
+ props.setProperty("${vdb-version}", String.valueOf(vdb.getVersion()));
+
+ ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+ ZipOutputStream out = new ZipOutputStream(byteStream);
+ writeEntry("WEB-INF/web.xml", out, replaceTemplates(getFileContents("rest-war/web.xml"), props).getBytes());
+ writeEntry("WEB-INF/jboss-web.xml", out, replaceTemplates(getFileContents("rest-war/jboss-web.xml"), props).getBytes());
+
+ ArrayList<String> applicationViews = new ArrayList<String>();
+ for (ModelMetaData model:vdb.getModelMetaDatas().values()) {
+ Schema schema = metadataStore.getSchema(model.getName());
+ byte[] viewContents = getViewClass(vdb.getName(), vdb.getVersion(), model.getName(), schema);
+ if (viewContents != null) {
+ writeEntry("WEB-INF/classes/org/teiid/jboss/rest/"+model.getName()+".class", out, viewContents);
+ applicationViews.add(schema.getName());
+ }
+ }
+ writeEntry("WEB-INF/classes/org/teiid/jboss/rest/TeiidRestApplication.class", out, getApplicationClass(applicationViews));
+ writeEntry("META-INF/MANIFEST.MF", out, getFileContents("rest-war/MANIFEST.MF").getBytes());
+
+ out.close();
+ return byteStream.toByteArray();
+ }
+
+ private void writeEntry(String name, ZipOutputStream out, byte[] contents) throws IOException {
+ ZipEntry e = new ZipEntry(name);
+ out.putNextEntry(e);
+ FileUtils.write(new ByteArrayInputStream(contents), out, 1024);
+ out.closeEntry();
+ }
+
+ private String getFileContents(String file) throws IOException {
+ InputStream in = this.getClass().getClassLoader().getResourceAsStream(file);
+ Reader reader = new InputStreamReader(in);
+ String webXML = ObjectConverterUtil.convertToString(reader);
+ return webXML;
+ }
+
+ private String replaceTemplates(String orig, Properties replacements) {
+ for (String key:replacements.stringPropertyNames()) {
+ orig = StringUtil.replace(orig, key, replacements.getProperty(key));
+ }
+ return orig;
+ }
+
+ private static ArrayList<String> getPathParameters(String uri ) {
+ ArrayList pathParams = new ArrayList();
+ String param;
+ if (uri.contains("{")) {
+ while (uri.indexOf("}") > -1) {
+ int start = uri.indexOf("{");
+ int end = uri.indexOf("}");
+ param = uri.substring(start + 1, end);
+ uri = uri.substring(end + 1);
+ pathParams.add(param);
+ }
+ }
+ return pathParams;
+ }
+
+ public byte[] getApplicationClass(ArrayList<String> models) {
+ ClassWriter cw = new ClassWriter(0);
+ FieldVisitor fv;
+ MethodVisitor mv;
+
+ cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, "org/teiid/jboss/rest/TeiidRestApplication", null, "javax/ws/rs/core/Application", null);
+
+ {
+ fv = cw.visitField(ACC_PRIVATE, "singletons", "Ljava/util/Set;", "Ljava/util/Set<Ljava/lang/Object;>;", null);
+ fv.visitEnd();
+ }
+
+ {
+ fv = cw.visitField(ACC_PRIVATE, "empty", "Ljava/util/Set;", "Ljava/util/Set<Ljava/lang/Class<*>;>;", null);
+ fv.visitEnd();
+ }
+
+ {
+ mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKESPECIAL, "javax/ws/rs/core/Application", "<init>", "()V");
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitTypeInsn(NEW, "java/util/HashSet");
+ mv.visitInsn(DUP);
+ mv.visitMethodInsn(INVOKESPECIAL, "java/util/HashSet", "<init>", "()V");
+ mv.visitFieldInsn(PUTFIELD, "org/teiid/jboss/rest/TeiidRestApplication", "singletons", "Ljava/util/Set;");
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitTypeInsn(NEW, "java/util/HashSet");
+ mv.visitInsn(DUP);
+ mv.visitMethodInsn(INVOKESPECIAL, "java/util/HashSet", "<init>", "()V");
+ mv.visitFieldInsn(PUTFIELD, "org/teiid/jboss/rest/TeiidRestApplication", "empty", "Ljava/util/Set;");
+ mv.visitVarInsn(ALOAD, 0);
+
+ for (int i = 0; i < models.size(); i++) {
+ mv.visitFieldInsn(GETFIELD, "org/teiid/jboss/rest/TeiidRestApplication", "singletons", "Ljava/util/Set;");
+ mv.visitTypeInsn(NEW, "org/teiid/jboss/rest/"+models.get(i));
+ mv.visitInsn(DUP);
+ mv.visitMethodInsn(INVOKESPECIAL, "org/teiid/jboss/rest/"+models.get(i), "<init>", "()V");
+ mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Set", "add", "(Ljava/lang/Object;)Z");
+ mv.visitInsn(POP);
+ if (i < models.size()-1) {
+ mv.visitVarInsn(ALOAD, 0);
+ }
+ }
+
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(3, 1);
+ mv.visitEnd();
+ }
+
+ {
+ mv = cw.visitMethod(ACC_PUBLIC, "getClasses", "()Ljava/util/Set;", "()Ljava/util/Set<Ljava/lang/Class<*>;>;", null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitFieldInsn(GETFIELD, "org/teiid/jboss/rest/TeiidRestApplication", "empty", "Ljava/util/Set;");
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(1, 1);
+ mv.visitEnd();
+ }
+ {
+ mv = cw.visitMethod(ACC_PUBLIC, "getSingletons", "()Ljava/util/Set;", "()Ljava/util/Set<Ljava/lang/Object;>;", null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitFieldInsn(GETFIELD, "org/teiid/jboss/rest/TeiidRestApplication", "singletons", "Ljava/util/Set;");
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(1, 1);
+ mv.visitEnd();
+ }
+ cw.visitEnd();
+
+ return cw.toByteArray();
+ }
+
+ private byte[] getViewClass(String vdbName, int vdbVersion, String modelName, Schema schema) {
+ ClassWriter cw = new ClassWriter(0);
+ FieldVisitor fv;
+ MethodVisitor mv;
+ AnnotationVisitor av0;
+ boolean hasValidProcedures = false;
+
+ cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, "org/teiid/jboss/rest/"+modelName, null, "org/teiid/jboss/rest/TeiidRSProvider", null);
+
+ {
+ av0 = cw.visitAnnotation("Ljavax/ws/rs/Path;", true);
+ av0.visit("value", "/"+modelName.toLowerCase());
+ av0.visitEnd();
+ }
+ cw.visitInnerClass("javax/ws/rs/core/Response$Status", "javax/ws/rs/core/Response", "Status", ACC_PUBLIC + ACC_FINAL + ACC_STATIC + ACC_ENUM);
+
+ {
+ mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKESPECIAL, "org/teiid/jboss/rest/TeiidRSProvider", "<init>", "()V");
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(1, 1);
+ mv.visitEnd();
+ }
+
+ Collection<Procedure> procedures = schema.getProcedures().values();
+ for (Procedure procedure:procedures) {
+ String uri = procedure.getProperty(ResteasyEnabler.REST_NAMESPACE+"URI", false);
+ String method = procedure.getProperty(ResteasyEnabler.REST_NAMESPACE+"METHOD", false);
+ String contentType = procedure.getProperty(ResteasyEnabler.REST_NAMESPACE+"PRODUCES", false);
+ String charSet = procedure.getProperty(ResteasyEnabler.REST_NAMESPACE+"CHARSET", false);
+ if (getPathParameters(uri).size() != procedure.getParameters().size()) {
+ LogManager.logWarning(LogConstants.CTX_RUNTIME, IntegrationPlugin.Util.gs(IntegrationPlugin.Event.TEIID50091, procedure.getFullName()));
+ continue;
+ }
+ if (uri != null && method != null) {
+ if (contentType == null) {
+ contentType = findContentType(procedure);
+ }
+
+ if (contentType != null) {
+ contentType = contentType.toLowerCase();
+ if (contentType.equals("xml")) {
+ contentType = "application/xml";
+ }
+ else if (contentType.equals("json")) {
+ contentType = "application/json";
+ }
+ else if (contentType.equals("plain")) {
+ contentType = "text/plain";
+ }
+ buildRestService(modelName, procedure, method, uri, cw, contentType, charSet==null?"US-ASCII":charSet);
+ hasValidProcedures = true;
+ }
+ }
+ }
+
+ // getConnection method
+ {
+ mv = cw.visitMethod(ACC_PROTECTED, "getConnection", "()Ljava/sql/Connection;", null, new String[] { "java/sql/SQLException" });
+ mv.visitCode();
+ mv.visitTypeInsn(NEW, "org/teiid/jdbc/TeiidDriver");
+ mv.visitInsn(DUP);
+ mv.visitMethodInsn(INVOKESPECIAL, "org/teiid/jdbc/TeiidDriver", "<init>", "()V");
+ mv.visitVarInsn(ASTORE, 1);
+ mv.visitVarInsn(ALOAD, 1);
+ mv.visitLdcInsn("jdbc:teiid:"+vdbName+"."+vdbVersion);
+ mv.visitInsn(ACONST_NULL);
+ mv.visitMethodInsn(INVOKEVIRTUAL, "org/teiid/jdbc/TeiidDriver", "connect", "(Ljava/lang/String;Ljava/util/Properties;)Lorg/teiid/jdbc/ConnectionImpl;");
+ mv.visitInsn(ARETURN);
+ mv.visitMaxs(3, 2);
+ mv.visitEnd();
+ }
+ cw.visitEnd();
+
+ if (!hasValidProcedures) {
+ return null;
+ }
+ return cw.toByteArray();
+ }
+
+ private String findContentType(Procedure procedure) {
+ String contentType = "plain";
+ ColumnSet<Procedure> rs = procedure.getResultSet();
+ if (rs != null) {
+ Column returnColumn = rs.getColumns().get(0);
+ if (returnColumn.getDatatype().getRuntimeTypeName().equals(DataTypeManager.DefaultDataTypes.XML)) {
+ contentType = "xml"; //$NON-NLS-1$
+ }
+ else if (returnColumn.getDatatype().getRuntimeTypeName().equals(DataTypeManager.DefaultDataTypes.CLOB)) {
+ contentType = "json";
+ }
+ }
+ else {
+ for (ProcedureParameter pp:procedure.getParameters()) {
+ if (pp.getType().equals(ProcedureParameter.Type.ReturnValue)) {
+ if (pp.getDatatype().getRuntimeTypeName().equals(DataTypeManager.DefaultDataTypes.XML)) {
+ contentType = "xml"; //$NON-NLS-1$
+ }
+ else if (pp.getDatatype().getRuntimeTypeName().equals(DataTypeManager.DefaultDataTypes.CLOB)) {
+ contentType = "json"; //$NON-NLS-1$
+ }
+ }
+ }
+ }
+ return contentType;
+ }
+
+ private void buildRestService(String modelName, Procedure procedure,
+ String method, String uri, ClassWriter cw, String contentType,
+ String charSet) {
+
+ int paramsSize = procedure.getParameters().size();
+ MethodVisitor mv;
+
+ AnnotationVisitor av0;
+ {
+ StringBuilder paramSignature = new StringBuilder();
+ paramSignature.append("(");
+ for (int i = 0; i < paramsSize; i++) {
+ paramSignature.append("Ljava/lang/String;");
+ }
+ paramSignature.append(")");
+
+ mv = cw.visitMethod(ACC_PUBLIC, procedure.getName()+contentType, paramSignature+"Ljava/io/InputStream;", null, new String[] { "javax/ws/rs/WebApplicationException" });
+ {
+ av0 = mv.visitAnnotation("Ljavax/ws/rs/Produces;", true);
+ {
+ AnnotationVisitor av1 = av0.visitArray("value");
+ av1.visit(null, contentType);
+ av1.visitEnd();
+ }
+ av0.visitEnd();
+ }
+ {
+ av0 = mv.visitAnnotation("Ljavax/ws/rs/"+method.toUpperCase()+";", true);
+ av0.visitEnd();
+ }
+ {
+ av0 = mv.visitAnnotation("Ljavax/ws/rs/Path;", true);
+ av0.visit("value", uri);
+ av0.visitEnd();
+ }
+ {
+ av0 = mv.visitAnnotation("Ljavax/annotation/security/PermitAll;", true);
+ av0.visitEnd();
+ }
+
+ for (int i = 0; i < paramsSize; i++)
+ {
+ av0 = mv.visitParameterAnnotation(i, "Ljavax/ws/rs/PathParam;", true);
+ av0.visit("value", procedure.getParameters().get(i).getName());
+ av0.visitEnd();
+ }
+
+ mv.visitCode();
+ Label l0 = new Label();
+ Label l1 = new Label();
+ Label l2 = new Label();
+ mv.visitTryCatchBlock(l0, l1, l2, "java/sql/SQLException");
+ mv.visitLabel(l0);
+ mv.visitTypeInsn(NEW, "java/util/LinkedHashMap");
+ mv.visitInsn(DUP);
+ mv.visitMethodInsn(INVOKESPECIAL, "java/util/LinkedHashMap", "<init>", "()V");
+
+ mv.visitVarInsn(ASTORE, paramsSize+1);
+ for (int i = 0; i < paramsSize; i++) {
+ mv.visitVarInsn(ALOAD, paramsSize+1);
+ mv.visitLdcInsn(procedure.getParameters().get(i).getName());
+ mv.visitVarInsn(ALOAD, i+1);
+ mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+ mv.visitInsn(POP);
+ }
+
+ mv.visitVarInsn(ALOAD, 0);
+
+ // send parametr type information the procedure name
+ StringBuilder sb = new StringBuilder();
+ sb.append(procedure.getFullName()).append("(");
+ for (ProcedureParameter pp:procedure.getParameters()) {
+ sb.append(pp.getRuntimeType()).append(",");
+ }
+ sb.append(")");
+ mv.visitLdcInsn(sb.toString());
+
+ mv.visitVarInsn(ALOAD, paramsSize+1);
+ mv.visitLdcInsn(charSet);
+ mv.visitMethodInsn(INVOKEVIRTUAL, "org/teiid/jboss/rest/"+modelName, "execute", "(Ljava/lang/String;Ljava/util/Map;Ljava/lang/String;)Ljava/io/InputStream;");
+ mv.visitLabel(l1);
+ mv.visitInsn(ARETURN);
+ mv.visitLabel(l2);
+ mv.visitFrame(F_SAME1, 0, null, 1, new Object[] {"java/sql/SQLException"});
+ mv.visitVarInsn(ASTORE, paramsSize+1);
+ mv.visitTypeInsn(NEW, "javax/ws/rs/WebApplicationException");
+ mv.visitInsn(DUP);
+ mv.visitVarInsn(ALOAD, paramsSize+1);
+ mv.visitFieldInsn(GETSTATIC, "javax/ws/rs/core/Response$Status", "INTERNAL_SERVER_ERROR", "Ljavax/ws/rs/core/Response$Status;");
+ mv.visitMethodInsn(INVOKESPECIAL, "javax/ws/rs/WebApplicationException", "<init>", "(Ljava/lang/Throwable;Ljavax/ws/rs/core/Response$Status;)V");
+ mv.visitInsn(ATHROW);
+ mv.visitMaxs(4, paramsSize+2);
+ mv.visitEnd();
+ }
+ }
+}
Property changes on: trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/RestASMBasedWebArchiveBuilder.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/ResteasyEnabler.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/ResteasyEnabler.java (rev 0)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/ResteasyEnabler.java 2012-08-23 14:07:39 UTC (rev 4359)
@@ -0,0 +1,130 @@
+/*
+ * 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.jboss.rest;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.concurrent.Executor;
+
+import org.jboss.as.controller.ModelController;
+import org.teiid.adminapi.Admin;
+import org.teiid.adminapi.AdminException;
+import org.teiid.adminapi.AdminFactory;
+import org.teiid.adminapi.AdminFactory.AdminImpl;
+import org.teiid.adminapi.impl.ModelMetaData;
+import org.teiid.adminapi.impl.VDBMetaData;
+import org.teiid.deployers.CompositeVDB;
+import org.teiid.deployers.VDBLifeCycleListener;
+import org.teiid.logging.LogConstants;
+import org.teiid.logging.LogManager;
+import org.teiid.metadata.MetadataStore;
+import org.teiid.metadata.Procedure;
+import org.teiid.metadata.Schema;
+import org.teiid.query.metadata.TransformationMetadata;
+
+public class ResteasyEnabler implements VDBLifeCycleListener {
+ static final String REST_NAMESPACE = "{http://teiid.org/rest}"; //$NON-NLS-1$
+ private Admin admin;
+ private Executor executor;
+
+ public ResteasyEnabler(ModelController deployer, Executor executor) {
+ this.admin = AdminFactory.getInstance().createAdmin(deployer.createClient(executor));
+ this.executor = executor;
+ }
+
+ @Override
+ public void added(String name, int version, CompositeVDB vdb) {
+ }
+
+ @Override
+ public void finishedDeployment(String name, int version, CompositeVDB cvdb) {
+ final VDBMetaData vdb = cvdb.getVDB();
+
+ String generate = vdb.getPropertyValue("auto-generate-rest-war"); //$NON-NLS-1$
+
+ final String warName = buildName(vdb);
+ if (generate != null && Boolean.parseBoolean(generate)
+ && hasRestMetadata(vdb)
+ && !((AdminImpl) this.admin).getDeployments().contains(warName)) {
+ // this must be executing the async thread to avoid any lock-up from management operations
+ this.executor.execute(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ RestASMBasedWebArchiveBuilder builder = new RestASMBasedWebArchiveBuilder();
+ byte[] warContents = builder.createRestArchive(vdb);
+ admin.deploy(warName, new ByteArrayInputStream(warContents));
+ } catch (FileNotFoundException e) {
+ LogManager.logWarning(LogConstants.CTX_RUNTIME, e);
+ } catch (IOException e) {
+ LogManager.logWarning(LogConstants.CTX_RUNTIME, e);
+ } catch (AdminException e) {
+ LogManager.logWarning(LogConstants.CTX_RUNTIME, e);
+ }
+ }
+ });
+ }
+ }
+
+ @Override
+ public void removed(String name, int version, CompositeVDB cvdb) {
+ VDBMetaData vdb = cvdb.getVDB();
+ String generate = vdb.getPropertyValue("auto-generate-rest-war"); //$NON-NLS-1$
+ final String warName = buildName(vdb);
+ if (generate != null && Boolean.parseBoolean(generate)
+ && ((AdminImpl) this.admin).getDeployments().contains(warName)) {
+ this.executor.execute(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ admin.undeploy(warName);
+ } catch (AdminException e) {
+ LogManager.logWarning(LogConstants.CTX_RUNTIME, e);
+ }
+ }
+ });
+ }
+ }
+
+ private String buildName(VDBMetaData vdb) {
+ return vdb.getName().toLowerCase()+"_"+vdb.getVersion()+".war"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ private boolean hasRestMetadata(VDBMetaData vdb) {
+ MetadataStore metadataStore = vdb.getAttachment(TransformationMetadata.class).getMetadataStore();
+ for (ModelMetaData model: vdb.getModelMetaDatas().values()) {
+ Schema schema = metadataStore.getSchema(model.getName());
+ Collection<Procedure> procedures = schema.getProcedures().values();
+ for (Procedure procedure:procedures) {
+ String uri = procedure.getProperty(REST_NAMESPACE+"URI", false); //$NON-NLS-1$
+ String method = procedure.getProperty(REST_NAMESPACE+"METHOD", false); //$NON-NLS-1$
+ if (uri != null && method != null) {
+ return true;
+ }
+ }
+
+ }
+ return false;
+ }
+}
Property changes on: trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/ResteasyEnabler.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/TeiidRSProvider.java
===================================================================
--- trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/TeiidRSProvider.java (rev 0)
+++ trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/TeiidRSProvider.java 2012-08-23 14:07:39 UTC (rev 4359)
@@ -0,0 +1,132 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2011, Red Hat, Inc., and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This 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 software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.teiid.jboss.rest;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLXML;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.teiid.core.types.DataTypeManager;
+import org.teiid.core.types.Transform;
+import org.teiid.core.types.TransformationException;
+import org.teiid.core.util.ReaderInputStream;
+import org.teiid.jboss.IntegrationPlugin;
+
+public abstract class TeiidRSProvider {
+
+ public InputStream execute(String procedureSignature, Map<String, String> parameters, String charSet) throws SQLException {
+ Object result = null;
+ Connection conn = getConnection();
+ try {
+ List<String> paramTypes = getPathTypes(procedureSignature);
+ final String executeStatement = "call " + procedureSignature.substring(0, procedureSignature.indexOf('(')) + (parameters.isEmpty() ? "()" : createParmString(parameters.size())) + ";"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+ PreparedStatement statement = conn.prepareStatement(executeStatement);
+ if (!parameters.isEmpty()) {
+ int i = 1;
+ for (Object value : parameters.values()) {
+ try {
+ Transform t = DataTypeManager.getTransform(DataTypeManager.DefaultDataTypes.STRING, paramTypes.get(i-1));
+ if (t != null) {
+ statement.setObject(i++, t.transform(value));
+ }
+ else {
+ statement.setString(i++, (String)value);
+ }
+ } catch (TransformationException e) {
+ throw new SQLException(e);
+ }
+ }
+ }
+
+ final boolean hasResultSet = statement.execute();
+ if (hasResultSet) {
+ ResultSet rs = statement.getResultSet();
+ if (rs.next()) {
+ result = rs.getObject(1);
+ } else {
+ throw new SQLException(IntegrationPlugin.Util.gs(IntegrationPlugin.Event.TEIID50092));
+ }
+ rs.close();
+ }
+ else {
+ throw new SQLException(IntegrationPlugin.Util.gs(IntegrationPlugin.Event.TEIID50092));
+ }
+
+ statement.close();
+
+ if (result instanceof SQLXML) {
+ return ((SQLXML)result).getBinaryStream();
+ }
+ else if (result instanceof Blob) {
+ return ((Blob)result).getBinaryStream();
+ }
+ else if (result instanceof Clob) {
+ return new ReaderInputStream(((Clob)result).getCharacterStream(), Charset.forName(charSet));
+ }
+ return new ByteArrayInputStream(result.toString().getBytes());
+ } finally {
+ if (conn != null) {
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ }
+ }
+ }
+ }
+
+ protected String createParmString(int paramCount ) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("(?"); //$NON-NLS-1$
+ for (int i = 1; i < paramCount; i++) {
+ sb.append(","); //$NON-NLS-1$
+ sb.append("?"); //$NON-NLS-1$
+ }
+ sb.append(")"); //$NON-NLS-1$
+ return sb.toString();
+ }
+
+ private ArrayList<String> getPathTypes(String pathStr ) {
+ ArrayList pathParams = new ArrayList();
+
+ String parms = pathStr.substring(pathStr.indexOf('(')+1, pathStr.indexOf(')'));
+ StringTokenizer st = new StringTokenizer(parms, ","); //$NON-NLS-1$
+ while (st.hasMoreTokens()) {
+ pathParams.add(st.nextToken());
+ }
+ return pathParams;
+ }
+
+ protected abstract Connection getConnection() throws SQLException;
+
+}
Property changes on: trunk/jboss-integration/src/main/java/org/teiid/jboss/rest/TeiidRSProvider.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/jboss-integration/src/main/resources/org/teiid/jboss/i18n.properties
===================================================================
--- trunk/jboss-integration/src/main/resources/org/teiid/jboss/i18n.properties 2012-08-22 22:50:26 UTC (rev 4358)
+++ trunk/jboss-integration/src/main/resources/org/teiid/jboss/i18n.properties 2012-08-23 14:07:39 UTC (rev 4359)
@@ -68,6 +68,8 @@
TEIID50076=For {0}.{1} VDB, recursive delegation {2} found.
TEIID50077=The translator type "{0}" was not found in configuration; VDB {1}.{2} will not be started until translator is available.
TEIID50090=No context associated. More than likely either pass-through authentication should not be used or there are no security domains defined on the embedded transport.
+TEIID50091=The URI parameters defined on procedure {0}, do not match to number of parameters defined on procedure. Correct and reploy VDB to expose this procedure through REST.
+TEIID50092=Only result produceing procedures are allowed
wrong_vdb= Wrong VDB name and/or version supplied, or VDB is not active, or not available.
# subsystem description
Added: trunk/jboss-integration/src/main/resources/rest-war/MANIFEST.MF
===================================================================
--- trunk/jboss-integration/src/main/resources/rest-war/MANIFEST.MF (rev 0)
+++ trunk/jboss-integration/src/main/resources/rest-war/MANIFEST.MF 2012-08-23 14:07:39 UTC (rev 4359)
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+Dependencies: org.jboss.teiid, org.jboss.teiid.client, org.jboss.resteasy.resteasy-jaxrs
Property changes on: trunk/jboss-integration/src/main/resources/rest-war/MANIFEST.MF
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/jboss-integration/src/main/resources/rest-war/jboss-web.xml
===================================================================
--- trunk/jboss-integration/src/main/resources/rest-war/jboss-web.xml (rev 0)
+++ trunk/jboss-integration/src/main/resources/rest-war/jboss-web.xml 2012-08-23 14:07:39 UTC (rev 4359)
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<jboss-web>
+ <security-domain>java:/jaas/teiid-security</security-domain>
+</jboss-web>
\ No newline at end of file
Property changes on: trunk/jboss-integration/src/main/resources/rest-war/jboss-web.xml
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/jboss-integration/src/main/resources/rest-war/web.xml
===================================================================
--- trunk/jboss-integration/src/main/resources/rest-war/web.xml (rev 0)
+++ trunk/jboss-integration/src/main/resources/rest-war/web.xml 2012-08-23 14:07:39 UTC (rev 4359)
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
+ <display-name>${context-name}</display-name>
+ <context-param>
+ <param-name>javax.ws.rs.Application</param-name>
+ <param-value>org.teiid.jboss.rest.TeiidRestApplication</param-value>
+ </context-param>
+ <listener>
+ <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
+ </listener>
+ <servlet>
+ <servlet-name>RestDataservice</servlet-name>
+ <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>RestDataservice</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+ <!--
+ <security-role>
+ <description>security role</description>
+ <role-name>example-role</role-name>
+ </security-role>
+
+ <security-constraint>
+ <display-name>require valid user</display-name>
+ <web-resource-collection>
+ <web-resource-name>Teiid rest application</web-resource-name>
+ <url-pattern>/*</url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name>example-role</role-name>
+ </auth-constraint>
+ </security-constraint>
+
+ <login-config>
+ <auth-method>BASIC</auth-method>
+ <realm-name>yourdomain.com</realm-name>
+ </login-config>
+ -->
+</web-app>
\ No newline at end of file
Property changes on: trunk/jboss-integration/src/main/resources/rest-war/web.xml
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/jboss-integration/src/test/java/org/teiid/jboss/rest/TestRestWebArchiveBuilder.java
===================================================================
--- trunk/jboss-integration/src/test/java/org/teiid/jboss/rest/TestRestWebArchiveBuilder.java (rev 0)
+++ trunk/jboss-integration/src/test/java/org/teiid/jboss/rest/TestRestWebArchiveBuilder.java 2012-08-23 14:07:39 UTC (rev 4359)
@@ -0,0 +1,93 @@
+/*
+ * 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.jboss.rest;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Properties;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+import org.teiid.adminapi.impl.ModelMetaData;
+import org.teiid.adminapi.impl.VDBMetaData;
+import org.teiid.adminapi.impl.VDBMetadataParser;
+import org.teiid.core.util.UnitTestUtil;
+import org.teiid.metadata.Datatype;
+import org.teiid.metadata.MetadataFactory;
+import org.teiid.metadata.MetadataStore;
+import org.teiid.query.metadata.QueryMetadataInterface;
+import org.teiid.query.metadata.SystemMetadata;
+import org.teiid.query.metadata.TransformationMetadata;
+import org.teiid.query.parser.ParseException;
+import org.teiid.query.parser.QueryParser;
+import org.teiid.query.unittest.RealMetadataFactory;
+
+@SuppressWarnings("nls")
+public class TestRestWebArchiveBuilder {
+
+ @Test
+ public void testBuildArchive() throws Exception {
+ VDBMetaData vdb = VDBMetadataParser.unmarshell(new FileInputStream(UnitTestUtil.getTestDataFile("sample-vdb.xml")));
+ MetadataStore ms = new MetadataStore();
+ for (ModelMetaData model: vdb.getModelMetaDatas().values()) {
+ MetadataFactory mf = buildMetadataFactory(model.getSchemaText(), model.getName());
+ ms.addSchema(mf.getSchema());
+ }
+
+ TransformationMetadata metadata = RealMetadataFactory.createTransformationMetadata(ms, "Rest");
+ vdb.addAttchment(QueryMetadataInterface.class, metadata);
+ vdb.addAttchment(TransformationMetadata.class, metadata);
+ vdb.addAttchment(MetadataStore.class, ms);
+
+ RestASMBasedWebArchiveBuilder builder = new RestASMBasedWebArchiveBuilder();
+ byte[] contents = builder.createRestArchive(vdb);
+
+ ArrayList<String> files = new ArrayList<String>();
+ files.add("WEB-INF/web.xml");
+ files.add("WEB-INF/jboss-web.xml");
+ files.add("WEB-INF/classes/org/teiid/jboss/rest/View.class");
+ files.add("WEB-INF/classes/org/teiid/jboss/rest/TeiidRestApplication.class");
+ files.add("META-INF/MANIFEST.MF");
+
+ ZipInputStream zipIn = new ZipInputStream(new ByteArrayInputStream(contents));
+ ZipEntry ze;
+ while ((ze = zipIn.getNextEntry()) != null) {
+ assertTrue(files.contains(ze.getName()));
+ zipIn.closeEntry();
+ }
+ }
+
+
+ public MetadataFactory buildMetadataFactory(String ddl, String model) throws ParseException {
+ MetadataFactory mf = new MetadataFactory(null, 1, model, getDataTypes(), new Properties(), null);
+ new QueryParser().parseDDL(mf, ddl);
+ return mf;
+ }
+
+ static Map<String, Datatype> getDataTypes() {
+ return SystemMetadata.getInstance().getRuntimeTypeMap();
+ }
+}
Property changes on: trunk/jboss-integration/src/test/java/org/teiid/jboss/rest/TestRestWebArchiveBuilder.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/jboss-integration/src/test/resources/sample-vdb.xml
===================================================================
--- trunk/jboss-integration/src/test/resources/sample-vdb.xml (rev 0)
+++ trunk/jboss-integration/src/test/resources/sample-vdb.xml 2012-08-23 14:07:39 UTC (rev 4359)
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<vdb name="sample" version="1">
+ <property name="UseConnectorMetadata" value="true" />
+ <property name="auto-generate-rest-war" value="true"/>
+
+ <model name="Txns">
+ <source name="text-connector" translator-name="loopback" />
+ <metadata type="DDL"><![CDATA[
+ CREATE FOREIGN TABLE G1 (e1 string, e2 integer);
+ CREATE FOREIGN TABLE G2 (e1 string, e2 integer);
+ ]]> </metadata>
+ </model>
+ <model name="View" type ="VIRTUAL">
+ <metadata type="DDL"><![CDATA[
+ SET NAMESPACE 'http://teiid.org/rest' AS REST;
+ CREATE VIRTUAL PROCEDURE g1Table(IN p1 integer) RETURNS TABLE (xml_out xml) OPTIONS (UPDATECOUNT 0, "REST:METHOD" 'GET', "REST:URI" 'g1/{p1}')
+ AS
+ BEGIN
+ SELECT XMLELEMENT(NAME sample.g1Table.p1, XMLATTRIBUTES (g1Table.p1 as p1), XMLAGG(XMLELEMENT(NAME "row", XMLFOREST(e1, e2)))) AS xml_out FROM Txns.G1;
+ END
+ CREATE VIRTUAL PROCEDURE g2Table() RETURNS TABLE (xml_out string) OPTIONS (UPDATECOUNT 0, "REST:METHOD" 'GET', "REST:URI" 'g2')
+ AS
+ BEGIN
+ SELECT '{ "age":100, "name":test,messages:["msg1","msg2","msg3"]}' as xml_out;
+ END
+ ]]> </metadata>
+ </model>
+
+</vdb>
\ No newline at end of file
Property changes on: trunk/jboss-integration/src/test/resources/sample-vdb.xml
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/test-integration/common/src/test/java/org/teiid/arquillian/IntegrationTestRestWebserviceGeneration.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/arquillian/IntegrationTestRestWebserviceGeneration.java (rev 0)
+++ trunk/test-integration/common/src/test/java/org/teiid/arquillian/IntegrationTestRestWebserviceGeneration.java 2012-08-23 14:07:39 UTC (rev 4359)
@@ -0,0 +1,92 @@
+/*
+ * 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.arquillian;
+
+import static org.junit.Assert.*;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+import org.jboss.arquillian.junit.Arquillian;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.teiid.adminapi.Admin;
+import org.teiid.adminapi.AdminException;
+import org.teiid.adminapi.AdminFactory;
+import org.teiid.adminapi.AdminFactory.AdminImpl;
+import org.teiid.core.util.UnitTestUtil;
+import org.teiid.jdbc.AbstractMMQueryTestCase;
+import org.teiid.jdbc.TeiidDriver;
+
+(a)RunWith(Arquillian.class)
+@SuppressWarnings("nls")
+public class IntegrationTestRestWebserviceGeneration extends AbstractMMQueryTestCase {
+
+ private Admin admin;
+
+ @Before
+ public void setup() throws Exception {
+ admin = AdminFactory.getInstance().createAdmin("localhost", 9999, "admin", "admin".toCharArray());
+ }
+
+ @After
+ public void teardown() throws AdminException {
+ AdminUtil.cleanUp(admin);
+ admin.close();
+ }
+
+ @Test
+ public void testReuse() throws Exception {
+ admin.deploy("sample-vdb.xml",new FileInputStream(UnitTestUtil.getTestDataFile("sample-vdb.xml")));
+
+ assertTrue(AdminUtil.waitForVDBLoad(admin, "sample", 1, 3));
+
+ this.internalConnection = TeiidDriver.getInstance().connect("jdbc:teiid:sample@mm://localhost:31000;user=user;password=user", null);
+
+ execute("SELECT * FROM Txns.G1"); //$NON-NLS-1$
+ this.internalResultSet.next();
+
+ assertTrue(((AdminImpl)admin).getDeployments().contains("sample_1.war"));
+
+ String response = httpCall("http://localhost:8080/sample_1/view/g1/123", "GET");
+ assertEquals("<sample.g1Table.p1 p1=\"123\"><row><e1>ABCDEFGHIJ</e1><e2>0</e2></row></sample.g1Table.p1>", response);
+ }
+
+ private String httpCall(String url, String method) throws Exception {
+ StringBuffer buff = new StringBuffer();
+ HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
+ connection.setRequestMethod(method);
+ connection.setDoOutput(true);
+ BufferedReader serverResponse = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+ String line;
+ while ((line = serverResponse.readLine()) != null) {
+ buff.append(line);
+ }
+ return buff.toString();
+ }
+}
Property changes on: trunk/test-integration/common/src/test/java/org/teiid/arquillian/IntegrationTestRestWebserviceGeneration.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/test-integration/common/src/test/resources/sample-vdb.xml
===================================================================
--- trunk/test-integration/common/src/test/resources/sample-vdb.xml (rev 0)
+++ trunk/test-integration/common/src/test/resources/sample-vdb.xml 2012-08-23 14:07:39 UTC (rev 4359)
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<vdb name="sample" version="1">
+ <property name="UseConnectorMetadata" value="true" />
+ <property name="auto-generate-rest-war" value="true"/>
+
+ <model name="Txns">
+ <source name="text-connector" translator-name="loopback" />
+ <metadata type="DDL"><![CDATA[
+ CREATE FOREIGN TABLE G1 (e1 string, e2 integer);
+ CREATE FOREIGN TABLE G2 (e1 string, e2 integer);
+ ]]> </metadata>
+ </model>
+ <model name="View" type ="VIRTUAL">
+ <metadata type="DDL"><![CDATA[
+ SET NAMESPACE 'http://teiid.org/rest' AS REST;
+ CREATE VIRTUAL PROCEDURE g1Table(IN p1 integer) RETURNS TABLE (xml_out xml) OPTIONS (UPDATECOUNT 0, "REST:METHOD" 'GET', "REST:URI" 'g1/{p1}')
+ AS
+ BEGIN
+ SELECT XMLELEMENT(NAME sample.g1Table.p1, XMLATTRIBUTES (g1Table.p1 as p1), XMLAGG(XMLELEMENT(NAME "row", XMLFOREST(e1, e2)))) AS xml_out FROM Txns.G1;
+ END
+ CREATE VIRTUAL PROCEDURE g2Table() RETURNS TABLE (xml_out string) OPTIONS (UPDATECOUNT 0, "REST:METHOD" 'GET', "REST:URI" 'g2')
+ AS
+ BEGIN
+ SELECT '{ "age":100, "name":test,messages:["msg1","msg2","msg3"]}' as xml_out;
+ END
+ ]]> </metadata>
+ </model>
+
+</vdb>
Property changes on: trunk/test-integration/common/src/test/resources/sample-vdb.xml
___________________________________________________________________
Added: svn:mime-type
+ text/plain
13 years, 4 months
teiid SVN: r4358 - in trunk/engine/src: test/java/org/teiid/query/processor and 1 other directory.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-08-22 18:50:26 -0400 (Wed, 22 Aug 2012)
New Revision: 4358
Modified:
trunk/engine/src/main/java/org/teiid/query/sql/lang/XMLTable.java
trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java
Log:
TEIID-2160 fixing the for ordinality column type
Modified: trunk/engine/src/main/java/org/teiid/query/sql/lang/XMLTable.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/sql/lang/XMLTable.java 2012-08-22 14:36:45 UTC (rev 4357)
+++ trunk/engine/src/main/java/org/teiid/query/sql/lang/XMLTable.java 2012-08-22 22:50:26 UTC (rev 4358)
@@ -26,7 +26,7 @@
private XPathExpression pathExpression;
public XMLColumn(String name) {
- super(name, DataTypeManager.DefaultDataTypes.STRING);
+ super(name, DataTypeManager.DefaultDataTypes.INTEGER);
this.ordinal = true;
}
Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java 2012-08-22 14:36:45 UTC (rev 4357)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestSQLXMLProcessing.java 2012-08-22 22:50:26 UTC (rev 4358)
@@ -22,6 +22,7 @@
package org.teiid.query.processor;
+import static org.junit.Assert.*;
import static org.teiid.query.processor.TestProcessor.*;
import java.io.FileInputStream;
@@ -52,6 +53,7 @@
import org.teiid.query.mapping.relational.QueryNode;
import org.teiid.query.metadata.TransformationMetadata;
import org.teiid.query.optimizer.capabilities.DefaultCapabilitiesFinder;
+import org.teiid.query.sql.symbol.Expression;
import org.teiid.query.unittest.RealMetadataFactory;
import org.teiid.query.unittest.TimestampUtil;
@@ -320,7 +322,8 @@
Arrays.asList(4, null),
};
- process(sql, expected);
+ ProcessorPlan plan = process(sql, expected);
+ assertEquals(DataTypeManager.DefaultDataClasses.INTEGER, ((Expression)plan.getOutputElements().get(0)).getType());
}
@Test public void testXmlTableDescendantPath() throws Exception {
@@ -514,10 +517,11 @@
TimestampWithTimezone.resetCalendar(null); //$NON-NLS-1$
}
- private void process(String sql, List<?>[] expected) throws Exception {
+ private ProcessorPlan process(String sql, List<?>[] expected) throws Exception {
ProcessorPlan plan = helpGetPlan(helpParse(sql), RealMetadataFactory.example1Cached(), new DefaultCapabilitiesFinder(), createCommandContext());
helpProcess(plan, createCommandContext(), dataManager, expected);
+ return plan;
}
public static BlobType blobFromFile(final String file) {
13 years, 4 months
teiid SVN: r4357 - in trunk/build: kits/embedded and 1 other directories.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-08-22 10:36:45 -0400 (Wed, 22 Aug 2012)
New Revision: 4357
Modified:
trunk/build/assembly/embedded-dist.xml
trunk/build/kits/embedded/examples/embedded-portfolio/run.bat
trunk/build/kits/embedded/examples/embedded-portfolio/run.sh
trunk/build/kits/embedded/readme.txt
Log:
TEIID-2155 adding connector jars to the embedded kit
Modified: trunk/build/assembly/embedded-dist.xml
===================================================================
--- trunk/build/assembly/embedded-dist.xml 2012-08-22 02:39:00 UTC (rev 4356)
+++ trunk/build/assembly/embedded-dist.xml 2012-08-22 14:36:45 UTC (rev 4357)
@@ -106,6 +106,26 @@
<fileMode>0644</fileMode>
</binaries>
</moduleSet>
-
+
+ <moduleSet>
+ <includeSubModules>true</includeSubModules>
+ <useAllReactorProjects>true</useAllReactorProjects>
+
+ <includes>
+ <include>org.jboss.teiid.connectors:connector-file</include>
+ <include>org.jboss.teiid.connectors:connector-ldap</include>
+ <include>org.jboss.teiid.connectors:connector-salesforce</include>
+ <include>org.jboss.teiid.connectors:connector-ws</include>
+ </includes>
+
+ <binaries>
+ <includeDependencies>true</includeDependencies>
+ <attachmentClassifier>lib</attachmentClassifier>
+ <unpack>false</unpack>
+ <outputDirectory>optional</outputDirectory>
+ <fileMode>0644</fileMode>
+ </binaries>
+ </moduleSet>
+
</moduleSets>
</assembly>
Modified: trunk/build/kits/embedded/examples/embedded-portfolio/run.bat
===================================================================
--- trunk/build/kits/embedded/examples/embedded-portfolio/run.bat 2012-08-22 02:39:00 UTC (rev 4356)
+++ trunk/build/kits/embedded/examples/embedded-portfolio/run.bat 2012-08-22 14:36:45 UTC (rev 4357)
@@ -1,4 +1,4 @@
-TEIID_PATH=..\..\lib\*;..\..\optional\translator-file-${pom.version}.jar;..\..\optional\translator-jdbc-${pom.version}.jar;h2-1.3.161.jar
+TEIID_PATH=..\..\lib\*;..\..\optional\translator-file-${pom.version}.jar;..\..\optional\connector-file-${pom.version}-lib.jar;..\..\optional\translator-jdbc-${pom.version}.jar;h2-1.3.161.jar
javac -cp %TEIID_PATH% src\org\teiid\example\*.java
Modified: trunk/build/kits/embedded/examples/embedded-portfolio/run.sh
===================================================================
--- trunk/build/kits/embedded/examples/embedded-portfolio/run.sh 2012-08-22 02:39:00 UTC (rev 4356)
+++ trunk/build/kits/embedded/examples/embedded-portfolio/run.sh 2012-08-22 14:36:45 UTC (rev 4357)
@@ -1,6 +1,6 @@
#!/bin/sh
-TEIID_PATH=../../lib/*:../../optional/translator-file-${pom.version}.jar:../../optional/translator-jdbc-${pom.version}.jar:h2-1.3.161.jar
+TEIID_PATH=../../lib/*:../../optional/translator-file-${pom.version}.jar:../../optional/connector-file-${pom.version}-lib.jar:../../optional/translator-jdbc-${pom.version}.jar:h2-1.3.161.jar
javac -cp ${TEIID_PATH} src/org/teiid/example/*.java
Modified: trunk/build/kits/embedded/readme.txt
===================================================================
--- trunk/build/kits/embedded/readme.txt 2012-08-22 02:39:00 UTC (rev 4356)
+++ trunk/build/kits/embedded/readme.txt 2012-08-22 14:36:45 UTC (rev 4357)
@@ -12,6 +12,5 @@
- Access through Admin API
- Authentication
- Connection pools
--
\ No newline at end of file
13 years, 4 months
teiid SVN: r4356 - in trunk/engine/src/main/java/org/teiid/common/buffer: impl and 1 other directory.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-08-21 22:39:00 -0400 (Tue, 21 Aug 2012)
New Revision: 4356
Modified:
trunk/engine/src/main/java/org/teiid/common/buffer/LobManager.java
trunk/engine/src/main/java/org/teiid/common/buffer/impl/BufferManagerImpl.java
Log:
TEIID-2153 allowing cached lobs to be referenced after close
Modified: trunk/engine/src/main/java/org/teiid/common/buffer/LobManager.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/common/buffer/LobManager.java 2012-08-21 17:49:10 UTC (rev 4355)
+++ trunk/engine/src/main/java/org/teiid/common/buffer/LobManager.java 2012-08-22 02:39:00 UTC (rev 4356)
@@ -247,11 +247,16 @@
Streamable<?> persistedLob;
OutputStream fsos = store.createOutputStream();
-byteLength = ObjectConverterUtil.write(fsos, is, bytes, -1);
+ byteLength = ObjectConverterUtil.write(fsos, is, bytes, -1);
// re-construct the new lobs based on the file store
final long lobOffset = offset;
final long lobLength = byteLength;
+ /*
+ * Using an inner class here will hold a reference to the LobManager
+ * which prevents the removal of the FileStore until all of the
+ * lobs have been gc'd
+ */
InputStreamFactory isf = new InputStreamFactory() {
@Override
public InputStream getInputStream() throws IOException {
@@ -263,7 +268,7 @@
return StorageMode.PERSISTENT;
}
};
-
+ isf.setLength(byteLength);
if (lob instanceof BlobType) {
persistedLob = new BlobType(new BlobImpl(isf));
}
Modified: trunk/engine/src/main/java/org/teiid/common/buffer/impl/BufferManagerImpl.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/common/buffer/impl/BufferManagerImpl.java 2012-08-21 17:49:10 UTC (rev 4355)
+++ trunk/engine/src/main/java/org/teiid/common/buffer/impl/BufferManagerImpl.java 2012-08-22 02:39:00 UTC (rev 4356)
@@ -465,16 +465,13 @@
Class<?>[] types = getTypeClasses(elements);
BatchManagerImpl batchManager = createBatchManager(newID, types);
LobManager lobManager = null;
- FileStore lobStore = null;
if (lobIndexes != null) {
- lobStore = createFileStore(newID + "_lobs"); //$NON-NLS-1$
+ FileStore lobStore = createFileStore(newID + "_lobs"); //$NON-NLS-1$
lobManager = new LobManager(lobIndexes, lobStore);
+ AutoCleanupUtil.setCleanupReference(lobManager, lobStore);
batchManager.setLobManager(lobManager);
}
TupleBuffer tupleBuffer = new TupleBuffer(batchManager, String.valueOf(newID), elements, lobManager, getProcessorBatchSize(elements));
- if (lobStore != null) {
- AutoCleanupUtil.setCleanupReference(batchManager, lobStore);
- }
if (LogManager.isMessageToBeRecorded(LogConstants.CTX_BUFFER_MGR, MessageLevel.DETAIL)) {
LogManager.logDetail(LogConstants.CTX_BUFFER_MGR, "Creating TupleBuffer:", newID, elements, Arrays.toString(types), "of type", tupleSourceType); //$NON-NLS-1$ //$NON-NLS-2$
}
13 years, 4 months
teiid SVN: r4355 - in branches/7.7.x/connectors/translator-jdbc/src: test/java/org/teiid/translator/jdbc/sybase and 1 other directory.
by teiid-commits@lists.jboss.org
Author: jolee
Date: 2012-08-21 13:49:10 -0400 (Tue, 21 Aug 2012)
New Revision: 4355
Modified:
branches/7.7.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sybase/SybaseExecutionFactory.java
branches/7.7.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sybase/TestSybaseSQLConversionVisitor.java
Log:
TEIID-2157 adding sybase limit for older releases
Modified: branches/7.7.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sybase/SybaseExecutionFactory.java
===================================================================
--- branches/7.7.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sybase/SybaseExecutionFactory.java 2012-08-21 17:29:30 UTC (rev 4354)
+++ branches/7.7.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sybase/SybaseExecutionFactory.java 2012-08-21 17:49:10 UTC (rev 4355)
@@ -52,7 +52,8 @@
@Translator(name="sybase", description="A translator for Sybase Database")
public class SybaseExecutionFactory extends BaseSybaseExecutionFactory {
-
+
+ public static final String TWELVE_5_3 = "12.5.3"; //$NON-NLS-1$
public static final String TWELVE_5 = "12.5"; //$NON-NLS-1$
public static final String FIFTEEN_0_2 = "15.0.2"; //$NON-NLS-1$
public static final String FIFTEEN_5 = "15.5"; //$NON-NLS-1$
@@ -363,7 +364,7 @@
@Override
public boolean supportsRowLimit() {
- return getDatabaseVersion().compareTo(FIFTEEN_0_2) >= 0;
+ return (getDatabaseVersion().startsWith("12") && getDatabaseVersion().compareTo(TWELVE_5_3) >= 0) || getDatabaseVersion().compareTo(FIFTEEN_0_2) >=0; //$NON-NLS-1$
}
}
Modified: branches/7.7.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sybase/TestSybaseSQLConversionVisitor.java
===================================================================
--- branches/7.7.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sybase/TestSybaseSQLConversionVisitor.java 2012-08-21 17:29:30 UTC (rev 4354)
+++ branches/7.7.x/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sybase/TestSybaseSQLConversionVisitor.java 2012-08-21 17:49:10 UTC (rev 4355)
@@ -35,6 +35,7 @@
/**
*/
+@SuppressWarnings("nls")
public class TestSybaseSQLConversionVisitor {
private static SybaseExecutionFactory trans = new SybaseExecutionFactory();
@@ -256,4 +257,16 @@
"SELECT {fn timestampadd(sql_tsi_second, 1, SmallA.TimestampValue)}, dateadd(millisecond, 1000/1000000, SmallA.TimestampValue), datediff(millisecond, SmallA.TimestampValue,SmallA.TimestampValue)*1000000 FROM SmallA"); //$NON-NLS-1$
}
+ @Test public void testLimitSupport() {
+ SybaseExecutionFactory sybaseExecutionFactory = new SybaseExecutionFactory();
+ sybaseExecutionFactory.setDatabaseVersion("12.5.4");
+ assertTrue(sybaseExecutionFactory.supportsRowLimit());
+ sybaseExecutionFactory.setDatabaseVersion("12.5.2");
+ assertFalse(sybaseExecutionFactory.supportsRowLimit());
+ sybaseExecutionFactory.setDatabaseVersion("15");
+ assertFalse(sybaseExecutionFactory.supportsRowLimit());
+ sybaseExecutionFactory.setDatabaseVersion("15.1");
+ assertTrue(sybaseExecutionFactory.supportsRowLimit());
+ }
+
}
13 years, 4 months
teiid SVN: r4354 - in trunk/connectors/translator-jdbc/src: test/java/org/teiid/translator/jdbc/sybase and 1 other directory.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-08-21 13:29:30 -0400 (Tue, 21 Aug 2012)
New Revision: 4354
Modified:
trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sybase/SybaseExecutionFactory.java
trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sybase/TestSybaseSQLConversionVisitor.java
Log:
TEIID-2157 adding sybase limit for older releases
Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sybase/SybaseExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sybase/SybaseExecutionFactory.java 2012-08-21 16:45:15 UTC (rev 4353)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sybase/SybaseExecutionFactory.java 2012-08-21 17:29:30 UTC (rev 4354)
@@ -58,7 +58,8 @@
@Translator(name="sybase", description="A translator for Sybase Database")
public class SybaseExecutionFactory extends BaseSybaseExecutionFactory {
-
+
+ public static final String TWELVE_5_3 = "12.5.3"; //$NON-NLS-1$
public static final String TWELVE_5 = "12.5"; //$NON-NLS-1$
public static final String FIFTEEN_0_2 = "15.0.2"; //$NON-NLS-1$
public static final String FIFTEEN_5 = "15.5"; //$NON-NLS-1$
@@ -370,7 +371,7 @@
@Override
public boolean supportsRowLimit() {
- return getDatabaseVersion().compareTo(FIFTEEN_0_2) >= 0;
+ return (getDatabaseVersion().startsWith("12") && getDatabaseVersion().compareTo(TWELVE_5_3) >= 0) || getDatabaseVersion().compareTo(FIFTEEN_0_2) >=0; //$NON-NLS-1$
}
@TranslatorProperty(display="JTDS Driver", description="True if the driver is the JTDS driver",advanced=true)
Modified: trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sybase/TestSybaseSQLConversionVisitor.java
===================================================================
--- trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sybase/TestSybaseSQLConversionVisitor.java 2012-08-21 16:45:15 UTC (rev 4353)
+++ trunk/connectors/translator-jdbc/src/test/java/org/teiid/translator/jdbc/sybase/TestSybaseSQLConversionVisitor.java 2012-08-21 17:29:30 UTC (rev 4354)
@@ -35,6 +35,7 @@
/**
*/
+@SuppressWarnings("nls")
public class TestSybaseSQLConversionVisitor {
private static SybaseExecutionFactory trans = new SybaseExecutionFactory();
@@ -256,4 +257,16 @@
"SELECT {fn timestampadd(sql_tsi_second, 1, SmallA.TimestampValue)}, dateadd(millisecond, 1000/1000000, SmallA.TimestampValue), datediff(millisecond, SmallA.TimestampValue,SmallA.TimestampValue)*1000000 FROM SmallA"); //$NON-NLS-1$
}
+ @Test public void testLimitSupport() {
+ SybaseExecutionFactory sybaseExecutionFactory = new SybaseExecutionFactory();
+ sybaseExecutionFactory.setDatabaseVersion("12.5.4");
+ assertTrue(sybaseExecutionFactory.supportsRowLimit());
+ sybaseExecutionFactory.setDatabaseVersion("12.5.2");
+ assertFalse(sybaseExecutionFactory.supportsRowLimit());
+ sybaseExecutionFactory.setDatabaseVersion("15");
+ assertFalse(sybaseExecutionFactory.supportsRowLimit());
+ sybaseExecutionFactory.setDatabaseVersion("15.1");
+ assertTrue(sybaseExecutionFactory.supportsRowLimit());
+ }
+
}
13 years, 4 months
teiid SVN: r4353 - in branches/7.4.x: connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sybase and 1 other directory.
by teiid-commits@lists.jboss.org
Author: jolee
Date: 2012-08-21 12:45:15 -0400 (Tue, 21 Aug 2012)
New Revision: 4353
Modified:
branches/7.4.x/build/kits/jboss-container/teiid-releasenotes.html
branches/7.4.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sybase/SybaseExecutionFactory.java
Log:
TEIID-2157 Need ability to push down LIMIT clause to Sybase
Modified: branches/7.4.x/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- branches/7.4.x/build/kits/jboss-container/teiid-releasenotes.html 2012-08-21 16:33:11 UTC (rev 4352)
+++ branches/7.4.x/build/kits/jboss-container/teiid-releasenotes.html 2012-08-21 16:45:15 UTC (rev 4353)
@@ -265,6 +265,7 @@
<li>[<a href='https://issues.jboss.org/browse/TEIID-2120'>TEIID-2120</a>] - fix for batchiterator early termination</li>
<li>[<a href='https://issues.jboss.org/browse/TEIID-2146'>TEIID-2146</a>] - Dependent join independent dup removal issue</li>
<li>[<a href='https://issues.jboss.org/browse/TEIID-1956'>TEIID-1956</a>] - (updated) an additional fix for having the same element repeated in equi-join criteria</li>
+<li>[<a href='https://issues.jboss.org/browse/TEIID-2157'>TEIID-2157</a>] - Need ability to push down LIMIT clause to Sybase</li>
</ul>
Modified: branches/7.4.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sybase/SybaseExecutionFactory.java
===================================================================
--- branches/7.4.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sybase/SybaseExecutionFactory.java 2012-08-21 16:33:11 UTC (rev 4352)
+++ branches/7.4.x/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/sybase/SybaseExecutionFactory.java 2012-08-21 16:45:15 UTC (rev 4353)
@@ -1,394 +1,400 @@
-/*
- * 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.
- */
-
/*
+ * 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.translator.jdbc.sybase;
-import java.sql.CallableStatement;
-import java.sql.Date;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.teiid.language.Command;
-import org.teiid.language.Function;
-import org.teiid.language.LanguageObject;
-import org.teiid.language.Limit;
-import org.teiid.language.OrderBy;
-import org.teiid.language.SetQuery;
-import org.teiid.translator.ExecutionContext;
-import org.teiid.translator.SourceSystemFunctions;
-import org.teiid.translator.Translator;
-import org.teiid.translator.TranslatorException;
-import org.teiid.translator.TypeFacility;
-import org.teiid.translator.jdbc.AliasModifier;
-import org.teiid.translator.jdbc.ConvertModifier;
-import org.teiid.translator.jdbc.EscapeSyntaxModifier;
-import org.teiid.translator.jdbc.FunctionModifier;
-import org.teiid.translator.jdbc.JDBCExecutionFactory;
-import org.teiid.translator.jdbc.ModFunctionModifier;
-import org.teiid.translator.jdbc.db2.DB2ExecutionFactory;
-import org.teiid.translator.jdbc.oracle.ConcatFunctionModifier;
-
+import java.sql.CallableStatement;
+import java.sql.Date;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import org.teiid.language.Command;
+import org.teiid.language.Function;
+import org.teiid.language.LanguageObject;
+import org.teiid.language.Limit;
+import org.teiid.language.OrderBy;
+import org.teiid.language.SetQuery;
+import org.teiid.translator.ExecutionContext;
+import org.teiid.translator.SourceSystemFunctions;
+import org.teiid.translator.Translator;
+import org.teiid.translator.TranslatorException;
+import org.teiid.translator.TypeFacility;
+import org.teiid.translator.jdbc.AliasModifier;
+import org.teiid.translator.jdbc.ConvertModifier;
+import org.teiid.translator.jdbc.EscapeSyntaxModifier;
+import org.teiid.translator.jdbc.FunctionModifier;
+import org.teiid.translator.jdbc.JDBCExecutionFactory;
+import org.teiid.translator.jdbc.ModFunctionModifier;
+import org.teiid.translator.jdbc.db2.DB2ExecutionFactory;
+import org.teiid.translator.jdbc.oracle.ConcatFunctionModifier;
+
+
@Translator(name="sybase", description="A translator for Sybase Database")
-public class SybaseExecutionFactory extends JDBCExecutionFactory {
-
- public static final String TWELVE_5 = "12.5"; //$NON-NLS-1$
- public static final String FIFTEEN_0_2 = "15.0.2"; //$NON-NLS-1$
- public static final String FIFTEEN_5 = "15.5"; //$NON-NLS-1$
-
- public SybaseExecutionFactory() {
- setDatabaseVersion(TWELVE_5);
- setSupportsFullOuterJoins(false);
- setMaxInCriteriaSize(250);
- setMaxDependentInPredicates(10);
+public class SybaseExecutionFactory extends JDBCExecutionFactory {
+
+ public static final String TWELVE_5 = "12.5"; //$NON-NLS-1$
+ public static final String TWELVE_5_3 = "12.5.3"; //$NON-NLS-1$
+ public static final String FIFTEEN_0_2 = "15.0.2"; //$NON-NLS-1$
+ public static final String FIFTEEN_5 = "15.5"; //$NON-NLS-1$
+
+ public SybaseExecutionFactory() {
+ setDatabaseVersion(TWELVE_5);
+ setSupportsFullOuterJoins(false);
+ setMaxInCriteriaSize(250);
+ setMaxDependentInPredicates(10);
}
public void start() throws TranslatorException {
- super.start();
+ super.start();
- registerFunctionModifier(SourceSystemFunctions.MOD, new ModFunctionModifier("%", getLanguageFactory())); //$NON-NLS-1$
+ registerFunctionModifier(SourceSystemFunctions.MOD, new ModFunctionModifier("%", getLanguageFactory())); //$NON-NLS-1$
if (nullPlusNonNullIsNull()) {
- registerFunctionModifier(SourceSystemFunctions.CONCAT, new AliasModifier("+")); //$NON-NLS-1$
- } else {
- registerFunctionModifier(SourceSystemFunctions.CONCAT, new ConcatFunctionModifier(getLanguageFactory()) {
- @Override
- public List<?> translate(Function function) {
- function.setName("+"); //$NON-NLS-1$
- return super.translate(function);
- }
- });
+ registerFunctionModifier(SourceSystemFunctions.CONCAT, new AliasModifier("+")); //$NON-NLS-1$
+ } else {
+ registerFunctionModifier(SourceSystemFunctions.CONCAT, new ConcatFunctionModifier(getLanguageFactory()) {
+ @Override
+ public List<?> translate(Function function) {
+ function.setName("+"); //$NON-NLS-1$
+ return super.translate(function);
+ }
+ });
}
registerFunctionModifier(SourceSystemFunctions.LCASE, new AliasModifier("lower")); //$NON-NLS-1$
registerFunctionModifier(SourceSystemFunctions.IFNULL, new AliasModifier("isnull")); //$NON-NLS-1$
- registerFunctionModifier(SourceSystemFunctions.UCASE, new AliasModifier("upper")); //$NON-NLS-1$
- registerFunctionModifier(SourceSystemFunctions.REPEAT, new AliasModifier("replicate")); //$NON-NLS-1$
- registerFunctionModifier(SourceSystemFunctions.SUBSTRING, new SubstringFunctionModifier(getLanguageFactory()));
- registerFunctionModifier(SourceSystemFunctions.DAYNAME, new EscapeSyntaxModifier());
- registerFunctionModifier(SourceSystemFunctions.MONTHNAME, new EscapeSyntaxModifier());
- registerFunctionModifier(SourceSystemFunctions.DAYOFWEEK, new EscapeSyntaxModifier());
- registerFunctionModifier(SourceSystemFunctions.DAYOFYEAR, new EscapeSyntaxModifier());
- registerFunctionModifier(SourceSystemFunctions.DAYOFMONTH, new EscapeSyntaxModifier());
- registerFunctionModifier(SourceSystemFunctions.HOUR, new EscapeSyntaxModifier());
- registerFunctionModifier(SourceSystemFunctions.MINUTE, new EscapeSyntaxModifier());
- registerFunctionModifier(SourceSystemFunctions.QUARTER, new EscapeSyntaxModifier());
- registerFunctionModifier(SourceSystemFunctions.SECOND, new EscapeSyntaxModifier());
- registerFunctionModifier(SourceSystemFunctions.WEEK, new EscapeSyntaxModifier());
- registerFunctionModifier(SourceSystemFunctions.TIMESTAMPADD, new EscapeSyntaxModifier());
- registerFunctionModifier(SourceSystemFunctions.TIMESTAMPDIFF, new EscapeSyntaxModifier());
- registerFunctionModifier(SourceSystemFunctions.LENGTH, new EscapeSyntaxModifier());
- registerFunctionModifier(SourceSystemFunctions.ATAN2, new EscapeSyntaxModifier());
-
- //add in type conversion
- ConvertModifier convertModifier = new ConvertModifier();
- convertModifier.setBooleanNullable(booleanNullable());
- //boolean isn't treated as bit, since it doesn't support null
- //byte is treated as smallint, since tinyint is unsigned
- convertModifier.addTypeMapping("smallint", FunctionModifier.BYTE, FunctionModifier.SHORT); //$NON-NLS-1$
- convertModifier.addTypeMapping("int", FunctionModifier.INTEGER); //$NON-NLS-1$
- convertModifier.addTypeMapping("numeric(19,0)", FunctionModifier.LONG); //$NON-NLS-1$
- convertModifier.addTypeMapping("real", FunctionModifier.FLOAT); //$NON-NLS-1$
- convertModifier.addTypeMapping("double precision", FunctionModifier.DOUBLE); //$NON-NLS-1$
- convertModifier.addTypeMapping("numeric(38, 0)", FunctionModifier.BIGINTEGER); //$NON-NLS-1$
- convertModifier.addTypeMapping("numeric(38, 19)", FunctionModifier.BIGDECIMAL); //$NON-NLS-1$
- convertModifier.addTypeMapping("char(1)", FunctionModifier.CHAR); //$NON-NLS-1$
- convertModifier.addTypeMapping("varchar(40)", FunctionModifier.STRING); //$NON-NLS-1$
- convertModifier.addTypeMapping("datetime", FunctionModifier.DATE, FunctionModifier.TIME, FunctionModifier.TIMESTAMP); //$NON-NLS-1$
- convertModifier.addConvert(FunctionModifier.TIMESTAMP, FunctionModifier.TIME, new FunctionModifier() {
- @Override
- public List<?> translate(Function function) {
- List<Object> result = new ArrayList<Object>();
- result.add("cast("); //$NON-NLS-1$
- boolean needsEnd = false;
- if (!nullPlusNonNullIsNull() && !ConcatFunctionModifier.isNotNull(function.getParameters().get(0))) {
- result.add("CASE WHEN "); //$NON-NLS-1$
- result.add(function.getParameters().get(0));
- result.add(" IS NOT NULL THEN "); //$NON-NLS-1$
- needsEnd = true;
- }
- result.add("'1970-01-01 ' + "); //$NON-NLS-1$
- result.addAll(convertTimeToString(function));
- if (needsEnd) {
- result.add(" END"); //$NON-NLS-1$
- }
- result.add(" AS datetime)"); //$NON-NLS-1$
- return result;
- }
- });
- convertModifier.addConvert(FunctionModifier.TIMESTAMP, FunctionModifier.DATE, new FunctionModifier() {
- @Override
- public List<?> translate(Function function) {
- List<Object> result = new ArrayList<Object>();
- result.add("cast("); //$NON-NLS-1$
- result.addAll(convertDateToString(function));
- result.add(" AS datetime)"); //$NON-NLS-1$
- return result;
- }
- });
- convertModifier.addConvert(FunctionModifier.TIME, FunctionModifier.STRING, new FunctionModifier() {
- @Override
- public List<?> translate(Function function) {
- return convertTimeToString(function);
- }
- });
- convertModifier.addConvert(FunctionModifier.DATE, FunctionModifier.STRING, new FunctionModifier() {
- @Override
- public List<?> translate(Function function) {
- return convertDateToString(function);
- }
- });
- convertModifier.addConvert(FunctionModifier.TIMESTAMP, FunctionModifier.STRING, new FunctionModifier() {
- @Override
- public List<?> translate(Function function) {
- return convertTimestampToString(function);
- }
- });
- convertModifier.addNumericBooleanConversions();
+ registerFunctionModifier(SourceSystemFunctions.UCASE, new AliasModifier("upper")); //$NON-NLS-1$
+ registerFunctionModifier(SourceSystemFunctions.REPEAT, new AliasModifier("replicate")); //$NON-NLS-1$
+ registerFunctionModifier(SourceSystemFunctions.SUBSTRING, new SubstringFunctionModifier(getLanguageFactory()));
+ registerFunctionModifier(SourceSystemFunctions.DAYNAME, new EscapeSyntaxModifier());
+ registerFunctionModifier(SourceSystemFunctions.MONTHNAME, new EscapeSyntaxModifier());
+ registerFunctionModifier(SourceSystemFunctions.DAYOFWEEK, new EscapeSyntaxModifier());
+ registerFunctionModifier(SourceSystemFunctions.DAYOFYEAR, new EscapeSyntaxModifier());
+ registerFunctionModifier(SourceSystemFunctions.DAYOFMONTH, new EscapeSyntaxModifier());
+ registerFunctionModifier(SourceSystemFunctions.HOUR, new EscapeSyntaxModifier());
+ registerFunctionModifier(SourceSystemFunctions.MINUTE, new EscapeSyntaxModifier());
+ registerFunctionModifier(SourceSystemFunctions.QUARTER, new EscapeSyntaxModifier());
+ registerFunctionModifier(SourceSystemFunctions.SECOND, new EscapeSyntaxModifier());
+ registerFunctionModifier(SourceSystemFunctions.WEEK, new EscapeSyntaxModifier());
+ registerFunctionModifier(SourceSystemFunctions.TIMESTAMPADD, new EscapeSyntaxModifier());
+ registerFunctionModifier(SourceSystemFunctions.TIMESTAMPDIFF, new EscapeSyntaxModifier());
+ registerFunctionModifier(SourceSystemFunctions.LENGTH, new EscapeSyntaxModifier());
+ registerFunctionModifier(SourceSystemFunctions.ATAN2, new EscapeSyntaxModifier());
+
+ //add in type conversion
+ ConvertModifier convertModifier = new ConvertModifier();
+ convertModifier.setBooleanNullable(booleanNullable());
+ //boolean isn't treated as bit, since it doesn't support null
+ //byte is treated as smallint, since tinyint is unsigned
+ convertModifier.addTypeMapping("smallint", FunctionModifier.BYTE, FunctionModifier.SHORT); //$NON-NLS-1$
+ convertModifier.addTypeMapping("int", FunctionModifier.INTEGER); //$NON-NLS-1$
+ convertModifier.addTypeMapping("numeric(19,0)", FunctionModifier.LONG); //$NON-NLS-1$
+ convertModifier.addTypeMapping("real", FunctionModifier.FLOAT); //$NON-NLS-1$
+ convertModifier.addTypeMapping("double precision", FunctionModifier.DOUBLE); //$NON-NLS-1$
+ convertModifier.addTypeMapping("numeric(38, 0)", FunctionModifier.BIGINTEGER); //$NON-NLS-1$
+ convertModifier.addTypeMapping("numeric(38, 19)", FunctionModifier.BIGDECIMAL); //$NON-NLS-1$
+ convertModifier.addTypeMapping("char(1)", FunctionModifier.CHAR); //$NON-NLS-1$
+ convertModifier.addTypeMapping("varchar(40)", FunctionModifier.STRING); //$NON-NLS-1$
+ convertModifier.addTypeMapping("datetime", FunctionModifier.DATE, FunctionModifier.TIME, FunctionModifier.TIMESTAMP); //$NON-NLS-1$
+ convertModifier.addConvert(FunctionModifier.TIMESTAMP, FunctionModifier.TIME, new FunctionModifier() {
+ @Override
+ public List<?> translate(Function function) {
+ List<Object> result = new ArrayList<Object>();
+ result.add("cast("); //$NON-NLS-1$
+ boolean needsEnd = false;
+ if (!nullPlusNonNullIsNull() && !ConcatFunctionModifier.isNotNull(function.getParameters().get(0))) {
+ result.add("CASE WHEN "); //$NON-NLS-1$
+ result.add(function.getParameters().get(0));
+ result.add(" IS NOT NULL THEN "); //$NON-NLS-1$
+ needsEnd = true;
+ }
+ result.add("'1970-01-01 ' + "); //$NON-NLS-1$
+ result.addAll(convertTimeToString(function));
+ if (needsEnd) {
+ result.add(" END"); //$NON-NLS-1$
+ }
+ result.add(" AS datetime)"); //$NON-NLS-1$
+ return result;
+ }
+ });
+ convertModifier.addConvert(FunctionModifier.TIMESTAMP, FunctionModifier.DATE, new FunctionModifier() {
+ @Override
+ public List<?> translate(Function function) {
+ List<Object> result = new ArrayList<Object>();
+ result.add("cast("); //$NON-NLS-1$
+ result.addAll(convertDateToString(function));
+ result.add(" AS datetime)"); //$NON-NLS-1$
+ return result;
+ }
+ });
+ convertModifier.addConvert(FunctionModifier.TIME, FunctionModifier.STRING, new FunctionModifier() {
+ @Override
+ public List<?> translate(Function function) {
+ return convertTimeToString(function);
+ }
+ });
+ convertModifier.addConvert(FunctionModifier.DATE, FunctionModifier.STRING, new FunctionModifier() {
+ @Override
+ public List<?> translate(Function function) {
+ return convertDateToString(function);
+ }
+ });
+ convertModifier.addConvert(FunctionModifier.TIMESTAMP, FunctionModifier.STRING, new FunctionModifier() {
+ @Override
+ public List<?> translate(Function function) {
+ return convertTimestampToString(function);
+ }
+ });
+ convertModifier.addNumericBooleanConversions();
registerFunctionModifier(SourceSystemFunctions.CONVERT, convertModifier);
- }
-
- private List<Object> convertTimeToString(Function function) {
- return Arrays.asList("convert(varchar, ", function.getParameters().get(0), ", 8)"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- protected List<Object> convertDateToString(Function function) {
- return Arrays.asList("stuff(stuff(convert(varchar, ", function.getParameters().get(0), ", 102), 5, 1, '-'), 8, 1, '-')"); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- //TODO: this looses the milliseconds
- protected List<?> convertTimestampToString(Function function) {
- LinkedList<Object> result = new LinkedList<Object>();
- result.addAll(convertDateToString(function));
- result.add('+');
- result.addAll(convertTimeToString(function));
- return result;
- }
-
- @Override
- public boolean useAsInGroupAlias() {
- return false;
- }
-
- @Override
- public boolean hasTimeType() {
- return false;
- }
-
- @Override
- public int getTimestampNanoPrecision() {
- return 3;
- }
-
- /**
- * SetQueries don't have a concept of TOP, an inline view is needed.
- */
- @Override
- public List<?> translateCommand(Command command, ExecutionContext context) {
- if (!(command instanceof SetQuery)) {
- return null;
- }
- SetQuery queryCommand = (SetQuery)command;
- if (queryCommand.getLimit() == null) {
- return null;
- }
- Limit limit = queryCommand.getLimit();
- OrderBy orderBy = queryCommand.getOrderBy();
- queryCommand.setLimit(null);
- queryCommand.setOrderBy(null);
- List<Object> parts = new ArrayList<Object>(6);
- parts.add("SELECT "); //$NON-NLS-1$
- parts.addAll(translateLimit(limit, context));
- parts.add(" * FROM ("); //$NON-NLS-1$
- parts.add(queryCommand);
- parts.add(") AS X"); //$NON-NLS-1$
- if (orderBy != null) {
- parts.add(" "); //$NON-NLS-1$
- parts.add(orderBy);
- }
- return parts;
- }
-
- @Override
- public List<?> translate(LanguageObject obj, ExecutionContext context) {
- if (!supportsCrossJoin()) {
- DB2ExecutionFactory.convertCrossJoinToInner(obj, getLanguageFactory());
- }
- return super.translate(obj, context);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public List<?> translateLimit(Limit limit, ExecutionContext context) {
- return Arrays.asList("TOP ", limit.getRowLimit()); //$NON-NLS-1$
- }
-
- @Override
- public boolean useSelectLimit() {
- return true;
- }
-
- @Override
- public List<String> getSupportedFunctions() {
- List<String> supportedFunctions = new ArrayList<String>();
- supportedFunctions.addAll(super.getSupportedFunctions());
- supportedFunctions.add("ABS"); //$NON-NLS-1$
- supportedFunctions.add("ACOS"); //$NON-NLS-1$
- supportedFunctions.add("ASIN"); //$NON-NLS-1$
- supportedFunctions.add("ATAN"); //$NON-NLS-1$
- supportedFunctions.add("ATAN2"); //$NON-NLS-1$
- supportedFunctions.add("COS"); //$NON-NLS-1$
- supportedFunctions.add("COT"); //$NON-NLS-1$
- supportedFunctions.add("DEGREES"); //$NON-NLS-1$
- supportedFunctions.add("EXP"); //$NON-NLS-1$
- supportedFunctions.add("FLOOR"); //$NON-NLS-1$
- supportedFunctions.add("LOG"); //$NON-NLS-1$
- supportedFunctions.add("LOG10"); //$NON-NLS-1$
- supportedFunctions.add("MOD"); //$NON-NLS-1$
- supportedFunctions.add("PI"); //$NON-NLS-1$
- supportedFunctions.add("POWER"); //$NON-NLS-1$
- supportedFunctions.add("RADIANS"); //$NON-NLS-1$
- supportedFunctions.add("SIGN"); //$NON-NLS-1$
- supportedFunctions.add("SIN"); //$NON-NLS-1$
- supportedFunctions.add("SQRT"); //$NON-NLS-1$
- supportedFunctions.add("TAN"); //$NON-NLS-1$
- supportedFunctions.add("ASCII"); //$NON-NLS-1$
- supportedFunctions.add("CHAR"); //$NON-NLS-1$
- supportedFunctions.add("CHR"); //$NON-NLS-1$
- supportedFunctions.add("CONCAT"); //$NON-NLS-1$
- supportedFunctions.add("||"); //$NON-NLS-1$
- supportedFunctions.add("LCASE"); //$NON-NLS-1$
- supportedFunctions.add("LEFT"); //$NON-NLS-1$
- supportedFunctions.add("LENGTH"); //$NON-NLS-1$
- supportedFunctions.add("LOWER"); //$NON-NLS-1$
- supportedFunctions.add("LTRIM"); //$NON-NLS-1$
- supportedFunctions.add("REPEAT"); //$NON-NLS-1$
- //supportedFunctions.add("RAND"); //$NON-NLS-1$
- supportedFunctions.add("RIGHT"); //$NON-NLS-1$
- supportedFunctions.add("RTRIM"); //$NON-NLS-1$
- supportedFunctions.add("SPACE"); //$NON-NLS-1$
- supportedFunctions.add("SUBSTRING"); //$NON-NLS-1$
- supportedFunctions.add("UCASE"); //$NON-NLS-1$
- supportedFunctions.add("UPPER"); //$NON-NLS-1$
- //supportedFunctons.add("CURDATE"); //$NON-NLS-1$
- //supportedFunctons.add("CURTIME"); //$NON-NLS-1$
- supportedFunctions.add("DAYNAME"); //$NON-NLS-1$
- supportedFunctions.add("DAYOFMONTH"); //$NON-NLS-1$
- supportedFunctions.add("DAYOFWEEK"); //$NON-NLS-1$
- supportedFunctions.add("DAYOFYEAR"); //$NON-NLS-1$
- supportedFunctions.add("HOUR"); //$NON-NLS-1$
- supportedFunctions.add("MINUTE"); //$NON-NLS-1$
- supportedFunctions.add("MONTH"); //$NON-NLS-1$
- supportedFunctions.add("MONTHNAME"); //$NON-NLS-1$
- //supportedFunctions.add("NOW"); //$NON-NLS-1$
- supportedFunctions.add("QUARTER"); //$NON-NLS-1$
- supportedFunctions.add("SECOND"); //$NON-NLS-1$
- supportedFunctions.add("TIMESTAMPADD"); //$NON-NLS-1$
- supportedFunctions.add("TIMESTAMPDIFF"); //$NON-NLS-1$
- supportedFunctions.add("WEEK"); //$NON-NLS-1$
- supportedFunctions.add("YEAR"); //$NON-NLS-1$
- supportedFunctions.add("CAST"); //$NON-NLS-1$
- supportedFunctions.add("CONVERT"); //$NON-NLS-1$
- supportedFunctions.add("IFNULL"); //$NON-NLS-1$
- supportedFunctions.add("NVL"); //$NON-NLS-1$
- //supportedFunctions.add("FORMATTIMESTAMP"); //$NON-NLS-1$
-
- return supportedFunctions;
- }
-
- @Override
- public boolean supportsInlineViews() {
- return true;
- }
-
- @Override
- public boolean supportsFunctionsInGroupBy() {
- return true;
- }
-
- @Override
- public int getMaxFromGroups() {
- return 50;
- }
-
- @Override
- public boolean supportsAggregatesEnhancedNumeric() {
- return getDatabaseVersion().compareTo(FIFTEEN_0_2) >= 0;
- }
-
- public boolean nullPlusNonNullIsNull() {
- return false;
- }
-
- public boolean booleanNullable() {
- return false;
- }
-
- @Override
- public Object retrieveValue(ResultSet results, int columnIndex,
- Class<?> expectedType) throws SQLException {
- if (expectedType == TypeFacility.RUNTIME_TYPES.BYTE) {
- expectedType = TypeFacility.RUNTIME_TYPES.SHORT;
- }
- return super.retrieveValue(results, columnIndex, expectedType);
- }
-
- @Override
- public Object retrieveValue(CallableStatement results, int parameterIndex,
- Class<?> expectedType) throws SQLException {
- if (expectedType == TypeFacility.RUNTIME_TYPES.BYTE) {
- expectedType = TypeFacility.RUNTIME_TYPES.SHORT;
- }
- return super.retrieveValue(results, parameterIndex, expectedType);
- }
-
- @Override
- public void bindValue(PreparedStatement stmt, Object param,
- Class<?> paramType, int i) throws SQLException {
- if (paramType == TypeFacility.RUNTIME_TYPES.BYTE) {
- paramType = TypeFacility.RUNTIME_TYPES.SHORT;
- param = ((Byte)param).shortValue();
- }
- super.bindValue(stmt, param, paramType, i);
- }
-
- @Override
- public String translateLiteralTimestamp(Timestamp timestampValue) {
- return "CAST('" + formatDateValue(timestampValue) +"' AS DATETIME)"; //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- @Override
- public String translateLiteralDate(Date dateValue) {
- return "CAST('" + formatDateValue(dateValue) +"' AS DATE)"; //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- protected boolean supportsCrossJoin() {
- return false;
- }
-
+ }
+
+ private List<Object> convertTimeToString(Function function) {
+ return Arrays.asList("convert(varchar, ", function.getParameters().get(0), ", 8)"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ protected List<Object> convertDateToString(Function function) {
+ return Arrays.asList("stuff(stuff(convert(varchar, ", function.getParameters().get(0), ", 102), 5, 1, '-'), 8, 1, '-')"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ //TODO: this looses the milliseconds
+ protected List<?> convertTimestampToString(Function function) {
+ LinkedList<Object> result = new LinkedList<Object>();
+ result.addAll(convertDateToString(function));
+ result.add('+');
+ result.addAll(convertTimeToString(function));
+ return result;
+ }
+
+ @Override
+ public boolean useAsInGroupAlias() {
+ return false;
+ }
+
+ @Override
+ public boolean hasTimeType() {
+ return false;
+ }
+
+ @Override
+ public int getTimestampNanoPrecision() {
+ return 3;
+ }
+
+ /**
+ * SetQueries don't have a concept of TOP, an inline view is needed.
+ */
+ @Override
+ public List<?> translateCommand(Command command, ExecutionContext context) {
+ if (!(command instanceof SetQuery)) {
+ return null;
+ }
+ SetQuery queryCommand = (SetQuery)command;
+ if (queryCommand.getLimit() == null) {
+ return null;
+ }
+ Limit limit = queryCommand.getLimit();
+ OrderBy orderBy = queryCommand.getOrderBy();
+ queryCommand.setLimit(null);
+ queryCommand.setOrderBy(null);
+ List<Object> parts = new ArrayList<Object>(6);
+ parts.add("SELECT "); //$NON-NLS-1$
+ parts.addAll(translateLimit(limit, context));
+ parts.add(" * FROM ("); //$NON-NLS-1$
+ parts.add(queryCommand);
+ parts.add(") AS X"); //$NON-NLS-1$
+ if (orderBy != null) {
+ parts.add(" "); //$NON-NLS-1$
+ parts.add(orderBy);
+ }
+ return parts;
+ }
+
+ @Override
+ public List<?> translate(LanguageObject obj, ExecutionContext context) {
+ if (!supportsCrossJoin()) {
+ DB2ExecutionFactory.convertCrossJoinToInner(obj, getLanguageFactory());
+ }
+ return super.translate(obj, context);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<?> translateLimit(Limit limit, ExecutionContext context) {
+ return Arrays.asList("TOP ", limit.getRowLimit()); //$NON-NLS-1$
+ }
+
+ @Override
+ public boolean useSelectLimit() {
+ return true;
+ }
+
+ @Override
+ public List<String> getSupportedFunctions() {
+ List<String> supportedFunctions = new ArrayList<String>();
+ supportedFunctions.addAll(super.getSupportedFunctions());
+ supportedFunctions.add("ABS"); //$NON-NLS-1$
+ supportedFunctions.add("ACOS"); //$NON-NLS-1$
+ supportedFunctions.add("ASIN"); //$NON-NLS-1$
+ supportedFunctions.add("ATAN"); //$NON-NLS-1$
+ supportedFunctions.add("ATAN2"); //$NON-NLS-1$
+ supportedFunctions.add("COS"); //$NON-NLS-1$
+ supportedFunctions.add("COT"); //$NON-NLS-1$
+ supportedFunctions.add("DEGREES"); //$NON-NLS-1$
+ supportedFunctions.add("EXP"); //$NON-NLS-1$
+ supportedFunctions.add("FLOOR"); //$NON-NLS-1$
+ supportedFunctions.add("LOG"); //$NON-NLS-1$
+ supportedFunctions.add("LOG10"); //$NON-NLS-1$
+ supportedFunctions.add("MOD"); //$NON-NLS-1$
+ supportedFunctions.add("PI"); //$NON-NLS-1$
+ supportedFunctions.add("POWER"); //$NON-NLS-1$
+ supportedFunctions.add("RADIANS"); //$NON-NLS-1$
+ supportedFunctions.add("SIGN"); //$NON-NLS-1$
+ supportedFunctions.add("SIN"); //$NON-NLS-1$
+ supportedFunctions.add("SQRT"); //$NON-NLS-1$
+ supportedFunctions.add("TAN"); //$NON-NLS-1$
+ supportedFunctions.add("ASCII"); //$NON-NLS-1$
+ supportedFunctions.add("CHAR"); //$NON-NLS-1$
+ supportedFunctions.add("CHR"); //$NON-NLS-1$
+ supportedFunctions.add("CONCAT"); //$NON-NLS-1$
+ supportedFunctions.add("||"); //$NON-NLS-1$
+ supportedFunctions.add("LCASE"); //$NON-NLS-1$
+ supportedFunctions.add("LEFT"); //$NON-NLS-1$
+ supportedFunctions.add("LENGTH"); //$NON-NLS-1$
+ supportedFunctions.add("LOWER"); //$NON-NLS-1$
+ supportedFunctions.add("LTRIM"); //$NON-NLS-1$
+ supportedFunctions.add("REPEAT"); //$NON-NLS-1$
+ //supportedFunctions.add("RAND"); //$NON-NLS-1$
+ supportedFunctions.add("RIGHT"); //$NON-NLS-1$
+ supportedFunctions.add("RTRIM"); //$NON-NLS-1$
+ supportedFunctions.add("SPACE"); //$NON-NLS-1$
+ supportedFunctions.add("SUBSTRING"); //$NON-NLS-1$
+ supportedFunctions.add("UCASE"); //$NON-NLS-1$
+ supportedFunctions.add("UPPER"); //$NON-NLS-1$
+ //supportedFunctons.add("CURDATE"); //$NON-NLS-1$
+ //supportedFunctons.add("CURTIME"); //$NON-NLS-1$
+ supportedFunctions.add("DAYNAME"); //$NON-NLS-1$
+ supportedFunctions.add("DAYOFMONTH"); //$NON-NLS-1$
+ supportedFunctions.add("DAYOFWEEK"); //$NON-NLS-1$
+ supportedFunctions.add("DAYOFYEAR"); //$NON-NLS-1$
+ supportedFunctions.add("HOUR"); //$NON-NLS-1$
+ supportedFunctions.add("MINUTE"); //$NON-NLS-1$
+ supportedFunctions.add("MONTH"); //$NON-NLS-1$
+ supportedFunctions.add("MONTHNAME"); //$NON-NLS-1$
+ //supportedFunctions.add("NOW"); //$NON-NLS-1$
+ supportedFunctions.add("QUARTER"); //$NON-NLS-1$
+ supportedFunctions.add("SECOND"); //$NON-NLS-1$
+ supportedFunctions.add("TIMESTAMPADD"); //$NON-NLS-1$
+ supportedFunctions.add("TIMESTAMPDIFF"); //$NON-NLS-1$
+ supportedFunctions.add("WEEK"); //$NON-NLS-1$
+ supportedFunctions.add("YEAR"); //$NON-NLS-1$
+ supportedFunctions.add("CAST"); //$NON-NLS-1$
+ supportedFunctions.add("CONVERT"); //$NON-NLS-1$
+ supportedFunctions.add("IFNULL"); //$NON-NLS-1$
+ supportedFunctions.add("NVL"); //$NON-NLS-1$
+ //supportedFunctions.add("FORMATTIMESTAMP"); //$NON-NLS-1$
+
+ return supportedFunctions;
+ }
+
+ @Override
+ public boolean supportsInlineViews() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsFunctionsInGroupBy() {
+ return true;
+ }
+
+ @Override
+ public int getMaxFromGroups() {
+ return 50;
+ }
+
+ @Override
+ public boolean supportsAggregatesEnhancedNumeric() {
+ return getDatabaseVersion().compareTo(FIFTEEN_0_2) >= 0;
+ }
+
+ public boolean nullPlusNonNullIsNull() {
+ return false;
+ }
+
+ public boolean booleanNullable() {
+ return false;
+ }
+
+ @Override
+ public Object retrieveValue(ResultSet results, int columnIndex,
+ Class<?> expectedType) throws SQLException {
+ if (expectedType == TypeFacility.RUNTIME_TYPES.BYTE) {
+ expectedType = TypeFacility.RUNTIME_TYPES.SHORT;
+ }
+ return super.retrieveValue(results, columnIndex, expectedType);
+ }
+
+ @Override
+ public Object retrieveValue(CallableStatement results, int parameterIndex,
+ Class<?> expectedType) throws SQLException {
+ if (expectedType == TypeFacility.RUNTIME_TYPES.BYTE) {
+ expectedType = TypeFacility.RUNTIME_TYPES.SHORT;
+ }
+ return super.retrieveValue(results, parameterIndex, expectedType);
+ }
+
+ @Override
+ public void bindValue(PreparedStatement stmt, Object param,
+ Class<?> paramType, int i) throws SQLException {
+ if (paramType == TypeFacility.RUNTIME_TYPES.BYTE) {
+ paramType = TypeFacility.RUNTIME_TYPES.SHORT;
+ param = ((Byte)param).shortValue();
+ }
+ super.bindValue(stmt, param, paramType, i);
+ }
+
+ @Override
+ public String translateLiteralTimestamp(Timestamp timestampValue) {
+ return "CAST('" + formatDateValue(timestampValue) +"' AS DATETIME)"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ @Override
+ public String translateLiteralDate(Date dateValue) {
+ return "CAST('" + formatDateValue(dateValue) +"' AS DATE)"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ protected boolean supportsCrossJoin() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsRowLimit() {
+ return getDatabaseVersion().compareTo(TWELVE_5_3) >= 0;
+ }
+
}
13 years, 4 months
teiid SVN: r4352 - in trunk: connectors/translator-file/src/main/java/org/teiid/translator/file and 1 other directory.
by teiid-commits@lists.jboss.org
Author: shawkins
Date: 2012-08-21 12:33:11 -0400 (Tue, 21 Aug 2012)
New Revision: 4352
Modified:
trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html
trunk/connectors/translator-file/src/main/java/org/teiid/translator/file/FileExecutionFactory.java
Log:
TEIID-2156 changing the default value
Modified: trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html
===================================================================
--- trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html 2012-08-21 10:50:28 UTC (rev 4351)
+++ trunk/build/kits/jboss-as7/docs/teiid/teiid-releasenotes.html 2012-08-21 16:33:11 UTC (rev 4352)
@@ -25,7 +25,6 @@
<LI><A HREF="#About">About JBoss</A>
</UL>
<H2><A NAME="Highlights"></A>Highlights</H2>
-
<ul>
<li>TEIID-2150 <b>Positional procedure defaults</b> - a procedure now may be called positionally with just the leading input parameters as long as all trailing parameters are out or defaultable.
<li>TEIID-2148 <b>Streaming Improvements</b> - the ws translator invoke/invokeHttp procedures now execpt a stream parameter to indicate that the result should be streamed directly without an intermediate copy being created.
@@ -39,12 +38,6 @@
<li>decodeinteger/decodestring have been deprecated. A CASE expression should be used instead.
</ul>
-<h4>from 8.1</h4>
-<ul>
- <li>TEIID-2149 <B>Subquery Unnesting</B> - the optimizer will not consult the subqueryUnnestDefault property if it can make a cost based decision to replace a subquery with a merge join.
-Use the subquery hints, DJ, MJ, and NO_UNNEST to override this behavior if needed.
-<ul>
-
<h4>from 8.0</h4>
<ul>
<li>org.teiid.metadata.Schema holds FunctionMethods by uuid rather than name to accommodate overridden method signatures.
@@ -66,7 +59,7 @@
<li>TEIID-2127 if ExecutionFactory.isSourceRequired returns true (the default) then not obtaining a connection will for an Execution will result in an error. If an ExecutionFactory does not use a source, then no connection-jndi-name should be
specified and isSourceRequired should return false (see setSourceRequired). If isSourceRequired returns false and a connection-jndi-name is specified, then Teiid will still attempt to obtain a connection, but no exception will be thrown if a connection isn't available.
<li>TEIID-2138 the odbc layer will report standard_conforming_strings as on, rather than off to better reflect the string literal handling of Teiid.
-<ul>
+</ul>
<h4>from 7.x</h4>
<ul>
@@ -151,14 +144,25 @@
See the <a href="teiid-docs/teiid_admin_guide.pdf">Admin Guide</a> for more on configuration and installation.
-<h4>from 7.4</h4>
+<h4>from 8.1</h4>
<ul>
- <li>The configuration for the buffer service now defaults to 256/512 for processor and connector batch sizes respectively. The buffer service also has 4 new properties inline-lobs, memory-buffer-space, memory-buffer-off-heap, and max-storage-object-size.
- If you were explicitly setting the value for 'max-reserve-kb', you should consider lowering that value to account for the memory buffer and/or explicitly set the memory-buffer-space.
+ <li>The file translator now defaults to exceptionIfFileNotFound=true, you can set the translator property to false to preserve the old behavior of returning null.
</ul>
+<h4>from 8.0</h4>
+<ul>
+ <li>teiid-security-users and teiid-security-roles properties files have been moved under the configuration directory of their respective deployment.
+</ul>
+
+<h4>from 7.7</h4>
+<ul>
+ <li>The server is now dependent upon AS 7.x. The old configuration and deployment structure is no longer applicable.
+</ul>
+
<h4>from 7.4</h4>
<ul>
+ <li>The configuration for the buffer service now defaults to 256/512 for processor and connector batch sizes respectively. The buffer service also has 4 new properties inline-lobs, memory-buffer-space, memory-buffer-off-heap, and max-storage-object-size.
+ If you were explicitly setting the value for 'max-reserve-kb', you should consider lowering that value to account for the memory buffer and/or explicitly set the memory-buffer-space.
<LI>The configuration for authorization has been moved off of the RuntimeEngineDeployer bean and onto separate AuthorizationValidator and PolicyDecider beans.
<LI>The configuration for the buffer manager has been simplified to refer to memory sizes in KB, rather than batch columns.
</ul>
@@ -241,8 +245,8 @@
</ul>
<h2><a name="Details">Detailed Release Notes</a></h2>
- Detailed Release Notes - Teiid - Version ${project.version}
-
+ Detailed Release Notes - Teiid - Version ${project.version}
+
<h2><a name="Documentation">Documentation and Help</a></h2>
The <a href="http://www.jboss.org/teiid/">Teiid community project</a> is hosted on jboss.org.
Modified: trunk/connectors/translator-file/src/main/java/org/teiid/translator/file/FileExecutionFactory.java
===================================================================
--- trunk/connectors/translator-file/src/main/java/org/teiid/translator/file/FileExecutionFactory.java 2012-08-21 10:50:28 UTC (rev 4351)
+++ trunk/connectors/translator-file/src/main/java/org/teiid/translator/file/FileExecutionFactory.java 2012-08-21 16:33:11 UTC (rev 4352)
@@ -145,7 +145,7 @@
public static final String SAVEFILE = "saveFile"; //$NON-NLS-1$
private Charset encoding = Charset.defaultCharset();
- private boolean exceptionIfFileNotFound;
+ private boolean exceptionIfFileNotFound = true;
public FileExecutionFactory() {
setSourceRequiredForMetadata(false);
13 years, 4 months