@@ -679,7 +679,7 @@ CREATE OR REPLACE PACKAGE BODY dbms_partition_wrangler IS
679
679
END set_unmanaged_table;
680
680
681
681
--whether all specified partitions have been allocated?
682
- FUNCTION is_preallocated()
682
+ FUNCTION is_preallocated(
683
683
p_table_owner IN VARCHAR2,
684
684
p_table_name IN VARCHAR2
685
685
) RETURN BOOLEAN IS
@@ -726,14 +726,14 @@ SELECT warehouse_name warehouse,
726
726
partition_name,
727
727
extractvalue(dbms_xmlgen.getxmltype('SELECT high_value
728
728
FROM DBA_TAB_PARTITIONS
729
- WHERE owner = ''' || UPPER(p_table_name ) ||
730
- ''' AND table_name = ''' || UPPER(p_table_owner ) ||
729
+ WHERE owner = ''' || UPPER(p_table_owner ) ||
730
+ ''' AND table_name = ''' || UPPER(p_table_name ) ||
731
731
''' AND PARTITION_NAME = ''' || t.PARTITION_NAME || ''''),
732
732
'//text()'
733
733
) AS high_value
734
734
FROM dba_tab_partitions t
735
- WHERE owner = UPPER(p_table_name )
736
- AND table_name = UPPER(p_table_owner )
735
+ WHERE owner = UPPER(p_table_owner )
736
+ AND table_name = UPPER(p_table_name )
737
737
), final_result (
738
738
SELECT partition_name,
739
739
TO_DATE(substr(high_value,11,10),'YYYY-DD-MM') high_value
@@ -751,6 +751,35 @@ SELECT warehouse_name warehouse,
751
751
752
752
END is_preallocated;
753
753
754
+ FUNCTION is_subpartitioned(
755
+ p_table_owner IN VARCHAR2,
756
+ p_table_name IN VARCHAR2
757
+ ) RETURN BOOLEAN IS
758
+ l_count INTEGER;
759
+ BEGIN
760
+ --checks
761
+ IF NOT check_object_parameters(
762
+ p_table_owner => UPPER(p_table_owner),
763
+ p_table_name => UPPER(p_table_name),
764
+ p_object_type => 'TABLE')
765
+ ) THEN
766
+ --this will never trigger because the function will trigger first it validation fails
767
+ raise_application_error(-20000,'Invalid parameters');
768
+ END IF;
769
+
770
+ SELECT COUNT(1) INTO l_count
771
+ FROM DBA_PART_TABLES
772
+ WHERE SUBPARTITIONING_TYPE != 'NONE'
773
+ AND owner = UPPER(p_table_owner)
774
+ AND table_name = UPPER(p_table_name);
775
+
776
+ IF l_count > 0 THEN
777
+ RETURN TRUE;
778
+ ELSE
779
+ RETURN FALSE;
780
+ END IF;
781
+ END is_subpartitioned;
782
+
754
783
/*
755
784
Top-level procedure to add, compress, move, readonly, truncate, shrink, drop partititions and tablespaces
756
785
*/
@@ -780,11 +809,132 @@ SELECT warehouse_name warehouse,
780
809
set_lock(p_table_owner => p_table_owner, p_table_name => p_table_name);
781
810
782
811
--determine if new partitions need to be pre-allocated based upon the configured parameter
783
- WHILE NOT is_preallocated() LOOP
784
- add_partition(p_table_owner => p_table_owner, p_table_name => p_table_name)
812
+ WHILE NOT is_preallocated(p_table_owner => p_table_owner, p_table_name => p_table_name ) LOOP
813
+ add_partition(p_table_owner => p_table_owner, p_table_name => p_table_name);
785
814
END LOOP;
786
815
787
816
--determine if inactive partitions need to be moved to a different buffer pool
817
+ l_inactive_tab_partition_bpool := get_parameter(
818
+ p_table_owner => UPPER(p_table_owner),
819
+ p_table_name => UPPER(p_table_name),
820
+ p_parameter => 'TAB_INACTIVE_BUFFER_POOL'
821
+ );
822
+
823
+ l_inactive_ind_partition_bpool := get_parameter(
824
+ p_table_owner => UPPER(p_table_owner),
825
+ p_table_name => UPPER(p_table_name),
826
+ p_parameter => 'IND_INACTIVE_BUFFER_POOL'
827
+ );
828
+
829
+ --process table partitions
830
+ IF l_inactive_tab_partition_bpool IS NOT NULL THEN
831
+ IF is_subpartitioned(p_table_owner => p_table_owner, p_table_name => p_table_name) THEN
832
+ --process table subpartitions
833
+ FOR x IN (
834
+ SELECT owner, table_name, subpartition_name, BUFFER_POOL
835
+ FROM dba_tab_subpartitions
836
+ WHERE partition_name IN (
837
+ SELECT partition_name
838
+ FROM dba_partitions
839
+ WHERE table_owner = UPPER(p_table_owner)
840
+ AND table_name = UPPER(p_table_name)
841
+ )
842
+ AND BUFFER_POOL != l_inactive_tab_partition_bpool
843
+ )
844
+ LOOP
845
+
846
+ IF is_expired_partition(
847
+ p_table_owner => UPPER(p_table_owner),
848
+ p_table_name => UPPER(p_table_name),
849
+ p_partition_name => UPPER(p_partition_name)
850
+ ) THEN
851
+ --check syntax
852
+ EXECUTE IMMEDIATE 'ALTER TABLE '||UPPER(p_table_owner)||'.'||UPPER(p_table_name)||
853
+ ' MODIFY SUBPARTITION '||x.subpartition_name||' (BUFFER POOL '||l_inactive_tab_partition_bpool||')';
854
+ END IF;
855
+
856
+ END LOOP;
857
+
858
+ ELSE
859
+ --process partitions
860
+ FOR x IN (
861
+ SELECT partition_name
862
+ FROM dba_partitions
863
+ WHERE table_owner = UPPER(p_table_owner)
864
+ AND table_name = UPPER(p_table_name)
865
+ AND BUFFER_POOL != l_inactive_tab_partition_bpool
866
+ )
867
+ LOOP
868
+
869
+ IF is_expired_partition(
870
+ p_table_owner => UPPER(p_table_owner),
871
+ p_table_name => UPPER(p_table_name),
872
+ p_partition_name => UPPER(p_partition_name)
873
+ ) THEN
874
+ --check syntax
875
+ EXECUTE IMMEDIATE 'ALTER TABLE '||UPPER(p_table_owner)||'.'||UPPER(p_table_name)||
876
+ ' MODIFY PARTITION '||x.partition_name||' (BUFFER POOL '||l_inactive_tab_partition_bpool||')';
877
+ END IF;
878
+
879
+ END LOOP;
880
+
881
+ END IF;
882
+ END IF;
883
+
884
+ --process index partitions
885
+ IF l_inactive_ind_partition_bpool IS NOT NULL THEN
886
+ IF is_subpartitioned(p_table_owner => p_table_owner, p_table_name => p_table_name) THEN
887
+ --process table subpartitions
888
+ FOR x IN (
889
+ SELECT owner, table_name, subpartition_name, BUFFER_POOL
890
+ FROM dba_ind_subpartitions
891
+ WHERE partition_name IN (
892
+ SELECT partition_name
893
+ FROM dba_partitions
894
+ WHERE table_owner = UPPER(p_table_owner)
895
+ AND table_name = UPPER(p_table_name)
896
+ )
897
+ AND BUFFER_POOL != l_inactive_ind_partition_bpool
898
+ )
899
+ LOOP
900
+
901
+ IF is_expired_partition(
902
+ p_table_owner => UPPER(p_table_owner),
903
+ p_table_name => UPPER(p_table_name),
904
+ p_partition_name => UPPER(p_partition_name)
905
+ ) THEN
906
+ --check syntax
907
+ EXECUTE IMMEDIATE 'ALTER TABLE '||UPPER(p_table_owner)||'.'||UPPER(p_table_name)||
908
+ ' MODIFY SUBPARTITION '||x.subpartition_name||' (BUFFER POOL '||l_inactive_tab_partition_bpool||')';
909
+ END IF;
910
+
911
+ END LOOP;
912
+
913
+ ELSE
914
+ --process partitions
915
+ FOR x IN (
916
+ SELECT partition_name
917
+ FROM dba_partitions
918
+ WHERE table_owner = UPPER(p_table_owner)
919
+ AND table_name = UPPER(p_table_name)
920
+ AND BUFFER_POOL != l_inactive_ind_partition_bpool
921
+ )
922
+ LOOP
923
+
924
+ IF is_expired_partition(
925
+ p_table_owner => UPPER(p_table_owner),
926
+ p_table_name => UPPER(p_table_name),
927
+ p_partition_name => UPPER(p_partition_name)
928
+ ) THEN
929
+ --check syntax
930
+ EXECUTE IMMEDIATE 'ALTER TABLE '||UPPER(p_table_owner)||'.'||UPPER(p_table_name)||
931
+ ' MODIFY PARTITION '||x.partition_name||' (BUFFER POOL '||l_inactive_ind_partition_bpool||')';
932
+ END IF;
933
+
934
+ END LOOP;
935
+
936
+ END IF;
937
+ END IF;
788
938
789
939
/* bulk compress partitions once they are [mostly] inactive, and shrink the tablespace storage */
790
940
--determine if inactive partitions need to be compressed
@@ -1203,8 +1353,8 @@ FUNCTION count_all_partitions(
1203
1353
--handle where tablespace is empty by failing to get l_hwm
1204
1354
WHEN OTHERS THEN
1205
1355
l_size := NVL(get_parameter(
1206
- p_table_owner => p_table_owner,
1207
- p_table_name => p_table_name,
1356
+ p_table_owner => UPPER( p_table_owner) ,
1357
+ p_table_name => UPPER( p_table_name) ,
1208
1358
p_parameter => 'TABLESPACE_MINSIZE'
1209
1359
),1*l_db_block_size);
1210
1360
END;
0 commit comments