@@ -3088,8 +3088,9 @@ pub fn create_cube_regclass_cast_udf() -> ScalarUDF {
3088
3088
match PgType :: get_all ( ) . iter ( ) . find ( |e| e. typname == as_str) {
3089
3089
None => {
3090
3090
// 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
3092
3092
// For now, we'll return 0 so metabase can sync without failing
3093
+ // TODO actually read `pg_type`
3093
3094
if as_str. contains ( '.' ) {
3094
3095
builder. append_value ( 0 ) ?;
3095
3096
} else {
@@ -3156,6 +3157,7 @@ pub fn create_pg_get_serial_sequence_udf() -> ScalarUDF {
3156
3157
}
3157
3158
3158
3159
// 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
3159
3161
// TODO: Implement this
3160
3162
pub fn create_col_description_udf ( ) -> ScalarUDF {
3161
3163
let fun = make_scalar_function ( move |args : & [ ArrayRef ] | {
@@ -3174,15 +3176,26 @@ pub fn create_col_description_udf() -> ScalarUDF {
3174
3176
3175
3177
ScalarUDF :: new (
3176
3178
"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
3177
3185
& 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 ,
3180
3192
) ,
3181
3193
& return_type,
3182
3194
& fun,
3183
3195
)
3184
3196
}
3185
3197
3198
+ // See https://www.postgresql.org/docs/17/functions-string.html#FUNCTIONS-STRING-FORMAT
3186
3199
pub fn create_format_udf ( ) -> ScalarUDF {
3187
3200
let fun = make_scalar_function ( move |args : & [ ArrayRef ] | {
3188
3201
// Ensure at least one argument is provided
@@ -3255,11 +3268,11 @@ pub fn create_format_udf() -> ScalarUDF {
3255
3268
}
3256
3269
} ;
3257
3270
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 ;
3263
3276
3264
3277
if needs_quoting {
3265
3278
result. push ( '"' ) ;
@@ -3298,6 +3311,10 @@ pub fn create_format_udf() -> ScalarUDF {
3298
3311
3299
3312
ScalarUDF :: new (
3300
3313
"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
3301
3318
& Signature :: variadic ( vec ! [ DataType :: Utf8 ] , Volatility :: Immutable ) ,
3302
3319
& return_type,
3303
3320
& fun,
0 commit comments