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]