Skip to content

Validate id column uniqueness in MariaDBSchemaValidator - #6708

Open
dev-xong wants to merge 1 commit into
spring-projects:mainfrom
dev-xong:feat/mariadb-schema-validator-id-unique-check
Open

Validate id column uniqueness in MariaDBSchemaValidator#6708
dev-xong wants to merge 1 commit into
spring-projects:mainfrom
dev-xong:feat/mariadb-schema-validator-id-unique-check

Conversation

@dev-xong

Copy link
Copy Markdown

Summary

Implements the TODO left in MariaDBSchemaValidator#validateTableSchema (ensure id is a primary key for batch update).
MariaDBVectorStore's batch upsert uses INSERT ... ON DUPLICATE KEY UPDATE, which only behaves as "insert or update on duplicate" when the id column is backed by a single-column PRIMARY KEY or UNIQUE constraint. Without that, duplicate rows kept getting inserted instead of updated. This change catches that misconfiguration during schema validation.

Changes

  • Added isSoleUniqueOrPrimaryKeyColumn, which queries INFORMATION_SCHEMA.STATISTICS to check whether the id column is the sole column of a PRIMARY KEY or UNIQUE index.
  • Added a validation step in validateTableSchema that throws IllegalStateException when this condition isn't met.

Why not COLUMNS.COLUMN_KEY?

An earlier approach considered simply checking whether INFORMATION_SCHEMA.COLUMNS.COLUMN_KEY equals 'PRI', but that was rejected for two reasons:

  1. Misses UNIQUE constraints: ON DUPLICATE KEY UPDATE works the same way for UNIQUE constraints as for the PRIMARY KEY, so checking only 'PRI' would wrongly reject valid schemas.
  2. False pass on composite keys: COLUMN_KEY reports 'PRI'/'UNI' even when a column is merely part of a composite PRIMARY KEY/UNIQUE constraint. For example, in a table with PRIMARY KEY (id, tenant_id), id shows COLUMN_KEY = 'PRI', even though id alone doesn't guarantee uniqueness — this case should fail validation but wouldn't have.

To address this, the check was rewritten as a query against INFORMATION_SCHEMA.STATISTICS that directly verifies "does a unique index made up of exactly this one column exist?"

SELECT s.INDEX_NAME FROM INFORMATION_SCHEMA.STATISTICS s
WHERE s.TABLE_SCHEMA = ? AND s.TABLE_NAME = ? AND s.NON_UNIQUE = 0
GROUP BY s.INDEX_NAME
HAVING COUNT(*) = 1 AND SUM(s.COLUMN_NAME = ?) = 1
  • NON_UNIQUE = 0: includes both PRIMARY and UNIQUE indexes
  • HAVING COUNT(*) = 1: only single-column indexes (excludes composite keys)
  • SUM(COLUMN_NAME = ?) = 1: confirms the matched column is the id under validation

Notes

  • idFieldName is already a quoted identifier, so a separate raw (unquoted) column name (rawIdColumnName) is kept around to compare against INFORMATION_SCHEMA.STATISTICS.COLUMN_NAME, which returns raw names.
  • Columns that are part of a composite PRIMARY KEY/UNIQUE constraint are intentionally excluded from passing validation (documented in the Javadoc).

Behavior change

When schema validation is enabled (schemaValidation = true), existing tables without a single-column PRIMARY KEY or UNIQUE constraint on id will now fail schema validation at startup instead of silently duplicating rows at runtime during batch upsert.

Tests

Added 5 scenarios to MariaDBSchemaValidatorIT

  • id is the sole PRIMARY KEY → passes (validatesSuccessfullyWhenIdIsSolePrimaryKey)
  • id is a sole UNIQUE column → passes (validatesSuccessfullyWhenIdIsSoleUniqueColumn)
  • id has no unique constraint at all → throws (rejectsWhenIdHasNoUniqueConstraint)
  • id is part of a composite PRIMARY KEY → throws (rejectsWhenIdIsPartOfCompositePrimaryKey)
  • id is part of a composite UNIQUE index → throws (rejectsWhenIdIsPartOfCompositeUniqueConstraint)

INSERT ... ON DUPLICATE KEY UPDATE only behaves as an upsert
when the id column is backed by a single-column PRIMARY KEY or
UNIQUE constraint. Without that, duplicate rows kept getting
inserted instead of updated, and this misconfiguration went
undetected by schema validation.

Add isSoleUniqueOrPrimaryKeyColumn, which queries
INFORMATION_SCHEMA.STATISTICS to verify the id column is the
sole column of a PRIMARY KEY or UNIQUE index, and fail schema
validation when it isn't.

Add MariaDBSchemaValidatorIT covering sole/composite PRIMARY
KEY and UNIQUE constraint scenarios.

Signed-off-by: dev-xong <songyoona1209@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants