Skip to content

Commit 8c00b69

Browse files
committed
Merge branch 'main' into ado-net-driver
2 parents 8469320 + 21aa88e commit 8c00b69

File tree

15 files changed

+89
-37
lines changed

15 files changed

+89
-37
lines changed

parser/statement_parser.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,8 +458,8 @@ func (p *StatementParser) skipQuoted(sql []byte, pos int, quote byte) (int, int,
458458
// This was the end quote.
459459
return pos + 1, quoteLength, nil
460460
}
461-
} else if (p.supportsBackslashEscape() || isEscapeString) && len(sql) > pos+1 && c == '\\' && sql[pos+1] == quote {
462-
// This is an escaped quote (e.g. 'foo\'bar').
461+
} else if (p.supportsBackslashEscape() || isEscapeString) && len(sql) > pos+1 && c == '\\' && (sql[pos+1] == quote || sql[pos+1] == '\\') {
462+
// This is an escaped quote (e.g. 'foo\'bar') or an escaped backslash (e.g 'test\\').
463463
// Note that in raw strings, the \ officially does not start an
464464
// escape sequence, but the result is still the same, as in a raw
465465
// string 'both characters are preserved'.

parser/statement_parser_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,17 @@ SELECT * FROM PersonsTable WHERE id=@id`,
740740
databasepb.DatabaseDialect_POSTGRESQL: spanner.ToSpannerError(status.Errorf(codes.InvalidArgument, "SQL statement contains an unclosed literal: %s", `?"?it\"?s"?`)),
741741
},
742742
},
743+
"backslash at end of string": {
744+
input: `?'test\\'?`,
745+
wantSQL: map[databasepb.DatabaseDialect]string{
746+
databasepb.DatabaseDialect_GOOGLE_STANDARD_SQL: `@p1'test\\'@p2`,
747+
databasepb.DatabaseDialect_POSTGRESQL: `$1'test\\'$2`,
748+
},
749+
want: map[databasepb.DatabaseDialect][]string{
750+
databasepb.DatabaseDialect_GOOGLE_STANDARD_SQL: {"p1", "p2"},
751+
databasepb.DatabaseDialect_POSTGRESQL: {"p1", "p2"},
752+
},
753+
},
743754
"triple-quoted string": {
744755
input: `?'''?it\'?s'''?`,
745756
wantSQL: map[databasepb.DatabaseDialect]string{
@@ -1092,6 +1103,16 @@ SELECT * FROM PersonsTable WHERE id=$1`,
10921103
input: `?"?it\"?s"?`,
10931104
wantErr: spanner.ToSpannerError(status.Errorf(codes.InvalidArgument, "SQL statement contains an unclosed literal: %s", `?"?it\"?s"?`)),
10941105
},
1106+
"backslash at end of string": {
1107+
input: `?'test\\'?`,
1108+
wantSQL: `$1'test\\'$2`,
1109+
want: []string{"p1", "p2"},
1110+
},
1111+
"backslash at end of double-quoted string": {
1112+
input: `?"test\\"?`,
1113+
wantSQL: `$1"test\\"$2`,
1114+
want: []string{"p1", "p2"},
1115+
},
10951116
"triple-quoted string": {
10961117
input: `?'''?it\'?s'''?`,
10971118
wantErr: spanner.ToSpannerError(status.Errorf(codes.InvalidArgument, "SQL statement contains an unclosed literal: %s", `?'''?it\'?s'''?`)),
@@ -1263,6 +1284,16 @@ func TestFindParamsWithCommentsPostgreSQL(t *testing.T) {
12631284
wantSQL: `$1\"?it\\"\"?s\"%s$2`,
12641285
want: []string{"p1", "p2"},
12651286
},
1287+
"backslash at end of string": {
1288+
input: `?'test\\'%s?`,
1289+
wantSQL: `$1'test\\'%s$2`,
1290+
want: []string{"p1", "p2"},
1291+
},
1292+
"backslash at end of double-quoted string": {
1293+
input: `?"test\\"%s?`,
1294+
wantSQL: `$1"test\\"%s$2`,
1295+
want: []string{"p1", "p2"},
1296+
},
12661297
"triple-quotes": {
12671298
input: `?%s'''?it\''?s'''?`,
12681299
wantSQL: `$1%s'''?it\''?s'''$2`,
@@ -2028,6 +2059,13 @@ func TestSkip(t *testing.T) {
20282059
databasepb.DatabaseDialect_POSTGRESQL: "'''foo\\'",
20292060
},
20302061
},
2062+
"escaped backslash at end of string literal": {
2063+
input: "'test\\\\' as foo",
2064+
skipped: map[databasepb.DatabaseDialect]string{
2065+
databasepb.DatabaseDialect_GOOGLE_STANDARD_SQL: "'test\\\\'",
2066+
databasepb.DatabaseDialect_POSTGRESQL: "'test\\\\'",
2067+
},
2068+
},
20312069
"string with linefeed": {
20322070
input: "'foo\n' ",
20332071
skipped: map[databasepb.DatabaseDialect]string{

spannerlib/wrappers/spannerlib-dotnet/build.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,19 @@ echo "Building .NET packages..."
6161
dotnet nuget remove source local-native-build 2>/dev/null
6262
if [ "$RUNNER_OS" == "Windows" ]; then
6363
# PWD does not work on Windows
64+
mkdir -p "${GITHUB_WORKSPACE}\spannerlib\wrappers\spannerlib-dotnet\spannerlib-dotnet-native\bin\Release"
6465
dotnet nuget add source "${GITHUB_WORKSPACE}\spannerlib\wrappers\spannerlib-dotnet\spannerlib-dotnet-native\bin\Release" --name local-native-build
6566
else
67+
mkdir -p "$PWD"/spannerlib-dotnet-native/bin/Release
6668
dotnet nuget add source "$PWD"/spannerlib-dotnet-native/bin/Release --name local-native-build
6769
fi
6870
dotnet nuget remove source local-grpc-server-build 2>/dev/null
6971
if [ "$RUNNER_OS" == "Windows" ]; then
7072
# PWD does not work on Windows
73+
mkdir -p "${GITHUB_WORKSPACE}\spannerlib\wrappers\spannerlib-dotnet\spannerlib-dotnet-grpc-server\bin\Release"
7174
dotnet nuget add source "${GITHUB_WORKSPACE}\spannerlib\wrappers\spannerlib-dotnet\spannerlib-dotnet-grpc-server\bin\Release" --name local-grpc-server-build
7275
else
76+
mkdir -p "$PWD"/spannerlib-dotnet-grpc-server/bin/Release
7377
dotnet nuget add source "$PWD"/spannerlib-dotnet-grpc-server/bin/Release --name local-grpc-server-build
7478
fi
7579

spannerlib/wrappers/spannerlib-dotnet/spannerlib-dotnet-grpc-impl/GrpcLibSpanner.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ public async Task CloseConnectionAsync(Connection connection, CancellationToken
157157
{
158158
try
159159
{
160-
await _client.CloseConnectionAsync(ToProto(connection), cancellationToken: cancellationToken);
160+
await _client.CloseConnectionAsync(ToProto(connection), cancellationToken: cancellationToken).ConfigureAwait(false);
161161
}
162162
catch (RpcException exception)
163163
{
@@ -184,7 +184,7 @@ public async Task CloseConnectionAsync(Connection connection, CancellationToken
184184
{
185185
Connection = ToProto(connection),
186186
Mutations = mutations,
187-
}, cancellationToken: cancellationToken);
187+
}, cancellationToken: cancellationToken).ConfigureAwait(false);
188188
return response.CommitTimestamp == null ? null : response;
189189
}
190190
catch (RpcException exception)
@@ -223,13 +223,13 @@ public async Task<Rows> ExecuteAsync(Connection connection, ExecuteSqlRequest st
223223
{
224224
if (_useStreamingRows)
225225
{
226-
return await ExecuteStreamingAsync(connection, statement, cancellationToken);
226+
return await ExecuteStreamingAsync(connection, statement, cancellationToken).ConfigureAwait(false);
227227
}
228228
var rows = await _client.ExecuteAsync(new ExecuteRequest
229229
{
230230
Connection = ToProto(connection),
231231
ExecuteSqlRequest = statement,
232-
}, cancellationToken: cancellationToken);
232+
}, cancellationToken: cancellationToken).ConfigureAwait(false);
233233
return FromProto(connection, rows);
234234
}
235235
catch (RpcException exception)
@@ -246,7 +246,7 @@ private async Task<StreamingRows> ExecuteStreamingAsync(Connection connection, E
246246
Connection = ToProto(connection),
247247
ExecuteSqlRequest = statement,
248248
}));
249-
return await StreamingRows.CreateAsync(connection, stream, cancellationToken);
249+
return await StreamingRows.CreateAsync(connection, stream, cancellationToken).ConfigureAwait(false);
250250
}
251251

252252
public long[] ExecuteBatch(Connection connection, ExecuteBatchDmlRequest statements)
@@ -283,7 +283,7 @@ public async Task<long[]> ExecuteBatchAsync(Connection connection, ExecuteBatchD
283283
{
284284
Connection = ToProto(connection),
285285
ExecuteBatchDmlRequest = statements,
286-
}, cancellationToken: cancellationToken);
286+
}, cancellationToken: cancellationToken).ConfigureAwait(false);
287287
var result = new long[stats.ResultSets.Count];
288288
for (var i = 0; i < result.Length; i++)
289289
{
@@ -306,7 +306,7 @@ public async Task<long[]> ExecuteBatchAsync(Connection connection, ExecuteBatchD
306306
{
307307
try
308308
{
309-
return await _client.MetadataAsync(ToProto(rows), cancellationToken: cancellationToken);
309+
return await _client.MetadataAsync(ToProto(rows), cancellationToken: cancellationToken).ConfigureAwait(false);
310310
}
311311
catch (RpcException exception)
312312
{
@@ -323,7 +323,7 @@ public async Task<long[]> ExecuteBatchAsync(Connection connection, ExecuteBatchD
323323
{
324324
try
325325
{
326-
return await _client.NextResultSetAsync(ToProto(rows), cancellationToken: cancellationToken);
326+
return await _client.NextResultSetAsync(ToProto(rows), cancellationToken: cancellationToken).ConfigureAwait(false);
327327
}
328328
catch (RpcException exception)
329329
{
@@ -356,7 +356,7 @@ public async Task<long[]> ExecuteBatchAsync(Connection connection, ExecuteBatchD
356356
Rows = ToProto(rows),
357357
NumRows = numRows,
358358
Encoding = (long)encoding,
359-
}, cancellationToken: cancellationToken);
359+
}, cancellationToken: cancellationToken).ConfigureAwait(false);
360360
}
361361
catch (RpcException exception)
362362
{
@@ -373,7 +373,7 @@ public async Task CloseRowsAsync(Rows rows, CancellationToken cancellationToken
373373
{
374374
try
375375
{
376-
await _client.CloseRowsAsync(ToProto(rows), cancellationToken: cancellationToken);
376+
await _client.CloseRowsAsync(ToProto(rows), cancellationToken: cancellationToken).ConfigureAwait(false);
377377
}
378378
catch (RpcException exception)
379379
{
@@ -400,7 +400,7 @@ public void BeginTransaction(Connection connection, TransactionOptions transacti
400400
{
401401
try
402402
{
403-
var response = await _client.CommitAsync(ToProto(connection), cancellationToken: cancellationToken);
403+
var response = await _client.CommitAsync(ToProto(connection), cancellationToken: cancellationToken).ConfigureAwait(false);
404404
return response.CommitTimestamp == null ? null : response;
405405
}
406406
catch (RpcException exception)
@@ -418,7 +418,7 @@ public async Task RollbackAsync(Connection connection, CancellationToken cancell
418418
{
419419
try
420420
{
421-
await _client.RollbackAsync(ToProto(connection), cancellationToken: cancellationToken);
421+
await _client.RollbackAsync(ToProto(connection), cancellationToken: cancellationToken).ConfigureAwait(false);
422422
}
423423
catch (RpcException exception)
424424
{

spannerlib/wrappers/spannerlib-dotnet/spannerlib-dotnet-grpc-impl/StreamingRows.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public static StreamingRows Create(Connection connection, AsyncServerStreamingCa
3232
public static async Task<StreamingRows> CreateAsync(Connection connection, AsyncServerStreamingCall<RowData> stream, CancellationToken cancellationToken = default)
3333
{
3434
var rows = new StreamingRows(connection, stream);
35-
rows._pendingRow = await rows.NextAsync(cancellationToken);
35+
rows._pendingRow = await rows.NextAsync(cancellationToken).ConfigureAwait(false);
3636
return rows;
3737
}
3838

@@ -118,7 +118,7 @@ private void MarkDone()
118118
}
119119
try
120120
{
121-
var hasNext = await _stream.ResponseStream.MoveNext(cancellationToken);
121+
var hasNext = await _stream.ResponseStream.MoveNext(cancellationToken).ConfigureAwait(false);
122122
if (!hasNext)
123123
{
124124
MarkDone();
@@ -180,7 +180,7 @@ public override async Task<bool> NextResultSetAsync(CancellationToken cancellati
180180
return false;
181181
}
182182
// Read data until we reach the next result set.
183-
await ReadUntilEndAsync(cancellationToken);
183+
await ReadUntilEndAsync(cancellationToken).ConfigureAwait(false);
184184

185185
return HasNextResultSet();
186186
}
@@ -206,7 +206,7 @@ private void ReadUntilEnd()
206206
private async Task ReadUntilEndAsync(CancellationToken cancellationToken)
207207
{
208208
// Read the remaining rows in the current result set.
209-
while (!_pendingNextResultSetCall && await NextAsync(cancellationToken) != null)
209+
while (!_pendingNextResultSetCall && await NextAsync(cancellationToken).ConfigureAwait(false) != null)
210210
{
211211
}
212212
}

spannerlib/wrappers/spannerlib-dotnet/spannerlib-dotnet-grpc-impl/spannerlib-dotnet-grpc-impl.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
</PropertyGroup>
1212

1313
<ItemGroup>
14+
<PackageReference Include="ConfigureAwaitChecker.Analyzer" PrivateAssets="All" Version="5.0.0.1" />
1415
<PackageReference Include="Alpha.Google.Cloud.SpannerLib.GrpcServer" Version="1.0.0-alpha.20251027150914" />
1516
</ItemGroup>
1617

spannerlib/wrappers/spannerlib-dotnet/spannerlib-dotnet-grpc-server/spannerlib-dotnet-grpc-server.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
<Version>1.0.0-alpha.20251027150914</Version>
1212
</PropertyGroup>
1313

14+
<ItemGroup>
15+
<PackageReference Include="ConfigureAwaitChecker.Analyzer" PrivateAssets="All" Version="5.0.0.1" />
16+
</ItemGroup>
17+
1418
<ItemGroup>
1519
<None Include="binaries/any/*" Pack="true" PackagePath="runtimes/any/native/" />
1620
<None Include="binaries/linux-x64/*" Pack="true" PackagePath="runtimes/linux-x64/native/" />

spannerlib/wrappers/spannerlib-dotnet/spannerlib-dotnet-native-impl/SharedLibSpanner.cs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,10 @@ public void CloseConnection(Connection connection)
105105
return CommitResponse.Parser.ParseFrom(handler.Value());
106106
}
107107

108-
public Task<CommitResponse?> WriteMutationsAsync(Connection connection,
108+
public async Task<CommitResponse?> WriteMutationsAsync(Connection connection,
109109
BatchWriteRequest.Types.MutationGroup mutations, CancellationToken cancellationToken = default)
110110
{
111-
return Task.Run(() => WriteMutations(connection, mutations), cancellationToken);
111+
return await Task.Run(() => WriteMutations(connection, mutations), cancellationToken).ConfigureAwait(false);
112112
}
113113

114114
public Rows Execute(Connection connection, ExecuteSqlRequest statement)
@@ -122,9 +122,9 @@ public Rows Execute(Connection connection, ExecuteSqlRequest statement)
122122
return new Rows(connection, handler.ObjectId());
123123
}
124124

125-
public Task<Rows> ExecuteAsync(Connection connection, ExecuteSqlRequest statement, CancellationToken cancellationToken)
125+
public async Task<Rows> ExecuteAsync(Connection connection, ExecuteSqlRequest statement, CancellationToken cancellationToken)
126126
{
127-
return Task.Run(() => Execute(connection, statement), cancellationToken);
127+
return await Task.Run(() => Execute(connection, statement), cancellationToken).ConfigureAwait(false);
128128
}
129129

130130
public long[] ExecuteBatch(Connection connection, ExecuteBatchDmlRequest statements)
@@ -161,9 +161,9 @@ public long[] ExecuteBatch(Connection connection, ExecuteBatchDmlRequest stateme
161161
return result;
162162
}
163163

164-
public Task<long[]> ExecuteBatchAsync(Connection connection, ExecuteBatchDmlRequest statements, CancellationToken cancellationToken = default)
164+
public async Task<long[]> ExecuteBatchAsync(Connection connection, ExecuteBatchDmlRequest statements, CancellationToken cancellationToken = default)
165165
{
166-
return Task.Run(() => ExecuteBatch(connection, statements), cancellationToken);
166+
return await Task.Run(() => ExecuteBatch(connection, statements), cancellationToken).ConfigureAwait(false);
167167
}
168168

169169
public ResultSetMetadata? Metadata(Rows rows)
@@ -174,7 +174,7 @@ public Task<long[]> ExecuteBatchAsync(Connection connection, ExecuteBatchDmlRequ
174174

175175
public async Task<ResultSetMetadata?> MetadataAsync(Rows rows, CancellationToken cancellationToken = default)
176176
{
177-
return await Task.Run(() => Metadata(rows), cancellationToken);
177+
return await Task.Run(() => Metadata(rows), cancellationToken).ConfigureAwait(false);
178178
}
179179

180180
public ResultSetMetadata? NextResultSet(Rows rows)
@@ -185,7 +185,7 @@ public Task<long[]> ExecuteBatchAsync(Connection connection, ExecuteBatchDmlRequ
185185

186186
public async Task<ResultSetMetadata?> NextResultSetAsync(Rows rows, CancellationToken cancellationToken = default)
187187
{
188-
return await Task.Run(() => NextResultSet(rows), cancellationToken);
188+
return await Task.Run(() => NextResultSet(rows), cancellationToken).ConfigureAwait(false);
189189
}
190190

191191
public ResultSetStats? Stats(Rows rows)
@@ -202,17 +202,17 @@ public Task<long[]> ExecuteBatchAsync(Connection connection, ExecuteBatchDmlRequ
202202

203203
public async Task<ListValue?> NextAsync(Rows rows, int numRows, ISpannerLib.RowEncoding encoding, CancellationToken cancellationToken = default)
204204
{
205-
return await Task.Run(() => Next(rows, numRows, encoding), cancellationToken);
205+
return await Task.Run(() => Next(rows, numRows, encoding), cancellationToken).ConfigureAwait(false);
206206
}
207207

208208
public void CloseRows(Rows rows)
209209
{
210210
ExecuteAndReleaseLibraryFunction(() => SpannerLib.CloseRows(rows.SpannerConnection.Pool.Id, rows.SpannerConnection.Id, rows.Id));
211211
}
212212

213-
public Task CloseRowsAsync(Rows rows, CancellationToken cancellationToken = default)
213+
public async Task CloseRowsAsync(Rows rows, CancellationToken cancellationToken = default)
214214
{
215-
return Task.Run(() => CloseRows(rows), cancellationToken);
215+
await Task.Run(() => CloseRows(rows), cancellationToken).ConfigureAwait(false);
216216
}
217217

218218
public void BeginTransaction(Connection connection, TransactionOptions transactionOptions)
@@ -241,8 +241,8 @@ public void Rollback(Connection connection)
241241
ExecuteAndReleaseLibraryFunction(() => SpannerLib.Rollback(connection.Pool.Id, connection.Id));
242242
}
243243

244-
public Task RollbackAsync(Connection connection, CancellationToken cancellationToken = default)
244+
public async Task RollbackAsync(Connection connection, CancellationToken cancellationToken = default)
245245
{
246-
return Task.Run(() => Rollback(connection), cancellationToken);
246+
await Task.Run(() => Rollback(connection), cancellationToken).ConfigureAwait(false);
247247
}
248248
}

spannerlib/wrappers/spannerlib-dotnet/spannerlib-dotnet-native-impl/spannerlib-dotnet-native-impl.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
</ItemGroup>
1616

1717
<ItemGroup>
18+
<PackageReference Include="ConfigureAwaitChecker.Analyzer" PrivateAssets="All" Version="5.0.0.1" />
1819
<PackageReference Include="Alpha.Google.Cloud.SpannerLib.Native" Version="1.0.0-alpha.20251027150914" />
1920
</ItemGroup>
2021

spannerlib/wrappers/spannerlib-dotnet/spannerlib-dotnet-native/MessageHandler.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
// limitations under the License.
1414

1515
using System;
16-
using System.Data;
1716
using System.Text;
1817

1918
namespace Google.Cloud.SpannerLib.Native;

0 commit comments

Comments
 (0)