Skip to content

Commit ec67f50

Browse files
authored
Add binary types to tests (#641)
* add binary and varbinary * add known issue to readme
1 parent 76a9981 commit ec67f50

File tree

11 files changed

+61
-12
lines changed

11 files changed

+61
-12
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ Databases on SQL Server, Azure SQL Database, or Azure SQL Managed Instance which
4141

4242
## Known Issues
4343
- The table used by a SQL binding or SQL trigger cannot contain two columns that only differ by casing (Ex. 'Name' and 'name').
44+
- Non-CSharp functions using SQL bindings against tables with columns of data types `BINARY` or `VARBINARY` need to map those columns to a string type. Input bindings will return the binary value as a base64 encoded string. Output bindings require the value upserted to binary columns to be a base64 encoded string.
4445

4546
### Output Bindings
4647
- Output bindings against tables with columns of data types `NTEXT`, `TEXT`, or `IMAGE` are not supported and data upserts will fail. These types [will be removed](https://docs.microsoft.com/sql/t-sql/data-types/ntext-text-and-image-transact-sql) in a future version of SQL Server and are not compatible with the `OPENJSON` function used by this Azure Functions binding.

test-outofproc/Product.cs

+7-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT License. See License.txt in the project root for license information.
33
using System.Collections.Generic;
44
using System;
5+
using System.Linq;
56

67
namespace DotnetIsolatedTests.Common
78
{
@@ -138,6 +139,10 @@ public class ProductColumnTypes
138139

139140
public string Nvarchar { get; set; }
140141

142+
public byte[] Binary { get; set; }
143+
144+
public byte[] Varbinary { get; set; }
145+
141146
public override bool Equals(object obj)
142147
{
143148
if (obj is ProductColumnTypes)
@@ -149,7 +154,8 @@ public override bool Equals(object obj)
149154
this.FloatType == that.FloatType && this.Real == that.Real && this.Date == that.Date &&
150155
this.Datetime == that.Datetime && this.Datetime2 == that.Datetime2 && this.DatetimeOffset == that.DatetimeOffset &&
151156
this.SmallDatetime == that.SmallDatetime && this.Time == that.Time && this.CharType == that.CharType &&
152-
this.Varchar == that.Varchar && this.Nchar == that.Nchar && this.Nvarchar == that.Nvarchar;
157+
this.Varchar == that.Varchar && this.Nchar == that.Nchar && this.Nvarchar == that.Nvarchar &&
158+
this.Binary.SequenceEqual(that.Binary) && this.Varbinary.SequenceEqual(that.Varbinary);
153159
}
154160
return false;
155161
}

test/Common/ProductColumnTypes.cs

+8-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT License. See License.txt in the project root for license information.
33

44
using System;
5+
using System.Linq;
56

67
namespace Microsoft.Azure.WebJobs.Extensions.Sql.Tests.Common
78
{
@@ -49,6 +50,10 @@ public class ProductColumnTypes
4950

5051
public string Nvarchar { get; set; }
5152

53+
public byte[] Binary { get; set; }
54+
55+
public byte[] Varbinary { get; set; }
56+
5257
public override bool Equals(object obj)
5358
{
5459
if (obj is ProductColumnTypes)
@@ -60,14 +65,15 @@ public override bool Equals(object obj)
6065
this.FloatType == that.FloatType && this.Real == that.Real && this.Date == that.Date &&
6166
this.Datetime == that.Datetime && this.Datetime2 == that.Datetime2 && this.DatetimeOffset == that.DatetimeOffset &&
6267
this.SmallDatetime == that.SmallDatetime && this.Time == that.Time && this.CharType == that.CharType &&
63-
this.Varchar == that.Varchar && this.Nchar == that.Nchar && this.Nvarchar == that.Nvarchar;
68+
this.Varchar == that.Varchar && this.Nchar == that.Nchar && this.Nvarchar == that.Nvarchar &&
69+
this.Binary.SequenceEqual(that.Binary) && this.Varbinary.SequenceEqual(that.Varbinary);
6470
}
6571
return false;
6672
}
6773

6874
public override string ToString()
6975
{
70-
return $"[{this.ProductId}, {this.BigInt}, {this.Bit}, {this.DecimalType}, {this.Money}, {this.Numeric}, {this.SmallInt}, {this.SmallMoney}, {this.TinyInt}, {this.FloatType}, {this.Real}, {this.Date}, {this.Datetime}, {this.Datetime2}, {this.DatetimeOffset}, {this.SmallDatetime}, {this.Time}, {this.CharType}, {this.Varchar}, {this.Nchar}, {this.Nvarchar}]";
76+
return $"[{this.ProductId}, {this.BigInt}, {this.Bit}, {this.DecimalType}, {this.Money}, {this.Numeric}, {this.SmallInt}, {this.SmallMoney}, {this.TinyInt}, {this.FloatType}, {this.Real}, {this.Date}, {this.Datetime}, {this.Datetime2}, {this.DatetimeOffset}, {this.SmallDatetime}, {this.Time}, {this.CharType}, {this.Varchar}, {this.Nchar}, {this.Nvarchar}, {this.Binary}, {this.Varbinary}]";
7177
}
7278
}
7379
}

test/Database/Tables/ProductsColumnTypes.sql

+2
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,6 @@
2020
[Varchar] [varchar](100),
2121
[Nchar] [nchar](4),
2222
[Nvarchar] [nvarchar](100),
23+
[Binary] [binary](4),
24+
[Varbinary] [varbinary](100)
2325
)

test/Integration/SqlInputBindingIntegrationTests.cs

+8-4
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ public async void GetProductsColumnTypesSerializationAsyncEnumerableTest(string
143143
this.StartFunctionHost(nameof(GetProductsColumnTypesSerializationAsyncEnumerable), lang, true);
144144

145145
string datetime = "2022-10-20 12:39:13.123";
146-
ProductColumnTypes[] expectedResponse = JsonConvert.DeserializeObject<ProductColumnTypes[]>("[{\"ProductId\":999,\"BigInt\":999,\"Bit\":false,\"DecimalType\":1.2345,\"Money\":1.2345,\"Numeric\":1.2345,\"SmallInt\":1,\"SmallMoney\":1.2345,\"TinyInt\":1,\"FloatType\":0.1,\"Real\":0.1,\"Date\":\"2022-10-20T00:00:00.000Z\",\"Datetime\":\"2022-10-20T12:39:13.123Z\",\"Datetime2\":\"2022-10-20T12:39:13.123Z\",\"DatetimeOffset\":\"2022-10-20T12:39:13.123Z\",\"SmallDatetime\":\"2022-10-20T12:39:00.000Z\",\"Time\":\"12:39:13.1230000\",\"CharType\":\"test\",\"Varchar\":\"test\",\"Nchar\":\"\uFFFD\u0020\u0020\u0020\",\"Nvarchar\":\"\uFFFD\"}]");
146+
ProductColumnTypes[] expectedResponse = JsonConvert.DeserializeObject<ProductColumnTypes[]>("[{\"ProductId\":999,\"BigInt\":999,\"Bit\":false,\"DecimalType\":1.2345,\"Money\":1.2345,\"Numeric\":1.2345,\"SmallInt\":1,\"SmallMoney\":1.2345,\"TinyInt\":1,\"FloatType\":0.1,\"Real\":0.1,\"Date\":\"2022-10-20T00:00:00.000Z\",\"Datetime\":\"2022-10-20T12:39:13.123Z\",\"Datetime2\":\"2022-10-20T12:39:13.123Z\",\"DatetimeOffset\":\"2022-10-20T12:39:13.123Z\",\"SmallDatetime\":\"2022-10-20T12:39:00.000Z\",\"Time\":\"12:39:13.1230000\",\"CharType\":\"test\",\"Varchar\":\"test\",\"Nchar\":\"\uFFFD\u0020\u0020\u0020\",\"Nvarchar\":\"\uFFFD\",\"Binary\":\"dGVzdA==\",\"Varbinary\":\"dGVzdA==\"}]");
147147

148148
this.ExecuteNonQuery("INSERT INTO [dbo].[ProductsColumnTypes] VALUES (" +
149149
"999, " + // ProductId,
@@ -166,7 +166,9 @@ public async void GetProductsColumnTypesSerializationAsyncEnumerableTest(string
166166
"'test', " + // CharType
167167
"'test', " + // Varchar
168168
"NCHAR(0xD84C), " + // Nchar
169-
"NCHAR(0xD84C))"); // Nvarchar
169+
"NCHAR(0xD84C), " + // Nvarchar
170+
"CONVERT(BINARY, 'test'), " + // Binary
171+
"CONVERT(VARBINARY, 'test'))"); // Varbinary
170172

171173
HttpResponseMessage response = await this.SendInputRequest("getproducts-columntypesserializationasyncenumerable", $"?culture={culture}");
172174
// We expect the datetime and datetime2 fields to be returned in UTC format
@@ -206,11 +208,13 @@ public async void GetProductsColumnTypesSerializationTest(SupportedLanguages lan
206208
"'test', " + // CharType
207209
"'test', " + // Varchar
208210
"NCHAR(0xD84C), " + // Nchar
209-
"NCHAR(0xD84C))"); // Nvarchar
211+
"NCHAR(0xD84C), " + // Nvarchar
212+
"CONVERT(BINARY, 'test'), " + // Binary
213+
"CONVERT(VARBINARY, 'test'))"); // Varbinary
210214

211215
HttpResponseMessage response = await this.SendInputRequest("getproducts-columntypesserialization");
212216
// We expect the date fields to be returned in UTC format
213-
ProductColumnTypes[] expectedResponse = JsonConvert.DeserializeObject<ProductColumnTypes[]>("[{\"ProductId\":999,\"BigInt\":999,\"Bit\":false,\"DecimalType\":1.2345,\"Money\":1.2345,\"Numeric\":1.2345,\"SmallInt\":1,\"SmallMoney\":1.2345,\"TinyInt\":1,\"FloatType\":0.1,\"Real\":0.1,\"Date\":\"2022-10-20T00:00:00.000Z\",\"Datetime\":\"2022-10-20T12:39:13.123Z\",\"Datetime2\":\"2022-10-20T12:39:13.123Z\",\"DatetimeOffset\":\"2022-10-20T12:39:13.123Z\",\"SmallDatetime\":\"2022-10-20T12:39:00.000Z\",\"Time\":\"12:39:13.1230000\",\"CharType\":\"test\",\"Varchar\":\"test\",\"Nchar\":\"\uFFFD\u0020\u0020\u0020\",\"Nvarchar\":\"\uFFFD\"}]");
217+
ProductColumnTypes[] expectedResponse = JsonConvert.DeserializeObject<ProductColumnTypes[]>("[{\"ProductId\":999,\"BigInt\":999,\"Bit\":false,\"DecimalType\":1.2345,\"Money\":1.2345,\"Numeric\":1.2345,\"SmallInt\":1,\"SmallMoney\":1.2345,\"TinyInt\":1,\"FloatType\":0.1,\"Real\":0.1,\"Date\":\"2022-10-20T00:00:00.000Z\",\"Datetime\":\"2022-10-20T12:39:13.123Z\",\"Datetime2\":\"2022-10-20T12:39:13.123Z\",\"DatetimeOffset\":\"2022-10-20T12:39:13.123Z\",\"SmallDatetime\":\"2022-10-20T12:39:00.000Z\",\"Time\":\"12:39:13.1230000\",\"CharType\":\"test\",\"Varchar\":\"test\",\"Nchar\":\"\uFFFD\u0020\u0020\u0020\",\"Nvarchar\":\"\uFFFD\",\"Binary\":\"dGVzdA==\",\"Varbinary\":\"dGVzdA==\"}]");
214218
string actualResponse = await response.Content.ReadAsStringAsync();
215219
ProductColumnTypes[] actualProductResponse = JsonConvert.DeserializeObject<ProductColumnTypes[]>(actualResponse);
216220

test/Integration/test-java/src/main/java/com/function/AddProductColumnTypes.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ public HttpResponseMessage run(
5858
"test",
5959
"test",
6060
"\u2649",
61-
"\u2649");
61+
"\u2649",
62+
"dGVzdA==",
63+
"dGVzdA==");
6264
product.setValue(p);
6365

6466
// Items were inserted successfully so return success, an exception would be thrown if there

test/Integration/test-java/src/main/java/com/function/Common/ProductColumnTypes.java

+21-1
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,14 @@ public class ProductColumnTypes {
3131
private String Varchar;
3232
private String Nchar;
3333
private String Nvarchar;
34+
private String Binary;
35+
private String Varbinary;
3436

3537

3638
public ProductColumnTypes(int productId, long bigInt, boolean bit, BigDecimal decimalType, BigDecimal money,
3739
BigDecimal numeric, short smallInt, BigDecimal smallMoney, short tinyInt, double floatType, double real, Timestamp date,
3840
Timestamp datetime, Timestamp datetime2, Timestamp datetimeOffset, Timestamp smallDatetime, String time, String charType,
39-
String varchar, String nchar, String nvarchar) {
41+
String varchar, String nchar, String nvarchar, String binary, String varbinary) {
4042
ProductId = productId;
4143
BigInt = bigInt;
4244
Bit = bit;
@@ -58,6 +60,8 @@ public ProductColumnTypes(int productId, long bigInt, boolean bit, BigDecimal de
5860
Varchar = varchar;
5961
Nchar = nchar;
6062
Nvarchar = nvarchar;
63+
Binary = binary;
64+
Varbinary = varbinary;
6165
}
6266

6367
public int getProductId() {
@@ -223,4 +227,20 @@ public String getNvarchar() {
223227
public void setNvarchar(String nvarchar) {
224228
Nvarchar = nvarchar;
225229
}
230+
231+
public String getBinary() {
232+
return Binary;
233+
}
234+
235+
public void setBinary(String binary) {
236+
Binary = binary;
237+
}
238+
239+
public String getVarbinary() {
240+
return Varbinary;
241+
}
242+
243+
public void setVarbinary(String varbinary) {
244+
Varbinary = varbinary;
245+
}
226246
}

test/Integration/test-js/AddProductColumnTypes/index.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ module.exports = async function (context, req) {
2727
"CharType": "test",
2828
"Varchar": "test",
2929
"Nchar": "\u2649",
30-
"Nvarchar": "\u2649"
30+
"Nvarchar": "\u2649",
31+
"Binary": "dGVzdA==",
32+
"Varbinary": "dGVzdA=="
3133
};
3234

3335
context.bindings.product = JSON.stringify(product);

test/Integration/test-powershell/AddProductColumnTypes/run.ps1

+2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ $req_query = @{
3333
Varchar="test";
3434
Nchar="\u2649";
3535
Nvarchar="\u2649";
36+
Binary="dGVzdA==";
37+
Varbinary="dGVzdA==";
3638
};
3739

3840
# Assign the value we want to pass to the SQL Output binding.

test/Integration/test-python/AddProductColumnTypes/__init__.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ def main(req: func.HttpRequest, product: func.Out[func.SqlRow]) -> func.HttpResp
2929
"test",
3030
"test",
3131
"\u2649",
32-
"\u2649")
32+
"\u2649",
33+
"dGVzdA==",
34+
"dGVzdA==")
3335
)
3436
product.set(productColumnTypes)
3537

test/Integration/test-python/Common/productcolumntypes.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
class ProductColumnTypes(collections.UserDict):
77
def __init__(self, productId, bigInt, bit, decimalType, money, numeric, smallInt,
88
smallMoney, tinyInt, floatType, real, date, datetime, datetime2, datetimeOffset,
9-
smallDatetime, time, charType, varchar, nchar, nvarchar):
9+
smallDatetime, time, charType, varchar, nchar, nvarchar, binary, varBinary):
1010
super().__init__()
1111
self['ProductId'] = productId
1212
self['BigInt'] = bigInt
@@ -29,4 +29,6 @@ def __init__(self, productId, bigInt, bit, decimalType, money, numeric, smallInt
2929
self['Varchar'] = varchar
3030
self['Nchar'] = nchar
3131
self['Nvarchar'] = nvarchar
32+
self['Binary'] = binary
33+
self['Varbinary'] = varBinary
3234

0 commit comments

Comments
 (0)