"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getAggregatedField = exports.getFieldQuoteChar = exports.defaultNullSafeEqualSql = exports.getConnectionDefaults = void 0;
const tslib_1 = require("tslib");
const dbt_1 = require("../types/dbt");
const projects_1 = require("../types/projects");
const types_1 = require("../visualizations/types");
const assertUnreachable_1 = tslib_1.__importDefault(require("./assertUnreachable"));
const nonEmpty = (value) => value || undefined;
const getConnectionDefaults = (credentials) => {
    switch (credentials.type) {
        case projects_1.WarehouseTypes.POSTGRES:
        case projects_1.WarehouseTypes.REDSHIFT:
        case projects_1.WarehouseTypes.TRINO:
            return {
                database: nonEmpty(credentials.dbname),
                schema: nonEmpty(credentials.schema),
            };
        case projects_1.WarehouseTypes.SNOWFLAKE:
        case projects_1.WarehouseTypes.ATHENA:
            return {
                database: nonEmpty(credentials.database),
                schema: nonEmpty(credentials.schema),
            };
        case projects_1.WarehouseTypes.BIGQUERY:
            return {
                database: nonEmpty(credentials.project),
                schema: nonEmpty(credentials.dataset),
            };
        case projects_1.WarehouseTypes.DATABRICKS:
            return {
                database: nonEmpty(credentials.catalog),
                schema: nonEmpty(credentials.database),
            };
        case projects_1.WarehouseTypes.CLICKHOUSE:
            return {
                database: undefined,
                schema: nonEmpty(credentials.schema),
            };
        case projects_1.WarehouseTypes.DUCKDB:
            if (credentials.connectionType === projects_1.DuckdbConnectionType.DUCKLAKE) {
                return {
                    database: nonEmpty(credentials.catalogAlias) ?? 'ducklake',
                    schema: nonEmpty(credentials.schema),
                };
            }
            return {
                database: nonEmpty(credentials.database),
                schema: nonEmpty(credentials.schema),
            };
        default:
            return (0, assertUnreachable_1.default)(credentials, 'Unknown warehouse type when getting connection defaults');
    }
};
exports.getConnectionDefaults = getConnectionDefaults;
// `NULL = NULL` is NULL in standard SQL, which silently drops rows in JOINs.
const defaultNullSafeEqualSql = (left, right) => `(${left} = ${right} OR (${left} IS NULL AND ${right} IS NULL))`;
exports.defaultNullSafeEqualSql = defaultNullSafeEqualSql;
/**
 * @deprecated use WarehouseSqlBuilder.getFieldQuoteChar instead
 * @param warehouseType
 */
const getFieldQuoteChar = (warehouseType) => {
    if (warehouseType) {
        switch (warehouseType) {
            case projects_1.WarehouseTypes.BIGQUERY:
            case projects_1.WarehouseTypes.DATABRICKS:
                return '`';
            case projects_1.WarehouseTypes.SNOWFLAKE:
            case projects_1.WarehouseTypes.REDSHIFT:
            case projects_1.WarehouseTypes.POSTGRES:
            case projects_1.WarehouseTypes.TRINO:
            case projects_1.WarehouseTypes.CLICKHOUSE:
            case projects_1.WarehouseTypes.ATHENA:
            case projects_1.WarehouseTypes.DUCKDB:
                return '"';
            default:
                return (0, assertUnreachable_1.default)(warehouseType, `Unknown warehouse type ${warehouseType}`);
        }
    }
    return '"';
};
exports.getFieldQuoteChar = getFieldQuoteChar;
const getAggregatedField = (warehouseSqlBuilder, aggregation, reference) => {
    const q = warehouseSqlBuilder.getFieldQuoteChar();
    const adapterType = warehouseSqlBuilder.getAdapterType();
    switch (adapterType) {
        case dbt_1.SupportedDbtAdapter.BIGQUERY:
        case dbt_1.SupportedDbtAdapter.DATABRICKS:
        case dbt_1.SupportedDbtAdapter.SPARK:
        case dbt_1.SupportedDbtAdapter.SNOWFLAKE:
        case dbt_1.SupportedDbtAdapter.REDSHIFT:
        case dbt_1.SupportedDbtAdapter.TRINO:
        case dbt_1.SupportedDbtAdapter.ATHENA:
        case dbt_1.SupportedDbtAdapter.DUCKDB:
            const aggregationFunction = aggregation === types_1.VizAggregationOptions.ANY
                ? 'ANY_VALUE'
                : aggregation;
            return `${aggregationFunction}(${q}${reference}${q})`;
        case dbt_1.SupportedDbtAdapter.POSTGRES:
            if (aggregation === types_1.VizAggregationOptions.ANY) {
                // ANY_VALUE on Postgres is only available from version v16+
                return `(ARRAY_AGG(${q}${reference}${q}))[1]`;
            }
            break;
        case dbt_1.SupportedDbtAdapter.CLICKHOUSE:
            if (aggregation === types_1.VizAggregationOptions.ANY) {
                // ClickHouse uses any() function for ANY_VALUE equivalent
                return `any(${q}${reference}${q})`;
            }
            break;
        default:
            return (0, assertUnreachable_1.default)(adapterType, `Unknown warehouse type ${adapterType}`);
    }
    return `${aggregation}(${q}${reference}${q})`;
};
exports.getAggregatedField = getAggregatedField;
//# sourceMappingURL=warehouse.js.map