LuciferYang opened a new pull request, #59545:
URL: https://github.com/apache/spark/pull/59545
### What changes were proposed in this pull request?
`ALTER TABLE ... ADD CONSTRAINT ... CHECK` builds the V2 predicate it stores
in the catalog from the optimized condition, so a function that the optimizer
replaces with its current value is stored as its value at the time of the ALTER
TABLE. This covers `current_timestamp()`, `now()`, `current_date()`,
`localtimestamp()`, `current_database()`, `current_user()` and casts like
`CAST('now' AS TIMESTAMP)` or `to_timestamp('now')`. Later writes check the
stored predicate.
This PR makes `CheckConstraint` keep its analyzed condition, as
`DefaultValueExpression` and `GeneratedColumnExpression` do
(`AnalysisAwareExpression`). When the condition reads such a value, the
predicate is built from the analyzed condition, as CREATE TABLE builds it, so
each write computes the value itself. For `current_timestamp()` that predicate
has no V2 form and writes check `predicateSql`, as for the same constraint
created by CREATE TABLE. Any other condition is built from the optimized
condition as before.
The analyzed condition is not used for every constraint: a
`RuntimeReplaceable` such as `nullif` has no V2 form there, and writes would
have to parse `predicateSql`, which does not resolve a column qualified by the
table name (`tbl.id`) the way ALTER TABLE does.
### Why are the changes needed?
```sql
CREATE TABLE t (id INT, ts TIMESTAMP);
ALTER TABLE t ADD CONSTRAINT vt CHECK (ts <= current_timestamp());
-- the stored predicate is ts <= <the time of the ALTER TABLE>
INSERT INTO t VALUES (1, current_timestamp());
-- [CHECK_CONSTRAINT_VIOLATION] CHECK constraint vt ts <=
current_timestamp() violated ...
```
### Does this PR introduce _any_ user-facing change?
Yes. A CHECK constraint added by ALTER TABLE that reads the current time,
date, catalog, user and the like is checked against their values at the time of
each write, as one created by CREATE TABLE is. A constraint added before this
change keeps the predicate it was stored with.
### How was this patch tested?
`CheckConstraintSuite`:
- A constraint `creation_time <= <now>` added by ALTER TABLE, with
`current_timestamp()`, `CAST('now' AS TIMESTAMP)` and `to_timestamp('now')` as
`<now>`, accepts a row written with the current time and rejects one written
with tomorrow. It fails without the change.
- A constraint `nullif(tbl.id, 3) > 0` added by ALTER TABLE on a table with
a struct column `tbl` checks the column `id` on later writes, the column ALTER
TABLE resolved `tbl.id` to. It passes without the change and fails if every
constraint is built from its analyzed condition.
### Was this patch authored or co-authored using generative AI tooling?
Generated-by: Claude Opus 5
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]