mingnuj commented on issue #44467:
URL: https://github.com/apache/arrow/issues/44467#issuecomment-2440540273

   I've been building each Flight SQL-related branch following the Arrow 15.0.0 
release and identified an issue occurring after commit [GH-33475: Add parameter 
binding for Prepared Statements in JDBC driver (#38404)].
   
   After debugging last week, I observed the following:
   
   When querying from DBeaver, the `prepareAndExecute` function is called 
within `ArrowFlightMetaImpl.java` in `flight-sql-jdbc-core`. Before this 
commit, the signature in `ArrowFlightMetaImpl` was a fixed value, declared as 
final. However, with the parameter binding addition, the code now utilizes the 
handle's signature, making it mutable.
   
   * Previous code (ArrowFlightMetaImpl.java, line 160):
       ```java
       final Signature signature = newSignature(query); // Immutable
       final long updateCount = statementType.equals(StatementType.UPDATE) ? 
preparedStatement.executeUpdate() : -1;
       synchronized (callback.getMonitor()) {
           callback.clear();
           callback.assign(signature, null, updateCount);
       }
       callback.execute();
       final MetaResultSet metaResultSet = 
MetaResultSet.create(handle.connectionId, handle.id, false, signature, null);
       ``` 
   * Updated code (ArrowFlightMetaImpl.java, line 196):
       ```java
       PreparedStatement preparedStatement = prepareForHandle(query, handle);
       final StatementType statementType = preparedStatement.getType();
       final long updateCount = statementType.equals(StatementType.UPDATE) ? 
preparedStatement.executeUpdate() : -1;
       synchronized (callback.getMonitor()) {
           callback.clear();
           callback.assign(handle.signature, null, updateCount);
       }
       callback.execute();
       final MetaResultSet metaResultSet = 
MetaResultSet.create(handle.connectionId, handle.id, false, handle.signature, 
null); // Mutable
       ```
   
   The addition is needed for parameter binding, yet it introduces an issue 
where columns are appended repeatedly. During execution, the 
`executeFlightInfoQuery` function in `ArrowFlightStatement.java` (in 
flight-sql-jdbc-core) is invoked, which appends columns.
   
   ```java
   @Override
   public FlightInfo executeFlightInfoQuery() throws SQLException {
      final PreparedStatement preparedStatement = 
getConnection().getMeta().getPreparedStatement(handle);
      final Meta.Signature signature = getSignature();
      if (signature == null) {
          return null;
      }
   
      final Schema resultSetSchema = preparedStatement.getDataSetSchema();
      
signature.columns.addAll(ConvertUtils.convertArrowFieldsToColumnMetaDataList(resultSetSchema.getFields()));
      setSignature(signature);
   
      return preparedStatement.executeQuery();
   }
   ```
   
   With every query, the signature column set is duplicated and propagated. In 
cases where the result has endpoints (e.g., a typical `doPut` operation in 
`FlightSqlClient`), the column list seems consistent as the signature is 
replaced with the result signature. However, in my case, where there are no 
endpoints, the columns appear duplicated.
   
   To address this, I temporarily fixed the issue by simply calling clear on 
the column list before adding new columns.
   ```java
   @Override
   public FlightInfo executeFlightInfoQuery() throws SQLException {
      final PreparedStatement preparedStatement = 
getConnection().getMeta().getPreparedStatement(handle);
      final Meta.Signature signature = getSignature();
      if (signature == null) {
          return null;
      }
   
      final Schema resultSetSchema = preparedStatement.getDataSetSchema();
      signature.columns.clear();
      
signature.columns.addAll(ConvertUtils.convertArrowFieldsToColumnMetaDataList(resultSetSchema.getFields()));
      setSignature(signature);
   
      return preparedStatement.executeQuery();
   }
   ```
   
   However, I believe a more fundamental solution could be beneficial here. 
Could anyone provide insights or assistance?
   Thank you.


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