When I execute an upsert with filters through the Phoenix JDBC connector, preparedStatement.executeUpdate returns ~2x the number of executed rows. If the upsert doesn't change the filtered columns, the number it returns is stable within a codebase (i.e. I am attempting to update 100000 rows, calling executeUpdate repeatedly returns 195000 every time) but not across them (when I execute the exact same update in a different codebase, executeUpdate returns 197500 every time it's called). Executing queries with just the filter clauses (i.e. everything from SELECT onwards in the upsert) returns 100000 rows, as expected, and running the upsert through SQLLine correctly notes that 100000 rows were updated.
After looking at the SQLLine code, I tried replacing my preparedStatement with a Statement, but both statement.executeUpdate and statement.executeBatch returned 195000 (as expected from the Phoenix code). I also confirmed this count mismatch on a newly created tables with no indices, views, etc. (I expected 6666 rows to be updated, as SQLLine confirms, but executeUpdate returned 12666).