Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/Core/Resolvers/QueryExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,12 @@ internal int StreamCharData(DbDataReader dbDataReader, long availableSize, Strin
// else we throw exception.
ValidateSize(availableSize, resultFieldSize);

// If the cell is empty, don't append anything to the resultJsonString and return 0.
if (resultFieldSize == 0)
{
return 0;
}

char[] buffer = new char[resultFieldSize];

// read entire field into buffer and reduce available size.
Expand All @@ -766,6 +772,13 @@ internal int StreamByteData(DbDataReader dbDataReader, long availableSize, int o
// else we throw exception.
ValidateSize(availableSize, resultFieldSize);

// If the cell is empty, set resultBytes to an empty array and return 0.
if (resultFieldSize == 0)
{
resultBytes = Array.Empty<byte>();
return 0;
}

resultBytes = new byte[resultFieldSize];

dbDataReader.GetBytes(ordinal: ordinal, dataOffset: 0, buffer: resultBytes, bufferOffset: 0, length: resultBytes.Length);
Expand Down
3 changes: 2 additions & 1 deletion src/Service.Tests/DatabaseSchema-DwSql.sql
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,8 @@ VALUES (1, 'Awesome book', 1234),
(17, 'CONN%_CONN', 1234),
(18, '[Special Book]', 1234),
(19, 'ME\YOU', 1234),
(20, 'C:\\LIFE', 1234);
(20, 'C:\\LIFE', 1234),
(21, '', 1234);

INSERT INTO book_website_placements(id, book_id, price) VALUES (1, 1, 100), (2, 2, 50), (3, 3, 23), (4, 5, 33);

Expand Down
3 changes: 2 additions & 1 deletion src/Service.Tests/DatabaseSchema-MsSql.sql
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,8 @@ VALUES (1, 'Awesome book', 1234),
(17, 'CONN%_CONN', 1234),
(18, '[Special Book]', 1234),
(19, 'ME\YOU', 1234),
(20, 'C:\\LIFE', 1234);
(20, 'C:\\LIFE', 1234),
(21, '', 1234);
SET IDENTITY_INSERT books OFF

SET IDENTITY_INSERT books_mm ON
Expand Down
3 changes: 2 additions & 1 deletion src/Service.Tests/DatabaseSchema-MySql.sql
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,8 @@ INSERT INTO books(id, title, publisher_id)
(17, 'CONN%_CONN', 1234),
(18, '[Special Book]', 1234),
(19, 'ME\\YOU', 1234),
(20, 'C:\\\\LIFE', 1234);
(20, 'C:\\\\LIFE', 1234),
(21, '', 1234);
INSERT INTO book_website_placements(book_id, price) VALUES (1, 100), (2, 50), (3, 23), (5, 33);
INSERT INTO website_users(id, username) VALUES (1, 'George'), (2, NULL), (3, ''), (4, 'book_lover_95'), (5, 'null');
INSERT INTO book_author_link(book_id, author_id) VALUES (1, 123), (2, 124), (3, 123), (3, 124), (4, 123), (4, 124), (5, 126);
Expand Down
3 changes: 2 additions & 1 deletion src/Service.Tests/DatabaseSchema-PostgreSql.sql
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,8 @@ INSERT INTO books(id, title, publisher_id)
(17, 'CONN%_CONN', 1234),
(18, '[Special Book]', 1234),
(19, 'ME\YOU', 1234),
(20, 'C:\\LIFE', 1234);
(20, 'C:\\LIFE', 1234),
(21, '', 1234);
INSERT INTO book_website_placements(book_id, price) VALUES (1, 100), (2, 50), (3, 23), (5, 33);
INSERT INTO website_users(id, username) VALUES (1, 'George'), (2, NULL), (3, ''), (4, 'book_lover_95'), (5, 'null');
INSERT INTO book_author_link(book_id, author_id) VALUES (1, 123), (2, 124), (3, 123), (3, 124), (4, 123), (4, 124), (5, 126);;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ public async Task TestStoredProcedureMutationForDeletion(string dbQueryToVerifyD

string currentDbResponse = await GetDatabaseResultAsync(dbQueryToVerifyDeletion);
JsonDocument currentResult = JsonDocument.Parse(currentDbResponse);
Assert.AreEqual(currentResult.RootElement.GetProperty("maxId").GetInt64(), 20);
Assert.AreEqual(currentResult.RootElement.GetProperty("maxId").GetInt64(), 21);
JsonElement graphQLResponse = await ExecuteGraphQLRequestAsync(graphQLMutation, graphQLMutationName, isAuthenticated: true);

// Stored Procedure didn't return anything
Expand All @@ -266,7 +266,7 @@ public async Task TestStoredProcedureMutationForDeletion(string dbQueryToVerifyD
// check to verify new element is inserted
string updatedDbResponse = await GetDatabaseResultAsync(dbQueryToVerifyDeletion);
JsonDocument updatedResult = JsonDocument.Parse(updatedDbResponse);
Assert.AreEqual(updatedResult.RootElement.GetProperty("maxId").GetInt64(), 19);
Assert.AreEqual(updatedResult.RootElement.GetProperty("maxId").GetInt64(), 20);
}

public async Task InsertMutationOnTableWithTriggerWithNonAutoGenPK(string dbQuery)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,95 +84,101 @@ public async Task RequestMaxUsingNegativeOne()
}
}";

// this resultset represents all books in the db.
JsonElement actual = await ExecuteGraphQLRequestAsync(graphQLQuery, graphQLQueryName, isAuthenticated: false);
string expected = @"{
""items"": [
""items"": [
{
""id"": 1,
""title"": ""Awesome book""
""id"": 1,
""title"": ""Awesome book""
},
{
""id"": 2,
""title"": ""Also Awesome book""
""id"": 2,
""title"": ""Also Awesome book""
},
{
""id"": 3,
""title"": ""Great wall of china explained""
""id"": 3,
""title"": ""Great wall of china explained""
},
{
""id"": 4,
""title"": ""US history in a nutshell""
""id"": 4,
""title"": ""US history in a nutshell""
},
{
""id"": 5,
""title"": ""Chernobyl Diaries""
""id"": 5,
""title"": ""Chernobyl Diaries""
},
{
""id"": 6,
""title"": ""The Palace Door""
""id"": 6,
""title"": ""The Palace Door""
},
{
""id"": 7,
""title"": ""The Groovy Bar""
""id"": 7,
""title"": ""The Groovy Bar""
},
{
""id"": 8,
""title"": ""Time to Eat""
""id"": 8,
""title"": ""Time to Eat""
},
{
""id"": 9,
""title"": ""Policy-Test-01""
""id"": 9,
""title"": ""Policy-Test-01""
},
{
""id"": 10,
""title"": ""Policy-Test-02""
""id"": 10,
""title"": ""Policy-Test-02""
},
{
""id"": 11,
""title"": ""Policy-Test-04""
""id"": 11,
""title"": ""Policy-Test-04""
},
{
""id"": 12,
""title"": ""Time to Eat 2""
""id"": 12,
""title"": ""Time to Eat 2""
},
{
""id"": 13,
""title"": ""Before Sunrise""
},
{
""id"": 13,
""title"": ""Before Sunrise""
""id"": 14,
""title"": ""Before Sunset""
},
{
""id"": 14,
""title"": ""Before Sunset""
""id"": 15,
""title"": ""SQL_CONN""
},
{
""id"": 15,
""title"": ""SQL_CONN""
""id"": 16,
""title"": ""SOME%CONN""
},
{
""id"": 16,
""title"": ""SOME%CONN""
""id"": 17,
""title"": ""CONN%_CONN""
},
{
""id"": 17,
""title"": ""CONN%_CONN""
""id"": 18,
""title"": ""[Special Book]""
},
{
""id"": 18,
""title"": ""[Special Book]""
""id"": 19,
""title"": ""ME\\YOU""
},
{
""id"": 19,
""title"": ""ME\\YOU""
""id"": 20,
""title"": ""C:\\\\LIFE""
},
{
""id"": 20,
""title"": ""C:\\\\LIFE""
""id"": 21,
""title"": """"
}
],
""endCursor"": null,
""hasNextPage"": false
],
""endCursor"": null,
""hasNextPage"": false
}";

// Note: The max page size is 21 for MsSql and 20 for all other data sources, so when using -1
// this resultset represents all books in the db.
JsonElement actual = await ExecuteGraphQLRequestAsync(graphQLQuery, graphQLQueryName, isAuthenticated: false);

SqlTestHelper.PerformTestEqualJsonStrings(expected, actual.ToString());
}

Expand All @@ -196,91 +202,96 @@ public async Task RequestNoParamFullConnection()
}";

JsonElement actual = await ExecuteGraphQLRequestAsync(graphQLQuery, graphQLQueryName, isAuthenticated: false);

string expected = @"{
""items"": [
""items"": [
{
""id"": 1,
""title"": ""Awesome book""
""id"": 1,
""title"": ""Awesome book""
},
{
""id"": 2,
""title"": ""Also Awesome book""
""id"": 2,
""title"": ""Also Awesome book""
},
{
""id"": 3,
""title"": ""Great wall of china explained""
""id"": 3,
""title"": ""Great wall of china explained""
},
{
""id"": 4,
""title"": ""US history in a nutshell""
""id"": 4,
""title"": ""US history in a nutshell""
},
{
""id"": 5,
""title"": ""Chernobyl Diaries""
""id"": 5,
""title"": ""Chernobyl Diaries""
},
{
""id"": 6,
""title"": ""The Palace Door""
""id"": 6,
""title"": ""The Palace Door""
},
{
""id"": 7,
""title"": ""The Groovy Bar""
""id"": 7,
""title"": ""The Groovy Bar""
},
{
""id"": 8,
""title"": ""Time to Eat""
""id"": 8,
""title"": ""Time to Eat""
},
{
""id"": 9,
""title"": ""Policy-Test-01""
""id"": 9,
""title"": ""Policy-Test-01""
},
{
""id"": 10,
""title"": ""Policy-Test-02""
""id"": 10,
""title"": ""Policy-Test-02""
},
{
""id"": 11,
""title"": ""Policy-Test-04""
""id"": 11,
""title"": ""Policy-Test-04""
},
{
""id"": 12,
""title"": ""Time to Eat 2""
""id"": 12,
""title"": ""Time to Eat 2""
},
{
""id"": 13,
""title"": ""Before Sunrise""
""id"": 13,
""title"": ""Before Sunrise""
},
{
""id"": 14,
""title"": ""Before Sunset""
""id"": 14,
""title"": ""Before Sunset""
},
{
""id"": 15,
""title"": ""SQL_CONN""
""id"": 15,
""title"": ""SQL_CONN""
},
{
""id"": 16,
""title"": ""SOME%CONN""
""id"": 16,
""title"": ""SOME%CONN""
},
{
""id"": 17,
""title"": ""CONN%_CONN""
""id"": 17,
""title"": ""CONN%_CONN""
},
{
""id"": 18,
""title"": ""[Special Book]""
""id"": 18,
""title"": ""[Special Book]""
},
{
""id"": 19,
""title"": ""ME\\YOU""
""id"": 19,
""title"": ""ME\\YOU""
},
{
""id"": 20,
""title"": ""C:\\\\LIFE""
""id"": 20,
""title"": ""C:\\\\LIFE""
},
{
""id"": 21,
""title"": """"
}
],
""endCursor"": null,
""hasNextPage"": false
],
""endCursor"": null,
""hasNextPage"": false
}";

SqlTestHelper.PerformTestEqualJsonStrings(expected, actual.ToString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,22 @@ SELECT title FROM books
await QueryWithSingleColumnPrimaryKey(msSqlQuery);
}

[TestMethod]
public virtual async Task QueryWithEmptyStringResult()
{
string graphQLQueryName = "book_by_pk";
string graphQLQuery = @"{
book_by_pk(id: 21) {
title
}
}";

JsonElement actual = await ExecuteGraphQLRequestAsync(graphQLQuery, graphQLQueryName, isAuthenticated: false);

string title = actual.GetProperty("title").GetString();
Assert.AreEqual("", title);
}

[TestMethod]
public async Task QueryWithSingleColumnPrimaryKeyAndMappings()
{
Expand Down
Loading
Loading