Skip to content

Commit 1704ac3

Browse files
authored
feat: support analyze DDL statement (#1879)
Adds support for the ANALYZE statement. This statement is sent to the UpdateDatabaseDdl RPC.
1 parent 01f460e commit 1704ac3

File tree

3 files changed

+117
-1
lines changed

3 files changed

+117
-1
lines changed

google-cloud-spanner/src/main/java/com/google/cloud/spanner/connection/AbstractStatementParser.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ ClientSideStatement getClientSideStatement() {
320320
}
321321
}
322322

323-
static final Set<String> ddlStatements = ImmutableSet.of("CREATE", "DROP", "ALTER");
323+
static final Set<String> ddlStatements = ImmutableSet.of("CREATE", "DROP", "ALTER", "ANALYZE");
324324
static final Set<String> selectStatements = ImmutableSet.of("SELECT", "WITH", "SHOW");
325325
static final Set<String> dmlStatements = ImmutableSet.of("INSERT", "UPDATE", "DELETE");
326326
private final Set<ClientSideStatementImpl> statements;
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* Copyright 2022 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud.spanner.connection;
18+
19+
import static org.junit.Assert.assertEquals;
20+
21+
import com.google.cloud.spanner.Statement;
22+
import com.google.cloud.spanner.connection.StatementResult.ResultType;
23+
import com.google.longrunning.Operation;
24+
import com.google.protobuf.Any;
25+
import com.google.protobuf.Empty;
26+
import com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata;
27+
import com.google.spanner.admin.database.v1.UpdateDatabaseDdlRequest;
28+
import java.util.List;
29+
import java.util.stream.Collectors;
30+
import org.junit.After;
31+
import org.junit.Test;
32+
import org.junit.runner.RunWith;
33+
import org.junit.runners.JUnit4;
34+
35+
@RunWith(JUnit4.class)
36+
public class DdlTest extends AbstractMockServerTest {
37+
38+
@After
39+
public void reset() {
40+
mockDatabaseAdmin.reset();
41+
}
42+
43+
@Override
44+
protected String getBaseUrl() {
45+
return String.format(
46+
"cloudspanner://localhost:%d/projects/proj/instances/inst/databases/db?usePlainText=true",
47+
getPort());
48+
}
49+
50+
private void addUpdateDdlResponse() {
51+
mockDatabaseAdmin.addResponse(
52+
Operation.newBuilder()
53+
.setMetadata(
54+
Any.pack(
55+
UpdateDatabaseDdlMetadata.newBuilder()
56+
.setDatabase("projects/proj/instances/inst/databases/db")
57+
.build()))
58+
.setName("projects/proj/instances/inst/databases/db/operations/1")
59+
.setDone(true)
60+
.setResponse(Any.pack(Empty.getDefaultInstance()))
61+
.build());
62+
}
63+
64+
@Test
65+
public void testSingleAnalyzeStatement() {
66+
addUpdateDdlResponse();
67+
68+
try (Connection connection = createConnection()) {
69+
StatementResult result = connection.execute(Statement.of("analyze"));
70+
assertEquals(ResultType.NO_RESULT, result.getResultType());
71+
}
72+
73+
List<UpdateDatabaseDdlRequest> requests =
74+
mockDatabaseAdmin.getRequests().stream()
75+
.filter(request -> request instanceof UpdateDatabaseDdlRequest)
76+
.map(request -> (UpdateDatabaseDdlRequest) request)
77+
.collect(Collectors.toList());
78+
assertEquals(1, requests.size());
79+
assertEquals(1, requests.get(0).getStatementsCount());
80+
assertEquals("analyze", requests.get(0).getStatements(0));
81+
}
82+
83+
@Test
84+
public void testBatchedAnalyzeStatement() {
85+
addUpdateDdlResponse();
86+
87+
try (Connection connection = createConnection()) {
88+
connection.startBatchDdl();
89+
assertEquals(
90+
ResultType.NO_RESULT,
91+
connection
92+
.execute(Statement.of("create table foo (id int64) primary key (id)"))
93+
.getResultType());
94+
assertEquals(
95+
ResultType.NO_RESULT, connection.execute(Statement.of("analyze")).getResultType());
96+
connection.runBatch();
97+
}
98+
99+
List<UpdateDatabaseDdlRequest> requests =
100+
mockDatabaseAdmin.getRequests().stream()
101+
.filter(request -> request instanceof UpdateDatabaseDdlRequest)
102+
.map(request -> (UpdateDatabaseDdlRequest) request)
103+
.collect(Collectors.toList());
104+
assertEquals(1, requests.size());
105+
assertEquals(2, requests.get(0).getStatementsCount());
106+
assertEquals("create table foo (id int64) primary key (id)", requests.get(0).getStatements(0));
107+
assertEquals("analyze", requests.get(0).getStatements(1));
108+
}
109+
}

google-cloud-spanner/src/test/java/com/google/cloud/spanner/connection/StatementParserTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,13 @@ public void testIsDdlStatement() {
510510
+ " CONCAT(Singers.FirstName, Singers.LastName) as Name\n"
511511
+ " FROM Singers"))
512512
.isDdl());
513+
514+
assertTrue(parser.parse(Statement.of("analyze")).isDdl());
515+
assertTrue(parser.parse(Statement.of("Analyze")).isDdl());
516+
assertTrue(parser.parse(Statement.of("ANALYZE")).isDdl());
517+
assertTrue(parser.parse(Statement.of("\t ANALYZE\n ")).isDdl());
518+
assertTrue(parser.parse(Statement.of("/* This is a comment */ ANALYZE ")).isDdl());
519+
assertTrue(parser.parse(Statement.of("-- comment\n ANALYZE ")).isDdl());
513520
}
514521

515522
@Test

0 commit comments

Comments
 (0)