@@ -3088,8 +3088,9 @@ pub fn create_cube_regclass_cast_udf() -> ScalarUDF {
30883088 match PgType :: get_all ( ) . iter ( ) . find ( |e| e. typname == as_str) {
30893089 None => {
30903090 // If the type name contains a dot, it's a schema-qualified name
3091- // and we should return return the approprate RegClass to be converted to OID
3091+ // and we should return the approprate RegClass to be converted to OID
30923092 // For now, we'll return 0 so metabase can sync without failing
3093+ // TODO actually read `pg_type`
30933094 if as_str. contains ( '.' ) {
30943095 builder. append_value ( 0 ) ?;
30953096 } else {
@@ -3156,6 +3157,7 @@ pub fn create_pg_get_serial_sequence_udf() -> ScalarUDF {
31563157}
31573158
31583159// Return a NOOP for this so metabase can sync without failing
3160+ // See https://www.postgresql.org/docs/17/functions-info.html#FUNCTIONS-INFO-COMMENT here
31593161// TODO: Implement this
31603162pub fn create_col_description_udf ( ) -> ScalarUDF {
31613163 let fun = make_scalar_function ( move |args : & [ ArrayRef ] | {
@@ -3174,15 +3176,26 @@ pub fn create_col_description_udf() -> ScalarUDF {
31743176
31753177 ScalarUDF :: new (
31763178 "col_description" ,
3179+ // Correct signature for col_description should be `(oid, integer) → text`
3180+ // We model oid as UInt32, so [DataType::UInt32, DataType::Int32] is a proper arguments
3181+ // However, it seems that coercion rules in DF differs from PostgreSQL at the moment
3182+ // And metabase uses col_description(CAST(CAST(... AS regclass) AS oid), cardinal_number)
3183+ // And we model regclass as Int64, and cardinal_number as UInt32
3184+ // Which is why second signature is necessary
31773185 & Signature :: one_of (
3178- vec ! [ TypeSignature :: Exact ( vec![ DataType :: Utf8 , DataType :: Utf8 ] ) ] ,
3179- Volatility :: Immutable ,
3186+ vec ! [
3187+ TypeSignature :: Exact ( vec![ DataType :: UInt32 , DataType :: Int32 ] ) ,
3188+ // TODO remove this signature in favor of proper model/coercion
3189+ TypeSignature :: Exact ( vec![ DataType :: Int64 , DataType :: UInt32 ] ) ,
3190+ ] ,
3191+ Volatility :: Stable ,
31803192 ) ,
31813193 & return_type,
31823194 & fun,
31833195 )
31843196}
31853197
3198+ // See https://www.postgresql.org/docs/17/functions-string.html#FUNCTIONS-STRING-FORMAT
31863199pub fn create_format_udf ( ) -> ScalarUDF {
31873200 let fun = make_scalar_function ( move |args : & [ ArrayRef ] | {
31883201 // Ensure at least one argument is provided
@@ -3255,11 +3268,11 @@ pub fn create_format_udf() -> ScalarUDF {
32553268 }
32563269 } ;
32573270
3258- // Quote identifier if necessary
3259- let needs_quoting = !value
3260- . chars ( )
3261- . all ( |c| c . is_ascii_lowercase ( ) || c . is_ascii_digit ( ) || c == '_' )
3262- || value . is_empty ( ) ;
3271+ // Quote any identifier for now
3272+ // That's a safety-first approach: it would quote too much, but every edge-case would be covered
3273+ // Like `1` or `1a` or `select`
3274+ // TODO Quote identifier only if necessary
3275+ let needs_quoting = true ;
32633276
32643277 if needs_quoting {
32653278 result. push ( '"' ) ;
@@ -3298,6 +3311,10 @@ pub fn create_format_udf() -> ScalarUDF {
32983311
32993312 ScalarUDF :: new (
33003313 "format" ,
3314+ // Actually, format should be variadic with types (Utf8, any*)
3315+ // But ATM DataFusion does not support those signatures
3316+ // And this would work through implicit casting to Utf8
3317+ // TODO migrate to proper custom signature once it's supported by DF
33013318 & Signature :: variadic ( vec ! [ DataType :: Utf8 ] , Volatility :: Immutable ) ,
33023319 & return_type,
33033320 & fun,
0 commit comments