diff --git a/product_docs/docs/biganimal/release/getting_started/managing_cluster.mdx b/product_docs/docs/biganimal/release/getting_started/managing_cluster.mdx index 734bc825d86..3be340ce116 100644 --- a/product_docs/docs/biganimal/release/getting_started/managing_cluster.mdx +++ b/product_docs/docs/biganimal/release/getting_started/managing_cluster.mdx @@ -22,7 +22,7 @@ After seven days, single-node and high-availability clusters automatically resum 2. Do one of the following: - In the row for the cluster, at right, from the ellipsis menu, select **Pause Cluster**. - Select the cluster you want to pause. From **Quick Actions** on the cluster details page, select **Pause Cluster**. -3. Confirm that you want to pause the cluster. When the process finishes, the cluster status appears as Paused. It may take up to 15 minutes for the compute instance in your CSP to scale down. +3. Confirm that you want to pause the cluster. When the process finishes, the cluster status appears as Paused. It can take up to 15 minutes for the compute instance in your CSP to scale down. ### Resuming a cluster diff --git a/product_docs/docs/biganimal/release/release_notes/apr_2023_rel_notes.mdx b/product_docs/docs/biganimal/release/release_notes/apr_2023_rel_notes.mdx index 4d446ae3bdb..6a2160bc2f2 100644 --- a/product_docs/docs/biganimal/release/release_notes/apr_2023_rel_notes.mdx +++ b/product_docs/docs/biganimal/release/release_notes/apr_2023_rel_notes.mdx @@ -3,7 +3,7 @@ title: BigAnimal April release notes navTitle: "April 2023" --- -BigAnimal's April 2023 release includes the following enhancements and bugfixes: +BigAnimal's April 2023 release includes the following enhancements and bug fixes: | Type | Description | | ----------- | ------------------------------------------------------------------ | diff --git a/product_docs/docs/biganimal/release/release_notes/aug_2023_rel_notes.mdx b/product_docs/docs/biganimal/release/release_notes/aug_2023_rel_notes.mdx index e0788405301..c3280aed066 100644 --- a/product_docs/docs/biganimal/release/release_notes/aug_2023_rel_notes.mdx +++ b/product_docs/docs/biganimal/release/release_notes/aug_2023_rel_notes.mdx @@ -3,7 +3,7 @@ title: BigAnimal August release notes navTitle: "August 2023" --- -BigAnimal's August 2023 release includes the following enhancements and bugfixes: +BigAnimal's August 2023 release includes the following enhancements and bug fixes: | Type | Description | | ----------- | ----------------------------------------------------------------------- | diff --git a/product_docs/docs/biganimal/release/release_notes/dec_2023_rel_notes.mdx b/product_docs/docs/biganimal/release/release_notes/dec_2023_rel_notes.mdx index e73a3d0a317..255812f8048 100644 --- a/product_docs/docs/biganimal/release/release_notes/dec_2023_rel_notes.mdx +++ b/product_docs/docs/biganimal/release/release_notes/dec_2023_rel_notes.mdx @@ -3,7 +3,7 @@ title: BigAnimal December release notes navTitle: "December 2023" --- -BigAnimal's December 2023 release includes the following enhancements and bugfixes: +BigAnimal's December 2023 release includes the following enhancements and bug fixes: | Type | Description | | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/product_docs/docs/biganimal/release/release_notes/feb_2023_rel_notes.mdx b/product_docs/docs/biganimal/release/release_notes/feb_2023_rel_notes.mdx index 584e139f050..7f9bbac066f 100644 --- a/product_docs/docs/biganimal/release/release_notes/feb_2023_rel_notes.mdx +++ b/product_docs/docs/biganimal/release/release_notes/feb_2023_rel_notes.mdx @@ -3,7 +3,7 @@ title: BigAnimal February release notes navTitle: "February 2023" --- -BigAnimal's February 2023 release includes the following enhancements and bugfixes: +BigAnimal's February 2023 release includes the following enhancements and bug fixes: | Type | Description | | ----------- | ------------------------------------------------------------ | diff --git a/product_docs/docs/biganimal/release/release_notes/jan_2023_rel_notes.mdx b/product_docs/docs/biganimal/release/release_notes/jan_2023_rel_notes.mdx index d803816c8e3..4cc667e3bf5 100644 --- a/product_docs/docs/biganimal/release/release_notes/jan_2023_rel_notes.mdx +++ b/product_docs/docs/biganimal/release/release_notes/jan_2023_rel_notes.mdx @@ -3,10 +3,10 @@ title: BigAnimal January release notes navTitle: "January 2023" --- -BigAnimal's January 2023 release includes the following enhancements and bugfixes: +BigAnimal's January 2023 release includes the following enhancements and bug fixes: | Type | Description | | ----------- | ------------------------------------------------------------------------------------------------------------------------------- | | Enhancement | Added support for an additional AWS region: AWS Asia Pacific Southeast 2 (Sydney). | -| Enhancement | BigAnimal CLI v1.12.0 & v1.13.0 is now allowing users to provision far away replicas and get monitoring info for their clusters. | +| Enhancement | BigAnimal CLI v1.12.0 & v1.13.0 now allows users to provision faraway replicas and get monitoring info for their clusters. | \ No newline at end of file diff --git a/product_docs/docs/biganimal/release/release_notes/jul_2023_rel_notes.mdx b/product_docs/docs/biganimal/release/release_notes/jul_2023_rel_notes.mdx index 3bdcb19a5fb..3c07a1f596c 100644 --- a/product_docs/docs/biganimal/release/release_notes/jul_2023_rel_notes.mdx +++ b/product_docs/docs/biganimal/release/release_notes/jul_2023_rel_notes.mdx @@ -3,11 +3,11 @@ title: BigAnimal July release notes navTitle: "July 2023" --- -BigAnimal's July 2023 release includes the following enhancements and bugfixes: +BigAnimal's July 2023 release includes the following enhancements and bug fixes: | Type | Description | | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Enhancement | Added support Google Cloud, in your cloud account or ours. With the addition of Google Cloud, you can now run BigAnimal on the three largest cloud service providers. | | Enhancement | Added support for GCP with CLI version 2.1.0. | | Enhancement | BigAnimal Terraform provider version 0.5.1 is now available. | -| Enhancement | Added support for several new extensions including EDB Wait States, EDB Query Advisor, and Postgres Failover Slots. | +| Enhancement | Added support for several new extensions, including EDB Wait States, EDB Query Advisor, and Postgres Failover Slots. | diff --git a/product_docs/docs/biganimal/release/release_notes/jun_2023_rel_notes.mdx b/product_docs/docs/biganimal/release/release_notes/jun_2023_rel_notes.mdx index 728a77041fd..a71fc24ca27 100644 --- a/product_docs/docs/biganimal/release/release_notes/jun_2023_rel_notes.mdx +++ b/product_docs/docs/biganimal/release/release_notes/jun_2023_rel_notes.mdx @@ -3,12 +3,12 @@ title: BigAnimal June release notes navTitle: "June 2023" --- -BigAnimal's June 2023 release includes the following enhancements and bugfixes: +BigAnimal's June 2023 release includes the following enhancements and bug fixes: | Type | Description | | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Enhancement | Added support to new deployment and payment options. You can now choose to deploy fully-managed Postgres Database-as-a-service in BigAnimal's cloud account, with simplified credit card billing options to get your workloads up and running seamlessly. | -| Enhancement | Added support for a self-service pay-go purchase experience for BigAnimal. | +| Enhancement | Added new deployment and payment options. You can now choose to deploy fully managed Postgres database-as-a-service in BigAnimal's cloud account, with simplified credit card billing options to get your workloads up and running seamlessly. | +| Enhancement | Added support for a self-service pay-as-you-go purchase experience for BigAnimal. | | Enhancement | You can now configure Postgres superuser privileges for your BigAnimal clusters directly from the portal. Enable superuser access when creating or editing a single-node or high availability cluster if you need to bypass all permission checks on your database.| | Enhancement | Added support for the AWS Asia Pacific South 2 (Hyderabad) region. | | Enhancement | Added support to invite other users by their organizations. | diff --git a/product_docs/docs/biganimal/release/release_notes/mar_2023_rel_notes.mdx b/product_docs/docs/biganimal/release/release_notes/mar_2023_rel_notes.mdx index 0354e138318..9dd8eb80252 100644 --- a/product_docs/docs/biganimal/release/release_notes/mar_2023_rel_notes.mdx +++ b/product_docs/docs/biganimal/release/release_notes/mar_2023_rel_notes.mdx @@ -3,11 +3,11 @@ title: BigAnimal March release notes navTitle: "March 2023" --- -BigAnimal's March 2023 release includes the following enhancements and bugfixes: +BigAnimal's March 2023 release includes the following enhancements and bug fixes: | Type | Description | | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Enhancement | Added support for custom maintenance windows. With custom maintenance windows, you can now have more control over the database restarts during the maintenance upgrade events. | -| Enhancement | Added Autocluster, Refdata and EDB Postgres Tuner extensions.

- Autocluster — A table access method extension from the Advanced Storage Pack that supports faster access for clustered data.

- Refdata — A table access method extension from the Advanced Storage Pack that increases performance and scalability of foreign key lookups on normalized data models.

- EDB Postgres Tuner — It is available in BigAnimal to provide intelligent parameter tuning recommendations based on your clusters' settings. | +| Enhancement | Added Autocluster, Refdata, and EDB Postgres Tuner extensions.

- Autocluster — A table access method extension from the Advanced Storage Pack that supports faster access for clustered data.

- Refdata — A table access method extension from the Advanced Storage Pack that increases performance and scalability of foreign key lookups on normalized data models.

- EDB Postgres Tuner — Available in BigAnimal to provide intelligent parameter tuning recommendations based on your clusters' settings. | | Enhancement | BigAnimal CLI v1.14.0 is now available. | | Security fix | Added [PCI DSS Compliance Certification](https://www.enterprisedb.com/blog/EDB-BigAnimal-PCI-Certification-Security). | \ No newline at end of file diff --git a/product_docs/docs/biganimal/release/release_notes/may_2023_rel_notes.mdx b/product_docs/docs/biganimal/release/release_notes/may_2023_rel_notes.mdx index 519aed4c950..b00b27641ef 100644 --- a/product_docs/docs/biganimal/release/release_notes/may_2023_rel_notes.mdx +++ b/product_docs/docs/biganimal/release/release_notes/may_2023_rel_notes.mdx @@ -3,7 +3,7 @@ title: BigAnimal May release notes navTitle: "May 2023" --- -BigAnimal's May 2023 release includes the following enhancements and bugfixes: +BigAnimal's May 2023 release includes the following enhancements and bug fixes: | Type | Description | | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | diff --git a/product_docs/docs/biganimal/release/release_notes/nov_2023_rel_notes.mdx b/product_docs/docs/biganimal/release/release_notes/nov_2023_rel_notes.mdx index cbe24da438b..0ae684da217 100644 --- a/product_docs/docs/biganimal/release/release_notes/nov_2023_rel_notes.mdx +++ b/product_docs/docs/biganimal/release/release_notes/nov_2023_rel_notes.mdx @@ -3,13 +3,13 @@ title: BigAnimal November release notes navTitle: "November 2023" --- -BigAnimal's November 2023 release includes the following enhancements and bugfixes: +BigAnimal's November 2023 release includes the following enhancements and bug fixes: | Type | Description | | ----------- | --------------------------------------------------------------------------------------------------------------------------- | -| Enhancement | Added support for new extension PostGIS to allow storage and processing of geo-spatial data types in Postgres on BigAnimal. | +| Enhancement | Added support for new extension PostGIS to allow storage and processing of geospatial data types in Postgres on BigAnimal. | | Enhancement | BigAnimal CLI version 3.3.0 is now available. | | Enhancement | Added support for EDB Postgres Advanced Server and EDB Postgres Extended Server version 16. | -| Enhancement | Added support for AWS eu-south-2 (spain) region. | +| Enhancement | Added support for AWS Europe (Spain) region. | | Enhancement | BigAnimal is now available on AWS marketplace. | diff --git a/product_docs/docs/biganimal/release/release_notes/oct_2023_rel_notes.mdx b/product_docs/docs/biganimal/release/release_notes/oct_2023_rel_notes.mdx index e2d8d42cedc..2cfd82a9b7d 100644 --- a/product_docs/docs/biganimal/release/release_notes/oct_2023_rel_notes.mdx +++ b/product_docs/docs/biganimal/release/release_notes/oct_2023_rel_notes.mdx @@ -3,7 +3,7 @@ title: BigAnimal October release notes navTitle: "October 2023" --- -BigAnimal's October 2023 release includes the following enhancements and bugfixes: +BigAnimal's October 2023 release includes the following enhancements and bug fixes: | Type | Description | | ----------- | --------------------------------------------------------------------------------- | diff --git a/product_docs/docs/biganimal/release/release_notes/sep_2023_rel_notes.mdx b/product_docs/docs/biganimal/release/release_notes/sep_2023_rel_notes.mdx index d4d27694f08..0fd62bd6339 100644 --- a/product_docs/docs/biganimal/release/release_notes/sep_2023_rel_notes.mdx +++ b/product_docs/docs/biganimal/release/release_notes/sep_2023_rel_notes.mdx @@ -3,9 +3,9 @@ title: BigAnimal September release notes navTitle: "September 2023" --- -BigAnimal's September 2023 release includes the following enhancements and bugfixes: +BigAnimal's September 2023 release includes the following enhancements and bug fixes: | Type | Description | | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Enhancement | Added support to deploy fully-managed Postgres Database-as-a-service in BigAnimal's Azure account. | -| Enhancement | Added support for database-level authentication on Bring-Your-Own-Account deployments using your cloud account's Identity and Access Management (IAM) credentials. Admins can now manage database users centrally within your cloud provider's IAM service and database users can authenticate to Postgres using their existing Azure Active Directory, AWS IAM, or Google Cloud IAM credentials. | +| Enhancement | Added support to deploy fully managed Postgres database-as-a-service in BigAnimal's Azure account. | +| Enhancement | Added support for database-level authentication on bring-your-own-account deployments using your cloud account's Identity and Access Management (IAM) credentials. Admins can now manage database users centrally within your cloud provider's IAM service, and database users can authenticate to Postgres using their existing Azure Active Directory, AWS IAM, or Google Cloud IAM credentials. | diff --git a/product_docs/docs/epas/11/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx b/product_docs/docs/epas/11/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx index 42c164b5741..79576c232ee 100644 --- a/product_docs/docs/epas/11/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx +++ b/product_docs/docs/epas/11/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx @@ -65,7 +65,7 @@ EXEC program_action => 'BEGIN INSERT INTO my_log VALUES(current_timestamp); END;', enabled => TRUE, - comment => 'This program adds a row to the my_log table.'); + comments => 'This program adds a row to the my_log table.'); ``` `update_log` is a PL/SQL block that adds a row containing the current date and time to the `my_log` table. The program will be enabled when the `CREATE_PROGRAM` procedure executes. diff --git a/product_docs/docs/epas/11/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx b/product_docs/docs/epas/11/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx index 2c73f15c07f..b209d60f5fd 100644 --- a/product_docs/docs/epas/11/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx +++ b/product_docs/docs/epas/11/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx @@ -51,7 +51,7 @@ The following code fragment calls `CREATE_SCHEDULE` to create a schedule named ` EXEC DBMS_SCHEDULER.CREATE_SCHEDULE ( schedule_name => 'weeknights_at_5', - start_date => '01-JUN-13 09:00:00.000000' + start_date => '01-JUN-13 09:00:00.000000', repeat_interval => 'FREQ=DAILY;BYDAY=MON,TUE,WED,THU,FRI;BYHOUR=17;', comments => 'This schedule executes each weeknight at 5:00'); ``` diff --git a/product_docs/docs/epas/12/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx b/product_docs/docs/epas/12/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx index e5a6792c445..a59799a2465 100644 --- a/product_docs/docs/epas/12/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx +++ b/product_docs/docs/epas/12/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx @@ -65,7 +65,7 @@ EXEC program_action => 'BEGIN INSERT INTO my_log VALUES(current_timestamp); END;', enabled => TRUE, - comment => 'This program adds a row to the my_log table.'); + comments => 'This program adds a row to the my_log table.'); ``` `update_log` is a PL/SQL block that adds a row containing the current date and time to the `my_log` table. The program will be enabled when the `CREATE_PROGRAM` procedure executes. diff --git a/product_docs/docs/epas/12/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx b/product_docs/docs/epas/12/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx index 7d04cbb7b3d..00125442459 100644 --- a/product_docs/docs/epas/12/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx +++ b/product_docs/docs/epas/12/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx @@ -51,7 +51,7 @@ The following code fragment calls `CREATE_SCHEDULE` to create a schedule named ` EXEC DBMS_SCHEDULER.CREATE_SCHEDULE ( schedule_name => 'weeknights_at_5', - start_date => '01-JUN-13 09:00:00.000000' + start_date => '01-JUN-13 09:00:00.000000', repeat_interval => 'FREQ=DAILY;BYDAY=MON,TUE,WED,THU,FRI;BYHOUR=17;', comments => 'This schedule executes each weeknight at 5:00'); ``` diff --git a/product_docs/docs/epas/13/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx b/product_docs/docs/epas/13/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx index 639fbb972d0..75b62232128 100644 --- a/product_docs/docs/epas/13/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx +++ b/product_docs/docs/epas/13/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx @@ -65,7 +65,7 @@ EXEC program_action => 'BEGIN INSERT INTO my_log VALUES(current_timestamp); END;', enabled => TRUE, - comment => 'This program adds a row to the my_log table.'); + comments => 'This program adds a row to the my_log table.'); ``` `update_log` is a PL/SQL block that adds a row containing the current date and time to the `my_log` table. The program will be enabled when the `CREATE_PROGRAM` procedure executes. diff --git a/product_docs/docs/epas/13/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx b/product_docs/docs/epas/13/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx index 5cc8d9e5c42..23b3676a4fc 100644 --- a/product_docs/docs/epas/13/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx +++ b/product_docs/docs/epas/13/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx @@ -51,7 +51,7 @@ The following code fragment calls `CREATE_SCHEDULE` to create a schedule named ` EXEC DBMS_SCHEDULER.CREATE_SCHEDULE ( schedule_name => 'weeknights_at_5', - start_date => '01-JUN-13 09:00:00.000000' + start_date => '01-JUN-13 09:00:00.000000', repeat_interval => 'FREQ=DAILY;BYDAY=MON,TUE,WED,THU,FRI;BYHOUR=17;', comments => 'This schedule executes each weeknight at 5:00'); ``` diff --git a/product_docs/docs/epas/14/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx b/product_docs/docs/epas/14/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx index 44fefde00d5..07207e30e58 100644 --- a/product_docs/docs/epas/14/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx +++ b/product_docs/docs/epas/14/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx @@ -61,7 +61,7 @@ EXEC program_action => 'BEGIN INSERT INTO my_log VALUES(current_timestamp); END;', enabled => TRUE, - comment => 'This program adds a row to the my_log table.'); + comments => 'This program adds a row to the my_log table.'); ``` `update_log` is a PL/SQL block that adds a row containing the current date and time to the `my_log` table. The program is enabled when the `CREATE_PROGRAM` procedure executes. diff --git a/product_docs/docs/epas/14/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx b/product_docs/docs/epas/14/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx index 55369b65d12..4a0f53a56e9 100644 --- a/product_docs/docs/epas/14/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx +++ b/product_docs/docs/epas/14/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx @@ -49,7 +49,7 @@ This code fragment calls `CREATE_SCHEDULE` to create a schedule named `weeknight EXEC DBMS_SCHEDULER.CREATE_SCHEDULE ( schedule_name => 'weeknights_at_5', - start_date => '01-JUN-13 09:00:00.000000' + start_date => '01-JUN-13 09:00:00.000000', repeat_interval => 'FREQ=DAILY;BYDAY=MON,TUE,WED,THU,FRI;BYHOUR=17;', comments => 'This schedule executes each weeknight at 5:00'); ``` diff --git a/product_docs/docs/epas/15/reference/oracle_compatibility_reference/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx b/product_docs/docs/epas/15/reference/oracle_compatibility_reference/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx index 8d278f9e528..6680ad735e2 100644 --- a/product_docs/docs/epas/15/reference/oracle_compatibility_reference/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx +++ b/product_docs/docs/epas/15/reference/oracle_compatibility_reference/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx @@ -63,7 +63,7 @@ EXEC program_action => 'BEGIN INSERT INTO my_log VALUES(current_timestamp); END;', enabled => TRUE, - comment => 'This program adds a row to the my_log table.'); + comments => 'This program adds a row to the my_log table.'); ``` `update_log` is a PL/SQL block that adds a row containing the current date and time to the `my_log` table. The program is enabled when the `CREATE_PROGRAM` procedure executes. diff --git a/product_docs/docs/epas/15/reference/oracle_compatibility_reference/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx b/product_docs/docs/epas/15/reference/oracle_compatibility_reference/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx index 43fc2d10e83..9cf4a6116ce 100644 --- a/product_docs/docs/epas/15/reference/oracle_compatibility_reference/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx +++ b/product_docs/docs/epas/15/reference/oracle_compatibility_reference/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx @@ -51,7 +51,7 @@ This code fragment calls `CREATE_SCHEDULE` to create a schedule named `weeknight EXEC DBMS_SCHEDULER.CREATE_SCHEDULE ( schedule_name => 'weeknights_at_5', - start_date => '01-JUN-13 09:00:00.000000' + start_date => '01-JUN-13 09:00:00.000000', repeat_interval => 'FREQ=DAILY;BYDAY=MON,TUE,WED,THU,FRI;BYHOUR=17;', comments => 'This schedule executes each weeknight at 5:00'); ``` diff --git a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/01_numeric_types.mdx b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/01_numeric_types.mdx index c0c8d2b5793..d91cdf5434c 100644 --- a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/01_numeric_types.mdx +++ b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/01_numeric_types.mdx @@ -5,27 +5,45 @@ legacyRedirectsGenerated: - "/edb-docs/d/edb-postgres-advanced-server/reference/database-compatibility-for-oracle-developers-reference-guide/9.6/Database_Compatibility_for_Oracle_Developers_Reference_Guide.1.012.html" - "/edb-docs/d/edb-postgres-advanced-server/user-guides/database-compatibility-for-oracle-developers-guide/9.5/Database_Compatibility_for_Oracle_Developers_Guide.1.044.html" redirects: - - /epas/latest/epas_compat_reference/02_the_sql_language/02_data_types/01_numeric_types/ #generated for docs/epas/reorg-role-use-case-mode + - ../../../../../epas_compat_reference/02_the_sql_language/02_data_types/01_numeric_types #generated for docs/epas/reorg-role-use-case-mode +source: + url: https://www.postgresql.org/docs/current/datatype-numeric.html + timestamp: 2023-08-30 + --- -Numeric types consist of four-byte integers, four-byte and eight-byte floating-point numbers, and fixed-precision decimals. The following table lists the available types. - -| Name | Storage size | Description | Range | -| ------------------- | ------------ | ---------------------------------------------------------------- | ------------------------------------------- | -| `BINARY_INTEGER` | 4 bytes | Signed integer, alias for `INTEGER` | -2,147,483,648 to +2,147,483,647 | -| `DOUBLE PRECISION` | 8 bytes | Variable-precision, inexact | 15 decimal digits precision | -| `INTEGER` | 4 bytes | Usual choice for integer | -2,147,483,648 to +2,147,483,647 | -| `NUMBER` | Variable | User-specified precision, exact | Up to 1000 digits of precision | -| `NUMBER(p [, s ] )` | Variable | Exact numeric of maximum precision, `p`, and optional scale, `s` | Up to 1000 digits of precision | -| `PLS_INTEGER` | 4 bytes | Signed integer, alias for `INTEGER` | -2,147,483,648 to +2,147,483,647 | -| `REAL` | 4 bytes | Variable-precision, inexact | 6 decimal digits precision | -| `ROWID` | 8 bytes | Signed 8 bit integer. | -9223372036854775808 to 9223372036854775807 | +| Data type | Native | Alias | Description | +| ------------------- | ------ | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `SMALLINT` | ✅ | | Small-range integer, 2 bytes storage, -32768 to +32767 range | +| `INTEGER` | ✅ | | Usual choice for integer, 4 bytes storage, -2147483648 to +2147483647 range | +| `BINARY_INTEGER` | | ✅ | Alias for `INTEGER` | +| `BIGINT` | ✅ | | Large-range integer, 8 bytes storage, -9223372036854775808 to +9223372036854775807 range | | +| `PLS_INTEGER` | | ✅ | Alias for `INTEGER` | +| `DECIMAL` | ✅ | | User-specified precision, exact; variable storage; up to 131072 digits before the decimal point up to 16383 digits after the decimal point range | +| `NUMERIC` | ✅ | | User-specified precision, exact; variable storage, up to 131072 digits before the decimal point; up to 16383 digits after the decimal point range | +| `NUMBER` | | ✅ | Alias for native numeric | +| `NUMBER(p [, s ] )` | | ✅ | Alias of native numeric with exact numeric of maximum precision, `p`, and optional scale, `s`; variable storage, p to 1000 digits of precision | +| `REAL` | ✅ | | Variable-precision, inexact; 4 bytes storage; 6 decimal digits precision range | +| `DOUBLE PRECISION` | ✅ | | Variable-precision, inexact; 8 bytes storage; 15 decimal digits precision range | +| `BINARY FLOAT` | | ✅ | Alias for native `DOUBLE PRECISION` | +| `SMALLSERIAL` | ✅ | | Small autoincrementing integer, 2 bytes storage, 1 to 32767 range | +| `SERIAL` | ✅ | | Autoincrementing integer, 4 bytes storage, 1 to 2147483647 range | +| `BIGSERIAL` | ✅ | | Large autoincrementing integer, 8 bytes storage, 1 to 9223372036854775807 range | +| `ROWID` | | | Custom type for emulating Oracle ROWID, signed 8 bit integer; 8 bytes storage; -9223372036854775808 to 9223372036854775807 range (see [Migration Handbook](/migrating/oracle/oracle_epas_comparison/database_features/#data-types)) | + +## Overview + +Numeric types consist of four-byte integers, four-byte and eight-byte floating-point numbers, and fixed-precision decimals. + +The syntax of constants for the numeric types is described in [Constants](https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS) in the PostgreSQL documentation. The numeric types have a full set of corresponding arithmetic operators and functions. Refer to [Functions and Operators](../03_functions_and_operators) for more information. The following sections describe the types in detail. ## Integer types -The `BINARY_INTEGER`, `INTEGER`, `PLS_INTEGER`, and `ROWID` types store whole numbers (without fractional components) as specified in the numeric types table. Attempts to store values outside of the allowed range result in an error. +The `BIGINT`, `BINARY_INTEGER`, `INTEGER`, `PLS_INTEGER`, `SMALLINT` and `ROWID` types store whole numbers (without fractional components) as specified in the numeric types table. Attempts to store values outside of the allowed range result in an error. + +The type `INTEGER` is the common choice, as it offers the best balance between range, storage size, and performance. The `SMALLINT` type is generally only used if disk space is at a premium. The `BIGINT` type is designed to be used when the range of the `INTEGER` type is insufficient. ## Arbitrary precision numbers @@ -49,6 +67,36 @@ Specifying `NUMBER` without any precision or scale creates a column in which you If the precision or scale of a value is greater than the declared precision or scale of a column, the system attempts to round the value. If the value can't be rounded to satisfy the declared limits, an error occurs. +Numeric values are physically stored without any extra leading or trailing zeroes. Thus, the declared precision and scale of a column are maximums, not fixed allocations. (In this sense the `NUMBER` type is more akin to `VARCHAR(N)` than to `CHAR(N)`.) The actual storage requirement is two bytes for each group of four decimal digits, plus three to eight bytes overhead. + +In addition to ordinary numeric values, the `NUMBER` type allows the special value NaN, meaning “not-a-number”. Any operation on NaN yields another NaN. When writing this value as a constant in an SQL command, you must put quotes around it, for example U`PDATE table SET x = 'NaN'`. On input, the string `NaN` is recognized in a case-insensitive manner. + +!!!Note +In most implementations of the “not-a-number” concept, `NaN` is not considered equal to any other numeric value (including `NaN`). In order to allow numeric values to be sorted and used in tree-based indexes, PostgreS treats `NaN` values as equal, and greater than all non-`NaN` values. +!!! + +The types `DECIMAL` and `NUMBER` are equivalent. Both types are part of the SQL standard. + +When rounding values, the `NUMBER` type rounds ties away from zero, while (on most machines) the `REAL` and `DOUBLE PRECISION` types round ties to the nearest even number. For example: + +```SQL +SELECT x, + round(x::numeric) AS num_round, + round(x::double precision) AS dbl_round +FROM generate_series(-3.5, 3.5, 1) as x; + x | num_round | dbl_round +------+-----------+----------- + -3.5 | -4 | -4 + -2.5 | -3 | -2 + -1.5 | -2 | -2 + -0.5 | -1 | -0 + 0.5 | 1 | 0 + 1.5 | 2 | 2 + 2.5 | 3 | 2 + 3.5 | 4 | 4 +(8 rows) +``` + ## Floating-point types The data types `REAL` and `DOUBLE PRECISION` are *inexact*, variable-precision numeric types. In practice, these types are usually implementations of IEEE Standard 754 for Binary Floating-Point Arithmetic (single and double precision, respectively), to the extent that the underlying processor, operating system, and compiler support it. @@ -63,4 +111,58 @@ Inexact means that some values can't be converted exactly to the internal format On most platforms, the `REAL` type has a range of at least `1E-37` to `1E+37` with a precision of at least six decimal digits. The `DOUBLE PRECISION` type typically has a range of around `1E-307` to `1E+308` with a precision of at least 15 digits. Values that are too large or too small cause an error. Rounding might occur if the precision of an input number is too high. Numbers too close to zero that you can't represent as distinct from zero cause an underflow error. +In addition to ordinary numeric values, the floating-point types have several special values: + + +- `Infinity` +- `-Infinity` +- `NaN` + +These represent the IEEE 754 special values “infinity”, “negative infinity”, and “not-a-number”, respectively. (On a machine whose floating-point arithmetic does not follow IEEE 754, these values will probably not work as expected.) When writing these values as constants in an SQL command, you must put quotes around them, for example `UPDATE table SET x = '-Infinity'`. On input, these strings are recognized in a case-insensitive manner. + +!!!Note +IEEE754 specifies that NaN should not compare equal to any other floating-point value (including `NaN`). In order to allow floating-point values to be sorted and used in tree-based indexes, Postgres treats `NaN` values as equal, and greater than all non-`NaN` values. +!!! + EDB Postgres Advanced Server also supports the SQL standard notations `FLOAT` and `FLOAT(p)` for specifying inexact numeric types. Here, `p` specifies the minimum acceptable precision in binary digits. EDB Postgres Advanced Server accepts `FLOAT(1)` to `FLOAT(24)` as selecting the `REAL` type and `FLOAT(25)` to `FLOAT(53)` as selecting `DOUBLE PRECISION`. Values of `p` outside the allowed range draw an error. `FLOAT` with no precision specified is taken to mean `DOUBLE PRECISION`. + + +!!!Note +The assumption that real and double precision have exactly 24 and 53 bits in the mantissa respectively is correct for IEEE-standard floating point implementations. On non-IEEE platforms it might be off a little, but for simplicity the same ranges of `p` are used on all platforms. +!!! + +## Serial types + +!!!Note +This section describes a PostgreSQL-specific way to create an autoincrementing column. Another way is to use the SQL-standard identity column feature, described in [CREATE TABLE](https://www.postgresql.org/docs/11/sql-createtable.html). +!!! + +The data types `SMALLSERIAL`, `SERIAL` and `BIGSERIAL` are not true types, but merely a notational convenience for creating unique identifier columns (similar to the `AUTO_INCREMENT` property supported by some other databases). In the current implementation, specifying: + +```sql +CREATE TABLE tablename ( + colname SERIAL +); +``` + +is equivalent to specifying: + +``` +CREATE SEQUENCE tablename_colname_seq AS integer; +CREATE TABLE tablename ( + colname integer NOT NULL DEFAULT nextval('tablename_colname_seq') +); +ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname; +``` + +Thus, we have created an integer column and arranged for its default values to be assigned from a sequence generator. A `NOT NULL` constraint is applied to ensure that a null value cannot be inserted. (In most cases you would also want to attach a `UNIQUE` or `PRIMARY KEY` constraint to prevent duplicate values from being inserted by accident, but this is not automatic.) Lastly, the sequence is marked as “owned by” the column, so that it will be dropped if the column or table is dropped. + +!!!Note +Because `SMALLSERIAL`, `SERIAL` and `BIGSERIAL` are implemented using sequences, there may be "holes" or gaps in the sequence of values which appears in the column, even if no rows are ever deleted. A value allocated from the sequence is still "used up" even if a row containing that value is never successfully inserted into the table column. This may happen, for example, if the inserting transaction rolls back. See [`nextval()`](https://www.postgresql.org/docs/11/functions-sequence.html) for details. +!!! + +To insert the next value of the sequence into the serial column, specify that the serial column should be assigned its default value. This can be done either by excluding the column from the list of columns in the INSERT statement, or through the use of the `DEFAULT` key word. + +The type names `SERIAL` and `SERIAL4` are equivalent: both create integer columns. The type names `BIGSERIAL` and `SERIAL8` work the same way, except that they create a bigint column. `BIGSERIAL` should be used if you anticipate the use of more than 2147483648 identifiers (2 to the 31st power)over the lifetime of the table. The type names `SMALLSERIAL` and `SERIAL2` also work the same way, except that they create a `SMALLINT` column. + +The sequence created for a `SERIAL` column is automatically dropped when the owning column is dropped. You can drop the sequence without dropping the column, but this will force removal of the column default expression. \ No newline at end of file diff --git a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/02_character_types.mdx b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/02_character_types.mdx index 1a0746f45ac..abf39993028 100644 --- a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/02_character_types.mdx +++ b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/02_character_types.mdx @@ -1,58 +1,94 @@ --- title: "Character types" redirects: - - /epas/latest/epas_compat_reference/02_the_sql_language/02_data_types/02_character_types/ #generated for docs/epas/reorg-role-use-case-mode + - ../../../../../epas_compat_reference/02_the_sql_language/02_data_types/02_character_types #generated for docs/epas/reorg-role-use-case-mode +source: + url: https://www.postgresql.org/docs/current/datatype-numeric.html + timestamp: 2023-09-07 --- -The following table lists the general-purpose character types available in EDB Postgres Advanced Server. +| Name | Native | Alias | Description | +| ------------------------ | --------- | ------ | ----------------------------------------------------------------------------------------------------- | +| `CHAR[(n)]` | ✅ | | Fixed-length character string, blank-padded to the size specified by `n` | +| `CHARACTER[(n)]` | ✅ | | Fixed-length character string, blank-padded to the size specified by `n` | +| `CHARACTER VARYING[(n)]` | ✅ | | Variable-length character string, with limit | +| `CLOB` | | | Custom type for emulating Oracle CLOB, large variable-length up to 1 GB (see [Migration Handbook](/migrating/oracle/oracle_epas_comparison/database_features/#data-types)) | +| `LONG` | | ✅ | Alias for `TEXT` | +| `NCHAR[(n)]` | | ✅ | Alias for `CHARACTER` | +| `NVARCHAR[(n)]` | | ✅ | Alias for `CHARACTER VARYING` | +| `NVARCHAR2[(n)]` | | ✅ | Alias for `CHARACTER VARYING` | +| `STRING` | | ✅ | Alias for `VARCHAR2` | +| `TEXT` | ✅ | | Variable-length character string, unlimited | +| `VARCHAR[(n)]` | ✅ | | Variable-length character string, with limit (considered deprecated, but supported for compatibility) | +| `VARCHAR2[(n)]` | | ✅ | Alias for `CHARACTER VARYING` | -| Name | Description | -| -------------- | ----------------------------------------------------------------------------------------------------- | -| `CHAR[(n)]` | Fixed-length character string, blank-padded to the size specified by `n` | -| `CLOB` | Large variable-length up to 1 GB | -| `LONG` | Variable unlimited length. | -| `NVARCHAR(n)` | Variable-length national character string, with limit | -| `NVARCHAR2(n)` | Variable-length national character string, with limit | -| `STRING` | Alias for `VARCHAR2` | -| `VARCHAR(n)` | Variable-length character string, with limit (considered deprecated, but supported for compatibility) | -| `VARCHAR2(n)` | Variable-length character string, with limit | -Where `n` is a positive integer, these types can store strings up to `n` characters in length. An attempt to assign a value that exceeds the length of `n` results in an error, unless the excess characters are all spaces. In this case, the string is truncated to the maximum length. +## Overview -The storage requirement for data of these types is the actual string plus 1 byte if the string is less than 127 bytes or 4 bytes if the string is 127 bytes or greater. In the case of `CHAR`, the padding also requires storage. Long strings are compressed by the system automatically, so the physical requirement on disk might be less. Long values are stored in background tables so they don't interfere with rapid access to the shorter column values. +SQL defines two primary character types: `CHARACTER VARYING(n)` and `CHARACTER(n)`, where `n` is a positive integer. These types can store strings up to `n` characters in length. If you don't specify a value for `n`, `n` defaults to `1`. Assigning a value that exceeds the length of `n` results in an error unless the excess characters are all spaces. In this case, the string is truncated to the maximum length. If the string to be stored is shorter than `n`, values of type `CHARACTER` are space-padded to the specified width (`n`) and are stored and displayed that way; values of type `CHARACTER VARYING` simply store the shorter string. -The database character set determines the character set used to store textual values. +If you explicitly cast a value to `CHARACTER VARYING(n)` or `CHARACTER(n)`, an over-length value is truncated to n characters without raising an error. -`CHAR` +The notations `VARCHAR(n)` and `CHAR(n)` are aliases for `CHARACTER VARYING(n)` and `CHARACTER(n)`, respectively. If specified, the length must be greater than zero and cannot exceed 10485760. `CHARACTER` without a length specifier is equivalent to `CHARACTER(1)`. If `CHARACTER VARYING` is used without a length specifier, the type accepts strings of any size. The latter is a PostgreSQL extension. - If you don't specify a value for `n`, `n` defaults to `1`. If the string to assign is shorter than `n`, values of type `CHAR` are space-padded to the specified width (`n`) and are stored and displayed that way. +In addition, PostgreSQL provides the `TEXT` type, which stores strings of any length. Although the type T$XT is not in the SQL standard, several other SQL database management systems have it as well. - Padding spaces are treated as semantically insignificant. That is, trailing spaces are disregarded when comparing two values of type `CHAR`, and they are removed when converting a `CHAR` value to one of the other string types. +Values of type `CHARACTER` are physically padded with spaces to the specified width n, and are stored and displayed that way. However, trailing spaces are treated as semantically insignificant and disregarded when comparing two values of type `CHARACTER`. In collations where whitespace is significant, this behavior can produce unexpected results; for example `SELECT 'a '::CHAR(2) collate "C" < E'a\n'::CHAR(2)` returns true, even though C locale would consider a space to be greater than a newline. Trailing spaces are removed when converting a `CHARACTER` value to one of the other string types. Note that trailing spaces are semantically significant in `CHARACTER VARYING` and `TEXT` values, and when using pattern matching, that is `LIKE` and regular expressions. - If you explicitly cast an over-length value to a `CHAR(n)` type, the value is truncated to `n` characters without raising an error (as specified by the SQL standard). +The characters that can be stored in any of these data types are determined by the database character set, which is selected when the database is created. Regardless of the specific character set, the character with code zero (sometimes called `NUL`) can't be stored. For more information refer to [Character Set Support](https://www.postgresql.org/docs/current/multibyte.html). -```sql -VARCHAR, VARCHAR2, NVARCHAR and NVARCHAR2 -``` +The storage requirement for a short string (up to 126 bytes) is 1 byte plus the actual string, which includes the space padding in the case of `CHARACTER`. Longer strings have 4 bytes of overhead instead of 1. Long strings are compressed by the system automatically, so the physical requirement on disk might be less. Very long values are also stored in background tables so that they do not interfere with rapid access to shorter column values. In any case, the longest possible character string that can be stored is about 1 GB. (The maximum value that is allowed for n in the data type declaration is less than that. It wouldn't be useful to change this because with multibyte character encodings the number of characters and bytes can be quite different. If you desire to store long strings with no specific upper limit, use `TEXT` or `CHARACTER VARYING` without a length specifier, rather than making up an arbitrary length limit.) - If the string to assign is shorter than `n`, values of type `VARCHAR`, `VARCHAR2`, `NVARCHAR`, and `NVARCHAR2` store the shorter string without padding. +!!!Tip +There is no performance difference among these three types, apart from increased storage space when using the blank-padded type, and a few extra CPU cycles to check the length when storing into a length-constrained column. While `CHARACTER(n)` has performance advantages in some other database systems, there is no such advantage in PostgreSQL; in fact CHARACTER(n) is usually the slowest of the three because of its additional storage costs. In most situations `TEXT` or `CHARACTER VARYING` should be used instead. -!!! Note -The trailing spaces are semantically significant in `VARCHAR` values. +Refer to the [Postgres documentation on string constances](https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS) for information about the syntax of string literals and [functions and operators](https://www.postgresql.org/docs/current/functions.html) for information about available operators and functions. !!! - If you explicitly cast a value to a `VARCHAR` type, an over-length value is truncated to `n` characters without raising an error (as specified by the SQL standard). +Example: Using the character types + +```sql +CREATE TABLE test1 (a character(4)); +INSERT INTO test1 VALUES ('ok'); +SELECT a, char_length(a) FROM test1; -- (1) + + a | char_length +------+------------- + ok | 2 + + +CREATE TABLE test2 (b varchar(5)); +INSERT INTO test2 VALUES ('ok'); +INSERT INTO test2 VALUES ('good '); +INSERT INTO test2 VALUES ('too long'); +ERROR: value too long for type character varying(5) +INSERT INTO test2 VALUES ('too long'::varchar(5)); -- explicit truncation +SELECT b, char_length(b) FROM test2; + + b | char_length +-------+------------- + ok | 2 + good | 5 + too l | 5 +``` + +There are two other fixed-length character types in PostgreSQL, shown in the following table. These are not intended for general-purpose use, only for use in the internal system catalogs. The `NAME` type is used to store identifiers. Its length is currently defined as 64 bytes (63 usable characters plus terminator) but should be referenced using the constant NAMEDATALEN in C source code. The length is set at compile time (and is therefore adjustable for special uses); the default maximum length might change in a future release. The type "CHAR" (note the quotes) is different from `CHAR(1)` in that it only uses one byte of storage, and therefore can store only a single ASCII character. It is used in the system catalogs as a simplistic enumeration type. + +## Special Character Types -`CLOB` +| Name | Storage Size | Description | +| ------ | ------------ | ----------- | +| "CHAR" | 1 byte | single-byte internal type | +| `NAME` | 64 bytes | internal type for object names | You can store a large character string in a `CLOB` type. `CLOB` is semantically equivalent to `VARCHAR2` except no length limit is specified. Generally, use a `CLOB` type if you don't know the maximum string length. The longest possible character string that you can store in a `CLOB` type is about 1 GB. - !!!Note - The `CLOB` data type is actually a `DOMAIN` based on the PostgreSQL `TEXT` data type. For information on a `DOMAIN`, see the [PostgreSQL core documentation](https://www.postgresql.org/docs/current/static/sql-createdomain.html). +!!!Note + The `CLOB` data type is actually a `DOMAIN` based on the PostgreSQL `TEXT` data type. For information on a `DOMAIN`, see the [PostgreSQL core documentation](https://www.postgresql.org/docs/current/static/sql-createdomain.html). Thus, use of the `CLOB` type is limited by what can be done for `TEXT`, such as a maximum size of approximately 1 GB. diff --git a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/03_binary_data.mdx b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/03_binary_data.mdx index e2606e4ec6e..6073b3674a1 100644 --- a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/03_binary_data.mdx +++ b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/03_binary_data.mdx @@ -5,20 +5,82 @@ legacyRedirectsGenerated: - "/edb-docs/d/edb-postgres-advanced-server/reference/database-compatibility-for-oracle-developers-reference-guide/9.6/Database_Compatibility_for_Oracle_Developers_Reference_Guide.1.013.html" - "/edb-docs/d/edb-postgres-advanced-server/user-guides/database-compatibility-for-oracle-developers-guide/9.5/Database_Compatibility_for_Oracle_Developers_Guide.1.045.html" redirects: - - /epas/latest/epas_compat_reference/02_the_sql_language/02_data_types/03_binary_data/ #generated for docs/epas/reorg-role-use-case-mode + - ../../../../../epas_compat_reference/02_the_sql_language/02_data_types/03_binary_data #generated for docs/epas/reorg-role-use-case-mode +source: + url: https://www.postgresql.org/docs/current/datatype-binary.html + timestamp: 2023-07-11 --- -The following table shows data types that allow the storage of binary strings. +| Name | Native | Alias | Description | +| ----------- | ------ | ----- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| `BYTEA` | ✅ | | Variable-length binary string, 1 or 4 bytes plus the actual binary string. +| `BINARY` | | ✅ | Alias for `BYTEA`. Fixed-length binary string, with a length between 1 and 8300. | +| `BLOB` | | ✅ | Alias for `BYTEA`. Variable-length binary string, with a maximum size of 1 GB. The actual binary string plus 1 byte if the binary string is less than 127 bytes, or 4 bytes if the binary string is 127 bytes or greater | +| `VARBINARY` | | ✅ | Alias for `BYTEA`. Variable-length binary string, with a length between 1 and 8300. | -| Name | Storage size | Description | -| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------- | -| `BINARY` | The length of the binary string | Fixed-length binary string, with a length between 1 and 8300 | -| `BLOB` | The actual binary string plus 1 byte if the binary string is less than 127 bytes, or 4 bytes if the binary string is 127 bytes or greater | Variable-length binary string, with a maximum size of 1 GB | -| `VARBINARY` | The length of the binary string | Variable-length binary string, with a length between 1 and 8300 | +## Overview A binary string is a sequence of octets (or bytes). Binary strings are distinguished from characters strings by two characteristics: - Binary strings specifically allow storing octets of value zero and other "non-printable" octets (defined as octets outside the range 32 to 126). - Operations on binary strings process the actual bytes, whereas the encoding and processing of character strings depends on locale settings. + +The `BYTEA` type supports two formats for input and output: “hex” format and “escape” format. Both of these are always accepted on input. The output format depends on the configuration parameter bytea_output; the default is hex. + +### Hex format + +The hex format encodes binary data as two hexadecimal digits per byte, most significant nibble first. The entire string is preceded by the sequence \x (to distinguish it from the escape format). In some contexts, the initial backslash may need to be escaped by doubling it. For input, the hexadecimal digits can be either upper or lower case, and whitespace is permitted between digit pairs (but not within a digit pair or in the starting \x sequence). The hex format is compatible with a wide range of external applications and protocols, and it tends to be faster to convert than the escape format, so its use is preferred. + +Example: + +``` +SET bytea_output = 'hex'; + +SELECT '\xDEADBEEF'::bytea; + bytea +------------ + \xdeadbeef +``` + +### Escape format + +The “escape” format is the traditional PostgreSQL format for the bytea type. It takes the approach of representing a binary string as a sequence of ASCII characters, while converting those bytes that cannot be represented as an ASCII character into special escape sequences. If, from the point of view of the application, representing bytes as characters makes sense, then this representation can be convenient. But in practice it is usually confusing because it blurs the distinction between binary strings and character strings. Also, the escape mechanism can be unwieldy. Therefore, this format should probably be avoided for most new applications. + +When entering `BYTEA` values in escape format, octets of certain values *must* be escaped, while all octet values *can* be escaped. In general, to escape an octet, convert it into its three-digit octal value and precede it by a backslash. A backslash itself (octet decimal value 92) can alternatively be represented by double backslashes. The following table shows the characters that must be escaped, and gives the alternative escape sequences where applicable. + +| Decimal octet value | Description | Escaped input representation | Example | Hex representation | +| ---------------------- | ---------------------- | ---------------------------- | --------------- | ------------------ | +| 0 | zero octet | `'\000'` | `'\000'::bytea` | \x00 | +| 39 | single quote | `''''` or `'\047'` | `''''::bytea` | \x27 | +| 92 | backslash | `'\\'` or `'\134'` | `'\\'::bytea` | \x5c | +| 0 to 31 and 127 to 255 | “non-printable” octets | `'\xxx'` (octal value) | `'\001'::bytea` | \x01 | + +The requirement to escape non-printable octets varies depending on locale settings. In some instances you can leave them unescaped. + +The reason that single quotes must be doubled is that this is true for any string literal in an SQL command. The generic string-literal parser consumes the outermost single quotes and reduces any pair of single quotes to one data character. What the `BYTEA` input function sees is just one single quote, which it treats as a plain data character. However, the `BYTEA` input function treats backslashes as special, and the other behaviors shown in the table are implemented by that function. + +In some contexts, backslashes must be doubled compared to what is shown above, because the generic string-literal parser will also reduce pairs of backslashes to one data character. + +`BYTEA` octets are output in hex format by default. If you change bytea_output to escape, “non-printable” octets are converted to their equivalent three-digit octal value and preceded by one backslash. Most “printable” octets are output by their standard representation in the client character set, as shown in the following example: + +``` +SET bytea_output = 'escape'; + +SELECT 'abc \153\154\155 \052\251\124'::bytea; + bytea +---------------- + abc klm *\251T +``` + +The octet with decimal value 92 (backslash) is doubled in the output. The following table provides details: + +| Decimal octet value | Description | Escaped input representation | Example | Output result | +| ---------------------- | ---------------------- | ----------------------------------- | --------------- | ------------- | +| 92 | backslash | `\\` | `'\134'::bytea` | `\\` | +| 0 to 31 and 127 to 255 | “non-printable” octets | `'\xxx'` (octal value) | `'\001'::bytea` | `\001` | +| 32 to 126 | “printable” octets | client character set representation | `'\176'::bytea` | ~ | + +Depending on the front end to PostgreSQL you use, you might have additional work in terms of escaping and unescaping `BYTEA` strings. For example, you might also have to escape line feeds and carriage returns if your interface automatically translates these. + diff --git a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/04_date_time_types.mdx b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/04_date_time_types.mdx index 336ab2e82d3..3c7b70af26f 100644 --- a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/04_date_time_types.mdx +++ b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/04_date_time_types.mdx @@ -5,22 +5,27 @@ legacyRedirectsGenerated: - "/edb-docs/d/edb-postgres-advanced-server/reference/database-compatibility-for-oracle-developers-reference-guide/9.6/Database_Compatibility_for_Oracle_Developers_Reference_Guide.1.014.html" - "/edb-docs/d/edb-postgres-advanced-server/user-guides/database-compatibility-for-oracle-developers-guide/9.5/Database_Compatibility_for_Oracle_Developers_Guide.1.046.html" redirects: - - /epas/latest/epas_compat_reference/02_the_sql_language/02_data_types/04_date_time_types/ #generated for docs/epas/reorg-role-use-case-mode + - ../../../../../epas_compat_reference/02_the_sql_language/02_data_types/04_date_time_types #generated for docs/epas/reorg-role-use-case-mode +source: + url: https://www.postgresql.org/docs/current/datatype-datetime.html + timestamp: 2023-09-20 --- -The following discussion of the date/time types assumes that the configuration parameter `edb_redwood_date` is set to `TRUE` whenever a table is created or altered. -EDB Postgres Advanced Server supports the date/time types shown in the table. +| Name | Native | Alias | Description | +| -------------------------------- | -------| ----- | ---------------------------------------------------------------------------------------------- | +| `DATE` | ✅ | | Date and time, 8 bytes storage, 4713 BC to 5874897 AD range, and resolution 1 second. | +| `INTERVAL DAY TO SECOND [(p)]` | ✅ | | Period of time, 12 bytes storage, -178000000 years to 178000000 years range, and resolution 1 microsecond / 14 digits | +| `INTERVAL YEAR TO MONTH` | ✅ | | Period of time, 12 bytes storage, -178000000 years to 178000000 years range, and resolution 1 microsecond / 14 digits. | +| `TIMESTAMP [(p)]` | ✅ | | Date and time, 8 bytes storage, 4713 BC to 5874897 AD range, and resolution 1 microsecond. | +| `TIMESTAMP [(p)] WITH TIME ZONE` | ✅ | | Date and time with time zone, 8 bytes storage, 4713 BC to 5874897 AD range, and resolution 1 microsecond. | + -| Name | Storage size | Description | Low value | High value | Resolution | -| -------------------------------- | ------------ | ---------------------------- | ---------------- | --------------- | ------------------------- | -| `DATE` | 8 bytes | Date and time | 4713 BC | 5874897 AD | 1 second | -| `INTERVAL DAY TO SECOND [(p)]` | 12 bytes | Period of time | -178000000 years | 178000000 years | 1 microsecond / 14 digits | -| `INTERVAL YEAR TO MONTH` | 12 bytes | Period of time | -178000000 years | 178000000 years | 1 microsecond / 14 digits | -| `TIMESTAMP [(p)]` | 8 bytes | Date and time | 4713 BC | 5874897 AD | 1 microsecond | -| `TIMESTAMP [(p)] WITH TIME ZONE` | 8 bytes | Date and time with time zone | 4713 BC | 5874897 AD | 1 microsecond | +## Overview + +The following discussion of the date/time types assumes that the configuration parameter `edb_redwood_date` is set to `TRUE` whenever a table is created or altered. When `DATE` appears as the data type of a column in the data definition language (DDL) commands `CREATE TABLE` or `ALTER TABLE`, it's translated to `TIMESTAMP` at the time the table definition is stored in the database. Thus, a time component is also stored in the column along with the date. @@ -59,33 +64,33 @@ The first variation supported by EDB Postgres Advanced Server is `INTERVAL DAY T `p` specifies the precision of the `second` field. -EDB Postgres Advanced Server interprets this value as as 1 day, 2 hours, 34 minutes, 5 seconds and 678 thousandths of a second: +EDB Postgres Advanced Server interprets the following value as as 1 day, 2 hours, 34 minutes, 5 seconds and 678 thousandths of a second: `INTERVAL '1 2:34:5.678' DAY TO SECOND(3)` -EDB Postgres Advanced Server interprets this value as 1 day and 23 hours: +EDB Postgres Advanced Server interprets the following value as 1 day and 23 hours: `INTERVAL '1 23' DAY TO HOUR` -EDB Postgres Advanced Server interprets this value as 2 hours and 34 minutes: +EDB Postgres Advanced Server interprets the following value as 2 hours and 34 minutes: `INTERVAL '2:34' HOUR TO MINUTE` -EDB Postgres Advanced Server interprets this value as 2 hours, 34 minutes, 56 seconds and 13 thousandths of a second. The fractional second is rounded up to 13 because of the specified precision. +EDB Postgres Advanced Server interprets the following value as 2 hours, 34 minutes, 56 seconds and 13 thousandths of a second. The fractional second is rounded up to 13 because of the specified precision. `INTERVAL '2:34:56.129' HOUR TO SECOND(2)` The second variation supported by EDB Postgres Advanced Server that's compatible with Oracle databases is `INTERVAL YEAR TO MONTH`. This variation stores a time interval in years and months. -EDB Postgres Advanced Server interprets this value as 12 years and 3 months: +EDB Postgres Advanced Server interprets the following value as 12 years and 3 months: `INTERVAL '12-3' YEAR TO MONTH` -EDB Postgres Advanced Server interprets this value as 12 years and 3 months: +EDB Postgres Advanced Server interprets the following value as 12 years and 3 months: `INTERVAL '456' YEAR(2)` -EDB Postgres Advanced Server interprets this value as 25 years: +EDB Postgres Advanced Server interprets the following value as 25 years: `INTERVAL '300' MONTH` @@ -148,6 +153,35 @@ This example shows a time stamp that follows the ISO 8601 standard: `1999-01-08 04:05:06` +### Special Values + +PostgreSQL supports several special date/time input values for convenience, as shown in the following table. The values `infinity` and `-infinity` are specially represented inside the system and are displayed unchanged; the others are simply notational shorthands that are converted to ordinary date/time values when read. (In particular, `now` and related strings are converted to a specific time value as soon as they are read.) All of these values must be enclosed in single quotes when used as constants in SQL commands. + +| Input String | Valid Types | Description | +| ------------ | --------------------- | ---------------------------------------------- | +| epoch | date, timestamp | 1970-01-01 00:00:00+00 (Unix system time zero) | +| infinity | date, timestamp | later than all other time stamps | +| -infinity | date, timestamp | earlier than all other time stamps | +| now | date, time, timestamp | current transaction's start time | +| today | date, timestamp | midnight (00:00) today | +| tomorrow | date, timestamp | midnight (00:00) tomorrow | +| yesterday | date, timestamp | midnight (00:00) yesterday | +| allballs | time | 00:00:00.00 UTC | + +The following SQL-compatible functions can also be used to obtain the current time value for the corresponding data type: + +`CURRENT_DATE` +`CURRENT_TIME` +`CURRENT_TIMESTAMP` +`LOCALTIME` +`LOCALTIMESTAMP` + +Note that these are SQL functions and are not recognized in data input strings. + +!!!Note +While the input strings `now`, `today`, `tomorrow`, and `yesterday` are fine to use in interactive SQL commands, they can have surprising behavior when the command is saved to be executed later, for example in prepared statements, views, and function definitions. The string can be converted to a specific time value that continues to be used long after it becomes stale. Use one of the SQL functions instead in such contexts. For example, `CURRENT_DATE + 1` is safer than `tomorrow::date`. +!!! + ## Date/time output The default output format of the date/time types is either: @@ -167,3 +201,128 @@ The following table shows examples of the output formats for the two styles: Red ## Internals EDB Postgres Advanced Server uses Julian dates for all date/time calculations. Julian dates correctly predict or calculate any date after 4713 BC based on the assumption that the length of the year is 365.2425 days. + +## Time Zones + +PostgreSQL uses the widely-used IANA (Olson) time zone database for information about historical time zone rules. For times in the future, the assumption is that the latest known rules for a given time zone will continue to be observed indefinitely far into the future. + +PostgreSQL endeavors to be compatible with the SQL standard definitions for typical usage. However, the SQL standard has an odd mix of date and time types and capabilities. Two obvious problems are: + +- Although the date type cannot have an associated time zone, the time type can. Time zones in the real world have little meaning unless associated with a date as well as a time, since the offset can vary through the year with daylight-saving time boundaries. + +- The default time zone is specified as a constant numeric offset from UTC. It is therefore impossible to adapt to daylight-saving time when doing date/time arithmetic across DST boundaries. + +To address these difficulties, we recommend using date/time types that contain both date and time when using time zones. We do not recommend using the type `time with time zone` (though it is supported by PostgreSQL for legacy applications and for compliance with the SQL standard). PostgreSQL assumes your local time zone for any type containing only date or time. + +All time zone-aware dates and times are stored internally in UTC. They are converted to local time in the zone specified by the `TimeZone` configuration parameter before being displayed to the client. + +PostgreSQL allows you to specify time zones in three different forms: + +- A full time zone name, for example America/New_York. The recognized time zone names are listed in the `pg_timezone_names` view. PostgreSQL uses the widely-used IANA time zone data for this purpose, so the same time zone names are also recognized by other software. + +- A time zone abbreviation, for example PST. Such a specification merely defines a particular offset from UTC, in contrast to full time zone names which can imply a set of daylight savings transition rules as well. The recognized abbreviations are listed in the `pg_timezone_abbrevs` view. You cannot set the configuration parameters `TimeZone` or `log_timezone` to a time zone abbreviation, but you can use abbreviations in date/time input values and with the `AT TIME ZONE` operator. + +- PostgreSQL also accepts POSIX-style time zone specifications. This option is not normally preferable to using a named time zone, but it may be necessary if no suitable IANA time zone entry is available. + +In short, this is the difference between abbreviations and full names: abbreviations represent a specific offset from UTC, whereas many of the full names imply a local daylight-savings time rule and so have two possible UTC offsets. As an example, 2014-06-04 12:00 America/New_York represents noon local time in New York, which for this particular date was Eastern Daylight Time (UTC-4). So 2014-06-04 12:00 EDT specifies that same time instant. But 2014-06-04 12:00 EST specifies noon Eastern Standard Time (UTC-5), regardless of whether daylight savings was nominally in effect on that date. + +To complicate matters, some jurisdictions have used the same time zone abbreviation to mean different UTC offsets at different times; for example, in Moscow MSK has meant UTC+3 in some years and UTC+4 in others. PostgreSQL interprets such abbreviations according to whatever they meant (or had most recently meant) on the specified date; but, as with the EST example above, this is not necessarily the same as local civil time on that date. + +In all cases, time zone names and abbreviations are recognized case-insensitively. (This is a change from PostgreSQL versions prior to 8.2, which were case-sensitive in some contexts but not others.) + +Neither time zone names nor abbreviations are hard-wired into the server; they are obtained from configuration files stored under `.../share/timezone/` and `.../share/timezonesets/` of the installation directory. + +The `TimeZone` configuration parameter can be set in the file `postgresql.conf`, or in any of the other standard ways using server configuration. There are also some special ways to set it: + +- The SQL command `SET TIME ZONE` sets the time zone for the session. This is an alternative spelling of `SET TIMEZONE TO` with a more SQL-spec-compatible syntax. + +- The `PGTZ` environment variable is used by libpq clients to send a `SET TIME ZONE` command to the server upon connection. + +## Interval Input + +Interval values can be written using the following verbose syntax: + +``` +[@] quantity unit [quantity unit...] [direction] +``` + +where `quantity` is a number (possibly signed); `unit` is `microsecond`, `millisecond`, `second`, `minute`, `hour`, `day`, `week`, `month`, `year`, `decade`, `century`, `millennium`, or abbreviations or plurals of these units; `direction` can be `ago` or empty. The at sign (@) is optional noise. The amounts of the different units are implicitly added with appropriate sign accounting. `ago` negates all the fields. This syntax is also used for interval output if `IntervalStyle` is set to `postgres_verbose`. + +Quantities of days, hours, minutes, and seconds can be specified without explicit unit markings. For example, '1 12:59:10' is read the same as '1 day 12 hours 59 min 10 sec'. Also, a combination of years and months can be specified with a dash; for example '200-10' is read the same as '200 years 10 months'. (These shorter forms are in fact the only ones allowed by the SQL standard, and are used for output when `IntervalStyle` is set to `sql_standard`.) + +Interval values can also be written as ISO 8601 time intervals, using either the “format with designators” of the standard's section 4.4.3.2 or the “alternative format” of section 4.4.3.3. The format with designators looks like this: + +``` +P quantity unit [ quantity unit ...] [ T [ quantity unit ...]] +``` + +The string must start with a P, and may include a T that introduces the time-of-day units. The following table provides the available unit abbreviations. Units may be omitted, and may be specified in any order, but units smaller than a day must appear after T. In particular, the meaning of M depends on whether it is before or after T. + +| Abbreviation | Meaning | +| ------------ | ------------------------- | +| Y | Years | +| M | Months (in the date part) | +| W | Weeks | +| D | Days | +| H | Hours | +| M | Minutes | +| S | Seconds | + +In the alternative format: + +``` +P [ years-months-days ] [ T hours:minutes:seconds ] +``` + +the string must begin with P, and a T separates the date and time parts of the interval. The values are given as numbers similar to ISO 8601 dates. + +When writing an interval constant with a fields specification, or when assigning a string to an interval column that was defined with a fields specification, the interpretation of unmarked quantities depends on the fields. For example `INTERVAL '1' YEAR` is read as 1 year, whereas `INTERVAL '1'` means 1 second. Also, field values “to the right” of the least significant field allowed by the fields specification are silently discarded. For example, writing `INTERVAL '1 day 2:03:04' HOUR TO MINUTE` results in dropping the seconds field, but not the day field. + +According to the SQL standard all fields of an interval value must have the same sign, so a leading negative sign applies to all fields; for example, the negative sign in the interval literal '-1 2:03:04' applies to both the days and hour/minute/second parts. PostgreSQL allows the fields to have different signs, and traditionally treats each field in the textual representation as independently signed, so that the hour/minute/second part is considered positive in this example. If `IntervalStyle` is set to `sql_standard` then a leading sign is considered to apply to all fields (but only if no additional signs appear). Otherwise the traditional PostgreSQL interpretation is used. To avoid ambiguity, it's recommended to attach an explicit sign to each field if any field is negative. + +Field values can have fractional parts: for example, '1.5 weeks' or '01:02:03.45'. However, because interval internally stores only three integer units (months, days, microseconds), fractional units must be spilled to smaller units. Fractional parts of units greater than months are rounded to be an integer number of months, for example, '1.5 years' becomes '1 year 6 mons'. Fractional parts of weeks and days are computed to be an integer number of days and microseconds, assuming 30 days per month and 24 hours per day, e.g., '1.75 months' becomes 1 mon 22 days 12:00:00. Only seconds will ever be shown as fractional on output. + +The following table shows some examples of valid interval input. + +| Example | Description | +| -------------------------------------------------- | ------------------------------------------------------------------------------- | +| 1-2 | SQL standard format: 1 year 2 months | +| 3 4:05:06 | SQL standard format: 3 days 4 hours 5 minutes 6 seconds | +| 1 year 2 months 3 days 4 hours 5 minutes 6 seconds | Traditional Postgres format: 1 year 2 months 3 days 4 hours 5 minutes 6 seconds | +| P1Y2M3DT4H5M6S | ISO 8601 “format with designators”: same meaning as above | +| P0001-02-03T04:05:06 | ISO 8601 “alternative format”: same meaning as above | + +Internally, interval values are stored as months, days, and microseconds. This is done because the number of days in a month varies, and a day can have 23 or 25 hours if a daylight savings time adjustment is involved. The months and days fields are integers while the microseconds field can store fractional seconds. Because intervals are usually created from constant strings or timestamp subtraction, this storage method works well in most cases, but can cause unexpected results: + +``` +SELECT EXTRACT(hours from '80 minutes'::interval); + date_part +----------- + 1 + +SELECT EXTRACT(days from '80 hours'::interval); + date_part +----------- + 0 +``` + +Functions `justify_days` and `justify_hours` are available for adjusting days and hours that overflow their normal ranges. + +## Interval Output + +Using the command `SET intervalstyle` you can set the output format of the interval type to one of four styles: `sql_standard`, `postgres`, `postgres_verbose`, or `iso_8601`. The default is the `postgres` format. The table in this section shows examples of each output style. + +The `sql_standard` style produces output that conforms to the SQL standard's specification for interval literal strings, if the interval value meets the standard's restrictions (either year-month only or day-time only, with no mixing of positive and negative components). Otherwise the output looks like a standard year-month literal string followed by a day-time literal string, with explicit signs added to disambiguate mixed-sign intervals. + +The output of the `postgres` style matches the output of PostgreSQL releases prior to 8.4 when the `DateStyle` parameter was set to ISO. + +The output of the `postgres_verbose` style matches the output of PostgreSQL releases prior to 8.4 when the `DateStyle` parameter was set to non-ISO output. + +The output of the `iso_8601` style matches the “format with designators” described in the ISO 8601 standard. + +| Style Specification | Year-Month Interval | Day-Time Interval | Mixed Interval | +| ------------------- | ------------------- | ------------------------------ | ------------------------------------------------- | +| sql_standard | 1-2 | 3 4:05:06 | -1-2 +3 -4:05:06 | +| postgres | 1 year 2 mons | 3 days 04:05:06 | -1 year -2 mons +3 days -04:05:06 | +| postgres_verbose | @ 1 year 2 mons | @ 3 days 4 hours 5 mins 6 secs | @ 1 year 2 mons -3 days 4 hours 5 mins 6 secs ago | +| iso_8601 | P1Y2M | P3DT4H5M6S | P-1Y-2M3D​T-4H-5M-6S | diff --git a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/05_boolean_type.mdx b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/05_boolean_type.mdx index 7adc9606d65..21d2f4b0a16 100644 --- a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/05_boolean_type.mdx +++ b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/05_boolean_type.mdx @@ -1,15 +1,42 @@ --- title: "Boolean types" redirects: - - /epas/latest/epas_compat_reference/02_the_sql_language/02_data_types/05_boolean_type/ #generated for docs/epas/reorg-role-use-case-mode + - ../../../../../epas_compat_reference/02_the_sql_language/02_data_types/05_boolean_type #generated for docs/epas/reorg-role-use-case-mode +source: + url: https://www.postgresql.org/docs/current/datatype-boolean.html + timestamp: 2023-09-20 --- + +| Name | Native | Alias | Description | +| --------- | ------ | ----- | --------------------------------------------- | +| `BOOLEAN` | ✅ | | Logical Boolean (true/false), 1 byte storage. | + +## Overview + EDB Postgres Advanced Server provides the standard SQL type `BOOLEAN`. `BOOLEAN` can have one of only two states: `TRUE` or `FALSE`. A third state, `UNKNOWN`, is represented by the SQL `NULL` value. -| Name | Storage size | Description | -| --------- | ------------ | ---------------------------- | -| `BOOLEAN` | 1 byte | Logical Boolean (true/false) | +Literal values representing the `TRUE` state include 'TRUE', 'true', 'y', '1' and 't'. Literal values representing `FALSE` include 'FALSE', 'false', 'n', '0' and 'f'. There is no literal value for `UNKNOWN`; use `NULL`. + +The follow is an example using the boolean type: + +```sql +CREATE TABLE test1 (a boolean, b text); +INSERT INTO test1 VALUES (TRUE, 'sic est'); +INSERT INTO test1 VALUES (FALSE, 'non est'); +SELECT * FROM test1; + a | b +---+--------- + t | sic est + f | non est + +SELECT * FROM test1 WHERE a; + a | b +---+--------- + t | sic est + ``` + +Note that the parser automatically understands that `TRUE` and `FALSE` are of type boolean, but this is not so for `NULL` because that can have any type. So in some contexts you might have to cast `NULL` to `BOOLEAN` explicitly. -The valid literal value for representing the true state is `TRUE`. The valid literal for representing the false state is `FALSE`. diff --git a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/06_xml_type.mdx b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/06_xml_type.mdx index f99abce490d..1dc06d60f89 100644 --- a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/06_xml_type.mdx +++ b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/06_xml_type.mdx @@ -5,11 +5,20 @@ legacyRedirectsGenerated: - "/edb-docs/d/edb-postgres-advanced-server/reference/database-compatibility-for-oracle-developers-reference-guide/9.6/Database_Compatibility_for_Oracle_Developers_Reference_Guide.1.016.html" - "/edb-docs/d/edb-postgres-advanced-server/user-guides/database-compatibility-for-oracle-developers-guide/9.5/Database_Compatibility_for_Oracle_Developers_Guide.1.048.html" redirects: - - /epas/latest/epas_compat_reference/02_the_sql_language/02_data_types/06_xml_type/ #generated for docs/epas/reorg-role-use-case-mode + - ../../../../../epas_compat_reference/02_the_sql_language/02_data_types/06_xml_type #generated for docs/epas/reorg-role-use-case-mode +source: + url: https://www.postgresql.org/docs/current/datatype-xml.html + timestamp: 2023-09-20 --- +| Name | Native | Alias | Description | +| -------------- | ------ | ----- | --------------------------------------------- | +| `XMLTYPE` | ✅ | | Data type used to store XML data. | + +## Overview + The `XMLTYPE` data type is used to store XML data. Its advantage over storing XML data in a character field is that it checks the input values for how well they're formed. Also, support functions perform type-safe operations on it. The XML type can store well-formed “documents,” as defined by the XML standard, as well as “content” fragments, which are defined by the production `XMLDecl? content` in the XML standard. Roughly, this means that content fragments can have more than one top-level element or character node. @@ -34,3 +43,73 @@ __OUTPUT__ Manual... (1 row) ``` + +## Creating XML Values + +To produce a value of type XML from character data, use the function `XMLPARSE`: + +``` +XMLPARSE ( { DOCUMENT | CONTENT } value) +``` + +Examples: + +``` +XMLPARSE (DOCUMENT 'Manual...') +XMLPARSE (CONTENT 'abcbarfoo') +``` + +While this is the only way to convert character strings into XML values according to the SQL standard, the PostgreSQL-specific syntaxes: + +``` +xml 'bar' +'bar'::xml +``` + +can also be used. + +The XML type does not validate input values against a document type declaration (DTD), even when the input value specifies a DTD. There is also currently no built-in support for validating against other XML schema languages such as XML Schema. + +The inverse operation, producing a character string value from XML, uses the function `XMLSERIALIZE`: + +``` +XMLSERIALIZE ( { DOCUMENT | CONTENT } value AS type [ [ NO ] INDENT ] ) +``` + +`type` can be `character`, `character varying`, or `text` (or an alias for one of those). Again, according to the SQL standard, this is the only way to convert between type XML and character types, but PostgreSQL also allows you to simply cast the value. + +The `INDENT` option causes the result to be pretty-printed, while `NO INDENT` (which is the default) just emits the original input string. Casting to a character type likewise produces the original string. + +When a character string value is cast to or from type XML without going through `XMLPARSE` or `XMLSERIALIZE`, respectively, the choice of `DOCUMENT` versus `CONTENT` is determined by the “XML option” session configuration parameter, which can be set using the standard command: + +``` +SET XML OPTION { DOCUMENT | CONTENT }; +``` + +or the more PostgreSQL-like syntax + +``` +SET xmloption TO { DOCUMENT | CONTENT }; +``` + +The default is `CONTENT`, so all forms of XML data are allowed. + +## Encoding Handling + +Take care when dealing with multiple character encodings on the client, server, and in the XML data passed through them. When using the text mode to pass queries to the server and query results to the client, which is the normal mode, PostgreSQL converts all character data passed between the client and the server and vice versa to the character encoding of the respective end. This includes string representations of XML values. This would ordinarily mean that encoding declarations contained in XML data can become invalid as the character data is converted to other encodings while traveling between client and server, because the embedded encoding declaration is not changed. To cope with this behavior, encoding declarations contained in character strings presented for input to the XML type are ignored, and content is assumed to be in the current server encoding. Consequently, for correct processing, character strings of XML data must be sent from the client in the current client encoding. It is the responsibility of the client to either convert documents to the current client encoding before sending them to the server, or to adjust the client encoding appropriately. On output, values of type XML will not have an encoding declaration, and clients should assume all data is in the current client encoding. + +When using binary mode to pass query parameters to the server and query results back to the client, no encoding conversion is performed, so the situation is different. In this case, an encoding declaration in the XML data will be observed, and if it is absent, the data will be assumed to be in UTF-8 (as required by the XML standard; note that PostgreSQL does not support UTF-16). On output, data will have an encoding declaration specifying the client encoding, unless the client encoding is UTF-8, in which case it will be omitted. + +Processing XML data with PostgreSQL will be less error-prone and more efficient if the XML data encoding, client encoding, and server encoding are the same. Since XML data is internally processed in UTF-8, computations will be most efficient if the server encoding is also UTF-8. + +!!!Note +Some XML-related functions may not work at all on non-ASCII data when the server encoding is not UTF-8. This is known to be an issue for `xmltable()` and `xpath()` in particular. +!!! + +## Accessing XML Values + +The XML data type is unusual because it does not provide any comparison operators. This is because there is no well-defined and universally useful comparison algorithm for XML data. One consequence of this is that you cannot retrieve rows by comparing an XML column against a search value. XML values should therefore typically be accompanied by a separate key field such as an ID. An alternative solution for comparing XML values is to convert them to character strings first, but note that character string comparison has little to do with a useful XML comparison method. + +Because there are no comparison operators for the XML data type, it is not possible to create an index directly on a column of this type. If speedy searches in XML data are desired, possible workarounds include casting the expression to a character string type and indexing that, or indexing an XPath expression. Of course, the actual query would have to be adjusted to search by the indexed expression. + +The text-search functionality in PostgreSQL can also be used to speed up full-document searches of XML data. The necessary preprocessing support is, however, not yet available in the PostgreSQL distribution. \ No newline at end of file diff --git a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/array_types.mdx b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/array_types.mdx new file mode 100644 index 00000000000..7177a033f84 --- /dev/null +++ b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/array_types.mdx @@ -0,0 +1,457 @@ +--- +title: "Array types" +--- + +| Name | Native | Alias | Description | +| -------------------------------------------------------------------- | ------ | ----- | --------------------------------------------- | +| `<*built-in* \| *user-defined* \| *enum* \| *composite* type>` []... | ✅ | | Variable-length multidimensional arrays. | + +## Overview + +PostgreSQL allows the columns of a table to be defined as variable-length multidimensional arrays. Arrays of any built-in or user-defined base type, enum type, or composite type can be created. Arrays of domains aren't yet supported. + +## Declaration of array types + +To illustrate the use of array types, we can create the following table: + +```sql +CREATE TABLE sal_emp ( + name text, + pay_by_quarter integer[], + schedule text[][] +); +``` + +As shown, an array data type is named by appending square brackets (`[]`) to the data type name of the array elements. The above command creates a table named `sal_emp` with a column of type text (`name`), a one-dimensional array of type integer (`pay_by_quarter`), which represents the employee's salary by quarter, and a two-dimensional array of text (`schedule`), which represents the employee's weekly schedule. + +The syntax for `CREATE TABLE` allows the exact size of arrays to be specified, for example: + +```sql +CREATE TABLE tictactoe ( + squares integer[3][3] +); +``` + +However, the current implementation ignores any supplied array size limits, that is, the behavior is the same as for arrays of unspecified length. + +The current implementation doesn't enforce the declared number of dimensions either. Arrays of a particular element type are all considered to be of the same type, regardless of size or number of dimensions. So, declaring the array size or number of dimensions in `CREATE TABLE` is simply documentation; it does not affect run-time behavior. + +An alternative syntax, which conforms to the SQL standard by using the keyword `ARRAY`, can be used for one-dimensional arrays. `pay_by_quarter` could have been defined as: + +```sql +pay_by_quarter integer ARRAY[4], +``` + +Or, if no array size is to be specified: + +```sql +pay_by_quarter integer ARRAY, +``` + +As before, however, PostgreSQL does not enforce the size restriction in any case. + +## Array value input + +To write an array value as a literal constant, enclose the element values within curly braces and separate them by commas. (If you know C, this is not unlike the C syntax for initializing structures.) You can put double quotes around any element value, and must do so if it contains commas or curly braces. (More details appear below.) Thus, the general format of an array constant is the following: + +```sql +'{ val1 delim val2 delim ... }' +``` + +where `delim` is the delimiter character for the type, as recorded in its `pg_type` entry. Among the standard data types provided in the PostgreSQL distribution, all use a comma (`,`), except for type box which uses a semicolon (`;`). Each `val` is either a constant of the array element type, or a subarray. An example of an array constant is: + +```sql +'{{1,2,3},{4,5,6},{7,8,9}}' +``` + +This constant is a two-dimensional, 3-by-3 array consisting of three subarrays of integers. + +To set an element of an array constant to NULL, write `NULL` for the element value. (Any upper- or lower-case variant of `NULL` will do.) If you want an actual string value "NULL", you must put double quotes around it. + +!!! Note + These kinds of array constants are actually only a special case of the generic type constants discussed in [Constants of Other Types](https://www.postgresql.org/docs/9.3/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS-GENERIC). The constant is initially treated as a string and passed to the array input conversion routine. An explicit type specification might be necessary. + +The following are `INSERT` statements: + +```sql +INSERT INTO sal_emp + VALUES ('Bill', + '{10000, 10000, 10000, 10000}', + '{{"meeting", "lunch"}, {"training", "presentation"}}'); + +INSERT INTO sal_emp + VALUES ('Carol', + '{20000, 25000, 25000, 25000}', + '{{"breakfast", "consulting"}, {"meeting", "lunch"}}'); +__OUTPUT__ +SELECT * FROM sal_emp; + name | pay_by_quarter | schedule +-------+---------------------------+------------------------------------------- + Bill | {10000,10000,10000,10000} | {{meeting,lunch},{training,presentation}} + Carol | {20000,25000,25000,25000} | {{breakfast,consulting},{meeting,lunch}} +(2 rows) +``` + +Multidimensional arrays must have matching extents for each dimension. A mismatch causes an error, for example: + +```sql +INSERT INTO sal_emp + VALUES ('Bill', + '{10000, 10000, 10000, 10000}', + '{{"meeting", "lunch"}, {"meeting"}}'); +ERROR: multidimensional arrays must have array expressions with matching dimensions +``` + +The `ARRAY` constructor syntax can also be used: + +```sql +INSERT INTO sal_emp + VALUES ('Bill', + ARRAY[10000, 10000, 10000, 10000], + ARRAY[['meeting', 'lunch'], ['training', 'presentation']]); + +INSERT INTO sal_emp + VALUES ('Carol', + ARRAY[20000, 25000, 25000, 25000], + ARRAY[['breakfast', 'consulting'], ['meeting', 'lunch']]); +``` + +Notice that the array elements are ordinary SQL constants or expressions; for instance, string literals are single quoted, instead of double quoted as they would be in an array literal. For more details on `ARRAY` constructor syntax, see [Array constructors](https://www.postgresql.org/docs/9.3/sql-expressions.html#SQL-SYNTAX-ARRAY-CONSTRUCTORS). + +## Accessing arrays + +Now, we can run some queries on the table. First, we show how to access a single element of an array. This query retrieves the names of the employees whose pay changed in the second quarter: + +```sql +SELECT name FROM sal_emp WHERE pay_by_quarter[1] <> pay_by_quarter[2]; +__OUTPUT__ + name +------- + Carol +(1 row) +``` + +The array subscript numbers are written within square brackets. By default PostgreSQL uses a one-based numbering convention for arrays, that is, an array of `n` elements starts with `array[1]` and ends with `array[n]`. + +This query retrieves the third quarter pay of all employees: + +```sql +SELECT pay_by_quarter[3] FROM sal_emp; +__OUTPUT__ + pay_by_quarter +---------------- + 10000 + 25000 +(2 rows) +``` + +We can also access arbitrary rectangular slices of an array, or subarrays. An array slice is denoted by writing `lower-bound:upper-bound` for one or more array dimensions. For example, this query retrieves the first item on Bill's schedule for the first two days of the week: + +```sql +SELECT schedule[1:2][1:1] FROM sal_emp WHERE name = 'Bill'; +__OUTPUT__ + schedule +------------------------ + {{meeting},{training}} +(1 row) +``` + +If any dimension is written as a slice, that is, contains a colon, then all dimensions are treated as slices. Any dimension that has only a single number (no colon) is treated as being from 1 to the number specified. For example, `[2]` is treated as `[1:2]`, as in this example: + +```sql +SELECT schedule[1:2][2] FROM sal_emp WHERE name = 'Bill'; +__OUTPUT__ + schedule +------------------------------------------- + {{meeting,lunch},{training,presentation}} +(1 row) +``` + +To avoid confusion with the non-slice case, it's best to use slice syntax for all dimensions, for example, `[1:2][1:1]`, not `[2][1:1]`. + +An array subscript expression returns null if either the array itself or any of the subscript expressions are null. Also, null is returned if a subscript is outside the array bounds (this case does not raise an error). For example, if `schedule` currently has the dimensions `[1:3][1:2]` then referencing `schedule[3][3]` yields `NULL`. Similarly, an array reference with the wrong number of subscripts yields a null rather than an error. + +An array slice expression likewise yields null if the array itself or any of the subscript expressions are null. However, in other cases such as selecting an array slice that is completely outside the current array bounds, a slice expression yields an empty (zero-dimensional) array instead of null. (This does not match non-slice behavior and is done for historical reasons.) If the requested slice partially overlaps the array bounds, then it is silently reduced to just the overlapping region instead of returning null. + +The current dimensions of any array value can be retrieved with the `array_dims` function: + +```sql +SELECT array_dims(schedule) FROM sal_emp WHERE name = 'Carol'; +__OUTPUT__ + array_dims +------------ + [1:2][1:2] +(1 row) +``` + +`array_dims` produces a text result, which is convenient for people to read but perhaps inconvenient for programs. Dimensions can also be retrieved with `array_upper` and `array_lower`, which return the upper and lower bound of a specified array dimension, respectively: + +```sql +SELECT array_upper(schedule, 1) FROM sal_emp WHERE name = 'Carol'; +__OUTPUT__ + array_upper +------------- + 2 +(1 row) +``` + +`array_length` returns the length of a specified array dimension: + +```sql +SELECT array_length(schedule, 1) FROM sal_emp WHERE name = 'Carol'; +__OUTPUT__ + array_length +-------------- + 2 +(1 row) +``` + +## Modifying arrays + +An array value can be replaced completely: + +```sql +UPDATE sal_emp SET pay_by_quarter = '{25000,25000,27000,27000}' + WHERE name = 'Carol'; +``` + +or using the `ARRAY` expression syntax: + +```sql +UPDATE sal_emp SET pay_by_quarter = ARRAY[25000,25000,27000,27000] + WHERE name = 'Carol'; +``` + +An array can also be updated at a single element: + +```sql +UPDATE sal_emp SET pay_by_quarter[4] = 15000 + WHERE name = 'Bill'; +``` + +or updated in a slice: + +```sql +UPDATE sal_emp SET pay_by_quarter[1:2] = '{27000,27000}' + WHERE name = 'Carol'; +``` + +A stored array value can be enlarged by assigning to elements not already present. Any positions between those previously present and the newly assigned elements are filled with nulls. For example, if array `myarray` currently has 4 elements, it will have six elements after an update that assigns to `myarray[6]`; `myarray[5]` will contain null. Currently, enlargement in this fashion is only allowed for one-dimensional arrays, not multidimensional arrays. + +Subscripted assignment allows creation of arrays that do not use one-based subscripts. For example one might assign to `myarray[-2:7]` to create an array with subscript values from -2 to 7. + +New array values can also be constructed using the concatenation operator, `||`: + +```sql +SELECT ARRAY[1,2] || ARRAY[3,4]; +__OUTPUT__ + ?column? +----------- + {1,2,3,4} +(1 row) +``` +```sql +SELECT ARRAY[5,6] || ARRAY[[1,2],[3,4]]; +__OUTPUT__ + ?column? +--------------------- + {{5,6},{1,2},{3,4}} +(1 row) +``` + +The concatenation operator allows a single element to be pushed onto the beginning or end of a one-dimensional array. It also accepts two `N`-dimensional arrays, or an `N`-dimensional and an `N+1`-dimensional array. + +When a single element is pushed onto either the beginning or end of a one-dimensional array, the result is an array with the same lower bound subscript as the array operand. For example: + +```sql +SELECT array_dims(1 || '[0:1]={2,3}'::int[]); +__OUTPUT__ + array_dims +------------ + [0:2] +(1 row) +``` +```sql +SELECT array_dims(ARRAY[1,2] || 3); +__OUTPUT__ + array_dims +------------ + [1:3] +(1 row) +``` + +When two arrays with an equal number of dimensions are concatenated, the result retains the lower bound subscript of the left-hand operand's outer dimension. The result is an array comprising every element of the left-hand operand followed by every element of the right-hand operand. For example: + +```sql +SELECT array_dims(ARRAY[1,2] || ARRAY[3,4,5]); +__OUTPUT__ + array_dims +------------ + [1:5] +(1 row) +``` +```sql +SELECT array_dims(ARRAY[[1,2],[3,4]] || ARRAY[[5,6],[7,8],[9,0]]); +__OUTPUT__ + array_dims +------------ + [1:5][1:2] +(1 row) +``` + +When an `N`-dimensional array is pushed onto the beginning or end of an `N+1`-dimensional array, the result is analogous to the element-array case above. Each `N`-dimensional sub-array is essentially an element of the `N+1`-dimensional array's outer dimension. For example: + +```sql +SELECT array_dims(ARRAY[1,2] || ARRAY[[3,4],[5,6]]); +__OUTPUT__ + array_dims +------------ + [1:3][1:2] +(1 row) +``` + +An array can also be constructed by using the functions `array_prepend`, `array_append`, or `array_cat`. The first two only support one-dimensional arrays, but `array_cat` supports multidimensional arrays. Some examples: + +```sql +SELECT array_prepend(1, ARRAY[2,3]); +__OUTPUT__ + array_prepend +--------------- + {1,2,3} +(1 row) +``` +```sql +SELECT array_append(ARRAY[1,2], 3); +__OUTPUT__ + array_append +-------------- + {1,2,3} +(1 row) +``` +```sql +SELECT array_cat(ARRAY[1,2], ARRAY[3,4]); +__OUTPUT__ + array_cat +----------- + {1,2,3,4} +(1 row) +``` +```sql +SELECT array_cat(ARRAY[[1,2],[3,4]], ARRAY[5,6]); +__OUTPUT__ + array_cat +--------------------- + {{1,2},{3,4},{5,6}} +(1 row) +``` +```sql +SELECT array_cat(ARRAY[5,6], ARRAY[[1,2],[3,4]]); +__OUTPUT__ + array_cat +--------------------- + {{5,6},{1,2},{3,4}} + ``` + +In simple cases, the concatenation operator discussed above is preferred over direct use of these functions. However, because the concatenation operator is overloaded to serve all three cases, there are situations where use of one of the functions is helpful to avoid ambiguity. For example consider: + +```sql +SELECT ARRAY[1, 2] || '{3, 4}'; -- the untyped literal is taken as an array +__OUTPUT__ + ?column? +----------- + {1,2,3,4} +``` +```sql +SELECT ARRAY[1, 2] || '7'; -- so is this one +__OUTPUT__ +ERROR: malformed array literal: "7" +``` +```sql +SELECT ARRAY[1, 2] || NULL; -- so is an undecorated NULL +__OUTPUT__ + ?column? +---------- + {1,2} +(1 row) +``` +```sql +SELECT array_append(ARRAY[1, 2], NULL); -- this might have been meant +__OUTPUT__ + array_append +-------------- + {1,2,NULL} +``` + +In the examples above, the parser sees an integer array on one side of the concatenation operator, and a constant of undetermined type on the other. The heuristic it uses to resolve the constant's type is to assume it's of the same type as the operator's other input — in this case, integer array. So the concatenation operator is presumed to represent `array_cat`, not `array_append`. When that's the wrong choice, it could be fixed by casting the constant to the array's element type; but explicit use of `array_append` might be a preferable solution. + +## Searching in arrays + +To search for a value in an array, each value must be checked. This can be done manually, if you know the size of the array. For example: + +```sql +SELECT * FROM sal_emp WHERE pay_by_quarter[1] = 10000 OR + pay_by_quarter[2] = 10000 OR + pay_by_quarter[3] = 10000 OR + pay_by_quarter[4] = 10000; +``` + +However, this quickly becomes tedious for large arrays, and is not helpful if the size of the array is unknown. An alternative method is described in [Row and Array Comparisons](https://www.postgresql.org/docs/9.3/functions-comparisons.html). The above query could be replaced by: + +```sql +SELECT * FROM sal_emp WHERE 10000 = ANY (pay_by_quarter); +``` + +In addition, you can find rows where the array has all values equal to 10000 with: + +```sql +SELECT * FROM sal_emp WHERE 10000 = ALL (pay_by_quarter); +``` + +Alternatively, the `generate_subscripts` function can be used. For example: + +```sql +SELECT * FROM + (SELECT pay_by_quarter, + generate_subscripts(pay_by_quarter, 1) AS s + FROM sal_emp) AS foo + WHERE pay_by_quarter[s] = 10000; +``` + +You can also search an array using the `&&` operator, which checks whether the left operand overlaps with the right operand. For instance: + +```sql +SELECT * FROM sal_emp WHERE pay_by_quarter && ARRAY[10000]; +``` + +!!! Note + Arrays are not sets; searching for specific array elements can be a sign of database misdesign. Consider using a separate table with a row for each item that would be an array element. This is easier to search, and is likely to scale better for a large number of elements. + +## Array input and output syntax + +The external text representation of an array value consists of items that are interpreted according to the I/O conversion rules for the array's element type, plus decoration that indicates the array structure. The decoration consists of curly braces (`{` and `}`) around the array value plus delimiter characters between adjacent items. The delimiter character is usually a comma (`,`) but can be something else: it is determined by the `typdelim` setting for the array's element type. Among the standard data types provided in the PostgreSQL distribution, all use a comma, except for type box, which uses a semicolon (`;`). In a multidimensional array, each dimension (row, plane, cube, etc.) gets its own level of curly braces, and delimiters must be written between adjacent curly-braced entities of the same level. + +The array output routine will put double quotes around element values if they are empty strings, contain curly braces, delimiter characters, double quotes, backslashes, or white space, or match the word `NULL`. Double quotes and backslashes embedded in element values will be backslash-escaped. For numeric data types it is safe to assume that double quotes will never appear, but for textual data types one should be prepared to cope with either the presence or absence of quotes. + +By default, the lower bound index value of an array's dimensions is set to one. To represent arrays with other lower bounds, the array subscript ranges can be specified explicitly before writing the array contents. This decoration consists of square brackets (`[]`) around each array dimension's lower and upper bounds, with a colon (`:`) delimiter character in between. The array dimension decoration is followed by an equal sign (`=`). For example: + +```sql +SELECT f1[1][-2][3] AS e1, f1[1][-1][5] AS e2 + FROM (SELECT '[1:1][-2:-1][3:5]={{{1,2,3},{4,5,6}}}'::int[] AS f1) AS ss; +__OUTPUT__ + e1 | e2 +----+---- + 1 | 6 +(1 row) +``` + +The array output routine includes explicit dimensions in its result only when there are one or more lower bounds different from one. + +If the value written for an element is `NULL` (in any case variant), the element is taken to be NULL. The presence of any quotes or backslashes disables this and allows the literal string value "NULL" to be entered. Also, for backward compatibility with pre-8.2 versions of PostgreSQL, the [`array_nulls`](https://www.postgresql.org/docs/9.3/runtime-config-compatible.html#GUC-ARRAY-NULLS) configuration parameter can be turned off to suppress recognition of `NULL` as a NULL. + +As shown previously, when writing an array value you can use double quotes around any individual array element. You must do so if the element value would otherwise confuse the array-value parser. For example, elements containing curly braces, commas (or the data type's delimiter character), double quotes, backslashes, or leading or trailing whitespace must be double-quoted. Empty strings and strings matching the word `NULL` must be quoted, too. To put a double quote or backslash in a quoted array element value, precede it with a backslash. Alternatively, you can avoid quotes and use backslash-escaping to protect all data characters that would otherwise be taken as array syntax. + +You can add whitespace before a left brace or after a right brace. You can also add whitespace before or after any individual item string. In all of these cases the whitespace will be ignored. However, whitespace within double-quoted elements, or surrounded on both sides by non-whitespace characters of an element, is not ignored. + +!!! Note + The `ARRAY` constructor syntax is often easier to work with than the array-literal syntax when writing array values in SQL commands. In `ARRAY`, individual element values are written the same way they would be written when not members of an array. + diff --git a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/composite_types.mdx b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/composite_types.mdx new file mode 100644 index 00000000000..f5a7f8f38e5 --- /dev/null +++ b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/composite_types.mdx @@ -0,0 +1,300 @@ +--- +title: "Composite types" +--- + +| Name | Native | Alias | Description | +| -------------------------------------------------------------------- | ------ | ----- | --------------------------------------------- | +| `CREATE TYPE AS (col1 data type, col2 datatype,..)` | ✅ | | Structure of a row or record. | + +## Overview + +A composite type represents the structure of a row or record; it is essentially just a list of field names and their data types. PostgreSQL allows composite types to be used in many of the same ways that simple types can be used. For example, a column of a table can be declared to be of a composite type. + +## Declaration of composite types + +Here are two simple examples of defining composite types: + +```sql +CREATE TYPE complex AS ( + r double precision, + i double precision +); + +CREATE TYPE inventory_item AS ( + name text, + supplier_id integer, + price numeric +); +``` + +The syntax is comparable to `CREATE TABLE`, except that only field names and types can be specified. No constraints (such as `NOT NULL`) can presently be included. The AS keyword is essential because without it, the system will think a different kind of `CREATE TYPE` command is meant, and you can get odd syntax errors. + +Having defined the types, we can use them to create tables: + +```sql +CREATE TABLE on_hand ( + item inventory_item, + count integer +); + +INSERT INTO on_hand VALUES (ROW('fuzzy dice', 42, 1.99), 1000); +``` + +or functions: + +```sql +CREATE FUNCTION price_extension(inventory_item, integer) RETURNS numeric +AS 'SELECT $1.price * $2' LANGUAGE SQL; + +SELECT price_extension(item, 10) FROM on_hand; +``` + +Whenever you create a table, a composite type is also automatically created, with the same name as the table, to represent the table's row type. For example, had we said: + +```sql +CREATE TABLE inventory_item ( + name text, + supplier_id integer REFERENCES suppliers, + price numeric CHECK (price > 0) +); +``` + +then the same `inventory_item` composite type shown above would come into being as a byproduct, and could be used just as above. However there is an important restriction of the current implementation: since no constraints are associated with a composite type, the constraints shown in the table definition do not apply to values of the composite type outside the table. (A partial workaround is to use domain types as members of composite types.) + +## Constructing composite values + +To write a composite value as a literal constant, enclose the field values in parentheses and separate them by commas. You can put double quotes around any field value, and must do so if it contains commas or parentheses. Therefore, the general format of a composite constant is the following: + +```sql +'( val1 , val2 , ... )' +``` + +An example is: + +```sql +'("fuzzy dice",42,1.99)' +``` + +which would be a valid value of the `inventory_item` type defined above. To make a field be NULL, write no characters at all in its position in the list. For example, this constant specifies a NULL third field: + +```sql +'("fuzzy dice",42,)' +``` + +If you want an empty string rather than NULL, write double quotes: + +```sql +'("",42,)' +``` + +Here the first field is a non-NULL empty string, the third is NULL. + +!!! Note + These constants are actually only a special case of the generic type constants discussed in [Constants of Other Types](https://www.postgresql.org/docs/9.3/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS-GENERIC). The constant is initially treated as a string and passed to the composite-type input conversion routine. An explicit type specification might be necessary to tell which type to convert the constant to. + +The `ROW` expression syntax can also be used to construct composite values. In most cases this is considerably simpler to use than the string-literal syntax since you don't have to worry about multiple layers of quoting. We already used this method above: + +```sql +ROW('fuzzy dice', 42, 1.99) +ROW('', 42, NULL) +``` + +The `ROW` keyword is actually optional as long as you have more than one field in the expression, so these can be simplified to: + +```sql +('fuzzy dice', 42, 1.99) +('', 42, NULL) +``` + +## Accessing composite types + +To access a field of a composite column, one writes a dot and the field name, much like selecting a field from a table name. In fact, it's so much like selecting from a table name that you often have to use parentheses to keep from confusing the parser. For example, you might try to select some subfields from our `on_hand` example table with something like: + +```sql +SELECT item.name FROM on_hand WHERE item.price > 9.99; +``` + +However, that doesn't work since the name item is taken to be a table name, not a column name of `on_hand`, per SQL syntax rules. You must write it like this: + +```sql +SELECT (item).name FROM on_hand WHERE (item).price > 9.99; +``` + +or if you need to use the table name as well (for instance in a multitable query), like this: + +```sql +SELECT (on_hand.item).name FROM on_hand WHERE (on_hand.item).price > 9.99; +``` + +Now the parenthesized object is correctly interpreted as a reference to the item column, and then the subfield can be selected from it. + +Similar syntactic issues apply whenever you select a field from a composite value. For instance, to select just one field from the result of a function that returns a composite value, you'd need to write something like: + +```sql +SELECT (my_func(...)).field FROM ... +``` + +Without the extra parentheses, this command generates a syntax error. + +## Modifying composite types + +Here are some examples of the proper syntax for inserting and updating composite columns. First, inserting or updating a whole column: + +```sql +INSERT INTO mytab (complex_col) VALUES((1.1,2.2)); + +UPDATE mytab SET complex_col = ROW(1.1,2.2) WHERE ...; +``` + +The first example omits `ROW`, the second uses it. It can be done either way. + +We can update an individual subfield of a composite column: + +```sql +UPDATE mytab SET complex_col.r = (complex_col).r + 1 WHERE ...; +``` + +Notice here that we don't need to (and indeed cannot) put parentheses around the column name appearing just after `SET`, but we do need parentheses when referencing the same column in the expression to the right of the equal sign. + +And we can specify subfields as targets for `INSERT`, too: + +```sql +INSERT INTO mytab (complex_col.r, complex_col.i) VALUES(1.1, 2.2); +``` + +Had we not supplied values for all the subfields of the column, the remaining subfields would have been filled with null values. + +## Using composite types in queries + +There are various special syntax rules and behaviors associated with composite types in queries. These rules provide useful shortcuts, but can be confusing if you don't know the logic behind them. + +In PostgreSQL, a reference to a table name (or alias) in a query is effectively a reference to the composite value of the table's current row. For example, if we had a table `inventory_item` as shown in [Declaration of composite types](#declaration-of-composite-types), we could write: + +```sql +SELECT c FROM inventory_item c; +``` + +This query produces a single composite-valued column, so we might get output like: + +```sql +__OUTPUT__ + c +------------------------ + ("fuzzy dice",42,1.99) +(1 row) +``` + +Simple names are matched to column names before table names, so this example works only because there is no column named `c` in the query's tables. + +The ordinary qualified-column-name syntax `table_name.column_name` can be understood as applying field selection to the composite value of the table's current row. For efficiency reasons, it's not actually implemented that way. + +When we write + +```sql +SELECT c.* FROM inventory_item c; +``` + +then, according to the SQL standard, we should get the contents of the table expanded into separate columns: + +```sql +__OUTPUT__ + name | supplier_id | price +------------+-------------+------- + fuzzy dice | 42 | 1.99 +(1 row) +``` + +as if the query were: + +```sql +SELECT c.name, c.supplier_id, c.price FROM inventory_item c; +``` + +PostgreSQL applies this expansion behavior to any composite-valued expression, although as shown in [Accessing composite types](#accessing-composite-types), you need to write parentheses around the value that `.*` is applied to whenever it's not a simple table name. For example, if `myfunc()` is a function returning a composite type with columns `a`, `b`, and `c`, then these two queries have the same result: + +```sql +SELECT (myfunc(x)).* FROM some_table; +SELECT (myfunc(x)).a, (myfunc(x)).b, (myfunc(x)).c FROM some_table; +``` + +!!! note Tip + PostgreSQL handles column expansion by actually transforming the first form into the second. So, in this example, `myfunc()` would get invoked three times per row with either syntax. If it's an expensive function you may wish to avoid that, which you can do with a query like: + + ```sql + SELECT (m).* FROM (SELECT myfunc(x) AS m FROM some_table OFFSET 0) ss; + ``` + + The `OFFSET 0` clause keeps the optimizer from "flattening" the sub-select to arrive at the form with multiple calls of `myfunc()`. + +The `composite_value.*` syntax results in column expansion of this kind when it appears at the top level of a `SELECT` output list, a `RETURNING` list in `INSERT`/`UPDATE`/`DELETE`, a `VALUES` clause, or a row constructor. In all other contexts (including when nested inside one of those constructs), attaching `.*` to a composite value does not change the value, since it means "all columns" and so the same composite value is produced again. For example, if `somefunc()` accepts a composite-valued argument, these queries are the same: + +```sql +SELECT somefunc(c.*) FROM inventory_item c; +SELECT somefunc(c) FROM inventory_item c; +``` + +In both cases, the current row of `inventory_item` is passed to the function as a single composite-valued argument. Even though `.*` does nothing in such cases, using it is good style, since it makes clear that a composite value is intended. In particular, the parser considers `c` in `c.*` to refer to a table name or alias, not to a column name, so that there is no ambiguity; whereas without `.*`, it is not clear whether `c` means a table name or a column name, and in fact the column-name interpretation is preferred if there is a column named `c`. + +Another example demonstrating these concepts is that all these queries mean the same thing: + +```sql +SELECT * FROM inventory_item c ORDER BY c; +SELECT * FROM inventory_item c ORDER BY c.*; +SELECT * FROM inventory_item c ORDER BY ROW(c.*); +``` + +All of these `ORDER BY` clauses specify the row's composite value. However, if `inventory_item` contained a column named `c`, the first case would be different from the others, as it would mean to sort by that column only. Given the column names previously shown, these queries are also equivalent to those above: + +```sql +SELECT * FROM inventory_item c ORDER BY ROW(c.name, c.supplier_id, c.price); +SELECT * FROM inventory_item c ORDER BY (c.name, c.supplier_id, c.price); +``` + +Another special syntactical behavior associated with composite values is that we can use functional notation for extracting a field of a composite value. The simple way to explain this is that the notations `field(table)` and `table.field` are interchangeable. For example, these queries are equivalent: + +```sql +SELECT c.name FROM inventory_item c WHERE c.price > 1000; +SELECT name(c) FROM inventory_item c WHERE price(c) > 1000; +``` + +Moreover, if we have a function that accepts a single argument of a composite type, we can call it with either notation. These queries are all equivalent: + +```sql +SELECT somefunc(c) FROM inventory_item c; +SELECT somefunc(c.*) FROM inventory_item c; +SELECT c.somefunc FROM inventory_item c; +``` + +This equivalence between functional notation and field notation makes it possible to use functions on composite types to implement "computed fields". An application using the last query above wouldn't need to be directly aware that `somefunc` isn't a real column of the table. + +!!! note Tip + Because of this behavior, it's unwise to give a function that takes a single composite-type argument the same name as any of the fields of that composite type. If there is ambiguity, the field-name interpretation is preferred, so that such a function could not be called without tricks. One way to force the function interpretation is to schema-qualify the function name, that is, write `schema.func(compositevalue)`. + +## Composite type input and output syntax + +The external text representation of a composite value consists of items that are interpreted according to the I/O conversion rules for the individual field types, plus decoration that indicates the composite structure. The decoration consists of parentheses (`(` and `)`) around the whole value, plus commas (`,`) between adjacent items. Whitespace outside the parentheses is ignored, but within the parentheses it is considered part of the field value, and might or might not be significant depending on the input conversion rules for the field data type. For example, in: + +```sql +'( 42)' +``` + +The whitespace is ignored if the field type is integer, but not if it is text. + +As shown previously, when writing a composite value you can write double quotes around any individual field value. You must do so if the field value would otherwise confuse the composite-value parser. In particular, fields containing parentheses, commas, double quotes, or backslashes must be double-quoted. To put a double quote or backslash in a quoted composite field value, precede it with a backslash. Also, a pair of double quotes within a double-quoted field value is taken to represent a double quote character, analogously to the rules for single quotes in SQL literal strings. Alternatively, you can avoid quoting and use backslash-escaping to protect all data characters that would otherwise be taken as composite syntax. + +A completely empty field value (no characters at all between the commas or parentheses) represents a NULL. To write a value that is an empty string rather than NULL, write `""`. + +The composite output routine puts double quotes around field values if they are empty strings or contain parentheses, commas, double quotes, backslashes, or white space. Doing so for white space is not essential, but aids legibility. Double quotes and backslashes embedded in field values are doubled. + +!!! Note + Remember that what you write in an SQL command is first interpreted as a string literal, and then as a composite. This doubles the number of backslashes you need (assuming escape string syntax is used). For example, to insert a text field containing a double quote and a backslash in a composite value, you'd need to write: + + ```sql + INSERT ... VALUES ('("\"\\")'); + ``` + + The string-literal processor removes one level of backslashes, so that what arrives at the composite-value parser looks like (`"\"\\"`). In turn, the string fed to the text data type's input routine becomes `"\`. If we were working with a data type whose input routine also treated backslashes specially, `bytea` for example, we might need as many as eight backslashes in the command to get one backslash into the stored composite field. Dollar quoting can be used to avoid the need to double backslashes. + +!!! note Tip + The `ROW` constructor syntax is usually easier to work with than the composite-literal syntax when writing composite values in SQL commands. In `ROW`, individual field values are written the same way they would be written when not members of a composite. + diff --git a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/enumerated_types.mdx b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/enumerated_types.mdx new file mode 100644 index 00000000000..96b83bcba1e --- /dev/null +++ b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/enumerated_types.mdx @@ -0,0 +1,32 @@ +--- +title: "Enumerated types" +--- + + +| Name | Native | Alias | Description | +| --------- | ------ | ----- | --------------------------------------------- | +| `ENUM` | ✅ | | Static, ordered set of values, 4 bytes storage, max length is limited by `NAMEDATALEN` setting into PostgreSQL. | + +## Example + +This example shows how to create `ENUM` types and use it: + +```sql +CREATE TYPE city AS ENUM('Pune','Mumbai','Chennai'); + +CREATE TABLE shops(name text, location city); + +INSERT INTO shops VALUES('Puma',`Mumbai` ); + +SELECT * FROM shops; +__OUTPUT__ + name | location +--------+----------- + Puma | Mumbai +``` + +`ENUM` types are case sensitive, and whitespace in `ENUM` types is also significant. + +The `ENUM` types and its labels are stored in `pg_enum` system catalog. + +For more information on enumerated data types, see [PostgreSQL docs](https://www.postgresql.org/docs/current/datatype-enum.html). \ No newline at end of file diff --git a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/geometric_types.mdx b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/geometric_types.mdx new file mode 100644 index 00000000000..3447d7e6b9b --- /dev/null +++ b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/geometric_types.mdx @@ -0,0 +1,20 @@ +--- +title: "Geometric types" +--- + +| Name | Native | Alias | Description | +| --------------- | -------| ----- | ---------------------------------------------------------------------------------------------- | +| `POINT` | ✅ | | Point on a plane, 16 bytes storage, represented as `(x,y)`. | +| `LINE` | ✅ | | Infinite line, 32 bytes storage, represented as `{A,B,C}`. | +| `LSEG` | ✅ | | Finite line segment, 32 bytes storage, represented as `((x1,y1),(x2,y2))`. | +| `BOX` | ✅ | | Rectangular box, 32 bytes storage, represented as `((x1,y1),(x2,y2))`. | +| `PATH` | ✅ | | Closed path (similar to polygon), 16 + 16n bytes storage, represented as `((x1,y1),...)`. | +| `PATH` | ✅ | | Open path, 16 + 16n bytes storage, represented as `[(x1,y1),...]`. | +| `POLYGON` | ✅ | | Polygon (similar to closed path), 40 + 16n bytes storage, represented as `((x1,y1),...)`. | +| `CIRCLE` | ✅ | | Circle, 24 bytes storage, represented as `<(x,y),r>` (center point and radius). | + +## Overview + +Geometric data types represent two-dimensional spatial objects. + +For more information on geometric data types, see [PostgreSQL docs](https://www.postgresql.org/docs/current/datatype-geometric.html). \ No newline at end of file diff --git a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/index.mdx b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/index.mdx index 802b04dfd0e..dd13602a7d1 100644 --- a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/index.mdx +++ b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/index.mdx @@ -9,6 +9,23 @@ legacyRedirectsGenerated: redirects: - /epas/latest/epas_compat_reference/02_the_sql_language/02_data_types/ #generated for docs/epas/reorg-role-use-case-mode - ../../../reference/sql_reference/02_the_sql_language/02_data_types +navigation: + - 01_numeric_types + - monetary_types + - 02_character_types + - 03_binary_data + - 04_date_time_types + - 05_boolean_type + - enumerated_types + - geometric_types + - network_address_types + - 06_xml_type + - array_types + - composite_types + - range_types + - object_identifier_types + - pseudo_types --- +EDB Postgres Advanced Server has the following data types. diff --git a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/monetary_types.mdx b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/monetary_types.mdx new file mode 100644 index 00000000000..928f51531e8 --- /dev/null +++ b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/monetary_types.mdx @@ -0,0 +1,32 @@ +--- +title: Monetary types +source: + url: https://www.postgresql.org/docs/current/datatype-money.html + timestamp: 2023-09-11 +--- + +| Data type | Native | Alias | Description | +| --------- | ------ | ------ | ------------------------------------------------------------------------------------- | +| `MONEY` | | ✅ | Currency amount, 8 byte storage, -92233720368547758.08 to +92233720368547758.07 range | + +## Overview + +The `MONEY` type stores a currency amount with a fixed fractional precision. The fractional precision is determined by the database's `lc_monetary` setting. The range assumes there are two fractional digits. Input is accepted in a variety of formats, including integer and floating-point literals, as well as typical currency formatting, such as '$1,000.00'. Output is generally in the latter form but depends on the locale. + +Since the output of this data type is locale-sensitive, it might not work to load money data into a database that has a different setting of `lc_monetary`. To avoid problems, before restoring a dump into a new database make sure `lc_monetary` has the same or equivalent value as in the database that was dumped. + +Values of `NUMERIC`, `INT`, and `BIGINT` data types can be cast to `MONEY`. Conversion from `REAL` and `DOUBLE PRECISION` data types can be done by casting to `NUMERIC` first, for example: + +```sql +SELECT '12.34'::float8::numeric::money; +``` + +However, this is not recommended. Floating point numbers shouldn't be used to handle money due to the potential for rounding errors. + +A money value can be cast to `NUMERIC` without loss of precision. Conversion to other types could potentially lose precision, and must also be done in two stages: + +```sql +SELECT '52093.89'::money::numeric::float8; +``` + +Division of a money value by an integer value is performed with truncation of the fractional part towards zero. To get a rounded result, divide by a floating-point value, or cast the money value to numeric before dividing and back to money afterwards. (The latter is preferable to avoid risking precision loss.) When a money value is divided by another money value, the result is double precision (that is, a pure number, not money); the currency units cancel each other out in the division. \ No newline at end of file diff --git a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/network_address_types.mdx b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/network_address_types.mdx new file mode 100644 index 00000000000..858c8f6a536 --- /dev/null +++ b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/network_address_types.mdx @@ -0,0 +1,18 @@ +--- +title: "Network address types" +--- + +| Name | Native | Alias | Description | +|-----------|--------|--------|-----------------------------------------------------------------------------------| +| `CIDR` | ✅ | | IPV4 and IPV6 networks, 7 or 19 bytes storage. | +| `INET` | ✅ | | IPV4 and IPV6 hosts and networks, 7 or 19 bytes storage. | +| `MACADDR` | ✅ | | MAC addresses, 6 bytes storage. | +| `MACADDR8`| ✅ | | MAC addresses (EUI-64 format), 8 bytes storage. | + +## Overview + +EDB Postgres Advanced Server offers data types to store IPV4, IPV6, and MAC addresses. + +These data types offer input error checking and specialized operators and functions. + +For more information on network address types, see [PostgreSQL docs](https://www.postgresql.org/docs/current/datatype-net-types.html). \ No newline at end of file diff --git a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/object_identifier_types.mdx b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/object_identifier_types.mdx new file mode 100644 index 00000000000..0059b2366af --- /dev/null +++ b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/object_identifier_types.mdx @@ -0,0 +1,63 @@ +--- +title: "Object identifier types" +--- + +| Data type | Native | Alias | Description | +| ------------------- | ------ | ----- | -------------------------------------- | +| `oid` | ✅ | | The numeric object identifier. | +| `regproc` | ✅ | | The name of the function. | +| `regprocedure`| ✅ | | The function with argument types. | +| `regoper` | ✅ | | The name of the operator. | +| `regoperator` | ✅ | | The operator with argument types. | +| `regclass` | ✅ | | The name of the relation. | +| `regtype` | ✅ | | The name of the data type. | +| `regconfig` | ✅ | | The text search configuration. | +| `regdictionary` | ✅ | | The text search dictionary. | + +## Overview + +Object identifiers (OIDs) are used internally by PostgreSQL as primary keys for various system tables. OIDs are not added to user-created tables, unless `WITH OIDS` is specified when the table is created, or the [`default_with_oids`](https://www.postgresql.org/docs/9.3/runtime-config-compatible.html#GUC-DEFAULT-WITH-OIDS) configuration variable is enabled. Type `oid` represents an object identifier. There are also several alias types for `oid`: `regproc`, `regprocedure`, `regoper`, `regoperator`, `regclass`, `regtype`, `regconfig`, and `regdictionary`. + +The `oid` type is currently implemented as an unsigned four-byte integer. Therefore, it is not large enough to provide database-wide uniqueness in large databases, or even in large individual tables. So, using a user-created table's OID column as a primary key is discouraged. OIDs are best used only for references to system tables. + +The `oid` type itself has few operations beyond comparison. It can be cast to integer, however, and then manipulated using the standard integer operators. Beware of possible signed-versus-unsigned confusion if you do this. + +The OID alias types have no operations of their own except for specialized input and output routines. These routines are able to accept and display symbolic names for system objects, rather than the raw numeric value that type `oid` would use. The alias types allow simplified lookup of OID values for objects. For example, to examine the pg_attribute rows related to a table` mytable`, one could write: + +```sql +SELECT * FROM pg_attribute WHERE attrelid = 'mytable'::regclass; +``` +rather than: + +```sql +SELECT * FROM pg_attribute + WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'mytable'); +``` + +While that doesn't look all that bad by itself, it's still oversimplified. A far more complicated sub-select would be needed to select the right OID if there are multiple tables named `mytable` in different schemas. The `regclass` input converter handles the table lookup according to the schema path setting, and so it does the "right thing" automatically. Similarly, casting a table's OID to `regclass` is handy for symbolic display of a numeric OID. + +The following table lists the available object identifier types: + +| Name | References | Description | Value example | +| ---- | ---------- | ----------- | ------------- | +| `oid` | Any | Numeric object identifier | `564182` | +| `regproc` | `pg_proc` | Function name | `sum` | +| `regprocedure` | `pg_proc ` | Function with argument types | `sum(int4)` | +| `regoper` | `pg_operator` | Operator name | `+` | +| `regoperator` | `pg_operator` | Operator with argument types | `*(integer,integer) or -(NONE,integer)` | +| `regclass` | `pg_class` | Relation name | `pg_type` | +| `regtype` | `pg_type` | Data type name | `integer` | +| `regconfig` | `pg_ts_config` | Text search configuration | `english` | +| `regdictionary` | `pg_ts_dict` | Text search dictionary | `simple` | + +All of the OID alias types accept schema-qualified names, and display schema-qualified names on output if the object can't be found in the current search path without being qualified. The `regproc` and `regoper` alias types accept only input names that are unique (not overloaded), so they are of limited use. For most uses, `regprocedure` or `regoperator` are more appropriate. For `regoperator`, unary operators are identified by writing `NONE` for the unused operand. + +An additional property of the OID alias types is the creation of dependencies. If a constant of one of these types appears in a stored expression (such as a column default expression or view), it creates a dependency on the referenced object. For example, if a column has a default expression `nextval('my_seq'::regclass)`, PostgreSQL understands that the default expression depends on the sequence `my_seq`. The system doesn't let the sequence be dropped without first removing the default expression. + +Another identifier type used by the system is `xid`, or transaction (abbreviated xact) identifier. This is the data type of the system columns `xmin` and `xmax`. Transaction identifiers are 32-bit quantities. + +A third identifier type used by the system is `cid`, or command identifier. This is the data type of the system columns `cmin` and `cmax`. Command identifiers are also 32-bit quantities. + +A final identifier type used by the system is `tid`, or tuple identifier (row identifier). This is the data type of the system column `ctid`. A tuple ID is a pair (block number, tuple index within block) that identifies the physical location of the row within its table. + +For more information on system columns, see the [PostgreSQL documentation](https://www.postgresql.org/docs/9.3/ddl-system-columns.html). diff --git a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/pseudo_types.mdx b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/pseudo_types.mdx new file mode 100644 index 00000000000..ddb1b1c5926 --- /dev/null +++ b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/pseudo_types.mdx @@ -0,0 +1,31 @@ +--- +title: "Pseudo-types" +--- + +| Data type | Native | Alias | Description | +| ------------------- | ------ | ----- | -------------------------------------- | +| `any` | ✅ | | Indicates that a function accepts any input data type. | +| `anyelement` | ✅ | | Indicates that a function accepts any data type. For more information, see [Polymorphic types](https://www.postgresql.org/docs/9.3/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC) in the PostgreSQL documentation. | +| `anyarray` | ✅ | | Indicates that a function accepts any array data type. For more information, see [Polymorphic types](https://www.postgresql.org/docs/9.3/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC) in the PostgreSQL documentation. | +| `anynonarray` | ✅ | | Indicates that a function accepts any non-array data type. For more information, see [Polymorphic types](https://www.postgresql.org/docs/9.3/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC) in the PostgreSQL documentation. | +| `anyenum` | ✅ | | Indicates that a function accepts any enum data type. For more information, see [Polymorphic types](https://www.postgresql.org/docs/9.3/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC) and [Enumerated types](https://www.postgresql.org/docs/9.3/datatype-enum.html) in the PostgreSQL documentation. | +| `anyrange` | ✅ | | Indicates that a function accepts any range data type. For more information, see [Polymorphic types](https://www.postgresql.org/docs/9.3/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC) and [Range types](https://www.postgresql.org/docs/9.3/rangetypes.html) in the PostgreSQL documentation. | +| `cstring` | ✅ | | Indicates that a function accepts or returns a null-terminated C string. | +| `internal` | ✅ | | Indicates that a function accepts or returns a server-internal data type. | +| `language_handler` | ✅ | | A procedural language call handler is declared to return `language_handler`. | +| `fdw_handler` | ✅ | | A foreign-data wrapper handler is declared to return `fdw_handler`. | +| `record` | ✅ | | Identifies a function taking or returning an unspecified row type. | +| `trigger` | ✅ | | A trigger function is declared to return trigger. | +| `event_trigger` | ✅ | | An event trigger function is declared to return `event_trigger`. | +| `void` | ✅ | | Indicates that a function returns no value. | +| `opaque` | ✅ | | An obsolete type name that formerly served all the above purposes. | + +## Overview + +The PostgreSQL type system contains a number of special-purpose entries that are collectively called pseudo-types. A pseudo-type cannot be used as a column data type, but it can be used to declare a function's argument or result type. Each of the available pseudo-types is useful in situations where a function's behavior does not correspond to simply taking or returning a value of a specific SQL data type. + +Functions coded in C (whether built-in or dynamically loaded) can be declared to accept or return any of these pseudo data types. It is up to the function author to ensure that the function will behave safely when a pseudo-type is used as an argument type. + +Functions coded in procedural languages can use pseudo-types only as allowed by their implementation languages. At present most procedural languages forbid use of a pseudo-type as an argument type, and allow only void and record as a result type (plus trigger or event_trigger when the function is used as a trigger or event trigger). Some also support polymorphic functions using the types `anyelement`, `anyarray`, `anynonarray`, `anyenum`, and `anyrange`. + +The `internal` pseudo-type is used to declare functions that are meant only to be called internally by the database system, and not by direct invocation in an SQL query. If a function has at least one internal-type argument then it cannot be called from SQL. To preserve the type safety of this restriction it is important to follow this coding rule: do not create any function that is declared to return `internal` unless it has at least one internal argument. diff --git a/product_docs/docs/epas/15/reference/sql_reference/02_data_types/range_types.mdx b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/range_types.mdx new file mode 100644 index 00000000000..fcdd2bb4e13 --- /dev/null +++ b/product_docs/docs/epas/15/reference/sql_reference/02_data_types/range_types.mdx @@ -0,0 +1,223 @@ +--- +title: "Range types" +--- + +| Name | Native | Alias | Description | +| ----------- | ------ | ----- | --------------------------------------- | +| `int4range` | ✅ | | Range of `integer`. | +| `int8range` | ✅ | | Range of `bigint`. | +| `numrange` | ✅ | | Range of `numeric`. | +| `tsrange` | ✅ | | Range of `timestamp without time zone`. | +| `tstzrange` | ✅ | | Range of `timestamp with time zone`. | +| `daterange` | ✅ | | Range of `date`. | + + +## Overview + +Range types are data types representing a range of values of some element type (called the range's subtype). For instance, ranges of `timestamp` might be used to represent the ranges of time that a meeting room is reserved. In this case the data type is `tsrange` (short for timestamp range), and `timestamp` is the subtype. The subtype must have a total order so that it is well-defined whether element values are within, before, or after a range of values. + +Range types are useful because they represent many element values in a single range value, and because concepts such as overlapping ranges can be expressed clearly. The use of time and date ranges for scheduling purposes is the clearest example; but price ranges, measurement ranges from an instrument, and so forth can also be useful. + +## Built-in range types + +PostgreSQL comes with the following built-in range types: + +- `int4range` — Range of `integer` +- `int8range` — Range of `bigint` +- `numrange` — Range of `numeric` +- `tsrange` — Range of `timestamp without time zone` +- `tstzrange` — Range of `timestamp with time zone` +- `daterange` — Range of `date` + +In addition, you can define your own range types. See the [PostgreSQL documentation](https://www.postgresql.org/docs/9.3/sql-createtype.html), for more information. + +## Examples + +```sql +CREATE TABLE reservation (room int, during tsrange); +INSERT INTO reservation VALUES + (1108, '[2010-01-01 14:30, 2010-01-01 15:30)'); + +-- Containment +SELECT int4range(10, 20) @> 3; + +-- Overlaps +SELECT numrange(11.1, 22.2) && numrange(20.0, 30.0); + +-- Extract the upper bound +SELECT upper(int8range(15, 25)); + +-- Compute the intersection +SELECT int4range(10, 20) * int4range(15, 25); + +-- Is the range empty? +SELECT isempty(numrange(1, 5)); +``` + +## Inclusive and exclusive bounds + +Every non-empty range has two bounds, the lower bound and the upper bound. All points between these values are included in the range. An inclusive bound means that the boundary point itself is included in the range as well, while an exclusive bound means that the boundary point isn't included in the range. + +In the text form of a range, an inclusive lower bound is represented by "`[`" while an exclusive lower bound is represented by "`(`". Likewise, an inclusive upper bound is represented by "`]`", while an exclusive upper bound is represented by "`)`". + +The functions `lower_inc` and `upper_inc` test the inclusivity of the lower and upper bounds of a range value, respectively. + +## Infinite (unbounded) ranges + +The lower bound of a range can be omitted, meaning that all points less than the upper bound are included in the range. Likewise, if the upper bound of the range is omitted, then all points greater than the lower bound are included in the range. If both lower and upper bounds are omitted, all values of the element type are considered to be in the range. + +Omitting the lower or upper bound is equivalent to considering that the lower bound is "minus infinity", or the upper bound is "plus infinity", respectively. But note that these infinite values are never values of the range's element type, and can never be part of the range. So there is no such thing as an inclusive infinite bound — if you try to write one, it automatically is converted to an exclusive bound. + +Also, some element types have a notion of "infinity", but that is just another value so far as the range type mechanisms are concerned. For example, in timestamp ranges, `[today,]` means the same thing as `[today,)`. But `[today,infinity]` means something different from `[today,infinity)` — the latter excludes the special timestamp value infinity. + +The functions `lower_inf` and `upper_inf` test for infinite lower and upper bounds of a range, respectively. + +## Range input/output + +The input for a range value must follow one of the following patterns: + +```sql +(lower-bound,upper-bound) +(lower-bound,upper-bound] +[lower-bound,upper-bound) +[lower-bound,upper-bound] +empty +``` + +The parentheses or brackets indicate whether the lower and upper bounds are exclusive or inclusive, as described previously. Notice that the final pattern is empty, which represents an empty range (a range that contains no points). + +The lower-bound may be either a string that is valid input for the subtype, or empty to indicate no lower bound. Likewise, upper-bound may be either a string that is valid input for the subtype, or empty to indicate no upper bound. + +Each bound value can be quoted using double quotes (`"`). This is necessary if the bound value contains parentheses, brackets, commas, double quotes, or backslashes, since these characters would otherwise be taken as part of the range syntax. To put a double quote or backslash in a quoted bound value, precede it with a backslash. Also, a pair of double quotes within a double-quoted bound value is taken to represent a double quote character, analogously to the rules for single quotes in SQL literal strings. Alternatively, you can avoid quoting and use backslash-escaping to protect all data characters that would otherwise be taken as range syntax. Also, to write a bound value that is an empty string, write `""`, since writing nothing means an infinite bound. + +Whitespace is allowed before and after the range value, but any whitespace between the parentheses or brackets is taken as part of the lower or upper bound value. Depending on the element type, it might or might not be significant. + +Examples: + +```sql +-- includes 3, does not include 7, and does include all points in between +SELECT '[3,7)'::int4range; + +-- does not include either 3 or 7, but includes all points in between +SELECT '(3,7)'::int4range; + +-- includes only the single point 4 +SELECT '[4,4]'::int4range; + +-- includes no points (and will be normalized to 'empty') +SELECT '[4,4)'::int4range; +``` + +## Constructing ranges + +Each range type has a constructor function with the same name as the range type. Using the constructor function is frequently more convenient than writing a range literal constant, since it avoids the need for extra quoting of the bound values. The constructor function accepts two or three arguments. The two-argument form constructs a range in standard form (lower bound inclusive, upper bound exclusive), while the three-argument form constructs a range with bounds of the form specified by the third argument. The third argument must be one of the strings "`()`", "`(]`", "`[)`", or "`[]`". For example: + +```sql +-- The full form is: lower bound, upper bound, and text argument indicating +-- inclusivity/exclusivity of bounds. +SELECT numrange(1.0, 14.0, '(]'); + +-- If the third argument is omitted, '[)' is assumed. +SELECT numrange(1.0, 14.0); + +-- Although '(]' is specified here, on display the value will be converted to +-- canonical form, since int8range is a discrete range type (see below). +SELECT int8range(1, 14, '(]'); + +-- Using NULL for either bound causes the range to be unbounded on that side. +SELECT numrange(NULL, 2.2); +``` +## Discrete range types + +A discrete range is one whose element type has a well-defined "step", such as integer or date. In these types two elements can be said to be adjacent, when there are no valid values between them. This contrasts with continuous ranges, where it's always (or almost always) possible to identify other element values between two given values. For example, a range over the `numeric` type is continuous, as is a range over `timestamp`. Even though timestamp has limited precision, and so could theoretically be treated as discrete, it's better to consider it continuous since the step size is normally not of interest. + +Another way to think about a discrete range type is that there is a clear idea of a "next" or "previous" value for each element value. Knowing that, it is possible to convert between inclusive and exclusive representations of a range's bounds, by choosing the next or previous element value instead of the one originally given. For example, in an integer range type `[4,8]` and `(3,9)` denote the same set of values; but this would not be so for a range over numeric. + +A discrete range type should have a *canonicalization* function that is aware of the desired step size for the element type. The canonicalization function is charged with converting equivalent values of the range type to have identical representations, in particular consistently inclusive or exclusive bounds. If a canonicalization function is not specified, then ranges with different formatting are always treated as unequal, even though they might represent the same set of values in reality. + +The built-in range types `int4range`, `int8range`, and `daterange` all use a canonical form that includes the lower bound and excludes the upper bound; that is, `[)`. User-defined range types can use other conventions, however. + +## Defining new range types + +Users can define their own range types. The most common reason to do this is to use ranges over subtypes not provided among the built-in range types. For example, to define a new range type of subtype `float8`: + +```sql +CREATE TYPE floatrange AS RANGE ( + subtype = float8, + subtype_diff = float8mi +); + +SELECT '[1.234, 5.678]'::floatrange; +``` + +Because `float8` has no meaningful "step", we do not define a canonicalization function in this example. + +If the subtype is considered to have discrete rather than continuous values, the `CREATE TYPE` command should specify a `canonical` function. The canonicalization function takes an input range value, and must return an equivalent range value that may have different bounds and formatting. The canonical output for two ranges that represent the same set of values, for example the integer ranges `[1, 7]` and `[1, 8)`, must be identical. It doesn't matter which representation you choose to be the canonical one, so long as two equivalent values with different formattings are always mapped to the same value with the same formatting. In addition to adjusting the inclusive/exclusive bounds format, a canonicalization function might round off boundary values, in case the desired step size is larger than what the subtype is capable of storing. For instance, a range type over timestamp could be defined to have a step size of an hour, in which case the canonicalization function would need to round off bounds that weren't a multiple of an hour, or perhaps throw an error instead. + +Defining your own range type also allows you to specify a different subtype B-tree operator class or collation to use, so as to change the sort ordering that determines which values fall into a given range. + +In addition, any range type that is meant to be used with GiST or SP-GiST indexes should define a subtype difference, or `subtype_diff`, function. The index still works without `subtype_diff`, but it is likely to be considerably less efficient than if a difference function is provided. The subtype difference function takes two input values of the subtype, and returns their difference, for example, `X` minus `Y`, represented as a `float8` value. In our example above, the function that underlies the regular `float8` minus operator can be used; but for any other subtype, some type conversion would be necessary. Some creative thought about how to represent differences as numbers might be needed, too. To the greatest extent possible, the `subtype_diff` function should agree with the sort ordering implied by the selected operator class and collation; that is, its result should be positive whenever its first argument is greater than its second according to the sort ordering. + +See the [PostgreSQL documentation](https://www.postgresql.org/docs/9.3/sql-createtype.html) for more information about creating range types. + +## Indexing + +GiST and SP-GiST indexes can be created for table columns of range types. For instance, to create a GiST index: + +```sql +CREATE INDEX reservation_idx ON reservation USING gist (during); +``` + +A GiST or SP-GiST index can accelerate queries involving these range operators: `=`, `&&`, `<@`, `@>`, `<<`, `>>`, `-|-`, `&<`, and `&>`. + +In addition, B-tree and hash indexes can be created for table columns of range types. For these index types, basically the only useful range operation is equality. There is a B-tree sort ordering defined for range values, with corresponding `<` and `>` operators, but the ordering is rather arbitrary and not usually useful in the real world. Range types' B-tree and hash support is primarily meant to allow sorting and hashing internally in queries, rather than creation of actual indexes. + +## Constraints on ranges + +While `UNIQUE` is a natural constraint for scalar values, it is usually unsuitable for range types. Instead, an exclusion constraint is often more appropriate. Exclusion constraints allow the specification of constraints such as "non-overlapping" on a range type. For example: + +```sql +CREATE TABLE reservation ( + during tsrange, + EXCLUDE USING gist (during WITH &&) +); +``` + +That constraint prevents any overlapping values from existing in the table at the same time: + +```sql +INSERT INTO reservation VALUES + ('[2010-01-01 11:30, 2010-01-01 15:00)'); +INSERT 0 1 + +INSERT INTO reservation VALUES + ('[2010-01-01 14:45, 2010-01-01 15:45)'); +ERROR: conflicting key value violates exclusion constraint "reservation_during_excl" +DETAIL: Key (during)=(["2010-01-01 14:45:00","2010-01-01 15:45:00")) conflicts +with existing key (during)=(["2010-01-01 11:30:00","2010-01-01 15:00:00")). +``` + +You can use the [`btree_gist`](https://www.postgresql.org/docs/9.3/btree-gist.html) extension to define exclusion constraints on plain scalar data types, which can then be combined with range exclusions for maximum flexibility. For example, after `btree_gist` is installed, the following constraint will reject overlapping ranges only if the meeting room numbers are equal: + +```sql +CREATE EXTENSION btree_gist; +CREATE TABLE room_reservation ( + room text, + during tsrange, + EXCLUDE USING gist (room WITH =, during WITH &&) +); + +INSERT INTO room_reservation VALUES + ('123A', '[2010-01-01 14:00, 2010-01-01 15:00)'); +INSERT 0 1 + +INSERT INTO room_reservation VALUES + ('123A', '[2010-01-01 14:30, 2010-01-01 15:30)'); +ERROR: conflicting key value violates exclusion constraint "room_reservation_room_during_excl" +DETAIL: Key (room, during)=(123A, ["2010-01-01 14:30:00","2010-01-01 15:30:00")) conflicts +with existing key (room, during)=(123A, ["2010-01-01 14:00:00","2010-01-01 15:00:00")). + +INSERT INTO room_reservation VALUES + ('123B', '[2010-01-01 14:30, 2010-01-01 15:30)'); +INSERT 0 1 +``` diff --git a/product_docs/docs/epas/16/reference/oracle_compatibility_reference/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx b/product_docs/docs/epas/16/reference/oracle_compatibility_reference/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx index 8d278f9e528..6680ad735e2 100644 --- a/product_docs/docs/epas/16/reference/oracle_compatibility_reference/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx +++ b/product_docs/docs/epas/16/reference/oracle_compatibility_reference/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/03_create_program.mdx @@ -63,7 +63,7 @@ EXEC program_action => 'BEGIN INSERT INTO my_log VALUES(current_timestamp); END;', enabled => TRUE, - comment => 'This program adds a row to the my_log table.'); + comments => 'This program adds a row to the my_log table.'); ``` `update_log` is a PL/SQL block that adds a row containing the current date and time to the `my_log` table. The program is enabled when the `CREATE_PROGRAM` procedure executes. diff --git a/product_docs/docs/epas/16/reference/oracle_compatibility_reference/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx b/product_docs/docs/epas/16/reference/oracle_compatibility_reference/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx index 43fc2d10e83..9cf4a6116ce 100644 --- a/product_docs/docs/epas/16/reference/oracle_compatibility_reference/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx +++ b/product_docs/docs/epas/16/reference/oracle_compatibility_reference/epas_compat_bip_guide/03_built-in_packages/15_dbms_scheduler/04_create_schedule.mdx @@ -51,7 +51,7 @@ This code fragment calls `CREATE_SCHEDULE` to create a schedule named `weeknight EXEC DBMS_SCHEDULER.CREATE_SCHEDULE ( schedule_name => 'weeknights_at_5', - start_date => '01-JUN-13 09:00:00.000000' + start_date => '01-JUN-13 09:00:00.000000', repeat_interval => 'FREQ=DAILY;BYDAY=MON,TUE,WED,THU,FRI;BYHOUR=17;', comments => 'This schedule executes each weeknight at 5:00'); ``` diff --git a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/01_numeric_types.mdx b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/01_numeric_types.mdx index c0c8d2b5793..2bdd2fbde95 100644 --- a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/01_numeric_types.mdx +++ b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/01_numeric_types.mdx @@ -6,26 +6,43 @@ legacyRedirectsGenerated: - "/edb-docs/d/edb-postgres-advanced-server/user-guides/database-compatibility-for-oracle-developers-guide/9.5/Database_Compatibility_for_Oracle_Developers_Guide.1.044.html" redirects: - /epas/latest/epas_compat_reference/02_the_sql_language/02_data_types/01_numeric_types/ #generated for docs/epas/reorg-role-use-case-mode +source: + url: https://www.postgresql.org/docs/current/datatype-numeric.html + timestamp: 2023-08-30 --- -Numeric types consist of four-byte integers, four-byte and eight-byte floating-point numbers, and fixed-precision decimals. The following table lists the available types. - -| Name | Storage size | Description | Range | -| ------------------- | ------------ | ---------------------------------------------------------------- | ------------------------------------------- | -| `BINARY_INTEGER` | 4 bytes | Signed integer, alias for `INTEGER` | -2,147,483,648 to +2,147,483,647 | -| `DOUBLE PRECISION` | 8 bytes | Variable-precision, inexact | 15 decimal digits precision | -| `INTEGER` | 4 bytes | Usual choice for integer | -2,147,483,648 to +2,147,483,647 | -| `NUMBER` | Variable | User-specified precision, exact | Up to 1000 digits of precision | -| `NUMBER(p [, s ] )` | Variable | Exact numeric of maximum precision, `p`, and optional scale, `s` | Up to 1000 digits of precision | -| `PLS_INTEGER` | 4 bytes | Signed integer, alias for `INTEGER` | -2,147,483,648 to +2,147,483,647 | -| `REAL` | 4 bytes | Variable-precision, inexact | 6 decimal digits precision | -| `ROWID` | 8 bytes | Signed 8 bit integer. | -9223372036854775808 to 9223372036854775807 | +| Data type | Native | Alias | Description | +| ------------------- | ------ | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `SMALLINT` | ✅ | | Small-range integer, 2 bytes storage, -32768 to +32767 range | +| `INTEGER` | ✅ | | Usual choice for integer, 4 bytes storage, -2147483648 to +2147483647 range | +| `BINARY_INTEGER` | | ✅ | Alias for `INTEGER` | +| `BIGINT` | ✅ | | Large-range integer, 8 bytes storage, -9223372036854775808 to +9223372036854775807 range | | +| `PLS_INTEGER` | | ✅ | Alias for `INTEGER` | +| `DECIMAL` | ✅ | | User-specified precision, exact; variable storage; up to 131072 digits before the decimal point up to 16383 digits after the decimal point range | +| `NUMERIC` | ✅ | | User-specified precision, exact; variable storage, up to 131072 digits before the decimal point; up to 16383 digits after the decimal point range | +| `NUMBER` | | ✅ | Alias for native numeric | +| `NUMBER(p [, s ] )` | | ✅ | Alias of native numeric with exact numeric of maximum precision, `p`, and optional scale, `s`; variable storage, p to 1000 digits of precision | +| `REAL` | ✅ | | Variable-precision, inexact; 4 bytes storage; 6 decimal digits precision range | +| `DOUBLE PRECISION` | ✅ | | Variable-precision, inexact; 8 bytes storage; 15 decimal digits precision range | +| `BINARY FLOAT` | | ✅ | Alias for native `DOUBLE PRECISION` | +| `SMALLSERIAL` | ✅ | | Small autoincrementing integer, 2 bytes storage, 1 to 32767 range | +| `SERIAL` | ✅ | | Autoincrementing integer, 4 bytes storage, 1 to 2147483647 range | +| `BIGSERIAL` | ✅ | | Large autoincrementing integer, 8 bytes storage, 1 to 9223372036854775807 range | +| `ROWID` | | | Custom type for emulating Oracle ROWID, signed 8 bit integer; 8 bytes storage; -9223372036854775808 to 9223372036854775807 range (see [Migration Handbook](/migrating/oracle/oracle_epas_comparison/database_features/#data-types)) | + +## Overview + +Numeric types consist of four-byte integers, four-byte and eight-byte floating-point numbers, and fixed-precision decimals. + +The syntax of constants for the numeric types is described in [Constants](https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS) in the PostgreSQL documentation. The numeric types have a full set of corresponding arithmetic operators and functions. Refer to [Functions and Operators](../03_functions_and_operators) for more information. The following sections describe the types in detail. ## Integer types -The `BINARY_INTEGER`, `INTEGER`, `PLS_INTEGER`, and `ROWID` types store whole numbers (without fractional components) as specified in the numeric types table. Attempts to store values outside of the allowed range result in an error. +The `BIGINT`, `BINARY_INTEGER`, `INTEGER`, `PLS_INTEGER`, `SMALLINT` and `ROWID` types store whole numbers (without fractional components) as specified in the numeric types table. Attempts to store values outside of the allowed range result in an error. + +The type `INTEGER` is the common choice, as it offers the best balance between range, storage size, and performance. The `SMALLINT` type is generally only used if disk space is at a premium. The `BIGINT` type is designed to be used when the range of the `INTEGER` type is insufficient. ## Arbitrary precision numbers @@ -49,6 +66,36 @@ Specifying `NUMBER` without any precision or scale creates a column in which you If the precision or scale of a value is greater than the declared precision or scale of a column, the system attempts to round the value. If the value can't be rounded to satisfy the declared limits, an error occurs. +Numeric values are physically stored without any extra leading or trailing zeroes. Thus, the declared precision and scale of a column are maximums, not fixed allocations. (In this sense the `NUMBER` type is more akin to `VARCHAR(N)` than to `CHAR(N)`.) The actual storage requirement is two bytes for each group of four decimal digits, plus three to eight bytes overhead. + +In addition to ordinary numeric values, the `NUMBER` type allows the special value NaN, meaning “not-a-number”. Any operation on NaN yields another NaN. When writing this value as a constant in an SQL command, you must put quotes around it, for example U`PDATE table SET x = 'NaN'`. On input, the string `NaN` is recognized in a case-insensitive manner. + +!!!Note +In most implementations of the “not-a-number” concept, `NaN` is not considered equal to any other numeric value (including `NaN`). In order to allow numeric values to be sorted and used in tree-based indexes, PostgreS treats `NaN` values as equal, and greater than all non-`NaN` values. +!!! + +The types `DECIMAL` and `NUMBER` are equivalent. Both types are part of the SQL standard. + +When rounding values, the `NUMBER` type rounds ties away from zero, while (on most machines) the `REAL` and `DOUBLE PRECISION` types round ties to the nearest even number. For example: + +```SQL +SELECT x, + round(x::numeric) AS num_round, + round(x::double precision) AS dbl_round +FROM generate_series(-3.5, 3.5, 1) as x; + x | num_round | dbl_round +------+-----------+----------- + -3.5 | -4 | -4 + -2.5 | -3 | -2 + -1.5 | -2 | -2 + -0.5 | -1 | -0 + 0.5 | 1 | 0 + 1.5 | 2 | 2 + 2.5 | 3 | 2 + 3.5 | 4 | 4 +(8 rows) +``` + ## Floating-point types The data types `REAL` and `DOUBLE PRECISION` are *inexact*, variable-precision numeric types. In practice, these types are usually implementations of IEEE Standard 754 for Binary Floating-Point Arithmetic (single and double precision, respectively), to the extent that the underlying processor, operating system, and compiler support it. @@ -63,4 +110,58 @@ Inexact means that some values can't be converted exactly to the internal format On most platforms, the `REAL` type has a range of at least `1E-37` to `1E+37` with a precision of at least six decimal digits. The `DOUBLE PRECISION` type typically has a range of around `1E-307` to `1E+308` with a precision of at least 15 digits. Values that are too large or too small cause an error. Rounding might occur if the precision of an input number is too high. Numbers too close to zero that you can't represent as distinct from zero cause an underflow error. +In addition to ordinary numeric values, the floating-point types have several special values: + + +- `Infinity` +- `-Infinity` +- `NaN` + +These represent the IEEE 754 special values “infinity”, “negative infinity”, and “not-a-number”, respectively. (On a machine whose floating-point arithmetic does not follow IEEE 754, these values will probably not work as expected.) When writing these values as constants in an SQL command, you must put quotes around them, for example `UPDATE table SET x = '-Infinity'`. On input, these strings are recognized in a case-insensitive manner. + +!!!Note +IEEE754 specifies that NaN should not compare equal to any other floating-point value (including `NaN`). In order to allow floating-point values to be sorted and used in tree-based indexes, Postgres treats `NaN` values as equal, and greater than all non-`NaN` values. +!!! + EDB Postgres Advanced Server also supports the SQL standard notations `FLOAT` and `FLOAT(p)` for specifying inexact numeric types. Here, `p` specifies the minimum acceptable precision in binary digits. EDB Postgres Advanced Server accepts `FLOAT(1)` to `FLOAT(24)` as selecting the `REAL` type and `FLOAT(25)` to `FLOAT(53)` as selecting `DOUBLE PRECISION`. Values of `p` outside the allowed range draw an error. `FLOAT` with no precision specified is taken to mean `DOUBLE PRECISION`. + + +!!!Note +The assumption that real and double precision have exactly 24 and 53 bits in the mantissa respectively is correct for IEEE-standard floating point implementations. On non-IEEE platforms it might be off a little, but for simplicity the same ranges of `p` are used on all platforms. +!!! + +## Serial types + +!!!Note +This section describes a PostgreSQL-specific way to create an autoincrementing column. Another way is to use the SQL-standard identity column feature, described in [CREATE TABLE](https://www.postgresql.org/docs/11/sql-createtable.html). +!!! + +The data types `SMALLSERIAL`, `SERIAL` and `BIGSERIAL` are not true types, but merely a notational convenience for creating unique identifier columns (similar to the `AUTO_INCREMENT` property supported by some other databases). In the current implementation, specifying: + +```sql +CREATE TABLE tablename ( + colname SERIAL +); +``` + +is equivalent to specifying: + +``` +CREATE SEQUENCE tablename_colname_seq AS integer; +CREATE TABLE tablename ( + colname integer NOT NULL DEFAULT nextval('tablename_colname_seq') +); +ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname; +``` + +Thus, we have created an integer column and arranged for its default values to be assigned from a sequence generator. A `NOT NULL` constraint is applied to ensure that a null value cannot be inserted. (In most cases you would also want to attach a `UNIQUE` or `PRIMARY KEY` constraint to prevent duplicate values from being inserted by accident, but this is not automatic.) Lastly, the sequence is marked as “owned by” the column, so that it will be dropped if the column or table is dropped. + +!!!Note +Because `SMALLSERIAL`, `SERIAL` and `BIGSERIAL` are implemented using sequences, there may be "holes" or gaps in the sequence of values which appears in the column, even if no rows are ever deleted. A value allocated from the sequence is still "used up" even if a row containing that value is never successfully inserted into the table column. This may happen, for example, if the inserting transaction rolls back. See [`nextval()`](https://www.postgresql.org/docs/11/functions-sequence.html) for details. +!!! + +To insert the next value of the sequence into the serial column, specify that the serial column should be assigned its default value. This can be done either by excluding the column from the list of columns in the INSERT statement, or through the use of the `DEFAULT` key word. + +The type names `SERIAL` and `SERIAL4` are equivalent: both create integer columns. The type names `BIGSERIAL` and `SERIAL8` work the same way, except that they create a bigint column. `BIGSERIAL` should be used if you anticipate the use of more than 2147483648 identifiers (2 to the 31st power)over the lifetime of the table. The type names `SMALLSERIAL` and `SERIAL2` also work the same way, except that they create a `SMALLINT` column. + +The sequence created for a `SERIAL` column is automatically dropped when the owning column is dropped. You can drop the sequence without dropping the column, but this will force removal of the column default expression. \ No newline at end of file diff --git a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/02_character_types.mdx b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/02_character_types.mdx index 1a0746f45ac..0fec7533eec 100644 --- a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/02_character_types.mdx +++ b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/02_character_types.mdx @@ -2,57 +2,93 @@ title: "Character types" redirects: - /epas/latest/epas_compat_reference/02_the_sql_language/02_data_types/02_character_types/ #generated for docs/epas/reorg-role-use-case-mode +source: + url: https://www.postgresql.org/docs/current/datatype-numeric.html + timestamp: 2023-09-07 --- -The following table lists the general-purpose character types available in EDB Postgres Advanced Server. +| Name | Native | Alias | Description | +| ------------------------ | --------- | ------ | ----------------------------------------------------------------------------------------------------- | +| `CHAR[(n)]` | ✅ | | Fixed-length character string, blank-padded to the size specified by `n` | +| `CHARACTER[(n)]` | ✅ | | Fixed-length character string, blank-padded to the size specified by `n` | +| `CHARACTER VARYING[(n)]` | ✅ | | Variable-length character string, with limit | +| `CLOB` | | | Custom type for emulating Oracle CLOB, large variable-length up to 1 GB (see [Migration Handbook](/migrating/oracle/oracle_epas_comparison/database_features/#data-types)) | +| `LONG` | | ✅ | Alias for `TEXT` | +| `NCHAR[(n)]` | | ✅ | Alias for `CHARACTER` | +| `NVARCHAR[(n)]` | | ✅ | Alias for `CHARACTER VARYING` | +| `NVARCHAR2[(n)]` | | ✅ | Alias for `CHARACTER VARYING` | +| `STRING` | | ✅ | Alias for `VARCHAR2` | +| `TEXT` | ✅ | | Variable-length character string, unlimited | +| `VARCHAR[(n)]` | ✅ | | Variable-length character string, with limit (considered deprecated, but supported for compatibility) | +| `VARCHAR2[(n)]` | | ✅ | Alias for `CHARACTER VARYING` | -| Name | Description | -| -------------- | ----------------------------------------------------------------------------------------------------- | -| `CHAR[(n)]` | Fixed-length character string, blank-padded to the size specified by `n` | -| `CLOB` | Large variable-length up to 1 GB | -| `LONG` | Variable unlimited length. | -| `NVARCHAR(n)` | Variable-length national character string, with limit | -| `NVARCHAR2(n)` | Variable-length national character string, with limit | -| `STRING` | Alias for `VARCHAR2` | -| `VARCHAR(n)` | Variable-length character string, with limit (considered deprecated, but supported for compatibility) | -| `VARCHAR2(n)` | Variable-length character string, with limit | -Where `n` is a positive integer, these types can store strings up to `n` characters in length. An attempt to assign a value that exceeds the length of `n` results in an error, unless the excess characters are all spaces. In this case, the string is truncated to the maximum length. +## Overview -The storage requirement for data of these types is the actual string plus 1 byte if the string is less than 127 bytes or 4 bytes if the string is 127 bytes or greater. In the case of `CHAR`, the padding also requires storage. Long strings are compressed by the system automatically, so the physical requirement on disk might be less. Long values are stored in background tables so they don't interfere with rapid access to the shorter column values. +SQL defines two primary character types: `CHARACTER VARYING(n)` and `CHARACTER(n)`, where `n` is a positive integer. These types can store strings up to `n` characters in length. If you don't specify a value for `n`, `n` defaults to `1`. Assigning a value that exceeds the length of `n` results in an error unless the excess characters are all spaces. In this case, the string is truncated to the maximum length. If the string to be stored is shorter than `n`, values of type `CHARACTER` are space-padded to the specified width (`n`) and are stored and displayed that way; values of type `CHARACTER VARYING` simply store the shorter string. -The database character set determines the character set used to store textual values. +If you explicitly cast a value to `CHARACTER VARYING(n)` or `CHARACTER(n)`, an over-length value is truncated to n characters without raising an error. -`CHAR` +The notations `VARCHAR(n)` and `CHAR(n)` are aliases for `CHARACTER VARYING(n)` and `CHARACTER(n)`, respectively. If specified, the length must be greater than zero and cannot exceed 10485760. `CHARACTER` without a length specifier is equivalent to `CHARACTER(1)`. If `CHARACTER VARYING` is used without a length specifier, the type accepts strings of any size. The latter is a PostgreSQL extension. - If you don't specify a value for `n`, `n` defaults to `1`. If the string to assign is shorter than `n`, values of type `CHAR` are space-padded to the specified width (`n`) and are stored and displayed that way. +In addition, PostgreSQL provides the `TEXT` type, which stores strings of any length. Although the type T$XT is not in the SQL standard, several other SQL database management systems have it as well. - Padding spaces are treated as semantically insignificant. That is, trailing spaces are disregarded when comparing two values of type `CHAR`, and they are removed when converting a `CHAR` value to one of the other string types. +Values of type `CHARACTER` are physically padded with spaces to the specified width n, and are stored and displayed that way. However, trailing spaces are treated as semantically insignificant and disregarded when comparing two values of type `CHARACTER`. In collations where whitespace is significant, this behavior can produce unexpected results; for example `SELECT 'a '::CHAR(2) collate "C" < E'a\n'::CHAR(2)` returns true, even though C locale would consider a space to be greater than a newline. Trailing spaces are removed when converting a `CHARACTER` value to one of the other string types. Note that trailing spaces are semantically significant in `CHARACTER VARYING` and `TEXT` values, and when using pattern matching, that is `LIKE` and regular expressions. - If you explicitly cast an over-length value to a `CHAR(n)` type, the value is truncated to `n` characters without raising an error (as specified by the SQL standard). +The characters that can be stored in any of these data types are determined by the database character set, which is selected when the database is created. Regardless of the specific character set, the character with code zero (sometimes called `NUL`) can't be stored. For more information refer to [Character Set Support](https://www.postgresql.org/docs/current/multibyte.html). -```sql -VARCHAR, VARCHAR2, NVARCHAR and NVARCHAR2 -``` +The storage requirement for a short string (up to 126 bytes) is 1 byte plus the actual string, which includes the space padding in the case of `CHARACTER`. Longer strings have 4 bytes of overhead instead of 1. Long strings are compressed by the system automatically, so the physical requirement on disk might be less. Very long values are also stored in background tables so that they do not interfere with rapid access to shorter column values. In any case, the longest possible character string that can be stored is about 1 GB. (The maximum value that is allowed for n in the data type declaration is less than that. It wouldn't be useful to change this because with multibyte character encodings the number of characters and bytes can be quite different. If you desire to store long strings with no specific upper limit, use `TEXT` or `CHARACTER VARYING` without a length specifier, rather than making up an arbitrary length limit.) - If the string to assign is shorter than `n`, values of type `VARCHAR`, `VARCHAR2`, `NVARCHAR`, and `NVARCHAR2` store the shorter string without padding. +!!!Tip +There is no performance difference among these three types, apart from increased storage space when using the blank-padded type, and a few extra CPU cycles to check the length when storing into a length-constrained column. While `CHARACTER(n)` has performance advantages in some other database systems, there is no such advantage in PostgreSQL; in fact CHARACTER(n) is usually the slowest of the three because of its additional storage costs. In most situations `TEXT` or `CHARACTER VARYING` should be used instead. -!!! Note -The trailing spaces are semantically significant in `VARCHAR` values. +Refer to the [Postgres documentation on string constances](https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS) for information about the syntax of string literals and [functions and operators](https://www.postgresql.org/docs/current/functions.html) for information about available operators and functions. !!! - If you explicitly cast a value to a `VARCHAR` type, an over-length value is truncated to `n` characters without raising an error (as specified by the SQL standard). +Example: Using the character types + +```sql +CREATE TABLE test1 (a character(4)); +INSERT INTO test1 VALUES ('ok'); +SELECT a, char_length(a) FROM test1; -- (1) + + a | char_length +------+------------- + ok | 2 + + +CREATE TABLE test2 (b varchar(5)); +INSERT INTO test2 VALUES ('ok'); +INSERT INTO test2 VALUES ('good '); +INSERT INTO test2 VALUES ('too long'); +ERROR: value too long for type character varying(5) +INSERT INTO test2 VALUES ('too long'::varchar(5)); -- explicit truncation +SELECT b, char_length(b) FROM test2; + + b | char_length +-------+------------- + ok | 2 + good | 5 + too l | 5 +``` + +There are two other fixed-length character types in PostgreSQL, shown in the following table. These are not intended for general-purpose use, only for use in the internal system catalogs. The `NAME` type is used to store identifiers. Its length is currently defined as 64 bytes (63 usable characters plus terminator) but should be referenced using the constant NAMEDATALEN in C source code. The length is set at compile time (and is therefore adjustable for special uses); the default maximum length might change in a future release. The type "CHAR" (note the quotes) is different from `CHAR(1)` in that it only uses one byte of storage, and therefore can store only a single ASCII character. It is used in the system catalogs as a simplistic enumeration type. + +## Special Character Types -`CLOB` +| Name | Storage Size | Description | +| ------ | ------------ | ----------- | +| "CHAR" | 1 byte | single-byte internal type | +| `NAME` | 64 bytes | internal type for object names | You can store a large character string in a `CLOB` type. `CLOB` is semantically equivalent to `VARCHAR2` except no length limit is specified. Generally, use a `CLOB` type if you don't know the maximum string length. The longest possible character string that you can store in a `CLOB` type is about 1 GB. - !!!Note - The `CLOB` data type is actually a `DOMAIN` based on the PostgreSQL `TEXT` data type. For information on a `DOMAIN`, see the [PostgreSQL core documentation](https://www.postgresql.org/docs/current/static/sql-createdomain.html). +!!!Note + The `CLOB` data type is actually a `DOMAIN` based on the PostgreSQL `TEXT` data type. For information on a `DOMAIN`, see the [PostgreSQL core documentation](https://www.postgresql.org/docs/current/static/sql-createdomain.html). Thus, use of the `CLOB` type is limited by what can be done for `TEXT`, such as a maximum size of approximately 1 GB. diff --git a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/03_binary_data.mdx b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/03_binary_data.mdx index e2606e4ec6e..575b115eb74 100644 --- a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/03_binary_data.mdx +++ b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/03_binary_data.mdx @@ -6,19 +6,81 @@ legacyRedirectsGenerated: - "/edb-docs/d/edb-postgres-advanced-server/user-guides/database-compatibility-for-oracle-developers-guide/9.5/Database_Compatibility_for_Oracle_Developers_Guide.1.045.html" redirects: - /epas/latest/epas_compat_reference/02_the_sql_language/02_data_types/03_binary_data/ #generated for docs/epas/reorg-role-use-case-mode +source: + url: https://www.postgresql.org/docs/current/datatype-binary.html + timestamp: 2023-07-11 --- -The following table shows data types that allow the storage of binary strings. +| Name | Native | Alias | Description | +| ----------- | ------ | ----- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| `BYTEA` | ✅ | | Variable-length binary string, 1 or 4 bytes plus the actual binary string. +| `BINARY` | | ✅ | Alias for `BYTEA`. Fixed-length binary string, with a length between 1 and 8300. | +| `BLOB` | | ✅ | Alias for `BYTEA`. Variable-length binary string, with a maximum size of 1 GB. The actual binary string plus 1 byte if the binary string is less than 127 bytes, or 4 bytes if the binary string is 127 bytes or greater | +| `VARBINARY` | | ✅ | Alias for `BYTEA`. Variable-length binary string, with a length between 1 and 8300. | -| Name | Storage size | Description | -| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------- | -| `BINARY` | The length of the binary string | Fixed-length binary string, with a length between 1 and 8300 | -| `BLOB` | The actual binary string plus 1 byte if the binary string is less than 127 bytes, or 4 bytes if the binary string is 127 bytes or greater | Variable-length binary string, with a maximum size of 1 GB | -| `VARBINARY` | The length of the binary string | Variable-length binary string, with a length between 1 and 8300 | +## Overview A binary string is a sequence of octets (or bytes). Binary strings are distinguished from characters strings by two characteristics: - Binary strings specifically allow storing octets of value zero and other "non-printable" octets (defined as octets outside the range 32 to 126). - Operations on binary strings process the actual bytes, whereas the encoding and processing of character strings depends on locale settings. + +The `BYTEA` type supports two formats for input and output: “hex” format and “escape” format. Both of these are always accepted on input. The output format depends on the configuration parameter bytea_output; the default is hex. + +### Hex format + +The hex format encodes binary data as two hexadecimal digits per byte, most significant nibble first. The entire string is preceded by the sequence \x (to distinguish it from the escape format). In some contexts, the initial backslash may need to be escaped by doubling it. For input, the hexadecimal digits can be either upper or lower case, and whitespace is permitted between digit pairs (but not within a digit pair or in the starting \x sequence). The hex format is compatible with a wide range of external applications and protocols, and it tends to be faster to convert than the escape format, so its use is preferred. + +Example: + +``` +SET bytea_output = 'hex'; + +SELECT '\xDEADBEEF'::bytea; + bytea +------------ + \xdeadbeef +``` + +### Escape format + +The “escape” format is the traditional PostgreSQL format for the bytea type. It takes the approach of representing a binary string as a sequence of ASCII characters, while converting those bytes that cannot be represented as an ASCII character into special escape sequences. If, from the point of view of the application, representing bytes as characters makes sense, then this representation can be convenient. But in practice it is usually confusing because it blurs the distinction between binary strings and character strings. Also, the escape mechanism can be unwieldy. Therefore, this format should probably be avoided for most new applications. + +When entering `BYTEA` values in escape format, octets of certain values *must* be escaped, while all octet values *can* be escaped. In general, to escape an octet, convert it into its three-digit octal value and precede it by a backslash. A backslash itself (octet decimal value 92) can alternatively be represented by double backslashes. The following table shows the characters that must be escaped, and gives the alternative escape sequences where applicable. + +| Decimal octet value | Description | Escaped input representation | Example | Hex representation | +| ---------------------- | ---------------------- | ---------------------------- | --------------- | ------------------ | +| 0 | zero octet | `'\000'` | `'\000'::bytea` | \x00 | +| 39 | single quote | `''''` or `'\047'` | `''''::bytea` | \x27 | +| 92 | backslash | `'\\'` or `'\134'` | `'\\'::bytea` | \x5c | +| 0 to 31 and 127 to 255 | “non-printable” octets | `'\xxx'` (octal value) | `'\001'::bytea` | \x01 | + +The requirement to escape non-printable octets varies depending on locale settings. In some instances you can leave them unescaped. + +The reason that single quotes must be doubled is that this is true for any string literal in an SQL command. The generic string-literal parser consumes the outermost single quotes and reduces any pair of single quotes to one data character. What the `BYTEA` input function sees is just one single quote, which it treats as a plain data character. However, the `BYTEA` input function treats backslashes as special, and the other behaviors shown in the table are implemented by that function. + +In some contexts, backslashes must be doubled compared to what is shown above, because the generic string-literal parser will also reduce pairs of backslashes to one data character. + +`BYTEA` octets are output in hex format by default. If you change bytea_output to escape, “non-printable” octets are converted to their equivalent three-digit octal value and preceded by one backslash. Most “printable” octets are output by their standard representation in the client character set, as shown in the following example: + +``` +SET bytea_output = 'escape'; + +SELECT 'abc \153\154\155 \052\251\124'::bytea; + bytea +---------------- + abc klm *\251T +``` + +The octet with decimal value 92 (backslash) is doubled in the output. The following table provides details: + +| Decimal octet value | Description | Escaped input representation | Example | Output result | +| ---------------------- | ---------------------- | ----------------------------------- | --------------- | ------------- | +| 92 | backslash | `\\` | `'\134'::bytea` | `\\` | +| 0 to 31 and 127 to 255 | “non-printable” octets | `'\xxx'` (octal value) | `'\001'::bytea` | `\001` | +| 32 to 126 | “printable” octets | client character set representation | `'\176'::bytea` | ~ | + +Depending on the front end to PostgreSQL you use, you might have additional work in terms of escaping and unescaping `BYTEA` strings. For example, you might also have to escape line feeds and carriage returns if your interface automatically translates these. + diff --git a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/04_date_time_types.mdx b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/04_date_time_types.mdx index 336ab2e82d3..e68d39329ef 100644 --- a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/04_date_time_types.mdx +++ b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/04_date_time_types.mdx @@ -6,21 +6,25 @@ legacyRedirectsGenerated: - "/edb-docs/d/edb-postgres-advanced-server/user-guides/database-compatibility-for-oracle-developers-guide/9.5/Database_Compatibility_for_Oracle_Developers_Guide.1.046.html" redirects: - /epas/latest/epas_compat_reference/02_the_sql_language/02_data_types/04_date_time_types/ #generated for docs/epas/reorg-role-use-case-mode +source: + url: https://www.postgresql.org/docs/current/datatype-datetime.html + timestamp: 2023-09-20 --- -The following discussion of the date/time types assumes that the configuration parameter `edb_redwood_date` is set to `TRUE` whenever a table is created or altered. -EDB Postgres Advanced Server supports the date/time types shown in the table. +| Name | Native | Alias | Description | +| -------------------------------- | -------| ----- | ---------------------------------------------------------------------------------------------- | +| `DATE` | ✅ | | Date and time, 8 bytes storage, 4713 BC to 5874897 AD range, and resolution 1 second. | +| `INTERVAL DAY TO SECOND [(p)]` | ✅ | | Period of time, 12 bytes storage, -178000000 years to 178000000 years range, and resolution 1 microsecond / 14 digits | +| `INTERVAL YEAR TO MONTH` | ✅ | | Period of time, 12 bytes storage, -178000000 years to 178000000 years range, and resolution 1 microsecond / 14 digits. | +| `TIMESTAMP [(p)]` | ✅ | | Date and time, 8 bytes storage, 4713 BC to 5874897 AD range, and resolution 1 microsecond. | +| `TIMESTAMP [(p)] WITH TIME ZONE` | ✅ | | Date and time with time zone, 8 bytes storage, 4713 BC to 5874897 AD range, and resolution 1 microsecond. | + +## Overview -| Name | Storage size | Description | Low value | High value | Resolution | -| -------------------------------- | ------------ | ---------------------------- | ---------------- | --------------- | ------------------------- | -| `DATE` | 8 bytes | Date and time | 4713 BC | 5874897 AD | 1 second | -| `INTERVAL DAY TO SECOND [(p)]` | 12 bytes | Period of time | -178000000 years | 178000000 years | 1 microsecond / 14 digits | -| `INTERVAL YEAR TO MONTH` | 12 bytes | Period of time | -178000000 years | 178000000 years | 1 microsecond / 14 digits | -| `TIMESTAMP [(p)]` | 8 bytes | Date and time | 4713 BC | 5874897 AD | 1 microsecond | -| `TIMESTAMP [(p)] WITH TIME ZONE` | 8 bytes | Date and time with time zone | 4713 BC | 5874897 AD | 1 microsecond | +The following discussion of the date/time types assumes that the configuration parameter `edb_redwood_date` is set to `TRUE` whenever a table is created or altered. When `DATE` appears as the data type of a column in the data definition language (DDL) commands `CREATE TABLE` or `ALTER TABLE`, it's translated to `TIMESTAMP` at the time the table definition is stored in the database. Thus, a time component is also stored in the column along with the date. @@ -59,33 +63,33 @@ The first variation supported by EDB Postgres Advanced Server is `INTERVAL DAY T `p` specifies the precision of the `second` field. -EDB Postgres Advanced Server interprets this value as as 1 day, 2 hours, 34 minutes, 5 seconds and 678 thousandths of a second: +EDB Postgres Advanced Server interprets the following value as as 1 day, 2 hours, 34 minutes, 5 seconds and 678 thousandths of a second: `INTERVAL '1 2:34:5.678' DAY TO SECOND(3)` -EDB Postgres Advanced Server interprets this value as 1 day and 23 hours: +EDB Postgres Advanced Server interprets the following value as 1 day and 23 hours: `INTERVAL '1 23' DAY TO HOUR` -EDB Postgres Advanced Server interprets this value as 2 hours and 34 minutes: +EDB Postgres Advanced Server interprets the following value as 2 hours and 34 minutes: `INTERVAL '2:34' HOUR TO MINUTE` -EDB Postgres Advanced Server interprets this value as 2 hours, 34 minutes, 56 seconds and 13 thousandths of a second. The fractional second is rounded up to 13 because of the specified precision. +EDB Postgres Advanced Server interprets the following value as 2 hours, 34 minutes, 56 seconds and 13 thousandths of a second. The fractional second is rounded up to 13 because of the specified precision. `INTERVAL '2:34:56.129' HOUR TO SECOND(2)` The second variation supported by EDB Postgres Advanced Server that's compatible with Oracle databases is `INTERVAL YEAR TO MONTH`. This variation stores a time interval in years and months. -EDB Postgres Advanced Server interprets this value as 12 years and 3 months: +EDB Postgres Advanced Server interprets the following value as 12 years and 3 months: `INTERVAL '12-3' YEAR TO MONTH` -EDB Postgres Advanced Server interprets this value as 12 years and 3 months: +EDB Postgres Advanced Server interprets the following value as 12 years and 3 months: `INTERVAL '456' YEAR(2)` -EDB Postgres Advanced Server interprets this value as 25 years: +EDB Postgres Advanced Server interprets the following value as 25 years: `INTERVAL '300' MONTH` @@ -148,6 +152,35 @@ This example shows a time stamp that follows the ISO 8601 standard: `1999-01-08 04:05:06` +### Special Values + +PostgreSQL supports several special date/time input values for convenience, as shown in the following table. The values `infinity` and `-infinity` are specially represented inside the system and are displayed unchanged; the others are simply notational shorthands that are converted to ordinary date/time values when read. (In particular, `now` and related strings are converted to a specific time value as soon as they are read.) All of these values must be enclosed in single quotes when used as constants in SQL commands. + +| Input String | Valid Types | Description | +| ------------ | --------------------- | ---------------------------------------------- | +| epoch | date, timestamp | 1970-01-01 00:00:00+00 (Unix system time zero) | +| infinity | date, timestamp | later than all other time stamps | +| -infinity | date, timestamp | earlier than all other time stamps | +| now | date, time, timestamp | current transaction's start time | +| today | date, timestamp | midnight (00:00) today | +| tomorrow | date, timestamp | midnight (00:00) tomorrow | +| yesterday | date, timestamp | midnight (00:00) yesterday | +| allballs | time | 00:00:00.00 UTC | + +The following SQL-compatible functions can also be used to obtain the current time value for the corresponding data type: + +`CURRENT_DATE` +`CURRENT_TIME` +`CURRENT_TIMESTAMP` +`LOCALTIME` +`LOCALTIMESTAMP` + +Note that these are SQL functions and are not recognized in data input strings. + +!!!Note +While the input strings `now`, `today`, `tomorrow`, and `yesterday` are fine to use in interactive SQL commands, they can have surprising behavior when the command is saved to be executed later, for example in prepared statements, views, and function definitions. The string can be converted to a specific time value that continues to be used long after it becomes stale. Use one of the SQL functions instead in such contexts. For example, `CURRENT_DATE + 1` is safer than `tomorrow::date`. +!!! + ## Date/time output The default output format of the date/time types is either: @@ -167,3 +200,128 @@ The following table shows examples of the output formats for the two styles: Red ## Internals EDB Postgres Advanced Server uses Julian dates for all date/time calculations. Julian dates correctly predict or calculate any date after 4713 BC based on the assumption that the length of the year is 365.2425 days. + +## Time Zones + +PostgreSQL uses the widely-used IANA (Olson) time zone database for information about historical time zone rules. For times in the future, the assumption is that the latest known rules for a given time zone will continue to be observed indefinitely far into the future. + +PostgreSQL endeavors to be compatible with the SQL standard definitions for typical usage. However, the SQL standard has an odd mix of date and time types and capabilities. Two obvious problems are: + +- Although the date type cannot have an associated time zone, the time type can. Time zones in the real world have little meaning unless associated with a date as well as a time, since the offset can vary through the year with daylight-saving time boundaries. + +- The default time zone is specified as a constant numeric offset from UTC. It is therefore impossible to adapt to daylight-saving time when doing date/time arithmetic across DST boundaries. + +To address these difficulties, we recommend using date/time types that contain both date and time when using time zones. We do not recommend using the type `time with time zone` (though it is supported by PostgreSQL for legacy applications and for compliance with the SQL standard). PostgreSQL assumes your local time zone for any type containing only date or time. + +All time zone-aware dates and times are stored internally in UTC. They are converted to local time in the zone specified by the `TimeZone` configuration parameter before being displayed to the client. + +PostgreSQL allows you to specify time zones in three different forms: + +- A full time zone name, for example America/New_York. The recognized time zone names are listed in the `pg_timezone_names` view. PostgreSQL uses the widely-used IANA time zone data for this purpose, so the same time zone names are also recognized by other software. + +- A time zone abbreviation, for example PST. Such a specification merely defines a particular offset from UTC, in contrast to full time zone names which can imply a set of daylight savings transition rules as well. The recognized abbreviations are listed in the `pg_timezone_abbrevs` view. You cannot set the configuration parameters `TimeZone` or `log_timezone` to a time zone abbreviation, but you can use abbreviations in date/time input values and with the `AT TIME ZONE` operator. + +- PostgreSQL also accepts POSIX-style time zone specifications. This option is not normally preferable to using a named time zone, but it may be necessary if no suitable IANA time zone entry is available. + +In short, this is the difference between abbreviations and full names: abbreviations represent a specific offset from UTC, whereas many of the full names imply a local daylight-savings time rule and so have two possible UTC offsets. As an example, 2014-06-04 12:00 America/New_York represents noon local time in New York, which for this particular date was Eastern Daylight Time (UTC-4). So 2014-06-04 12:00 EDT specifies that same time instant. But 2014-06-04 12:00 EST specifies noon Eastern Standard Time (UTC-5), regardless of whether daylight savings was nominally in effect on that date. + +To complicate matters, some jurisdictions have used the same time zone abbreviation to mean different UTC offsets at different times; for example, in Moscow MSK has meant UTC+3 in some years and UTC+4 in others. PostgreSQL interprets such abbreviations according to whatever they meant (or had most recently meant) on the specified date; but, as with the EST example above, this is not necessarily the same as local civil time on that date. + +In all cases, time zone names and abbreviations are recognized case-insensitively. (This is a change from PostgreSQL versions prior to 8.2, which were case-sensitive in some contexts but not others.) + +Neither time zone names nor abbreviations are hard-wired into the server; they are obtained from configuration files stored under `.../share/timezone/` and `.../share/timezonesets/` of the installation directory. + +The `TimeZone` configuration parameter can be set in the file `postgresql.conf`, or in any of the other standard ways using server configuration. There are also some special ways to set it: + +- The SQL command `SET TIME ZONE` sets the time zone for the session. This is an alternative spelling of `SET TIMEZONE TO` with a more SQL-spec-compatible syntax. + +- The `PGTZ` environment variable is used by libpq clients to send a `SET TIME ZONE` command to the server upon connection. + +## Interval Input + +Interval values can be written using the following verbose syntax: + +``` +[@] quantity unit [quantity unit...] [direction] +``` + +where `quantity` is a number (possibly signed); `unit` is `microsecond`, `millisecond`, `second`, `minute`, `hour`, `day`, `week`, `month`, `year`, `decade`, `century`, `millennium`, or abbreviations or plurals of these units; `direction` can be `ago` or empty. The at sign (@) is optional noise. The amounts of the different units are implicitly added with appropriate sign accounting. `ago` negates all the fields. This syntax is also used for interval output if `IntervalStyle` is set to `postgres_verbose`. + +Quantities of days, hours, minutes, and seconds can be specified without explicit unit markings. For example, '1 12:59:10' is read the same as '1 day 12 hours 59 min 10 sec'. Also, a combination of years and months can be specified with a dash; for example '200-10' is read the same as '200 years 10 months'. (These shorter forms are in fact the only ones allowed by the SQL standard, and are used for output when `IntervalStyle` is set to `sql_standard`.) + +Interval values can also be written as ISO 8601 time intervals, using either the “format with designators” of the standard's section 4.4.3.2 or the “alternative format” of section 4.4.3.3. The format with designators looks like this: + +``` +P quantity unit [ quantity unit ...] [ T [ quantity unit ...]] +``` + +The string must start with a P, and may include a T that introduces the time-of-day units. The following table provides the available unit abbreviations. Units may be omitted, and may be specified in any order, but units smaller than a day must appear after T. In particular, the meaning of M depends on whether it is before or after T. + +| Abbreviation | Meaning | +| ------------ | ------------------------- | +| Y | Years | +| M | Months (in the date part) | +| W | Weeks | +| D | Days | +| H | Hours | +| M | Minutes | +| S | Seconds | + +In the alternative format: + +``` +P [ years-months-days ] [ T hours:minutes:seconds ] +``` + +the string must begin with P, and a T separates the date and time parts of the interval. The values are given as numbers similar to ISO 8601 dates. + +When writing an interval constant with a fields specification, or when assigning a string to an interval column that was defined with a fields specification, the interpretation of unmarked quantities depends on the fields. For example `INTERVAL '1' YEAR` is read as 1 year, whereas `INTERVAL '1'` means 1 second. Also, field values “to the right” of the least significant field allowed by the fields specification are silently discarded. For example, writing `INTERVAL '1 day 2:03:04' HOUR TO MINUTE` results in dropping the seconds field, but not the day field. + +According to the SQL standard all fields of an interval value must have the same sign, so a leading negative sign applies to all fields; for example, the negative sign in the interval literal '-1 2:03:04' applies to both the days and hour/minute/second parts. PostgreSQL allows the fields to have different signs, and traditionally treats each field in the textual representation as independently signed, so that the hour/minute/second part is considered positive in this example. If `IntervalStyle` is set to `sql_standard` then a leading sign is considered to apply to all fields (but only if no additional signs appear). Otherwise the traditional PostgreSQL interpretation is used. To avoid ambiguity, it's recommended to attach an explicit sign to each field if any field is negative. + +Field values can have fractional parts: for example, '1.5 weeks' or '01:02:03.45'. However, because interval internally stores only three integer units (months, days, microseconds), fractional units must be spilled to smaller units. Fractional parts of units greater than months are rounded to be an integer number of months, for example, '1.5 years' becomes '1 year 6 mons'. Fractional parts of weeks and days are computed to be an integer number of days and microseconds, assuming 30 days per month and 24 hours per day, e.g., '1.75 months' becomes 1 mon 22 days 12:00:00. Only seconds will ever be shown as fractional on output. + +The following table shows some examples of valid interval input. + +| Example | Description | +| -------------------------------------------------- | ------------------------------------------------------------------------------- | +| 1-2 | SQL standard format: 1 year 2 months | +| 3 4:05:06 | SQL standard format: 3 days 4 hours 5 minutes 6 seconds | +| 1 year 2 months 3 days 4 hours 5 minutes 6 seconds | Traditional Postgres format: 1 year 2 months 3 days 4 hours 5 minutes 6 seconds | +| P1Y2M3DT4H5M6S | ISO 8601 “format with designators”: same meaning as above | +| P0001-02-03T04:05:06 | ISO 8601 “alternative format”: same meaning as above | + +Internally, interval values are stored as months, days, and microseconds. This is done because the number of days in a month varies, and a day can have 23 or 25 hours if a daylight savings time adjustment is involved. The months and days fields are integers while the microseconds field can store fractional seconds. Because intervals are usually created from constant strings or timestamp subtraction, this storage method works well in most cases, but can cause unexpected results: + +``` +SELECT EXTRACT(hours from '80 minutes'::interval); + date_part +----------- + 1 + +SELECT EXTRACT(days from '80 hours'::interval); + date_part +----------- + 0 +``` + +Functions `justify_days` and `justify_hours` are available for adjusting days and hours that overflow their normal ranges. + +## Interval Output + +Using the command `SET intervalstyle` you can set the output format of the interval type to one of four styles: `sql_standard`, `postgres`, `postgres_verbose`, or `iso_8601`. The default is the `postgres` format. The table in this section shows examples of each output style. + +The `sql_standard` style produces output that conforms to the SQL standard's specification for interval literal strings, if the interval value meets the standard's restrictions (either year-month only or day-time only, with no mixing of positive and negative components). Otherwise the output looks like a standard year-month literal string followed by a day-time literal string, with explicit signs added to disambiguate mixed-sign intervals. + +The output of the `postgres` style matches the output of PostgreSQL releases prior to 8.4 when the `DateStyle` parameter was set to ISO. + +The output of the `postgres_verbose` style matches the output of PostgreSQL releases prior to 8.4 when the `DateStyle` parameter was set to non-ISO output. + +The output of the `iso_8601` style matches the “format with designators” described in the ISO 8601 standard. + +| Style Specification | Year-Month Interval | Day-Time Interval | Mixed Interval | +| ------------------- | ------------------- | ------------------------------ | ------------------------------------------------- | +| sql_standard | 1-2 | 3 4:05:06 | -1-2 +3 -4:05:06 | +| postgres | 1 year 2 mons | 3 days 04:05:06 | -1 year -2 mons +3 days -04:05:06 | +| postgres_verbose | @ 1 year 2 mons | @ 3 days 4 hours 5 mins 6 secs | @ 1 year 2 mons -3 days 4 hours 5 mins 6 secs ago | +| iso_8601 | P1Y2M | P3DT4H5M6S | P-1Y-2M3D​T-4H-5M-6S | diff --git a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/05_boolean_type.mdx b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/05_boolean_type.mdx index 7adc9606d65..4210d15a926 100644 --- a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/05_boolean_type.mdx +++ b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/05_boolean_type.mdx @@ -2,14 +2,40 @@ title: "Boolean types" redirects: - /epas/latest/epas_compat_reference/02_the_sql_language/02_data_types/05_boolean_type/ #generated for docs/epas/reorg-role-use-case-mode +source: + url: https://www.postgresql.org/docs/current/datatype-boolean.html + timestamp: 2023-09-20 --- +| Name | Native | Alias | Description | +| --------- | ------ | ----- | --------------------------------------------- | +| `BOOLEAN` | ✅ | | Logical Boolean (true/false), 1 byte storage. | + +## Overview + EDB Postgres Advanced Server provides the standard SQL type `BOOLEAN`. `BOOLEAN` can have one of only two states: `TRUE` or `FALSE`. A third state, `UNKNOWN`, is represented by the SQL `NULL` value. -| Name | Storage size | Description | -| --------- | ------------ | ---------------------------- | -| `BOOLEAN` | 1 byte | Logical Boolean (true/false) | +Literal values representing the `TRUE` state include 'TRUE', 'true', 'y', '1' and 't'. Literal values representing `FALSE` include 'FALSE', 'false', 'n', '0' and 'f'. There is no literal value for `UNKNOWN`; use `NULL`. + +The follow is an example using the boolean type: + +```sql +CREATE TABLE test1 (a boolean, b text); +INSERT INTO test1 VALUES (TRUE, 'sic est'); +INSERT INTO test1 VALUES (FALSE, 'non est'); +SELECT * FROM test1; + a | b +---+--------- + t | sic est + f | non est + +SELECT * FROM test1 WHERE a; + a | b +---+--------- + t | sic est + ``` + +Note that the parser automatically understands that `TRUE` and `FALSE` are of type boolean, but this is not so for `NULL` because that can have any type. So in some contexts you might have to cast `NULL` to `BOOLEAN` explicitly. -The valid literal value for representing the true state is `TRUE`. The valid literal for representing the false state is `FALSE`. diff --git a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/06_xml_type.mdx b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/06_xml_type.mdx index f99abce490d..6a5034bd3e1 100644 --- a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/06_xml_type.mdx +++ b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/06_xml_type.mdx @@ -6,10 +6,19 @@ legacyRedirectsGenerated: - "/edb-docs/d/edb-postgres-advanced-server/user-guides/database-compatibility-for-oracle-developers-guide/9.5/Database_Compatibility_for_Oracle_Developers_Guide.1.048.html" redirects: - /epas/latest/epas_compat_reference/02_the_sql_language/02_data_types/06_xml_type/ #generated for docs/epas/reorg-role-use-case-mode +source: + url: https://www.postgresql.org/docs/current/datatype-xml.html + timestamp: 2023-09-20 --- +| Name | Native | Alias | Description | +| -------------- | ------ | ----- | --------------------------------------------- | +| `XMLTYPE` | ✅ | | Data type used to store XML data. | + +## Overview + The `XMLTYPE` data type is used to store XML data. Its advantage over storing XML data in a character field is that it checks the input values for how well they're formed. Also, support functions perform type-safe operations on it. The XML type can store well-formed “documents,” as defined by the XML standard, as well as “content” fragments, which are defined by the production `XMLDecl? content` in the XML standard. Roughly, this means that content fragments can have more than one top-level element or character node. @@ -34,3 +43,73 @@ __OUTPUT__ Manual... (1 row) ``` + +## Creating XML Values + +To produce a value of type XML from character data, use the function `XMLPARSE`: + +``` +XMLPARSE ( { DOCUMENT | CONTENT } value) +``` + +Examples: + +``` +XMLPARSE (DOCUMENT 'Manual...') +XMLPARSE (CONTENT 'abcbarfoo') +``` + +While this is the only way to convert character strings into XML values according to the SQL standard, the PostgreSQL-specific syntaxes: + +``` +xml 'bar' +'bar'::xml +``` + +can also be used. + +The XML type does not validate input values against a document type declaration (DTD), even when the input value specifies a DTD. There is also currently no built-in support for validating against other XML schema languages such as XML Schema. + +The inverse operation, producing a character string value from XML, uses the function `XMLSERIALIZE`: + +``` +XMLSERIALIZE ( { DOCUMENT | CONTENT } value AS type [ [ NO ] INDENT ] ) +``` + +`type` can be `character`, `character varying`, or `text` (or an alias for one of those). Again, according to the SQL standard, this is the only way to convert between type XML and character types, but PostgreSQL also allows you to simply cast the value. + +The `INDENT` option causes the result to be pretty-printed, while `NO INDENT` (which is the default) just emits the original input string. Casting to a character type likewise produces the original string. + +When a character string value is cast to or from type XML without going through `XMLPARSE` or `XMLSERIALIZE`, respectively, the choice of `DOCUMENT` versus `CONTENT` is determined by the “XML option” session configuration parameter, which can be set using the standard command: + +``` +SET XML OPTION { DOCUMENT | CONTENT }; +``` + +or the more PostgreSQL-like syntax + +``` +SET xmloption TO { DOCUMENT | CONTENT }; +``` + +The default is `CONTENT`, so all forms of XML data are allowed. + +## Encoding Handling + +Take care when dealing with multiple character encodings on the client, server, and in the XML data passed through them. When using the text mode to pass queries to the server and query results to the client, which is the normal mode, PostgreSQL converts all character data passed between the client and the server and vice versa to the character encoding of the respective end. This includes string representations of XML values. This would ordinarily mean that encoding declarations contained in XML data can become invalid as the character data is converted to other encodings while traveling between client and server, because the embedded encoding declaration is not changed. To cope with this behavior, encoding declarations contained in character strings presented for input to the XML type are ignored, and content is assumed to be in the current server encoding. Consequently, for correct processing, character strings of XML data must be sent from the client in the current client encoding. It is the responsibility of the client to either convert documents to the current client encoding before sending them to the server, or to adjust the client encoding appropriately. On output, values of type XML will not have an encoding declaration, and clients should assume all data is in the current client encoding. + +When using binary mode to pass query parameters to the server and query results back to the client, no encoding conversion is performed, so the situation is different. In this case, an encoding declaration in the XML data will be observed, and if it is absent, the data will be assumed to be in UTF-8 (as required by the XML standard; note that PostgreSQL does not support UTF-16). On output, data will have an encoding declaration specifying the client encoding, unless the client encoding is UTF-8, in which case it will be omitted. + +Processing XML data with PostgreSQL will be less error-prone and more efficient if the XML data encoding, client encoding, and server encoding are the same. Since XML data is internally processed in UTF-8, computations will be most efficient if the server encoding is also UTF-8. + +!!!Note +Some XML-related functions may not work at all on non-ASCII data when the server encoding is not UTF-8. This is known to be an issue for `xmltable()` and `xpath()` in particular. +!!! + +## Accessing XML Values + +The XML data type is unusual because it does not provide any comparison operators. This is because there is no well-defined and universally useful comparison algorithm for XML data. One consequence of this is that you cannot retrieve rows by comparing an XML column against a search value. XML values should therefore typically be accompanied by a separate key field such as an ID. An alternative solution for comparing XML values is to convert them to character strings first, but note that character string comparison has little to do with a useful XML comparison method. + +Because there are no comparison operators for the XML data type, it is not possible to create an index directly on a column of this type. If speedy searches in XML data are desired, possible workarounds include casting the expression to a character string type and indexing that, or indexing an XPath expression. Of course, the actual query would have to be adjusted to search by the indexed expression. + +The text-search functionality in PostgreSQL can also be used to speed up full-document searches of XML data. The necessary preprocessing support is, however, not yet available in the PostgreSQL distribution. \ No newline at end of file diff --git a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/array_types.mdx b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/array_types.mdx new file mode 100644 index 00000000000..7177a033f84 --- /dev/null +++ b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/array_types.mdx @@ -0,0 +1,457 @@ +--- +title: "Array types" +--- + +| Name | Native | Alias | Description | +| -------------------------------------------------------------------- | ------ | ----- | --------------------------------------------- | +| `<*built-in* \| *user-defined* \| *enum* \| *composite* type>` []... | ✅ | | Variable-length multidimensional arrays. | + +## Overview + +PostgreSQL allows the columns of a table to be defined as variable-length multidimensional arrays. Arrays of any built-in or user-defined base type, enum type, or composite type can be created. Arrays of domains aren't yet supported. + +## Declaration of array types + +To illustrate the use of array types, we can create the following table: + +```sql +CREATE TABLE sal_emp ( + name text, + pay_by_quarter integer[], + schedule text[][] +); +``` + +As shown, an array data type is named by appending square brackets (`[]`) to the data type name of the array elements. The above command creates a table named `sal_emp` with a column of type text (`name`), a one-dimensional array of type integer (`pay_by_quarter`), which represents the employee's salary by quarter, and a two-dimensional array of text (`schedule`), which represents the employee's weekly schedule. + +The syntax for `CREATE TABLE` allows the exact size of arrays to be specified, for example: + +```sql +CREATE TABLE tictactoe ( + squares integer[3][3] +); +``` + +However, the current implementation ignores any supplied array size limits, that is, the behavior is the same as for arrays of unspecified length. + +The current implementation doesn't enforce the declared number of dimensions either. Arrays of a particular element type are all considered to be of the same type, regardless of size or number of dimensions. So, declaring the array size or number of dimensions in `CREATE TABLE` is simply documentation; it does not affect run-time behavior. + +An alternative syntax, which conforms to the SQL standard by using the keyword `ARRAY`, can be used for one-dimensional arrays. `pay_by_quarter` could have been defined as: + +```sql +pay_by_quarter integer ARRAY[4], +``` + +Or, if no array size is to be specified: + +```sql +pay_by_quarter integer ARRAY, +``` + +As before, however, PostgreSQL does not enforce the size restriction in any case. + +## Array value input + +To write an array value as a literal constant, enclose the element values within curly braces and separate them by commas. (If you know C, this is not unlike the C syntax for initializing structures.) You can put double quotes around any element value, and must do so if it contains commas or curly braces. (More details appear below.) Thus, the general format of an array constant is the following: + +```sql +'{ val1 delim val2 delim ... }' +``` + +where `delim` is the delimiter character for the type, as recorded in its `pg_type` entry. Among the standard data types provided in the PostgreSQL distribution, all use a comma (`,`), except for type box which uses a semicolon (`;`). Each `val` is either a constant of the array element type, or a subarray. An example of an array constant is: + +```sql +'{{1,2,3},{4,5,6},{7,8,9}}' +``` + +This constant is a two-dimensional, 3-by-3 array consisting of three subarrays of integers. + +To set an element of an array constant to NULL, write `NULL` for the element value. (Any upper- or lower-case variant of `NULL` will do.) If you want an actual string value "NULL", you must put double quotes around it. + +!!! Note + These kinds of array constants are actually only a special case of the generic type constants discussed in [Constants of Other Types](https://www.postgresql.org/docs/9.3/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS-GENERIC). The constant is initially treated as a string and passed to the array input conversion routine. An explicit type specification might be necessary. + +The following are `INSERT` statements: + +```sql +INSERT INTO sal_emp + VALUES ('Bill', + '{10000, 10000, 10000, 10000}', + '{{"meeting", "lunch"}, {"training", "presentation"}}'); + +INSERT INTO sal_emp + VALUES ('Carol', + '{20000, 25000, 25000, 25000}', + '{{"breakfast", "consulting"}, {"meeting", "lunch"}}'); +__OUTPUT__ +SELECT * FROM sal_emp; + name | pay_by_quarter | schedule +-------+---------------------------+------------------------------------------- + Bill | {10000,10000,10000,10000} | {{meeting,lunch},{training,presentation}} + Carol | {20000,25000,25000,25000} | {{breakfast,consulting},{meeting,lunch}} +(2 rows) +``` + +Multidimensional arrays must have matching extents for each dimension. A mismatch causes an error, for example: + +```sql +INSERT INTO sal_emp + VALUES ('Bill', + '{10000, 10000, 10000, 10000}', + '{{"meeting", "lunch"}, {"meeting"}}'); +ERROR: multidimensional arrays must have array expressions with matching dimensions +``` + +The `ARRAY` constructor syntax can also be used: + +```sql +INSERT INTO sal_emp + VALUES ('Bill', + ARRAY[10000, 10000, 10000, 10000], + ARRAY[['meeting', 'lunch'], ['training', 'presentation']]); + +INSERT INTO sal_emp + VALUES ('Carol', + ARRAY[20000, 25000, 25000, 25000], + ARRAY[['breakfast', 'consulting'], ['meeting', 'lunch']]); +``` + +Notice that the array elements are ordinary SQL constants or expressions; for instance, string literals are single quoted, instead of double quoted as they would be in an array literal. For more details on `ARRAY` constructor syntax, see [Array constructors](https://www.postgresql.org/docs/9.3/sql-expressions.html#SQL-SYNTAX-ARRAY-CONSTRUCTORS). + +## Accessing arrays + +Now, we can run some queries on the table. First, we show how to access a single element of an array. This query retrieves the names of the employees whose pay changed in the second quarter: + +```sql +SELECT name FROM sal_emp WHERE pay_by_quarter[1] <> pay_by_quarter[2]; +__OUTPUT__ + name +------- + Carol +(1 row) +``` + +The array subscript numbers are written within square brackets. By default PostgreSQL uses a one-based numbering convention for arrays, that is, an array of `n` elements starts with `array[1]` and ends with `array[n]`. + +This query retrieves the third quarter pay of all employees: + +```sql +SELECT pay_by_quarter[3] FROM sal_emp; +__OUTPUT__ + pay_by_quarter +---------------- + 10000 + 25000 +(2 rows) +``` + +We can also access arbitrary rectangular slices of an array, or subarrays. An array slice is denoted by writing `lower-bound:upper-bound` for one or more array dimensions. For example, this query retrieves the first item on Bill's schedule for the first two days of the week: + +```sql +SELECT schedule[1:2][1:1] FROM sal_emp WHERE name = 'Bill'; +__OUTPUT__ + schedule +------------------------ + {{meeting},{training}} +(1 row) +``` + +If any dimension is written as a slice, that is, contains a colon, then all dimensions are treated as slices. Any dimension that has only a single number (no colon) is treated as being from 1 to the number specified. For example, `[2]` is treated as `[1:2]`, as in this example: + +```sql +SELECT schedule[1:2][2] FROM sal_emp WHERE name = 'Bill'; +__OUTPUT__ + schedule +------------------------------------------- + {{meeting,lunch},{training,presentation}} +(1 row) +``` + +To avoid confusion with the non-slice case, it's best to use slice syntax for all dimensions, for example, `[1:2][1:1]`, not `[2][1:1]`. + +An array subscript expression returns null if either the array itself or any of the subscript expressions are null. Also, null is returned if a subscript is outside the array bounds (this case does not raise an error). For example, if `schedule` currently has the dimensions `[1:3][1:2]` then referencing `schedule[3][3]` yields `NULL`. Similarly, an array reference with the wrong number of subscripts yields a null rather than an error. + +An array slice expression likewise yields null if the array itself or any of the subscript expressions are null. However, in other cases such as selecting an array slice that is completely outside the current array bounds, a slice expression yields an empty (zero-dimensional) array instead of null. (This does not match non-slice behavior and is done for historical reasons.) If the requested slice partially overlaps the array bounds, then it is silently reduced to just the overlapping region instead of returning null. + +The current dimensions of any array value can be retrieved with the `array_dims` function: + +```sql +SELECT array_dims(schedule) FROM sal_emp WHERE name = 'Carol'; +__OUTPUT__ + array_dims +------------ + [1:2][1:2] +(1 row) +``` + +`array_dims` produces a text result, which is convenient for people to read but perhaps inconvenient for programs. Dimensions can also be retrieved with `array_upper` and `array_lower`, which return the upper and lower bound of a specified array dimension, respectively: + +```sql +SELECT array_upper(schedule, 1) FROM sal_emp WHERE name = 'Carol'; +__OUTPUT__ + array_upper +------------- + 2 +(1 row) +``` + +`array_length` returns the length of a specified array dimension: + +```sql +SELECT array_length(schedule, 1) FROM sal_emp WHERE name = 'Carol'; +__OUTPUT__ + array_length +-------------- + 2 +(1 row) +``` + +## Modifying arrays + +An array value can be replaced completely: + +```sql +UPDATE sal_emp SET pay_by_quarter = '{25000,25000,27000,27000}' + WHERE name = 'Carol'; +``` + +or using the `ARRAY` expression syntax: + +```sql +UPDATE sal_emp SET pay_by_quarter = ARRAY[25000,25000,27000,27000] + WHERE name = 'Carol'; +``` + +An array can also be updated at a single element: + +```sql +UPDATE sal_emp SET pay_by_quarter[4] = 15000 + WHERE name = 'Bill'; +``` + +or updated in a slice: + +```sql +UPDATE sal_emp SET pay_by_quarter[1:2] = '{27000,27000}' + WHERE name = 'Carol'; +``` + +A stored array value can be enlarged by assigning to elements not already present. Any positions between those previously present and the newly assigned elements are filled with nulls. For example, if array `myarray` currently has 4 elements, it will have six elements after an update that assigns to `myarray[6]`; `myarray[5]` will contain null. Currently, enlargement in this fashion is only allowed for one-dimensional arrays, not multidimensional arrays. + +Subscripted assignment allows creation of arrays that do not use one-based subscripts. For example one might assign to `myarray[-2:7]` to create an array with subscript values from -2 to 7. + +New array values can also be constructed using the concatenation operator, `||`: + +```sql +SELECT ARRAY[1,2] || ARRAY[3,4]; +__OUTPUT__ + ?column? +----------- + {1,2,3,4} +(1 row) +``` +```sql +SELECT ARRAY[5,6] || ARRAY[[1,2],[3,4]]; +__OUTPUT__ + ?column? +--------------------- + {{5,6},{1,2},{3,4}} +(1 row) +``` + +The concatenation operator allows a single element to be pushed onto the beginning or end of a one-dimensional array. It also accepts two `N`-dimensional arrays, or an `N`-dimensional and an `N+1`-dimensional array. + +When a single element is pushed onto either the beginning or end of a one-dimensional array, the result is an array with the same lower bound subscript as the array operand. For example: + +```sql +SELECT array_dims(1 || '[0:1]={2,3}'::int[]); +__OUTPUT__ + array_dims +------------ + [0:2] +(1 row) +``` +```sql +SELECT array_dims(ARRAY[1,2] || 3); +__OUTPUT__ + array_dims +------------ + [1:3] +(1 row) +``` + +When two arrays with an equal number of dimensions are concatenated, the result retains the lower bound subscript of the left-hand operand's outer dimension. The result is an array comprising every element of the left-hand operand followed by every element of the right-hand operand. For example: + +```sql +SELECT array_dims(ARRAY[1,2] || ARRAY[3,4,5]); +__OUTPUT__ + array_dims +------------ + [1:5] +(1 row) +``` +```sql +SELECT array_dims(ARRAY[[1,2],[3,4]] || ARRAY[[5,6],[7,8],[9,0]]); +__OUTPUT__ + array_dims +------------ + [1:5][1:2] +(1 row) +``` + +When an `N`-dimensional array is pushed onto the beginning or end of an `N+1`-dimensional array, the result is analogous to the element-array case above. Each `N`-dimensional sub-array is essentially an element of the `N+1`-dimensional array's outer dimension. For example: + +```sql +SELECT array_dims(ARRAY[1,2] || ARRAY[[3,4],[5,6]]); +__OUTPUT__ + array_dims +------------ + [1:3][1:2] +(1 row) +``` + +An array can also be constructed by using the functions `array_prepend`, `array_append`, or `array_cat`. The first two only support one-dimensional arrays, but `array_cat` supports multidimensional arrays. Some examples: + +```sql +SELECT array_prepend(1, ARRAY[2,3]); +__OUTPUT__ + array_prepend +--------------- + {1,2,3} +(1 row) +``` +```sql +SELECT array_append(ARRAY[1,2], 3); +__OUTPUT__ + array_append +-------------- + {1,2,3} +(1 row) +``` +```sql +SELECT array_cat(ARRAY[1,2], ARRAY[3,4]); +__OUTPUT__ + array_cat +----------- + {1,2,3,4} +(1 row) +``` +```sql +SELECT array_cat(ARRAY[[1,2],[3,4]], ARRAY[5,6]); +__OUTPUT__ + array_cat +--------------------- + {{1,2},{3,4},{5,6}} +(1 row) +``` +```sql +SELECT array_cat(ARRAY[5,6], ARRAY[[1,2],[3,4]]); +__OUTPUT__ + array_cat +--------------------- + {{5,6},{1,2},{3,4}} + ``` + +In simple cases, the concatenation operator discussed above is preferred over direct use of these functions. However, because the concatenation operator is overloaded to serve all three cases, there are situations where use of one of the functions is helpful to avoid ambiguity. For example consider: + +```sql +SELECT ARRAY[1, 2] || '{3, 4}'; -- the untyped literal is taken as an array +__OUTPUT__ + ?column? +----------- + {1,2,3,4} +``` +```sql +SELECT ARRAY[1, 2] || '7'; -- so is this one +__OUTPUT__ +ERROR: malformed array literal: "7" +``` +```sql +SELECT ARRAY[1, 2] || NULL; -- so is an undecorated NULL +__OUTPUT__ + ?column? +---------- + {1,2} +(1 row) +``` +```sql +SELECT array_append(ARRAY[1, 2], NULL); -- this might have been meant +__OUTPUT__ + array_append +-------------- + {1,2,NULL} +``` + +In the examples above, the parser sees an integer array on one side of the concatenation operator, and a constant of undetermined type on the other. The heuristic it uses to resolve the constant's type is to assume it's of the same type as the operator's other input — in this case, integer array. So the concatenation operator is presumed to represent `array_cat`, not `array_append`. When that's the wrong choice, it could be fixed by casting the constant to the array's element type; but explicit use of `array_append` might be a preferable solution. + +## Searching in arrays + +To search for a value in an array, each value must be checked. This can be done manually, if you know the size of the array. For example: + +```sql +SELECT * FROM sal_emp WHERE pay_by_quarter[1] = 10000 OR + pay_by_quarter[2] = 10000 OR + pay_by_quarter[3] = 10000 OR + pay_by_quarter[4] = 10000; +``` + +However, this quickly becomes tedious for large arrays, and is not helpful if the size of the array is unknown. An alternative method is described in [Row and Array Comparisons](https://www.postgresql.org/docs/9.3/functions-comparisons.html). The above query could be replaced by: + +```sql +SELECT * FROM sal_emp WHERE 10000 = ANY (pay_by_quarter); +``` + +In addition, you can find rows where the array has all values equal to 10000 with: + +```sql +SELECT * FROM sal_emp WHERE 10000 = ALL (pay_by_quarter); +``` + +Alternatively, the `generate_subscripts` function can be used. For example: + +```sql +SELECT * FROM + (SELECT pay_by_quarter, + generate_subscripts(pay_by_quarter, 1) AS s + FROM sal_emp) AS foo + WHERE pay_by_quarter[s] = 10000; +``` + +You can also search an array using the `&&` operator, which checks whether the left operand overlaps with the right operand. For instance: + +```sql +SELECT * FROM sal_emp WHERE pay_by_quarter && ARRAY[10000]; +``` + +!!! Note + Arrays are not sets; searching for specific array elements can be a sign of database misdesign. Consider using a separate table with a row for each item that would be an array element. This is easier to search, and is likely to scale better for a large number of elements. + +## Array input and output syntax + +The external text representation of an array value consists of items that are interpreted according to the I/O conversion rules for the array's element type, plus decoration that indicates the array structure. The decoration consists of curly braces (`{` and `}`) around the array value plus delimiter characters between adjacent items. The delimiter character is usually a comma (`,`) but can be something else: it is determined by the `typdelim` setting for the array's element type. Among the standard data types provided in the PostgreSQL distribution, all use a comma, except for type box, which uses a semicolon (`;`). In a multidimensional array, each dimension (row, plane, cube, etc.) gets its own level of curly braces, and delimiters must be written between adjacent curly-braced entities of the same level. + +The array output routine will put double quotes around element values if they are empty strings, contain curly braces, delimiter characters, double quotes, backslashes, or white space, or match the word `NULL`. Double quotes and backslashes embedded in element values will be backslash-escaped. For numeric data types it is safe to assume that double quotes will never appear, but for textual data types one should be prepared to cope with either the presence or absence of quotes. + +By default, the lower bound index value of an array's dimensions is set to one. To represent arrays with other lower bounds, the array subscript ranges can be specified explicitly before writing the array contents. This decoration consists of square brackets (`[]`) around each array dimension's lower and upper bounds, with a colon (`:`) delimiter character in between. The array dimension decoration is followed by an equal sign (`=`). For example: + +```sql +SELECT f1[1][-2][3] AS e1, f1[1][-1][5] AS e2 + FROM (SELECT '[1:1][-2:-1][3:5]={{{1,2,3},{4,5,6}}}'::int[] AS f1) AS ss; +__OUTPUT__ + e1 | e2 +----+---- + 1 | 6 +(1 row) +``` + +The array output routine includes explicit dimensions in its result only when there are one or more lower bounds different from one. + +If the value written for an element is `NULL` (in any case variant), the element is taken to be NULL. The presence of any quotes or backslashes disables this and allows the literal string value "NULL" to be entered. Also, for backward compatibility with pre-8.2 versions of PostgreSQL, the [`array_nulls`](https://www.postgresql.org/docs/9.3/runtime-config-compatible.html#GUC-ARRAY-NULLS) configuration parameter can be turned off to suppress recognition of `NULL` as a NULL. + +As shown previously, when writing an array value you can use double quotes around any individual array element. You must do so if the element value would otherwise confuse the array-value parser. For example, elements containing curly braces, commas (or the data type's delimiter character), double quotes, backslashes, or leading or trailing whitespace must be double-quoted. Empty strings and strings matching the word `NULL` must be quoted, too. To put a double quote or backslash in a quoted array element value, precede it with a backslash. Alternatively, you can avoid quotes and use backslash-escaping to protect all data characters that would otherwise be taken as array syntax. + +You can add whitespace before a left brace or after a right brace. You can also add whitespace before or after any individual item string. In all of these cases the whitespace will be ignored. However, whitespace within double-quoted elements, or surrounded on both sides by non-whitespace characters of an element, is not ignored. + +!!! Note + The `ARRAY` constructor syntax is often easier to work with than the array-literal syntax when writing array values in SQL commands. In `ARRAY`, individual element values are written the same way they would be written when not members of an array. + diff --git a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/composite_types.mdx b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/composite_types.mdx new file mode 100644 index 00000000000..f5a7f8f38e5 --- /dev/null +++ b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/composite_types.mdx @@ -0,0 +1,300 @@ +--- +title: "Composite types" +--- + +| Name | Native | Alias | Description | +| -------------------------------------------------------------------- | ------ | ----- | --------------------------------------------- | +| `CREATE TYPE AS (col1 data type, col2 datatype,..)` | ✅ | | Structure of a row or record. | + +## Overview + +A composite type represents the structure of a row or record; it is essentially just a list of field names and their data types. PostgreSQL allows composite types to be used in many of the same ways that simple types can be used. For example, a column of a table can be declared to be of a composite type. + +## Declaration of composite types + +Here are two simple examples of defining composite types: + +```sql +CREATE TYPE complex AS ( + r double precision, + i double precision +); + +CREATE TYPE inventory_item AS ( + name text, + supplier_id integer, + price numeric +); +``` + +The syntax is comparable to `CREATE TABLE`, except that only field names and types can be specified. No constraints (such as `NOT NULL`) can presently be included. The AS keyword is essential because without it, the system will think a different kind of `CREATE TYPE` command is meant, and you can get odd syntax errors. + +Having defined the types, we can use them to create tables: + +```sql +CREATE TABLE on_hand ( + item inventory_item, + count integer +); + +INSERT INTO on_hand VALUES (ROW('fuzzy dice', 42, 1.99), 1000); +``` + +or functions: + +```sql +CREATE FUNCTION price_extension(inventory_item, integer) RETURNS numeric +AS 'SELECT $1.price * $2' LANGUAGE SQL; + +SELECT price_extension(item, 10) FROM on_hand; +``` + +Whenever you create a table, a composite type is also automatically created, with the same name as the table, to represent the table's row type. For example, had we said: + +```sql +CREATE TABLE inventory_item ( + name text, + supplier_id integer REFERENCES suppliers, + price numeric CHECK (price > 0) +); +``` + +then the same `inventory_item` composite type shown above would come into being as a byproduct, and could be used just as above. However there is an important restriction of the current implementation: since no constraints are associated with a composite type, the constraints shown in the table definition do not apply to values of the composite type outside the table. (A partial workaround is to use domain types as members of composite types.) + +## Constructing composite values + +To write a composite value as a literal constant, enclose the field values in parentheses and separate them by commas. You can put double quotes around any field value, and must do so if it contains commas or parentheses. Therefore, the general format of a composite constant is the following: + +```sql +'( val1 , val2 , ... )' +``` + +An example is: + +```sql +'("fuzzy dice",42,1.99)' +``` + +which would be a valid value of the `inventory_item` type defined above. To make a field be NULL, write no characters at all in its position in the list. For example, this constant specifies a NULL third field: + +```sql +'("fuzzy dice",42,)' +``` + +If you want an empty string rather than NULL, write double quotes: + +```sql +'("",42,)' +``` + +Here the first field is a non-NULL empty string, the third is NULL. + +!!! Note + These constants are actually only a special case of the generic type constants discussed in [Constants of Other Types](https://www.postgresql.org/docs/9.3/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS-GENERIC). The constant is initially treated as a string and passed to the composite-type input conversion routine. An explicit type specification might be necessary to tell which type to convert the constant to. + +The `ROW` expression syntax can also be used to construct composite values. In most cases this is considerably simpler to use than the string-literal syntax since you don't have to worry about multiple layers of quoting. We already used this method above: + +```sql +ROW('fuzzy dice', 42, 1.99) +ROW('', 42, NULL) +``` + +The `ROW` keyword is actually optional as long as you have more than one field in the expression, so these can be simplified to: + +```sql +('fuzzy dice', 42, 1.99) +('', 42, NULL) +``` + +## Accessing composite types + +To access a field of a composite column, one writes a dot and the field name, much like selecting a field from a table name. In fact, it's so much like selecting from a table name that you often have to use parentheses to keep from confusing the parser. For example, you might try to select some subfields from our `on_hand` example table with something like: + +```sql +SELECT item.name FROM on_hand WHERE item.price > 9.99; +``` + +However, that doesn't work since the name item is taken to be a table name, not a column name of `on_hand`, per SQL syntax rules. You must write it like this: + +```sql +SELECT (item).name FROM on_hand WHERE (item).price > 9.99; +``` + +or if you need to use the table name as well (for instance in a multitable query), like this: + +```sql +SELECT (on_hand.item).name FROM on_hand WHERE (on_hand.item).price > 9.99; +``` + +Now the parenthesized object is correctly interpreted as a reference to the item column, and then the subfield can be selected from it. + +Similar syntactic issues apply whenever you select a field from a composite value. For instance, to select just one field from the result of a function that returns a composite value, you'd need to write something like: + +```sql +SELECT (my_func(...)).field FROM ... +``` + +Without the extra parentheses, this command generates a syntax error. + +## Modifying composite types + +Here are some examples of the proper syntax for inserting and updating composite columns. First, inserting or updating a whole column: + +```sql +INSERT INTO mytab (complex_col) VALUES((1.1,2.2)); + +UPDATE mytab SET complex_col = ROW(1.1,2.2) WHERE ...; +``` + +The first example omits `ROW`, the second uses it. It can be done either way. + +We can update an individual subfield of a composite column: + +```sql +UPDATE mytab SET complex_col.r = (complex_col).r + 1 WHERE ...; +``` + +Notice here that we don't need to (and indeed cannot) put parentheses around the column name appearing just after `SET`, but we do need parentheses when referencing the same column in the expression to the right of the equal sign. + +And we can specify subfields as targets for `INSERT`, too: + +```sql +INSERT INTO mytab (complex_col.r, complex_col.i) VALUES(1.1, 2.2); +``` + +Had we not supplied values for all the subfields of the column, the remaining subfields would have been filled with null values. + +## Using composite types in queries + +There are various special syntax rules and behaviors associated with composite types in queries. These rules provide useful shortcuts, but can be confusing if you don't know the logic behind them. + +In PostgreSQL, a reference to a table name (or alias) in a query is effectively a reference to the composite value of the table's current row. For example, if we had a table `inventory_item` as shown in [Declaration of composite types](#declaration-of-composite-types), we could write: + +```sql +SELECT c FROM inventory_item c; +``` + +This query produces a single composite-valued column, so we might get output like: + +```sql +__OUTPUT__ + c +------------------------ + ("fuzzy dice",42,1.99) +(1 row) +``` + +Simple names are matched to column names before table names, so this example works only because there is no column named `c` in the query's tables. + +The ordinary qualified-column-name syntax `table_name.column_name` can be understood as applying field selection to the composite value of the table's current row. For efficiency reasons, it's not actually implemented that way. + +When we write + +```sql +SELECT c.* FROM inventory_item c; +``` + +then, according to the SQL standard, we should get the contents of the table expanded into separate columns: + +```sql +__OUTPUT__ + name | supplier_id | price +------------+-------------+------- + fuzzy dice | 42 | 1.99 +(1 row) +``` + +as if the query were: + +```sql +SELECT c.name, c.supplier_id, c.price FROM inventory_item c; +``` + +PostgreSQL applies this expansion behavior to any composite-valued expression, although as shown in [Accessing composite types](#accessing-composite-types), you need to write parentheses around the value that `.*` is applied to whenever it's not a simple table name. For example, if `myfunc()` is a function returning a composite type with columns `a`, `b`, and `c`, then these two queries have the same result: + +```sql +SELECT (myfunc(x)).* FROM some_table; +SELECT (myfunc(x)).a, (myfunc(x)).b, (myfunc(x)).c FROM some_table; +``` + +!!! note Tip + PostgreSQL handles column expansion by actually transforming the first form into the second. So, in this example, `myfunc()` would get invoked three times per row with either syntax. If it's an expensive function you may wish to avoid that, which you can do with a query like: + + ```sql + SELECT (m).* FROM (SELECT myfunc(x) AS m FROM some_table OFFSET 0) ss; + ``` + + The `OFFSET 0` clause keeps the optimizer from "flattening" the sub-select to arrive at the form with multiple calls of `myfunc()`. + +The `composite_value.*` syntax results in column expansion of this kind when it appears at the top level of a `SELECT` output list, a `RETURNING` list in `INSERT`/`UPDATE`/`DELETE`, a `VALUES` clause, or a row constructor. In all other contexts (including when nested inside one of those constructs), attaching `.*` to a composite value does not change the value, since it means "all columns" and so the same composite value is produced again. For example, if `somefunc()` accepts a composite-valued argument, these queries are the same: + +```sql +SELECT somefunc(c.*) FROM inventory_item c; +SELECT somefunc(c) FROM inventory_item c; +``` + +In both cases, the current row of `inventory_item` is passed to the function as a single composite-valued argument. Even though `.*` does nothing in such cases, using it is good style, since it makes clear that a composite value is intended. In particular, the parser considers `c` in `c.*` to refer to a table name or alias, not to a column name, so that there is no ambiguity; whereas without `.*`, it is not clear whether `c` means a table name or a column name, and in fact the column-name interpretation is preferred if there is a column named `c`. + +Another example demonstrating these concepts is that all these queries mean the same thing: + +```sql +SELECT * FROM inventory_item c ORDER BY c; +SELECT * FROM inventory_item c ORDER BY c.*; +SELECT * FROM inventory_item c ORDER BY ROW(c.*); +``` + +All of these `ORDER BY` clauses specify the row's composite value. However, if `inventory_item` contained a column named `c`, the first case would be different from the others, as it would mean to sort by that column only. Given the column names previously shown, these queries are also equivalent to those above: + +```sql +SELECT * FROM inventory_item c ORDER BY ROW(c.name, c.supplier_id, c.price); +SELECT * FROM inventory_item c ORDER BY (c.name, c.supplier_id, c.price); +``` + +Another special syntactical behavior associated with composite values is that we can use functional notation for extracting a field of a composite value. The simple way to explain this is that the notations `field(table)` and `table.field` are interchangeable. For example, these queries are equivalent: + +```sql +SELECT c.name FROM inventory_item c WHERE c.price > 1000; +SELECT name(c) FROM inventory_item c WHERE price(c) > 1000; +``` + +Moreover, if we have a function that accepts a single argument of a composite type, we can call it with either notation. These queries are all equivalent: + +```sql +SELECT somefunc(c) FROM inventory_item c; +SELECT somefunc(c.*) FROM inventory_item c; +SELECT c.somefunc FROM inventory_item c; +``` + +This equivalence between functional notation and field notation makes it possible to use functions on composite types to implement "computed fields". An application using the last query above wouldn't need to be directly aware that `somefunc` isn't a real column of the table. + +!!! note Tip + Because of this behavior, it's unwise to give a function that takes a single composite-type argument the same name as any of the fields of that composite type. If there is ambiguity, the field-name interpretation is preferred, so that such a function could not be called without tricks. One way to force the function interpretation is to schema-qualify the function name, that is, write `schema.func(compositevalue)`. + +## Composite type input and output syntax + +The external text representation of a composite value consists of items that are interpreted according to the I/O conversion rules for the individual field types, plus decoration that indicates the composite structure. The decoration consists of parentheses (`(` and `)`) around the whole value, plus commas (`,`) between adjacent items. Whitespace outside the parentheses is ignored, but within the parentheses it is considered part of the field value, and might or might not be significant depending on the input conversion rules for the field data type. For example, in: + +```sql +'( 42)' +``` + +The whitespace is ignored if the field type is integer, but not if it is text. + +As shown previously, when writing a composite value you can write double quotes around any individual field value. You must do so if the field value would otherwise confuse the composite-value parser. In particular, fields containing parentheses, commas, double quotes, or backslashes must be double-quoted. To put a double quote or backslash in a quoted composite field value, precede it with a backslash. Also, a pair of double quotes within a double-quoted field value is taken to represent a double quote character, analogously to the rules for single quotes in SQL literal strings. Alternatively, you can avoid quoting and use backslash-escaping to protect all data characters that would otherwise be taken as composite syntax. + +A completely empty field value (no characters at all between the commas or parentheses) represents a NULL. To write a value that is an empty string rather than NULL, write `""`. + +The composite output routine puts double quotes around field values if they are empty strings or contain parentheses, commas, double quotes, backslashes, or white space. Doing so for white space is not essential, but aids legibility. Double quotes and backslashes embedded in field values are doubled. + +!!! Note + Remember that what you write in an SQL command is first interpreted as a string literal, and then as a composite. This doubles the number of backslashes you need (assuming escape string syntax is used). For example, to insert a text field containing a double quote and a backslash in a composite value, you'd need to write: + + ```sql + INSERT ... VALUES ('("\"\\")'); + ``` + + The string-literal processor removes one level of backslashes, so that what arrives at the composite-value parser looks like (`"\"\\"`). In turn, the string fed to the text data type's input routine becomes `"\`. If we were working with a data type whose input routine also treated backslashes specially, `bytea` for example, we might need as many as eight backslashes in the command to get one backslash into the stored composite field. Dollar quoting can be used to avoid the need to double backslashes. + +!!! note Tip + The `ROW` constructor syntax is usually easier to work with than the composite-literal syntax when writing composite values in SQL commands. In `ROW`, individual field values are written the same way they would be written when not members of a composite. + diff --git a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/enumerated_types.mdx b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/enumerated_types.mdx new file mode 100644 index 00000000000..96b83bcba1e --- /dev/null +++ b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/enumerated_types.mdx @@ -0,0 +1,32 @@ +--- +title: "Enumerated types" +--- + + +| Name | Native | Alias | Description | +| --------- | ------ | ----- | --------------------------------------------- | +| `ENUM` | ✅ | | Static, ordered set of values, 4 bytes storage, max length is limited by `NAMEDATALEN` setting into PostgreSQL. | + +## Example + +This example shows how to create `ENUM` types and use it: + +```sql +CREATE TYPE city AS ENUM('Pune','Mumbai','Chennai'); + +CREATE TABLE shops(name text, location city); + +INSERT INTO shops VALUES('Puma',`Mumbai` ); + +SELECT * FROM shops; +__OUTPUT__ + name | location +--------+----------- + Puma | Mumbai +``` + +`ENUM` types are case sensitive, and whitespace in `ENUM` types is also significant. + +The `ENUM` types and its labels are stored in `pg_enum` system catalog. + +For more information on enumerated data types, see [PostgreSQL docs](https://www.postgresql.org/docs/current/datatype-enum.html). \ No newline at end of file diff --git a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/geometric_types.mdx b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/geometric_types.mdx new file mode 100644 index 00000000000..3447d7e6b9b --- /dev/null +++ b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/geometric_types.mdx @@ -0,0 +1,20 @@ +--- +title: "Geometric types" +--- + +| Name | Native | Alias | Description | +| --------------- | -------| ----- | ---------------------------------------------------------------------------------------------- | +| `POINT` | ✅ | | Point on a plane, 16 bytes storage, represented as `(x,y)`. | +| `LINE` | ✅ | | Infinite line, 32 bytes storage, represented as `{A,B,C}`. | +| `LSEG` | ✅ | | Finite line segment, 32 bytes storage, represented as `((x1,y1),(x2,y2))`. | +| `BOX` | ✅ | | Rectangular box, 32 bytes storage, represented as `((x1,y1),(x2,y2))`. | +| `PATH` | ✅ | | Closed path (similar to polygon), 16 + 16n bytes storage, represented as `((x1,y1),...)`. | +| `PATH` | ✅ | | Open path, 16 + 16n bytes storage, represented as `[(x1,y1),...]`. | +| `POLYGON` | ✅ | | Polygon (similar to closed path), 40 + 16n bytes storage, represented as `((x1,y1),...)`. | +| `CIRCLE` | ✅ | | Circle, 24 bytes storage, represented as `<(x,y),r>` (center point and radius). | + +## Overview + +Geometric data types represent two-dimensional spatial objects. + +For more information on geometric data types, see [PostgreSQL docs](https://www.postgresql.org/docs/current/datatype-geometric.html). \ No newline at end of file diff --git a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/index.mdx b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/index.mdx index 802b04dfd0e..dd13602a7d1 100644 --- a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/index.mdx +++ b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/index.mdx @@ -9,6 +9,23 @@ legacyRedirectsGenerated: redirects: - /epas/latest/epas_compat_reference/02_the_sql_language/02_data_types/ #generated for docs/epas/reorg-role-use-case-mode - ../../../reference/sql_reference/02_the_sql_language/02_data_types +navigation: + - 01_numeric_types + - monetary_types + - 02_character_types + - 03_binary_data + - 04_date_time_types + - 05_boolean_type + - enumerated_types + - geometric_types + - network_address_types + - 06_xml_type + - array_types + - composite_types + - range_types + - object_identifier_types + - pseudo_types --- +EDB Postgres Advanced Server has the following data types. diff --git a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/monetary_types.mdx b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/monetary_types.mdx new file mode 100644 index 00000000000..928f51531e8 --- /dev/null +++ b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/monetary_types.mdx @@ -0,0 +1,32 @@ +--- +title: Monetary types +source: + url: https://www.postgresql.org/docs/current/datatype-money.html + timestamp: 2023-09-11 +--- + +| Data type | Native | Alias | Description | +| --------- | ------ | ------ | ------------------------------------------------------------------------------------- | +| `MONEY` | | ✅ | Currency amount, 8 byte storage, -92233720368547758.08 to +92233720368547758.07 range | + +## Overview + +The `MONEY` type stores a currency amount with a fixed fractional precision. The fractional precision is determined by the database's `lc_monetary` setting. The range assumes there are two fractional digits. Input is accepted in a variety of formats, including integer and floating-point literals, as well as typical currency formatting, such as '$1,000.00'. Output is generally in the latter form but depends on the locale. + +Since the output of this data type is locale-sensitive, it might not work to load money data into a database that has a different setting of `lc_monetary`. To avoid problems, before restoring a dump into a new database make sure `lc_monetary` has the same or equivalent value as in the database that was dumped. + +Values of `NUMERIC`, `INT`, and `BIGINT` data types can be cast to `MONEY`. Conversion from `REAL` and `DOUBLE PRECISION` data types can be done by casting to `NUMERIC` first, for example: + +```sql +SELECT '12.34'::float8::numeric::money; +``` + +However, this is not recommended. Floating point numbers shouldn't be used to handle money due to the potential for rounding errors. + +A money value can be cast to `NUMERIC` without loss of precision. Conversion to other types could potentially lose precision, and must also be done in two stages: + +```sql +SELECT '52093.89'::money::numeric::float8; +``` + +Division of a money value by an integer value is performed with truncation of the fractional part towards zero. To get a rounded result, divide by a floating-point value, or cast the money value to numeric before dividing and back to money afterwards. (The latter is preferable to avoid risking precision loss.) When a money value is divided by another money value, the result is double precision (that is, a pure number, not money); the currency units cancel each other out in the division. \ No newline at end of file diff --git a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/network_address_types.mdx b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/network_address_types.mdx new file mode 100644 index 00000000000..858c8f6a536 --- /dev/null +++ b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/network_address_types.mdx @@ -0,0 +1,18 @@ +--- +title: "Network address types" +--- + +| Name | Native | Alias | Description | +|-----------|--------|--------|-----------------------------------------------------------------------------------| +| `CIDR` | ✅ | | IPV4 and IPV6 networks, 7 or 19 bytes storage. | +| `INET` | ✅ | | IPV4 and IPV6 hosts and networks, 7 or 19 bytes storage. | +| `MACADDR` | ✅ | | MAC addresses, 6 bytes storage. | +| `MACADDR8`| ✅ | | MAC addresses (EUI-64 format), 8 bytes storage. | + +## Overview + +EDB Postgres Advanced Server offers data types to store IPV4, IPV6, and MAC addresses. + +These data types offer input error checking and specialized operators and functions. + +For more information on network address types, see [PostgreSQL docs](https://www.postgresql.org/docs/current/datatype-net-types.html). \ No newline at end of file diff --git a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/object_identifier_types.mdx b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/object_identifier_types.mdx new file mode 100644 index 00000000000..0059b2366af --- /dev/null +++ b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/object_identifier_types.mdx @@ -0,0 +1,63 @@ +--- +title: "Object identifier types" +--- + +| Data type | Native | Alias | Description | +| ------------------- | ------ | ----- | -------------------------------------- | +| `oid` | ✅ | | The numeric object identifier. | +| `regproc` | ✅ | | The name of the function. | +| `regprocedure`| ✅ | | The function with argument types. | +| `regoper` | ✅ | | The name of the operator. | +| `regoperator` | ✅ | | The operator with argument types. | +| `regclass` | ✅ | | The name of the relation. | +| `regtype` | ✅ | | The name of the data type. | +| `regconfig` | ✅ | | The text search configuration. | +| `regdictionary` | ✅ | | The text search dictionary. | + +## Overview + +Object identifiers (OIDs) are used internally by PostgreSQL as primary keys for various system tables. OIDs are not added to user-created tables, unless `WITH OIDS` is specified when the table is created, or the [`default_with_oids`](https://www.postgresql.org/docs/9.3/runtime-config-compatible.html#GUC-DEFAULT-WITH-OIDS) configuration variable is enabled. Type `oid` represents an object identifier. There are also several alias types for `oid`: `regproc`, `regprocedure`, `regoper`, `regoperator`, `regclass`, `regtype`, `regconfig`, and `regdictionary`. + +The `oid` type is currently implemented as an unsigned four-byte integer. Therefore, it is not large enough to provide database-wide uniqueness in large databases, or even in large individual tables. So, using a user-created table's OID column as a primary key is discouraged. OIDs are best used only for references to system tables. + +The `oid` type itself has few operations beyond comparison. It can be cast to integer, however, and then manipulated using the standard integer operators. Beware of possible signed-versus-unsigned confusion if you do this. + +The OID alias types have no operations of their own except for specialized input and output routines. These routines are able to accept and display symbolic names for system objects, rather than the raw numeric value that type `oid` would use. The alias types allow simplified lookup of OID values for objects. For example, to examine the pg_attribute rows related to a table` mytable`, one could write: + +```sql +SELECT * FROM pg_attribute WHERE attrelid = 'mytable'::regclass; +``` +rather than: + +```sql +SELECT * FROM pg_attribute + WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'mytable'); +``` + +While that doesn't look all that bad by itself, it's still oversimplified. A far more complicated sub-select would be needed to select the right OID if there are multiple tables named `mytable` in different schemas. The `regclass` input converter handles the table lookup according to the schema path setting, and so it does the "right thing" automatically. Similarly, casting a table's OID to `regclass` is handy for symbolic display of a numeric OID. + +The following table lists the available object identifier types: + +| Name | References | Description | Value example | +| ---- | ---------- | ----------- | ------------- | +| `oid` | Any | Numeric object identifier | `564182` | +| `regproc` | `pg_proc` | Function name | `sum` | +| `regprocedure` | `pg_proc ` | Function with argument types | `sum(int4)` | +| `regoper` | `pg_operator` | Operator name | `+` | +| `regoperator` | `pg_operator` | Operator with argument types | `*(integer,integer) or -(NONE,integer)` | +| `regclass` | `pg_class` | Relation name | `pg_type` | +| `regtype` | `pg_type` | Data type name | `integer` | +| `regconfig` | `pg_ts_config` | Text search configuration | `english` | +| `regdictionary` | `pg_ts_dict` | Text search dictionary | `simple` | + +All of the OID alias types accept schema-qualified names, and display schema-qualified names on output if the object can't be found in the current search path without being qualified. The `regproc` and `regoper` alias types accept only input names that are unique (not overloaded), so they are of limited use. For most uses, `regprocedure` or `regoperator` are more appropriate. For `regoperator`, unary operators are identified by writing `NONE` for the unused operand. + +An additional property of the OID alias types is the creation of dependencies. If a constant of one of these types appears in a stored expression (such as a column default expression or view), it creates a dependency on the referenced object. For example, if a column has a default expression `nextval('my_seq'::regclass)`, PostgreSQL understands that the default expression depends on the sequence `my_seq`. The system doesn't let the sequence be dropped without first removing the default expression. + +Another identifier type used by the system is `xid`, or transaction (abbreviated xact) identifier. This is the data type of the system columns `xmin` and `xmax`. Transaction identifiers are 32-bit quantities. + +A third identifier type used by the system is `cid`, or command identifier. This is the data type of the system columns `cmin` and `cmax`. Command identifiers are also 32-bit quantities. + +A final identifier type used by the system is `tid`, or tuple identifier (row identifier). This is the data type of the system column `ctid`. A tuple ID is a pair (block number, tuple index within block) that identifies the physical location of the row within its table. + +For more information on system columns, see the [PostgreSQL documentation](https://www.postgresql.org/docs/9.3/ddl-system-columns.html). diff --git a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/pseudo_types.mdx b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/pseudo_types.mdx new file mode 100644 index 00000000000..ddb1b1c5926 --- /dev/null +++ b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/pseudo_types.mdx @@ -0,0 +1,31 @@ +--- +title: "Pseudo-types" +--- + +| Data type | Native | Alias | Description | +| ------------------- | ------ | ----- | -------------------------------------- | +| `any` | ✅ | | Indicates that a function accepts any input data type. | +| `anyelement` | ✅ | | Indicates that a function accepts any data type. For more information, see [Polymorphic types](https://www.postgresql.org/docs/9.3/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC) in the PostgreSQL documentation. | +| `anyarray` | ✅ | | Indicates that a function accepts any array data type. For more information, see [Polymorphic types](https://www.postgresql.org/docs/9.3/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC) in the PostgreSQL documentation. | +| `anynonarray` | ✅ | | Indicates that a function accepts any non-array data type. For more information, see [Polymorphic types](https://www.postgresql.org/docs/9.3/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC) in the PostgreSQL documentation. | +| `anyenum` | ✅ | | Indicates that a function accepts any enum data type. For more information, see [Polymorphic types](https://www.postgresql.org/docs/9.3/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC) and [Enumerated types](https://www.postgresql.org/docs/9.3/datatype-enum.html) in the PostgreSQL documentation. | +| `anyrange` | ✅ | | Indicates that a function accepts any range data type. For more information, see [Polymorphic types](https://www.postgresql.org/docs/9.3/extend-type-system.html#EXTEND-TYPES-POLYMORPHIC) and [Range types](https://www.postgresql.org/docs/9.3/rangetypes.html) in the PostgreSQL documentation. | +| `cstring` | ✅ | | Indicates that a function accepts or returns a null-terminated C string. | +| `internal` | ✅ | | Indicates that a function accepts or returns a server-internal data type. | +| `language_handler` | ✅ | | A procedural language call handler is declared to return `language_handler`. | +| `fdw_handler` | ✅ | | A foreign-data wrapper handler is declared to return `fdw_handler`. | +| `record` | ✅ | | Identifies a function taking or returning an unspecified row type. | +| `trigger` | ✅ | | A trigger function is declared to return trigger. | +| `event_trigger` | ✅ | | An event trigger function is declared to return `event_trigger`. | +| `void` | ✅ | | Indicates that a function returns no value. | +| `opaque` | ✅ | | An obsolete type name that formerly served all the above purposes. | + +## Overview + +The PostgreSQL type system contains a number of special-purpose entries that are collectively called pseudo-types. A pseudo-type cannot be used as a column data type, but it can be used to declare a function's argument or result type. Each of the available pseudo-types is useful in situations where a function's behavior does not correspond to simply taking or returning a value of a specific SQL data type. + +Functions coded in C (whether built-in or dynamically loaded) can be declared to accept or return any of these pseudo data types. It is up to the function author to ensure that the function will behave safely when a pseudo-type is used as an argument type. + +Functions coded in procedural languages can use pseudo-types only as allowed by their implementation languages. At present most procedural languages forbid use of a pseudo-type as an argument type, and allow only void and record as a result type (plus trigger or event_trigger when the function is used as a trigger or event trigger). Some also support polymorphic functions using the types `anyelement`, `anyarray`, `anynonarray`, `anyenum`, and `anyrange`. + +The `internal` pseudo-type is used to declare functions that are meant only to be called internally by the database system, and not by direct invocation in an SQL query. If a function has at least one internal-type argument then it cannot be called from SQL. To preserve the type safety of this restriction it is important to follow this coding rule: do not create any function that is declared to return `internal` unless it has at least one internal argument. diff --git a/product_docs/docs/epas/16/reference/sql_reference/02_data_types/range_types.mdx b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/range_types.mdx new file mode 100644 index 00000000000..fcdd2bb4e13 --- /dev/null +++ b/product_docs/docs/epas/16/reference/sql_reference/02_data_types/range_types.mdx @@ -0,0 +1,223 @@ +--- +title: "Range types" +--- + +| Name | Native | Alias | Description | +| ----------- | ------ | ----- | --------------------------------------- | +| `int4range` | ✅ | | Range of `integer`. | +| `int8range` | ✅ | | Range of `bigint`. | +| `numrange` | ✅ | | Range of `numeric`. | +| `tsrange` | ✅ | | Range of `timestamp without time zone`. | +| `tstzrange` | ✅ | | Range of `timestamp with time zone`. | +| `daterange` | ✅ | | Range of `date`. | + + +## Overview + +Range types are data types representing a range of values of some element type (called the range's subtype). For instance, ranges of `timestamp` might be used to represent the ranges of time that a meeting room is reserved. In this case the data type is `tsrange` (short for timestamp range), and `timestamp` is the subtype. The subtype must have a total order so that it is well-defined whether element values are within, before, or after a range of values. + +Range types are useful because they represent many element values in a single range value, and because concepts such as overlapping ranges can be expressed clearly. The use of time and date ranges for scheduling purposes is the clearest example; but price ranges, measurement ranges from an instrument, and so forth can also be useful. + +## Built-in range types + +PostgreSQL comes with the following built-in range types: + +- `int4range` — Range of `integer` +- `int8range` — Range of `bigint` +- `numrange` — Range of `numeric` +- `tsrange` — Range of `timestamp without time zone` +- `tstzrange` — Range of `timestamp with time zone` +- `daterange` — Range of `date` + +In addition, you can define your own range types. See the [PostgreSQL documentation](https://www.postgresql.org/docs/9.3/sql-createtype.html), for more information. + +## Examples + +```sql +CREATE TABLE reservation (room int, during tsrange); +INSERT INTO reservation VALUES + (1108, '[2010-01-01 14:30, 2010-01-01 15:30)'); + +-- Containment +SELECT int4range(10, 20) @> 3; + +-- Overlaps +SELECT numrange(11.1, 22.2) && numrange(20.0, 30.0); + +-- Extract the upper bound +SELECT upper(int8range(15, 25)); + +-- Compute the intersection +SELECT int4range(10, 20) * int4range(15, 25); + +-- Is the range empty? +SELECT isempty(numrange(1, 5)); +``` + +## Inclusive and exclusive bounds + +Every non-empty range has two bounds, the lower bound and the upper bound. All points between these values are included in the range. An inclusive bound means that the boundary point itself is included in the range as well, while an exclusive bound means that the boundary point isn't included in the range. + +In the text form of a range, an inclusive lower bound is represented by "`[`" while an exclusive lower bound is represented by "`(`". Likewise, an inclusive upper bound is represented by "`]`", while an exclusive upper bound is represented by "`)`". + +The functions `lower_inc` and `upper_inc` test the inclusivity of the lower and upper bounds of a range value, respectively. + +## Infinite (unbounded) ranges + +The lower bound of a range can be omitted, meaning that all points less than the upper bound are included in the range. Likewise, if the upper bound of the range is omitted, then all points greater than the lower bound are included in the range. If both lower and upper bounds are omitted, all values of the element type are considered to be in the range. + +Omitting the lower or upper bound is equivalent to considering that the lower bound is "minus infinity", or the upper bound is "plus infinity", respectively. But note that these infinite values are never values of the range's element type, and can never be part of the range. So there is no such thing as an inclusive infinite bound — if you try to write one, it automatically is converted to an exclusive bound. + +Also, some element types have a notion of "infinity", but that is just another value so far as the range type mechanisms are concerned. For example, in timestamp ranges, `[today,]` means the same thing as `[today,)`. But `[today,infinity]` means something different from `[today,infinity)` — the latter excludes the special timestamp value infinity. + +The functions `lower_inf` and `upper_inf` test for infinite lower and upper bounds of a range, respectively. + +## Range input/output + +The input for a range value must follow one of the following patterns: + +```sql +(lower-bound,upper-bound) +(lower-bound,upper-bound] +[lower-bound,upper-bound) +[lower-bound,upper-bound] +empty +``` + +The parentheses or brackets indicate whether the lower and upper bounds are exclusive or inclusive, as described previously. Notice that the final pattern is empty, which represents an empty range (a range that contains no points). + +The lower-bound may be either a string that is valid input for the subtype, or empty to indicate no lower bound. Likewise, upper-bound may be either a string that is valid input for the subtype, or empty to indicate no upper bound. + +Each bound value can be quoted using double quotes (`"`). This is necessary if the bound value contains parentheses, brackets, commas, double quotes, or backslashes, since these characters would otherwise be taken as part of the range syntax. To put a double quote or backslash in a quoted bound value, precede it with a backslash. Also, a pair of double quotes within a double-quoted bound value is taken to represent a double quote character, analogously to the rules for single quotes in SQL literal strings. Alternatively, you can avoid quoting and use backslash-escaping to protect all data characters that would otherwise be taken as range syntax. Also, to write a bound value that is an empty string, write `""`, since writing nothing means an infinite bound. + +Whitespace is allowed before and after the range value, but any whitespace between the parentheses or brackets is taken as part of the lower or upper bound value. Depending on the element type, it might or might not be significant. + +Examples: + +```sql +-- includes 3, does not include 7, and does include all points in between +SELECT '[3,7)'::int4range; + +-- does not include either 3 or 7, but includes all points in between +SELECT '(3,7)'::int4range; + +-- includes only the single point 4 +SELECT '[4,4]'::int4range; + +-- includes no points (and will be normalized to 'empty') +SELECT '[4,4)'::int4range; +``` + +## Constructing ranges + +Each range type has a constructor function with the same name as the range type. Using the constructor function is frequently more convenient than writing a range literal constant, since it avoids the need for extra quoting of the bound values. The constructor function accepts two or three arguments. The two-argument form constructs a range in standard form (lower bound inclusive, upper bound exclusive), while the three-argument form constructs a range with bounds of the form specified by the third argument. The third argument must be one of the strings "`()`", "`(]`", "`[)`", or "`[]`". For example: + +```sql +-- The full form is: lower bound, upper bound, and text argument indicating +-- inclusivity/exclusivity of bounds. +SELECT numrange(1.0, 14.0, '(]'); + +-- If the third argument is omitted, '[)' is assumed. +SELECT numrange(1.0, 14.0); + +-- Although '(]' is specified here, on display the value will be converted to +-- canonical form, since int8range is a discrete range type (see below). +SELECT int8range(1, 14, '(]'); + +-- Using NULL for either bound causes the range to be unbounded on that side. +SELECT numrange(NULL, 2.2); +``` +## Discrete range types + +A discrete range is one whose element type has a well-defined "step", such as integer or date. In these types two elements can be said to be adjacent, when there are no valid values between them. This contrasts with continuous ranges, where it's always (or almost always) possible to identify other element values between two given values. For example, a range over the `numeric` type is continuous, as is a range over `timestamp`. Even though timestamp has limited precision, and so could theoretically be treated as discrete, it's better to consider it continuous since the step size is normally not of interest. + +Another way to think about a discrete range type is that there is a clear idea of a "next" or "previous" value for each element value. Knowing that, it is possible to convert between inclusive and exclusive representations of a range's bounds, by choosing the next or previous element value instead of the one originally given. For example, in an integer range type `[4,8]` and `(3,9)` denote the same set of values; but this would not be so for a range over numeric. + +A discrete range type should have a *canonicalization* function that is aware of the desired step size for the element type. The canonicalization function is charged with converting equivalent values of the range type to have identical representations, in particular consistently inclusive or exclusive bounds. If a canonicalization function is not specified, then ranges with different formatting are always treated as unequal, even though they might represent the same set of values in reality. + +The built-in range types `int4range`, `int8range`, and `daterange` all use a canonical form that includes the lower bound and excludes the upper bound; that is, `[)`. User-defined range types can use other conventions, however. + +## Defining new range types + +Users can define their own range types. The most common reason to do this is to use ranges over subtypes not provided among the built-in range types. For example, to define a new range type of subtype `float8`: + +```sql +CREATE TYPE floatrange AS RANGE ( + subtype = float8, + subtype_diff = float8mi +); + +SELECT '[1.234, 5.678]'::floatrange; +``` + +Because `float8` has no meaningful "step", we do not define a canonicalization function in this example. + +If the subtype is considered to have discrete rather than continuous values, the `CREATE TYPE` command should specify a `canonical` function. The canonicalization function takes an input range value, and must return an equivalent range value that may have different bounds and formatting. The canonical output for two ranges that represent the same set of values, for example the integer ranges `[1, 7]` and `[1, 8)`, must be identical. It doesn't matter which representation you choose to be the canonical one, so long as two equivalent values with different formattings are always mapped to the same value with the same formatting. In addition to adjusting the inclusive/exclusive bounds format, a canonicalization function might round off boundary values, in case the desired step size is larger than what the subtype is capable of storing. For instance, a range type over timestamp could be defined to have a step size of an hour, in which case the canonicalization function would need to round off bounds that weren't a multiple of an hour, or perhaps throw an error instead. + +Defining your own range type also allows you to specify a different subtype B-tree operator class or collation to use, so as to change the sort ordering that determines which values fall into a given range. + +In addition, any range type that is meant to be used with GiST or SP-GiST indexes should define a subtype difference, or `subtype_diff`, function. The index still works without `subtype_diff`, but it is likely to be considerably less efficient than if a difference function is provided. The subtype difference function takes two input values of the subtype, and returns their difference, for example, `X` minus `Y`, represented as a `float8` value. In our example above, the function that underlies the regular `float8` minus operator can be used; but for any other subtype, some type conversion would be necessary. Some creative thought about how to represent differences as numbers might be needed, too. To the greatest extent possible, the `subtype_diff` function should agree with the sort ordering implied by the selected operator class and collation; that is, its result should be positive whenever its first argument is greater than its second according to the sort ordering. + +See the [PostgreSQL documentation](https://www.postgresql.org/docs/9.3/sql-createtype.html) for more information about creating range types. + +## Indexing + +GiST and SP-GiST indexes can be created for table columns of range types. For instance, to create a GiST index: + +```sql +CREATE INDEX reservation_idx ON reservation USING gist (during); +``` + +A GiST or SP-GiST index can accelerate queries involving these range operators: `=`, `&&`, `<@`, `@>`, `<<`, `>>`, `-|-`, `&<`, and `&>`. + +In addition, B-tree and hash indexes can be created for table columns of range types. For these index types, basically the only useful range operation is equality. There is a B-tree sort ordering defined for range values, with corresponding `<` and `>` operators, but the ordering is rather arbitrary and not usually useful in the real world. Range types' B-tree and hash support is primarily meant to allow sorting and hashing internally in queries, rather than creation of actual indexes. + +## Constraints on ranges + +While `UNIQUE` is a natural constraint for scalar values, it is usually unsuitable for range types. Instead, an exclusion constraint is often more appropriate. Exclusion constraints allow the specification of constraints such as "non-overlapping" on a range type. For example: + +```sql +CREATE TABLE reservation ( + during tsrange, + EXCLUDE USING gist (during WITH &&) +); +``` + +That constraint prevents any overlapping values from existing in the table at the same time: + +```sql +INSERT INTO reservation VALUES + ('[2010-01-01 11:30, 2010-01-01 15:00)'); +INSERT 0 1 + +INSERT INTO reservation VALUES + ('[2010-01-01 14:45, 2010-01-01 15:45)'); +ERROR: conflicting key value violates exclusion constraint "reservation_during_excl" +DETAIL: Key (during)=(["2010-01-01 14:45:00","2010-01-01 15:45:00")) conflicts +with existing key (during)=(["2010-01-01 11:30:00","2010-01-01 15:00:00")). +``` + +You can use the [`btree_gist`](https://www.postgresql.org/docs/9.3/btree-gist.html) extension to define exclusion constraints on plain scalar data types, which can then be combined with range exclusions for maximum flexibility. For example, after `btree_gist` is installed, the following constraint will reject overlapping ranges only if the meeting room numbers are equal: + +```sql +CREATE EXTENSION btree_gist; +CREATE TABLE room_reservation ( + room text, + during tsrange, + EXCLUDE USING gist (room WITH =, during WITH &&) +); + +INSERT INTO room_reservation VALUES + ('123A', '[2010-01-01 14:00, 2010-01-01 15:00)'); +INSERT 0 1 + +INSERT INTO room_reservation VALUES + ('123A', '[2010-01-01 14:30, 2010-01-01 15:30)'); +ERROR: conflicting key value violates exclusion constraint "room_reservation_room_during_excl" +DETAIL: Key (room, during)=(123A, ["2010-01-01 14:30:00","2010-01-01 15:30:00")) conflicts +with existing key (room, during)=(123A, ["2010-01-01 14:00:00","2010-01-01 15:00:00")). + +INSERT INTO room_reservation VALUES + ('123B', '[2010-01-01 14:30, 2010-01-01 15:30)'); +INSERT 0 1 +``` diff --git a/product_docs/docs/language_pack/2/images/uninstall_lp1.png b/product_docs/docs/language_pack/4/images/uninstall_lp1.png similarity index 100% rename from product_docs/docs/language_pack/2/images/uninstall_lp1.png rename to product_docs/docs/language_pack/4/images/uninstall_lp1.png diff --git a/product_docs/docs/language_pack/2/images/uninstall_lp2.png b/product_docs/docs/language_pack/4/images/uninstall_lp2.png similarity index 100% rename from product_docs/docs/language_pack/2/images/uninstall_lp2.png rename to product_docs/docs/language_pack/4/images/uninstall_lp2.png diff --git a/product_docs/docs/language_pack/2/index.mdx b/product_docs/docs/language_pack/4/index.mdx similarity index 79% rename from product_docs/docs/language_pack/2/index.mdx rename to product_docs/docs/language_pack/4/index.mdx index ef21d3349fc..d3c32dd323b 100644 --- a/product_docs/docs/language_pack/2/index.mdx +++ b/product_docs/docs/language_pack/4/index.mdx @@ -18,15 +18,13 @@ Learn how to install, configure, and use the procedural languages (PL/Perl, PL/P Language pack installers install the PL/Perl, PL/Python, and PL/Tcl procedural languages that can be used with EDB Postgres Advanced Server and PostgreSQL. The language pack installers allow you to install Perl, Tcl/TK, and Python without installing supporting software from third-party vendors. -The Language Pack 2.0 installer includes: +The Language Pack 4.1 installer includes: -- Tcl with TK version 8.6 -- Perl version 5.26 -- Python version 3.7 +- Tcl with TK version 8.6.13 +- Perl version 5.38.2 +- Python version 3.11.7 -Language Pack 2.0 works with Postgres 14 and later. - -The Perl package contains the `cpan` package manager, and Python contains `pip` and `easy_install` package managers. There is no package manager for Tcl/TK. +Language Pack 4.1 contains the `cpan` package manager, and Python contains `pip` and `easy_install` package managers. There is no package manager for Tcl/TK. In previous Postgres releases, `plpython` was statically linked with ActiveState's python library. The Language Pack Installer dynamically links with our shared object for python. In ActiveState Linux installers for Python, there is no dynamic library. As a result of these changes, `plpython` no longer works with ActiveState installers. diff --git a/product_docs/docs/language_pack/2/installing/index.mdx b/product_docs/docs/language_pack/4/installing/index.mdx similarity index 100% rename from product_docs/docs/language_pack/2/installing/index.mdx rename to product_docs/docs/language_pack/4/installing/index.mdx diff --git a/product_docs/docs/language_pack/2/installing/linux.mdx b/product_docs/docs/language_pack/4/installing/linux.mdx similarity index 100% rename from product_docs/docs/language_pack/2/installing/linux.mdx rename to product_docs/docs/language_pack/4/installing/linux.mdx diff --git a/product_docs/docs/language_pack/2/installing/macos.mdx b/product_docs/docs/language_pack/4/installing/macos.mdx similarity index 100% rename from product_docs/docs/language_pack/2/installing/macos.mdx rename to product_docs/docs/language_pack/4/installing/macos.mdx diff --git a/product_docs/docs/language_pack/2/installing/windows.mdx b/product_docs/docs/language_pack/4/installing/windows.mdx similarity index 100% rename from product_docs/docs/language_pack/2/installing/windows.mdx rename to product_docs/docs/language_pack/4/installing/windows.mdx diff --git a/product_docs/docs/language_pack/2/uninstalling.mdx b/product_docs/docs/language_pack/4/uninstalling.mdx similarity index 100% rename from product_docs/docs/language_pack/2/uninstalling.mdx rename to product_docs/docs/language_pack/4/uninstalling.mdx diff --git a/product_docs/docs/language_pack/2/using.mdx b/product_docs/docs/language_pack/4/using.mdx similarity index 100% rename from product_docs/docs/language_pack/2/using.mdx rename to product_docs/docs/language_pack/4/using.mdx diff --git a/product_docs/docs/pgd/5/appusage/feature-compatibility.mdx b/product_docs/docs/pgd/5/appusage/feature-compatibility.mdx index 25b866430c6..765ed11a6ca 100644 --- a/product_docs/docs/pgd/5/appusage/feature-compatibility.mdx +++ b/product_docs/docs/pgd/5/appusage/feature-compatibility.mdx @@ -1,11 +1,11 @@ --- -title: Feature compatibiliy +title: Feature compatibility navTitle: Feature compatibility --- -## Server feature/Commit scope interoperability +## Server feature/commit scope interoperability -Not all server features work with all commit scopes. This table shows which interoperate: +Not all server features work with all commit scopes. This table shows the ones that interoperate. @@ -54,15 +54,15 @@ Not all server features work with all commit scopes. This table shows which inte #### Notes -⛔︎ : The Async column in the table represents PGD without a synchronous commit scope in use; Lag Control is not a synchronous commit scope, but a controlling commit scope and is therefore available with asynchronous operations. +⛔︎ : The Async column in the table represents PGD without a synchronous commit scope in use. Lag Control isn't a synchronous commit scope. It's a controlling commit scope and is therefore available with asynchronous operations. -❗️ : Attempting to use Group Commit and Transaction Streaming presents a warning suggesting that transaction streaming be disabled and the transaction appears to take place. In the background, group commit has been automatically disabled to allow the transaction to occur. +❗️ : Attempting to use Group Commit and Transaction Streaming presents a warning. The warning suggests that you disable transaction streaming, and the transaction appears to take place. In the background, Group Commit was disabled to allow the transaction to occur. -## Commit scope/Commit scope interoperability +## Commit scope/commit scope interoperability -Although you cannot mix commit scopes, you can [combine rules](../durability/commit-scope-rules/#combining-rules) with an `AND` operator. This table shows where commit scopes can be combined: +Although you can't mix commit scopes, you can [combine rules](../durability/commit-scope-rules/#combining-rules) with an `AND` operator. This table shows where commit scopes can be combined.
@@ -110,5 +110,5 @@ Although you cannot mix commit scopes, you can [combine rules](../durability/com #### Notes -Each commit scope implicity works with itself. +Each commit scope implicitly works with itself. diff --git a/product_docs/docs/pgd/5/architectures.mdx b/product_docs/docs/pgd/5/architectures.mdx index 210ac0bcf2f..4853b76a549 100644 --- a/product_docs/docs/pgd/5/architectures.mdx +++ b/product_docs/docs/pgd/5/architectures.mdx @@ -18,10 +18,10 @@ Postgres Distributed’s multi-master capability and its ability to achieve You can use EDB Postgres Distributed for architectures beyond the examples described here. Use-case-specific variations have been successfully deployed in production. However, these variations must undergo rigorous architecture review -first. Also, EDB’s standard deployment tool for Always On architectures, you must enable -Trusted Postgres Architect (TPA) -to support the variations before they can be supported in -production environments. +first. + +Always On architectures can be deployed using EDB’s standard deployment tool +Trusted Postgres Architect (TPA) or configured manually. ## Standard EDB Always On architectures diff --git a/product_docs/docs/pgd/5/consistency/conflicts.mdx b/product_docs/docs/pgd/5/consistency/conflicts.mdx index bff16b3b707..0c95109560d 100644 --- a/product_docs/docs/pgd/5/consistency/conflicts.mdx +++ b/product_docs/docs/pgd/5/consistency/conflicts.mdx @@ -680,7 +680,7 @@ This matrix helps you individuate the conflict types the conflict resolvers can
!!! note target_table_missing -This conflict type is not detectable on Community Postgresql, and if the target table is missing, it will cause an error and halt replication. +This conflict type isn't detected on community Postgresql. If the target table is missing, it causes an error and halts replication. EDB Postgres servers detect and handle missing target tables and can invoke the resolver. !!! diff --git a/product_docs/docs/pgd/5/durability/limitations.mdx b/product_docs/docs/pgd/5/durability/limitations.mdx index d1ee0319903..1e705fe3f53 100644 --- a/product_docs/docs/pgd/5/durability/limitations.mdx +++ b/product_docs/docs/pgd/5/durability/limitations.mdx @@ -6,10 +6,6 @@ The following limitations apply to the use of commit scopes and the various dura ## General limitations -- Replacing a node with its physical standby doesn't work for nodes that use - CAMO/Eager/Group Commit. We don't recommend combining physical standbys and EDB Postgres - Distributed, even if it's possible. - - [Legacy synchronous replication](legacy-sync) uses a mechanism for transaction confirmation different from the one used by CAMO, Eager, and Group Commit. The two aren't compatible, so don't use them together. Whenever you use Group Commit, CAMO @@ -26,7 +22,7 @@ The following limitations apply to the use of commit scopes and the various dura [Group Commit](group-commit) enables configurable synchronous commits over nodes in a group. If you use this feature, take the following limitations into account: -- Not all DDL can run when you use Group Commit. If you use unsupported DDL, a warning is logged, and the transactions commit scope is set to local. The only supported DDL operations are: +- Not all DDL can run when you use Group Commit. If you use unsupported DDL, a warning is logged, and the transactions commit scope is set to local. The only supported DDL operations are: - Nonconcurrent `CREATE INDEX` - Nonconcurrent `DROP INDEX` - Nonconcurrent `REINDEX` of an individual table or index @@ -34,6 +30,7 @@ nodes in a group. If you use this feature, take the following limitations into a - `ANALYZE` - `TRUNCATE` + - Explicit two-phase commit is not supported by Group Commit as it already uses two-phase commit. - Combining different commit decision options in the same transaction or diff --git a/product_docs/docs/pgd/5/index.mdx b/product_docs/docs/pgd/5/index.mdx index 953eb08d76e..f839471471a 100644 --- a/product_docs/docs/pgd/5/index.mdx +++ b/product_docs/docs/pgd/5/index.mdx @@ -47,7 +47,7 @@ navigation: --- -EDB Postgres Distributed (PGD) provides multi-master replication and data distribution with advanced conflict management, data-loss protection, and throughput up to 5X faster than native logical replication. It enables distributed Postgres clusters with high availability up to five 9s. +EDB Postgres Distributed (PGD) provides multi-master replication and data distribution with advanced conflict management, data-loss protection, and [throughput up to 5X faster than native logical replication](https://www.enterprisedb.com/blog/performance-improvements-edb-postgres-distributed). It enables distributed Postgres clusters with high availability up to five 9s. By default, EDB Postgres Distributed uses asynchronous replication, applying changes on the peer nodes only after the local commit. You can configure additional levels of synchronicity between different nodes, groups of nodes, or all nodes by configuring diff --git a/product_docs/docs/pgd/5/node_management/index.mdx b/product_docs/docs/pgd/5/node_management/index.mdx index 7dae078c09b..ab79a7f6c87 100644 --- a/product_docs/docs/pgd/5/node_management/index.mdx +++ b/product_docs/docs/pgd/5/node_management/index.mdx @@ -71,3 +71,8 @@ with nodes and subgroups. * [Node recovery](node_recovery) details the steps needed to bring a node back into service after a failure or scheduled downtime and the impact it has on the cluster as it returns. + +* [Maintenance commands through proxies](maintainance_with_proxies) shows how to send maintence commands to + nodes that you cannot directly access, such as those behind a proxy. + + diff --git a/product_docs/docs/pgd/5/node_management/maintainance_with_proxies.mdx b/product_docs/docs/pgd/5/node_management/maintainance_with_proxies.mdx new file mode 100644 index 00000000000..ef1648ff14a --- /dev/null +++ b/product_docs/docs/pgd/5/node_management/maintainance_with_proxies.mdx @@ -0,0 +1,169 @@ +--- +title: Maintenance commands through proxies +--- + +## Maintenance and performance + +As a general rule, you should never perform maintenance operations on a cluster's write leader. +Maintenance operations such as `VACUUM` can be quite disruptive to the smooth running of a busy server and often detrimental to workload performance. +Therefore it is best to run maintenance commands on any node in a group that isn't the write leader. +Generally, this requires you connect directly and issue the maintenance commands on the non-write leader nodes. +But there are situations where this is not possible. + +## Maintenance and proxies + +Proxies, by design, always connect to and send commands to the current write leader. +This would usually mean that you should not connect via a proxy to perform maintenance. +PGD clusters nodes are able to present a direct connection for psql and pgd cli clients which can be used for issuing maintenance commands to the server on those nodes. +But there are environment in which the PGD cluster is deployed where a proxy is the only way to access the cluster. + +For example, in BigAnimal, PGD clusters are locked down such that the only access to the database is through an instance of PGD Proxy. +This reduces the footprint of the cluster and makes it more secure but it does require a different way of sending maintenance requests to the cluster’s nodes. + +The technique outlined here is generally useful for despatching commands to specific nodes without being directly connected to that node’s server. + +## Maintenance commands + +When we refer to maintenance commands, we are referring to: + +* `VACUUM` +* Non-replicated DDL commands (which you may want to manually replicate) + + +## A note on node names + +We will be addressing the servers in the cluster by their PGD cluster node names. To get a list of node names in your cluster, use: + +```SQL +select node_name from bdr.node; +``` + +!!! Tip +More details about [`bdr.node`](/pgd/latest/reference/catalogs-visible#bdrnode) table are available in the reference section. +!!! + +This will list just the node names. If you need to know which group they are a member of, use: + +``` +select node_name, node_group_name from bdr.node_summary; +``` + +!!! Tip +More details about [`bdr.node_summary`](/pgd/latest/reference/catalogs-visible#bdrnode_summary) table are available in the reference section. +!!! + +## Finding the write leader + +If we assume that you are connected through the proxy, then you will be connected to the write leader. +Run `select node_name from bdr.local_node_summary` to see the name of the node: + +``` +select node_name from bdr.local_node_summary; +__OUTPUT__ + node_name +------------------ +node-two +(1 row) +``` + +This is the node you do **not** want to run your maintenance tasks on. + +``` +select * from bdr.node_group_routing_summary; +__OUTPUT__ + node_group_name | write_lead | previous_write_lead | read_nodes +-----------------+------------------+---------------------+------------------------- + dc1 | node-two | node-one | {node-one,node-three} +``` + +Where the write_lead is the node we determined earlier (node-two), we can also see the two read_nodes (node-one and node-three). +It's these nodes that we can safely perform maintenance. + + +!!! Tip +You can perform that operation with a single query: +```SQL +select read_nodes from bdr.node_group_routing_summary where write_lead = (select node_name from bdr.local_node_summary); +``` +!!! + +## Using `bdr.run_on_nodes()` +PGD does have the ability to run specific commands on specific nodes using the `bdr.run_on_nodes()` function. This takes two parameters, an array of node names and the command you would like to run on those nodes. For example: + +```SQL +SELECT bdr.run_on_nodes(ARRAY['node-one','node-three'],'vacuum full foo'); +__OUTPUT__ + + run_on_nodes +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + [{"dsn": "host=host-one port=5444 dbname=bdrdb", "node_id": "807899305", "response": {"command_status": "VACUUM"}, "node_name": "node-one", "query_send_time": "2024-01-16 16:24:35.418323+00"}, {"dsn": "host=host-three port=5432 dbname=bdrdb", "node_id": "199017004", "response": {"command_status": "VACUUM"}, "node_name": "node", "query_send_time": "2024-01-16 16:24:35.4542+00"}] +``` + +This command runs the `vacuum full foo` command on the node-one and node-three nodes. +Note that the node names are passed to the function in an array. + +The bdr.run_on_nodes reports its results as JSONB. +The results include the name of the node and the response (or error message) resulting from running the command. +Other fields may be included may not be relevant. + +The results also appear as a single string which is hard to read. To make it more readable, we can apply some formatting. + +## Formatting `bdr.run_on_nodes()` output + +Using Postgres’s JSON expressions, it is possible to reduce the output to just the columns we are interested in. The following command is functionally equivalent to the previous example but lists only the node and response as its results: + +```SQL +select q->>'node_name' as node, q->>'response' as response FROM jsonb_array_elements(bdr.run_on_nodes(ARRAY['node-one','node-three'], 'VACUUM FULL foo')) q; +__OUTPUT__ + node | response +------------------+------------------------------ + node-one | {"command_status": "VACUUM"} + node-three | {"command_status": "VACUUM"} +``` + +If an error occurs, the command_status field will be set to error and an additional error_message value will be included in the response. For example: + +```SQL +select q->>'node_name' as node, q->>'response' as response FROM jsonb_array_elements(bdr.run_on_nodes(ARRAY['node-one','node-three'], 'VACUUM FULL fool')) q; +__OUTPUT__ + node | response +------------------+-------------------------------------------------------------------------------------------- + node-one | {"error_message": "ERROR: relation \"fool\" does not exist\n", "command_status": "ERROR"} + node-three | {"error_message": "ERROR: relation \"fool\" does not exist\n", "command_status": "ERROR"} +(2 rows) +``` + +## Defining a function for maintenance + +If you find yourself regularly issuing maintenance commands to one node at a time, you do have the option to define a function to simplify things: + +```SQL +create or replace function runmaint(nodename varchar, command varchar) returns TABLE(node text,response jsonb) as $$ +begin +return query +select (q->>'node_name')::text, (q->'response') from jsonb_array_elements(bdr.run_on_nodes(ARRAY [nodename], command)) as q; +end; +$$ language 'plpgsql'; +``` + +This function takes a node name and a command and runs the command on that node, returning the results like so: + +```SQL +select runmaint('node-one','VACUUM FULL foo'); +__OUTPUT__ + runmaint +------------------------------------------------------- + (node-one,"{""command_status"": ""VACUUM""}") +``` + +You can break up the response by using select * from : + +```SQL +select * from runmaint('node-one','VACUUM FULL foo'); +__OUTPUT__ + node | response +------------------+------------------------------ + node-one | {"command_status": "VACUUM"} +(1 row) +``` + diff --git a/product_docs/docs/pgd/5/reference/nodes-management-interfaces.mdx b/product_docs/docs/pgd/5/reference/nodes-management-interfaces.mdx index 3c85ed0e498..09a93a3fa51 100644 --- a/product_docs/docs/pgd/5/reference/nodes-management-interfaces.mdx +++ b/product_docs/docs/pgd/5/reference/nodes-management-interfaces.mdx @@ -235,7 +235,9 @@ This function creates a node. ### Synopsis ```sql -bdr.create_node(node_name text, local_dsn text) +bdr.create_node(node_name text, + local_dsn text, + node_kind DEFAULT NULL) ``` ### Parameters @@ -244,6 +246,9 @@ bdr.create_node(node_name text, local_dsn text) database. Valid node names consist of lowercase letters, numbers, hyphens, and underscores. - `local_dsn` — Connection string to the node. +- `node_kind` — One of `data` (the default), `standby`, `subscriber-only` + or `witness`. If this parameter is not set, or `NULL` is provided, + the default `data` node kind is used. ### Notes @@ -254,7 +259,7 @@ created, the function reports an error if run again. This function is a transactional function. You can roll it back and the changes made by it are visible to the current transaction. -The function holds lock on the newly created bdr node until the end of +The function holds lock on the newly created node until the end of the transaction. ## `bdr.create_node_group` @@ -389,12 +394,12 @@ bdr.join_node_group ( !!! Warning `pause_in_standby` is deprecated since BDR 5.0. The recommended way to create a logical standby is to set `node_kind` to `standby` when creating the node - with `[bdr.create_node](#bdrcreate_node)`. + with [`bdr.create_node`](#bdrcreate_node). If `wait_for_completion` is specified as `false`, the function call will return as soon as the joining procedure starts. Progress of the join can be viewed in -the log files and the `[bdr.event_summary](catalogs-internal.mdx#bdrevent_summary)` -information view. The function `[bdr.wait_for_join_completion()](#bdrwait_for_join_completion)` +the log files and the [`bdr.event_summary`](catalogs-internal.mdx#bdrevent_summary) +information view. The function [`bdr.wait_for_join_completion()`](#bdrwait_for_join_completion) can be called after `bdr.join_node_group()` to wait for the join operation to complete, and can emit progress information if called with `verbose_progress` set to `true`. diff --git a/product_docs/docs/postgres_for_kubernetes/1/rel_notes/1_22_0_rel_notes.mdx b/product_docs/docs/postgres_for_kubernetes/1/rel_notes/1_22_0_rel_notes.mdx index 3221bbb549a..bdf782202d7 100644 --- a/product_docs/docs/postgres_for_kubernetes/1/rel_notes/1_22_0_rel_notes.mdx +++ b/product_docs/docs/postgres_for_kubernetes/1/rel_notes/1_22_0_rel_notes.mdx @@ -3,7 +3,7 @@ title: "EDB Postgres for Kubernetes 1.22.0 release notes" navTitle: "Version 1.22.0" --- -Released: 08 Nov 2023 +Released: 22 Dec 2023 This release of EDB Postgres for Kubernetes includes the following: diff --git a/static/_redirects b/static/_redirects index f7fccd15600..691985d7ad3 100644 --- a/static/_redirects +++ b/static/_redirects @@ -192,6 +192,7 @@ # Language Pack breakout from EPAS /docs/epas/latest/language_pack/* /docs/language_pack/2/:splat 301 +/docs/language_pack/2/* /docs/language_pack/latest/:splat 301 # EDB*Plus breakout from EPAS /docs/epas/:version/edb_plus/* /docs/edb_plus/latest/:splat 301!