Skip to content

Commit

Permalink
Merge pull request #978 from shawkins/sqlalchemy-backport
Browse files Browse the repository at this point in the history
Sqlalchemy backport
  • Loading branch information
shawkins committed Jul 5, 2017
2 parents d08433e + fbf87a5 commit a5d52c0
Show file tree
Hide file tree
Showing 91 changed files with 3,660 additions and 2,047 deletions.
Expand Up @@ -191,6 +191,7 @@ public class SourceSystemFunctions {
public static final String ST_EQUALS = "st_equals"; //$NON-NLS-1$
public static final String ST_TRANSFORM = "st_transform"; //$NON-NLS-1$
public static final String ST_SIMPLIFY = "st_simplify"; //$NON-NLS-1$
public static final String ST_SIMPLIFYPRESERVETOPOLOGY = "st_simplifypreservetopology"; //$NON-NLS-1$
public static final String ST_FORCE_2D = "st_force_2d"; //$NON-NLS-1$
public static final String ST_ENVELOPE = "st_envelope"; //$NON-NLS-1$
public static final String ST_WITHIN = "st_within"; //$NON-NLS-1$
Expand Down Expand Up @@ -237,5 +238,7 @@ 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$
public static final String ST_SNAPTOGRID = "st_snaptogrid"; //$NON-NLS-1$

}
Expand Up @@ -216,8 +216,13 @@ <h2 class="western"><a name="Compatibility"></a>Compatibility Issues</h2>
<p><a href="https://issues.jboss.org/browse/TEIID-4205">TEIID-4205</a> By default,
the wrapping begin/commit of a UseDeclareFetch cursor will be ignored as Teiid does not require a transaction.
Set the org.teiid.honorDeclareFetchTxn system property to false to revert to the old behavior which honored the transaction.</p>
<li/>
<p><a href="https://issues.jboss.org/browse/TEIID-4866">TEIID-4866</a> For usability
with SQLAlchemy and Superset the version() function over ODBC will report ""PostgreSQL 8.2" rather than "Teiid version".
You can use the system property org.teiid.pgVersion to control this further.</p>
</ul>


<h4 class="western">from ${project.version}</h4>
<ul>
<li/>
Expand Down
20 changes: 12 additions & 8 deletions client/src/main/java/org/teiid/jdbc/ResultSetImpl.java
Expand Up @@ -276,6 +276,10 @@ public int getRow() throws SQLException {
}
return getAbsoluteRowNumber();
}

public Object getRawCurrentValue() {
return currentValue;
}

/**
* Get the value of the current row at the column index specified.
Expand All @@ -300,33 +304,33 @@ public Object getObjectDirect(int column) throws SQLException {
if (currentValue instanceof Streamable<?>) {
Object reference = ((Streamable<?>)currentValue).getReference();
if (reference != null) {
currentValue = reference;
return currentValue;
return reference;
}
if(currentValue instanceof ClobType){
currentValue = new ClobImpl(createInputStreamFactory((ClobType)currentValue), ((ClobType)currentValue).getLength());
return new ClobImpl(createInputStreamFactory((ClobType)currentValue), ((ClobType)currentValue).getLength());
}
else if (currentValue instanceof BlobType) {
InputStreamFactory isf = createInputStreamFactory((BlobType)currentValue);
isf.setLength(((BlobType)currentValue).getLength());
currentValue = new BlobImpl(isf);
return new BlobImpl(isf);
}
else if (currentValue instanceof XMLType) {
XMLType val = (XMLType)currentValue;
currentValue = new SQLXMLImpl(createInputStreamFactory(val));
((SQLXMLImpl)currentValue).setEncoding(val.getEncoding());
SQLXMLImpl impl = new SQLXMLImpl(createInputStreamFactory(val));
impl.setEncoding(val.getEncoding());
return impl;
}
}
else if (currentValue instanceof java.util.Date) {
return TimestampWithTimezone.create((java.util.Date)currentValue, serverTimeZone, getDefaultCalendar(), currentValue.getClass());
}
else if (maxFieldSize > 0 && currentValue instanceof String) {
String val = (String)currentValue;
currentValue = val.substring(0, Math.min(maxFieldSize/2, val.length()));
return val.substring(0, Math.min(maxFieldSize/2, val.length()));
}
else if (currentValue instanceof BinaryType) {
BinaryType val = (BinaryType)currentValue;
currentValue = val.getBytesDirect();
return val.getBytesDirect();
}
return currentValue;
}
Expand Down
26 changes: 25 additions & 1 deletion client/src/main/java/org/teiid/jdbc/StatementImpl.java
Expand Up @@ -162,7 +162,7 @@ enum State {
static Pattern TRANSACTION_STATEMENT = Pattern.compile("\\s*(commit|rollback|(start\\s+transaction))\\s*;?\\s*", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
static Pattern SET_STATEMENT = Pattern.compile("\\s*set(?:\\s+(payload))?\\s+((?:session authorization)|(?:[a-zA-Z]\\w*)|(?:\"[^\"]*\")+)\\s+(?:to\\s+)?((?:[^\\s]*)|(?:'[^']*')+)\\s*;?\\s*", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
static Pattern SET_CHARACTERISTIC_STATEMENT = Pattern.compile("\\s*set\\s+session\\s+characteristics\\s+as\\s+transaction\\s+isolation\\s+level\\s+((?:read\\s+(?:(?:committed)|(?:uncommitted)))|(?:repeatable\\s+read)|(?:serializable))\\s*", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
static Pattern SHOW_STATEMENT = Pattern.compile("\\s*show\\s+([a-zA-Z]\\w*|(?:\"[^\"]*\")+)\\s*;?\\s*?", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
static Pattern SHOW_STATEMENT = Pattern.compile("\\s*show\\s+((?:transaction isolation level)|(?:[a-zA-Z]\\w*)|(?:\"[^\"]*\")+)\\s*;?\\s*", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$

/**
* MMStatement Constructor.
Expand Down Expand Up @@ -646,6 +646,30 @@ ResultsFuture<Boolean> executeShow(Matcher match)
new String[] {DataTypeManager.DefaultDataTypes.STRING, DataTypeManager.DefaultDataTypes.STRING});
return booleanFuture(true);
}
if (show.equalsIgnoreCase("transaction isolation level")) { //$NON-NLS-1$
List<ArrayList<Object>> records = new ArrayList<ArrayList<Object>>(1);
ArrayList<Object> row = new ArrayList<Object>(1);
switch (driverConnection.getTransactionIsolation()) {
case Connection.TRANSACTION_READ_COMMITTED:
row.add("READ COMMITTED"); //$NON-NLS-1$
break;
case Connection.TRANSACTION_READ_UNCOMMITTED:
row.add("READ UNCOMMITTED"); //$NON-NLS-1$
break;
case Connection.TRANSACTION_REPEATABLE_READ:
row.add("REPEATABLE READ"); //$NON-NLS-1$
break;
case Connection.TRANSACTION_SERIALIZABLE:
row.add("SERIALIZABLE"); //$NON-NLS-1$
break;
default:
row.add("UNKNOWN"); //$NON-NLS-1$
}
records.add(row);
createResultSet(records, new String[] {"TRANSACTION ISOLATION"}, //$NON-NLS-1$
new String[] {DataTypeManager.DefaultDataTypes.STRING});
return booleanFuture(true);
}
List<List<String>> records = Collections.singletonList(Collections.singletonList(driverConnection.getExecutionProperty(show)));
createResultSet(records, new String[] {show}, new String[] {DataTypeManager.DefaultDataTypes.STRING});
return booleanFuture(true);
Expand Down
17 changes: 17 additions & 0 deletions client/src/test/java/org/teiid/jdbc/TestStatement.java
Expand Up @@ -32,6 +32,7 @@
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.TimeZone;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;

Expand Down Expand Up @@ -295,4 +296,20 @@ public Boolean answer(InvocationOnMock invocation) throws Throwable {
Mockito.verify(conn).setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
}

@Test public void testShowTxnIsolationLevel() throws SQLException {
ConnectionImpl conn = Mockito.mock(ConnectionImpl.class);
StatementImpl statement = new StatementImpl(conn, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY) {
@Override
protected TimeZone getServerTimeZone() throws SQLException {
return TimeZone.getDefault();
}
};
Mockito.stub(conn.getTransactionIsolation()).toReturn(Connection.TRANSACTION_READ_COMMITTED);
assertTrue(statement.execute("show transaction isolation level")); //$NON-NLS-1$
ResultSet rs = statement.getResultSet();
rs.next();
assertEquals("READ COMMITTED", rs.getString(1));
assertFalse(rs.next());
}

}
Expand Up @@ -679,6 +679,8 @@ public List<String> getSupportedFunctions() {
supportedFunctions.add(SourceSystemFunctions.ST_UNION);
supportedFunctions.add(SourceSystemFunctions.ST_X);
supportedFunctions.add(SourceSystemFunctions.ST_Y);
supportedFunctions.add(SourceSystemFunctions.ST_SNAPTOGRID);
supportedFunctions.add(SourceSystemFunctions.ST_SIMPLIFYPRESERVETOPOLOGY);
}
if (this.postGisVersion.compareTo(ONE_4) >= 0) {
supportedFunctions.add(SourceSystemFunctions.ST_ASGEOJSON);
Expand All @@ -688,6 +690,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,52 @@ 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);
supportedFunctions.add(SourceSystemFunctions.ST_SNAPTOGRID);
supportedFunctions.add(SourceSystemFunctions.ST_SIMPLIFYPRESERVETOPOLOGY);
}

return supportedFunctions;
}

Expand Down
Expand Up @@ -321,7 +321,11 @@ public ResultsFuture<ResultsMessage> processCursorRequest(long reqID,
}

void addRequest(RequestID requestID, RequestWorkItem workItem, ClientState state) {
this.requests.put(requestID, workItem);
RequestWorkItem item = this.requests.put(requestID, workItem);
if (item != null) {
this.requests.put(requestID, item);
throw new TeiidRuntimeException("duplicate request id " + requestID); //$NON-NLS-1$
}
state.addRequest(requestID);
}

Expand Down
Expand Up @@ -27,14 +27,8 @@
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
Expand Down Expand Up @@ -748,7 +742,20 @@ protected void fillRow(List<Object> row, KeyRecord key,
row.add(false);
row.add((key instanceof ForeignKey)?((ForeignKey)key).getUniqueKeyID():null);
row.add(key.getUUID());
row.add(key.getParent().getUUID());
row.add(null);
if (key instanceof ForeignKey) {
KeyRecord ref = ((ForeignKey)key).getReferenceKey();
if (ref != null) {
row.set(row.size() - 1, ref.getParent().getUUID());
}
}
List<Column> columns2 = key.getColumns();
Short[] pos = new Short[columns2.size()];
for (int i = 0; i < pos.length; i++) {
pos[i] = (short)columns2.get(i).getPosition();
}
row.add(new ArrayImpl((Object[])pos));
}

@Override
Expand Down Expand Up @@ -820,6 +827,7 @@ protected void fillRow(List<Object> row, List<?> record,
row.add(key.getName());
row.add(key.getReferenceKey().getName());
row.add(DatabaseMetaData.importedKeyInitiallyDeferred);
row.add(key.getUUID());
}

@Override
Expand Down Expand Up @@ -1320,16 +1328,28 @@ private TupleSource processSystemQuery(CommandContext context, Command command,
case ARRAYITERATE:
Object array = ((Constant)proc.getParameter(1).getExpression()).getValue();
if (array != null) {
Object[] vals = null;
final Object[] vals;
if (array instanceof Object[]) {
vals = (Object[])array;
} else {
ArrayImpl arrayImpl = (ArrayImpl)array;
vals = arrayImpl.getValues();
}
for (Object o : vals) {
rows.add(Arrays.asList(o));
}
return new CollectionTupleSource(new Iterator<List<?>> () {
int index = 0;
@Override
public boolean hasNext() {
return index < vals.length;
}

@Override
public List<?> next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return Arrays.asList(vals[index++]);
}
});
}
}
return new CollectionTupleSource(rows.iterator());
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,
}
}
43 changes: 38 additions & 5 deletions engine/src/main/java/org/teiid/query/eval/Evaluator.java
Expand Up @@ -36,6 +36,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -573,11 +574,43 @@ private Boolean evaluate(SubqueryCompareCriteria criteria, List<?> tuple)
}

ValueIterator valueIter;
try {
valueIter = evaluateSubquery(criteria, tuple);
} catch (TeiidProcessingException e) {
throw new ExpressionEvaluationException(e);
}
if (criteria.getCommand() != null) {
try {
valueIter = evaluateSubquery(criteria, tuple);
} catch (TeiidProcessingException e) {
throw new ExpressionEvaluationException(e);
}
} else {
Object array = evaluate(criteria.getArrayExpression(), tuple);
final Object[] vals;
if (array instanceof Object[]) {
vals = (Object[])array;
} else {
ArrayImpl arrayImpl = (ArrayImpl)array;
vals = arrayImpl.getValues();
}
valueIter = new ValueIterator() {
int index = 0;

@Override
public void reset() {
index = 0;
}

@Override
public boolean hasNext() {
return index < vals.length;
}

@Override
public Object next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return vals[index++];
}
};
}
while(valueIter.hasNext()) {
Object value = valueIter.next();

Expand Down

0 comments on commit a5d52c0

Please sign in to comment.