Skip to content

Commit 71e76fa

Browse files
committed
Improvement of ResultSet metadata
1 parent 5d545c0 commit 71e76fa

File tree

21 files changed

+342
-59
lines changed

21 files changed

+342
-59
lines changed

client/trino-client/src/main/java/io/trino/client/Column.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,33 +18,80 @@
1818
import com.google.errorprone.annotations.Immutable;
1919

2020
import java.util.Objects;
21+
import java.util.Optional;
2122

2223
import static java.util.Objects.requireNonNull;
2324

2425
@Immutable
2526
public class Column
2627
{
28+
private final Optional<String> catalog;
29+
private final Optional<String> schema;
30+
private final Optional<String> table;
2731
private final String name;
32+
private final Optional<String> label;
2833
private final String type;
2934
private final ClientTypeSignature typeSignature;
3035

36+
public Column(String name, String type, ClientTypeSignature typeSignature)
37+
{
38+
this(Optional.empty(), Optional.empty(), Optional.empty(), name, Optional.of(name), type, typeSignature);
39+
}
40+
41+
public Column(String catalog, String schema, String table, String name, String label, String type, ClientTypeSignature typeSignature)
42+
{
43+
this(Optional.of(catalog), Optional.of(schema), Optional.of(table), name, Optional.of(label), type, typeSignature);
44+
}
45+
3146
@JsonCreator
3247
public Column(
48+
@JsonProperty("catalog") Optional<String> catalog,
49+
@JsonProperty("schema") Optional<String> schema,
50+
@JsonProperty("table") Optional<String> table,
3351
@JsonProperty("name") String name,
52+
@JsonProperty("label") Optional<String> label,
3453
@JsonProperty("type") String type,
3554
@JsonProperty("typeSignature") ClientTypeSignature typeSignature)
3655
{
56+
this.catalog = requireNonNull(catalog, "catalog is null");
57+
this.schema = requireNonNull(schema, "schema is null");
58+
this.table = requireNonNull(table, "table is null");
3759
this.name = requireNonNull(name, "name is null");
60+
this.label = requireNonNull(label, "label is null");
3861
this.type = requireNonNull(type, "type is null");
3962
this.typeSignature = typeSignature;
4063
}
4164

65+
@JsonProperty
66+
public Optional<String> getCatalog()
67+
{
68+
return catalog;
69+
}
70+
71+
@JsonProperty
72+
public Optional<String> getSchema()
73+
{
74+
return schema;
75+
}
76+
77+
@JsonProperty
78+
public Optional<String> getTable()
79+
{
80+
return table;
81+
}
82+
4283
@JsonProperty
4384
public String getName()
4485
{
4586
return name;
4687
}
4788

89+
@JsonProperty
90+
public Optional<String> getLabel()
91+
{
92+
return label;
93+
}
94+
4895
@JsonProperty
4996
public String getType()
5097
{

client/trino-client/src/test/java/io/trino/client/TestQueryResults.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ public class TestQueryResults
2929
" \"id\" : \"20160128_214710_00012_rk68b\",\n" +
3030
" \"infoUri\" : \"http://localhost:54855/query.html?20160128_214710_00012_rk68b\",\n" +
3131
" \"columns\" : [ {\n" +
32+
" \"catalog\" : \"_cat0\",\n" +
33+
" \"schema\" : \"_sch0\",\n" +
34+
" \"table\" : \"_tab0\",\n" +
3235
" \"name\" : \"_col0\",\n" +
36+
" \"label\" : \"_lab0\",\n" +
3337
" \"type\" : \"bigint\",\n" +
3438
" \"typeSignature\" : {\n" +
3539
" \"rawType\" : \"varchar\",\n" +

client/trino-jdbc/src/main/java/io/trino/jdbc/AbstractTrinoResultSet.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1970,11 +1970,11 @@ private static List<ColumnInfo> getColumnInfo(List<Column> columns)
19701970
ImmutableList.Builder<ColumnInfo> list = ImmutableList.builderWithExpectedSize(columns.size());
19711971
for (Column column : columns) {
19721972
ColumnInfo.Builder builder = new ColumnInfo.Builder()
1973-
.setCatalogName("") // TODO
1974-
.setSchemaName("") // TODO
1975-
.setTableName("") // TODO
1973+
.setCatalogName(column.getCatalog().orElse(""))
1974+
.setSchemaName(column.getSchema().orElse(""))
1975+
.setTableName(column.getTable().orElse(""))
19761976
.setColumnLabel(column.getName())
1977-
.setColumnName(column.getName()) // TODO
1977+
.setColumnName(column.getLabel().orElse(column.getName()))
19781978
.setColumnTypeSignature(column.getTypeSignature())
19791979
.setNullable(Nullable.UNKNOWN)
19801980
.setCurrency(false);

client/trino-jdbc/src/test/java/io/trino/jdbc/TestTrinoDatabaseMetaData.java

Lines changed: 152 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package io.trino.execution;
15+
16+
import java.util.Optional;
17+
18+
// XXX: ColumnInfo allows the grouping of all the naming elements necessary to deliver complete ResultSetMetaData (see issue#22306).
19+
public record ColumnInfo(Optional<String> catalog, Optional<String> schema, Optional<String> table, String name, Optional<String> label)
20+
{
21+
// XXX: This constructor is used by the PlanBuilder.output() method and allows you to create ColumnInfo using only a column name.
22+
public ColumnInfo(String name)
23+
{
24+
this(Optional.empty(), Optional.empty(), Optional.empty(), name, Optional.of(name));
25+
}
26+
}

core/trino-main/src/main/java/io/trino/execution/QueryExecution.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import java.util.Queue;
3535
import java.util.function.Consumer;
3636

37+
import static com.google.common.collect.ImmutableList.toImmutableList;
3738
import static java.util.Objects.requireNonNull;
3839

3940
public interface QueryExecution
@@ -99,22 +100,27 @@ interface QueryExecutionFactory<T extends QueryExecution>
99100
*/
100101
class QueryOutputInfo
101102
{
102-
private final List<String> columnNames;
103+
private final List<ColumnInfo> columnInfos;
103104
private final List<Type> columnTypes;
104105
private final Queue<ExchangeInput> inputsQueue;
105106
private final boolean noMoreInputs;
106107

107-
public QueryOutputInfo(List<String> columnNames, List<Type> columnTypes, Queue<ExchangeInput> inputsQueue, boolean noMoreInputs)
108+
public QueryOutputInfo(List<ColumnInfo> columnInfos, List<Type> columnTypes, Queue<ExchangeInput> inputsQueue, boolean noMoreInputs)
108109
{
109-
this.columnNames = ImmutableList.copyOf(requireNonNull(columnNames, "columnNames is null"));
110+
this.columnInfos = ImmutableList.copyOf(requireNonNull(columnInfos, "columnInfos is null"));
110111
this.columnTypes = ImmutableList.copyOf(requireNonNull(columnTypes, "columnTypes is null"));
111112
this.inputsQueue = requireNonNull(inputsQueue, "inputsQueue is null");
112113
this.noMoreInputs = noMoreInputs;
113114
}
114115

116+
public List<ColumnInfo> getColumnInfos()
117+
{
118+
return columnInfos;
119+
}
120+
115121
public List<String> getColumnNames()
116122
{
117-
return columnNames;
123+
return columnInfos.stream().map(ColumnInfo::name).collect(toImmutableList());
118124
}
119125

120126
public List<Type> getColumnTypes()

core/trino-main/src/main/java/io/trino/execution/QueryStateMachine.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,9 +1010,9 @@ public void outputTaskFailed(TaskId taskId, Throwable failure)
10101010
outputManager.outputTaskFailed(taskId, failure);
10111011
}
10121012

1013-
public void setColumns(List<String> columnNames, List<Type> columnTypes)
1013+
public void setColumns(List<ColumnInfo> columnInfos, List<Type> columnTypes)
10141014
{
1015-
outputManager.setColumns(columnNames, columnTypes);
1015+
outputManager.setColumns(columnInfos, columnTypes);
10161016
}
10171017

10181018
public void updateInputsForQueryResults(List<ExchangeInput> inputs, boolean noMoreInputs)
@@ -1637,7 +1637,7 @@ public static class QueryOutputManager
16371637
private Optional<Consumer<QueryOutputInfo>> listener = Optional.empty();
16381638

16391639
@GuardedBy("this")
1640-
private List<String> columnNames;
1640+
private List<ColumnInfo> columnInfos;
16411641
@GuardedBy("this")
16421642
private List<Type> columnTypes;
16431643
@GuardedBy("this")
@@ -1670,17 +1670,17 @@ public void setOutputInfoListener(Consumer<QueryOutputInfo> listener)
16701670
fireStateChangedIfReady(queryOutputInfo, Optional.of(listener));
16711671
}
16721672

1673-
public void setColumns(List<String> columnNames, List<Type> columnTypes)
1673+
public void setColumns(List<ColumnInfo> columnInfos, List<Type> columnTypes)
16741674
{
1675-
requireNonNull(columnNames, "columnNames is null");
1675+
requireNonNull(columnInfos, "columnInfos is null");
16761676
requireNonNull(columnTypes, "columnTypes is null");
1677-
checkArgument(columnNames.size() == columnTypes.size(), "columnNames and columnTypes must be the same size");
1677+
checkArgument(columnInfos.size() == columnTypes.size(), "columnInfos and columnTypes must be the same size");
16781678

16791679
Optional<QueryOutputInfo> queryOutputInfo;
16801680
Optional<Consumer<QueryOutputInfo>> listener;
16811681
synchronized (this) {
1682-
checkState(this.columnNames == null && this.columnTypes == null, "output fields already set");
1683-
this.columnNames = ImmutableList.copyOf(columnNames);
1682+
checkState(this.columnInfos == null && this.columnTypes == null, "output fields already set");
1683+
this.columnInfos = ImmutableList.copyOf(columnInfos);
16841684
this.columnTypes = ImmutableList.copyOf(columnTypes);
16851685

16861686
queryOutputInfo = getQueryOutputInfo();
@@ -1755,10 +1755,10 @@ public void outputTaskFailed(TaskId taskId, Throwable failure)
17551755

17561756
private synchronized Optional<QueryOutputInfo> getQueryOutputInfo()
17571757
{
1758-
if (columnNames == null || columnTypes == null) {
1758+
if (columnInfos == null || columnTypes == null) {
17591759
return Optional.empty();
17601760
}
1761-
return Optional.of(new QueryOutputInfo(columnNames, columnTypes, inputsQueue, noMoreInputs));
1761+
return Optional.of(new QueryOutputInfo(columnInfos, columnTypes, inputsQueue, noMoreInputs));
17621762
}
17631763

17641764
private void fireStateChangedIfReady(Optional<QueryOutputInfo> info, Optional<Consumer<QueryOutputInfo>> listener)

core/trino-main/src/main/java/io/trino/execution/SqlQueryExecution.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,7 @@ private void planDistribution(PlanRoot plan, CachingTableStatsProvider tableStat
524524
// record output field
525525
PlanFragment rootFragment = plan.getRoot().getFragment();
526526
stateMachine.setColumns(
527-
((OutputNode) rootFragment.getRoot()).getColumnNames(),
527+
((OutputNode) rootFragment.getRoot()).getColumnInfos(),
528528
rootFragment.getTypes());
529529

530530
RetryPolicy retryPolicy = getRetryPolicy(getSession());

core/trino-main/src/main/java/io/trino/server/protocol/OutputColumn.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,16 @@
1313
*/
1414
package io.trino.server.protocol;
1515

16+
import io.trino.execution.ColumnInfo;
1617
import io.trino.spi.type.Type;
1718

1819
import static java.util.Objects.requireNonNull;
1920

20-
public record OutputColumn(int sourcePageChannel, String columnName, Type type)
21+
public record OutputColumn(int sourcePageChannel, ColumnInfo columnInfo, Type type)
2122
{
2223
public OutputColumn
2324
{
24-
requireNonNull(columnName, "columnName is null");
25+
requireNonNull(columnInfo, "columnInfo is null");
2526
requireNonNull(type, "type is null");
2627

2728
if (sourcePageChannel < 0) {

core/trino-main/src/main/java/io/trino/server/protocol/ProtocolUtil.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import io.trino.execution.BasicStageInfo;
3030
import io.trino.execution.BasicStageStats;
3131
import io.trino.execution.BasicStagesInfo;
32+
import io.trino.execution.ColumnInfo;
3233
import io.trino.execution.ExecutionFailureInfo;
3334
import io.trino.execution.QueryState;
3435
import io.trino.execution.StageId;
@@ -53,6 +54,7 @@
5354

5455
import java.util.HashSet;
5556
import java.util.List;
57+
import java.util.Optional;
5658
import java.util.Set;
5759
import java.util.stream.Collectors;
5860

@@ -75,10 +77,20 @@ public final class ProtocolUtil
7577
private ProtocolUtil() {}
7678

7779
public static Column createColumn(String name, Type type, boolean supportsParametricDateTime)
80+
{
81+
return createColumn(Optional.empty(), Optional.empty(), Optional.empty(), name, Optional.of(name), type, supportsParametricDateTime);
82+
}
83+
84+
public static Column createColumn(ColumnInfo columnInfo, Type type, boolean supportsParametricDateTime)
85+
{
86+
return createColumn(columnInfo.catalog(), columnInfo.schema(), columnInfo.table(), columnInfo.name(), columnInfo.label(), type, supportsParametricDateTime);
87+
}
88+
89+
public static Column createColumn(Optional<String> catalog, Optional<String> schema, Optional<String> table, String name, Optional<String> label, Type type, boolean supportsParametricDateTime)
7890
{
7991
String formatted = formatType(TypeSignatureTranslator.toSqlType(type), supportsParametricDateTime);
8092

81-
return new Column(name, formatted, toClientTypeSignature(type.getTypeSignature(), supportsParametricDateTime));
93+
return new Column(catalog, schema, table, name, label, formatted, toClientTypeSignature(type.getTypeSignature(), supportsParametricDateTime));
8294
}
8395

8496
private static String formatType(DataType type, boolean supportsParametricDateTime)

0 commit comments

Comments
 (0)