diff --git a/CHANGELOG.md b/CHANGELOG.md index ffac301..6196e60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,7 @@ RFCs targeting v3.2.0 are tracked under [`tsc/rfcs/`](https://github.com/bitol-i * The POSIX `${VAR_NAME:-default}` form supplies an inline default, used when the variable is unset or empty. * Tools MUST resolve references before using a value, SHOULD error on unresolvable references (never silently substitute an empty string), and MUST preserve unresolved tokens verbatim when serializing back to YAML. * Non-breaking: no new section or field is added to the standard; interpolation applies to string values only. + * Server `port` fields now accept a string in addition to an integer, so they can hold a variable reference such as `${DB_PORT}` or `${DB_PORT:-5432}`, which the previous integer-only type rejected. * **Adds** `id` to relationship objects ([RFC 0047](https://github.com/bitol-io/tsc/blob/main/rfcs/approved/odcs-v3.2.0/0047-relationship-id.md)): * New optional `id` string on `RelationshipBase` (surfaced on both schema-level and property-level relationships), completing the stable-identifier work of RFC-0026a for the last referenceable array-item object that lacked one. * MUST be unique within its containing `relationships` array; SHOULD be stable across contract versions; cannot contain `.` `#` `/` `\` `@` `!` `%` `&` `^`. @@ -62,6 +63,10 @@ RFCs targeting v3.2.0 are tracked under [`tsc/rfcs/`](https://github.com/bitol-i * **Adds** Apache Iceberg server type ([RFC 0049](https://github.com/bitol-io/tsc/blob/main/rfcs/approved/odcs-v3.2.0/0049-iceberg-server-type.md)): * New `iceberg` server `type` describing access to Apache Iceberg catalogs through the standardized Iceberg REST API, with required `catalog` and `catalogUrl` plus optional `namespace` and `warehouse`. * Non-breaking: adds a new optional server type. +* **Adds** Exasol server type ([RFC 0058](https://github.com/bitol-io/tsc/blob/main/rfcs/approved/odcs-v3.2.0/0058-exasol-server-type.md)): + * New `exasol` server `type` describing data served from Exasol, an in-memory MPP analytics database, with required `host` plus optional `port` (defaults to `8563`) and `schema`. + * No `database` field: an Exasol cluster runs a single database and the schema is the namespace. `host` may be a cluster connection range, e.g. `n11..14.acme.com`. + * Non-breaking: adds a new optional server type. * **Changes** to Servers: * Add optional Athena Server `workgroup` field and fix `stagingDir` to be optional in schema. diff --git a/docs/examples/fundamentals/variables.odcs.yaml b/docs/examples/fundamentals/variables.odcs.yaml index 86a8705..a16567f 100644 --- a/docs/examples/fundamentals/variables.odcs.yaml +++ b/docs/examples/fundamentals/variables.odcs.yaml @@ -17,7 +17,7 @@ servers: environment: prod type: postgresql host: ${DB_HOST} - port: 5432 + port: ${DB_PORT:-5432} database: ${DB_NAME:-orders} schema: ${DB_SCHEMA:-public} diff --git a/docs/examples/server/exasol-server.odcs.yaml b/docs/examples/server/exasol-server.odcs.yaml new file mode 100644 index 0000000..37af66f --- /dev/null +++ b/docs/examples/server/exasol-server.odcs.yaml @@ -0,0 +1,25 @@ +# Copyright 2026 The Bitol Contributors +# SPDX-License-Identifier: Apache-2.0 + +# Demonstrates RFC-0058: the `exasol` server type for Exasol, an in-memory MPP +# analytics database. An Exasol cluster runs a single database, so the schema is +# the namespace and there is no `database` field. + +version: 1.0.0 +apiVersion: v3.2.0 +kind: DataContract +id: 5c9a1e73-8d24-4f60-b1a7-6e0c3b5d9f42 +status: active +servers: + - server: prod + type: exasol + host: exasol.acme.com + port: 8563 + schema: SALES +schema: + - name: sales + physicalType: table + properties: + - name: sale_id + logicalType: string + required: true diff --git a/docs/infrastructure-servers.md b/docs/infrastructure-servers.md index d616d6d..67e9e8c 100644 --- a/docs/infrastructure-servers.md +++ b/docs/infrastructure-servers.md @@ -43,15 +43,15 @@ servers: ### Common Server Properties -| Key | Type | UX label | Required | Description | -| ---------------- | ------ | ----------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| description | string | Description | No | Description of the server. | -| environment | string | Environment | No | Environment of the server. Examples includes: prod, preprod, dev, uat. | -| id | string | ID | No | A unique identifier used to reduce the risk of collisions, such as a UUID. | -| roles | array | Roles | No | List of roles that have access to the server. Check [roles](./roles.md) section for more details. | -| server | string | Server | Yes | Identifier of the server. | -| type | string | Type | Yes | Type of the server. Can be one of: api, athena, azure, bigquery, clickhouse, cloudsql, custom, databricks, db2, denodo, dremio, duckdb, glue, hive, impala, informix, kafka, kinesis, local, mysql, oracle, postgres, postgresql, presto, pubsub, redshift, s3, sftp, snowflake, sqlserver, synapse, trino, vertica, zen. | -| customProperties | array | Custom Properties | No | Custom properties that are not part of the standard. | +| Key | Type | UX label | Required | Description | +| ---------------- | ------ | ----------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| description | string | Description | No | Description of the server. | +| environment | string | Environment | No | Environment of the server. Examples includes: prod, preprod, dev, uat. | +| id | string | ID | No | A unique identifier used to reduce the risk of collisions, such as a UUID. | +| roles | array | Roles | No | List of roles that have access to the server. Check [roles](./roles.md) section for more details. | +| server | string | Server | Yes | Identifier of the server. | +| type | string | Type | Yes | Type of the server. Can be one of: api, athena, azure, bigquery, clickhouse, cloudsql, custom, databricks, db2, denodo, dremio, duckdb, exasol, glue, hive, impala, informix, kafka, kinesis, local, mysql, oracle, postgres, postgresql, presto, pubsub, redshift, s3, sftp, snowflake, sqlserver, synapse, trino, vertica, zen. | +| customProperties | array | Custom Properties | No | Custom properties that are not part of the standard. | ## Specific Server Properties @@ -63,6 +63,8 @@ If your server is not in the list, please use [custom](#custom-server) and sugge ### API Server +An API server describes data that is exposed through a network API rather than served from a database or file storage. The endpoint a consumer calls is identified by its URL. + | Key | Type | UX Label | Required | Description | | ------------ | ------ | -------- | -------- | -------------- | | **location** | string | Location | Yes | URL to the API | @@ -81,6 +83,8 @@ If your server is not in the list, please use [custom](#custom-server) and sugge ### Azure Server +[Azure Blob Storage](https://azure.microsoft.com/en-us/products/storage/blobs) and [Azure Data Lake Storage (ADLS)](https://azure.microsoft.com/en-us/products/storage/data-lake-storage) are the Microsoft Azure object storage services for unstructured data and large-scale analytics workloads. + | Key | Type | UX Label | Required | Description | | --------- | ------ | --------- | -------- | ----------------------------------------------------------------------------------------------------- | | delimiter | string | Delimiter | No | Only for format = json. How multiple json documents are delimited within one file | @@ -120,6 +124,8 @@ If your server is not in the list, please use [custom](#custom-server) and sugge ### Databricks Server +[Databricks](https://www.databricks.com/) is a cloud-based data platform, built on Apache Spark, that unifies data warehousing and data lakes under the lakehouse architecture. + | Key | Type | UX Label | Required | Description | | ------- | ------ | -------- | -------- | ------------------------------------- | | catalog | string | Catalog | Yes | The name of the Hive or Unity catalog | @@ -128,6 +134,8 @@ If your server is not in the list, please use [custom](#custom-server) and sugge ### IBM Db2 Server +[IBM Db2](https://www.ibm.com/products/db2) is a family of relational database management systems for transactional and analytical workloads, available both on cloud and on-premises. + | Key | Type | UX Label | Required | Description | | -------- | ------- | -------- | -------- | ------------------------------- | | database | string | Database | Yes | The name of the database. | @@ -137,6 +145,8 @@ If your server is not in the list, please use [custom](#custom-server) and sugge ### Denodo Server +[Denodo](https://www.denodo.com/) is a data virtualization platform that provides unified, real-time access to data spread across disparate sources, without replicating it. + | Key | Type | UX Label | Required | Description | | -------- | ------- | -------- | -------- | ------------------------------ | | database | string | Database | No | The name of the database. | @@ -145,6 +155,8 @@ If your server is not in the list, please use [custom](#custom-server) and sugge ### Dremio Server +[Dremio](https://www.dremio.com/) is a lakehouse platform that runs SQL queries directly against data lake storage, built on Apache Arrow and Apache Iceberg. + | Key | Type | UX Label | Required | Description | | ------ | ------- | -------- | -------- | ------------------------------ | | host | string | Host | Yes | The host of the Dremio server. | @@ -160,8 +172,22 @@ If your server is not in the list, please use [custom](#custom-server) and sugge | database | string | Database | Yes | Path to duckdb database file. | | schema | string | Schema | No | The name of the schema. | +### Exasol + +[Exasol](https://www.exasol.com/) is an in-memory, massively parallel processing (MPP) analytics database used as an enterprise data warehouse. Added in ODCS v3.2.0 ([RFC 0058](https://github.com/bitol-io/tsc/blob/main/rfcs/approved/odcs-v3.2.0/0058-exasol-server-type.md)). + +An Exasol cluster runs a single database and the schema is the namespace, so there is no `database` field. + +| Key | Type | UX Label | Required | Description | +| ------ | ------- | -------- | -------- | -------------------------------------------------------------------------------------- | +| host | string | Host | Yes | Host of the Exasol server. May be a cluster connection range, e.g. `n11..14.acme.com`. | +| port | integer | Port | No | Port of the Exasol server. Defaults to 8563. | +| schema | string | Schema | No | Name of the schema. | + ### Amazon Glue +[AWS Glue](https://aws.amazon.com/glue/) is a serverless data integration service. Its Data Catalog holds the table definitions and schema metadata describing data stored in Amazon S3 and other sources. + | Key | Type | UX Label | Required | Description | | -------- | ------ | -------- | -------- | ----------------------------------------------------------------------------------------------------- | | account | string | Account | Yes | The AWS Glue account | @@ -201,18 +227,20 @@ If your server is not in the list, please use [custom](#custom-server) and sugge | host | string | Host | Yes | The host to the Impala server. | | port | integer | Port | No | The port to the Impala server. Defaults to 21050. | -### IBM Informix and HCL Informix +### HCL Informix and IBM Informix -[IBM Informix](https://www.ibm.com/products/informix) is a high performance, always-on, highly scalable and easily embeddable enterprise-class database optimized for the most demanding transactional and analytics workloads. As an object-relational engine, IBM Informix seamlessly integrates the best of relational and object-oriented capabilities enabling the flexible modeling of complex data structures and relationships. +[HCL Informix](https://www.hcl-software.com/informix) and [IBM Informix](https://www.ibm.com/products/informix) are high performance, always-on, highly scalable and easily embeddable enterprise-class databases optimized for the most demanding transactional and analytics workloads. As object-relational engines, HCL Informix and IBM Informix seamlessly integrate the best of relational and object-oriented capabilities, enabling the flexible modeling of complex data structures and relationships. -| Key | Type | UX Label | Required | Description | -| -------- | ------- | -------- | -------- | -------------------------------------------------- | -| database | string | Database | Yes | The name of the database. | -| host | string | Host | Yes | The host to the Informix server. | -| port | integer | Port | No | The port to the Informix server. Defaults to 9088. | +| Key | Type | UX Label | Required | Description | +| -------- | ------- | -------- | -------- | ----------------------------------------------------------------------- | +| database | string | Database | Yes | The name of the database. | +| host | string | Host | Yes | The host to the HCL Informix and IBM Informix server. | +| port | integer | Port | No | The port to the HCL Informix and IBM Informix server. Defaults to 9088. | ### Kafka Server +[Apache Kafka](https://kafka.apache.org/) is an open-source distributed event streaming platform used for high-performance data pipelines, streaming analytics, and event-driven applications. + | Key | Type | UX Label | Required | Description | | -------- | ------ | -------- | -------- | ----------------------------------------------------------------------------------------------------- | | encoding | string | Encoding | No | Expected character encoding of the payload, e.g. UTF-8, ISO-8859-1, ASCII, UTF-16. Defaults to UTF-8. | @@ -221,6 +249,8 @@ If your server is not in the list, please use [custom](#custom-server) and sugge ### Amazon Kinesis +[Amazon Kinesis Data Streams](https://aws.amazon.com/kinesis/) is a serverless streaming data service for collecting, processing, and analyzing large streams of records in real time. + | Key | Type | UX Label | Required | Description | | -------- | ------ | -------- | -------- | ----------------------------------------------------------------------------------------------------- | | encoding | string | Encoding | No | Expected character encoding of the payload, e.g. UTF-8, ISO-8859-1, ASCII, UTF-16. Defaults to UTF-8. | @@ -230,6 +260,8 @@ If your server is not in the list, please use [custom](#custom-server) and sugge ### Local Files +A local server describes data stored as one or more files on the local file system, addressed by a relative or absolute path. It is typically used for development, testing, and small datasets. + | Key | Type | UX Label | Required | Description | | -------- | ------ | -------- | -------- | ----------------------------------------------------------------------------------------------------- | | encoding | string | Encoding | No | Expected character encoding of the payload, e.g. UTF-8, ISO-8859-1, ASCII, UTF-16. Defaults to UTF-8. | @@ -238,6 +270,8 @@ If your server is not in the list, please use [custom](#custom-server) and sugge ### MySQL Server +[MySQL](https://www.mysql.com/) is an open-source relational database management system, widely used for transactional and web applications. + | Key | Type | UX Label | Required | Description | | -------- | ------- | -------- | -------- | ----------------------------------------------- | | database | string | Database | Yes | The name of the database. | @@ -246,6 +280,8 @@ If your server is not in the list, please use [custom](#custom-server) and sugge ### Oracle +[Oracle Database](https://www.oracle.com/database/) is a multi-model relational database management system used for transactional and analytical enterprise workloads. Clients connect to a named service rather than directly to a database. + | Key | Type | UX Label | Required | Description | | ----------- | ------- | ------------ | -------- | ------------------------------ | | host | string | Host | Yes | The host to the Oracle server | @@ -265,6 +301,8 @@ If your server is not in the list, please use [custom](#custom-server) and sugge ### Presto Server +[Presto](https://prestodb.io/) is an open-source distributed SQL query engine for running interactive analytic queries against data sources of any size, from gigabytes to petabytes. + | Key | Type | UX Label | Required | Description | | ------- | ------ | -------- | -------- | ----------------------------- | | catalog | string | Catalog | No | The name of the catalog. | @@ -327,6 +365,8 @@ Secure File Transfer Protocol (SFTP) is a network protocol that enables secure a ### Snowflake +[Snowflake](https://www.snowflake.com/) is a fully managed cloud data platform that separates storage from compute, where compute is provided by virtual warehouses that can be sized and scaled independently. + | Key | Type | UX Label | Required | Description | | --------- | ------- | --------- | -------- | --------------------------------------------------------------------------- | | account | string | Account | Yes | The Snowflake account used by the server. | @@ -349,6 +389,8 @@ Secure File Transfer Protocol (SFTP) is a network protocol that enables secure a ### Synapse Server +[Azure Synapse Analytics](https://azure.microsoft.com/en-us/products/synapse-analytics) is the Microsoft Azure analytics service that brings together enterprise data warehousing and big data analytics. + | Key | Type | UX Label | Required | Description | | -------- | ------- | -------- | -------- | ------------------------------- | | database | string | Database | Yes | The name of the database. | @@ -357,6 +399,8 @@ Secure File Transfer Protocol (SFTP) is a network protocol that enables secure a ### Trino Server +[Trino](https://trino.io/) is an open-source distributed SQL query engine designed to query large datasets across one or more heterogeneous data sources. + | Key | Type | UX Label | Required | Description | | ------- | ------- | -------- | -------- | --------------------------------------- | | catalog | string | Catalog | Yes | The name of the catalog. | @@ -366,6 +410,8 @@ Secure File Transfer Protocol (SFTP) is a network protocol that enables secure a ### Vertica Server +[Vertica](https://docs.vertica.com/) is a column-oriented, massively parallel processing (MPP) analytical database for large-scale data warehousing. + | Key | Type | UX Label | Required | Description | | -------- | ------- | -------- | -------- | ------------------------------- | | database | string | Database | Yes | The name of the database. | @@ -385,6 +431,8 @@ Actian Zen (formerly Btrieve, later named Pervasive PSQL until version 13) is an ### Custom Server +A custom server describes any technology that does not have a dedicated type in ODCS yet. It accepts the union of the properties defined by the other server types, so connection details can still be expressed in a structured way. + | Key | Type | UX Label | Required | Description | | ----------- | ------- | ----------------- | -------- | ----------------------------------------------------------------------------------------------------- | | account | string | Account | No | Account used by the server. | diff --git a/docs/variables.md b/docs/variables.md index 69585a0..28b814b 100644 --- a/docs/variables.md +++ b/docs/variables.md @@ -24,7 +24,7 @@ servers: environment: prod type: postgresql host: ${DB_HOST} - port: 5432 + port: ${DB_PORT:-5432} database: ${DB_NAME:-orders} schema: ${DB_SCHEMA:-public} ``` @@ -53,7 +53,8 @@ quality: ## Notes -* Interpolation applies to **string** values only. A field typed as an integer or boolean in the JSON schema (such as a server `port`) cannot hold a variable reference: the unresolved token is a string and the schema rejects it. +* Interpolation applies to **string** values only. A field typed as an integer or boolean in the JSON schema cannot hold a variable reference: the unresolved token is a string and the schema rejects it. +* The server `port` is an exception: the schema accepts an integer or a string, so it can hold a variable reference such as `${DB_PORT}` or `${DB_PORT:-5432}`. * No new section or field is added to the standard: a contract using variables validates against the standard JSON schema as-is. [Back to TOC](README.md) diff --git a/schema/odcs-json-schema-latest.json b/schema/odcs-json-schema-latest.json index 998b907..3c83ece 100644 --- a/schema/odcs-json-schema-latest.json +++ b/schema/odcs-json-schema-latest.json @@ -217,6 +217,10 @@ "description": "Stable technical identifier for references. Must be unique within its containing array. Cannot contain special characters ('-', '_' allowed).", "pattern": "^[A-Za-z0-9_-]+$" }, + "Port": { + "type": ["integer", "string"], + "description": "A network port: an integer, or a string, e.g. to hold a variable reference such as ${DB_PORT} resolved at runtime (RFC 0050)." + }, "Server": { "type": "object", "description": "Data source details of where data is physically stored.", @@ -233,7 +237,7 @@ "description": "Type of the server.", "enum": [ "api", "athena", "azure", "bigquery", "clickhouse", "databricks", "denodo", "dremio", - "duckdb", "glue", "hana", "cloudsql", "db2", "hive", "iceberg", "impala", "informix", "kafka", "kinesis", "local", + "duckdb", "exasol", "glue", "hana", "cloudsql", "db2", "hive", "iceberg", "impala", "informix", "kafka", "kinesis", "local", "mysql", "oracle", "postgresql", "postgres", "presto", "pubsub", "redshift", "s3", "sftp", "snowflake", "sqlserver", "synapse", "trino", "vertica", "zen", "custom" ] @@ -376,6 +380,19 @@ "$ref": "#/$defs/ServerSource/DuckdbServer" } }, + { + "if": { + "properties": { + "type": { + "const": "exasol" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/ExasolServer" + } + }, { "if": { "properties": { @@ -859,7 +876,7 @@ "description": "The host of the ClickHouse server." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port to the ClickHouse server." }, "database": { @@ -907,7 +924,7 @@ "description": "The host of the Denodo server." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port of the Denodo server." }, "database": { @@ -929,7 +946,7 @@ "description": "The host of the Dremio server." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port of the Dremio server." }, "schema": { @@ -959,6 +976,35 @@ "database" ] }, + "ExasolServer": { + "type": "object", + "title": "ExasolServer", + "properties": { + "host": { + "type": "string", + "description": "Host of the Exasol server. May be a cluster connection range.", + "examples": [ + "exasol.acme.com", + "n11..14.acme.com" + ] + }, + "port": { + "$ref": "#/$defs/Port", + "description": "Port of the Exasol server.", + "default": 8563, + "examples": [ + 8563 + ] + }, + "schema": { + "type": "string", + "description": "Name of the schema." + } + }, + "required": [ + "host" + ] + }, "GlueServer": { "type": "object", "title": "GlueServer", @@ -1020,7 +1066,7 @@ "description": "The host of the Google Cloud Sql server." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port of the Google Cloud Sql server." }, "database": { @@ -1048,7 +1094,7 @@ "description": "The host of the IBM DB2 server." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port of the IBM DB2 server." }, "database": { @@ -1075,7 +1121,7 @@ "description": "The host to the Hive server. " }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port to the Hive server. Defaults to 10000." }, "database": { @@ -1097,7 +1143,7 @@ "description": "The host to the Impala server." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port to the Impala server. Defaults to 21050." }, "database": { @@ -1119,7 +1165,7 @@ "description": "The host to the Informix server. " }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port to the Informix server. Defaults to 9088." }, "database": { @@ -1141,7 +1187,7 @@ "description": "Hostname or IP address of the Zen server." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "Zen server SQL connections port. Defaults to 1583." }, "database": { @@ -1208,7 +1254,7 @@ "description": "Relative or absolute path to the data file(s)." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "Port to the server. No default value is assumed for custom servers." }, "project": { @@ -1355,7 +1401,7 @@ "description": "The host of the MySql server." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port of the MySql server." }, "database": { @@ -1381,7 +1427,7 @@ ] }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port to the oracle server.", "examples": [ 1523 @@ -1410,7 +1456,7 @@ "description": "The host to the Postgres server" }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port to the Postgres server." }, "database": { @@ -1438,7 +1484,7 @@ "description": "Host of the HANA server." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "Port of the HANA server." }, "database": { @@ -1664,7 +1710,7 @@ "description": "The host to the Snowflake server" }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port to the Snowflake server." }, "account": { @@ -1702,7 +1748,7 @@ ] }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port to the database server.", "default": 1433, "examples": [ @@ -1739,7 +1785,7 @@ "description": "The host of the Synapse server." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port of the Synapse server." }, "database": { @@ -1765,7 +1811,7 @@ ] }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The Trino port." }, "catalog": { @@ -1799,7 +1845,7 @@ "description": "The host of the Vertica server." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port of the Vertica server." }, "database": { diff --git a/schema/odcs-json-schema-v3.2.0.json b/schema/odcs-json-schema-v3.2.0.json index 10ed679..bac09b3 100644 --- a/schema/odcs-json-schema-v3.2.0.json +++ b/schema/odcs-json-schema-v3.2.0.json @@ -216,6 +216,10 @@ "description": "Stable technical identifier for references. Must be unique within its containing array. Cannot contain special characters ('-', '_' allowed).", "pattern": "^[A-Za-z0-9_-]+$" }, + "Port": { + "type": ["integer", "string"], + "description": "A network port: an integer, or a string, e.g. to hold a variable reference such as ${DB_PORT} resolved at runtime (RFC 0050)." + }, "Server": { "type": "object", "description": "Data source details of where data is physically stored.", @@ -232,7 +236,7 @@ "description": "Type of the server.", "enum": [ "api", "athena", "azure", "bigquery", "clickhouse", "databricks", "denodo", "dremio", - "duckdb", "glue", "hana", "cloudsql", "db2", "hive", "iceberg", "impala", "informix", "kafka", "kinesis", "local", + "duckdb", "exasol", "glue", "hana", "cloudsql", "db2", "hive", "iceberg", "impala", "informix", "kafka", "kinesis", "local", "mysql", "oracle", "postgresql", "postgres", "presto", "pubsub", "redshift", "s3", "sftp", "snowflake", "sqlserver", "synapse", "trino", "vertica", "zen", "custom" ] @@ -375,6 +379,19 @@ "$ref": "#/$defs/ServerSource/DuckdbServer" } }, + { + "if": { + "properties": { + "type": { + "const": "exasol" + } + }, + "required": ["type"] + }, + "then": { + "$ref": "#/$defs/ServerSource/ExasolServer" + } + }, { "if": { "properties": { @@ -858,7 +875,7 @@ "description": "The host of the ClickHouse server." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port to the ClickHouse server." }, "database": { @@ -906,7 +923,7 @@ "description": "The host of the Denodo server." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port of the Denodo server." }, "database": { @@ -928,7 +945,7 @@ "description": "The host of the Dremio server." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port of the Dremio server." }, "schema": { @@ -958,6 +975,35 @@ "database" ] }, + "ExasolServer": { + "type": "object", + "title": "ExasolServer", + "properties": { + "host": { + "type": "string", + "description": "Host of the Exasol server. May be a cluster connection range.", + "examples": [ + "exasol.acme.com", + "n11..14.acme.com" + ] + }, + "port": { + "$ref": "#/$defs/Port", + "description": "Port of the Exasol server.", + "default": 8563, + "examples": [ + 8563 + ] + }, + "schema": { + "type": "string", + "description": "Name of the schema." + } + }, + "required": [ + "host" + ] + }, "GlueServer": { "type": "object", "title": "GlueServer", @@ -1019,7 +1065,7 @@ "description": "The host of the Google Cloud Sql server." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port of the Google Cloud Sql server." }, "database": { @@ -1047,7 +1093,7 @@ "description": "The host of the IBM DB2 server." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port of the IBM DB2 server." }, "database": { @@ -1074,7 +1120,7 @@ "description": "The host to the Hive server. " }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port to the Hive server. Defaults to 10000." }, "database": { @@ -1096,7 +1142,7 @@ "description": "The host to the Impala server." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port to the Impala server. Defaults to 21050." }, "database": { @@ -1118,7 +1164,7 @@ "description": "The host to the Informix server. " }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port to the Informix server. Defaults to 9088." }, "database": { @@ -1140,7 +1186,7 @@ "description": "Hostname or IP address of the Zen server." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "Zen server SQL connections port. Defaults to 1583." }, "database": { @@ -1207,7 +1253,7 @@ "description": "Relative or absolute path to the data file(s)." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "Port to the server. No default value is assumed for custom servers." }, "project": { @@ -1354,7 +1400,7 @@ "description": "The host of the MySql server." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port of the MySql server." }, "database": { @@ -1380,7 +1426,7 @@ ] }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port to the oracle server.", "examples": [ 1523 @@ -1409,7 +1455,7 @@ "description": "The host to the Postgres server" }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port to the Postgres server." }, "database": { @@ -1437,7 +1483,7 @@ "description": "Host of the HANA server." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "Port of the HANA server." }, "database": { @@ -1663,7 +1709,7 @@ "description": "The host to the Snowflake server" }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port to the Snowflake server." }, "account": { @@ -1701,7 +1747,7 @@ ] }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port to the database server.", "default": 1433, "examples": [ @@ -1738,7 +1784,7 @@ "description": "The host of the Synapse server." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port of the Synapse server." }, "database": { @@ -1764,7 +1810,7 @@ ] }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The Trino port." }, "catalog": { @@ -1798,7 +1844,7 @@ "description": "The host of the Vertica server." }, "port": { - "type": "integer", + "$ref": "#/$defs/Port", "description": "The port of the Vertica server." }, "database": { diff --git a/src/script/negative-tests/exasol-missing-host.odcs.yaml b/src/script/negative-tests/exasol-missing-host.odcs.yaml new file mode 100644 index 0000000..7339e22 --- /dev/null +++ b/src/script/negative-tests/exasol-missing-host.odcs.yaml @@ -0,0 +1,19 @@ +# Copyright 2026 The Bitol Contributors +# SPDX-License-Identifier: Apache-2.0 + +# RFC-0058 negative test: an `exasol` server requires `host`. Here `host` is +# omitted, so the schema MUST reject this contract. + +version: 1.0.0 +apiVersion: v3.2.0 +kind: DataContract +id: 6d0b2f84-9e35-4a71-c2b8-7f1d4c6e0a53 +status: active +servers: + - server: prod + type: exasol + port: 8563 + schema: SALES +schema: + - name: sales + physicalType: table diff --git a/src/script/negative-tests/variables-in-integer-field.odcs.yaml b/src/script/negative-tests/variables-in-integer-field.odcs.yaml index cd971f1..321380f 100644 --- a/src/script/negative-tests/variables-in-integer-field.odcs.yaml +++ b/src/script/negative-tests/variables-in-integer-field.odcs.yaml @@ -2,8 +2,10 @@ # SPDX-License-Identifier: Apache-2.0 # RFC-0050 negative test: variable interpolation applies to STRING values only. -# A `postgresql` server `port` is typed as an integer, so the unresolved -# ${DB_PORT} token (a string) MUST be rejected by the schema. +# `primaryKeyPosition` is typed as an integer, so the unresolved ${KEY_POS} +# token (a string) MUST be rejected by the schema. (The server `port` is an +# explicit exception: it accepts integer or string, so it can hold a +# variable reference.) version: 1.0.0 apiVersion: v3.2.0 @@ -21,3 +23,9 @@ servers: schema: - name: orders physicalType: table + properties: + - name: order_id + logicalType: string + physicalType: varchar(36) + primaryKey: true + primaryKeyPosition: ${KEY_POS}