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

DataTable.Load() fails when joining SQLite tables with UNIQUE constraint #30765

Closed
CodeSpartan opened this issue Apr 25, 2023 · 0 comments · Fixed by #32648
Closed

DataTable.Load() fails when joining SQLite tables with UNIQUE constraint #30765

CodeSpartan opened this issue Apr 25, 2023 · 0 comments · Fixed by #32648
Assignees
Labels
area-adonet-sqlite closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported type-bug

Comments

@CodeSpartan
Copy link

CodeSpartan commented Apr 25, 2023

When using the DataTable.Load() method to load data from a SQLite query with a LEFT JOIN on a column with a UNIQUE constraint, an error is thrown. The error message is "Column 'guildId' is constrained to be unique. Value '1' is already present." even though the join operation should not enforce the unique constraint on the joined columns.

To reproduce the issue, consider the following SQLite schema and data:

CREATE TABLE "characters" (
	"id"	INTEGER,
	"name"	TEXT UNIQUE,
	"guild"	INTEGER,
);

CREATE TABLE "guilds" (
	"id"	INTEGER NOT NULL UNIQUE,
	"name"	TEXT UNIQUE,
	UNIQUE("name"),
	PRIMARY KEY("id" AUTOINCREMENT)
);
CREATE UNIQUE INDEX guildname 
ON guilds(name);
INSERT INTO characters (id, name, guild) VALUES (1, 'John', 1);
INSERT INTO characters (id, name, guild) VALUES (2, 'Jeanette', 1);

INSERT INTO guilds (id, name) VALUES (1, 'Testers');

And the following pseudo C# code using Microsoft.Data.Sqlite:

var connection = new SqliteConnection(connectionParameters);
var commandTxt = @"
    SELECT guilds.name as guildName, characters.name as charName FROM guilds
    LEFT JOIN characters
    ON guilds.id = characters.guild";
var command = new SqliteCommand(commandTxt, connection);
var reader = await command.ExecuteReaderAsync();
DataTable dt = new();
dt.Load(reader);

Expected behavior is to receive two rows of data:

  /*
   * guildName	        charName 	
   * Testers 		John
   * Testers            Jeanette
   */

Actual behavior:

The line dt.Load(reader) throws an exception: Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.

If you wrap the last line into a try-catch and add a breakpoint in the catch statement, then going into the Command Window and typing ? dt.GetErrors()[1].RowError would produce an explanation: "Column 'guildName' is constrained to be unique. Value 'Testers' is already present."

The UNIQUE constraint is meant to enforce uniqueness on the data stored in the table, not on the results of join operations. As such, the join operation should not enforce the unique constraint on the DataTable. Furthermore, executing the same code with MySqlConnector produces desired result. And other software such as DB Browser for SQLite doesn't exhibit the problem, either.

Microsoft.Data.Sqlite version: 7.0.5
Target framework: .NET 6.0
Operating system: Windows 11

@ajcvickers ajcvickers added this to the Backlog milestone Apr 27, 2023
@bricelam bricelam self-assigned this Apr 27, 2023
@bricelam bricelam removed their assignment Jul 8, 2023
ajcvickers added a commit that referenced this issue Dec 19, 2023
@ajcvickers ajcvickers self-assigned this Dec 19, 2023
@ajcvickers ajcvickers added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Dec 19, 2023
@ajcvickers ajcvickers modified the milestones: Backlog, 9.0.0 Dec 19, 2023
@ajcvickers ajcvickers modified the milestones: 9.0.0, 9.0.0-preview1 Jan 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-adonet-sqlite closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported type-bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants