daniellansun commented on PR #3155:
URL: https://github.com/apache/groovy/pull/3155#issuecomment-6768283276

   Jochen, thanks for the review. I agree with the direction: a mapping that 
cannot be decided should be rejected or left in memory, not emitted as a guess. 
The four points are handled as follows.
   
   **Mixed-mode rows.** A pushed join is no longer reconstructed from the 
labels of `alias.*` on the joined result. Each source is probed, the prefix is 
re-run with those columns named explicitly, and the values are read back by 
ordinal onto that source's own labels. `e.name.reverse(), d.name.reverse()` 
therefore keeps both names. Duplicate labels within one source are rejected 
rather than dropped, because JDBC labels, case folding and quoting are not a 
stable copy of the table. The ordinal that re-aligns the join is not stored as 
a column, so a real column named `__ginq_mixed_key` stays readable.
   
   **Nulls.** `==` and `!=` against a null literal are still `IS NULL` / `IS 
NOT NULL`. Every other comparison is null-safe (`IS NOT DISTINCT FROM`, MySQL 
`<=>`, SQLite `IS`), so `where e.deptId == wanted` matches a null `deptId` when 
`wanted` is null. `!in` on a list or a constant range keeps null rows (`IS NULL 
OR` outside the bounds / the list). Comparisons `<` `<=` `>` `>=`, and `AND` / 
`OR` / `NOT`, stay SQL three-valued logic: a null is not ordered below every 
value the way Groovy would order it. The user guide now lists each mapping and 
where the semantics differ. The exact result of a mapped function still depends 
on the database.
   
   **`+` and text methods.** `e.name + suffix` is no longer arithmetic. `+` is 
concatenation only when the left side is text, or a column stands beside a 
string literal, and addition only when a number anchors it (`e.salary + 1`) or 
both sides are numbers. A captured variable is pushed only when its declared 
type is text or numeric, or it is cast (`(suffix as String)`, `(bonus as 
int)`). Two columns are not pushed. `length()` and the other text methods are 
pushed only for a column or a value known to be text. Otherwise strict mode 
rejects the construct and mixed mode evaluates it in memory.
   
   **Dialects.** Whether a function can be rendered is one table, shared by the 
translator and both renderers. SQLite does not include `FLOOR` or `CEILING`. 
Strict mode rejects those calls. Mixed mode leaves the clause that uses them in 
memory and can still push the rest. A function that is only spelled 
differently, such as `CHAR_LENGTH` as `LENGTH`, is still pushed. Adding another 
gap is an entry in that table, not a special case in the planner. `ntile` uses 
integer division, so it does not depend on `FLOOR`.
   


-- 
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]

Reply via email to