You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by rv...@apache.org on 2013/06/12 22:39:21 UTC

svn commit: r1492413 - in /jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results: AskResults.java TripleIteratorResults.java TripleListResults.java metadata/AskResultsMetadata.java metadata/TripleResultsMetadata.java

Author: rvesse
Date: Wed Jun 12 20:39:20 2013
New Revision: 1492413

URL: http://svn.apache.org/r1492413
Log:
Refactoring to make it possible to customize the column names for ASK, CONSTRUCT and DESCRIBE results

Modified:
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/AskResults.java
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/TripleIteratorResults.java
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/TripleListResults.java
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/AskResultsMetadata.java
    jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/TripleResultsMetadata.java

Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/AskResults.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/AskResults.java?rev=1492413&r1=1492412&r2=1492413&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/AskResults.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/AskResults.java Wed Jun 12 20:39:20 2013
@@ -42,6 +42,7 @@ public class AskResults extends JenaResu
     private int currRow = 0;
     private boolean needsCommit = false;
     private AskResultsMetadata metadata;
+    private String columnLabel;
 
     /**
      * Creates a new ASK result
@@ -55,6 +56,7 @@ public class AskResults extends JenaResu
         this.result = result;
         this.needsCommit = commit;
         this.metadata = statement.getJenaConnection().applyPostProcessors(new AskResultsMetadata(this));
+        this.columnLabel = this.metadata.getColumnLabel(AskResultsMetadata.COLUMN_INDEX_ASK);
     }
 
     public boolean absolute(int row) throws SQLException {
@@ -91,7 +93,7 @@ public class AskResults extends JenaResu
     }
 
     public int findColumn(String columnLabel) throws SQLException {
-        if (columnLabel == AskResultsMetadata.COLUMN_LABEL_ASK) return 1;
+        if (this.columnLabel.equals(columnLabel)) return 1;
         throw new SQLException("The given column does not exist in this result set");
     }
 
@@ -187,7 +189,7 @@ public class AskResults extends JenaResu
 
     @Override
     protected String findColumnLabel(int columnIndex) throws SQLException {
-        if (columnIndex == 1) return AskResultsMetadata.COLUMN_LABEL_ASK;
+        if (columnIndex == AskResultsMetadata.COLUMN_INDEX_ASK) return this.columnLabel;
         throw new SQLException("Column Index is out of bounds");
     }
 
@@ -195,7 +197,7 @@ public class AskResults extends JenaResu
     protected Node getNode(String columnLabel) throws SQLException {
         if (this.isClosed()) throw new SQLException("Result Set is closed");
         if (this.currRow != 1) throw new SQLException("Not currently at a row");
-        if (AskResultsMetadata.COLUMN_LABEL_ASK.equals(columnLabel)) {
+        if (this.columnLabel.equals(columnLabel)) {
             return NodeFactory.createLiteral(Boolean.toString(this.result), XSDDatatype.XSDboolean);
         } else {
             throw new SQLException("The given column does not exist in the result set");
@@ -206,7 +208,7 @@ public class AskResults extends JenaResu
     public boolean getBoolean(String columnLabel) throws SQLException {
         if (this.isClosed()) throw new SQLException("Result Set is closed");
         if (this.currRow != 1) throw new SQLException("Not currently at a row");
-        if (AskResultsMetadata.COLUMN_LABEL_ASK.equals(columnLabel)) {
+        if (this.columnLabel.equals(columnLabel)) {
             this.setNull(false);
             return this.result;
         } else {

Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/TripleIteratorResults.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/TripleIteratorResults.java?rev=1492413&r1=1492412&r2=1492413&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/TripleIteratorResults.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/TripleIteratorResults.java Wed Jun 12 20:39:20 2013
@@ -40,8 +40,9 @@ import com.hp.hpl.jena.query.QueryExecut
 public class TripleIteratorResults extends StreamedResults<Triple> {
 
     private TripleResultsMetadata metadata;
-
     private PeekIterator<Triple> triples;
+    private String subjColumn, predColumn, objColumn;
+    private int numColumns;
 
     /**
      * Creates a new result set which is backed by a triple iterator
@@ -64,16 +65,23 @@ public class TripleIteratorResults exten
             throw new SQLException("Triple Iterator cannot be null");
         this.triples = PeekIterator.create(ts);
         this.metadata = statement.getJenaConnection().applyPostProcessors(new TripleResultsMetadata(this, this.triples));
+        this.numColumns = this.metadata.getColumnCount();
+        this.subjColumn = this.metadata.getSubjectColumnLabel();
+        this.predColumn = this.metadata.getPredicateColumnLabel();
+        this.objColumn = this.metadata.getObjectColumnLabel();
     }
 
     @Override
     public int findColumn(String columnLabel) throws SQLException {
-        if (TripleResultsMetadata.COLUMN_LABEL_SUBJECT.equals(columnLabel)) {
+        if (this.subjColumn != null && this.subjColumn.equals(columnLabel)) {
             return TripleResultsMetadata.COLUMN_INDEX_SUBJECT;
-        } else if (TripleResultsMetadata.COLUMN_LABEL_PREDICATE.equals(columnLabel)) {
-            return TripleResultsMetadata.COLUMN_INDEX_PREDICATE;
-        } else if (TripleResultsMetadata.COLUMN_LABEL_OBJECT.equals(columnLabel)) {
-            return TripleResultsMetadata.COLUMN_INDEX_OBJECT;
+        } else if (this.predColumn != null && this.predColumn.equals(columnLabel)) {
+            return this.subjColumn == null ? TripleResultsMetadata.COLUMN_INDEX_SUBJECT
+                    : TripleResultsMetadata.COLUMN_INDEX_PREDICATE;
+        } else if (this.objColumn != null && this.objColumn.equals(columnLabel)) {
+            return this.subjColumn == null && this.predColumn == null ? TripleResultsMetadata.COLUMN_INDEX_SUBJECT
+                    : (this.subjColumn == null || this.predColumn == null ? TripleResultsMetadata.COLUMN_INDEX_PREDICATE
+                            : TripleResultsMetadata.COLUMN_INDEX_OBJECT);
         } else {
             throw new SQLException("Column " + columnLabel + " does not exist in these results");
         }
@@ -126,14 +134,14 @@ public class TripleIteratorResults exten
     protected String findColumnLabel(int columnIndex) throws SQLException {
         if (this.isClosed())
             throw new SQLException("Result Set is closed");
-        if (columnIndex >= 1 && columnIndex <= TripleResultsMetadata.NUM_COLUMNS) {
+        if (columnIndex >= 1 && columnIndex <= this.numColumns) {
             switch (columnIndex) {
             case TripleResultsMetadata.COLUMN_INDEX_SUBJECT:
-                return TripleResultsMetadata.COLUMN_LABEL_SUBJECT;
+                return this.subjColumn != null ? this.subjColumn : (this.predColumn != null ? this.predColumn : this.objColumn);
             case TripleResultsMetadata.COLUMN_INDEX_PREDICATE:
-                return TripleResultsMetadata.COLUMN_LABEL_PREDICATE;
+                return this.subjColumn != null && this.predColumn != null ? this.predColumn : this.objColumn;
             case TripleResultsMetadata.COLUMN_INDEX_OBJECT:
-                return TripleResultsMetadata.COLUMN_LABEL_OBJECT;
+                return this.objColumn;
             default:
                 throw new SQLException("Column Index is out of bounds");
             }
@@ -149,11 +157,11 @@ public class TripleIteratorResults exten
         if (this.getCurrentRow() == null)
             throw new SQLException("Not currently at a row");
         Triple t = this.getCurrentRow();
-        if (TripleResultsMetadata.COLUMN_LABEL_SUBJECT.equals(columnLabel)) {
+        if (this.subjColumn != null && this.subjColumn.equals(columnLabel)) {
             return t.getSubject();
-        } else if (TripleResultsMetadata.COLUMN_LABEL_PREDICATE.equals(columnLabel)) {
+        } else if (this.predColumn != null && this.predColumn.equals(columnLabel)) {
             return t.getPredicate();
-        } else if (TripleResultsMetadata.COLUMN_LABEL_OBJECT.equals(columnLabel)) {
+        } else if (this.objColumn != null && this.objColumn.equals(columnLabel)) {
             return t.getObject();
         } else {
             throw new SQLException("Unknown column label");

Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/TripleListResults.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/TripleListResults.java?rev=1492413&r1=1492412&r2=1492413&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/TripleListResults.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/TripleListResults.java Wed Jun 12 20:39:20 2013
@@ -39,6 +39,8 @@ public class TripleListResults extends M
 
     private TripleResultsMetadata metadata;
     private List<Triple> triples;
+    private String subjColumn, predColumn, objColumn;
+    private int numColumns;
 
     /**
      * Creates a new result set which is backed by a triple iterator
@@ -59,17 +61,25 @@ public class TripleListResults extends M
         if (ts == null)
             throw new SQLException("Triple Iterator cannot be null");
         this.triples = ts;
-        this.metadata = statement.getJenaConnection().applyPostProcessors(new TripleResultsMetadata(this, new PeekIterator<Triple>(ts.iterator())));
+        this.metadata = statement.getJenaConnection().applyPostProcessors(
+                new TripleResultsMetadata(this, new PeekIterator<Triple>(ts.iterator())));
+        this.numColumns = this.metadata.getColumnCount();
+        this.subjColumn = this.metadata.getSubjectColumnLabel();
+        this.predColumn = this.metadata.getPredicateColumnLabel();
+        this.objColumn = this.metadata.getObjectColumnLabel();
     }
 
     @Override
     public int findColumn(String columnLabel) throws SQLException {
-        if (TripleResultsMetadata.COLUMN_LABEL_SUBJECT.equals(columnLabel)) {
+        if (this.subjColumn != null && this.subjColumn.equals(columnLabel)) {
             return TripleResultsMetadata.COLUMN_INDEX_SUBJECT;
-        } else if (TripleResultsMetadata.COLUMN_LABEL_PREDICATE.equals(columnLabel)) {
-            return TripleResultsMetadata.COLUMN_INDEX_PREDICATE;
-        } else if (TripleResultsMetadata.COLUMN_LABEL_OBJECT.equals(columnLabel)) {
-            return TripleResultsMetadata.COLUMN_INDEX_OBJECT;
+        } else if (this.predColumn != null && this.predColumn.equals(columnLabel)) {
+            return this.subjColumn == null ? TripleResultsMetadata.COLUMN_INDEX_SUBJECT
+                    : TripleResultsMetadata.COLUMN_INDEX_PREDICATE;
+        } else if (this.objColumn != null && this.objColumn.equals(columnLabel)) {
+            return this.subjColumn == null && this.predColumn == null ? TripleResultsMetadata.COLUMN_INDEX_SUBJECT
+                    : (this.subjColumn == null || this.predColumn == null ? TripleResultsMetadata.COLUMN_INDEX_PREDICATE
+                            : TripleResultsMetadata.COLUMN_INDEX_OBJECT);
         } else {
             throw new SQLException("Column " + columnLabel + " does not exist in these results");
         }
@@ -86,17 +96,17 @@ public class TripleListResults extends M
     protected Triple moveNext() throws SQLException {
         return this.triples.get(this.getRow());
     }
-    
+
     @Override
     protected boolean hasPrevious() throws SQLException {
         return this.getRow() > 1;
     }
-    
+
     @Override
     protected Triple movePrevious() throws SQLException {
         return this.triples.get(this.getRow() - 1);
     }
-    
+
     @Override
     protected int getTotalRows() {
         return this.triples.size();
@@ -118,14 +128,14 @@ public class TripleListResults extends M
     protected String findColumnLabel(int columnIndex) throws SQLException {
         if (this.isClosed())
             throw new SQLException("Result Set is closed");
-        if (columnIndex >= 1 && columnIndex <= TripleResultsMetadata.NUM_COLUMNS) {
+        if (columnIndex >= 1 && columnIndex <= this.numColumns) {
             switch (columnIndex) {
             case TripleResultsMetadata.COLUMN_INDEX_SUBJECT:
-                return TripleResultsMetadata.COLUMN_LABEL_SUBJECT;
+                return this.subjColumn != null ? this.subjColumn : (this.predColumn != null ? this.predColumn : this.objColumn);
             case TripleResultsMetadata.COLUMN_INDEX_PREDICATE:
-                return TripleResultsMetadata.COLUMN_LABEL_PREDICATE;
+                return this.subjColumn != null && this.predColumn != null ? this.predColumn : this.objColumn;
             case TripleResultsMetadata.COLUMN_INDEX_OBJECT:
-                return TripleResultsMetadata.COLUMN_LABEL_OBJECT;
+                return this.objColumn;
             default:
                 throw new SQLException("Column Index is out of bounds");
             }
@@ -141,11 +151,11 @@ public class TripleListResults extends M
         if (this.getCurrentRow() == null)
             throw new SQLException("Not currently at a row");
         Triple t = this.getCurrentRow();
-        if (TripleResultsMetadata.COLUMN_LABEL_SUBJECT.equals(columnLabel)) {
+        if (this.subjColumn != null && this.subjColumn.equals(columnLabel)) {
             return t.getSubject();
-        } else if (TripleResultsMetadata.COLUMN_LABEL_PREDICATE.equals(columnLabel)) {
+        } else if (this.predColumn != null && this.predColumn.equals(columnLabel)) {
             return t.getPredicate();
-        } else if (TripleResultsMetadata.COLUMN_LABEL_OBJECT.equals(columnLabel)) {
+        } else if (this.objColumn != null && this.objColumn.equals(columnLabel)) {
             return t.getObject();
         } else {
             throw new SQLException("Unknown column label");

Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/AskResultsMetadata.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/AskResultsMetadata.java?rev=1492413&r1=1492412&r2=1492413&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/AskResultsMetadata.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/AskResultsMetadata.java Wed Jun 12 20:39:20 2013
@@ -38,30 +38,49 @@ import org.apache.jena.jdbc.results.meta
 public class AskResultsMetadata extends JenaResultsMetadata {
 
     /**
-     * Constant for the ASK results column label
+     * Constant for the default ASK results column label
      */
     public static final String COLUMN_LABEL_ASK = "ASK";
-    
-    private static ColumnInfo[] COLUMNS;
-    
+
     /**
-     * Gets the columns for ASK results
-     * @return Column Information
-     * @throws SQLException
+     * Constant for the only column index for ASK queries
      */
-    private static synchronized ColumnInfo[] getColumns() throws SQLException {
-        if (COLUMNS == null) {
-            COLUMNS = new ColumnInfo[] { new BooleanColumn(COLUMN_LABEL_ASK, columnNoNulls) };
-        }
-        return COLUMNS;
+    public static final int COLUMN_INDEX_ASK = 1;
+
+    private static final ColumnInfo[] getColumns() throws SQLException {
+        return getColumns(COLUMN_LABEL_ASK);
     }
-    
+
+    private static final ColumnInfo[] getColumns(String label) throws SQLException {
+        if (label == null)
+            label = COLUMN_LABEL_ASK;
+        return new ColumnInfo[] { new BooleanColumn(label, columnNoNulls) };
+    }
+
     /**
      * Creates new ASK results metadata
-     * @param results Results
-     * @throws SQLException Thrown if the metadata cannot be created
+     * 
+     * @param results
+     *            Results
+     * @throws SQLException
+     *             Thrown if the metadata cannot be created
      */
     public AskResultsMetadata(JenaResultSet results) throws SQLException {
         super(results, AskResultsMetadata.getColumns());
     }
+
+    /**
+     * Creates new ASK results metadata
+     * 
+     * @param metadata
+     *            Metadata
+     * @param label
+     *            Label to give the single column
+     * 
+     * @throws SQLException
+     *             Thrown if the metadata cannot be created
+     */
+    public AskResultsMetadata(AskResultsMetadata metadata, String label) throws SQLException {
+        super(metadata.getJenaResultSet(), AskResultsMetadata.getColumns(label));
+    }
 }

Modified: jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/TripleResultsMetadata.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/TripleResultsMetadata.java?rev=1492413&r1=1492412&r2=1492413&view=diff
==============================================================================
--- jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/TripleResultsMetadata.java (original)
+++ jena/Experimental/jena-jdbc/jena-jdbc-core/src/main/java/org/apache/jena/jdbc/results/metadata/TripleResultsMetadata.java Wed Jun 12 20:39:20 2013
@@ -41,31 +41,31 @@ import com.hp.hpl.jena.graph.Triple;
  * 
  */
 public class TripleResultsMetadata extends JenaResultsMetadata {
-    
+
     private static final Logger LOGGER = LoggerFactory.getLogger(TripleResultsMetadata.class);
 
     /**
-     * Constant for the subject column label
+     * Constant for the default subject column label
      */
     public static final String COLUMN_LABEL_SUBJECT = "Subject";
     /**
-     * Constant for the predicate column label
+     * Constant for the default predicate column label
      */
     public static final String COLUMN_LABEL_PREDICATE = "Predicate";
     /**
-     * Constant for the object column label
+     * Constant for the default object column label
      */
     public static final String COLUMN_LABEL_OBJECT = "Object";
     /**
-     * Constant for the subject column index
+     * Constant for the subject column index (assuming no columns are omitted)
      */
     public static final int COLUMN_INDEX_SUBJECT = 1;
     /**
-     * Constant for the predicate column index
+     * Constant for the predicate column index (assuming no columns are omitted)
      */
     public static final int COLUMN_INDEX_PREDICATE = 2;
     /**
-     * Constant for the object column index
+     * Constant for the object column index (assuming no columns are omitted)
      */
     public static final int COLUMN_INDEX_OBJECT = 3;
     /**
@@ -73,28 +73,85 @@ public class TripleResultsMetadata exten
      */
     public static final int NUM_COLUMNS = 3;
 
+    private PeekIterator<Triple> ts;
+    private String subjColumn, predColumn, objColumn;
+
     /**
-     * Internal constant for the column names for triple result columns
+     * Gets the columns for CONSTRUCT/DESCRIBE results
+     * 
+     * @param results
+     *            Results
+     * @param ts
+     *            Underlying triples
+     * 
+     * @return Column Information
+     * @throws SQLException
      */
-    private static final String[] COLUMN_NAMES = new String[] { COLUMN_LABEL_SUBJECT, COLUMN_LABEL_PREDICATE, COLUMN_LABEL_OBJECT };
+    private static ColumnInfo[] makeColumns(JenaResultSet results, PeekIterator<Triple> ts) throws SQLException {
+        return makeColumns(results, ts, COLUMN_LABEL_SUBJECT, COLUMN_LABEL_PREDICATE, COLUMN_LABEL_OBJECT);
+    }
 
     /**
-     * Gets the columns for ASK results
+     * Gets the columns for CONSTRUCT/DESCRIBE results
+     * 
+     * @param results
+     *            Results
+     * @param ts
+     *            Underlying triples
+     * @param subjLabel
+     *            Label for subject column, use {@code null} to omit the subject
+     *            column
+     * @param predLabel
+     *            Label for predicate column, use {@code null} to omit the
+     *            predicate column
+     * @param objLabel
+     *            Label for object column, use {@code null} to omit the object
+     *            column
      * 
      * @return Column Information
      * @throws SQLException
      */
-    private static ColumnInfo[] makeColumns(JenaResultSet results, PeekIterator<Triple> ts) throws SQLException {
-        ColumnInfo[] columns = new ColumnInfo[NUM_COLUMNS];
+    private static ColumnInfo[] makeColumns(JenaResultSet results, PeekIterator<Triple> ts, String subjLabel, String predLabel,
+            String objLabel) throws SQLException {
+        int numColumns = 0;
+        if (subjLabel != null)
+            numColumns++;
+        if (predLabel != null)
+            numColumns++;
+        if (objLabel != null)
+            numColumns++;
+        ColumnInfo[] columns = new ColumnInfo[numColumns];
+
+        // Figure out column names
+        String[] names = new String[numColumns];
+        names[0] = subjLabel != null ? subjLabel : (predLabel != null ? predLabel : objLabel);
+        if (numColumns > 1) {
+            names[1] = subjLabel != null && predLabel != null ? predLabel : objLabel;
+        }
+        if (numColumns == 3) {
+            names[2] = objLabel;
+        }
 
         int level = JdbcCompatibility.normalizeLevel(results.getJdbcCompatibilityLevel());
         boolean columnsAsStrings = JdbcCompatibility.shouldTypeColumnsAsString(level);
         boolean columnsDetected = JdbcCompatibility.shouldDetectColumnTypes(level);
 
         Triple t = null;
+        Node[] values = new Node[numColumns];
         if (columnsDetected) {
             if (ts.hasNext()) {
+                // Need to peek the first Triple and grab appropriate nodes
                 t = ts.peek();
+                if (numColumns == NUM_COLUMNS) {
+                    values[0] = t.getSubject();
+                    values[1] = t.getPredicate();
+                    values[2] = t.getObject();
+                } else {
+                    values[0] = subjLabel != null ? t.getSubject() : (predLabel != null ? t.getPredicate() : t.getObject());
+                    if (numColumns > 1) {
+                        values[1] = subjLabel != null && predLabel != null ? t.getPredicate() : t.getObject();
+                    }
+                }
             } else {
                 // If we were supposed to detect columns but there is no data
                 // available then we will just fallback to typing everything as
@@ -108,18 +165,19 @@ public class TripleResultsMetadata exten
             if (!columnsAsStrings && !columnsDetected) {
                 // Low compatibility, report columns as being typed as
                 // JAVA_OBJECT with ARQ Node as the column class
-                columns[i] = new SparqlColumnInfo(COLUMN_NAMES[i], Types.JAVA_OBJECT, columnNoNulls);
-                LOGGER.info("Low JDBC compatibility, column " + COLUMN_NAMES[i] + " is being typed as Node");
+                columns[i] = new SparqlColumnInfo(names[i], Types.JAVA_OBJECT, columnNoNulls);
+                LOGGER.info("Low JDBC compatibility, column " + names[i] + " is being typed as Node");
             } else if (columnsAsStrings) {
                 // Medium compatibility, report columns as being typed as
                 // NVARChar with String as the column class
-                columns[i] = new StringColumn(COLUMN_NAMES[i], columnNoNulls);
-                LOGGER.info("Medium JDBC compatibility, column " + COLUMN_NAMES[i] + " is being typed as String");
+                columns[i] = new StringColumn(names[i], columnNoNulls);
+                LOGGER.info("Medium JDBC compatibility, column " + names[i] + " is being typed as String");
             } else if (columnsDetected) {
                 // High compatibility, detect columns types based on first row
                 // of results
-                columns[i] = JdbcCompatibility.detectColumnType(COLUMN_NAMES[i], getValue(t, i), false);
-                LOGGER.info("High compatibility, column " + COLUMN_NAMES[i] + " was detected as being of type " + columns[i].getClassName());
+                columns[i] = JdbcCompatibility.detectColumnType(names[i], values[i], false);
+                LOGGER.info("High compatibility, column " + names[i] + " was detected as being of type "
+                        + columns[i].getClassName());
             } else {
                 throw new SQLFeatureNotSupportedException("Unknown JDBC compatibility level was set");
             }
@@ -128,19 +186,6 @@ public class TripleResultsMetadata exten
         return columns;
     }
 
-    private static Node getValue(Triple t, int i) {
-        switch (i) {
-        case 0:
-            return t.getSubject();
-        case 1:
-            return t.getPredicate();
-        case 2:
-            return t.getObject();
-        default:
-            return null;
-        }
-    }
-
     /**
      * Creates new results metadata for triple (CONSTRUCT/DESCRIBE) results
      * 
@@ -153,6 +198,10 @@ public class TripleResultsMetadata exten
      */
     public TripleResultsMetadata(JenaResultSet results, PeekIterator<Triple> ts) throws SQLException {
         super(results, makeColumns(results, ts));
+        this.subjColumn = COLUMN_LABEL_SUBJECT;
+        this.predColumn = COLUMN_LABEL_PREDICATE;
+        this.objColumn = COLUMN_LABEL_OBJECT;
+        this.ts = ts;
     }
 
     /**
@@ -169,4 +218,124 @@ public class TripleResultsMetadata exten
         this(results, PeekIterator.create(ts));
     }
 
+    /**
+     * Creates new results metadata for triple (CONSTRUCT/DESCRIBE) results
+     * 
+     * @param results
+     *            Result Set
+     * @param ts
+     *            Triple iterator
+     * @param subjLabel
+     *            Label for subject column, use {@code null} to omit the subject
+     *            column
+     * @param predLabel
+     *            Label for predicate column, use {@code null} to omit the
+     *            predicate column
+     * @param objLabel
+     *            Label for object column, use {@code null} to omit the object
+     *            column
+     * @throws SQLException
+     *             Thrown if the metadata cannot be created
+     */
+    public TripleResultsMetadata(JenaResultSet results, PeekIterator<Triple> ts, String subjLabel, String predLabel,
+            String objLabel) throws SQLException {
+        super(results, makeColumns(results, ts, subjLabel, predLabel, objLabel));
+        this.subjColumn = subjLabel;
+        this.predColumn = predLabel;
+        this.objColumn = objLabel;
+        this.ts = ts;
+    }
+
+    /**
+     * Creates new results metadata for triple (CONSTRUCT/DESCRIBE) results
+     * 
+     * @param results
+     *            Result Set
+     * @param ts
+     *            Triple iterator
+     * @param subjLabel
+     *            Label for subject column, use {@code null} to omit the subject
+     *            column
+     * @param predLabel
+     *            Label for predicate column, use {@code null} to omit the
+     *            predicate column
+     * @param objLabel
+     *            Label for object column, use {@code null} to omit the object
+     *            column
+     * @throws SQLException
+     *             Thrown if the metadata cannot be created
+     */
+    public TripleResultsMetadata(JenaResultSet results, Iterator<Triple> ts, String subjLabel, String predLabel, String objLabel)
+            throws SQLException {
+        this(results, PeekIterator.create(ts), subjLabel, predLabel, objLabel);
+    }
+
+    /**
+     * Creates new results metadata for triple (CONSTRUCT/DESCRIBE) results
+     * 
+     * @param metadata
+     *            Metadata
+     * @param subjLabel
+     *            Label for subject column, use {@code null} to omit the subject
+     *            column
+     * @param predLabel
+     *            Label for predicate column, use {@code null} to omit the
+     *            predicate column
+     * @param objLabel
+     *            Label for object column, use {@code null} to omit the object
+     *            column
+     * @throws SQLException
+     *             Thrown if the metadata cannot be created
+     */
+    public TripleResultsMetadata(TripleResultsMetadata metadata, String subjLabel, String predLabel, String objLabel)
+            throws SQLException {
+        this(metadata.getJenaResultSet(), metadata.ts, subjLabel, predLabel, objLabel);
+    }
+
+    /**
+     * Creates new results metadata for triple (CONSTRUCT/DESCRIBE) results
+     * 
+     * @param metadata
+     *            Metadata
+     * @param columns
+     *            Column Information
+     * @throws SQLException
+     *             Thrown if the metadata cannot be created
+     */
+    public TripleResultsMetadata(TripleResultsMetadata metadata, ColumnInfo[] columns) throws SQLException {
+        super(metadata.getJenaResultSet(), columns);
+        if (metadata.getColumnCount() != columns.length)
+            throw new SQLException(
+                    "Must provide same number of columns as in original metadata, to filter down included columns use the TripleResultsMetadata(TripleResultsMetadata, String, String, String) constructor first");
+        this.subjColumn = metadata.getSubjectColumnLabel();
+        this.predColumn = metadata.getPredicateColumnLabel();
+        this.objColumn = metadata.getObjectColumnLabel();
+    }
+
+    /**
+     * Gets the subject column label
+     * 
+     * @return Column label or {@code null} if the column is omitted
+     */
+    public String getSubjectColumnLabel() {
+        return this.subjColumn;
+    }
+
+    /**
+     * Gets the predicate column label
+     * 
+     * @return Column label or {@code null} if the column is omitted
+     */
+    public String getPredicateColumnLabel() {
+        return this.predColumn;
+    }
+
+    /**
+     * Gets the object column label
+     * 
+     * @return Column label or {@code null} if the column is omitted
+     */
+    public String getObjectColumnLabel() {
+        return this.objColumn;
+    }
 }