<?xml version="1.0" ?>
<!--
NAME
    cmkuindex.xsl
DESCRIPTION
    Convert mdapi INDEX_T document to INDEX document (editable XML)

MODIFIED    MM/DD/YY
    pkaliren    05/15/08 - Merge 11GC functionality
    xshen       07/08/05 - bug 4478304 
    xshen       06/16/05 - remove ignore_partition conditions 
    xshen       06/13/05 - get at ts_list for hash partitioning 
    xshen       05/16/05 - support ignore partition option
    xshen       03/08/05 - fix schema mapping 
    xshen       02/24/05 - do not compare COMPUTE_STATISTICS in differ 
    lhan        11/12/04 - add schema_map support
    lhan        10/27/04 - add index statistics support
    lhan        10/12/04 - support CLUSTER index
    lhan        10/06/04 - reorder of compress
    ngade       09/09/04 - reorder for comparison fix
    lhan        08/05/04 - more on index attr
    lhan        08/17/04 - cleanup
    ngade       08/06/04 - modify DoStorage 
    lhan        08/05/04 - more on index attr
    xshen       08/04/04 - local composite partitioning 
    xshen       08/04/04 - support local partitioning 
    lhan        08/04/04 - hook up partitioning
    xshen       08/03/04 - support global partitioning 
    lhan        08/03/04 - more index attributes
    lhan        08/02/04 - lhan_cm_0802
    lhan        08/02/04 - creation
 -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!-- Top level imports -->
<xsl:import href="cmkucommon.xsl"/>
<xsl:import href="cmkucolumn.xsl"/>
<xsl:import href="cmkustorage.xsl"/>
<xsl:import href="cmkuiot.xsl"/>
<xsl:import href="cmkuprtobj.xsl"/>

<!-- Used for constraints matching -->
<xsl:param name="MATCH_CONSTR_BY_DEFINITION">1</xsl:param>
<xsl:param name="IGNORE_NAME_DIFFERENCES">1</xsl:param>

<!-- Include statistics or not -->
<xsl:param name="INCLUDE_STATISTICS">0</xsl:param>

<!-- Top-level parameters -->
 <xsl:param name="SEGMENT_ATTRIBUTES">1</xsl:param>
 <xsl:param name="STORAGE">1</xsl:param>
 <xsl:param name="TABLESPACE">1</xsl:param>

 <xsl:param name="PARALLEL">-1</xsl:param>
 <xsl:param name="RESET_PARALLEL">0</xsl:param>

<!-- Top level template for all objects -->
<xsl:template match="/">
 <xsl:apply-templates/>
</xsl:template>

<xsl:template match="RESULTSET | ROWSET">
  <xsl:for-each select="ROW">
    <xsl:apply-templates/>
  </xsl:for-each>
</xsl:template>

<xsl:template match="INDEX_T">
<INDEX>

   <xsl:choose>

    <!-- cluster index -->

    <xsl:when test="BASE_OBJ/TYPE_NUM=3">

      <xsl:call-template name="DoSchemaWithMapping">
       <xsl:with-param name="CurrentSchema" select="SCHEMA_OBJ/OWNER_NAME"/>
      </xsl:call-template>
      <NAME>
       <xsl:value-of select="SCHEMA_OBJ/NAME"/>
      </NAME>

     <xsl:element name="ON_CLUSTER">
      <xsl:apply-templates select="BASE_OBJ"/>
     </xsl:element>
    </xsl:when>

    <!-- table index -->

    <xsl:otherwise>

      <xsl:if test="(PROPERTY mod 2)=1">
       <xsl:element name="UNIQUE">
         <xsl:text>Y</xsl:text>
       </xsl:element>
      </xsl:if>

      <xsl:if test="(PROPERTY mod 2)!=1">
       <xsl:element name="UNIQUE">
         <xsl:text>N</xsl:text>
       </xsl:element>
      </xsl:if>

      <xsl:if test="TYPE_NUM='2'">
       <xsl:element name="BITMAP"> 
         <xsl:text>Y</xsl:text>
       </xsl:element>
      </xsl:if>

      <xsl:if test="TYPE_NUM !='2'">
       <xsl:element name="BITMAP"> 
         <xsl:text>N</xsl:text>
       </xsl:element>
      </xsl:if>

      <xsl:call-template name="DoSchemaWithMapping">
       <xsl:with-param name="CurrentSchema" select="SCHEMA_OBJ/OWNER_NAME"/>
      </xsl:call-template>

      <NAME>
       <xsl:value-of select="SCHEMA_OBJ/NAME"/>
      </NAME>

     <xsl:element name="ON_TABLE">
      <xsl:apply-templates select="BASE_OBJ"/>
     </xsl:element>

    </xsl:otherwise>

   </xsl:choose>

   <!-- NOTE: we do our own COL_LIST processing,
        not the one in column_list.xsl -->
   <xsl:call-template name="DoColList">
     <xsl:with-param name="ColListNode" select="COL_LIST"/>
     <xsl:with-param name="IndProperty" select="PROPERTY"/>
   </xsl:call-template>

   <!-- get status for emo display -->
   <xsl:if test="$USAGE=2">            <!-- status only for accessors -->
     <xsl:call-template name="DoStatus">
     </xsl:call-template>

     <xsl:choose>
      <xsl:when test="(PROPERTY mod 32)&lt;16">
       <xsl:element name="FUNCTIONAL">
        <xsl:text>Y</xsl:text>
       </xsl:element>
       <xsl:if test="(FLAGS mod 2048)&lt;1024">
        <xsl:element name="FUNCTIONAL_ENABLED"/>
       </xsl:if>       
      </xsl:when>
      <xsl:otherwise>
       <xsl:element name="FUNCTIONAL">
        <xsl:text>N</xsl:text>
       </xsl:element>
      </xsl:otherwise>
     </xsl:choose>
   </xsl:if>

   <xsl:choose>
    <!-- treat domain indexes (type=9) differently, skip since no emo -->
    <xsl:when test="TYPE_NUM=9"/>

    <xsl:otherwise>                             <!-- not domain index -->
     <xsl:choose>

      <xsl:when test="(PART_OBJ)"><!-- partitioned -->
       <xsl:choose>
        <xsl:when test="(PART_OBJ/PARTOBJ/FLAGS mod 2)=1"> <!-- local  -->
          <xsl:call-template name="DoLocalPart"/>      
        </xsl:when>
        <xsl:otherwise>                                    <!-- global -->
          <xsl:call-template name="DoGlobalPart"/>
        </xsl:otherwise>
       </xsl:choose>
       <!-- Partitioned IOT -->
       <INDEX_ATTRIBUTES>
        <xsl:choose>
         <xsl:when test="(FLAGS mod 64)>=32 and NUMKEYCOLS">
          <xsl:element name="COMPRESS">               <!-- key_compression -->
           <xsl:if test="NUMKEYCOLS>0">
            <xsl:value-of select="NUMKEYCOLS"/>
           </xsl:if>
          </xsl:element>
         </xsl:when>
         <xsl:otherwise>
          <xsl:element name="COMPRESS">
           <xsl:text>N</xsl:text>
          </xsl:element>
         </xsl:otherwise>
        </xsl:choose>         
       </INDEX_ATTRIBUTES>
       </xsl:when>
      <xsl:otherwise>                           <!-- non-partitioned -->
      <INDEX_ATTRIBUTES>
       <!-- if this is an index on a temporary table, skip segment attrs -->
       <xsl:if test="2>(BASE_OBJ/FLAGS mod 4)">

       <xsl:if test="$SEGMENT_ATTRIBUTES=1">
        <xsl:call-template name="DoPCT">
         <xsl:with-param name="ParentNode" select="current()"/>
         <xsl:with-param name="ADT_type">INDEX</xsl:with-param>
        </xsl:call-template>

        <!-- No Logging is bit 0x04 in FLAGS=1 -->
        <xsl:element name="LOGGING">
         <xsl:choose>
          <xsl:when test="(FLAGS mod 8)>=4">N</xsl:when>
          <xsl:otherwise>Y</xsl:otherwise>
         </xsl:choose>
        </xsl:element>

        <xsl:call-template name="DoTablespace">
         <xsl:with-param name="ParentNode" select="current()"/>
        </xsl:call-template>

        <xsl:choose>
         <xsl:when test="(FLAGS mod 64)>=32 and NUMKEYCOLS">
          <xsl:element name="COMPRESS">               <!-- key_compression -->
           <xsl:if test="NUMKEYCOLS>0">
            <xsl:value-of select="NUMKEYCOLS"/>
           </xsl:if>
          </xsl:element>
         </xsl:when>
         <xsl:otherwise>
          <xsl:element name="COMPRESS">
           <xsl:text>N</xsl:text>
          </xsl:element>
         </xsl:otherwise>
        </xsl:choose>         

        <!-- The COMPUTE STATISTICS for indexes are deprecated in 10g: SQL Manual p14-91 -->
        <xsl:if test="(FLAGS mod 4)>=2 and ($USAGE!=1 or ($L_VERSION=9 and $R_VERSION=9))"> 
          <xsl:element name="COMPUTE_STATISTICS"/>
        </xsl:if>

        <xsl:call-template name="DoStorage">
          <xsl:with-param name="ParentNode" select="current()/STORAGE"/>
          <xsl:with-param name="BlkSize" select="current()/BLOCKSIZE"/>
        </xsl:call-template>

       </xsl:if>

       <xsl:if test="$SEGMENT_ATTRIBUTES=1">
        <xsl:call-template name="DoParallel">
         <xsl:with-param name="ADT_type">INDEX</xsl:with-param>
         <xsl:with-param name="FlagsParent" select="current()"/>
         <xsl:with-param name="SetParallel" select="$PARALLEL"/>
        </xsl:call-template>
       </xsl:if>

      </xsl:if>

      <xsl:choose>
       <xsl:when test="(PROPERTY mod 8)>=4">
        <xsl:element name="REVERSE">
         <xsl:text>Y</xsl:text>
        </xsl:element>
       </xsl:when>
       <xsl:otherwise>
        <xsl:element name="REVERSE">       
         <xsl:text>N</xsl:text>
        </xsl:element>
       </xsl:otherwise>
      </xsl:choose>

      </INDEX_ATTRIBUTES>
      </xsl:otherwise>

     </xsl:choose>
    </xsl:otherwise>
   </xsl:choose>

 <!-- Index Statistics -->
 <xsl:if test="$INCLUDE_STATISTICS=1">
   <xsl:call-template name="GenIndexStatistics"/>
 </xsl:if>

</INDEX>
</xsl:template>

<xsl:template name="DoColList">
 <xsl:param name="ColListNode" select="''"/>
 <xsl:param name="IndProperty" select="''"/>
  <COL_LIST>
  <xsl:for-each select="$ColListNode/COL_LIST_ITEM">
   <COL_LIST_ITEM> 
   <!--xsl:sort select="POS_NUM" data-type="number"/-->
   <xsl:choose>
<!-- check PROPERTY flags: functional index virt column is marked
     both virtual and hidden
                /* 0x0020 =      32 = hidden column                          */
            /* 0x00010000 =   65536 = virtual column                         */
     In such case we put out col$.default$ which contains the
     defining functional expression.
-->
    <xsl:when test="((COL/PROPERTY mod 64)>=32 
                 and (COL/PROPERTY mod 131072)>=65536)">
     <COL>
      <xsl:value-of select="COL/DEFAULT_VAL"/>
     </COL>
    </xsl:when>

    <xsl:otherwise>
     <!-- if this is a bitmap join index -->
     <xsl:choose>
      <xsl:when test="($IndProperty mod 2048)>=1024">
       <!-- bji is not yet supported in emo -->
       <xsl:element name="JOIN_TABLE_LIST"> 
        <xsl:text>Y</xsl:text>
       </xsl:element>
      </xsl:when>
      <xsl:otherwise>
       <xsl:element name="JOIN_TABLE_LIST"> 
        <xsl:text>N</xsl:text>
       </xsl:element>
      </xsl:otherwise>
     </xsl:choose>
     <NAME>
      <xsl:call-template name="ColNameOrAttr">
       <xsl:with-param name="ColItem" select="COL"/>
      </xsl:call-template>
     </NAME>
     <xsl:if test="$USAGE=2">            <!-- only for accessors -->
      <xsl:call-template name="ColType">
        <xsl:with-param name="TypeNum" select="COL/TYPE_NUM"/>
      </xsl:call-template>
     </xsl:if>
    </xsl:otherwise>
   </xsl:choose>

 <!-- DESCending order index is bit 0x20000 (131072) in col$.property -->
   <xsl:if test="(COL/PROPERTY mod 262144)>=131072">
    <xsl:element name="DESC"/>
   </xsl:if>

   </COL_LIST_ITEM> 
  </xsl:for-each>
  </COL_LIST>  
  
</xsl:template>

<xsl:template name="DoStatus">
  <STATUS>
   <xsl:choose>
    <xsl:when test="(PROPERTY mod 4)>=2">
     <xsl:choose>
      <xsl:when test="TYPE_NUM=9">
       <xsl:choose>
        <xsl:when test="(FLAGS mod 16)>=8">
         <xsl:text>INPROGRS</xsl:text>
        </xsl:when>
        <xsl:otherwise>     
         <xsl:text>VALID</xsl:text>
        </xsl:otherwise>
       </xsl:choose>
      </xsl:when>
      <xsl:otherwise>     
       <xsl:text>NA</xsl:text>
      </xsl:otherwise>
     </xsl:choose>
    </xsl:when>
    <xsl:otherwise>     
     <xsl:choose>
      <xsl:when test="(FLAGS mod 2)>=1">
       <xsl:text>UNUSABLE</xsl:text>
      </xsl:when>
      <xsl:otherwise>
       <xsl:choose>
        <xsl:when test="(FLAGS mod 16)>=8">
         <xsl:text>INPROGRS</xsl:text>
        </xsl:when>
        <xsl:otherwise>     
         <xsl:text>VALID</xsl:text>
        </xsl:otherwise>
       </xsl:choose>
      </xsl:otherwise>
     </xsl:choose>
    </xsl:otherwise>
   </xsl:choose>
  </STATUS>
</xsl:template>

<!-- Begin Template: Global Partitioning -->
<xsl:template name="DoGlobalPart">
  <xsl:param name="ADT_type">INDEX</xsl:param>
  <xsl:element name="GLOBAL_PARTITIONING">
    <xsl:apply-templates select="PART_OBJ/PARTCOLS"/>       <!-- column list -->
    <xsl:if test="$USAGE=2">
      <xsl:apply-templates select="PART_OBJ/PARTOBJ" />    
    </xsl:if>
    <xsl:choose>
      <xsl:when test="PART_OBJ/PARTOBJ/PARTTYPE=1">         <!-- global range -->
        <xsl:element name="RANGE_PARTITIONING">
         <xsl:call-template name="DoPartLists">            
          <xsl:with-param name="ParentNode" select="PART_OBJ"/>
          <xsl:with-param name="ADT_type" select="$ADT_type"/>
          <xsl:with-param name="Parttype" select="PART_OBJ/PARTOBJ/PARTTYPE"/>
         </xsl:call-template>
        </xsl:element>         
      </xsl:when>
      <xsl:otherwise> 
        <xsl:element name="HASH_PARTITIONING">              <!-- global hash -->
         <!-- get ts_list for hash partitioning -->
         <xsl:call-template name="GetHashPartTSList">
           <xsl:with-param name="PartList" select="PART_OBJ/PART_LIST"/>
         </xsl:call-template>
         <xsl:call-template name="DoPartLists">            
          <xsl:with-param name="ParentNode" select="PART_OBJ"/>
          <xsl:with-param name="ADT_type" select="$ADT_type"/>
          <xsl:with-param name="Parttype" select="PART_OBJ/PARTOBJ/PARTTYPE"/>
         </xsl:call-template>
        </xsl:element>         
      </xsl:otherwise>
    </xsl:choose>          
  </xsl:element>
</xsl:template>
<!-- End Template: Global Partitioning-->

<!-- Begin Template: Local Partitioning -->
<xsl:template name="DoLocalPart">
  <xsl:param name="ADT_type">INDEX</xsl:param>
  <xsl:param name="Local">1</xsl:param>
  <xsl:element name="LOCAL_PARTITIONING">
      <xsl:apply-templates select="PART_OBJ/PARTCOLS"/>
      <xsl:apply-templates select="PART_OBJ/PARTOBJ" />
      <xsl:element name="PARTTYPE">
        <xsl:choose>
          <xsl:when test="PART_OBJ/PARTOBJ/PARTTYPE=1">
            <xsl:text>RANGE_PARTITIONING</xsl:text>
          </xsl:when>
          <xsl:when test="PART_OBJ/PARTOBJ/PARTTYPE=2">
            <xsl:text>HASH_PARTITIONING</xsl:text>
          </xsl:when>     
          <xsl:when test="PART_OBJ/PARTOBJ/PARTTYPE=4">
            <xsl:text>LIST_PARTITIONING</xsl:text>
          </xsl:when>          
        </xsl:choose>
      </xsl:element>
    
    <!-- Local Range check if subpartitioned -->
    <xsl:choose>
      <xsl:when test="PART_OBJ/PARTOBJ/PARTTYPE=1 and (PART_OBJ/PARTOBJ/SPARE2 mod 256)=2"> <!-- hash subpart -->
        <xsl:element name="HASH_SUBPARTITIONING">
         <xsl:apply-templates select="PART_OBJ/SUBPARTCOLS"/>
         <xsl:apply-templates select="PART_OBJ/COMPART_LIST">
           <xsl:with-param name="ADT_type" select="$ADT_type"/>  
           <xsl:with-param name="Local" select="$Local"/>
           <xsl:with-param name="Sub_type">HASH</xsl:with-param>
         </xsl:apply-templates>   
        </xsl:element>
      </xsl:when>
      <xsl:when test="PART_OBJ/PARTOBJ/PARTTYPE=1 and (PART_OBJ/PARTOBJ/SPARE2 mod 256)=4"> <!-- list subpart -->
        <xsl:element name="LIST_SUBPARTITIONING">
         <xsl:apply-templates select="PART_OBJ/SUBPARTCOLS"/>
         <xsl:apply-templates select="PART_OBJ/COMPART_LIST">
           <xsl:with-param name="ADT_type" select="$ADT_type"/>  
           <xsl:with-param name="Local" select="$Local"/>
         </xsl:apply-templates>  
        </xsl:element>
      </xsl:when>
      <!-- Do Part Lists -->
      <xsl:otherwise>    
        <xsl:call-template name="DoPartLists">            
          <xsl:with-param name="ParentNode" select="PART_OBJ"/>
          <xsl:with-param name="ADT_type" select="$ADT_type"/>
          <xsl:with-param name="Parttype" select="PART_OBJ/PARTOBJ/PARTTYPE"/>
          <xsl:with-param name="Local" select="$Local"/>
        </xsl:call-template>      
      </xsl:otherwise>
    </xsl:choose>  
  </xsl:element>
</xsl:template>
<!-- End Template: Local Partitioning-->

<xsl:template name="ColType">
 <xsl:param name="TypeNum">0</xsl:param>
 <DATATYPE>
 <xsl:choose>
  <xsl:when test="$TypeNum='1'">
   <xsl:choose>
     <xsl:when test="$TypeNum/../CHARSETFORM='2'">
     <xsl:text>NVARCHAR2</xsl:text>
    </xsl:when>
    <xsl:otherwise>
     <xsl:text>VARCHAR2</xsl:text>
    </xsl:otherwise>
   </xsl:choose>
  </xsl:when>
  <xsl:when test="$TypeNum='2'">
   <xsl:choose>
    <xsl:when test="($TypeNum/../PRECISION_NUM) and not($TypeNum/../SCALE)">FLOAT</xsl:when>
    <xsl:otherwise>NUMBER</xsl:otherwise>
   </xsl:choose>
  </xsl:when>
  <xsl:when test="$TypeNum='8'">LONG</xsl:when>  
  <xsl:when test="$TypeNum='12'">DATE</xsl:when>
  <xsl:when test="$TypeNum='23'">RAW</xsl:when>  
  <xsl:when test="$TypeNum='24'">LONG_RAW</xsl:when>
  <xsl:when test="$TypeNum='58'">OPAQUE</xsl:when>  
  <xsl:when test="$TypeNum='69'">ROWID</xsl:when>  
  <xsl:when test="$TypeNum='96'">
   <xsl:choose>
    <xsl:when test="$TypeNum/../CHARSETFORM='2'">
     <xsl:text>NCHAR</xsl:text>
    </xsl:when>
    <xsl:otherwise>
     <xsl:text>CHAR</xsl:text>
    </xsl:otherwise>
   </xsl:choose>
  </xsl:when>
  <xsl:when test="$TypeNum='100'">BINARY_FLOAT</xsl:when>  
  <xsl:when test="$TypeNum='101'">BINARY_DOUBLE</xsl:when>  
  <xsl:when test="$TypeNum='105'">MLSLABEL</xsl:when>  
  <xsl:when test="$TypeNum='111'">REF</xsl:when>
  <xsl:when test="$TypeNum='112'">
   <xsl:choose>
    <xsl:when test="$TypeNum/../CHARSETFORM='2'">
     <xsl:text>NCLOB</xsl:text>
    </xsl:when>
    <xsl:otherwise>
     <xsl:text>CLOB</xsl:text>
    </xsl:otherwise>
   </xsl:choose>
  </xsl:when>
  <xsl:when test="$TypeNum='113'">BLOB</xsl:when>
  <xsl:when test="$TypeNum='114'">BFILE</xsl:when>  
  <xsl:when test="$TypeNum='121'">UDT</xsl:when>
  <xsl:when test="$TypeNum='122'">NESTED_TABLE</xsl:when>
  <xsl:when test="$TypeNum='123'">VARRAY</xsl:when>    
  <xsl:when test="$TypeNum='178'">TIME</xsl:when>  
  <xsl:when test="$TypeNum='179'">TIME_WITH_TIMEZONE</xsl:when>    
  <xsl:when test="$TypeNum='180'">TIMESTAMP</xsl:when>    
  <xsl:when test="$TypeNum='181'">TIMESTAMP_WITH_TIMEZONE</xsl:when>  
  <xsl:when test="$TypeNum='182'">INTERVAL_YEAR_TO_MONTH</xsl:when>      
  <xsl:when test="$TypeNum='183'">INTERVAL_DAY_TO_SECOND</xsl:when>  
  <xsl:when test="$TypeNum='208'">UROWID</xsl:when>  
  <xsl:when test="$TypeNum='231'">TIMESTAMP_WITH_LOCAL_TIMEZONE</xsl:when>    
 </xsl:choose>
 </DATATYPE>

 <xsl:element name="POS_NUM">
   <xsl:value-of select="$TypeNum/../../POS_NUM"/>
 </xsl:element>     

</xsl:template>

<!-- Table Statistics -->
<xsl:template name="GenIndexStatistics">
  <xsl:if test="ANALYZETIME">
    <STATISTICS>
      <ANALYZETIME>
        <xsl:value-of select="ANALYZETIME"/>
      </ANALYZETIME>
      <BLEVEL>
        <xsl:value-of select="BLEVEL"/>
      </BLEVEL>
      <CLUFAC>
        <xsl:value-of select="CLUFAC"/>
      </CLUFAC>
      <DBLKKEY>
        <xsl:value-of select="DBLKKEY"/>
      </DBLKKEY>
      <DISTKEY>
        <xsl:value-of select="DISTKEY"/>
      </DISTKEY>
      <LBLKKEY>
        <xsl:value-of select="LBLKKEY"/>
      </LBLKKEY>
      <LEAFCNT>
        <xsl:value-of select="LEAFCNT"/>
      </LEAFCNT>
      <ROWCNT>
        <xsl:value-of select="ROWCNT"/>
      </ROWCNT>
      <SAMPLESIZE>
        <xsl:value-of select="SAMPLESIZE"/>
      </SAMPLESIZE>
    </STATISTICS>
  </xsl:if>
</xsl:template>

</xsl:stylesheet>


