I start by creating my composite range-list partitioned table:
SQL> create table p_objects
2 tablespace tbs1
3 partition by range(rdate)
4 subpartition by list(owner)
5 subpartition template
6 (
7 subpartition spsys values ('SYS')
8 , subpartition spsysaux values ('SYSAUX')
9 )
10 (
11 partition p201301 values less than (to_date('2013/02/01','YYYY/MM/DD')),
12 partition p201302 values less than (to_date('2013/03/01','YYYY/MM/DD')),
13 partition p201303 values less than (to_date('2013/04/01','YYYY/MM/DD')),
14 partition p201304 values less than (to_date('2013/05/01','YYYY/MM/DD')),
15 partition p201305 values less than (to_date('2013/06/01','YYYY/MM/DD')),
16 partition p201306 values less than (to_date('2013/07/01','YYYY/MM/DD')),
17 partition p201307 values less than (to_date('2013/08/01','YYYY/MM/DD')),
18 partition p201308 values less than (to_date('2013/09/01','YYYY/MM/DD')),
19 partition p201309 values less than (to_date('2013/10/01','YYYY/MM/DD')),
20 partition p201310 values less than (to_date('2013/11/01','YYYY/MM/DD')),
21 partition p201311 values less than (to_date('2013/12/01','YYYY/MM/DD')),
22 partition p201312 values less than (to_date('2014/01/01','YYYY/MM/DD'))
23 )
24 as select object_id
25 , owner
26 , object_name
27 , object_type
28 , to_date(trunc(dbms_random.value(
29 to_char(to_date('2013/01/01','YYYY/MM/DD'),'J'),
30 to_char(to_date('2013/12/31','YYYY/MM/DD'),'J')
31 )),'J') rdate
32 from all_objects
33 where owner in ('SYS','SYSAUX');
Table created.
This creates the partitions with 2 subpartitions each, per my defined template. For example:
PARTITION_NAME SUBPARTITION_NAME
------------------------------ ------------------------------
P201301 P201301_SPSYS
P201301_SPSYSAUX
P201302 P201302_SPSYS
P201302_SPSYSAUX
P201303 P201303_SPSYS
P201303_SPSYSAUX
Next I'll add two more partitions, one with no subpartition definition specified and another with a custom definition:
SQL> alter table p_objects
2 add partition p201408
3 values less than (to_date('2014/09/01','yyyy/mm/dd'));
Table altered.
SQL> alter table p_objects
2 add partition p201409
3 values less than (to_date('2014/10/01','yyyy/mm/dd'))
4 (
5 subpartition p201409_spdts values ('DTS')
6 , subpartition p201409_spsys values ('SYS')
7 , subpartition p201409_spsysaux values ('SYSAUX')
8 )
9 ;
Table altered.
The results:
PARTITION_NAME SUBPARTITION_NAME
------------------------------ ------------------------------
P201408 P201408_SPSYS
P201408_SPSYSAUX
P201409 P201409_SPDTS
P201409_SPSYS
P201409_SPSYSAUX
You can see that the first statement just used the subpartition template as defined in the original CREATE TABLE statement. The second uses the list I defined in the ALTER TABLE statement. I could have only defined the SPDTS subpartition and it would have only used that one and not used SYS or SYSAUX subpartitions at all.
Hopefully this post helps a few of you in your searching when faced with a similar task. This was probably obvious to most of you but the mind starts to slip for some of us.