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
40 changes: 40 additions & 0 deletions src/ParquetViewer.Tests/HelperTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,46 @@ public void FloatScientificNotation_IsWrappedInQuotes()
Assert.AreEqual("Value = '1.23E+20'", query);
}

[TestMethod]
[DataRow("de-DE")] //comma decimal separator
[DataRow("fr-FR")] //comma decimal separator + narrow no-break group separator
[DataRow("th-TH")] //non-Gregorian calendar by default
public void NumericAndDateFilters_AreCultureInvariant(string cultureName)
{
//DataView.RowFilter always expects '.' as the decimal separator and a Gregorian date,
//regardless of the user's locale. Without invariant formatting, a culture that uses ','
//would corrupt the filter since ',' also separates values inside an `IN (...)` clause.
var originalCulture = CultureInfo.CurrentCulture;
try
{
CultureInfo.CurrentCulture = new CultureInfo(cultureName);

Assert.AreEqual("Value = 1.5", ParquetGridView.GenerateFilterQuery(new()
{
("Value", typeof(double), new object[] { 1.5d })
}));

Assert.AreEqual("Value = '1.23E+20'", ParquetGridView.GenerateFilterQuery(new()
{
("Value", typeof(double), new object[] { 1.23e20 })
}));

Assert.AreEqual("Value IN (1.5,2.5)", ParquetGridView.GenerateFilterQuery(new()
{
("Value", typeof(double), new object[] { 1.5d, 2.5d })
}));

Assert.AreEqual("Value = #2024-01-31 13:45:30#", ParquetGridView.GenerateFilterQuery(new()
{
("Value", typeof(DateTime), new object[] { new DateTime(2024, 1, 31, 13, 45, 30) })
}));
}
finally
{
CultureInfo.CurrentCulture = originalCulture;
}
}

[TestMethod]
public void ByteArrayValue_IsCorrectlyTruncated()
{
Expand Down
13 changes: 10 additions & 3 deletions src/ParquetViewer/Controls/ParquetGridView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
Expand Down Expand Up @@ -1050,12 +1051,18 @@ public static string GenerateFilterQuery(List<(string ColumnName, Type ValueType
{
if (valueType == typeof(DateTime))
{
//Use a standard date format so the query is always syntactically correct
queryBuilder.AppendFormat(dateValueEscapeFormat, ((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss.FFFFFFF"));
//Use a standard date format so the query is always syntactically correct.
//Invariant culture is required: custom format strings still resolve the calendar from
//the current culture, so locales like th-TH would emit a non-Gregorian year.
queryBuilder.AppendFormat(CultureInfo.InvariantCulture, dateValueEscapeFormat,
((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss.FFFFFFF", CultureInfo.InvariantCulture));
}
else if (valueType.IsNumber())
{
var stringValue = value.ToString();
//DataView.RowFilter syntax is culture invariant: it always expects '.' as the decimal
//separator. Formatting with the current culture would emit ',' in locales like de-DE,
//which silently corrupts the filter since ',' separates values inside an `IN (...)` clause.
var stringValue = Convert.ToString(value, CultureInfo.InvariantCulture);
if ((valueType == typeof(float) || valueType == typeof(double))
&& stringValue?.Contains('E', StringComparison.OrdinalIgnoreCase) == true)
stringValue = $"'{stringValue}'"; //scientific notation values need to be wrapped in single quotes
Expand Down
Loading