j1wonpark commented on code in PR #56688:
URL: https://github.com/apache/spark/pull/56688#discussion_r3487104867


##########
sql/connect/client/jdbc/src/main/scala/org/apache/spark/sql/connect/client/jdbc/SparkConnectDatabaseMetaData.scala:
##########
@@ -816,4 +882,77 @@ object SparkConnectDatabaseMetaData {
   )
 
   private[jdbc] val TABLE_TYPES = Seq("TABLE", "VIEW")
+
+  // One row of the java.sql.DatabaseMetaData.getTypeInfo result.
+  private type TypeInfoRow =
+    (
+        String,  // TYPE_NAME
+        Int,     // DATA_TYPE
+        Int,     // PRECISION
+        String,  // LITERAL_PREFIX
+        String,  // LITERAL_SUFFIX
+        String,  // CREATE_PARAMS
+        Short,   // NULLABLE
+        Boolean, // CASE_SENSITIVE
+        Short,   // SEARCHABLE
+        Boolean, // UNSIGNED_ATTRIBUTE
+        Boolean, // FIXED_PREC_SCALE
+        Boolean, // AUTO_INCREMENT
+        String,  // LOCAL_TYPE_NAME
+        Short,   // MINIMUM_SCALE
+        Short,   // MAXIMUM_SCALE
+        Int,     // SQL_DATA_TYPE
+        Int,     // SQL_DATETIME_SUB
+        Int      // NUM_PREC_RADIX
+    )
+
+  // Fills the columns that are constant across all Spark atomic types: every 
type is
+  // nullable and searchable, and none are unsigned, fixed-prec-scale, or 
auto-increment.
+  // `literalQuote` is used as both the literal prefix and suffix.
+  private def typeRow(
+      typeName: String,
+      dataType: Int,
+      precision: Int,
+      literalQuote: String,
+      createParams: String,
+      caseSensitive: Boolean,
+      minScale: Short,
+      maxScale: Short,
+      numPrecRadix: Int): TypeInfoRow =
+    (
+      typeName,
+      dataType,
+      precision,
+      literalQuote,
+      literalQuote,
+      createParams,
+      typeNullable.toShort,
+      caseSensitive,
+      typeSearchable.toShort,
+      false,
+      false,
+      false,
+      null,
+      minScale,
+      maxScale,
+      0,
+      0,
+      numPrecRadix)
+
+  // Static JDBC type metadata for the Spark SQL atomic types, mirroring the
+  // JdbcTypeUtils type-code/precision mapping. Only STRING is case-sensitive.
+  // TIME and TIMESTAMP_NTZ are omitted (new and duplicate JDBC type codes).
+  private[jdbc] val TYPE_INFO: Seq[TypeInfoRow] = Seq(
+    typeRow("BOOLEAN", Types.BOOLEAN, 1, null, null, false, 0, 0, 0),
+    typeRow("TINYINT", Types.TINYINT, 3, null, null, false, 0, 0, 10),
+    typeRow("SMALLINT", Types.SMALLINT, 5, null, null, false, 0, 0, 10),
+    typeRow("INT", Types.INTEGER, 10, null, null, false, 0, 0, 10),
+    typeRow("BIGINT", Types.BIGINT, 19, null, null, false, 0, 0, 10),
+    typeRow("FLOAT", Types.FLOAT, 7, null, null, false, 0, 0, 10),
+    typeRow("DOUBLE", Types.DOUBLE, 15, null, null, false, 0, 0, 10),
+    typeRow("DECIMAL", Types.DECIMAL, 38, null, "precision,scale", false, 0, 
38, 10),
+    typeRow("STRING", Types.VARCHAR, Int.MaxValue, "'", null, true, 0, 0, 0),
+    typeRow("BINARY", Types.VARBINARY, Int.MaxValue, "'", null, false, 0, 0, 
0),

Review Comment:
   Fixed in 1303ab8: `BINARY` now reports `LITERAL_PREFIX` `X'` and 
`LITERAL_SUFFIX` `'` to match the hex literal syntax.



##########
sql/connect/client/jdbc/src/test/scala/org/apache/spark/sql/connect/client/jdbc/SparkConnectDatabaseMetaDataSuite.scala:
##########
@@ -808,4 +808,100 @@ class SparkConnectDatabaseMetaDataSuite extends 
ConnectFunSuite with RemoteSpark
       }
     }
   }
+
+  test("SparkConnectDatabaseMetaData getPrimaryKeys") {
+    withConnection { conn =>
+      val metadata = conn.getMetaData
+      // Spark has no primary keys, so an empty result set with the JDBC 
schema is returned.
+      Using.resource(metadata.getPrimaryKeys(null, null, null)) { rs =>
+        val rsmd = rs.getMetaData
+        assert((1 to rsmd.getColumnCount).map(rsmd.getColumnName) === Seq(
+          "TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "COLUMN_NAME", "KEY_SEQ", 
"PK_NAME"))
+        assert(!rs.next())
+      }
+    }
+  }
+
+  test("SparkConnectDatabaseMetaData getImportedKeys and getExportedKeys") {
+    withConnection { conn =>
+      val metadata = conn.getMetaData
+      val foreignKeySchema = Seq(
+        "PKTABLE_CAT", "PKTABLE_SCHEM", "PKTABLE_NAME", "PKCOLUMN_NAME",
+        "FKTABLE_CAT", "FKTABLE_SCHEM", "FKTABLE_NAME", "FKCOLUMN_NAME",
+        "KEY_SEQ", "UPDATE_RULE", "DELETE_RULE", "FK_NAME", "PK_NAME", 
"DEFERRABILITY")
+      // Spark has no foreign keys, so both return an empty result set with 
the JDBC schema.
+      Seq(
+        () => metadata.getImportedKeys(null, null, null),
+        () => metadata.getExportedKeys(null, null, null)).foreach { 
getForeignKeys =>
+        Using.resource(getForeignKeys()) { rs =>
+          val rsmd = rs.getMetaData
+          assert((1 to rsmd.getColumnCount).map(rsmd.getColumnName) === 
foreignKeySchema)
+          assert(!rs.next())
+        }
+      }
+    }
+  }
+
+  test("SparkConnectDatabaseMetaData getTypeInfo") {
+    withConnection { conn =>
+      val metadata = conn.getMetaData
+      Using.resource(metadata.getTypeInfo) { rs =>
+        val rsmd = rs.getMetaData
+        assert((1 to rsmd.getColumnCount).map(rsmd.getColumnName) === Seq(

Review Comment:
   Done in eef0e8a: the getTypeInfo test now asserts PRECISION, CREATE_PARAMS, 
(MINIMUM_SCALE, MAXIMUM_SCALE), the literal quotes, and NUM_PREC_RADIX for 
every type, so the per-type fidelity is locked in.



##########
sql/connect/client/jdbc/src/main/scala/org/apache/spark/sql/connect/client/jdbc/SparkConnectDatabaseMetaData.scala:
##########
@@ -816,4 +882,77 @@ object SparkConnectDatabaseMetaData {
   )
 
   private[jdbc] val TABLE_TYPES = Seq("TABLE", "VIEW")
+
+  // One row of the java.sql.DatabaseMetaData.getTypeInfo result.
+  private type TypeInfoRow =

Review Comment:
   Done in 684e0ec: `TypeInfoRow` and `typeRow` are now `private[jdbc]`.



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


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to