Skip to content

Commit 2277abd

Browse files
authored
Merge branch 'master' into new-rsmd
2 parents b2ac7eb + 925298b commit 2277abd

File tree

101 files changed

+2191
-188
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+2191
-188
lines changed

core/trino-grammar/src/main/antlr4/io/trino/grammar/sql/SqlBase.g4

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ statement
8787
RENAME COLUMN (IF EXISTS)? from=qualifiedName TO to=identifier #renameColumn
8888
| ALTER TABLE (IF EXISTS)? tableName=qualifiedName
8989
DROP COLUMN (IF EXISTS)? column=qualifiedName #dropColumn
90+
| ALTER TABLE (IF EXISTS)? tableName=qualifiedName
91+
ALTER COLUMN columnName=qualifiedName SET DEFAULT literal #setDefaultValue
92+
| ALTER TABLE (IF EXISTS)? tableName=qualifiedName
93+
ALTER COLUMN columnName=qualifiedName DROP DEFAULT #dropDefaultValue
9094
| ALTER TABLE (IF EXISTS)? tableName=qualifiedName
9195
ALTER COLUMN columnName=qualifiedName SET DATA TYPE type #setColumnType
9296
| ALTER TABLE (IF EXISTS)? tableName=qualifiedName

core/trino-main/src/main/java/io/trino/event/QueryMonitor.java

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import io.trino.operator.TableFinishInfo;
4747
import io.trino.operator.TaskStats;
4848
import io.trino.server.BasicQueryInfo;
49+
import io.trino.server.BasicQueryStats;
4950
import io.trino.spi.ErrorCode;
5051
import io.trino.spi.QueryId;
5152
import io.trino.spi.eventlistener.DoubleSymmetricDistribution;
@@ -182,6 +183,7 @@ public void queryCreatedEvent(BasicQueryInfo queryInfo)
182183

183184
public void queryImmediateFailureEvent(BasicQueryInfo queryInfo, ExecutionFailureInfo failure)
184185
{
186+
BasicQueryStats queryStats = queryInfo.getQueryStats();
185187
eventListenerManager.queryCompleted(requiresAnonymizedPlan -> new QueryCompletedEvent(
186188
new QueryMetadata(
187189
queryInfo.getQueryId().toString(),
@@ -200,16 +202,16 @@ public void queryImmediateFailureEvent(BasicQueryInfo queryInfo, ExecutionFailur
200202
new QueryStatistics(
201203
Duration.ZERO,
202204
Duration.ZERO,
203-
Duration.ZERO,
204-
queryInfo.getQueryStats().getQueuedTime().toJavaTime(),
205-
Optional.empty(),
206-
Optional.empty(),
207-
Optional.empty(),
208-
Optional.empty(),
205+
queryStats.getElapsedTime().toJavaTime(),
206+
queryStats.getQueuedTime().toJavaTime(),
209207
Optional.empty(),
210208
Optional.empty(),
209+
Optional.of(queryStats.getResourceWaitingTime().toJavaTime()),
210+
Optional.of(queryStats.getAnalysisTime().toJavaTime()),
211+
Optional.of(queryStats.getPlanningTime().toJavaTime()),
211212
Optional.empty(),
212213
Optional.empty(),
214+
Optional.of(queryStats.getExecutionTime().toJavaTime()),
213215
Optional.empty(),
214216
Optional.empty(),
215217
Optional.empty(),
@@ -666,8 +668,9 @@ private static void logQueryTimeline(QueryInfo queryInfo)
666668

667669
private static void logQueryTimeline(BasicQueryInfo queryInfo)
668670
{
669-
Instant queryStartTime = queryInfo.getQueryStats().getCreateTime().truncatedTo(MILLIS);
670-
Instant queryEndTime = queryInfo.getQueryStats().getEndTime().truncatedTo(MILLIS);
671+
BasicQueryStats queryStats = queryInfo.getQueryStats();
672+
Instant queryStartTime = queryStats.getCreateTime().truncatedTo(MILLIS);
673+
Instant queryEndTime = queryStats.getEndTime().truncatedTo(MILLIS);
671674

672675
// query didn't finish cleanly
673676
if (queryStartTime == null || queryEndTime == null) {
@@ -682,8 +685,8 @@ private static void logQueryTimeline(BasicQueryInfo queryInfo)
682685
queryInfo.getSession().getQueryDataEncoding(),
683686
Optional.ofNullable(queryInfo.getErrorCode()),
684687
elapsed,
685-
elapsed,
686-
0,
688+
queryStats.getPlanningTime().toMillis(),
689+
queryStats.getResourceWaitingTime().toMillis(),
687690
0,
688691
0,
689692
0,
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
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 com.google.common.util.concurrent.ListenableFuture;
17+
import com.google.inject.Inject;
18+
import io.trino.Session;
19+
import io.trino.connector.CatalogHandle;
20+
import io.trino.execution.warnings.WarningCollector;
21+
import io.trino.metadata.Metadata;
22+
import io.trino.metadata.QualifiedObjectName;
23+
import io.trino.metadata.RedirectionAwareTableHandle;
24+
import io.trino.metadata.TableHandle;
25+
import io.trino.security.AccessControl;
26+
import io.trino.spi.connector.ColumnHandle;
27+
import io.trino.spi.connector.ColumnMetadata;
28+
import io.trino.sql.tree.DropDefaultValue;
29+
import io.trino.sql.tree.Expression;
30+
import io.trino.sql.tree.QualifiedName;
31+
32+
import java.util.List;
33+
34+
import static com.google.common.util.concurrent.Futures.immediateVoidFuture;
35+
import static io.trino.metadata.MetadataUtil.createQualifiedObjectName;
36+
import static io.trino.spi.StandardErrorCode.COLUMN_NOT_FOUND;
37+
import static io.trino.spi.StandardErrorCode.GENERIC_USER_ERROR;
38+
import static io.trino.spi.StandardErrorCode.NOT_SUPPORTED;
39+
import static io.trino.spi.StandardErrorCode.TABLE_NOT_FOUND;
40+
import static io.trino.spi.connector.ConnectorCapabilities.DEFAULT_COLUMN_VALUE;
41+
import static io.trino.sql.analyzer.SemanticExceptions.semanticException;
42+
import static java.util.Objects.requireNonNull;
43+
44+
public class DropDefaultValueTask
45+
implements DataDefinitionTask<DropDefaultValue>
46+
{
47+
private final Metadata metadata;
48+
private final AccessControl accessControl;
49+
50+
@Inject
51+
public DropDefaultValueTask(Metadata metadata, AccessControl accessControl)
52+
{
53+
this.metadata = requireNonNull(metadata, "metadata is null");
54+
this.accessControl = requireNonNull(accessControl, "accessControl is null");
55+
}
56+
57+
@Override
58+
public String getName()
59+
{
60+
return "DROP DEFAULT";
61+
}
62+
63+
@Override
64+
public ListenableFuture<Void> execute(
65+
DropDefaultValue statement,
66+
QueryStateMachine stateMachine,
67+
List<Expression> parameters,
68+
WarningCollector warningCollector)
69+
{
70+
Session session = stateMachine.getSession();
71+
QualifiedObjectName tableName = createQualifiedObjectName(session, statement, statement.getTableName());
72+
RedirectionAwareTableHandle redirectionAwareTableHandle = metadata.getRedirectionAwareTableHandle(session, tableName);
73+
if (redirectionAwareTableHandle.tableHandle().isEmpty()) {
74+
String exceptionMessage = "Table '%s' does not exist".formatted(tableName);
75+
if (metadata.getMaterializedView(session, tableName).isPresent()) {
76+
exceptionMessage += ", but a materialized view with that name exists.";
77+
}
78+
else if (metadata.isView(session, tableName)) {
79+
exceptionMessage += ", but a view with that name exists.";
80+
}
81+
if (!statement.isTableExists()) {
82+
throw semanticException(TABLE_NOT_FOUND, statement, "%s", exceptionMessage);
83+
}
84+
return immediateVoidFuture();
85+
}
86+
accessControl.checkCanAlterColumn(session.toSecurityContext(), tableName);
87+
88+
TableHandle tableHandle = redirectionAwareTableHandle.tableHandle().get();
89+
CatalogHandle catalogHandle = tableHandle.catalogHandle();
90+
QualifiedName field = statement.getColumnName();
91+
if (field.getOriginalParts().size() != 1) {
92+
throw semanticException(NOT_SUPPORTED, statement, "Cannot modify nested fields");
93+
}
94+
String columnName = field.getOriginalParts().getFirst().getValue();
95+
ColumnHandle columnHandle = metadata.getColumnHandles(session, tableHandle).get(columnName);
96+
97+
if (columnHandle == null) {
98+
throw semanticException(COLUMN_NOT_FOUND, statement, "Column '%s' does not exist", columnName);
99+
}
100+
101+
ColumnMetadata columnMetadata = metadata.getColumnMetadata(session, tableHandle, columnHandle);
102+
if (columnMetadata.isHidden()) {
103+
throw semanticException(NOT_SUPPORTED, statement, "Cannot modify hidden column");
104+
}
105+
if (columnMetadata.getDefaultValue().isEmpty()) {
106+
throw semanticException(GENERIC_USER_ERROR, statement, "Column '%s' does not have a default value", columnName);
107+
}
108+
if (!metadata.getConnectorCapabilities(session, catalogHandle).contains(DEFAULT_COLUMN_VALUE)) {
109+
throw semanticException(NOT_SUPPORTED, statement, "Catalog '%s' does not support default value for column name '%s'", catalogHandle, columnName);
110+
}
111+
112+
metadata.dropDefaultValue(session, tableHandle, columnHandle);
113+
return immediateVoidFuture();
114+
}
115+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,7 @@ private BasicQueryStats createBasicQueryStats(BasicStageStats stageStats)
607607
queryStateTimer.getCreateTime(),
608608
getEndTime().orElse(null),
609609
queryStateTimer.getQueuedTime(),
610+
queryStateTimer.getResourceWaitingTime(),
610611
queryStateTimer.getElapsedTime(),
611612
queryStateTimer.getExecutionTime(),
612613

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
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 com.google.common.util.concurrent.ListenableFuture;
17+
import com.google.inject.Inject;
18+
import io.trino.Session;
19+
import io.trino.connector.CatalogHandle;
20+
import io.trino.execution.warnings.WarningCollector;
21+
import io.trino.metadata.Metadata;
22+
import io.trino.metadata.QualifiedObjectName;
23+
import io.trino.metadata.RedirectionAwareTableHandle;
24+
import io.trino.metadata.TableHandle;
25+
import io.trino.security.AccessControl;
26+
import io.trino.spi.connector.ColumnHandle;
27+
import io.trino.spi.connector.ColumnMetadata;
28+
import io.trino.sql.PlannerContext;
29+
import io.trino.sql.tree.Expression;
30+
import io.trino.sql.tree.NodeRef;
31+
import io.trino.sql.tree.Parameter;
32+
import io.trino.sql.tree.QualifiedName;
33+
import io.trino.sql.tree.SetDefaultValue;
34+
35+
import java.util.List;
36+
import java.util.Map;
37+
38+
import static com.google.common.util.concurrent.Futures.immediateVoidFuture;
39+
import static io.trino.execution.ParameterExtractor.bindParameters;
40+
import static io.trino.metadata.MetadataUtil.createQualifiedObjectName;
41+
import static io.trino.spi.StandardErrorCode.COLUMN_NOT_FOUND;
42+
import static io.trino.spi.StandardErrorCode.NOT_SUPPORTED;
43+
import static io.trino.spi.StandardErrorCode.TABLE_NOT_FOUND;
44+
import static io.trino.spi.connector.ConnectorCapabilities.DEFAULT_COLUMN_VALUE;
45+
import static io.trino.sql.analyzer.ExpressionAnalyzer.analyzeDefaultColumnValue;
46+
import static io.trino.sql.analyzer.SemanticExceptions.semanticException;
47+
import static java.util.Objects.requireNonNull;
48+
49+
public class SetDefaultValueTask
50+
implements DataDefinitionTask<SetDefaultValue>
51+
{
52+
private final PlannerContext plannerContext;
53+
private final Metadata metadata;
54+
private final AccessControl accessControl;
55+
56+
@Inject
57+
public SetDefaultValueTask(PlannerContext plannerContext, AccessControl accessControl)
58+
{
59+
this.plannerContext = requireNonNull(plannerContext, "plannerContext is null");
60+
this.metadata = plannerContext.getMetadata();
61+
this.accessControl = requireNonNull(accessControl, "accessControl is null");
62+
}
63+
64+
@Override
65+
public String getName()
66+
{
67+
return "SET DEFAULT";
68+
}
69+
70+
@Override
71+
public ListenableFuture<Void> execute(
72+
SetDefaultValue statement,
73+
QueryStateMachine stateMachine,
74+
List<Expression> parameters,
75+
WarningCollector warningCollector)
76+
{
77+
Session session = stateMachine.getSession();
78+
Map<NodeRef<Parameter>, Expression> parameterLookup = bindParameters(statement, parameters);
79+
QualifiedObjectName tableName = createQualifiedObjectName(session, statement, statement.getTableName());
80+
RedirectionAwareTableHandle redirectionAwareTableHandle = metadata.getRedirectionAwareTableHandle(session, tableName);
81+
82+
if (redirectionAwareTableHandle.tableHandle().isEmpty()) {
83+
String exceptionMessage = "Table '%s' does not exist".formatted(tableName);
84+
if (metadata.getMaterializedView(session, tableName).isPresent()) {
85+
exceptionMessage += ", but a materialized view with that name exists.";
86+
}
87+
else if (metadata.isView(session, tableName)) {
88+
exceptionMessage += ", but a view with that name exists.";
89+
}
90+
if (!statement.isTableExists()) {
91+
throw semanticException(TABLE_NOT_FOUND, statement, "%s", exceptionMessage);
92+
}
93+
return immediateVoidFuture();
94+
}
95+
accessControl.checkCanAlterColumn(session.toSecurityContext(), tableName);
96+
97+
TableHandle tableHandle = redirectionAwareTableHandle.tableHandle().get();
98+
CatalogHandle catalogHandle = tableHandle.catalogHandle();
99+
QualifiedName field = statement.getColumnName();
100+
if (field.getOriginalParts().size() != 1) {
101+
throw semanticException(NOT_SUPPORTED, statement, "Cannot modify nested fields");
102+
}
103+
String columnName = field.getOriginalParts().getFirst().getValue();
104+
ColumnHandle columnHandle = metadata.getColumnHandles(session, tableHandle).get(columnName);
105+
106+
if (columnHandle == null) {
107+
throw semanticException(COLUMN_NOT_FOUND, statement, "Column '%s' does not exist", columnName);
108+
}
109+
110+
ColumnMetadata columnMetadata = metadata.getColumnMetadata(session, tableHandle, columnHandle);
111+
if (columnMetadata.isHidden()) {
112+
throw semanticException(NOT_SUPPORTED, statement, "Cannot modify hidden column");
113+
}
114+
115+
if (!metadata.getConnectorCapabilities(session, catalogHandle).contains(DEFAULT_COLUMN_VALUE)) {
116+
throw semanticException(NOT_SUPPORTED, statement, "Catalog '%s' does not support default value for column name '%s'", catalogHandle, columnName);
117+
}
118+
Expression defaultValue = statement.getDefaultValue();
119+
analyzeDefaultColumnValue(session, plannerContext, accessControl, parameterLookup, warningCollector, columnMetadata.getType(), defaultValue);
120+
121+
metadata.setDefaultValue(session, tableHandle, columnHandle, defaultValue.toString());
122+
return immediateVoidFuture();
123+
}
124+
}

core/trino-main/src/main/java/io/trino/metadata/Metadata.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,16 @@ Optional<TableExecuteHandle> getTableHandleForExecute(
300300
*/
301301
void addField(Session session, TableHandle tableHandle, List<String> parentPath, String fieldName, Type type, boolean ignoreExisting);
302302

303+
/**
304+
* Set the specified default value to the column.
305+
*/
306+
void setDefaultValue(Session session, TableHandle tableHandle, ColumnHandle column, String defaultValue);
307+
308+
/**
309+
* Drop a default value on the specified column.
310+
*/
311+
void dropDefaultValue(Session session, TableHandle tableHandle, ColumnHandle column);
312+
303313
/**
304314
* Set the specified type to the column.
305315
*/

core/trino-main/src/main/java/io/trino/metadata/MetadataManager.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,22 @@ public void dropField(Session session, TableHandle tableHandle, ColumnHandle col
10011001
metadata.dropField(session.toConnectorSession(catalogHandle), tableHandle.connectorHandle(), column, fieldPath);
10021002
}
10031003

1004+
@Override
1005+
public void setDefaultValue(Session session, TableHandle tableHandle, ColumnHandle column, String defaultValue)
1006+
{
1007+
CatalogHandle catalogHandle = tableHandle.catalogHandle();
1008+
ConnectorMetadata metadata = getMetadataForWrite(session, catalogHandle);
1009+
metadata.setDefaultValue(session.toConnectorSession(catalogHandle), tableHandle.connectorHandle(), column, defaultValue);
1010+
}
1011+
1012+
@Override
1013+
public void dropDefaultValue(Session session, TableHandle tableHandle, ColumnHandle column)
1014+
{
1015+
CatalogHandle catalogHandle = tableHandle.catalogHandle();
1016+
ConnectorMetadata metadata = getMetadataForWrite(session, catalogHandle);
1017+
metadata.dropDefaultValue(session.toConnectorSession(catalogHandle), tableHandle.connectorHandle(), column);
1018+
}
1019+
10041020
@Override
10051021
public void setColumnType(Session session, TableHandle tableHandle, ColumnHandle column, Type type)
10061022
{

core/trino-main/src/main/java/io/trino/metadata/SystemFunctionBundle.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,11 @@
100100
import io.trino.operator.scalar.ArrayElementAtFunction;
101101
import io.trino.operator.scalar.ArrayExceptFunction;
102102
import io.trino.operator.scalar.ArrayFilterFunction;
103+
import io.trino.operator.scalar.ArrayFirstFunction;
103104
import io.trino.operator.scalar.ArrayHistogramFunction;
104105
import io.trino.operator.scalar.ArrayIntersectFunction;
105106
import io.trino.operator.scalar.ArrayJoin;
107+
import io.trino.operator.scalar.ArrayLastFunction;
106108
import io.trino.operator.scalar.ArrayMaxFunction;
107109
import io.trino.operator.scalar.ArrayMinFunction;
108110
import io.trino.operator.scalar.ArrayNgramsFunction;
@@ -492,6 +494,8 @@ public static FunctionBundle create(FeaturesConfig featuresConfig, TypeOperators
492494
.functions(IDENTITY_CAST, CAST_FROM_UNKNOWN)
493495
.scalar(ArrayRemoveFunction.class)
494496
.scalar(ArrayElementAtFunction.class)
497+
.scalar(ArrayFirstFunction.class)
498+
.scalar(ArrayLastFunction.class)
495499
.scalar(ArraySortFunction.class)
496500
.scalar(ArraySortComparatorFunction.class)
497501
.scalar(ArrayShuffleFunction.class)

core/trino-main/src/main/java/io/trino/operator/scalar/ArrayElementAtFunction.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import io.trino.spi.function.SqlNullable;
2323
import io.trino.spi.function.SqlType;
2424
import io.trino.spi.function.TypeParameter;
25-
import io.trino.spi.type.Type;
2625

2726
import java.lang.invoke.MethodHandle;
2827

@@ -42,7 +41,6 @@ private ArrayElementAtFunction() {}
4241
@SqlNullable
4342
@SqlType("E")
4443
public static Object elementAt(
45-
@TypeParameter("E") Type elementType,
4644
@OperatorDependency(operator = READ_VALUE, argumentTypes = "E", convention = @Convention(arguments = BLOCK_POSITION_NOT_NULL, result = FAIL_ON_NULL)) MethodHandle readValue,
4745
@SqlType("array(E)") Block array,
4846
@SqlType("bigint") long index)

0 commit comments

Comments
 (0)