1212// See the License for the specific language governing permissions and
1313// limitations under the License.
1414
15+ use std:: collections:: HashMap ;
1516use std:: sync:: Arc ;
1617
1718use databend_common_ast:: ast:: Expr as AExpr ;
@@ -25,6 +26,7 @@ use databend_common_catalog::table_context::TableContext;
2526use databend_common_exception:: ErrorCode ;
2627use databend_common_exception:: Result ;
2728use databend_common_expression:: ColumnId ;
29+ use databend_common_expression:: ColumnIndex ;
2830use databend_common_expression:: Constant ;
2931use databend_common_expression:: DataSchemaRef ;
3032use databend_common_expression:: Expr ;
@@ -454,9 +456,39 @@ pub fn analyze_cluster_keys(
454456 ctx : Arc < dyn TableContext > ,
455457 table_meta : Arc < dyn Table > ,
456458 sql : & str ,
457- ) -> Result < ( String , Vec < Expr < Symbol > > ) > {
459+ ) -> Result < ( String , Vec < Expr < FieldIndex > > ) > {
460+ analyze_cluster_keys_impl (
461+ ctx,
462+ table_meta,
463+ sql,
464+ |_, column| Ok ( column. as_field_index ( ) ) ,
465+ )
466+ }
467+
468+ pub fn analyze_cluster_key_order (
469+ ctx : Arc < dyn TableContext > ,
470+ table_meta : Arc < dyn Table > ,
471+ sql : & str ,
472+ column_id_to_symbol : & HashMap < ColumnId , Symbol > ,
473+ ) -> Result < Vec < Expr < Symbol > > > {
474+ let ( _, exprs) = analyze_cluster_keys_impl ( ctx, table_meta, sql, |column_id, _| {
475+ column_id_to_symbol
476+ . get ( & column_id)
477+ . copied ( )
478+ . ok_or_else ( || ErrorCode :: Internal ( "Cluster key column should exist in table metadata" ) )
479+ } ) ?;
480+ Ok ( exprs)
481+ }
482+
483+ fn analyze_cluster_keys_impl < Index : ColumnIndex + Copy > (
484+ ctx : Arc < dyn TableContext > ,
485+ table_meta : Arc < dyn Table > ,
486+ sql : & str ,
487+ mut project_column : impl FnMut ( ColumnId , Symbol ) -> Result < Index > ,
488+ ) -> Result < ( String , Vec < Expr < Index > > ) > {
458489 let ast_exprs = parse_cluster_key_exprs ( sql) ?;
459490 let ( mut bind_context, metadata) = bind_table ( table_meta) ?;
491+ let metadata_ref = metadata. clone ( ) ;
460492 let name_resolution_ctx = NameResolutionContext :: try_from ( ctx. get_settings ( ) . as_ref ( ) ) ?;
461493 let mut type_checker = TypeChecker :: try_create (
462494 & mut bind_context,
@@ -478,13 +510,30 @@ pub fn analyze_cluster_keys(
478510 let mut cluster_keys = Vec :: with_capacity ( exprs. len ( ) ) ;
479511 for ast in ast_exprs {
480512 let ( scalar, _) = * type_checker. resolve ( & ast) ?;
481- if scalar. used_columns ( ) . len ( ) != 1 || !scalar. evaluable ( ) {
513+ let used_columns = scalar. used_columns ( ) ;
514+ if used_columns. len ( ) != 1 || !scalar. evaluable ( ) {
482515 return Err ( ErrorCode :: InvalidClusterKeys ( format ! (
483516 "Cluster by expression `{:#}` is invalid" ,
484517 ast
485518 ) ) ) ;
486519 }
487520
521+ let column = * used_columns
522+ . iter ( )
523+ . next ( )
524+ . expect ( "cluster key should use one column" ) ;
525+ let column_id = {
526+ let metadata = metadata_ref. read ( ) ;
527+ let ColumnEntry :: BaseTableColumn ( BaseTableColumn { column_id, .. } ) =
528+ metadata. column ( column)
529+ else {
530+ return Err ( ErrorCode :: InvalidClusterKeys ( format ! (
531+ "Cluster by expression `{:#}` is invalid" ,
532+ ast
533+ ) ) ) ;
534+ } ;
535+ * column_id
536+ } ;
488537 let expr = scalar. as_symbol_expr ( ) ?;
489538 if !expr. is_deterministic ( & BUILTIN_FUNCTIONS ) {
490539 return Err ( ErrorCode :: InvalidClusterKeys ( format ! (
@@ -501,6 +550,8 @@ pub fn analyze_cluster_keys(
501550 ) ) ) ;
502551 }
503552
553+ let target_column = project_column ( column_id, column) ?;
554+ let expr = expr. project_column_ref ( |_| Ok ( target_column) ) ?;
504555 exprs. push ( expr) ;
505556
506557 let mut cluster_by = ast. clone ( ) ;
0 commit comments