Commit Graph

5 Commits

Author SHA1 Message Date
Mihir Kandoi
f751f80158 ci(postgres): flag division by a possibly-zero divisor in the compat guard (#56363)
Adds the division-by-zero divergence class to the PG-compat review tooling:
on a divisor that the data can drive to 0 (e.g. Sum(a)/Sum(b)), MariaDB
returns NULL for division by zero while PostgreSQL raises `division by zero`
and aborts the query. The portable fix is to wrap the divisor in
NullIf(divisor, 0), which yields NULL on both engines (matching MariaDB).

- .greptile/config.json: add it to the "would ERROR on PostgreSQL" list.
- .github/POSTGRES_COMPATIBILITY.md: document it under §1 (hard breaks).
- .github/helper/postgres_compat.py: note it in the docstring as a
  deliberately-not-statically-checked semantic divergence (data-dependent,
  like integer-division intent), so it stays a reviewer/Greptile concern.

Tooling-only; no source query changes. The instance fix shipped in #56361.
2026-06-23 12:00:50 +00:00
Mihir Kandoi
2f4e78f09e ci(postgres): flag COALESCE/IfNull of a typed column with a mismatched-type literal (#56358)
ci(postgres): teach the guard about COALESCE(date, int) type mismatch

New class found by the whole-repo audit (the Asset Depreciations report fix in this PR): IfNull/Coalesce of a typed column with a different-typed literal -- e.g. IfNull(date_col, 0) -> COALESCE(date, integer), which PostgreSQL rejects (DatatypeMismatch). Added to the Greptile config and POSTGRES_COMPATIBILITY.md (not statically checkable without column types).
2026-06-23 16:52:48 +05:30
Mihir Kandoi
fc9544435e ci(postgres): teach the PG-compat tooling the audit 6-9 divergence classes
The whole-repo MariaDB<->PostgreSQL audits surfaced classes the checker and
review guide did not yet cover. Add them:

Static checker (.github/helper/postgres_compat.py) - new mechanical breaks:
- .rlike() / raw RLIKE: frappe rewrites REGEXP->~* on Postgres but NOT RLIKE.
- Cast(x, "char") / raw CAST AS CHAR: bare CHAR is character(1) on Postgres
  and truncates multi-digit values; use "varchar".
(Both flag zero production code; the only repo hit is in patches/, which the
hook already excludes.)

Greptile config + POSTGRES_COMPATIBILITY.md - new semantic/hard classes:
- aggregate (Sum/Count) selected next to bare columns with no GROUP BY at all.
- .like()/LIKE on a non-text column (bigint ILIKE) -> Cast_ to varchar.
- get_all(fields=["CapitalCase"]) identifier-case (extends the get_value case).
- bool into a Check column via qb.update().set() (extends set_value/db_set).
- int/int division: float a literal (col/1440 -> col/1440.0).
- Concat over a nullable column leaking a bare prefix on Postgres.
- clarify REGEXP/.regexp() is translated but RLIKE/.rlike() is not.
2026-06-23 12:22:22 +05:30
Mihir Kandoi
3e2d61262a ci(greptile): widen guide scope to SQL-bearing non-Python files; fix HAVING-alias wording
Address Greptile review:
- customContext.files scope was **/*.py only, so Query Report SQL in .js/.sql/report .json
  files didn't get the guide attached as context (the global instructions still applied).
  Widen to .py/.js/.sql/report **/*.json.
- The guide's HAVING-alias rule said "with no GROUP BY"; PostgreSQL rejects a SELECT-alias in
  HAVING regardless of GROUP BY. Reworded to match (repeat the expression, or move a
  non-aggregate predicate to WHERE).
2026-06-22 09:34:23 +05:30
Mihir Kandoi
4a690c86d2 ci(greptile): teach the review bot to enforce MariaDB↔PostgreSQL parity
The PostgreSQL server-test job is label-gated, so until it is required the Greptile
PR-review bot is the always-on guard against cross-engine breaks. Extend
.greptile/config.json with `instructions` (and a `customContext` reference to a new
guide) so every review flags new/changed queries that would error on PostgreSQL or
silently diverge from MariaDB, under the prime rule that MariaDB output must not change.

- .github/POSTGRES_COMPATIBILITY.md — the catalogue the bot (and contributors) follow:
  hard breaks (loose GROUP BY, MySQL-only funcs, UPDATE..JOIN, HAVING-on-alias,
  DISTINCT+ORDER BY, single-quoted alias, varchar bitwise OR, capital identifiers,
  set_value(Check,bool)), silent divergences (text case-sensitivity, name-lookup case,
  empty-string↔NULL, NULL ordering, ORDER BY..LIMIT 1 tiebreakers, integer division,
  distinct-drops-ORDER-BY-on-PG + casefold sorting, function-rewrite parity, UnixTimestamp
  TZ), the GROUP BY row-count trap (Max()-wrap vs add-to-GROUP-BY; FD-by-source-table),
  the InFailedSqlTransaction/savepoint rule, and the false positives NOT to flag
  (.like→ILIKE, ifnull/backtick/LOCATE/REGEXP auto-translation, MariaDB-changing tiebreakers).
- Existing disabledLabels and frappe/frappe context are preserved.
2026-06-22 09:29:19 +05:30