<?xml version="1.0" encoding="utf-8"?>

<!-- EngineVersion = Java version -->
<ApiConfig Name="Apache Spark"
           Slug="apache-spark-connector"
           Type="JDBC"
           Category="big-data"
           Id="d3f9a8b2-7c6e-4d5f-9a8c-1e2b7f6c4d3e"
           Version="2"
           EngineVersion="8"
           Desc="Query Apache Spark Thrift Server (HiveServer2 protocol) from Power BI, SQL Server Linked Server via ZappySys Data Gateway, Crystal Reports, SSRS, Azure Data Factory, and other ODBC tools -- almost no coding required."
           Logo="https://cdn.zappysys.com/api/Images/logos/apache-spark-connector.png"
           HelpLink="https://community.zappysys.com/search?q=spark">

    <VersionHistory>
      <Change Ver="2" Date="2026-09-15" Type="Modified">Auth Notes (numbered steps), documented params, Maven DriverDownloadLinks, extra SQL examples for ODBC apps.</Change>
      <Change Ver="1" Date="2025-05-09" Type="New">Initial version.</Change>
    </VersionHistory>
    <Template>
        <Param Name="DriverDownloadPageLink"
               Value="https://spark.apache.org/docs/latest/sql-distributed-sql-engine-thrift-server.html" />
        <Param Name="MvnRepositoryDriverDownloadLink"
               Value="https://mvnrepository.com/artifact/org.apache.hive/hive-jdbc" />
        <Param Name="DriverDownloadLinks"
               Hidden="True"
               Value="hive-jdbc-4.2.0-standalone.jar=https://repo1.maven.org/maven2/org/apache/hive/hive-jdbc/4.2.0/hive-jdbc-4.2.0-standalone.jar" />
        <EndPoint Name="AdditionalDriverDownloadInstructions">
            <Body>
                <![CDATA[
        <li>
            <p>
                Download the <strong>standalone</strong> Hive JDBC JAR so you do not have to assemble Hadoop dependencies,
                e.g. <a href="https://repo1.maven.org/maven2/org/apache/hive/hive-jdbc/4.2.0/" target="_blank">hive-jdbc-4.2.0-standalone.jar</a>
                (commonly used to connect to Spark Thrift Server).
            </p>
        </li>
                ]]>
            </Body>
        </EndPoint>
    </Template>
    <Auths>
        <Auth Name="Default"
              Label="Thrift Server"
              ConnStr="jdbc:hive2://[$HostName$]:[$Port$]/[$Database$]"
              HelpLink="https://spark.apache.org/docs/latest/sql-distributed-sql-engine-thrift-server.html">
            <Params>
                <Param Name="DriverClass" Label="Driver class" Required="False" Value="org.apache.hive.jdbc.HiveDriver" Desc="Optional. Leave blank to auto-detect from the JAR unless SPI is ambiguous (e.g. org.apache.hive.jdbc.HiveDriver)." HelpLink="https://spark.apache.org/docs/latest/sql-distributed-sql-engine-thrift-server.html" />
                <Param Name="DriverFilePaths" Editor="FileOpen" Label="JDBC driver file(s)" Required="True" Value="{DownloadFolder}\hive-jdbc-4.2.0-standalone.jar" Desc="Filled by the wizard after download. Separate multiple JARs with a semicolon (e.g. C:\ZappySys\Jdbc\MyConnector\driver.jar)." HelpLink="https://spark.apache.org/docs/latest/sql-distributed-sql-engine-thrift-server.html" />
                <Param Name="HostName" Label="Host" Required="True" Value="MyHostName" Desc="JDBC host name or IP (e.g. MyHostName)." HelpLink="https://spark.apache.org/docs/latest/sql-distributed-sql-engine-thrift-server.html" />
                <Param Name="Port" Label="TCP port" Required="True" Value="10000" Desc="JDBC port (e.g. 10000)." HelpLink="https://spark.apache.org/docs/latest/sql-distributed-sql-engine-thrift-server.html" />
                <Param Name="Database" Label="Database name" Required="False" Value="MyDatabase" Desc="Database, schema, or catalog name (e.g. MyDatabase)." HelpLink="https://spark.apache.org/docs/latest/sql-distributed-sql-engine-thrift-server.html" />
                <Param Name="UserName" Label="User name" Required="False" Desc="Database user. Leave empty if the server allows anonymous JDBC." HelpLink="https://spark.apache.org/docs/latest/sql-distributed-sql-engine-thrift-server.html" />
                <Param Name="Password" Label="Password" Required="False" Secret="True" Desc="Database password. Leave empty if none." HelpLink="https://spark.apache.org/docs/latest/sql-distributed-sql-engine-thrift-server.html" />
            </Params>
            <Notes>
                <![CDATA[<p>Spark Thrift Server from Power BI, SQL Server Linked Server via ZappySys Data Gateway, Crystal Reports, SSRS, Azure Data Factory, and other ODBC tools.</p>
<ol>
<li>Start Spark Thrift Server or note the existing host and HS2 port (default <code>10000</code>).</li><li>Download the <strong>standalone</strong> Hive JDBC JAR (the wizard does this). Do not mix a partial Hadoop classpath.</li><li>Create a user if the cluster uses auth; otherwise leave user/password empty.</li><li>After Finish, replace the host (e.g. MyHostName) on the DSN Main UI.</li>
<li>Finish the wizard. Then click <strong>Test Connection</strong> on the DSN Main UI (the wizard does not run Test Connection).</li><li>Done. You can query from C#, Python, PowerShell, and ODBC apps.</li>
</ol>]]>
            </Notes>
        </Auth>
        <Auth Name="Ssl"
              Label="Thrift Server (SSL)"
              ConnStr="jdbc:hive2://[$HostName$]:[$Port$]/[$Database$];ssl=[$Ssl$]"
              HelpLink="https://spark.apache.org/docs/latest/sql-distributed-sql-engine-thrift-server.html">
            <Params>
                <Param Name="DriverClass" Label="Driver class" Required="False" Value="org.apache.hive.jdbc.HiveDriver" Desc="Optional. Leave blank to auto-detect from the JAR unless SPI is ambiguous (e.g. org.apache.hive.jdbc.HiveDriver)." HelpLink="https://spark.apache.org/docs/latest/sql-distributed-sql-engine-thrift-server.html" />
                <Param Name="DriverFilePaths" Editor="FileOpen" Label="JDBC driver file(s)" Required="True" Value="{DownloadFolder}\hive-jdbc-4.2.0-standalone.jar" Desc="Filled by the wizard after download. Separate multiple JARs with a semicolon (e.g. C:\ZappySys\Jdbc\MyConnector\driver.jar)." HelpLink="https://spark.apache.org/docs/latest/sql-distributed-sql-engine-thrift-server.html" />
                <Param Name="HostName" Label="Host" Required="True" Value="MyHostName" Desc="JDBC host name or IP (e.g. MyHostName)." HelpLink="https://spark.apache.org/docs/latest/sql-distributed-sql-engine-thrift-server.html" />
                <Param Name="Port" Label="TCP port" Required="True" Value="10000" Desc="JDBC port (e.g. 10000)." HelpLink="https://spark.apache.org/docs/latest/sql-distributed-sql-engine-thrift-server.html" />
                <Param Name="Database" Label="Database name" Required="False" Value="MyDatabase" Desc="Database, schema, or catalog name (e.g. MyDatabase)." HelpLink="https://spark.apache.org/docs/latest/sql-distributed-sql-engine-thrift-server.html" />
                <Param Name="Ssl" Label="SSL" Required="False" Options="Notset=;Yes=true;No=false" Value="true" Desc="SSL flag for this JDBC URL (e.g. Yes from the dropdown)." HelpLink="https://spark.apache.org/docs/latest/sql-distributed-sql-engine-thrift-server.html" />
                <Param Name="UserName" Label="User name" Required="True" Desc="Database user. Leave empty if the server allows anonymous JDBC." HelpLink="https://spark.apache.org/docs/latest/sql-distributed-sql-engine-thrift-server.html" />
                <Param Name="Password" Label="Password" Required="True" Secret="True" Desc="Database password. Leave empty if none." HelpLink="https://spark.apache.org/docs/latest/sql-distributed-sql-engine-thrift-server.html" />
            </Params>
            <Notes>
                <![CDATA[<p>Spark Thrift Server with SSL from Power BI, SQL Server Linked Server via ZappySys Data Gateway, Crystal Reports, SSRS, Azure Data Factory, and other ODBC tools.</p>
<ol>
<li>Same as Default Auth, plus TLS. Fill LDAP/Hive user and password.</li><li>Do not use a personal employee login for unattended Power BI or Linked Server refresh.</li>
<li>Finish the wizard. Then click <strong>Test Connection</strong> on the DSN Main UI (the wizard does not run Test Connection).</li><li>Done. You can query from C#, Python, PowerShell, and ODBC apps.</li>
</ol>]]>
            </Notes>
        </Auth>
    </Auths>

    <Examples>
        <Example Group="ODBC" Slug="list-tables" Label="List tables" HelpLink="https://spark.apache.org/docs/latest/sql-ref-syntax.html">
            <Desc><![CDATA[<p>Lists tables available to this connection. Use this in Power BI or a SQL Server Linked Server to confirm the catalog before building reports.</p>]]></Desc>
            <Code>
                <![CDATA[SHOW TABLES]]>
            </Code>
        </Example>

        <Example Group="ODBC" Slug="select-rows" Label="Select rows" HelpLink="https://spark.apache.org/docs/latest/sql-ref-syntax.html">
            <Desc><![CDATA[<p>Returns rows from <code>employees</code>. Replace the identifier with your catalog object. Works in Excel, SSRS, and Crystal Reports.</p>]]></Desc>
            <Code>
                <![CDATA[SELECT * FROM employees]]>
            </Code>
        </Example>

        <Example Group="ODBC" Slug="filter-rows" Label="Filter with WHERE" HelpLink="https://spark.apache.org/docs/latest/sql-ref-syntax.html">
            <Desc><![CDATA[<p>Returns matching rows from <code>employees</code>.</p>]]></Desc>
            <Code>
                <![CDATA[SELECT * FROM employees
WHERE id = 1]]>
            </Code>
        </Example>

        <Example Group="ODBC" Slug="join-tables" Label="Join tables" HelpLink="https://spark.apache.org/docs/latest/sql-ref-syntax.html">
            <Desc><![CDATA[<p>Joins two tables on a key. Use in Azure Data Factory or SSIS when you need a combined extract.</p>]]></Desc>
            <Code>
                <![CDATA[SELECT a.id, a.name, b.amount
FROM employees AS a
JOIN my_other_table AS b ON a.id = b.parent_id]]>
            </Code>
        </Example>

        <Example Group="ODBC" Slug="group-by" Label="Aggregate with GROUP BY" HelpLink="https://spark.apache.org/docs/latest/sql-ref-syntax.html">
            <Desc><![CDATA[<p>Counts rows per group. Typical Power BI import pattern before a visual.</p>]]></Desc>
            <Code>
                <![CDATA[SELECT status, COUNT(*) AS row_count
FROM employees
GROUP BY status]]>
            </Code>
        </Example>

        <Example Group="ODBC" Slug="order-limit" Label="Order and limit" HelpLink="https://spark.apache.org/docs/latest/sql-ref-syntax.html">
            <Desc><![CDATA[<p>Returns the first 100 rows. Useful for preview in Excel or Crystal Reports.</p>]]></Desc>
            <Code>
                <![CDATA[SELECT * FROM employees
ORDER BY 1
LIMIT 100]]>
            </Code>
        </Example>

        <Example Group="ODBC" Slug="count-all" Label="Count rows" HelpLink="https://spark.apache.org/docs/latest/sql-ref-syntax.html">
            <Desc><![CDATA[<p>Returns the number of rows in <code>employees</code>.</p>]]></Desc>
            <Code>
                <![CDATA[SELECT COUNT(*) AS row_count FROM employees]]>
            </Code>
        </Example>

        <Example Group="ODBC" Slug="case-expr" Label="CASE expression" HelpLink="https://spark.apache.org/docs/latest/sql-ref-syntax.html">
            <Desc><![CDATA[<p>Maps a column to labels with <code>CASE</code>.</p>]]></Desc>
            <Code>
                <![CDATA[SELECT id,
       CASE WHEN status = 'A' THEN 'Active' ELSE 'Other' END AS status_label
FROM employees]]>
            </Code>
        </Example>

        <Example Group="ODBC" Slug="select-list" Label="Select specific columns" HelpLink="https://spark.apache.org/docs/latest/sql-ref-syntax.html">
            <Desc><![CDATA[<p>Returns a column list instead of star. Prefer this in Linked Server views.</p>]]></Desc>
            <Code>
                <![CDATA[SELECT id, name, status
FROM employees]]>
            </Code>
        </Example>

        <Example Group="ODBC" Slug="having" Label="Filter groups with HAVING" HelpLink="https://spark.apache.org/docs/latest/sql-ref-syntax.html">
            <Desc><![CDATA[<p>Keeps groups whose count is at least 1.</p>]]></Desc>
            <Code>
                <![CDATA[SELECT status, COUNT(*) AS row_count
FROM employees
GROUP BY status
HAVING COUNT(*) >= 1]]>
            </Code>
        </Example>

        <Example Default="True" Group="ODBC" Slug="list-employees-in-a-department" Label="List employees in a department">
            <Desc><![CDATA[<p>Returns selected columns for employees in the Sales department. Use in Power BI or Excel to preview a filtered extract.</p>]]></Desc>
            <Code>
                <![CDATA[SELECT
    id,
    name,
    salary
FROM employees
WHERE department = 'Sales';]]>
            </Code>
        </Example>

        <Example Group="ODBC" Slug="rank-employees-by-salary-window-function" Label="Rank employees by salary (window function)">
            <Desc><![CDATA[<p>Ranks employees by salary within each department (highest first).</p>]]></Desc>
            <Code>
                <![CDATA[SELECT
    id,
    name,
    department,
    salary,
    ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) as salary_rank_in_dept
FROM employees;]]>
            </Code>
        </Example>

        <Example Group="ODBC" Slug="extract-field-from-json-string" Label="Extract field from JSON string">
            <Desc><![CDATA[<p>Extracts the city field from a JSON string in <code>user_data</code>.</p>]]></Desc>
            <Code>
                <![CDATA[SELECT
    user_id,
    get_json_object(user_data, '$.address.city') AS city
FROM user_activity
WHERE user_data IS NOT NULL;]]>
            </Code>
        </Example>

        <Example Group="ODBC" Slug="explode-array-into-rows-lateral-view" Label="Explode array into rows (lateral view)">
            <Desc><![CDATA[<p>Turns array elements into separate rows and filters for users interested in hiking.</p>]]></Desc>
            <Code>
                <![CDATA[SELECT DISTINCT
    up.user_id,
    up.name
FROM user_profiles up
LATERAL VIEW explode(interests) interest_table AS single_interest
WHERE single_interest = 'hiking';]]>
            </Code>
        </Example>

        <Example Group="ODBC" Slug="extract-browser-from-user-agent-regex" Label="Extract browser from user agent (Regex)">
            <Desc><![CDATA[<p>Parses the browser name from the user_agent string. Useful for SSRS or Crystal Reports web-log extracts.</p>]]></Desc>
            <Code>
                <![CDATA[SELECT
    user_agent,
    regexp_extract(user_agent, '(Firefox|Chrome|Safari|MSIE)', 1) AS browser
FROM web_logs
LIMIT 100;]]>
            </Code>
        </Example>
    </Examples>
</ApiConfig>
