# PreparedStatement Valid Indices
# Detects PreparedStatement and ResultSet methods with invalid indices
id: prepared-statement-valid-indices
name: PreparedStatement Methods Should Use Valid Indices
severity: error
category: reliability
defect_class: correctness
inline_tier: blocking
language: java

message: "PreparedStatement/ResultSet methods should use valid indices (1-based)"

description: |
  PreparedStatement and ResultSet methods use 1-based indices (not 0-based).
  Using 0 or negative indices causes SQLException. This is a common mistake
  for developers used to 0-based arrays.

  ✅ FIX: Use 1-based indices

  ```java
  PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE id = ?");
  stmt.setInt(1, userId);  // GOOD - index 1, not 0
  ```

query: |
  (method_invocation
    name: (identifier) @METHOD (#match? @METHOD "^(setString|setInt|setLong|setDouble|setBoolean|getString|getInt|getLong|getDouble|getBoolean)$")
    arguments: (argument_list
      (decimal_integer_literal) @INDEX) @ARGS)

metavars:
  - METHOD
  - INDEX
  - ARGS

post_filter: invalid_statement_index

tags:
  - reliability
  - java
  - sql
  - jdbc
  - common-mistake

examples:
  bad: |
    stmt.setString(0, value);  // BAD - index 0, should be 1
    String name = rs.getString(0);  // BAD - 0-based thinking

  good: |
    stmt.setString(1, value);  // GOOD - JDBC uses 1-based indices
    String name = rs.getString(1);  // GOOD

has_fix: true
fix_action: increment_index_by_1
