googleapis / java-spanner-jdbc

Apache License 2.0
64 stars 48 forks source link

Let ParameterMetadata for PreparedStatement report correct ParameterType before execution #35

Closed jeffersonatsafe closed 10 months ago

jeffersonatsafe commented 4 years ago

Thanks for stopping by to let us know something could be better!

Is your feature request related to a problem? Please describe. When using PreparedStatements with parameters, I need to obtain the parameters' JDBC Types before executing the PreparedStatement (so I can set the values of the parameters using the correct object types). The current version of the driver (v 1.12.0) does not allow this. Before executing the PreparedStatement, all parameters will be reported as JDBCType = 1111. After manually setting the parameters and executing the PreparedStatement, the ParameterMetaData will then report the correct parameter types.

Describe the solution you'd like ParameterMetaData to return the correct parameter types before PreparedStatement is executed.

Describe alternatives you've considered The alternative is to do a column name matching using the destination table schema, so I'm able to figure out the data types of the destination columns, and set the objects accordingly. However, this feels like a hacky solution.

Additional context Code snippet:

      Connection connection = driver.connect(connString, connProps);
      Statement statement = connection.createStatement();
      statement.execute("Create table manualTable (mykey int64, myint int64) primary key (mykey)");
      ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();
      PreparedStatement preparedStatement = connection.prepareStatement(
            "INSERT INTO `manualTable` (`mykey`, `myint`) VALUES (?, ?)");
      for (int i = 1; i <= parameterMetaData.getParameterCount(); i++ )
      {
         int jdbcTypeInt = parameterMetaData.getParameterType(i);
         JDBCType jdbcType = JDBCType.valueOf(jdbcTypeInt);
         System.out.println(String.format(
               "parameter %d is JDBC Type: %d - %s",
               i,
               jdbcTypeInt,
               jdbcType.getName()));
      }

Thanks!

olavloite commented 4 years ago

This feature will not be trivial to implement, as the Cloud Spanner backend does not have any API that can be used to get this information. It would only be possible to implement this by parsing the SQL statement in the driver and extracting the type information from the schema metadata tables (basically what you also describe as your workaround). I'm not sure that this is something that we would want to do in this driver.