@@ -528,4 +528,198 @@ class SessionCatalogSuite extends SparkFunSuite {
528528 }
529529 }
530530
531+ // --------------------------------------------------------------------------
532+ // Functions
533+ // --------------------------------------------------------------------------
534+
535+ test(" basic create and list functions" ) {
536+ val externalCatalog = newEmptyCatalog()
537+ val sessionCatalog = new SessionCatalog (externalCatalog)
538+ sessionCatalog.createDatabase(newDb(" mydb" ), ignoreIfExists = false )
539+ sessionCatalog.createFunction(" mydb" , newFunc(" myfunc" ))
540+ assert(externalCatalog.listFunctions(" mydb" , " *" ).toSet == Set (" myfunc" ))
541+ }
542+
543+ test(" create function when database does not exist" ) {
544+ val catalog = new SessionCatalog (newBasicCatalog())
545+ intercept[AnalysisException ] {
546+ catalog.createFunction(" does_not_exist" , newFunc())
547+ }
548+ }
549+
550+ test(" create function that already exists" ) {
551+ val catalog = new SessionCatalog (newBasicCatalog())
552+ intercept[AnalysisException ] {
553+ catalog.createFunction(" db2" , newFunc(" func1" ))
554+ }
555+ }
556+
557+ test(" create temp function" ) {
558+ val catalog = new SessionCatalog (newBasicCatalog())
559+ val tempFunc1 = newFunc(" temp1" )
560+ val tempFunc2 = newFunc(" temp2" )
561+ catalog.createTempFunction(tempFunc1, ignoreIfExists = false )
562+ catalog.createTempFunction(tempFunc2, ignoreIfExists = false )
563+ assert(catalog.getTempFunction(" temp1" ) == Some (tempFunc1))
564+ assert(catalog.getTempFunction(" temp2" ) == Some (tempFunc2))
565+ assert(catalog.getTempFunction(" temp3" ) == None )
566+ // Temporary function already exists
567+ intercept[AnalysisException ] {
568+ catalog.createTempFunction(tempFunc1, ignoreIfExists = false )
569+ }
570+ // Temporary function is overridden
571+ val tempFunc3 = tempFunc1.copy(className = " something else" )
572+ catalog.createTempFunction(tempFunc3, ignoreIfExists = true )
573+ assert(catalog.getTempFunction(" temp1" ) == Some (tempFunc3))
574+ }
575+
576+ test(" drop function" ) {
577+ val externalCatalog = newBasicCatalog()
578+ val sessionCatalog = new SessionCatalog (externalCatalog)
579+ assert(externalCatalog.listFunctions(" db2" , " *" ).toSet == Set (" func1" ))
580+ sessionCatalog.dropFunction(" db2" , FunctionIdentifier (" func1" ))
581+ assert(externalCatalog.listFunctions(" db2" , " *" ).isEmpty)
582+ }
583+
584+ test(" drop function when database does not exist" ) {
585+ val catalog = new SessionCatalog (newBasicCatalog())
586+ intercept[AnalysisException ] {
587+ catalog.dropFunction(" does_not_exist" , FunctionIdentifier (" something" ))
588+ }
589+ }
590+
591+ test(" drop function that does not exist" ) {
592+ val catalog = new SessionCatalog (newBasicCatalog())
593+ intercept[AnalysisException ] {
594+ catalog.dropFunction(" db2" , FunctionIdentifier (" does_not_exist" ))
595+ }
596+ }
597+
598+ test(" drop temp function" ) {
599+ val catalog = new SessionCatalog (newBasicCatalog())
600+ val tempFunc = newFunc(" func1" )
601+ catalog.createTempFunction(tempFunc, ignoreIfExists = false )
602+ assert(catalog.getTempFunction(" func1" ) == Some (tempFunc))
603+ catalog.dropTempFunction(" func1" , ignoreIfNotExists = false )
604+ assert(catalog.getTempFunction(" func1" ) == None )
605+ intercept[AnalysisException ] {
606+ catalog.dropTempFunction(" func1" , ignoreIfNotExists = false )
607+ }
608+ catalog.dropTempFunction(" func1" , ignoreIfNotExists = true )
609+ }
610+
611+ test(" get function" ) {
612+ val catalog = new SessionCatalog (newBasicCatalog())
613+ assert(catalog.getFunction(" db2" , FunctionIdentifier (" func1" )) ==
614+ CatalogFunction (FunctionIdentifier (" func1" , Some (" db2" )), funcClass))
615+ intercept[AnalysisException ] {
616+ catalog.getFunction(" db2" , FunctionIdentifier (" does_not_exist" ))
617+ }
618+ }
619+
620+ test(" get function when database does not exist" ) {
621+ val catalog = new SessionCatalog (newBasicCatalog())
622+ intercept[AnalysisException ] {
623+ catalog.getFunction(" does_not_exist" , FunctionIdentifier (" func1" ))
624+ }
625+ }
626+
627+ test(" get temp function" ) {
628+ val externalCatalog = newBasicCatalog()
629+ val sessionCatalog = new SessionCatalog (externalCatalog)
630+ val metastoreFunc = externalCatalog.getFunction(" db2" , " func1" )
631+ val tempFunc = newFunc(" func1" ).copy(className = " something weird" )
632+ sessionCatalog.createTempFunction(tempFunc, ignoreIfExists = false )
633+ // If a database is specified, we'll always return the function in that database
634+ assert(sessionCatalog.getFunction(" db2" , FunctionIdentifier (" func1" , Some (" db2" )))
635+ == metastoreFunc)
636+ // If no database is specified, we'll first return temporary functions
637+ assert(sessionCatalog.getFunction(" db2" , FunctionIdentifier (" func1" )) == tempFunc)
638+ // Then, if no such temporary function exist, check the current database
639+ sessionCatalog.dropTempFunction(" func1" , ignoreIfNotExists = false )
640+ assert(sessionCatalog.getFunction(" db2" , FunctionIdentifier (" func1" )) == metastoreFunc)
641+ }
642+
643+ test(" rename function" ) {
644+ val catalog = new SessionCatalog (newBasicCatalog())
645+ val newName = " funcky"
646+ assert(catalog.getFunction(" db2" , FunctionIdentifier (" func1" )).className == funcClass)
647+ catalog.renameFunction(" db2" , FunctionIdentifier (" func1" ), FunctionIdentifier (newName))
648+ intercept[AnalysisException ] { catalog.getFunction(" db2" , FunctionIdentifier (" func1" )) }
649+ assert(catalog.getFunction(" db2" , FunctionIdentifier (newName)).name.funcName == newName)
650+ assert(catalog.getFunction(" db2" , FunctionIdentifier (newName)).className == funcClass)
651+ intercept[AnalysisException ] {
652+ catalog.renameFunction(" db2" , FunctionIdentifier (" does_not_exist" ), FunctionIdentifier (" x" ))
653+ }
654+ }
655+
656+ test(" rename function when database does not exist" ) {
657+ val catalog = new SessionCatalog (newBasicCatalog())
658+ intercept[AnalysisException ] {
659+ catalog.renameFunction(
660+ " does_not_exist" , FunctionIdentifier (" func1" ), FunctionIdentifier (" func5" ))
661+ }
662+ }
663+
664+ test(" rename temp function" ) {
665+ val externalCatalog = newBasicCatalog()
666+ val sessionCatalog = new SessionCatalog (externalCatalog)
667+ val tempFunc = newFunc(" func1" ).copy(className = " something weird" )
668+ sessionCatalog.createTempFunction(tempFunc, ignoreIfExists = false )
669+ // If a database is specified, we'll always rename the function in that database
670+ sessionCatalog.renameFunction(
671+ " db2" , FunctionIdentifier (" func1" , Some (" db2" )), FunctionIdentifier (" func3" , Some (" db2" )))
672+ assert(sessionCatalog.getTempFunction(" func1" ) == Some (tempFunc))
673+ assert(sessionCatalog.getTempFunction(" func3" ) == None )
674+ assert(externalCatalog.listFunctions(" db2" , " *" ).toSet == Set (" func3" ))
675+ sessionCatalog.createFunction(" db2" , newFunc(" func1" , Some (" db2" )))
676+ // If no database is specified, we'll first rename temporary functions
677+ sessionCatalog.renameFunction(" db2" , FunctionIdentifier (" func1" ), FunctionIdentifier (" func4" ))
678+ assert(sessionCatalog.getTempFunction(" func4" ) ==
679+ Some (tempFunc.copy(name = FunctionIdentifier (" func4" ))))
680+ assert(sessionCatalog.getTempFunction(" func1" ) == None )
681+ assert(externalCatalog.listFunctions(" db2" , " *" ).toSet == Set (" func1" , " func3" ))
682+ // Then, if no such temporary function exist, rename the function in the current database
683+ sessionCatalog.renameFunction(" db2" , FunctionIdentifier (" func1" ), FunctionIdentifier (" func5" ))
684+ assert(sessionCatalog.getTempFunction(" func5" ) == None )
685+ assert(externalCatalog.listFunctions(" db2" , " *" ).toSet == Set (" func3" , " func5" ))
686+ }
687+
688+ test(" alter function" ) {
689+ val catalog = new SessionCatalog (newBasicCatalog())
690+ assert(catalog.getFunction(" db2" , FunctionIdentifier (" func1" )).className == funcClass)
691+ catalog.alterFunction(" db2" , newFunc(" func1" ).copy(className = " muhaha" ))
692+ assert(catalog.getFunction(" db2" , FunctionIdentifier (" func1" )).className == " muhaha" )
693+ intercept[AnalysisException ] { catalog.alterFunction(" db2" , newFunc(" funcky" )) }
694+ }
695+
696+ test(" alter function when database does not exist" ) {
697+ val catalog = new SessionCatalog (newBasicCatalog())
698+ intercept[AnalysisException ] {
699+ catalog.alterFunction(" does_not_exist" , newFunc())
700+ }
701+ }
702+
703+ test(" list functions" ) {
704+ val catalog = new SessionCatalog (newBasicCatalog())
705+ val tempFunc1 = newFunc(" func1" ).copy(className = " march" )
706+ val tempFunc2 = newFunc(" yes_me" ).copy(className = " april" )
707+ catalog.createFunction(" db2" , newFunc(" func2" ))
708+ catalog.createFunction(" db2" , newFunc(" not_me" ))
709+ catalog.createTempFunction(tempFunc1, ignoreIfExists = false )
710+ catalog.createTempFunction(tempFunc2, ignoreIfExists = false )
711+ assert(catalog.listFunctions(" db1" , " *" ).toSet ==
712+ Set (FunctionIdentifier (" func1" ), FunctionIdentifier (" yes_me" )))
713+ assert(catalog.listFunctions(" db2" , " *" ).toSet ==
714+ Set (FunctionIdentifier (" func1" ),
715+ FunctionIdentifier (" yes_me" ),
716+ FunctionIdentifier (" func1" , Some (" db2" )),
717+ FunctionIdentifier (" func2" , Some (" db2" )),
718+ FunctionIdentifier (" not_me" , Some (" db2" ))))
719+ assert(catalog.listFunctions(" db2" , " func*" ).toSet ==
720+ Set (FunctionIdentifier (" func1" ),
721+ FunctionIdentifier (" func1" , Some (" db2" )),
722+ FunctionIdentifier (" func2" , Some (" db2" ))))
723+ }
724+
531725}
0 commit comments