@@ -3912,6 +3912,79 @@ func createRoutinePopulate(
3912
3912
}
3913
3913
}
3914
3914
3915
+ func createRoutinePopulateByFnIndex (
3916
+ ctx context.Context ,
3917
+ unwrappedConstraint tree.Datum ,
3918
+ p * planner ,
3919
+ db catalog.DatabaseDescriptor ,
3920
+ addRow func (... tree.Datum ) error ,
3921
+ ) (matched bool , err error ) {
3922
+ // In here, we start from the DatabaseDescriptor and a routine ID and populate the remainder of a row
3923
+ // in the virtual table. This function, thus, is used to populate when indexing into the routine virtual tables,
3924
+ // `crdb_internal.create_function_statements` and `crdb_internal.create_procedure_statements`, helping
3925
+ // optimize the queries for the create statements output in `SHOW CREATE ALL ROUTINES`.
3926
+ fnID := descpb .ID (tree .MustBeDInt (unwrappedConstraint ))
3927
+ fnDesc , err := p .Descriptors ().ByIDWithoutLeased (p .txn ).WithoutNonPublic ().Get ().Function (ctx , fnID )
3928
+ if err != nil || fnDesc == nil {
3929
+ if errors .Is (err , catalog .ErrDescriptorNotFound ) || fnDesc == nil {
3930
+ return false , nil
3931
+ }
3932
+ return false , err
3933
+ }
3934
+ scID := fnDesc .GetParentSchemaID ()
3935
+ sc , err := p .Descriptors ().ByIDWithoutLeased (p .txn ).WithoutNonPublic ().Get ().Schema (ctx , scID )
3936
+ if err != nil || sc == nil {
3937
+ return false , err
3938
+ }
3939
+ scName := sc .GetName ()
3940
+ dbName := db .GetName ()
3941
+ dbID := db .GetID ()
3942
+
3943
+ treeNode , err := fnDesc .ToCreateExpr ()
3944
+ treeNode .Name .ObjectNamePrefix = tree.ObjectNamePrefix {
3945
+ ExplicitSchema : true ,
3946
+ SchemaName : tree .Name (scName ),
3947
+ }
3948
+ if err != nil {
3949
+ return false , err
3950
+ }
3951
+ for i := range treeNode .Options {
3952
+ if body , ok := treeNode .Options [i ].(tree.RoutineBodyStr ); ok {
3953
+ bodyStr := string (body )
3954
+ bodyStr , err = formatFunctionQueryTypesForDisplay (ctx , p .EvalContext (), & p .semaCtx , p .SessionData (), bodyStr , fnDesc .GetLanguage ())
3955
+ if err != nil {
3956
+ return false , err
3957
+ }
3958
+ bodyStr , err = formatQuerySequencesForDisplay (ctx , & p .semaCtx , bodyStr , true /* multiStmt */ , fnDesc .GetLanguage ())
3959
+ if err != nil {
3960
+ return false , err
3961
+ }
3962
+ bodyStr = strings .TrimSpace (bodyStr )
3963
+ stmtStrs := strings .Split (bodyStr , "\n " )
3964
+ for i := range stmtStrs {
3965
+ if stmtStrs [i ] != "" {
3966
+ stmtStrs [i ] = "\t " + stmtStrs [i ]
3967
+ }
3968
+ }
3969
+ p := & treeNode .Options [i ]
3970
+ * p = tree .RoutineBodyStr ("\n " + strings .Join (stmtStrs , "\n " ) + "\n " )
3971
+ }
3972
+ }
3973
+ createStatement := tree .AsString (treeNode )
3974
+ if err := addRow (
3975
+ tree .NewDInt (tree .DInt (dbID )), // database_id
3976
+ tree .NewDString (dbName ), // database_name
3977
+ tree .NewDInt (tree .DInt (scID )), // schema_id
3978
+ tree .NewDString (scName ), // schema_name
3979
+ tree .NewDInt (tree .DInt (fnDesc .GetID ())), // function_id
3980
+ tree .NewDString (fnDesc .GetName ()), // function_name
3981
+ tree .NewDString (createStatement ), // create_statement
3982
+ ); err != nil {
3983
+ return false , err
3984
+ }
3985
+ return true , nil
3986
+ }
3987
+
3915
3988
var crdbInternalCreateFunctionStmtsTable = virtualSchemaTable {
3916
3989
comment : "CREATE statements for all user-defined functions" ,
3917
3990
schema : `
@@ -3922,10 +3995,15 @@ CREATE TABLE crdb_internal.create_function_statements (
3922
3995
schema_name STRING,
3923
3996
function_id INT,
3924
3997
function_name STRING,
3925
- create_statement STRING
3926
- )
3927
- ` ,
3998
+ create_statement STRING,
3999
+ INDEX (function_id )
4000
+ ) ` ,
3928
4001
populate : createRoutinePopulate (false /* procedure */ ),
4002
+ indexes : []virtualIndex {
4003
+ {
4004
+ populate : createRoutinePopulateByFnIndex ,
4005
+ },
4006
+ },
3929
4007
}
3930
4008
3931
4009
var crdbInternalCreateProcedureStmtsTable = virtualSchemaTable {
@@ -3938,10 +4016,15 @@ CREATE TABLE crdb_internal.create_procedure_statements (
3938
4016
schema_name STRING,
3939
4017
procedure_id INT,
3940
4018
procedure_name STRING,
3941
- create_statement STRING
3942
- )
3943
- ` ,
4019
+ create_statement STRING,
4020
+ INDEX (procedure_id )
4021
+ ) ` ,
3944
4022
populate : createRoutinePopulate (true /* procedure */ ),
4023
+ indexes : []virtualIndex {
4024
+ {
4025
+ populate : createRoutinePopulateByFnIndex ,
4026
+ },
4027
+ },
3945
4028
}
3946
4029
3947
4030
func createTriggerPopulate (
0 commit comments