JingsongLi commented on code in PR #444:
URL: https://github.com/apache/paimon-rust/pull/444#discussion_r3519363955


##########
crates/integrations/datafusion/src/table/mod.rs:
##########
@@ -89,6 +97,131 @@ impl PaimonTableProvider {
     }
 }
 
+/// Build a `CREATE TABLE` DDL string for a Paimon table.
+///
+/// Mirrors the syntax accepted by `SQLContext::handle_create_table`:
+/// `CREATE TABLE <db>.<table> (<col> <type>, ..., PRIMARY KEY (...)) 
[PARTITIONED BY (...)] [WITH ('k'='v', ...)]`.
+fn build_table_definition(table: &Table) -> String {
+    let identifier = table.identifier();
+    let schema = table.schema();
+    let mut ddl = String::new();
+    let _ = write!(
+        ddl,
+        "CREATE TABLE {}.{} (",

Review Comment:
   `SHOW CREATE TABLE` should emit replayable SQL, but the table name is 
written without identifier quoting. A table created with quoted identifiers 
such as `CREATE TABLE paimon.test_db."select" ("order" INT)` would be rendered 
as `CREATE TABLE test_db.select (order INT)`, which is invalid or changes the 
identifier semantics when re-executed. The same issue applies to column names, 
primary/partition keys, and nested struct field names below. Please quote 
identifiers when required and escape embedded quotes, then add a round-trip 
case with a reserved-word or otherwise quoted identifier.



##########
crates/integrations/datafusion/src/table/mod.rs:
##########
@@ -89,6 +97,131 @@ impl PaimonTableProvider {
     }
 }
 
+/// Build a `CREATE TABLE` DDL string for a Paimon table.
+///
+/// Mirrors the syntax accepted by `SQLContext::handle_create_table`:
+/// `CREATE TABLE <db>.<table> (<col> <type>, ..., PRIMARY KEY (...)) 
[PARTITIONED BY (...)] [WITH ('k'='v', ...)]`.
+fn build_table_definition(table: &Table) -> String {
+    let identifier = table.identifier();
+    let schema = table.schema();
+    let mut ddl = String::new();
+    let _ = write!(
+        ddl,
+        "CREATE TABLE {}.{} (",
+        identifier.database(),
+        identifier.object()
+    );
+
+    for (i, field) in schema.fields().iter().enumerate() {
+        if i > 0 {
+            ddl.push_str(", ");
+        }
+        // `NOT NULL` is a column constraint; render it here at the column
+        // level rather than inside nested type arguments (see 
`data_type_to_sql`).
+        let ty = data_type_to_sql(field.data_type());
+        if field.data_type().is_nullable() {
+            let _ = write!(ddl, "{} {}", field.name(), ty);
+        } else {
+            let _ = write!(ddl, "{} {} NOT NULL", field.name(), ty);
+        }
+    }
+
+    let pks = schema.primary_keys();
+    if !pks.is_empty() {
+        ddl.push_str(", PRIMARY KEY (");
+        for (i, pk) in pks.iter().enumerate() {
+            if i > 0 {
+                ddl.push_str(", ");
+            }
+            let _ = write!(ddl, "{}", pk);
+        }
+        ddl.push(')');
+    }
+    ddl.push(')');
+
+    let partition_keys = schema.partition_keys();
+    if !partition_keys.is_empty() {
+        ddl.push_str(" PARTITIONED BY (");
+        for (i, pk) in partition_keys.iter().enumerate() {
+            if i > 0 {
+                ddl.push_str(", ");
+            }
+            let _ = write!(ddl, "{}", pk);
+        }
+        ddl.push(')');
+    }
+
+    let options = schema.options();
+    if !options.is_empty() {
+        ddl.push_str(" WITH (");
+        for (i, (k, v)) in options.iter().enumerate() {
+            if i > 0 {
+                ddl.push_str(", ");
+            }
+            let _ = write!(ddl, "'{}' = '{}'", k, v);

Review Comment:
   This needs SQL string escaping before interpolation. Option values are 
arbitrary table metadata, so a value containing a single quote, for example 
`WITH ('comment' = 'Bob's table')`, makes the returned definition invalid when 
users copy or re-execute `SHOW CREATE TABLE`. Please render string literals 
with SQL escaping (doubling `'` to `''`) for both keys and values, and add a 
round-trip test with an option value containing a quote.



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