Skip to content

Commit 1a72c9c

Browse files
Add tests for built_in methods support as default field values (#1986)
## Why make this change? - Closes #1857 - A bug was identified where we were seeing failures with REST/GraphQL mutation queries with tables having default values of columns as methods. - It was only happening in MSSQL. ## What is this change? - The above bug is resolved by the sql client and there are no more failures due to column default value as methods. - To verify that, I have added Tests for MSSQL, MYSQL, and POSTGRES, that confirms support for methods as default values for entity columns are supported. - We have added tests to show that all the queries run fine irrespective of columns are present in the excluded fields or not. - Tests for both REST and GraphQL are added. ## How was this tested? - [X] Integration Tests Added MySQL tests are failing because of the bug highlighted [here](#2014). It's currently marked to ignore in the test suite to not get blocked. ## Sample Request ### we have excluded `current_date` and `next_date` for the `create`. ![image](https://github.com/Azure/data-api-builder/assets/102276754/abb1d593-6e1e-4b36-99d7-614c43c46dfc) ![image](https://github.com/Azure/data-api-builder/assets/102276754/892195be-3474-48fa-9df5-719f914495a0) --------- Co-authored-by: Aniruddh Munde <[email protected]>
1 parent 02463a2 commit 1a72c9c

22 files changed

+514
-4
lines changed

config-generators/mssql-commands.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ add MappedBookmarks --config "dab-config.MsSql.json" --source "mappedbookmarks"
4343
add FteData --config "dab-config.MsSql.json" --source fte_data --permissions "anonymous:*" --graphql "FteData:FteData"
4444
add InternData --config "dab-config.MsSql.json" --source intern_data --permissions "anonymous:*" --graphql "InternData:InternData"
4545
add BooksSold --config "dab-config.MsSql.json" --source "books_sold" --rest true --graphql "books_sold:books_sold" --permissions "anonymous:*"
46+
add DefaultBuiltInFunction --config "dab-config.MsSql.json" --source "default_with_function_table" --rest true --graphql true --permissions "anonymous:*"
4647
update GQLmappings --config "dab-config.MsSql.json" --map "__column1:column1,__column2:column2" --permissions "authenticated:*"
4748
update Publisher --config "dab-config.MsSql.json" --permissions "authenticated:create,read,update,delete" --rest true --graphql true --relationship books --target.entity Book --cardinality many
4849
update Publisher --config "dab-config.MsSql.json" --permissions "policy_tester_01:create,delete"
@@ -188,3 +189,4 @@ update series --config "dab-config.MsSql.json" --permissions "TestNestedFilterMa
188189
update series --config "dab-config.MsSql.json" --permissions "TestNestedFilterManyOne_EntityReadForbidden:create,update,delete"
189190
update series --config "dab-config.MsSql.json" --permissions "TestNestedFilterOneMany_ColumnForbidden:read"
190191
update series --config "dab-config.MsSql.json" --permissions "TestNestedFilterOneMany_EntityReadForbidden:read"
192+
update DefaultBuiltInFunction --config "dab-config.MsSql.json" --permissions "anonymous:create" --fields.exclude "current_date,next_date"

config-generators/mysql-commands.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ add GQLmappings --config "dab-config.MySql.json" --source "GQLmappings" --permis
2828
add Bookmarks --config "dab-config.MySql.json" --source "bookmarks" --permissions "anonymous:*" --rest true --graphql true
2929
add MappedBookmarks --config "dab-config.MySql.json" --source "mappedbookmarks" --permissions "anonymous:*" --rest true --graphql true
3030
add BooksSold --config "dab-config.MySql.json" --source "books_sold" --rest true --graphql "books_sold:books_sold" --permissions "anonymous:*"
31+
add DefaultBuiltInFunction --config "dab-config.MySql.json" --source "default_with_function_table" --rest true --graphql true --permissions "anonymous:*"
3132
update GQLmappings --config "dab-config.MySql.json" --map "__column1:column1,__column2:column2" --permissions "authenticated:*"
3233
update Publisher --config "dab-config.MySql.json" --permissions "authenticated:create,read,update,delete" --rest true --graphql true --relationship books --target.entity Book --cardinality many
3334
update Publisher --config "dab-config.MySql.json" --permissions "policy_tester_01:create,delete"
@@ -125,3 +126,4 @@ update ArtOfWar --config "dab-config.MySql.json" --permissions "authenticated:*"
125126
update Sales --config "dab-config.MySql.json" --permissions "authenticated:*"
126127
update Bookmarks --config "dab-config.MySql.json" --permissions "authenticated:*"
127128
update MappedBookmarks --config "dab-config.MySql.json" --permissions "authenticated:*" --map "id:bkid,bkname:name"
129+
update DefaultBuiltInFunction --config "dab-config.MySql.json" --permissions "anonymous:create" --fields.exclude "current_date,next_date"

config-generators/postgresql-commands.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ add GQLmappings --config "dab-config.PostgreSql.json" --source "gqlmappings" --p
3131
add Bookmarks --config "dab-config.PostgreSql.json" --source "bookmarks" --permissions "anonymous:*" --rest true --graphql true
3232
add MappedBookmarks --config "dab-config.PostgreSql.json" --source "mappedbookmarks" --permissions "anonymous:*" --rest true --graphql true
3333
add BooksSold --config "dab-config.PostgreSql.json" --source "books_sold" --rest true --graphql "books_sold:books_sold" --permissions "anonymous:*"
34+
add DefaultBuiltInFunction --config "dab-config.PostgreSql.json" --source "default_with_function_table" --rest true --graphql true --permissions "anonymous:*"
3435
update GQLmappings --config "dab-config.PostgreSql.json" --map "__column1:column1,__column2:column2" --permissions "authenticated:*"
3536
update Publisher --config "dab-config.PostgreSql.json" --permissions "authenticated:create,read,update,delete" --rest true --graphql true --relationship books --target.entity Book --cardinality many
3637
update Publisher --config "dab-config.PostgreSql.json" --permissions "policy_tester_01:create,delete"
@@ -161,3 +162,4 @@ update series --config "dab-config.PostgreSql.json" --permissions "TestNestedFil
161162
update series --config "dab-config.PostgreSql.json" --permissions "TestNestedFilterManyOne_EntityReadForbidden:create,update,delete"
162163
update series --config "dab-config.PostgreSql.json" --permissions "TestNestedFilterOneMany_ColumnForbidden:read"
163164
update series --config "dab-config.PostgreSql.json" --permissions "TestNestedFilterOneMany_EntityReadForbidden:read"
165+
update DefaultBuiltInFunction --config "dab-config.PostgreSql.json" --permissions "anonymous:create" --fields.exclude "current_date,next_date"

src/Service.Tests/DatabaseSchema-MsSql.sql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ DROP TABLE IF EXISTS mappedbookmarks;
5050
DROP TABLE IF EXISTS fte_data;
5151
DROP TABLE IF EXISTS intern_data;
5252
DROP TABLE IF EXISTS books_sold;
53+
DROP TABLE IF EXISTS default_with_function_table;
5354
DROP SCHEMA IF EXISTS [foo];
5455
COMMIT;
5556

@@ -285,6 +286,20 @@ create table books_sold
285286
last_sold_on_date as last_sold_on,
286287
)
287288

289+
CREATE TABLE default_with_function_table
290+
(
291+
id INT PRIMARY KEY IDENTITY(5001,1),
292+
user_value INT,
293+
[current_date] DATETIME DEFAULT GETDATE() NOT NULL,
294+
[current_timestamp] DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
295+
random_number INT DEFAULT RAND() NOT NULL,
296+
next_date DATETIME DEFAULT DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()) + 1, 0) NOT NULL,
297+
default_string_with_parenthesis VARCHAR(100) DEFAULT '()',
298+
default_function_string_with_parenthesis VARCHAR(100) DEFAULT 'NOW()',
299+
default_integer INT DEFAULT 100,
300+
default_date_string DATETIME DEFAULT '1999-01-08 10:23:54'
301+
)
302+
288303
ALTER TABLE books
289304
ADD CONSTRAINT book_publisher_fk
290305
FOREIGN KEY (publisher_id)

src/Service.Tests/DatabaseSchema-MySql.sql

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ DROP TABLE IF EXISTS GQLmappings;
3434
DROP TABLE IF EXISTS bookmarks;
3535
DROP TABLE IF EXISTS mappedbookmarks;
3636
DROP TABLE IF EXISTS books_sold;
37+
DROP TABLE IF EXISTS default_with_function_table;
3738

3839
CREATE TABLE publishers(
3940
id int AUTO_INCREMENT PRIMARY KEY,
@@ -221,6 +222,19 @@ CREATE TABLE books_sold (
221222
last_sold_on_date DATETIME GENERATED ALWAYS AS (last_sold_on) STORED
222223
);
223224

225+
CREATE TABLE default_with_function_table
226+
(
227+
id INT AUTO_INCREMENT PRIMARY KEY,
228+
user_value INT,
229+
`current_date` TIMESTAMP DEFAULT (CURRENT_DATE) NOT NULL,
230+
`current_timestamp` TIMESTAMP DEFAULT (NOW()) NOT NULL,
231+
random_number INT DEFAULT (FLOOR(RAND() * 1000)) NOT NULL,
232+
next_date TIMESTAMP DEFAULT (CURRENT_DATE + INTERVAL 1 DAY),
233+
default_string_with_parenthesis VARCHAR(100) DEFAULT ('()'),
234+
default_function_string_with_parenthesis VARCHAR(100) DEFAULT ('NOW()'),
235+
default_integer INT DEFAULT 100,
236+
default_date_string DATETIME DEFAULT ("1999-01-08 10:23:54")
237+
);
224238

225239
ALTER TABLE books
226240
ADD CONSTRAINT book_publisher_fk
@@ -370,6 +384,8 @@ ALTER TABLE sales AUTO_INCREMENT = 5001;
370384
ALTER TABLE players AUTO_INCREMENT = 5001;
371385
ALTER TABLE clubs AUTO_INCREMENT = 5001;
372386

387+
ALTER TABLE default_with_function_table AUTO_INCREMENT = 5001;
388+
373389
prepare stmt1 from 'CREATE VIEW books_view_all AS SELECT * FROM books';
374390

375391
prepare stmt2 from 'CREATE VIEW books_view_with_mapping AS SELECT * FROM books';

src/Service.Tests/DatabaseSchema-PostgreSql.sql

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ DROP TABLE IF EXISTS GQLmappings;
3434
DROP TABLE IF EXISTS bookmarks;
3535
DROP TABLE IF EXISTS mappedbookmarks;
3636
DROP TABLE IF EXISTS books_sold;
37+
DROP TABLE IF EXISTS default_with_function_table;
3738
DROP FUNCTION IF EXISTS insertCompositeView;
3839

3940
DROP SCHEMA IF EXISTS foo;
@@ -226,6 +227,20 @@ CREATE TABLE books_sold (
226227
last_sold_on_date TIMESTAMP GENERATED ALWAYS AS (last_sold_on) STORED
227228
);
228229

230+
CREATE TABLE default_with_function_table
231+
(
232+
id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
233+
user_value INT,
234+
"current_date" TIMESTAMP DEFAULT CURRENT_DATE NOT NULL,
235+
"current_timestamp" TIMESTAMP DEFAULT NOW() NOT NULL,
236+
random_number INT DEFAULT FLOOR(RANDOM() * 1000),
237+
next_date TIMESTAMP DEFAULT (CURRENT_DATE + INTERVAL '1 day'),
238+
default_string_with_parenthesis VARCHAR(100) DEFAULT '()',
239+
default_function_string_with_parenthesis VARCHAR(100) DEFAULT 'NOW()',
240+
default_integer INT DEFAULT 100,
241+
default_date_string TIMESTAMP DEFAULT '1999-01-08 10:23:54'
242+
);
243+
229244
ALTER TABLE books
230245
ADD CONSTRAINT book_publisher_fk
231246
FOREIGN KEY (publisher_id)
@@ -347,6 +362,7 @@ INSERT INTO journals(id, journalname, color, ownername) VALUES (1, 'Journal1', '
347362
INSERT INTO aow("NoteNum", "DetailAssessmentAndPlanning", "WagingWar", "StrategicAttack") VALUES (1, 'chapter one notes: ', 'chapter two notes: ', 'chapter three notes: ');
348363
INSERT INTO sales(id, item_name, subtotal, tax) VALUES (1, 'Watch', 249.00, 20.59), (2, 'Montior', 120.50, 11.12);
349364
INSERT INTO books_sold(id,book_name,last_sold_on) values(1, 'Awesome Book', CURRENT_DATE);
365+
350366
--Starting with id > 5000 is chosen arbitrarily so that the incremented id-s won't conflict with the manually inserted ids in this script
351367
--Sequence counter is set to 5000 so the next autogenerated id will be 5001
352368

@@ -359,6 +375,7 @@ SELECT setval('type_table_id_seq', 5000);
359375
SELECT setval('sales_id_seq', 5000);
360376
SELECT setval('players_id_seq', 5000);
361377
SELECT setval('clubs_id_seq', 5000);
378+
SELECT setval('default_with_function_table_id_seq', 5000);
362379

363380
CREATE VIEW books_view_all AS SELECT * FROM books;
364381
CREATE VIEW books_view_with_mapping AS SELECT * FROM books;

src/Service.Tests/Snapshots/ConfigurationTests.TestReadingRuntimeConfigForMsSql.verified.txt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2566,6 +2566,47 @@
25662566
]
25672567
}
25682568
},
2569+
{
2570+
DefaultBuiltInFunction: {
2571+
Source: {
2572+
Object: default_with_function_table,
2573+
Type: Table
2574+
},
2575+
GraphQL: {
2576+
Singular: DefaultBuiltInFunction,
2577+
Plural: DefaultBuiltInFunctions,
2578+
Enabled: true
2579+
},
2580+
Rest: {
2581+
Enabled: true
2582+
},
2583+
Permissions: [
2584+
{
2585+
Role: anonymous,
2586+
Actions: [
2587+
{
2588+
Action: Create,
2589+
Fields: {
2590+
Exclude: [
2591+
current_date,
2592+
next_date
2593+
]
2594+
}
2595+
},
2596+
{
2597+
Action: Read
2598+
},
2599+
{
2600+
Action: Update
2601+
},
2602+
{
2603+
Action: Delete
2604+
}
2605+
]
2606+
}
2607+
]
2608+
}
2609+
},
25692610
{
25702611
PublisherNF: {
25712612
Source: {

src/Service.Tests/Snapshots/ConfigurationTests.TestReadingRuntimeConfigForMySql.verified.txt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1970,6 +1970,47 @@
19701970
}
19711971
]
19721972
}
1973+
},
1974+
{
1975+
DefaultBuiltInFunction: {
1976+
Source: {
1977+
Object: default_with_function_table,
1978+
Type: Table
1979+
},
1980+
GraphQL: {
1981+
Singular: DefaultBuiltInFunction,
1982+
Plural: DefaultBuiltInFunctions,
1983+
Enabled: true
1984+
},
1985+
Rest: {
1986+
Enabled: true
1987+
},
1988+
Permissions: [
1989+
{
1990+
Role: anonymous,
1991+
Actions: [
1992+
{
1993+
Action: Create,
1994+
Fields: {
1995+
Exclude: [
1996+
current_date,
1997+
next_date
1998+
]
1999+
}
2000+
},
2001+
{
2002+
Action: Read
2003+
},
2004+
{
2005+
Action: Update
2006+
},
2007+
{
2008+
Action: Delete
2009+
}
2010+
]
2011+
}
2012+
]
2013+
}
19732014
}
19742015
]
19752016
}

src/Service.Tests/Snapshots/ConfigurationTests.TestReadingRuntimeConfigForPostgreSql.verified.txt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2059,6 +2059,47 @@
20592059
]
20602060
}
20612061
},
2062+
{
2063+
DefaultBuiltInFunction: {
2064+
Source: {
2065+
Object: default_with_function_table,
2066+
Type: Table
2067+
},
2068+
GraphQL: {
2069+
Singular: DefaultBuiltInFunction,
2070+
Plural: DefaultBuiltInFunctions,
2071+
Enabled: true
2072+
},
2073+
Rest: {
2074+
Enabled: true
2075+
},
2076+
Permissions: [
2077+
{
2078+
Role: anonymous,
2079+
Actions: [
2080+
{
2081+
Action: Create,
2082+
Fields: {
2083+
Exclude: [
2084+
current_date,
2085+
next_date
2086+
]
2087+
}
2088+
},
2089+
{
2090+
Action: Read
2091+
},
2092+
{
2093+
Action: Update
2094+
},
2095+
{
2096+
Action: Delete
2097+
}
2098+
]
2099+
}
2100+
]
2101+
}
2102+
},
20622103
{
20632104
PublisherNF: {
20642105
Source: {

src/Service.Tests/SqlTests/GraphQLMutationTests/GraphQLMutationTestBase.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,62 @@ public async Task InsertMutation(string dbQuery)
4040
SqlTestHelper.PerformTestEqualJsonStrings(expected, actual.ToString());
4141
}
4242

43+
/// <summary>
44+
/// <code>Do: </code> Inserts new row and return all its columns
45+
/// <code>Check: </code> A row is inserted in the table that has rows with default values as built_in methods.
46+
/// it should insert it correctly with default values handled by database.
47+
/// current_date, current_timestamp, random_number, next_date have default value as built_in methods GETDATE(), NOW(), RAND(), DATEADD(), resp.
48+
/// default_string_with_parenthesis has default value "()", default_function_string_with_parenthesis has default value "NOW()".
49+
/// default_integer has default value 100, default_date_string has default value "1999-01-08 10:23:54".
50+
/// Returned response would look like:
51+
/// "createDefaultBuiltInFunction": {
52+
/// "current_date": "2023-12-15T16:24:48.267Z",
53+
/// "current_timestamp": "2023-12-15T16:24:48.267Z",
54+
/// "random_number": 0,
55+
/// "next_date": "2023-12-16T00:00:00.000Z",
56+
/// "default_string_with_paranthesis": "()",
57+
/// "default_function_string_with_paranthesis": "NOW()",
58+
/// "default_integer": 100,
59+
/// "default_date_string": "1999-01-08T10:23:54.000Z"
60+
/// }
61+
/// </summary>
62+
public virtual async Task InsertMutationWithDefaultBuiltInFunctions(string dbQuery)
63+
{
64+
string graphQLMutationName = "createDefaultBuiltInFunction";
65+
string graphQLMutation = @"
66+
mutation {
67+
createDefaultBuiltInFunction(item: { user_value: 1234 }) {
68+
id
69+
user_value
70+
current_date
71+
current_timestamp
72+
random_number
73+
next_date
74+
default_string_with_parenthesis
75+
default_function_string_with_parenthesis
76+
default_integer
77+
default_date_string
78+
}
79+
}
80+
";
81+
82+
JsonElement result = await ExecuteGraphQLRequestAsync(graphQLMutation, graphQLMutationName, isAuthenticated: true);
83+
string expected = await GetDatabaseResultAsync(dbQuery);
84+
85+
// Assert that the values inserted in the DB is same as the values returned by the mutation
86+
SqlTestHelper.PerformTestEqualJsonStrings(expected, result.ToString());
87+
88+
// Assert the values
89+
Assert.IsFalse(string.IsNullOrEmpty(result.GetProperty("current_date").GetString()));
90+
Assert.IsFalse(string.IsNullOrEmpty(result.GetProperty("current_timestamp").GetString()));
91+
Assert.IsNotNull(result.GetProperty("random_number").GetInt32());
92+
Assert.IsFalse(string.IsNullOrEmpty(result.GetProperty("next_date").GetString()));
93+
Assert.AreEqual("()", result.GetProperty("default_string_with_parenthesis").GetString());
94+
Assert.AreEqual("NOW()", result.GetProperty("default_function_string_with_parenthesis").GetString());
95+
Assert.AreEqual(100, result.GetProperty("default_integer").GetInt32());
96+
Assert.AreEqual("1999-01-08T10:23:54.000Z", result.GetProperty("default_date_string").GetString());
97+
}
98+
4399
/// <summary>
44100
/// <code>Do: </code> Attempt to insert a new publisher with name not allowed by database policy (@item.name ne 'New publisher')
45101
/// <code>Check: </code> Mutation fails with expected authorization failure.

0 commit comments

Comments
 (0)