/*
* 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.transport;
import static org.junit.Assert.*;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.sql.Array;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;
import org.postgresql.Driver;
import org.postgresql.core.v3.ExtendedQueryExectutorImpl;
import org.teiid.adminapi.Model.Type;
import org.teiid.adminapi.Request.ProcessingState;
import org.teiid.adminapi.impl.ModelMetaData;
import org.teiid.adminapi.impl.RequestMetadata;
import org.teiid.adminapi.impl.SessionMetadata;
import org.teiid.adminapi.impl.VDBMetaData;
import org.teiid.common.buffer.BufferManagerFactory;
import org.teiid.core.util.ObjectConverterUtil;
import org.teiid.core.util.UnitTestUtil;
import org.teiid.jdbc.FakeServer;
import org.teiid.jdbc.TestMMDatabaseMetaData;
import org.teiid.runtime.EmbeddedConfiguration;
import org.teiid.runtime.TestEmbeddedServer;
import org.teiid.runtime.TestEmbeddedServer.MockTransactionManager;
@SuppressWarnings("nls")
public class TestODBCSocketTransport {
private static final MockTransactionManager TRANSACTION_MANAGER = new TestEmbeddedServer.MockTransactionManager();
enum Mode {
LEGACY,//how the test was originally written
ENABLED,
LOGIN,
DISABLED
}
static class FakeOdbcServer {
InetSocketAddress addr;
ODBCSocketListener odbcTransport;
FakeServer server;
public void start(Mode mode) throws Exception {
SocketConfiguration config = new SocketConfiguration();
SSLConfiguration sslConfig = new SSLConfiguration();
if (mode == Mode.LOGIN) {
sslConfig.setMode(SSLConfiguration.LOGIN);
} else if (mode == Mode.ENABLED || mode == Mode.LEGACY) {
sslConfig.setMode(SSLConfiguration.ENABLED);
sslConfig.setAuthenticationMode(SSLConfiguration.ONEWAY);
sslConfig.setKeystoreFilename(UnitTestUtil.getTestDataFile("keystore.jks").getAbsolutePath());
sslConfig.setKeystorePassword("password");
} else {
sslConfig.setMode(SSLConfiguration.DISABLED);
}
config.setSSLConfiguration(sslConfig);
addr = new InetSocketAddress(0);
config.setBindAddress(addr.getHostName());
config.setPortNumber(addr.getPort());
server = new FakeServer(false);
EmbeddedConfiguration ec = new EmbeddedConfiguration();
ec.setTransactionManager(TRANSACTION_MANAGER);
server.start(ec, false);
LogonImpl logon = Mockito.mock(LogonImpl.class);
odbcTransport = new ODBCSocketListener(addr, config, Mockito.mock(ClientServiceRegistryImpl.class), BufferManagerFactory.getStandaloneBufferManager(), 100000, logon, server.getDriver());
odbcTransport.setMaxBufferSize(1000); //set to a small size to ensure buffering over the limit works
if (mode == Mode.LEGACY) {
odbcTransport.setRequireSecure(false);
}
server.deployVDB("parts", UnitTestUtil.getTestDataPath() + "/PartsSupplier.vdb");
}
public void stop() {
server.stop();
odbcTransport.stop();
}
}
private static FakeOdbcServer odbcServer = new FakeOdbcServer();
@BeforeClass public static void oneTimeSetup() throws Exception {
odbcServer.start(Mode.LEGACY);
}
@AfterClass public static void oneTimeTearDown() throws Exception {
odbcServer.stop();
}
Connection conn;
@Before public void setUp() throws Exception {
String database = "parts";
TRANSACTION_MANAGER.reset();
connect(database);
}
private void connect(String database) throws SQLException {
Driver d = new Driver();
Properties p = new Properties();
p.setProperty("user", "testuser");
p.setProperty("password", "testpassword");
conn = d.connect("jdbc:postgresql://"+odbcServer.addr.getHostName()+":" +odbcServer.odbcTransport.getPort()+"/"+database, p);
}
@After public void tearDown() throws Exception {
if (conn != null) {
conn.close();
}
}
/**
* Under the covers this still executes a prepared statement due to the driver handling
*/
@Test public void testSelect() throws Exception {
Statement s = conn.createStatement();
assertTrue(s.execute("select * from tables order by name"));
TestMMDatabaseMetaData.compareResultSet(s.getResultSet());
}
@Test public void testTransactionalMultibatch() throws Exception {
Statement s = conn.createStatement();
conn.setAutoCommit(false);
assertTrue(s.execute("select tables.name from tables, columns limit 1025"));
int count = 0;
while (s.getResultSet().next()) {
count++;
}
assertEquals(1025, count);
conn.setAutoCommit(true);
}
@Test public void testMultibatchSelect() throws Exception {
Statement s = conn.createStatement();
assertTrue(s.execute("select * from tables, columns limit 7000"));
ResultSet rs = s.getResultSet();
int i = 0;
while (rs.next()) {
i++;
rs.getString(1);
}
assertEquals(7000, i);
}
/**
* tests that the portal max is handled correctly
*/
@Test public void testMultibatchSelectPrepared() throws Exception {
PreparedStatement s = conn.prepareStatement("select * from (select * from tables order by name desc limit 21) t1, (select * from tables order by name desc limit 21) t2 where t1.name > ?");
conn.setAutoCommit(false);
s.setFetchSize(100);
s.setString(1, "0");
ResultSet rs = s.executeQuery();
int i = 0;
while (rs.next()) {
i++;
rs.getString(1);
}
assertEquals(441, i);
}
@Test public void testBlob() throws Exception {
Statement s = conn.createStatement();
assertTrue(s.execute("select to_bytes('abc', 'UTF-16')"));
ResultSet rs = s.getResultSet();
assertTrue(rs.next());
byte[] bytes = rs.getBytes(1);
assertEquals("abc", new String(bytes, Charset.forName("UTF-16")));
}
@Test public void testClob() throws Exception {
Statement s = conn.createStatement();
assertTrue(s.execute("select cast('abc' as clob)"));
ResultSet rs = s.getResultSet();
assertTrue(rs.next());
//getting as a clob is unsupported, since it uses the lo logic
String clob = rs.getString(1);
assertEquals("abc", clob);
}
@Test public void testLargeClob() throws Exception {
Statement s = conn.createStatement();
assertTrue(s.execute("select cast(repeat('_', 3000) as clob)"));
ResultSet rs = s.getResultSet();
assertTrue(rs.next());
//getting as a clob is unsupported, since it uses the lo logic
String clob = rs.getString(1);
assertEquals(3000, clob.length());
}
@Test public void testMultiRowBuffering() throws Exception {
Statement s = conn.createStatement();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 11; i++) {
sb.append("select '' union all ");
}
sb.append("select ''");
assertTrue(s.execute(sb.toString()));
ResultSet rs = s.getResultSet();
assertTrue(rs.next());
String str = rs.getString(1);
assertEquals(0, str.length());
}
@Test public void testTransactionCycle() throws Exception {
//TODO: drill in to ensure that the underlying statement has been set to autocommit false
conn.setAutoCommit(false);
Statement s = conn.createStatement();
assertTrue(s.execute("select * from tables order by name"));
conn.setAutoCommit(true);
}
@Test public void testRollbackSavepointNoOp() throws Exception {
conn.setAutoCommit(false);
Statement s = conn.createStatement();
assertFalse(s.execute("rollback to foo1"));
assertFalse(conn.getAutoCommit());
}
@Test public void testTxnStatement() throws Exception {
Statement s = conn.createStatement();
assertFalse(s.execute("begin work"));
assertFalse(s.execute("rollback transaction"));
}
@Test public void testPk() throws Exception {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select ta.attname, ia.attnum, ic.relname, n.nspname, tc.relname " +//$NON-NLS-1$
"from pg_catalog.pg_attribute ta, pg_catalog.pg_attribute ia, pg_catalog.pg_class tc, pg_catalog.pg_index i, " +//$NON-NLS-1$
"pg_catalog.pg_namespace n, pg_catalog.pg_class ic where tc.relname = E'pg_attribute' AND n.nspname = E'pg_catalog'");
TestMMDatabaseMetaData.compareResultSet(rs);
}
@Test public void testPkPrepared() throws Exception {
PreparedStatement stmt = conn.prepareStatement("select ta.attname, ia.attnum, ic.relname, n.nspname, tc.relname " +//$NON-NLS-1$
"from pg_catalog.pg_attribute ta, pg_catalog.pg_attribute ia, pg_catalog.pg_class tc, pg_catalog.pg_index i, " +//$NON-NLS-1$
"pg_catalog.pg_namespace n, pg_catalog.pg_class ic where tc.relname = E'pg_attribute' AND n.nspname = E'pg_catalog'");
ResultSet rs = stmt.executeQuery();
TestMMDatabaseMetaData.compareResultSet(rs);
}
@Test public void testColumnMetadataWithAlias() throws Exception {
PreparedStatement stmt = conn.prepareStatement("select ta.attname as x from pg_catalog.pg_attribute ta limit 1");
ResultSet rs = stmt.executeQuery();
TestMMDatabaseMetaData.compareResultSet(rs);
}
@Test public void testPreparedError() throws Exception {
PreparedStatement stmt = conn.prepareStatement("select cast(? as integer)");
stmt.setString(1, "a");
try {
stmt.executeQuery();
} catch (SQLException e) {
assertTrue(e.getMessage().contains("Error converting"));
}
}
@Test public void testPreparedError1() throws Exception {
PreparedStatement stmt = conn.prepareStatement("select");
try {
stmt.executeQuery();
} catch (SQLException e) {
assertTrue(e.getMessage().contains("Parsing error"));
}
}
@Test public void testEscapedLiteral() throws Exception {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select E'\\n\\thello pg'");
assertTrue(rs.next());
assertEquals("\n\thello pg", rs.getString(1));
}
@Test public void testPgProc() throws Exception {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from pg_proc");
rs.next();
assertEquals("oid", rs.getArray("proargtypes").getBaseTypeName());
TestMMDatabaseMetaData.compareResultSet(rs); //compare the rest
}
@Test public void testCursor() throws Exception {
Statement stmt = conn.createStatement();
ExtendedQueryExectutorImpl.simplePortal = "foo";
try {
assertFalse(stmt.execute("declare \"foo\" cursor for select * from pg_proc limit 13;"));
//should get a single row
stmt.execute("fetch \"foo\"");
ResultSet rs = stmt.getResultSet();
int rowCount = 0;
while (rs.next()) {
rowCount++;
}
assertEquals(1, rowCount);
//move 5
assertFalse(stmt.execute("move 5 in \"foo\""));
//fetch 10, but only 7 are left
stmt.execute("fetch 10 in \"foo\"");
rs = stmt.getResultSet();
rowCount = 0;
while (rs.next()) {
rowCount++;
}
assertEquals(7, rowCount);
stmt.execute("close \"foo\"");
//start a new cursor and check failure
assertFalse(stmt.execute("declare \"foo\" cursor for select * from pg_proc;"));
try {
stmt.execute("fetch 9999999999 in \"foo\"");
fail();
} catch (SQLException e) {
}
} finally {
ExtendedQueryExectutorImpl.simplePortal = null;
}
}
@Test public void testCursorUnquoted() throws Exception {
Statement stmt = conn.createStatement();
ExtendedQueryExectutorImpl.simplePortal = "foo";
try {
assertFalse(stmt.execute("declare foo cursor for select * from pg_proc limit 13;"));
//should get a single row
stmt.execute("fetch foo");
ResultSet rs = stmt.getResultSet();
int rowCount = 0;
while (rs.next()) {
rowCount++;
}
assertEquals(1, rowCount);
//move 5
assertFalse(stmt.execute("move 5 in foo"));
//fetch 10, but only 7 are left
stmt.execute("fetch 10 in \"foo\"");
rs = stmt.getResultSet();
rowCount = 0;
while (rs.next()) {
rowCount++;
}
assertEquals(7, rowCount);
stmt.execute("close foo");
} finally {
ExtendedQueryExectutorImpl.simplePortal = null;
}
}
@Test public void testScrollCursor() throws Exception {
Statement stmt = conn.createStatement();
ExtendedQueryExectutorImpl.simplePortal = "foo";
try {
assertFalse(stmt.execute("declare \"foo\" insensitive scroll cursor for select * from pg_proc limit 11;"));
assertFalse(stmt.execute("move 5 in \"foo\""));
stmt.execute("fetch 7 in \"foo\"");
ResultSet rs = stmt.getResultSet();
int rowCount = 0;
while (rs.next()) {
rowCount++;
}
assertEquals(6, rowCount);
//move past the end
//assertFalse(stmt.execute("move forward 0 in \"foo\""));
//move back
assertFalse(stmt.execute("move backward 2 in \"foo\""));
stmt.execute("fetch 6 in \"foo\"");
rs = stmt.getResultSet();
rowCount = 0;
while (rs.next()) {
rowCount++;
}
assertEquals(1, rowCount);
stmt.execute("close \"foo\"");
} finally {
ExtendedQueryExectutorImpl.simplePortal = null;
}
}
@Test public void testScrollCursorWithHold() throws Exception {
Statement stmt = conn.createStatement();
ExtendedQueryExectutorImpl.simplePortal = "foo";
try {
assertFalse(stmt.execute("declare \"foo\" insensitive scroll cursor with hold for select * from pg_proc;"));
assertFalse(stmt.execute("move 5 in \"foo\""));
stmt.execute("fetch 7 in \"foo\"");
ResultSet rs = stmt.getResultSet();
int rowCount = 0;
while (rs.next()) {
rowCount++;
}
assertEquals(7, rowCount);
stmt.execute("close \"foo\"");
} finally {
ExtendedQueryExectutorImpl.simplePortal = null;
}
}
@Test public void testScrollCursorOtherFetches() throws Exception {
Statement stmt = conn.createStatement();
ExtendedQueryExectutorImpl.simplePortal = "foo";
try {
assertFalse(stmt.execute("declare \"foo\" insensitive scroll cursor for values (1), (2), (3);"));
stmt.execute("fetch first in \"foo\"");
ResultSet rs = stmt.getResultSet();
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
assertFalse(rs.next());
stmt.execute("fetch last in \"foo\"");
rs = stmt.getResultSet();
assertTrue(rs.next());
assertEquals(3, rs.getInt(1));
assertFalse(rs.next());
stmt.execute("fetch absolute 2 in \"foo\"");
rs = stmt.getResultSet();
assertTrue(rs.next());
assertEquals(2, rs.getInt(1));
assertFalse(rs.next());
stmt.execute("fetch relative 1 in \"foo\"");
rs = stmt.getResultSet();
assertTrue(rs.next());
assertEquals(3, rs.getInt(1));
assertFalse(rs.next());
} finally {
ExtendedQueryExectutorImpl.simplePortal = null;
}
}
@Test public void testPgProcedure() throws Exception {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select has_function_privilege(100, 'foo')");
rs.next();
}
@Test public void testPreparedUpdate() throws Exception {
Statement stmt = conn.createStatement();
assertFalse(stmt.execute("create local temporary table x (y string)"));
PreparedStatement ps = conn.prepareStatement("delete from x");
assertFalse(ps.execute());
assertNull(ps.getMetaData());
}
@Test public void testSelectSsl() throws Exception {
conn.close();
Driver d = new Driver();
Properties p = new Properties();
p.setProperty("user", "testuser");
p.setProperty("password", "testpassword");
p.setProperty("ssl", "true");
p.setProperty("sslfactory", "org.postgresql.ssl.NonValidatingFactory");
conn = d.connect("jdbc:postgresql://"+odbcServer.addr.getHostName()+":" +odbcServer.odbcTransport.getPort()+"/parts", p);
Statement s = conn.createStatement();
assertTrue(s.execute("select * from tables order by name"));
TestMMDatabaseMetaData.compareResultSet("TestODBCSocketTransport/testSelect", s.getResultSet());
}
@Test public void testPayload() throws Exception {
Statement s = conn.createStatement();
assertFalse(s.execute("SET PAYLOAD x y"));
assertTrue(s.execute("SELECT commandpayload('x')"));
ResultSet rs = s.getResultSet();
assertTrue(rs.next());
String str = rs.getString(1);
assertEquals("y", str);
}
@Test public void testShowPlan() throws Exception {
Statement s = conn.createStatement();
assertFalse(s.execute("SET SHOWPLAN ON"));
assertTrue(s.execute("SELECT 1"));
assertTrue(s.execute("SHOW PLAN"));
ResultSet rs = s.getResultSet();
assertTrue(rs.next());
String str = rs.getString(1);
assertTrue(str.startsWith("ProjectNode\n + Relational Node ID:0\n + Output Columns:expr1 (integer)\n + Statistics:\n 0: Node Output Rows: 1"));
}
@Test public void testSetEmptyLiteral() throws Exception {
Statement s = conn.createStatement();
assertFalse(s.execute("SET min_client_messages TO ''"));
assertTrue(s.execute("SHOW min_client_messages"));
ResultSet rs = s.getResultSet();
assertTrue(rs.next());
assertEquals("", rs.getString(1));
}
@Test public void testSetNonString() throws Exception {
Statement s = conn.createStatement();
assertFalse(s.execute("SET extra_float_digits TO 2"));
assertTrue(s.execute("SHOW extra_float_digits"));
ResultSet rs = s.getResultSet();
assertTrue(rs.next());
assertEquals("2", rs.getString(1));
}
@Test public void testColons() throws Exception {
Statement s = conn.createStatement();
//make sure that we aren't mishandling the ::
ResultSet rs = s.executeQuery("select 'a::b'");
assertTrue(rs.next());
assertEquals("a::b", rs.getString(1));
rs = s.executeQuery("select ' a::b'");
assertTrue(rs.next());
assertEquals(" a::b", rs.getString(1));
rs = s.executeQuery("select name::varchar from tables where name = 'Columns'");
assertTrue(rs.next());
assertEquals("Columns", rs.getString(1));
}
@Test public void testInt2Vector() throws Exception {
Statement s = conn.createStatement();
ResultSet rs = s.executeQuery("select indkey FROM pg_index order by oid");
TestMMDatabaseMetaData.compareResultSet(rs);
}
@Test public void test_pg_client_encoding() throws Exception {
Statement s = conn.createStatement();
ResultSet rs = s.executeQuery("select pg_client_encoding()");
rs.next();
assertEquals("UTF8", rs.getString(1));
s.execute("set client_encoding UTF8");
rs = s.executeQuery("select pg_client_encoding()");
rs.next();
assertEquals("UTF8", rs.getString(1));
}
/**
* TODO: we really want an odbc test, but this confirms the pg_description table and ~ rewrite handling
* @throws Exception
*/
@Test public void test_table_with_underscore() throws Exception {
DatabaseMetaData metadata = conn.getMetaData();
ResultSet rs = metadata.getTables(null, null, "pg_index", null);
assertTrue(rs.next());
}
@Test public void test_pg_cast() throws Exception {
Statement s = conn.createStatement();
ResultSet rs = s.executeQuery("select '2011-01-01'::date");
rs.next();
assertEquals("2011-01-01", rs.getString(1));
}
/**
* Ensures that the client is notified about the change. However the driver will
* throw an exception as it requires UTF8
* @throws Exception
*/
@Test(expected=SQLException.class) public void test_pg_client_encoding1() throws Exception {
Statement s = conn.createStatement();
s.execute("set client_encoding LATIN1");
}
@Test public void testArray() throws Exception {
Statement s = conn.createStatement();
ResultSet rs = s.executeQuery("select (1,2)");
rs.next();
Array result = rs.getArray(1);
ResultSet rs1 = result.getResultSet();
rs1.next();
assertEquals(1, rs1.getInt(1));
//TODO:we are squashing the result to a text array, since
//that is a known type - eventually we will need typed array support
//Object array = result.getArray();
//assertEquals(1, java.lang.reflect.Array.get(array, 0));
}
@Test public void testClientIp() throws Exception {
Statement s = conn.createStatement();
assertTrue(s.execute("select * from objecttable('teiid_context' COLUMNS y string 'teiid_row.session.IPAddress') as X"));
ResultSet rs = s.getResultSet();
assertTrue(rs.next());
String value = rs.getString(1);
assertNotNull(value);
}
@Test public void testVDBConnectionProperty() throws Exception {
VDBMetaData vdb = new VDBMetaData();
vdb.setName("x");
vdb.addProperty("connection.foo", "bar");
ModelMetaData mmd = new ModelMetaData();
mmd.setName("x");
mmd.setSchemaSourceType("ddl");
mmd.setModelType(Type.VIRTUAL);
mmd.setSchemaText("create view v as select 1");
vdb.addModel(mmd);
odbcServer.server.deployVDB(vdb);
this.conn.close();
connect("x");
Statement s = conn.createStatement();
assertTrue(s.execute("show foo"));
ResultSet rs = s.getResultSet();
assertTrue(rs.next());
String value = rs.getString(1);
assertEquals("bar", value);
}
@Test public void testDecimalPrecision() throws Exception {
VDBMetaData vdb = new VDBMetaData();
vdb.setName("decimal");
vdb.addProperty("connection.foo", "bar");
ModelMetaData mmd = new ModelMetaData();
mmd.setName("x");
mmd.setModelType(Type.VIRTUAL);
mmd.addSourceMetadata("ddl", "create view v (x decimal(2), y decimal) as select 1.0, 2.0");
vdb.addModel(mmd);
odbcServer.server.deployVDB(vdb);
this.conn.close();
connect("decimal");
Statement s = conn.createStatement();
s.execute("select * from v");
ResultSetMetaData metadata = s.getResultSet().getMetaData();
assertEquals(2, metadata.getPrecision(1));
assertEquals(0, metadata.getScale(1));
assertEquals(32767, metadata.getPrecision(2));
assertEquals(16383, metadata.getScale(2));
s.execute("select atttypmod from pg_attribute where attname = 'y'");
s.getResultSet().next();
assertEquals(2147434499, s.getResultSet().getInt(1));
}
@Test public void testTransactionCycleDisabled() throws Exception {
Statement s = conn.createStatement();
s.execute("set disableLocalTxn true");
conn.setAutoCommit(false);
assertTrue(s.execute("select * from tables order by name"));
conn.setAutoCommit(true);
}
@Test public void testGropuByPositional() throws Exception {
Statement s = conn.createStatement();
//would normally throw an exception, but is allowable over odbc
s.execute("select name, count(schemaname) from tables group by 1");
}
@Test public void testImplicitPortalClosing() throws Exception {
Statement statement = conn.createStatement();
ResultSet rs = statement.executeQuery("select session_id()");
rs.next();
String id = rs.getString(1);
statement.close();
PreparedStatement s = conn.prepareStatement("select 1");
s.executeQuery();
s.executeQuery();
s.executeQuery();
//due to asynch close, there may be several requests
int runningCount = 0;
for (RequestMetadata request : odbcServer.server.getDqp().getRequestsForSession(id)) {
if (request.getState() == ProcessingState.PROCESSING) {
runningCount++;
}
}
assertEquals(1, runningCount);
s.close();
}
@Test public void testExportedKey() throws Exception {
String sql = ObjectConverterUtil.convertFileToString(UnitTestUtil.getTestDataFile("exported-fk-query.txt"));
Statement s = conn.createStatement();
s.execute(sql);
ResultSet rs = s.getResultSet();
assertTrue(rs.next());
assertEquals("STATUS_ID", rs.getString(4));
assertFalse(rs.next());
}
@Test public void testRegClass() throws Exception {
Statement s = conn.createStatement();
ResultSet rs = s.executeQuery("select '\"pg_catalog.pg_class\"'::regclass");
rs.next();
int oid = rs.getInt(1);
rs = s.executeQuery("select oid from pg_class where relname='pg_class'");
rs.next();
int oid1 = rs.getInt(1);
assertEquals(oid, oid1);
}
@Test public void testApplicationName() throws Exception {
Statement s = conn.createStatement();
checkApplicationName(s, "ODBC");
s.execute("set application_name to other");
checkApplicationName(s, "other");
}
@Test public void testGeometry() throws Exception {
Statement s = conn.createStatement();
s.execute("SELECT ST_GeomFromText('POLYGON ((40 0, 50 50, 0 50, 0 0, 40 0))')");
ResultSet rs = s.getResultSet();
rs.next();
ResultSetMetaData rsmd = rs.getMetaData();
assertEquals("geometry", rsmd.getColumnTypeName(1));
assertEquals("00200000030000000000000001000000054044000000000000000000000000000040490000000000004049000000000000000000000000000040490000000000000000000000000000000000000000000040440000000000000000000000000000", rs.getString(1));
}
@Test public void testConstraintDef() throws Exception {
Statement s = conn.createStatement();
s.execute("SELECT pg_get_constraintdef((select oid from pg_constraint where contype = 'f' and conrelid = (select oid from pg_class where relname = 'Functions')), true)");
ResultSet rs = s.getResultSet();
rs.next();
assertEquals("FOREIGN KEY (VDBName,SchemaName) REFERENCES SYS.Schemas(VDBName,Name)", rs.getString(1));
}
@Test public void testXML() throws Exception {
Statement s = conn.createStatement();
s.execute("SELECT xmlelement(name x)");
ResultSet rs = s.getResultSet();
rs.next();
ResultSetMetaData rsmd = rs.getMetaData();
assertEquals("xml", rsmd.getColumnTypeName(1));
assertEquals("<x></x>", rs.getString(1));
}
private void checkApplicationName(Statement s, String value) throws SQLException {
ResultSet rs = s.executeQuery("show application_name");
rs.next();
assertEquals(value, rs.getString(1));
rs.close();
rs = s.executeQuery("select session_id()");
rs.next();
String sessionId = rs.getString(1);
rs.close();
SessionMetadata current = null;
for (SessionMetadata session : odbcServer.server.getSessionService().getActiveSessions()) {
if (session.getSessionId().equals(sessionId)) {
current = session;
break;
}
}
assertEquals(value, current.getApplicationName());
}
}