Skip to content

Commit

Permalink
TEIID-4493 initial qgis support
Browse files Browse the repository at this point in the history
# Conflicts:
#	connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/teiid/TeiidExecutionFactory.java
#	engine/src/main/java/org/teiid/query/QueryPlugin.java
#	engine/src/main/java/org/teiid/query/resolver/util/ResolverVisitor.java
#	engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
#	engine/src/main/java/org/teiid/query/validator/ValidationVisitor.java
#	engine/src/test/java/org/teiid/query/processor/TestGeometry.java
#	runtime/src/main/java/org/teiid/deployers/PgCatalogMetadataStore.java
#	runtime/src/main/java/org/teiid/odbc/ODBCServerRemoteImpl.java
#	runtime/src/main/java/org/teiid/transport/PgBackendProtocol.java
#	runtime/src/main/java/org/teiid/transport/PgFrontendProtocol.java
#	test-integration/common/src/test/resources/TestCase3473/testGetTables.expected
#	test-integration/common/src/test/resources/TestJDBCSocketTransport/testSelect.expected
#	test-integration/common/src/test/resources/TestMMDatabaseMetaData/testGetColumns.expected
#	test-integration/common/src/test/resources/TestMMDatabaseMetaData/testGetFunctionColumns.expected
#	test-integration/common/src/test/resources/TestMMDatabaseMetaData/testGetFunctions.expected
#	test-integration/common/src/test/resources/TestODBCSchema/test_PG_ATTRDEF.expected
#	test-integration/common/src/test/resources/TestODBCSchema/test_PG_ATTRIBUTE.expected
#	test-integration/common/src/test/resources/TestODBCSchema/test_PG_ATTRIBUTE_overflow.expected
#	test-integration/common/src/test/resources/TestODBCSchema/test_PG_CLASS.expected
#	test-integration/common/src/test/resources/TestODBCSchema/test_PG_INDEX.expected
#	test-integration/common/src/test/resources/TestODBCSchema/test_PG_NAMESPACE.expected
#	test-integration/common/src/test/resources/TestODBCSocketTransport/testSelect.expected
#	test-integration/common/src/test/resources/TestPartsDatabaseMetadata/testColumns.expected
#	test-integration/common/src/test/resources/TestSystemVirtualModel/testColumns.expected
#	test-integration/common/src/test/resources/TestSystemVirtualModel/testFunctionParams.expected
#	test-integration/common/src/test/resources/TestSystemVirtualModel/testFunctions.expected
#	test-integration/common/src/test/resources/TestSystemVirtualModel/testKeyColumns.expected
#	test-integration/common/src/test/resources/TestSystemVirtualModel/testKeys.expected
#	test-integration/common/src/test/resources/TestSystemVirtualModel/testProperties.expected
#	test-integration/common/src/test/resources/TestSystemVirtualModel/testTables.expected
#	test-integration/common/src/test/resources/TestSystemVirtualModel/testViews.expected
#	test-integration/common/src/test/resources/TestVirtualDocWithVirtualProc/testDefect15241b.expected
  • Loading branch information
shawkins committed Jun 29, 2017
1 parent ebd1834 commit f3d9b56
Show file tree
Hide file tree
Showing 49 changed files with 3,410 additions and 152 deletions.
Expand Up @@ -237,5 +237,6 @@ public class SourceSystemFunctions {
public static final String ST_X = "st_x"; //$NON-NLS-1$
public static final String ST_Y = "st_y"; //$NON-NLS-1$
public static final String ST_Z = "st_z"; //$NON-NLS-1$
public static final String ST_MAKEENVELOPE = "st_makeenvelope"; //$NON-NLS-1$

}
Expand Up @@ -688,6 +688,7 @@ public List<String> getSupportedFunctions() {
}
if (this.postGisVersion.compareTo(ONE_5) >= 0) {
supportedFunctions.add(SourceSystemFunctions.ST_GEOMFROMGML);
supportedFunctions.add(SourceSystemFunctions.ST_MAKEENVELOPE);
}
if (this.postGisVersion.compareTo(TWO_0) >= 0) {
supportedFunctions.add(SourceSystemFunctions.ST_GEOMFROMGEOJSON);
Expand Down
Expand Up @@ -67,6 +67,8 @@ public class TeiidExecutionFactory extends JDBCExecutionFactory {
public static final Version EIGHT_12_5 = Version.getVersion("8.12.5"); //$NON-NLS-1$
public static final Version EIGHT_13 = Version.getVersion("8.13.0"); //$NON-NLS-1$
public static final Version NINE_0 = Version.getVersion("9.0"); //$NON-NLS-1$
public static final Version NINE_1 = Version.getVersion("9.1"); //$NON-NLS-1$
public static final Version NINE_2 = Version.getVersion("9.2"); //$NON-NLS-1$

public TeiidExecutionFactory() {
}
Expand Down Expand Up @@ -217,6 +219,50 @@ public List<String> getSupportedFunctions() {
supportedFunctions.add(SourceSystemFunctions.ST_ASEWKT);
}

if (getVersion().compareTo(NINE_1) >= 0) {
supportedFunctions.add(SourceSystemFunctions.ST_AREA);
supportedFunctions.add(SourceSystemFunctions.ST_BOUNDARY);
supportedFunctions.add(SourceSystemFunctions.ST_BUFFER);
supportedFunctions.add(SourceSystemFunctions.ST_CENTROID);
supportedFunctions.add(SourceSystemFunctions.ST_CONVEXHULL);
supportedFunctions.add(SourceSystemFunctions.ST_COORDDIM);
supportedFunctions.add(SourceSystemFunctions.ST_CURVETOLINE);
supportedFunctions.add(SourceSystemFunctions.ST_DIFFERENCE);
supportedFunctions.add(SourceSystemFunctions.ST_DIMENSION);
supportedFunctions.add(SourceSystemFunctions.ST_ENDPOINT);
supportedFunctions.add(SourceSystemFunctions.ST_EXTERIORRING);
supportedFunctions.add(SourceSystemFunctions.ST_GEOMETRYN);
supportedFunctions.add(SourceSystemFunctions.ST_GEOMETRYTYPE);
supportedFunctions.add(SourceSystemFunctions.ST_INTERIORRINGN);
supportedFunctions.add(SourceSystemFunctions.ST_INTERSECTION);
supportedFunctions.add(SourceSystemFunctions.ST_ISCLOSED);
supportedFunctions.add(SourceSystemFunctions.ST_ISEMPTY);
supportedFunctions.add(SourceSystemFunctions.ST_ISRING);
supportedFunctions.add(SourceSystemFunctions.ST_ISSIMPLE);
supportedFunctions.add(SourceSystemFunctions.ST_ISVALID);
supportedFunctions.add(SourceSystemFunctions.ST_LENGTH);
supportedFunctions.add(SourceSystemFunctions.ST_NUMGEOMETRIES);
supportedFunctions.add(SourceSystemFunctions.ST_NUMINTERIORRINGS);
supportedFunctions.add(SourceSystemFunctions.ST_NUMPOINTS);
supportedFunctions.add(SourceSystemFunctions.ST_ORDERINGEQUALS);
supportedFunctions.add(SourceSystemFunctions.ST_PERIMETER);
supportedFunctions.add(SourceSystemFunctions.ST_POINT);
supportedFunctions.add(SourceSystemFunctions.ST_POINTN);
supportedFunctions.add(SourceSystemFunctions.ST_POINTONSURFACE);
supportedFunctions.add(SourceSystemFunctions.ST_POLYGON);
supportedFunctions.add(SourceSystemFunctions.ST_RELATE);
supportedFunctions.add(SourceSystemFunctions.ST_STARTPOINT);
supportedFunctions.add(SourceSystemFunctions.ST_SYMDIFFERENCE);
supportedFunctions.add(SourceSystemFunctions.ST_UNION);
supportedFunctions.add(SourceSystemFunctions.ST_X);
supportedFunctions.add(SourceSystemFunctions.ST_Y);
supportedFunctions.add(SourceSystemFunctions.ST_Z);
}

if (getVersion().compareTo(NINE_2) >= 0) {
supportedFunctions.add(SourceSystemFunctions.ST_MAKEENVELOPE);
}

return supportedFunctions;
}

Expand Down
2 changes: 2 additions & 0 deletions engine/src/main/java/org/teiid/query/QueryPlugin.java
Expand Up @@ -609,5 +609,7 @@ public static enum Event implements BundleUtil.Event{
TEIID31206,
TEIID31207,
TEIID31208,
TEIID31209,
TEIID31210,
}
}
Expand Up @@ -65,6 +65,14 @@ public static BlobType asBlob(GeometryType geometry) {
return new BlobType(b);
}

public static BlobType asBlob(GeometryType geometry, String encoding) throws FunctionExecutionException {
if ("NDR".equals(encoding)) { //$NON-NLS-1$
return new BlobType(GeometryUtils.getBytes(GeometryUtils.getGeometry(geometry), false));
}
Blob b = geometry.getReference();
return new BlobType(b);
}

@TeiidFunction(name=SourceSystemFunctions.ST_ASEWKB,
category=FunctionCategoryConstants.GEOMETRY,
nullOnNull=true,
Expand Down Expand Up @@ -680,4 +688,20 @@ public static Double ordinateZ(GeometryType geom)
return GeometryUtils.ordinate(geom, GeometryUtils.Ordinate.Z);
}

@TeiidFunction(name=SourceSystemFunctions.ST_MAKEENVELOPE,
category=FunctionCategoryConstants.GEOMETRY,
nullOnNull=true,
pushdown=PushDown.CAN_PUSHDOWN)
public static GeometryType makeEnvelope(double xmin, double ymin, double xmax, double ymax) {
return GeometryUtils.makeEnvelope(xmin, ymin, xmax, ymax, null);
}

@TeiidFunction(name=SourceSystemFunctions.ST_MAKEENVELOPE,
category=FunctionCategoryConstants.GEOMETRY,
nullOnNull=true,
pushdown=PushDown.CAN_PUSHDOWN)
public static GeometryType makeEnvelope(double xmin, double ymin, double xmax, double ymax, int srid) {
return GeometryUtils.makeEnvelope(xmin, ymin, xmax, ymax, srid);
}

}
19 changes: 16 additions & 3 deletions engine/src/main/java/org/teiid/query/function/GeometryUtils.java
Expand Up @@ -374,9 +374,13 @@ public static GeometryType getGeometryType(Geometry jtsGeom) {
}

public static GeometryType getGeometryType(Geometry jtsGeom, int srid) {
WKBWriter writer = new WKBWriter();
byte[] bytes = writer.write(jtsGeom);
return new GeometryType(bytes, srid);
byte[] bytes = getBytes(jtsGeom, true);
return new GeometryType(bytes, srid);
}

public static byte[] getBytes(Geometry jtsGeom, boolean bigEndian) {
WKBWriter writer = new WKBWriter(2, bigEndian?ByteOrderValues.BIG_ENDIAN:ByteOrderValues.LITTLE_ENDIAN);
return writer.write(jtsGeom);
}

public static Geometry getGeometry(GeometryType geom)
Expand Down Expand Up @@ -784,4 +788,13 @@ public static Double ordinate(GeometryType geom, Ordinate ordinate) throws Funct
return value;
}

public static GeometryType makeEnvelope(double xmin, double ymin,
double xmax, double ymax, Integer srid) {
Geometry geom = GEOMETRY_FACTORY.createPolygon(new Coordinate[] {new Coordinate(xmin, ymin), new Coordinate(xmin, ymax), new Coordinate(xmax, ymax), new Coordinate(xmax, ymin), new Coordinate(xmin, ymin)});
if (srid != null) {
geom.setSRID(srid);
}
return getGeometryType(geom);
}

}
Expand Up @@ -257,7 +257,13 @@ public static Constant convertConstant(String sourceTypeName,
if (!DataTypeManager.isTransformable(targetTypeName, sourceTypeName)) {
return null;
}


//allow implicit conversion of literal values to floating
if (Number.class.isAssignableFrom(constant.getType()) &&
(result.getType() == DataTypeManager.DefaultDataClasses.DOUBLE || result.getType() == DataTypeManager.DefaultDataClasses.FLOAT)) {
return result;
}

if (!(constant.getValue() instanceof Comparable)) {
return null; //this is the case for xml constants
}
Expand Down Expand Up @@ -803,23 +809,45 @@ private static boolean nameMatchesGroup(String groupContext,
* @return implicit conversion Function, or null if none is necessary
* @throws QueryResolverException if a conversion is necessary but none can
* be found
* @throws TeiidComponentException
* @throws QueryMetadataException
*/
static Expression resolveSubqueryPredicateCriteria(Expression expression, SubqueryContainer crit, QueryMetadataInterface metadata)
throws QueryResolverException {
throws QueryResolverException, QueryMetadataException, TeiidComponentException {

// Check that type of the expression is same as the type of the
// single projected symbol of the subquery
Class<?> exprType = expression.getType();
if(exprType == null) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30075, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30075, expression));
}
String exprTypeName = DataTypeManager.getDataTypeName(exprType);

Collection<Expression> projectedSymbols = crit.getCommand().getProjectedSymbols();
if (projectedSymbols.size() != 1){
throw new QueryResolverException(QueryPlugin.Event.TEIID30093, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30093, crit.getCommand()));
List<Expression> projectedSymbols = crit.getCommand().getProjectedSymbols();
int size = projectedSymbols.size();
if (size != 1){
//special handling for array comparison, we don't require the subquery to be wrapped explicitly
if (expression instanceof Array) {
Array array = (Array)expression;
if (array.getExpressions().size() != size) {
throw new QueryResolverException(QueryPlugin.Event.TEIID31210, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31210, size, array.getExpressions().size(), crit));
}
for (int i = 0; i < size; i++) {
array.getExpressions().set(i, resolveComparision(array.getExpressions().get(i), crit, metadata, projectedSymbols.get(i).getType()));
}
return array;
}
throw new QueryResolverException(QueryPlugin.Event.TEIID30093, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30093, crit.getCommand()));
}
Class<?> subqueryType = projectedSymbols.iterator().next().getType();

return resolveComparision(expression, crit, metadata,
subqueryType);
}

private static Expression resolveComparision(Expression expression,
SubqueryContainer crit, QueryMetadataInterface metadata,
Class<?> subqueryType) throws QueryResolverException {
// Check that type of the expression is same as the type of the
// single projected symbol of the subquery
Class<?> exprType = expression.getType();
if(exprType == null) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30075, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30075, expression));
}
String exprTypeName = DataTypeManager.getDataTypeName(exprType);

String subqueryTypeName = DataTypeManager.getDataTypeName(subqueryType);
Expression result = null;
try {
Expand All @@ -830,8 +858,8 @@ static Expression resolveSubqueryPredicateCriteria(Expression expression, Subque
} catch (QueryResolverException qre) {
throw new QueryResolverException(QueryPlugin.Event.TEIID30094, qre, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30094, crit));
}
return result;
}
return result;
}

public static ResolvedLookup resolveLookup(Function lookup, QueryMetadataInterface metadata) throws QueryResolverException, TeiidComponentException {
Expression[] args = lookup.getArgs();
Expand Down
Expand Up @@ -273,6 +273,8 @@ public void visit(SubqueryCompareCriteria obj) {
obj.setLeftExpression(ResolverUtil.resolveSubqueryPredicateCriteria(obj.getLeftExpression(), obj, metadata));
} catch(QueryResolverException e) {
handleException(e);
} catch (TeiidComponentException e) {
handleException(e);
}
}

Expand All @@ -281,6 +283,8 @@ public void visit(SubquerySetCriteria obj) {
obj.setExpression(ResolverUtil.resolveSubqueryPredicateCriteria(obj.getExpression(), obj, metadata));
} catch(QueryResolverException e) {
handleException(e);
} catch (TeiidComponentException e) {
handleException(e);
}
}

Expand Down Expand Up @@ -337,31 +341,35 @@ public void visit(Array array) {
}
}
} else {
Class<?> type = null;
for (int i = 0; i < array.getExpressions().size(); i++) {
Expression expr = array.getExpressions().get(i);
Class<?> baseType = expr.getType();
while (baseType != null && baseType.isArray()) {
baseType = baseType.getComponentType();
}
if (baseType != DefaultDataClasses.NULL) {
if (type == null) {
type = expr.getType();
} else if (type != expr.getType()) {
type = DataTypeManager.DefaultDataClasses.OBJECT;
}
}
}
if (type == null) {
type = DataTypeManager.DefaultDataClasses.NULL;
}
array.setComponentType(type);
resolveComponentType(array);
}
} catch (QueryResolverException e) {
handleException(e);
}
}

public static void resolveComponentType(Array array) {
Class<?> type = null;
for (int i = 0; i < array.getExpressions().size(); i++) {
Expression expr = array.getExpressions().get(i);
Class<?> baseType = expr.getType();
while (baseType != null && baseType.isArray()) {
baseType = baseType.getComponentType();
}
if (baseType != DefaultDataClasses.NULL) {
if (type == null) {
type = expr.getType();
} else if (type != expr.getType()) {
type = DataTypeManager.DefaultDataClasses.OBJECT;
}
}
}
if (type == null) {
type = DataTypeManager.DefaultDataClasses.NULL;
}
array.setComponentType(type);
}

public void visit(CaseExpression obj) {
try {
resolveCaseExpression(obj);
Expand Down
24 changes: 22 additions & 2 deletions engine/src/main/java/org/teiid/query/rewriter/QueryRewriter.java
Expand Up @@ -65,6 +65,7 @@
import org.teiid.query.resolver.ProcedureContainerResolver;
import org.teiid.query.resolver.QueryResolver;
import org.teiid.query.resolver.util.ResolverUtil;
import org.teiid.query.resolver.util.ResolverVisitor;
import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.LanguageObject.Util;
import org.teiid.query.sql.LanguageVisitor;
Expand Down Expand Up @@ -894,6 +895,7 @@ private Criteria rewriteCriteria(Criteria criteria) throws TeiidComponentExcepti
}
} else if (criteria instanceof SubquerySetCriteria) {
SubquerySetCriteria sub = (SubquerySetCriteria)criteria;
rewriteWithExplicitArray(sub.getExpression(), sub);
rewriteSubqueryContainer(sub, true);
if (!RelationalNodeUtil.shouldExecute(sub.getCommand(), false, true)) {
return sub.isNegated()?TRUE_CRITERIA:FALSE_CRITERIA;
Expand All @@ -910,6 +912,24 @@ private Criteria rewriteCriteria(Criteria criteria) throws TeiidComponentExcepti
return evaluateCriteria(criteria);
}

private void rewriteWithExplicitArray(Expression ex, SubqueryContainer<QueryCommand> sub)
throws QueryMetadataException, QueryResolverException,
TeiidComponentException {
if (!(ex instanceof Array) || sub.getCommand() == null || sub.getCommand().getProjectedSymbols().size() == 1) {
return;
}
Query query = QueryRewriter.createInlineViewQuery(new GroupSymbol("x"), sub.getCommand(), metadata, sub.getCommand().getProjectedSymbols()); //$NON-NLS-1$
List<Expression> exprs = new ArrayList<Expression>();
for (Expression expr : query.getSelect().getProjectedSymbols()) {
exprs.add(SymbolMap.getExpression(expr));
}
Array array = new Array(exprs);
query.getSelect().clearSymbols();
query.getSelect().addSymbol(array);
ResolverVisitor.resolveComponentType(array);
sub.setCommand(query);
}

private void addImplicitLimit(SubqueryContainer<QueryCommand> container, int rowLimit) {
if (container.getCommand().getLimit() != null) {
Limit lim = container.getCommand().getLimit();
Expand Down Expand Up @@ -1342,8 +1362,8 @@ public static boolean isNull(Expression expr) {
* quantifier is replaced with the canonical and equivalent 'SOME'
*/
private Criteria rewriteCriteria(SubqueryCompareCriteria criteria) throws TeiidComponentException, TeiidProcessingException{
if (criteria.getCommand().getProcessorPlan() == null) {
rewriteWithExplicitArray(criteria.getArrayExpression(), criteria);
if (criteria.getCommand() != null && criteria.getCommand().getProcessorPlan() == null) {
if ((criteria.getOperator() == CompareCriteria.EQ && criteria.getPredicateQuantifier() != SubqueryCompareCriteria.ALL)
|| (criteria.getOperator() == CompareCriteria.NE && criteria.getPredicateQuantifier() == SubqueryCompareCriteria.ALL)) {
SubquerySetCriteria result = new SubquerySetCriteria(criteria.getLeftExpression(), criteria.getCommand());
Expand Down
Expand Up @@ -243,13 +243,6 @@ public void visit(Query obj) {
this.inQuery = true;
validateAggregates(obj);

//if it is select with no from, should not have ScalarSubQuery
if(obj.getSelect() != null && obj.getFrom() == null){
if(!ValueIteratorProviderCollectorVisitor.getValueIteratorProviders(obj.getSelect()).isEmpty()){
handleValidationError(QueryPlugin.Util.getString("ERR.015.012.0067"),obj); //$NON-NLS-1$
}
}

if (obj.getInto() != null) {
validateSelectInto(obj);
}
Expand All @@ -269,14 +262,6 @@ public void visit(SubquerySetCriteria obj) {
handleValidationError(QueryPlugin.Util.getString("ERR.015.012.0027", obj, DataTypeManager.getDataTypeName(obj.getExpression().getType())),obj); //$NON-NLS-1$
}
this.validateRowLimitFunctionNotInInvalidCriteria(obj);

Collection<Expression> projSymbols = obj.getCommand().getProjectedSymbols();

//Subcommand should have one projected symbol (query with one expression
//in SELECT or stored procedure execution that returns a single value).
if(projSymbols.size() != 1) {
handleValidationError(QueryPlugin.Util.getString("ERR.015.012.0011"),obj); //$NON-NLS-1$
}
}

@Override
Expand Down

0 comments on commit f3d9b56

Please sign in to comment.