<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
  ~ Licensed to the Apache Software Foundation (ASF) under one
  ~   or more contributor license agreements.  See the NOTICE file
  ~   distributed with this work for additional information
  ~   regarding copyright ownership.  The ASF licenses this file
  ~   to you under the Apache License, Version 2.0 (the
  ~   "License"); you may not use this file except in compliance
  ~   with the License.  You may obtain a copy of the License at
  ~
  ~   http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~   Unless required by applicable law or agreed to in writing, software
  ~   distributed under the License is distributed on an "AS IS" BASIS,
  ~   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~   See the License for the specific language governing permissions and
  ~   limitations under the License.
  -->

<datamodel name="test_scenario">
    <datamapping>
        <column>
            <!-- This column type defines what will generally happen to VARCHAR fields unless they are explicitly defined or overridden elsewhere -->
            <type>VARCHAR</type>
            <dataSequence>RANDOM</dataSequence>
            <length>15</length>
            <name>GENERAL_VARCHAR</name>
        </column>
        <column>
            <type>CHAR</type>
            <dataSequence>SEQUENTIAL</dataSequence>
            <length>15</length>
            <name>GENERAL_CHAR</name>
        </column>
        <column>
            <type>TIMESTAMP</type>
            <!--SEQUENTIAL is unsupported for DATE -->
            <dataSequence>RANDOM</dataSequence>
            <!-- Number [0-100] that represents the probability of creating a null value -->
            <!-- The higher the number, the more like the value will returned will be null -->
            <!-- Leaving this tag out is equivalent to having a 0 probability. i.e. never null -->
            <nullChance>0</nullChance>
            <minValue>2020</minValue>
            <maxValue>2025</maxValue>
            <name>GENERAL_TIMESTAMP</name>
        </column>
        <column>
            <type>DATE</type>
            <!--SEQUENTIAL is unsupported for DATE -->
            <dataSequence>RANDOM</dataSequence>
            <!-- Number [0-100] that represents the probability of creating a null value -->
            <!-- The higher the number, the more like the value will returned will be null -->
            <!-- Leaving this tag out is equivalent to having a 0 probability. i.e. never null -->
            <nullChance>0</nullChance>
            <minValue>1975</minValue>
            <maxValue>2025</maxValue>
            <name>GENERAL_DATE</name>
        </column>
        <column>
            <type>DATE</type>
            <!--SEQUENTIAL is unsupported for DATE -->
            <userDefined>true</userDefined>
            <dataSequence>RANDOM</dataSequence>
            <!-- Number [0-100] that represents the probability of creating a null value -->
            <!-- The higher the number, the more like the value will returned will be null -->
            <!-- Leaving this tag out is equivalent to having a 0 probability. i.e. never null -->
            <nullChance>0</nullChance>
            <useCurrentDate>true</useCurrentDate>
            <name>RND_DATE</name>
        </column>
        <column>
            <type>DECIMAL</type>
            <dataSequence>RANDOM</dataSequence>
            <minValue>0</minValue>
            <maxValue>1</maxValue>

            <!-- Precision is limited to 18 -->
            <precision>18</precision>
            <!-- Number [0-100] that represents the probability of creating a null value -->
            <!-- The higher the number, the more like the value will returned will be null -->
            <!-- Leaving this tag out is equivalent to having a 0 probability. i.e. never null -->
            <nullChance>10</nullChance>
            <name>GENERAL_DECIMAL</name>
        </column>
        <column>
            <type>INTEGER</type>
            <dataSequence>RANDOM</dataSequence>
            <minValue>1</minValue>
            <maxValue>50000000</maxValue>
            <!-- Number [0-100] that represents the probability of creating a null value -->
            <!-- The higher the number, the more like the value will returned will be null -->
            <!-- Leaving this tag out is equivalent to having a 0 probability. i.e. never null -->
            <nullChance>100</nullChance>
            <name>GENERAL_INTEGER</name>
        </column>
        <column>
            <type>DATE</type>
            <userDefined>true</userDefined>
            <!--SEQUENTIAL is now supported for DATE -->
            <dataSequence>SEQUENTIAL</dataSequence>
            <!-- Number [0-100] that represents the probability of creating a null value -->
            <!-- The higher the number, the more like the value will returned will be null -->
            <!-- Leaving this tag out is equivalent to having a 0 probability. i.e. never null -->
            <nullChance>0</nullChance>
            <useCurrentDate>true</useCurrentDate>
            <name>CREATED_DATE</name>
        </column>
        <column>
            <type>DATE</type>
            <userDefined>true</userDefined>
            <name>SOME_DATE</name>
            <minValue>1975</minValue>
            <maxValue>2025</maxValue>
            <valuelist>
                <!-- Distributes randomly with equal chance of being picked -->
                <datavalue distribution="80">
                    <!-- Joda time format: yyyy-MM-dd HH:mm:ss.SSS ZZZ -->
                    <minValue>2019-09-15 00:01:00.000</minValue>
                    <maxValue>2019-09-15 11:00:00.000</maxValue>
                </datavalue>
                <datavalue distribution="10">
                    <value>2019-09-19 00:01:00.000</value>
                </datavalue>
                <datavalue distribution="10">
                    <minValue>2019-09-22 00:01:00.000</minValue>
                    <maxValue>2019-09-22 00:01:00.300</maxValue>
                </datavalue>
            </valuelist>
        </column>
        <column>
            <type>DATE</type>
            <userDefined>true</userDefined>
            <name>PRESENT_DATE</name>
            <minValue>1975</minValue>
            <maxValue>2025</maxValue>
            <valuelist>
                <!-- Distributes randomly with equal chance of being picked -->
                <datavalue distribution="80">
                    <!-- Joda time format: yyyy-MM-dd HH:mm:ss.SSS z -->
                    <useCurrentDate>true</useCurrentDate>
                </datavalue>
                <datavalue distribution="20">
                    <useCurrentDate>true</useCurrentDate>
                </datavalue>
            </valuelist>
        </column>
        <column>
            <type>CHAR</type>
            <userDefined>true</userDefined>
            <dataSequence>LIST</dataSequence>
            <length>15</length>
            <name>PARENT_ID</name>
            <valuelist>
                <!-- Distributes according to specified values. These must total 100 -->
                <datavalue distribution="60">
                    <value>aAAyYhnNbBs9kWk</value>
                </datavalue>
                <datavalue distribution="20">
                    <value>bBByYhnNbBs9kWu</value>
                </datavalue>
                <datavalue distribution="20">
                    <value>cCCyYhnNbBs9kWr</value>
                </datavalue>
            </valuelist>
        </column>
        <column>
            <!-- This column type defines what will generally happen to VARCHAR fields unless they are explicitly defined or overridden elsewhere -->
            <type>VARCHAR</type>
            <length>10</length>
            <userDefined>true</userDefined>
            <dataSequence>RANDOM</dataSequence>
            <name>OLDVAL_STRING</name>
            <prefix>MYPRFX</prefix>
        </column>
        <column>
            <!-- This column type defines what will generally happen to VARCHAR fields unless they are explicitly defined or overridden elsewhere -->
            <type>VARCHAR</type>
            <length>15</length>
            <userDefined>true</userDefined>
            <dataSequence>SEQUENTIAL</dataSequence>
            <name>NEWVAL_STRING</name>
            <prefix>0F90000000000X</prefix>
        </column>
        <column>
            <type>VARCHAR_ARRAY</type>
            <userDefined>true</userDefined>
            <name>VAR_ARRAY</name>
            <valuelist>
                <datavalue>
                    <value>Foo</value>
                </datavalue>
                <datavalue>
                    <value>Bar</value>
                </datavalue>
            </valuelist>
        </column>
        <column>
            <type>CHAR</type>
            <length>3</length>
            <userDefined>true</userDefined>
            <dataSequence>LIST</dataSequence>
            <name>IDENTIFIER</name>
            <valuelist>
                <!-- Distributes according to specified values. These must total 100 -->
                <datavalue distribution="60">
                    <value>ABC</value>
                </datavalue>
                <datavalue distribution="20">
                    <value>XYZ</value>
                </datavalue>
                <datavalue distribution="20">
                    <value>LMN</value>
                </datavalue>
            </valuelist>
        </column>
        <column>
            <type>CHAR</type>
            <userDefined>true</userDefined>
            <dataSequence>SEQUENTIAL</dataSequence>
            <length>8</length>
            <name>OTHER_ID</name>
            <prefix>z0Oxx00</prefix>
        </column>
        <column>
            <type>VARBINARY</type>
            <userDefined>true</userDefined>
            <dataSequence>SEQUENTIAL</dataSequence>
            <length>8</length>
            <name>VAR_BIN</name>
            <prefix>VBOxx00</prefix>
        </column>
        <column>
           <type>VARCHAR</type>
           <userDefined>true</userDefined>
           <dataSequence>SEQUENTIAL</dataSequence>
           <length>1</length>
           <name>FIELD</name>
       </column>
        <column>
            <type>INTEGER</type>
            <dataSequence>SEQUENTIAL</dataSequence>
            <minValue>1</minValue>
            <maxValue>100000</maxValue>
            <name>SEQUENTIAL_INTEGER</name>
        </column>
    </datamapping>
    <scenarios>
        <scenario tableName="PHERF.TEST_TABLE" rowCount="100" name="testScenarioRW">
            <!-- Scenario level rule overrides will be unsupported in V1.
                    You can use the general datamappings in the mean time-->
            <dataOverride>
                <column>
                    <type>VARCHAR</type>
                    <userDefined>true</userDefined>
                    <dataSequence>RANDOM</dataSequence>
                    <length>5</length>
                    <name>FIELD</name>
                </column>
            </dataOverride>

            <!--
                This is used to add mixed R/W workloads.

                If this tag exists, a writer pool will be created based on the below properties.
                These props will override the default values in pherf.properties, but only for this
                scenario.The write jobs will run in conjunction with the querySet below.
            -->
            <writeParams executionDurationInMs="10000">
                <!--
                    Number of writer it insert into the threadpool
                -->
                <writerThreadCount>2</writerThreadCount>

                <!--
                    Time in Ms that each thread will sleep between batch writes. This helps to
                    throttle writers.
                -->
                <threadSleepDuration>10</threadSleepDuration>

                <batchSize>1</batchSize>
            </writeParams>
            <querySet concurrency="1" executionType="PARALLEL" executionDurationInMs="10000">
                <query id="q3" statement="select count(*) from PHERF.TEST_TABLE"/>
                <query id="q4" statement="select sum(SOME_INT) from PHERF.TEST_TABLE"/>
            </querySet>

        </scenario>

        <scenario tableName="PHERF.TEST_TABLE" rowCount="30" name="testScenario">
            <!-- Scenario level rule overrides will be unsupported in V1.
                    You can use the general datamappings in the mean time-->
            <dataOverride>
                <column>
                    <type>VARCHAR</type>
                    <userDefined>true</userDefined>
                    <dataSequence>RANDOM</dataSequence>
                    <length>10</length>
                    <name>FIELD</name>
                </column>
            </dataOverride>

            <!--Note: 1. Minimum of executionDurationInMs or numberOfExecutions. Which ever is reached first
                      2. DDL included in query are executed only once on start of querySet execution.
            -->
            <querySet concurrency="1-3" executionType="SERIAL" executionDurationInMs="5000"
                      numberOfExecutions="100">
                <query id="q1" tenantId="123456789012345" expectedAggregateRowCount="0"
                       statement="select count(*) from PHERF.TEST_TABLE"/>
                <!-- queryGroup is a way to organize queries across tables or scenario files.
                    The value will be dumped to results. This gives a value to group by on reporting to compare queries -->
                <query id="q2" queryGroup="g1"
                       statement="select sum(SOME_INT) from PHERF.TEST_TABLE"/>
            </querySet>
            <!--Minimum of executionDurationInMs or numberOfExecutions. Which ever is reached first -->
            <querySet concurrency="2-3" executionType="PARALLEL" executionDurationInMs="10000"
                      numberOfExecutions="10">
                <query id="q3" statement="select count(*) from PHERF.TEST_TABLE"/>
                <query id="q4" statement="select sum(SOME_INT) from PHERF.TEST_TABLE"/>
            </querySet>
        </scenario>

        <scenario tableName="PHERF.TEST_TABLE" rowCount="99" name="testPreAndPostDdls">
            <preScenarioDdls>
                 <ddl statement="CREATE INDEX IDX_DIVISION ON ? (DIVISION)" tableName="PHERF.TEST_TABLE"/>
            </preScenarioDdls>

            <postScenarioDdls>
                 <ddl statement="CREATE INDEX IDX_OLDVAL_STRING ON ? (OLDVAL_STRING)" tableName="PHERF.TEST_TABLE"/>
                 <ddl statement="CREATE INDEX IDX_CONNECTION_ID ON ? (CONNECTION_ID)" tableName="PHERF.TEST_TABLE"/>
            </postScenarioDdls>

            <querySet concurrency="1" executionType="SERIAL" executionDurationInMs="5000"
                      numberOfExecutions="1">
                <query id="q1" expectedAggregateRowCount="99" statement="select count(*) from PHERF.TEST_TABLE"/>
            </querySet>
        </scenario>

        <!-- To configure a Write Workload to write to a tenant specific view users need to
             specify the tenantId attribute on the scenario, specifying the tenant they
             want to write data for as the attribute value. This tells Pherf to take out a
             tenant-specific connection for executing the write workload.
             The name of the tenant specific view to write to can then be specified as the value of
             the tablename attribute. This assumes the tenant specific view has been created. To
             dynamically create the view see comments below with regard to the ddl attribute.
        -->
        <scenario tableName="PHERF.TEST_VIEW" tenantId="xyzdefghijklmno"
                    rowCount="100" name="testMTWriteScenario">
           <preScenarioDdls>
                <ddl statement="CREATE VIEW IF NOT EXISTS PHERF.TEST_VIEW (field1 VARCHAR, field2 VARCHAR) AS SELECT * FROM PHERF.TEST_TABLE" />
            </preScenarioDdls>
        </scenario>
        <!--  Scenario level DDL that is dynamically executed before the Write Workload is run.
              This pattern is really useful when you want to write data to multi-tenant view and the tenant id is
              tightly bound to the scenario. In such cases you can't create the view through the data model flow.
              The value of the tableName attribute is name of the view that is dynamically created based on the DDL
              in the ddl attribute. Queries accessing the View will need to manually make sure Pherf was run with the -l option at
              least once.
         -->
        <scenario tableName="PHERF.TEST_MT_VIEW" tenantId="abcdefghijklmno"
                    rowCount="100" name="testMTDdlWriteScenario">
            <preScenarioDdls>
                <ddl statement="CREATE VIEW IF NOT EXISTS PHERF.TEST_MT_VIEW (field1 VARCHAR) AS SELECT * FROM PHERF.TEST_TABLE" />
            </preScenarioDdls>
        </scenario>

    </scenarios>
</datamodel>
