Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nullability annotations for System.Data #38810

Merged
merged 1 commit into from
Jul 13, 2020

Conversation

roji
Copy link
Member

@roji roji commented Jul 6, 2020

Following ec73c56.

  • No (intentional) behavioral changes have been introduced.
  • To avoid making this huge PR even bigger, I've deliberately refrained from cleaning up/simplifying code as much as possible
  • I've concentrated especially on the public surface: private/internal areas may contain some imprecise annotating. This shouldn't have an impact - we can always come back and improve these if we want.
  • The APIs are generally very lax about nulls, accepting them (and doing nothing) in places where they don't really make sense (this is inconsistent across the codebase). I've stuck to annotating the current behavior - if a method accepts null (e.g. and does nothing), that parameter is annotated as nullable.
  • I've found various bugs; lots of simple cases where checks are missing and an NRE would be thrown, some other suspicious cases for actual bugs. I've made some notes, but as this is almost entirely legacy we should probably be reactive here and wait for bug reports to be filed.
  • A few corners have been left unannotated because of dependencies.

Part of #2339

@roji roji force-pushed the SystemDataNullability2 branch 2 times, most recently from 2aa2c47 to 1d6d1d2 Compare July 6, 2020 14:28
@@ -445,12 +446,12 @@ public void Clear()
try
{
// this will smartly add and remove the appropriate tables.
BaseGroupSwitch(constraints, oldLength, null, 0);
BaseGroupSwitch(constraints, oldLength, Array.Empty<Constraint>(), 0);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The following 0 count means the array never gets enumerated anyway

@roji roji marked this pull request as ready for review July 6, 2020 14:29
@roji roji requested a review from stephentoub July 6, 2020 14:29
@roji
Copy link
Member Author

roji commented Jul 6, 2020

/cc @ajcvickers @jeffhandley

[System.ComponentModel.DefaultValueAttribute("")]
[System.Diagnostics.CodeAnalysis.AllowNull]
public virtual string QuotePrefix { get { throw null; } set { } }
Copy link
Member

@stephentoub stephentoub Jul 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see call sites for some of these virtuals checking for and allowing null. Is non-nullable correct for the return value for all of these?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default implementation coalesces to string.Empty, and it's supposed to be a string you can always concatenate before/after the string. It's true that it's virtual so anything's possible, though I'm only seeing IsNullOrEmpty in the Odbc and OleDb providers, and SqlClient just calls base.QuotePrefix.

Where are you seeing null checks, anything persuasive? I can make it nullable if you think that's safer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where are you seeing null checks

The IsNullOrEmpty checks you mentioned. But it's not just in Odbc and OleDb, e.g. DBCommandBuilder allows null in both private void BuildInformation(DataTable schemaTable) and private string QuotedColumn(string column).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, yeah - I see them though they're also IsNullOrEmpty. I think the point is to check for length 0 rather than for null (the coalescing behavior of the property getters is a good indication), but if you think we should annotate these as nullable I can do that. We could also do a more thorough search outside the BCL to see who's overriding DbCommandBuilder and what they're doing, let me know.

Copy link
Member

@stephentoub stephentoub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only spot checked and I'm exhausted; thanks for slogging through this.

@roji roji force-pushed the SystemDataNullability2 branch 7 times, most recently from 2daaa57 to 655d26b Compare July 12, 2020 13:00
@ghost
Copy link

ghost commented Jul 12, 2020

Tagging subscribers to this area: @roji, @ajcvickers
Notify danmosemsft if you want to be subscribed.

@roji roji force-pushed the SystemDataNullability2 branch 2 times, most recently from 8aed39b to dc8fe20 Compare July 12, 2020 14:40
Following ec73c56.
A few corners have been left annotated because of dependencies.
@roji roji force-pushed the SystemDataNullability2 branch from dc8fe20 to d0f5d5e Compare July 12, 2020 19:19
@roji roji merged commit 8a94c7b into dotnet:master Jul 13, 2020
@roji
Copy link
Member Author

roji commented Jul 13, 2020

@stephentoub have merged this to be able to continue working on Odbc etc., thanks for taking the time to review this (it was most definitely a slog).

If there are any outstanding points (e.g. #38810 (comment)) let me know and I'll do fix-up to this in a later PR.

@ghost ghost locked as resolved and limited conversation to collaborators Dec 8, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants