From 4fdb36ae7ce1917025d6fb554458ebb6bc85451c Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 20 Mar 2022 14:43:50 +0200 Subject: [PATCH 001/316] Update index.rst Added a line of text to test search feature. --- index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.rst b/index.rst index e1455f21a..26b7459ec 100644 --- a/index.rst +++ b/index.rst @@ -4,7 +4,7 @@ SQream DB Documentation ************************* -For SQream version 2021.2. +The **2022.3 Preview** branch is a private branch designed for internal use only. .. only:: html From 94440c79ec952f53dde1dff744367a3d4eb974d2 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 20 Mar 2022 16:31:25 +0200 Subject: [PATCH 002/316] Started Creating Data Encryption Page --- feature_guides/data_encryption.rst | 115 +++++++++++++++++++++++++++++ feature_guides/index.rst | 1 + 2 files changed, 116 insertions(+) create mode 100644 feature_guides/data_encryption.rst diff --git a/feature_guides/data_encryption.rst b/feature_guides/data_encryption.rst new file mode 100644 index 000000000..02bdf2cea --- /dev/null +++ b/feature_guides/data_encryption.rst @@ -0,0 +1,115 @@ +.. _data_encryption: + +*********************** +Data Encryption +*********************** +The **Data Encryption** page: + +.. contents:: + :local: + :depth: 1 + +Overview +============== +Encryption functionality is an increasing growing demands from customers and new projects prospects (see Customers Specific Requirements section for more information), the functionality manifests in all sorts of ways as seen in the below section (implementation option) and the reason for it to be very important to customers is due to market strive to comply to the GDPR compliance regulations as it shows in the GDPR Compliance section. + +The encryption demand is growing around the world as it can be inserted to our sales pitch to promote vendors which security features is very important for them + +Column/Table-level encryption - More granular approach, encrypt only what you really need to + +Syntax +============== +The following is the correct syntax for encrypting a new table: + +.. code-block:: console + + CREATE TABLE client_name ( + first_name TEXT(128), + last_name TEXT(128), + salary INT(6) ENCRYPT); + +The following is the correct syntax for decrypting a new table: + +.. code-block:: console + + SELECT * FROM TABLE; + +The following is an example of encrypting a new table: + +.. code-block:: console + + EXAMPLE + +The following is an example of decryping a new table: + +.. code-block:: console + + EXAMPLE + +Encrypting Data in Transit +============== + +Encrypting Data at Rest +============== + +Data Types +============== + +How Encryption Works +============== +The **How Encryption Works** page describes the following: + +.. contents:: + :local: + :depth: 1 + +Encryption +---------------- + + + +Decryption +---------------- + + + +Encrypted Columns +---------------- + + + +Constraints +---------------- +Describe these in one of the existing sections. + + + +Use Case Considerations +============== +Include the relevant content from this section in the correct places in this document. + + + +Permissions +============== + + + +Usage Notes +============== +Include the relevant content from this section in the correct places in this document. + + + + + + + +Security Encryption available in one column. +Is there a flag associated with this feature? +There already is a Security page. Are we overriding it? +Give the big picture in the Overview. +Show Inon the before/after example. +Minimum Viable Product MVP +Permissions section - external +Deadline: two weeks minimum \ No newline at end of file diff --git a/feature_guides/index.rst b/feature_guides/index.rst index a0a996fc8..c5f472785 100644 --- a/feature_guides/index.rst +++ b/feature_guides/index.rst @@ -12,6 +12,7 @@ This section describes the following features: :titlesonly: delete_guide + data_encryption compression flexible_data_clustering python_functions From 93b019432b2e557c7c9200b15bcb6bbbea69ae5f Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 21 Mar 2022 09:34:34 +0200 Subject: [PATCH 003/316] Update data_encryption.rst --- feature_guides/data_encryption.rst | 78 ++++++++++++++++-------------- 1 file changed, 43 insertions(+), 35 deletions(-) diff --git a/feature_guides/data_encryption.rst b/feature_guides/data_encryption.rst index 02bdf2cea..e3e1af5f3 100644 --- a/feature_guides/data_encryption.rst +++ b/feature_guides/data_encryption.rst @@ -3,23 +3,53 @@ *********************** Data Encryption *********************** -The **Data Encryption** page: + +The **Data Encryption** page describes the following: .. contents:: :local: :depth: 1 - + + Overview ============== -Encryption functionality is an increasing growing demands from customers and new projects prospects (see Customers Specific Requirements section for more information), the functionality manifests in all sorts of ways as seen in the below section (implementation option) and the reason for it to be very important to customers is due to market strive to comply to the GDPR compliance regulations as it shows in the GDPR Compliance section. +**Data Encryption** helps protect sensitive data by preventing unauthorized users from reading it in the event of a breach. This is achieved by scrambling the content into an unreadable format based on encryption and decryption keys. + +The demand for confidentiality has steadily increased to protect the growing volumes of private data stored on computer systems and transmitted over the internet. To this end, regulatory bodies such as the **General Data Protection Regulation (GDPR)** have produced requirements to standardize and enforce compliance aimed at protecting customer data. -The encryption demand is growing around the world as it can be inserted to our sales pitch to promote vendors which security features is very important for them +For more information on GDPR compliance requirements, see the `GDPR checklist `_. Column/Table-level encryption - More granular approach, encrypt only what you really need to + + +Encryption Methods +============== +The **Encryption Methods** section describes the following: + +.. contents:: + :local: + :depth: 1 + +Encrypting Data in Transit +---------------- +**In-transit data** refers to data files inserted from customer repositories using the COPY FROM command, and is transmitted to SQream over a TLS-encrypted channel using a JDBC or ODBC connection. + +For more information, see the following: + +* :ref:`copy_from` +* :ref:`jdbc` +* :ref:`odbc` + +Encrypting Data at Rest +---------------- + +Data Types +============== + Syntax ============== -The following is the correct syntax for encrypting a new table: +The following is the correct syntax for **encrypting** a new table: .. code-block:: console @@ -27,33 +57,24 @@ The following is the correct syntax for encrypting a new table: first_name TEXT(128), last_name TEXT(128), salary INT(6) ENCRYPT); - -The following is the correct syntax for decrypting a new table: - -.. code-block:: console - - SELECT * FROM TABLE; - + The following is an example of encrypting a new table: .. code-block:: console EXAMPLE - -The following is an example of decryping a new table: + +The following is the correct syntax for **decrypting** a new table: .. code-block:: console - - EXAMPLE -Encrypting Data in Transit -============== + SELECT * FROM TABLE; -Encrypting Data at Rest -============== +The following is an example of decrypting a new table: -Data Types -============== +.. code-block:: console + + EXAMPLE How Encryption Works ============== @@ -100,16 +121,3 @@ Usage Notes Include the relevant content from this section in the correct places in this document. - - - - - -Security Encryption available in one column. -Is there a flag associated with this feature? -There already is a Security page. Are we overriding it? -Give the big picture in the Overview. -Show Inon the before/after example. -Minimum Viable Product MVP -Permissions section - external -Deadline: two weeks minimum \ No newline at end of file From a9e050e7d935f55a00cb385a732b9d655168bacd Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 21 Mar 2022 09:58:12 +0200 Subject: [PATCH 004/316] Created Data Encryption Folder Separate page for each section. --- feature_guides/data_encryption.rst | 123 ------------------ .../data_encryption/data_encryption.rst | 18 +++ .../data_encryption/data_encryption_flow.rst | 32 +++++ .../data_encryption_methods.rst | 23 ++++ .../data_encryption_overview.rst | 10 ++ .../data_encryption_syntax.rst | 44 +++++++ .../data_encryption/data_encryption_types.rst | 16 +++ .../data_encryption_use_cases.rst | 14 ++ 8 files changed, 157 insertions(+), 123 deletions(-) delete mode 100644 feature_guides/data_encryption.rst create mode 100644 feature_guides/data_encryption/data_encryption.rst create mode 100644 feature_guides/data_encryption/data_encryption_flow.rst create mode 100644 feature_guides/data_encryption/data_encryption_methods.rst create mode 100644 feature_guides/data_encryption/data_encryption_overview.rst create mode 100644 feature_guides/data_encryption/data_encryption_syntax.rst create mode 100644 feature_guides/data_encryption/data_encryption_types.rst create mode 100644 feature_guides/data_encryption/data_encryption_use_cases.rst diff --git a/feature_guides/data_encryption.rst b/feature_guides/data_encryption.rst deleted file mode 100644 index e3e1af5f3..000000000 --- a/feature_guides/data_encryption.rst +++ /dev/null @@ -1,123 +0,0 @@ -.. _data_encryption: - -*********************** -Data Encryption -*********************** - -The **Data Encryption** page describes the following: - -.. contents:: - :local: - :depth: 1 - - -Overview -============== -**Data Encryption** helps protect sensitive data by preventing unauthorized users from reading it in the event of a breach. This is achieved by scrambling the content into an unreadable format based on encryption and decryption keys. - -The demand for confidentiality has steadily increased to protect the growing volumes of private data stored on computer systems and transmitted over the internet. To this end, regulatory bodies such as the **General Data Protection Regulation (GDPR)** have produced requirements to standardize and enforce compliance aimed at protecting customer data. - -For more information on GDPR compliance requirements, see the `GDPR checklist `_. - -Column/Table-level encryption - More granular approach, encrypt only what you really need to - - - -Encryption Methods -============== -The **Encryption Methods** section describes the following: - -.. contents:: - :local: - :depth: 1 - -Encrypting Data in Transit ----------------- -**In-transit data** refers to data files inserted from customer repositories using the COPY FROM command, and is transmitted to SQream over a TLS-encrypted channel using a JDBC or ODBC connection. - -For more information, see the following: - -* :ref:`copy_from` -* :ref:`jdbc` -* :ref:`odbc` - -Encrypting Data at Rest ----------------- - -Data Types -============== - -Syntax -============== -The following is the correct syntax for **encrypting** a new table: - -.. code-block:: console - - CREATE TABLE client_name ( - first_name TEXT(128), - last_name TEXT(128), - salary INT(6) ENCRYPT); - -The following is an example of encrypting a new table: - -.. code-block:: console - - EXAMPLE - -The following is the correct syntax for **decrypting** a new table: - -.. code-block:: console - - SELECT * FROM TABLE; - -The following is an example of decrypting a new table: - -.. code-block:: console - - EXAMPLE - -How Encryption Works -============== -The **How Encryption Works** page describes the following: - -.. contents:: - :local: - :depth: 1 - -Encryption ----------------- - - - -Decryption ----------------- - - - -Encrypted Columns ----------------- - - - -Constraints ----------------- -Describe these in one of the existing sections. - - - -Use Case Considerations -============== -Include the relevant content from this section in the correct places in this document. - - - -Permissions -============== - - - -Usage Notes -============== -Include the relevant content from this section in the correct places in this document. - - diff --git a/feature_guides/data_encryption/data_encryption.rst b/feature_guides/data_encryption/data_encryption.rst new file mode 100644 index 000000000..e312e7fff --- /dev/null +++ b/feature_guides/data_encryption/data_encryption.rst @@ -0,0 +1,18 @@ +.. _data_encryption: + +*********************** +Data Encryption +*********************** + +The **Data Encryption** page describes the following: + +.. toctree:: + :maxdepth: 1 + :titlesonly: + + data_encryption_overview + data_encryption_methods + data_encryption_types + data_encryption_syntax + data_encryption_flow + data_encryption_use_cases \ No newline at end of file diff --git a/feature_guides/data_encryption/data_encryption_flow.rst b/feature_guides/data_encryption/data_encryption_flow.rst new file mode 100644 index 000000000..f65b1d240 --- /dev/null +++ b/feature_guides/data_encryption/data_encryption_flow.rst @@ -0,0 +1,32 @@ +.. _data_encryption_flow: + +*********************** +Data Encryption Flow +*********************** +The **Data Encryption Flow** page describes the following: + +.. contents:: + :local: + :depth: 1 + +Encryption +---------------- + + + +Decryption +---------------- + + + +Encrypted Columns +---------------- +Column/Table-level encryption - More granular approach, encrypt only what you really need to + + + + +Constraints +---------------- +Describe these in one of the existing sections. + diff --git a/feature_guides/data_encryption/data_encryption_methods.rst b/feature_guides/data_encryption/data_encryption_methods.rst new file mode 100644 index 000000000..031f263b3 --- /dev/null +++ b/feature_guides/data_encryption/data_encryption_methods.rst @@ -0,0 +1,23 @@ +.. _data_encryption_methods: + +*********************** +Encryption Methods +*********************** +The **Encryption Methods** section describes the following: + +.. contents:: + :local: + :depth: 1 + +Encrypting Data in Transit +---------------- +**In-transit data** refers to data files inserted from customer repositories using the COPY FROM command, and is transmitted to SQream over a TLS-encrypted channel using a JDBC or ODBC connection. + +For more information, see the following: + +* :ref:`copy_from` +* :ref:`jdbc` +* :ref:`odbc` + +Encrypting Data at Rest +---------------- diff --git a/feature_guides/data_encryption/data_encryption_overview.rst b/feature_guides/data_encryption/data_encryption_overview.rst new file mode 100644 index 000000000..5b3f3e344 --- /dev/null +++ b/feature_guides/data_encryption/data_encryption_overview.rst @@ -0,0 +1,10 @@ +.. _data_encryption_overview: + +*********************** +Overview +*********************** +**Data Encryption** helps protect sensitive data by preventing unauthorized users from reading it in the event of a breach. This is achieved by scrambling the content into an unreadable format based on encryption and decryption keys. + +The demand for confidentiality has steadily increased to protect the growing volumes of private data stored on computer systems and transmitted over the internet. To this end, regulatory bodies such as the **General Data Protection Regulation (GDPR)** have produced requirements to standardize and enforce compliance aimed at protecting customer data. + +For more information on GDPR compliance requirements, see the `GDPR checklist `_. \ No newline at end of file diff --git a/feature_guides/data_encryption/data_encryption_syntax.rst b/feature_guides/data_encryption/data_encryption_syntax.rst new file mode 100644 index 000000000..8df3e0d33 --- /dev/null +++ b/feature_guides/data_encryption/data_encryption_syntax.rst @@ -0,0 +1,44 @@ +.. _data_encryption_syntax: + +*********************** +Syntax +*********************** + +The **Syntax** page describes the following: + +.. contents:: + :local: + :depth: 1 + +The following is the correct syntax for **encrypting** a new table: + +.. code-block:: console + + CREATE TABLE client_name ( + first_name TEXT(128), + last_name TEXT(128), + salary INT(6) ENCRYPT); + +The following is an example of encrypting a new table: + +.. code-block:: console + + EXAMPLE + +The following is the correct syntax for **decrypting** a new table: + +.. code-block:: console + + SELECT * FROM TABLE; + +The following is an example of decrypting a new table: + +.. code-block:: console + + EXAMPLE + +Usage notes - this should be included on this page. + +When inputting the wrong master key/location in encryption/decryption an error should be raised to the user + +The master key needs to be masked in logs to protect user privacy, the responsibility maintaining the master key for the remote repository is on the user side \ No newline at end of file diff --git a/feature_guides/data_encryption/data_encryption_types.rst b/feature_guides/data_encryption/data_encryption_types.rst new file mode 100644 index 000000000..331b14f58 --- /dev/null +++ b/feature_guides/data_encryption/data_encryption_types.rst @@ -0,0 +1,16 @@ +.. _data_encryption_types: + +*********************** +Data Types +*********************** + + +Per the research done and per customer requirement the data types that should be supported are the following: + +Int + +BigInt + +String + +On most cases this data type, if encrypted, will be populated by PII value (Personal Identifiable Information) such as credit card number and other personal and sensitive information \ No newline at end of file diff --git a/feature_guides/data_encryption/data_encryption_use_cases.rst b/feature_guides/data_encryption/data_encryption_use_cases.rst new file mode 100644 index 000000000..9e9ddeb4a --- /dev/null +++ b/feature_guides/data_encryption/data_encryption_use_cases.rst @@ -0,0 +1,14 @@ +.. _data_encryption_use_cases: + +*********************** +Use Cases +*********************** + + + + + +Use Case Considerations +============== +Include the relevant content from this section in the correct places in this document. + From 8c9a1a4facaddd59b0f40a0a4a1544567a731409 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 21 Mar 2022 10:08:21 +0200 Subject: [PATCH 005/316] Updated Menu to include Data Encryption --- feature_guides/{data_encryption => }/data_encryption.rst | 0 feature_guides/{data_encryption => }/data_encryption_flow.rst | 0 feature_guides/{data_encryption => }/data_encryption_methods.rst | 0 feature_guides/{data_encryption => }/data_encryption_overview.rst | 0 feature_guides/{data_encryption => }/data_encryption_syntax.rst | 0 feature_guides/{data_encryption => }/data_encryption_types.rst | 0 .../{data_encryption => }/data_encryption_use_cases.rst | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename feature_guides/{data_encryption => }/data_encryption.rst (100%) rename feature_guides/{data_encryption => }/data_encryption_flow.rst (100%) rename feature_guides/{data_encryption => }/data_encryption_methods.rst (100%) rename feature_guides/{data_encryption => }/data_encryption_overview.rst (100%) rename feature_guides/{data_encryption => }/data_encryption_syntax.rst (100%) rename feature_guides/{data_encryption => }/data_encryption_types.rst (100%) rename feature_guides/{data_encryption => }/data_encryption_use_cases.rst (100%) diff --git a/feature_guides/data_encryption/data_encryption.rst b/feature_guides/data_encryption.rst similarity index 100% rename from feature_guides/data_encryption/data_encryption.rst rename to feature_guides/data_encryption.rst diff --git a/feature_guides/data_encryption/data_encryption_flow.rst b/feature_guides/data_encryption_flow.rst similarity index 100% rename from feature_guides/data_encryption/data_encryption_flow.rst rename to feature_guides/data_encryption_flow.rst diff --git a/feature_guides/data_encryption/data_encryption_methods.rst b/feature_guides/data_encryption_methods.rst similarity index 100% rename from feature_guides/data_encryption/data_encryption_methods.rst rename to feature_guides/data_encryption_methods.rst diff --git a/feature_guides/data_encryption/data_encryption_overview.rst b/feature_guides/data_encryption_overview.rst similarity index 100% rename from feature_guides/data_encryption/data_encryption_overview.rst rename to feature_guides/data_encryption_overview.rst diff --git a/feature_guides/data_encryption/data_encryption_syntax.rst b/feature_guides/data_encryption_syntax.rst similarity index 100% rename from feature_guides/data_encryption/data_encryption_syntax.rst rename to feature_guides/data_encryption_syntax.rst diff --git a/feature_guides/data_encryption/data_encryption_types.rst b/feature_guides/data_encryption_types.rst similarity index 100% rename from feature_guides/data_encryption/data_encryption_types.rst rename to feature_guides/data_encryption_types.rst diff --git a/feature_guides/data_encryption/data_encryption_use_cases.rst b/feature_guides/data_encryption_use_cases.rst similarity index 100% rename from feature_guides/data_encryption/data_encryption_use_cases.rst rename to feature_guides/data_encryption_use_cases.rst From cdbd5588263595ef3bb6b5e8276a05a2ffd4ebec Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 21 Mar 2022 14:06:16 +0200 Subject: [PATCH 006/316] Added Update --- reference/sql/sql_statements/index.rst | 4 + reference/sql/sql_statements/update.rst | 245 ++++++++++++++++++++++++ 2 files changed, 249 insertions(+) create mode 100644 reference/sql/sql_statements/update.rst diff --git a/reference/sql/sql_statements/index.rst b/reference/sql/sql_statements/index.rst index 955e1212f..e14041385 100644 --- a/reference/sql/sql_statements/index.rst +++ b/reference/sql/sql_statements/index.rst @@ -11,6 +11,8 @@ SQream DB supports commands from ANSI SQL. Data Definition Commands (DDL) ================================ + update + .. list-table:: DDL Commands :widths: auto :header-rows: 1 @@ -20,6 +22,8 @@ Data Definition Commands (DDL) - Usage * - :ref:`ADD COLUMN` - Add a new column to a table + * - :ref:`UPDATE` + - Modify the value of certain columns in existing rows without creating a table * - :ref:`ALTER DEFAULT SCHEMA` - Change the default schema for a role * - :ref:`ALTER TABLE` diff --git a/reference/sql/sql_statements/update.rst b/reference/sql/sql_statements/update.rst new file mode 100644 index 000000000..143363b3b --- /dev/null +++ b/reference/sql/sql_statements/update.rst @@ -0,0 +1,245 @@ +.. _update: + +********************** +UPDATE +********************** + +The **UPDATE** statement page describes the following: + +.. contents:: + :local: + :depth: 1 + +Overview +========== +The ``UPDATE`` command is used to modify the value of certain columns in existing rows without creating a table. + +It can be used to do the following: + +* Perform localized changes in existing data, such as correcting mistakes discovered after ingesting data. + +* Setting columns based on the values of others. + +Syntax +========== +The following is the correct syntax for the ``UPDATE`` command: + +.. code-block:: postgres + + UPDATE target_table_name [[AS] alias1] + SET column_name = expression [,...] + [FROM additional_table_name [[AS] alias2][,...]] + [WHERE condition] + +The following is the correct syntax for triggering a clean-up: + +.. code-block:: postgres + + SELECT cleanup_chunks('schema_name','table_name'); + SELECT cleanup_extents('schema_name','table_name'); + +**Comment** - *The cleanup example above is different than the one used on the DELETED page. Is this correct?* + +Parameters +============ +The following table describes the ``UPDATE`` parameters: + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``target_table_name`` + - Specifies the table containing the data to be updated. + * - ``column_name`` + - Specifies the column containing the data to be updated. + * - ``additional_table_name`` + - Additional tables used in the WHERE condition for performing complex joins. + * - ``condition`` + - Specifies the condition for updating the data. + +.. note:: Similar to a DELETE statement, an UPDATE statement may leave some uncleaned data behind, which requires a cleanup operation. + +Examples +=========== +The **Examples** section includes the following examples: + +.. contents:: + :local: + :depth: 1 + +Updating an Entire Table +----------------- +The Examples section shows how to modify the value of certain columns in existing rows without creating a table. The examples are based on the following tables: + +.. image:: /_static/images/delete_optimization.png + +The following methods for updating an entire table generate the same output, and result with the ``bands`` record set to ``NULL``: + +.. code-block:: postgres + + UPDATE bands SET records_sold = 0; + +.. code-block:: postgres + + UPDATE bands SET records_sold = 0 WHERE true; + +.. code-block:: postgres + + UPDATE bands SET records_sold = 0 USING countries; + +.. code-block:: postgres + + UPDATE bands SET records_sold = 0 USING countries WHERE 1=1; + +Performing Simple Updates +----------------- +The following is an example of performing a simple update: + +.. code-block:: postgres + + UPDATE bands SET records_sold = records_sold + 1 WHERE name LIKE 'The %'; + +Updating Tables that Contain Multi-Table Conditions +----------------- +The following shows an example of updating tables that contain multi-table conditions: + +.. code-block:: postgres + + UPDATE bands + SET records_sold = records_sold + 1 + WHERE EXISTS ( + SELECT 1 FROM countries + WHERE countries.id=bands.country_id + AND country.name = 'Sweden' + ); + +You can also write the statement above using the FROM clause: + +.. code-block:: psql + + UPDATE bands + SET records_sold = records_sold + 1 + FROM countries + WHERE countries.id=bands.country_id AND country.name = 'Sweden'; + +Updating Tables that Contain Multi-Table Expressions +----------------- +The following shows an example of updating tables that contain multi-table expressions: + +.. code-block:: postgres + + UPDATE bands + SET records_sold = records_sold + + CASE + WHEN c.name = 'Israel' THEN 2 + ELSE 1 + END + FROM countries c + +Configuring Update Behavior +----------------- +The ``failOnNondeterministicUpdate`` flag is used to configure ``UPDATE`` behavior when updating tables containing multi-table expressions. This flag is needed when you use the ``FROM`` clause along with a set expression containing columns from additional tables. Doing this can cause a match to occur between a row from the target table with multiple rows from the additional tables. + +**Note to self** - *Check if the Studio documentation must be updated for this flag.* + +For instance, the example in the previous section sets the records sold to ``2`` when the country name is Israel. If you were to insert a new entry into this table with Israel spelled in Hebrew (using the same country ID), you would have two rows with identical country ID's. + +When this happens, both rows 5 and 6 in the ``bands`` table match both Israel entries. Because no algorithm exists for determining which entry to use, updating this table may either increase ``records_sold`` by 2 (for Israel in English) or 1 (for Israel in Hebrew). + +You must set the ``failOnNondeterministicUpdate`` flag to ``FALSE`` to prevent an error from occuring. + +**Comment** - *Does the system actually choose one, or does it generate an error?* + +Note that a similar ambiguity can occur when the Hebrew spelling is used in the following example: + +.. code-block:: postgres + + UPDATE bands + SET record_count = record_count + 1 + FROM countries c + WHERE c.name = 'Israel' + +However, the ``WHERE`` clause above prevents a match with any entry other than the defined one. Because the target table row must match with the ``WHERE`` condition at least once to be included in the UPDATE statment, this scenario does not require configuring the ``failOnNondeterministicUpdate`` flag. + +**Comment** - *Please review the paragraph above. I'm pretty sure I described this correctly.* + +For more information, see `SQream Acceleration Studio `_. + +Identifying and Cleaning Up Tables +--------------------------------------- +**Comment** - *I copied and pasted this entire section from "DELETE". Does anything have to adjusted here for "UPDATE"?* + +The following section shows examples of each phase required for cleaning up tables: + +* :ref:`Listing tables that require clean-up` +* :ref:`Identifying clean-up predicates` +* :ref:`Triggering a clean-up` + +.. _listing_tables_that_require_cleanup: + +Listing Tables that Require Clean-Up +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The following shows an example of listing tables that require clean-up: + +.. code-block:: psql + + farm=> SELECT t.table_name FROM sqream_catalog.delete_predicates dp + JOIN sqream_catalog.tables t + ON dp.table_id = t.table_id + GROUP BY 1; + cool_animals + + 1 row + +.. _identifying_cleanup_predicates: + +Identifying Clean-Up Predicates +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The following shows an example of listing the clean-up predicates: + +.. code-block:: psql + + farm=> SELECT delete_predicate FROM sqream_catalog.delete_predicates dp + JOIN sqream_catalog.tables t + ON dp.table_id = t.table_id + WHERE t.table_name = 'cool_animals'; + weight > 1000 + + 1 row + +.. _triggering_a_cleanup: + +Triggering a Clean-Up +^^^^^^^^^^^^^^^^^^^^^^ +The following shows an example of triggering a clean-up: + +.. code-block:: psql + + -- Chunk reorganization (SWEEP) + farm=> SELECT CLEANUP_CHUNKS('public','cool_animals'); + executed + + -- Delete leftover files (VACUUM) + farm=> SELECT CLEANUP_EXTENTS('public','cool_animals'); + executed + + + farm=> SELECT delete_predicate FROM sqream_catalog.delete_predicates dp + JOIN sqream_catalog.tables t + ON dp.table_id = t.table_id + WHERE t.table_name = 'cool_animals'; + + 0 rows + +Permissions +============= +Executing an ``UPDATE`` statement requires the following permissions: + +* Both ``UPDATE`` and ``SELECT`` permissions on the target table. +* The ``SELECT`` permission for each additional table you reference in the statement (in ither the ``FROM`` clause or ``WHERE`` subquery section). + +Locking and Concurrency +============= +Executing the ``UPDATE`` statement obtains an exclusive UPDATE lock on the target table, but does not lock the destination tables. \ No newline at end of file From fade107ea80f689f5a0d304f6438c9a7ad63d29f Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Wed, 23 Mar 2022 09:59:21 +0200 Subject: [PATCH 007/316] Updated for RN Release - Preview --- data_ingestion/avro.rst | 344 ++++++++++++++++++ data_ingestion/index.rst | 3 +- feature_guides/data_encryption_methods.rst | 2 +- feature_guides/index.rst | 2 +- .../{ => dml_commands}/update.rst | 0 reference/sql/sql_statements/index.rst | 6 +- releases/2022.1.rst | 104 ++++++ releases/index.rst | 5 +- 8 files changed, 458 insertions(+), 8 deletions(-) create mode 100644 data_ingestion/avro.rst rename reference/sql/sql_statements/{ => dml_commands}/update.rst (100%) create mode 100644 releases/2022.1.rst diff --git a/data_ingestion/avro.rst b/data_ingestion/avro.rst new file mode 100644 index 000000000..920b6d44b --- /dev/null +++ b/data_ingestion/avro.rst @@ -0,0 +1,344 @@ +.. _avro: + +************************** +Inserting Data from Avro +************************** +The **Inserting Data from Avro** page describes inserting data from Avro into SQream and includes the following: + +.. contents:: + :local: + :depth: 1 + +Overview +=========== +**Avro** is a well-known data serialization system that relies on schemas. Due to its flexibility and nesting as an efficient data storage method, SQream supports the Avro binary data format as an alternative to JSON. + +Avro Data Types +=========== + +Avro includes the following data types: + +.. contents:: + :local: + :depth: 1 + +Primitive Data Types +-------------- +The following table shows the supported **Primitive** data types: + ++-------------+-------------------------------------------+ +| Avro Type | SQream Type | +| +--------+---------------+--------+---------+ +| | Number | Date/Datetime | String | Boolean | ++=============+========+===============+========+=========+ +| ``null`` | ✓ | ✓ | ✓ | ✓ | ++-------------+--------+---------------+--------+---------+ +| ``boolean`` | | | ✓ | ✓ | ++-------------+--------+---------------+--------+---------+ +| ``int`` | ✓ | | ✓ | | ++-------------+--------+---------------+--------+---------+ +| ``long`` | ✓ | | ✓ | | ++-------------+--------+---------------+--------+---------+ +| ``float`` | ✓ | | ✓ | | ++-------------+--------+---------------+--------+---------+ +| ``double`` | ✓ | | ✓ | | ++-------------+--------+---------------+--------+---------+ +| ``bytes`` | | | | | ++-------------+--------+---------------+--------+---------+ +| ``string`` | | ✓ | ✓ | | ++-------------+--------+---------------+--------+---------+ + + + + + + +Complex Data Types +-------------- +The following table shows the supported **Complex** data types: + ++------------+-------------------------------------------+ +| | SQream Type | +| +--------+---------------+--------+---------+ +|Avro Type | Number | Date/Datetime | String | Boolean | ++============+========+===============+========+=========+ +| ``record`` | | | | | ++------------+--------+---------------+--------+---------+ +| ``enum`` | | | ✓ | | ++------------+--------+---------------+--------+---------+ +| ``array`` | | | | | ++------------+--------+---------------+--------+---------+ +| ``map`` | | | | | ++------------+--------+---------------+--------+---------+ +| ``union`` | ✓ | ✓ | ✓ | ✓ | ++------------+--------+---------------+--------+---------+ +| ``fixed`` | | | | | ++------------+--------+---------------+--------+---------+ + + +Logical Data Types +-------------- +The following table shows the supported **Logical** data types: + ++----------------------------+-------------------------------------------+ +| Avro Type | SQream Type | +| +--------+---------------+--------+---------+ +| | Number | Date/Datetime | String | Boolean | ++============================+========+===============+========+=========+ +| ``decimal`` | ✓ | | ✓ | | ++----------------------------+--------+---------------+--------+---------+ +| ``uuid`` | | | ✓ | | ++----------------------------+--------+---------------+--------+---------+ +| ``date`` | | ✓ | ✓ | | ++----------------------------+--------+---------------+--------+---------+ +| ``time-millis`` | | | | | ++----------------------------+--------+---------------+--------+---------+ +| ``time-micros`` | | | | | ++----------------------------+--------+---------------+--------+---------+ +| ``timestamp-millis`` | | ✓ | ✓ | | ++----------------------------+--------+---------------+--------+---------+ +| ``timestamp-micros`` | | ✓ | ✓ | | ++----------------------------+--------+---------------+--------+---------+ +| ``local-timestamp-millis`` | | | | | ++----------------------------+--------+---------------+--------+---------+ +| ``local-timestamp-micros`` | | | | | ++----------------------------+--------+---------------+--------+---------+ +| ``duration`` | | | | | ++----------------------------+--------+---------------+--------+---------+ + + +Mapping Objects to Rows +=============== +When mapping objects to rows, each Avro object or message must contain one ``record`` type object corresponding to a single row in SQream. The ``record`` fields are associated by name to their target table columns. + +Additional unmapped fields will be ignored. Note that using the JSONPath option overrides this. + +Ingesting Avro Files +==================== +This section describes how to ingest Avro files into SQream and covers the following: + + +.. contents:: + :local: + :depth: 1 + + +Preparing Your Avro Source File +---------- +Prepare your Avro source files according to the following requirements: + +* RFC 4180 standard CSV files, but can also be modified to support non-standard CSVs (with multi-character delimiters, unquoted fields, etc). + + :: + +* Files are encoded with UTF-8 or ASCII. + + :: + +* Field delimiter is an ASCII character or characters. + + :: + +* Record delimiter, also known as a new line separator, is a Unix-style newline (``\n``), DOS-style newline (``\r\n``), or Mac style newline (``\r``). + + :: + +* If a field is quoted, any double quote that appears must be double-quoted (similar to the :ref:`string literals quoting rules`. For example, to encode ``What are "birds"?``, the field should appear as ``"What are ""birds""?"``. + + :: + +* Fields can be enclosed by double-quotes (optional), or mandatory quotes if they contain one of the following characters: + + * The record delimiter or field delimiter. + + :: + + * A double quote character. + + :: + + * A newline. + +SQream does not support other modes of escaping, such as ``1,"What are \"birds\"?"``. + +``NULL`` values can be marked in the following ways in Avro files: + + * An explicit null marker. For example, ``col1,\N,col3``. + + :: + + * An empty field delimited by the field delimiter. For example, ``col1,,col3``. + + .. note:: If a text field is quoted but contains no content (``""``) it is considered an empty text field and not ``NULL``. + +For more information about standard CSV files, see `RFC 4180 standard CSVs `_. + +Making Avro Files Accessible to Workers +--------------------- +To give workers access to files every node must have the same view of the storage being used. + +The following apply for Avro files to be accessible to workers: + +* For files hosted on NFS, ensure that the mount is accessible from all servers. + +* For HDFS, ensure that SQream servers have access to the HDFS name node with the correct **user-id**. For more information, see :ref:`hdfs`. + +* For S3, ensure network access to the S3 endpoint. For more information, see :ref:`s3`. + +For more information about restricted worker access, see :ref:`workload_manager`. + +Basing Your Table Structure on Inserted Tables +--------------------- +Before loading data, you must build the ``CREATE EXTERNAL TABLE`` to correspond with the file structure of the inserted table. + +The example in this section is based on the source ``nba.parquet`` table shown below: + +.. csv-table:: nba.parquet + :file: nba-t10.csv + :widths: auto + :header-rows: 1 + +The following example shows the correct file structure used to create the ``CREATE EXTERNAL TABLE`` statement based on the **nba.parquet** table: + +.. code-block:: postgres + + CREATE FOREIGN TABLE ext_nba + ( + Name VARCHAR(40), + Team VARCHAR(40), + Number BIGINT, + Position VARCHAR(2), + Age BIGINT, + Height VARCHAR(4), + Weight BIGINT, + College VARCHAR(40), + Salary FLOAT + ) + WRAPPER parquet_fdw + OPTIONS + ( + LOCATION = 's3://sqream-demo-data/nba.parquet' + ); + +.. tip:: + + An exact match must exist between the SQream and Avro types. For unsupported column types, you can set the type to any type and exclude it from subsequent queries. + +.. note:: The **nba.parquet** file is stored on S3 at ``s3://sqream-demo-data/nba.parquet``. + +Verifying Your Table Output +--------------------- +Because external tables do not automatically verify the file integrity or structure, you must manually verify that the table output is identical to the original inserted table. + +The following is an example of the output based on the **nba.parquet** table: + +.. code-block:: psql + + t=> SELECT * FROM ext_nba LIMIT 10; + Name | Team | Number | Position | Age | Height | Weight | College | Salary + --------------+----------------+--------+----------+-----+--------+--------+-------------------+--------- + Avery Bradley | Boston Celtics | 0 | PG | 25 | 6-2 | 180 | Texas | 7730337 + Jae Crowder | Boston Celtics | 99 | SF | 25 | 6-6 | 235 | Marquette | 6796117 + John Holland | Boston Celtics | 30 | SG | 27 | 6-5 | 205 | Boston University | + R.J. Hunter | Boston Celtics | 28 | SG | 22 | 6-5 | 185 | Georgia State | 1148640 + Jonas Jerebko | Boston Celtics | 8 | PF | 29 | 6-10 | 231 | | 5000000 + Amir Johnson | Boston Celtics | 90 | PF | 29 | 6-9 | 240 | | 12000000 + Jordan Mickey | Boston Celtics | 55 | PF | 21 | 6-8 | 235 | LSU | 1170960 + Kelly Olynyk | Boston Celtics | 41 | C | 25 | 7-0 | 238 | Gonzaga | 2165160 + Terry Rozier | Boston Celtics | 12 | PG | 22 | 6-2 | 190 | Louisville | 1824360 + Marcus Smart | Boston Celtics | 36 | PG | 22 | 6-4 | 220 | Oklahoma State | 3431040 + +.. note:: If your table output has errors, verify that the structure of the Avro files correctly corresponds to the external table structure that you created. + +Loading Data into SQream +--------------------- + +Syntax +~~~~~~~~~~~~~~~~~~~~~ +The following is the correct syntax for loading data into SQream: + +.. code-block:: postgres + + CREATE TABLE AS + SELECT * FROM ; + +The following is an example of loading data into SQream: + +.. code-block:: postgres + + CREATE TABLE nba AS + SELECT * FROM ext_nba; + +For more information about the **CREATE TABLE AS** statement, see :ref:`create_table_as`. + +Examples +~~~~~~~~~~~~~~~~~~~~~ + +This section includes the following examples of loading data into SQream: + +.. contents:: + :local: + :depth: 1 + +Omitting Unsupported Column Types +********************** +When loading data, you can omit columns using the ``NULL as`` argument. You can use this argument to omit unsupported columns from queries that access external tables. By omitting them, these columns will not be called and will avoid generating a "type mismatch" error. + +In the example below, the ``Position`` column is not supported due its type. + +.. code-block:: postgres + + CREATE TABLE nba AS + SELECT Name, Team, Number, NULL as Position, Age, Height, Weight, College, Salary FROM ext_nba; + + +Modifying Data Before Loading +********************** +One of the main reasons for staging data using the ``EXTERNAL TABLE`` argument is to examine and modify table contents before loading it into SQream. + +For example, we can replace pounds with kilograms using the :ref:`create_table_as` statement + +In the example below, the ``Position`` column is set to the default ``NULL``. + +.. code-block:: postgres + + CREATE TABLE nba AS + SELECT name, team, number, NULL as Position, age, height, (weight / 2.205) as weight, college, salary + FROM ext_nba + ORDER BY weight; + + +Loading a Table from a Directory of Avro Files on HDFS +********************** +The following is an example of loading a table from a directory of Avro files on HDFS: + +.. code-block:: postgres + + CREATE FOREIGN TABLE ext_users + (id INT NOT NULL, name VARCHAR(30) NOT NULL, email VARCHAR(50) NOT NULL) + WRAPPER parquet_fdw + OPTIONS + ( + LOCATION = 'hdfs://hadoop-nn.piedpiper.com/rhendricks/users/*.parquet' + ); + + CREATE TABLE users AS SELECT * FROM ext_users; + +For more configuration option examples, see the `CREATE FOREIGN TABLE parameters `_. + +Loading a Table from a Directory of Avro Files on S3 +********************** +The following is an example of loading a table from a directory of Avro files on S3: + +.. code-block:: postgres + + CREATE FOREIGN TABLE ext_users + (id INT NOT NULL, name VARCHAR(30) NOT NULL, email VARCHAR(50) NOT NULL) + WRAPPER parquet_fdw + OPTIONS + ( LOCATION = 's3://pp-secret-bucket/users/*.parquet', + AWS_ID = 'our_aws_id', + AWS_SECRET = 'our_aws_secret' + ); + + CREATE TABLE users AS SELECT * FROM ext_users; \ No newline at end of file diff --git a/data_ingestion/index.rst b/data_ingestion/index.rst index 83aca40ea..12582b8e4 100644 --- a/data_ingestion/index.rst +++ b/data_ingestion/index.rst @@ -10,9 +10,10 @@ The **Data Ingestion Sources** provides information about the following: :glob: inserting_data + avro csv parquet orc oracle -For information about database tools and interfaces that SQream supports, see `Third Party Tools `_. +For information about database tools and interfaces that SQream supports, see `Third Party Tools `_. \ No newline at end of file diff --git a/feature_guides/data_encryption_methods.rst b/feature_guides/data_encryption_methods.rst index 031f263b3..c0aae030d 100644 --- a/feature_guides/data_encryption_methods.rst +++ b/feature_guides/data_encryption_methods.rst @@ -16,7 +16,7 @@ Encrypting Data in Transit For more information, see the following: * :ref:`copy_from` -* :ref:`jdbc` +* `JDBC `_ * :ref:`odbc` Encrypting Data at Rest diff --git a/feature_guides/index.rst b/feature_guides/index.rst index c5f472785..650638c17 100644 --- a/feature_guides/index.rst +++ b/feature_guides/index.rst @@ -5,7 +5,7 @@ Feature Guides *********************** The **Feature Guides** section describes background processes that SQream uses to manage several areas of operation, such as data ingestion, load balancing, and access control. -This section describes the following features: +This section describes the following features: .. toctree:: :maxdepth: 1 diff --git a/reference/sql/sql_statements/update.rst b/reference/sql/sql_statements/dml_commands/update.rst similarity index 100% rename from reference/sql/sql_statements/update.rst rename to reference/sql/sql_statements/dml_commands/update.rst diff --git a/reference/sql/sql_statements/index.rst b/reference/sql/sql_statements/index.rst index e14041385..8ecd680df 100644 --- a/reference/sql/sql_statements/index.rst +++ b/reference/sql/sql_statements/index.rst @@ -11,8 +11,6 @@ SQream DB supports commands from ANSI SQL. Data Definition Commands (DDL) ================================ - update - .. list-table:: DDL Commands :widths: auto :header-rows: 1 @@ -22,8 +20,6 @@ Data Definition Commands (DDL) - Usage * - :ref:`ADD COLUMN` - Add a new column to a table - * - :ref:`UPDATE` - - Modify the value of certain columns in existing rows without creating a table * - :ref:`ALTER DEFAULT SCHEMA` - Change the default schema for a role * - :ref:`ALTER TABLE` @@ -86,6 +82,8 @@ Data Manipulation Commands (DML) - Select rows and column from a table * - :ref:`TRUNCATE` - Delete all rows from a table + * - :ref:`UPDATE` + - Modify the value of certain columns in existing rows without creating a table * - :ref:`VALUES` - Return rows containing literal values diff --git a/releases/2022.1.rst b/releases/2022.1.rst new file mode 100644 index 000000000..d36bc9463 --- /dev/null +++ b/releases/2022.1.rst @@ -0,0 +1,104 @@ +.. _2022.1: + +************************** +Release Notes 2022.1 +************************** +The 2022.1 release notes were released on x/xx/2022 and describe the following: + +.. contents:: + :local: + :depth: 1 + + +Version Content +---------- +The 2022.1 Release Notes describes the following: + +* Example - Major feature release targeted for all on-premises customers. +* Example - Basic Cloud functionality. + + +New Features +---------- +The 2022.1 Release Notes include the following new features: + +.. contents:: + :local: + :depth: 1 + +Data Encryption +************ + + +Update Feature +************ + + +Avro Ingestion +************ + + + + +Main Features +-------- +The following list describes the main features: + +* xxx +* xx + + +Resolved Issues +--------- +The following list describes the resolved issues: + +The following table lists the issues that were resolved in Version 2021.2: + +.. list-table:: + :widths: 17 200 + :header-rows: 1 + + * - SQ No. + - Description + * - SQ-xxxx + - Text + * - SQ-xxxx + - Text + * - SQ-xxxx + - Text + +Operations and Configuration Changes +-------- + +Subject +************ +Text + + + + +Subject +************ +Text + + + +Naming Changes +------- +No relevant naming changes were made. + +Deprecated Features +------- +No features were depecrated. + +Known Issues and Limitations +-------- +The the list below describes the following known issues and limitations: + +* xxx +* xxx + + +Upgrading to v2022.1 +------- + diff --git a/releases/index.rst b/releases/index.rst index 472197afc..9158933a4 100644 --- a/releases/index.rst +++ b/releases/index.rst @@ -12,7 +12,9 @@ Release Notes * - Version - Release Date - * - :ref:`2021.2` + * - :ref:`2022.1` + - April 17, 2022 + * - :ref:`2022.1` - September 13, 2021 * - :ref:`2021.1` - June 13, 2021 @@ -30,6 +32,7 @@ Release Notes :glob: :hidden: + 2022.1 2021.2_index 2021.1_index 2020.3_index From d80c9427434d4abd73b5879f80e97f34a75e3e0a Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Wed, 23 Mar 2022 10:21:44 +0200 Subject: [PATCH 008/316] Not Published --- releases/2022.1.rst | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/releases/2022.1.rst b/releases/2022.1.rst index d36bc9463..51a7333cc 100644 --- a/releases/2022.1.rst +++ b/releases/2022.1.rst @@ -7,8 +7,7 @@ The 2022.1 release notes were released on x/xx/2022 and describe the following: .. contents:: :local: - :depth: 1 - + :depth: 1 Version Content ---------- @@ -17,6 +16,7 @@ The 2022.1 Release Notes describes the following: * Example - Major feature release targeted for all on-premises customers. * Example - Basic Cloud functionality. +**Comment** - *This will be done at the end.* New Features ---------- @@ -28,30 +28,33 @@ The 2022.1 Release Notes include the following new features: Data Encryption ************ +SQream now supports data encryption mechanisms in accordance with **General Data Protection Regulation (GDPR)** standards. +For more information, see `Data Encryption `_. Update Feature ************ +SQream now supports the DML **Update** feature, which is used for modifying the value of certain columns in existing rows without creating a table. +For more information, see `UPDATE `_. Avro Ingestion ************ +SQream now supports ingesting data from Avro files. - - +For more information, see `Inserting Data from Avro `_. Main Features -------- The following list describes the main features: -* xxx -* xx +* Main feature +* Main feature +**Comment** - *This will be done at the end.* Resolved Issues --------- -The following list describes the resolved issues: - The following table lists the issues that were resolved in Version 2021.2: .. list-table:: @@ -65,10 +68,14 @@ The following table lists the issues that were resolved in Version 2021.2: * - SQ-xxxx - Text * - SQ-xxxx - - Text + - Text + +**Comment** - *I will be updated regarding which resolved issues to include.* Operations and Configuration Changes -------- +**Comment** - *TBD* + Subject ************ @@ -85,20 +92,30 @@ Text Naming Changes ------- +**Comment** - *TBD* + No relevant naming changes were made. Deprecated Features ------- +**Comment** - *TBD* + No features were depecrated. Known Issues and Limitations -------- +**Comment** - *TBD* + The the list below describes the following known issues and limitations: -* xxx -* xxx +* Text +* Text + +End of Support +------- +**Comment** - *TBD* Upgrading to v2022.1 ------- - +**Comment** - *TBD* \ No newline at end of file From 3cd71e0265075b7229b2681ca950d08333b326e5 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Wed, 23 Mar 2022 13:02:48 +0200 Subject: [PATCH 009/316] Replaced left menu with multi-layered list Left menu was too long. Running idea by Product. --- .../sql_functions/scalar_functions/index.rst | 93 ++++++++++++++++--- 1 file changed, 80 insertions(+), 13 deletions(-) diff --git a/reference/sql/sql_functions/scalar_functions/index.rst b/reference/sql/sql_functions/scalar_functions/index.rst index 1a7d639b3..114d26cd6 100644 --- a/reference/sql/sql_functions/scalar_functions/index.rst +++ b/reference/sql/sql_functions/scalar_functions/index.rst @@ -1,20 +1,87 @@ .. _scalar_functions: **************** -Built-In Scalar functions +Built-In Scalar Functions **************** -Built-in scalar functions return one value per call. +The **Built-In Scalar Functions** page describes functions that return one value per call: +.. hlist:: + :columns: 5 -.. toctree:: - :maxdepth: 1 - :caption: Built-in scalar functions - :glob: - - bitwise/* - conditionals/* - conversion/* - date_and_time/* - numeric/* - string/* \ No newline at end of file + + * `AND `_ + * `NOT `_ + * `OR `_ + * `SHIFT_LEFT `_ + * `SHIFT_RIGHT `_ + * `XOR `_ + * :ref:`between` + * :ref:`case` + * :ref:`coalesce` + * :ref:`in` + * :ref:`is_ascii` + * :ref:`is_null` + * :ref:`isnull` + * :ref:`from_unixts` + * :ref:`to_hex` + * :ref:`to_unixts` + * :ref:`curdate` + * :ref:`current_date` + * :ref:`current_timestamp` + * :ref:`dateadd` + * :ref:`datediff` + * :ref:`datepart` + * :ref:`eomonth` + * :ref:`extract` + * :ref:`getdate` + * :ref:`sysdate` + * :ref:`trunc` + * :ref:`abs` + * :ref:`acos` + * :ref:`asin` + * :ref:`atan` + * :ref:`atn2` + * :ref:`ceiling` + * :ref:`cos` + * :ref:`cot` + * :ref:`crc64` + * :ref:`degrees` + * :ref:`exp` + * :ref:`floor` + * :ref:`log` + * :ref:`log10` + * :ref:`mod` + * :ref:`pi` + * :ref:`power` + * :ref:`radians` + * :ref:`round` + * :ref:`sin` + * :ref:`sqrt` + * :ref:`square` + * :ref:`tan` + * :ref:`trunc` + * :ref:`char_length` + * :ref:`charindex` + * :ref:`concat` + * :ref:`isprefixof` + * :ref:`left` + * :ref:`len` + * :ref:`like` + * :ref:`lower` + * :ref:`ltrim` + * :ref:`octet_length` + * :ref:`patindex` + * :ref:`regexp_count` + * :ref:`regexp_instr` + * :ref:`regexp_replace` + * :ref:`regexp_substr` + * :ref:`repeat` + * :ref:`replace` + * :ref:`reverse` + * :ref:`right` + * :ref:`rlike` + * :ref:`rtrim` + * :ref:`substring` + * :ref:`trim` + * :ref:`upper` \ No newline at end of file From 58c097b2b9d0f8eca39b1ca90a85843d176fde3b Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Wed, 23 Mar 2022 13:50:14 +0200 Subject: [PATCH 010/316] Updated System Functions Menu --- .../system_functions/explain.rst | 59 ++++ .../sql_functions/system_functions/index.rst | 12 +- .../system_functions/show_connections.rst | 78 +++++ .../system_functions/show_locks.rst | 79 +++++ .../system_functions/show_node_info.rst | 310 ++++++++++++++++++ .../system_functions/show_server_status.rst | 108 ++++++ .../system_functions/stop_statement.rst | 77 +++++ 7 files changed, 719 insertions(+), 4 deletions(-) create mode 100644 reference/sql/sql_functions/system_functions/explain.rst create mode 100644 reference/sql/sql_functions/system_functions/show_connections.rst create mode 100644 reference/sql/sql_functions/system_functions/show_locks.rst create mode 100644 reference/sql/sql_functions/system_functions/show_node_info.rst create mode 100644 reference/sql/sql_functions/system_functions/show_server_status.rst create mode 100644 reference/sql/sql_functions/system_functions/stop_statement.rst diff --git a/reference/sql/sql_functions/system_functions/explain.rst b/reference/sql/sql_functions/system_functions/explain.rst new file mode 100644 index 000000000..e9b7e7ee9 --- /dev/null +++ b/reference/sql/sql_functions/system_functions/explain.rst @@ -0,0 +1,59 @@ +.. _explain: + +***************** +EXPLAIN +***************** + +``EXPLAIN`` returns a static query plan, which can be used to debug query plans. + +To see an actively running query or statement, use :ref:`show_node_info` instead. + +See also :ref:`show_node_info`, :ref:`show_server_status`. + + +Permissions +============= + +The role must have the ``SELECT`` permissions for any tables referenced by the query. + +Syntax +========== + +.. code-block:: postgres + + explain_statement ::= + SELECT EXPLAIN(query_stmt) + ; + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``query_stmt`` + - The select query to generate the plan for. + +Notes +=========== + +Use dollar-quoting to escape the query text + +Examples +=========== + +Generating a static query plan +---------------------------------- + +.. code-block:: psql + + t=> SELECT EXPLAIN($$SELECT DATEADD(hour,1,dt) FROM cool_dates$$); + Select + Specific (TTNative Gpu) (dateadd@null := dt@null, + dateadd@val := (pure_if dt@null "0" (addHoursdt2dt dt@val "1"))) + Table Scan + public.cool_dates ("dt@null", "dt@val") [] + diff --git a/reference/sql/sql_functions/system_functions/index.rst b/reference/sql/sql_functions/system_functions/index.rst index 734a9133a..a27dfda62 100644 --- a/reference/sql/sql_functions/system_functions/index.rst +++ b/reference/sql/sql_functions/system_functions/index.rst @@ -3,14 +3,18 @@ ******************** System Functions ******************** +**System functions** are used for returning system information, such as version and node information, and for maintenance operations that are not regularly accessed from any interface. -System functions are used for working with database objects, settings, and values. - +The System Functions page describes the following: .. toctree:: :maxdepth: 1 :glob: - :hidden: + explain show_version - + show_connections + show_locks + show_node_info + show_server_status + stop_statement \ No newline at end of file diff --git a/reference/sql/sql_functions/system_functions/show_connections.rst b/reference/sql/sql_functions/system_functions/show_connections.rst new file mode 100644 index 000000000..1bd320a4c --- /dev/null +++ b/reference/sql/sql_functions/system_functions/show_connections.rst @@ -0,0 +1,78 @@ +.. _show_connections: + +******************** +SHOW_CONNECTIONS +******************** + +``SHOW_CONNECTIONS`` returns a list of active sessions on the current worker. + +To see sessions across the cluster, see :ref:`show_server_status`. + +Permissions +============= + +The role must have the ``SUPERUSER`` permissions. + +Syntax +========== + +.. code-block:: postgres + + show_connections_statement ::= + SELECT SHOW_CONNECTIONS() + ; + +Parameters +============ + +None + +Returns +========= + +This function returns a list of active sessions. If no sessions are active on the worker, the result set will be empty. + +.. list-table:: Result columns + :widths: auto + :header-rows: 1 + + * - ``ip`` + - The worker hostname or IP + * - ``conn_id`` + - Connection ID + * - ``conn_start_time`` + - Connection start timestamp + * - ``stmt_id`` + - Statement ID. Connections with no active statement display ``-1``. + * - ``stmt_start_time`` + - Statement start timestamp + * - ``stmt`` + - Statement text + + +Notes +=========== + +* This utility shows the active connections. Some sessions may be actively connected, but not currently running a statement. + +* A connection is typically reused. There could be many statements under a single connection ID. + +Examples +=========== + +Using ``SHOW_CONNECTIONS`` to get statement IDs +---------------------------------------------------- + + +.. code-block:: psql + + t=> SELECT SHOW_CONNECTIONS(); + ip | conn_id | conn_start_time | stmt_id | stmt_start_time | stmt + -------------+---------+---------------------+---------+---------------------+-------------------------- + 192.168.1.91 | 103 | 2019-12-24 00:01:27 | 129 | 2019-12-24 00:38:18 | SELECT GET_DATE(), * F... + 192.168.1.91 | 23 | 2019-12-24 00:01:27 | -1 | 2019-12-24 00:01:27 | + 192.168.1.91 | 22 | 2019-12-24 00:01:27 | -1 | 2019-12-24 00:01:27 | + 192.168.1.91 | 26 | 2019-12-24 00:01:28 | -1 | 2019-12-24 00:01:28 | + + +The statement ID we're interested in is ``129``. We can see the connection started at 00:01:27, while the statement started at 00:38:18. \ No newline at end of file diff --git a/reference/sql/sql_functions/system_functions/show_locks.rst b/reference/sql/sql_functions/system_functions/show_locks.rst new file mode 100644 index 000000000..d5e7c02ec --- /dev/null +++ b/reference/sql/sql_functions/system_functions/show_locks.rst @@ -0,0 +1,79 @@ +.. _show_locks: + +******************** +SHOW_LOCKS +******************** + +``SHOW_LOCKS`` returns a list of locks from across the cluster. + +Read more about locks in :ref:`concurrency_and_locks`. + +Permissions +============= + +The role must have the ``SUPERUSER`` permissions. + +Syntax +========== + +.. code-block:: postgres + + show_locks_statement ::= + SELECT SHOW_LOCKS() + ; + +Parameters +============ + +None + +Returns +========= + +This function returns a list of active locks. If no locks are active in the cluster, the result set will be empty. + +.. list-table:: Result columns + :widths: auto + :header-rows: 1 + + * - ``stmt_id`` + - Statement ID that caused the lock. + * - ``stmt_string`` + - Statement text + * - ``username`` + - The role that executed the statement + * - ``server`` + - The worker node's IP + * - ``port`` + - The worker node's port + * - ``locked_object`` + - The full qualified name of the object being locked, separated with ``$`` (e.g. ``table$t$public$nba2`` for table ``nba2`` in schema ``public``, in database ``t`` + * - ``lockmode`` + - The locking mode (:ref:`inclusive` or :ref:`exclusive`). + * - ``statement_start_time`` + - Timestamp the statement started + * - ``lock_start_time`` + - Timestamp the lock was obtained + + +Examples +=========== + +Using ``SHOW_LOCKS`` to see active locks +--------------------------------------------------- + +In this example, we create a table based on results (:ref:`create_table_as`), but we are also effectively dropping the previous table (by using ``OR REPLACE``). Thus, SQream DB applies locks during the table creation process to prevent the table from being altered during it's creation. + + +.. code-block:: psql + + t=> SELECT SHOW_LOCKS(); + statement_id | statement_string | username | server | port | locked_object | lockmode | statement_start_time | lock_start_time + -------------+-------------------------------------------------------------------------------------------------+----------+--------------+------+---------------------------------+-----------+----------------------+-------------------- + 287 | CREATE OR REPLACE TABLE nba2 AS SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | sqream | 192.168.1.91 | 5000 | database$t | Inclusive | 2019-12-26 00:03:30 | 2019-12-26 00:03:30 + 287 | CREATE OR REPLACE TABLE nba2 AS SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | sqream | 192.168.1.91 | 5000 | globalpermission$ | Exclusive | 2019-12-26 00:03:30 | 2019-12-26 00:03:30 + 287 | CREATE OR REPLACE TABLE nba2 AS SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | sqream | 192.168.1.91 | 5000 | schema$t$public | Inclusive | 2019-12-26 00:03:30 | 2019-12-26 00:03:30 + 287 | CREATE OR REPLACE TABLE nba2 AS SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | sqream | 192.168.1.91 | 5000 | table$t$public$nba2$Insert | Exclusive | 2019-12-26 00:03:30 | 2019-12-26 00:03:30 + 287 | CREATE OR REPLACE TABLE nba2 AS SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | sqream | 192.168.1.91 | 5000 | table$t$public$nba2$Update | Exclusive | 2019-12-26 00:03:30 | 2019-12-26 00:03:30 + + diff --git a/reference/sql/sql_functions/system_functions/show_node_info.rst b/reference/sql/sql_functions/system_functions/show_node_info.rst new file mode 100644 index 000000000..345d16440 --- /dev/null +++ b/reference/sql/sql_functions/system_functions/show_node_info.rst @@ -0,0 +1,310 @@ +.. _show_node_info: + +******************** +SHOW_NODE_INFO +******************** + +``SHOW_NODE_INFO`` returns a snapshot of the current query plan, similar to ``EXPLAIN ANALYZE`` from other databases. + +The snapshot provides information about execution which can be used for monitoring and troubleshooting slow running statements by helping identify long-running execution nodes (components that process data), etc. + +See also :ref:`explain`, :ref:`show_server_status`. + +Permissions +============= + +The role must have the ``SUPERUSER`` permissions. + +Syntax +========== + +.. code-block:: postgres + + show_node_info_statement ::= + SELECT SHOW_NODE_INFO(stmt_id) + ; + + stmt_id ::= bigint + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``stmt_id`` + - The statement ID to explore + +Returns +========= + +This utility returns details of the execution nodes, if the statement is still running. + +If the statement has finished, or the statment ID does not exist, the utility returns an empty result set. + +.. list-table:: Result columns + :widths: auto + :header-rows: 1 + + * - Column name + - Description + * - ``stmt_id`` + - The ID for the statement + * - ``node_id`` + - This node's ID in this execution plan + * - ``node_type`` + - The node type + * - ``rows`` + - Total number of rows this node has processed + * - ``chunks`` + - Number of chunks this node has processed + * - ``avg_rows_in_chunk`` + - Average amount of rows that this node processes in each chunk (``rows / chunks``) + * - ``time`` + - Timestamp for this node's creation + * - ``parent_node_id`` + - The ``node_id`` of this node's parent + * - ``read`` + - Total data read from disk + * - ``write`` + - Total data written to disk + * - ``comment`` + - Additional information (e.g. table name for ``ReadTable``) + * - ``timesum`` + - Total elapsed time for this execution node's processing + + +.. _node_types: + +Node types +============= + +This is a full list of node types: + +.. list-table:: Node types + :widths: auto + :header-rows: 1 + + * - Column name + - Execution location + - Description + * - ``AddChunkId`` + - + - Used during insert operations + * - ``AddSequences`` + - + - Used during insert operations, with :ref:`identity columns` + * - ``AddMinMaxMetadata`` + - + - Used to calculate ranges for the :ref:`chunk metadata system` + * - ``AddTopSortFilters`` + - + - An operation to optimize ``LIMIT`` when used alongside ``ORDER BY`` + * - ``Compress`` + - CPU and GPU + - Compress data with both CPU and GPU schemes + * - ``CpuDecompress`` + - CPU + - Decompression operation, common for longer ``VARCHAR`` types + * - ``CpuLoopJoin`` + - CPU + - A non-indexed nested loop join, performed on the CPU + * - ``CpuReduce`` + - CPU + - A reduce process performed on the CPU, primarily with ``DISTINCT`` aggregates (e.g. ``COUNT(DISTINCT ...)``) + * - ``CpuToGpu``, ``GpuToCpu`` + - + - An operation that moves data to or from the GPU for processing + * - ``CpuTransform`` + - CPU + - A transform operation performed on the CPU, usually a :ref:`scalar function` + * - ``CrossJoin`` + - + - A join without a join condition + * - ``DeferredGather`` + - CPU + - Merges the results of GPU operations with a result set [#f0]_ + * - ``Distinct`` + - GPU + - Removes duplicate rows (usually as part of the ``DISTINCT`` operation) + * - ``Distinct_Merge`` + - CPU + - The merge operation of the ``Distinct`` operation + * - ``Filter`` + - GPU + - A filtering operation, such as a ``WHERE`` or ``JOIN`` clause + * - ``GpuCopy`` + - GPU + - Copies data between GPUs or within a single GPU + * - ``GpuDecompress`` + - GPU + - Decompression operation + * - ``GpuReduceMerge`` + - GPU + - An operation to optimize part of the merger phases in the GPU + * - ``GpuTransform`` + - GPU + - A transformation operation such as a type cast or :ref:`scalar function` + * - ``Hash`` + - CPU + - Hashes the output result. Used internally. + * - ``JoinSideMarker`` + - + - Used internally. + * - ``LiteralValues`` + - CPU + - Creates a virtual relation (table), when :ref:`values` is used + * - ``LocateFiles`` + - CPU + - Validates external file paths for foreign data wrappers, expanding directories and GLOB patterns + * - ``LoopJoin`` + - GPU + - A non-indexed nested loop join, performed on the GPU + * - ``MarkMatchedJoinRows`` + - + - Used in outer joins, matches rows for larger join operations + * - ``NullifyDuplicates`` + - + - Replaces duplicate values with ``NULL`` to calculate distinct aggregates + * - ``NullSink`` + - CPU + - Used internally + * - ``ParseCsv`` + - CPU + - A CSV parser, used after ``ReadFiles`` to convert the CSV into columnar data + * - ``PopNetworkQueue`` + - CPU + - Fetches data from the network queue (e.g. when used with :ref:`insert`) + * - ``PushToNetworkQueue`` + - CPU + - Sends result sets to a client connected over the network + * - ``ReadCatalog`` + - CPU + - Converts the :ref:`catalog` into a relation (table) + * - ``ReadFiles`` + - CPU + - Reads external flat-files + * - ``ReadOrc`` + - CPU + - Reads data from an ORC file + * - ``ReadParquet`` + - CPU + - Reads data from a Parquet file + * - ``ReadTable`` + - CPU + - Reads data from a standard table stored on disk + * - ``ReadTableMetadata`` + - CPU + - Reads only table metadata as an optimization + * - ``Rechunk`` + - + - Reorganize multiple small :ref:`chunks` into a full chunk. Commonly found after joins and when :ref:`HIGH_SELECTIVITY` is used + * - ``Reduce`` + - GPU + - A reduction operation, such as a ``GROUP BY`` + * - ``ReduceMerge`` + - GPU + - A merge operation of a reduction operation, helps operate on larger-than-RAM data + * - ``ReorderInput`` + - + - Change the order of arguments in preparation for the next operation + * - ``SeparatedGather`` + - GPU + - Gathers additional columns for the result + * - ``Sort`` + - GPU + - Sort operation [#f1]_ + * - ``SortMerge`` + - CPU + - A merge operation of a sort operation, helps operate on larger-than-RAM data + * - ``SortMergeJoin`` + - GPU + - A sort-merge join, performed on the GPU + * - ``TakeRowsFromChunk`` + - + - Take the first N rows from each chunk, to optimize ``LIMIT`` when used alongside ``ORDER BY`` + * - ``Top`` + - + - Limits the input size, when used with ``LIMIT`` (or its alias ``TOP``) + * - ``UdfTransform`` + - CPU + - Executes a :ref:`user defined function` + * - ``UnionAll`` + - + - Combines two sources of data when ``UNION ALL`` is used + * - ``VarCharJoiner`` + - + - Used internally + * - ``VarCharSplitter`` + - + - Used intenrally + * - ``Window`` + - GPU + - Executes a non-ranking :ref:`window function` + * - ``WindowRanking`` + - GPU + - Executes a ranking :ref:`window function` + * - ``WriteTable`` + - CPU + - Writes the result set to a standard table stored on disk + +.. rubric:: Footnotes + +.. [#f0] Gathers columns which should be returned. This node typically spends most of the time on decompressing additional columns. + +.. [#f1] A GPU sort operation can be added by the statement compiler before ``GROUP BY`` or ``JOIN`` operations. + +Statement statuses +======================= + +.. include:: /reference/sql/sql_statements/monitoring_commands/show_server_status.rst + :start-line: 67 + :end-line: 84 + +Notes +=========== + +* This utility shows the execution information for active statements. Once a query has finished execution, the information is no longer available using this utility. See :ref:`logging` for more information about extracting the information from the logs. + +* This utility is primarily intended for troubleshooting with SQream support. + +Examples +=========== + +Getting execution details for a statement +------------------------------------------------ + + +.. code-block:: psql + + t=> SELECT SHOW_SERVER_STATUS(); + service | instanceid | connection_id | serverip | serverport | database_name | user_name | clientip | statementid | statement | statementstarttime | statementstatus | statementstatusstart + --------+------------+---------------+--------------+------------+---------------+-----------+--------------+-------------+-----------------------------------------------------------------+---------------------+-----------------+--------------------- + sqream | | 152 | 192.168.1.91 | 5000 | t | sqream | 192.168.1.91 | 176 | SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | 25-12-2019 23:53:13 | Executing | 25-12-2019 23:53:13 + sqream | | 151 | 192.168.1.91 | 5000 | t | sqream | 192.168.0.1 | 177 | SELECT show_server_status() | 25-12-2019 23:51:31 | Executing | 25-12-2019 23:53:13 + + +The statement ID we want to reserach is ``176``, running on worker ``192.168.1.91``. + +The query text is ``SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1;`` + +.. code-block:: psql + + t=> SELECT SHOW_NODE_INFO(176); + stmt_id | node_id | node_type | rows | chunks | avg_rows_in_chunk | time | parent_node_id | read | write | comment | timeSum + --------+---------+--------------------+------+--------+-------------------+---------------------+----------------+------+-------+------------+-------- + 176 | 1 | PushToNetworkQueue | 1 | 1 | 1 | 2019-12-25 23:53:13 | -1 | | | | 0.0025 + 176 | 2 | Rechunk | 1 | 1 | 1 | 2019-12-25 23:53:13 | 1 | | | | 0 + 176 | 3 | GpuToCpu | 1 | 1 | 1 | 2019-12-25 23:53:13 | 2 | | | | 0 + 176 | 4 | ReorderInput | 1 | 1 | 1 | 2019-12-25 23:53:13 | 3 | | | | 0 + 176 | 5 | Filter | 1 | 1 | 1 | 2019-12-25 23:53:13 | 4 | | | | 0.0002 + 176 | 6 | GpuTransform | 457 | 1 | 457 | 2019-12-25 23:53:13 | 5 | | | | 0.0002 + 176 | 7 | GpuDecompress | 457 | 1 | 457 | 2019-12-25 23:53:13 | 6 | | | | 0 + 176 | 8 | CpuToGpu | 457 | 1 | 457 | 2019-12-25 23:53:13 | 7 | | | | 0.0003 + 176 | 9 | Rechunk | 457 | 1 | 457 | 2019-12-25 23:53:13 | 8 | | | | 0 + 176 | 10 | CpuDecompress | 457 | 1 | 457 | 2019-12-25 23:53:13 | 9 | | | | 0 + 176 | 11 | ReadTable | 457 | 1 | 457 | 2019-12-25 23:53:13 | 10 | 4MB | | public.nba | 0.0004 + diff --git a/reference/sql/sql_functions/system_functions/show_server_status.rst b/reference/sql/sql_functions/system_functions/show_server_status.rst new file mode 100644 index 000000000..f59f79ccc --- /dev/null +++ b/reference/sql/sql_functions/system_functions/show_server_status.rst @@ -0,0 +1,108 @@ +.. _show_server_status: + +******************** +SHOW_SERVER_STATUS +******************** + +``SHOW_SERVER_STATUS`` returns a list of active sessions across the cluster. + +To list active statements on the current worker only, see :ref:`show_connections`. + +Permissions +============= + +The role must have the ``SUPERUSER`` permissions. + +Syntax +========== + +.. code-block:: postgres + + show_server_status_statement ::= + SELECT SHOW_SERVER_STATUS() + ; + +Parameters +============ + +None + +Returns +========= + +This function returns a list of active sessions. If no sessions are active across the cluster, the result set will be empty. + +.. list-table:: Result columns + :widths: auto + :header-rows: 1 + + * - ``service`` + - The service name for the statement + * - ``instance`` + - The worker ID + * - ``connection_id`` + - Connection ID + * - ``serverip`` + - Worker end-point IP + * - ``serverport`` + - Worker end-point port + * - ``database_name`` + - Database name for the statement + * - ``user_name`` + - Username running the statement + * - ``clientip`` + - Client IP + * - ``statementid`` + - Statement ID + * - ``statement`` + - Statement text + * - ``statementstarttime`` + - Statement start timestamp + * - ``statementstatus`` + - Statement status (see table below) + * - ``statementstatusstart`` + - Last updated timestamp + +.. include from here: 66 + + +.. list-table:: Statement status values + :widths: auto + :header-rows: 1 + + * - Status + - Description + * - ``Preparing`` + - Statement is being prepared + * - ``In queue`` + - Statement is waiting for execution + * - ``Initializing`` + - Statement has entered execution checks + * - ``Executing`` + - Statement is executing + * - ``Stopping`` + - Statement is in the process of stopping + + +.. include until here 86 + +Notes +=========== + +* This utility shows the active sessions. Some sessions may be actively connected, but not running any statements. + +Examples +=========== + +Using ``SHOW_SERVER_STATUS`` to get statement IDs +---------------------------------------------------- + + +.. code-block:: psql + + t=> SELECT SHOW_SERVER_STATUS(); + service | instanceid | connection_id | serverip | serverport | database_name | user_name | clientip | statementid | statement | statementstarttime | statementstatus | statementstatusstart + --------+------------+---------------+--------------+------------+---------------+------------+-------------+-------------+-----------------------------+---------------------+-----------------+--------------------- + sqream | | 102 | 192.168.1.91 | 5000 | t | rhendricks | 192.168.0.1 | 128 | SELECT SHOW_SERVER_STATUS() | 24-12-2019 00:14:53 | Executing | 24-12-2019 00:14:53 + +The statement ID is ``128``, running on worker ``192.168.1.91``. diff --git a/reference/sql/sql_functions/system_functions/stop_statement.rst b/reference/sql/sql_functions/system_functions/stop_statement.rst new file mode 100644 index 000000000..30efc25b5 --- /dev/null +++ b/reference/sql/sql_functions/system_functions/stop_statement.rst @@ -0,0 +1,77 @@ +.. _stop_statement: + +******************** +STOP_STATEMENT +******************** + +``STOP_STATEMENT`` stops or aborts an active statement. + +To find a statement by ID, see :ref:`show_server_status` and :ref:`show_connections`. + +.. tip:: Some DBMSs call this process killing a session, terminating a job, or kill query + +Permissions +============= + +The role must have the ``SUPERUSER`` permissions. + +Syntax +========== + +.. code-block:: postgres + + stop_statement_statement ::= + SELECT STOP_STATEMENT(stmt_id) + ; + + stmt_id ::= bigint + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``stmt_id`` + - The statement ID to stop + +Returns +========= + +This utility does not return any value, and always succeeds even if the statement does not exist, or has already stopped. + + +Notes +=========== + +* This utility always succeeds even if the statement does not exist, or has already stopped. + +Examples +=========== + +Using :ref:`show_connections` to get statement IDs +---------------------------------------------------- + +.. tip:: Use :ref:`show_server_status` to find statments from across the entire cluster, or :ref:`show_connections` to show statements from the current worker the client is connected to. + +.. code-block:: psql + + t=> SELECT SHOW_CONNECTIONS(); + ip | conn_id | conn_start_time | stmt_id | stmt_start_time | stmt + -------------+---------+---------------------+---------+---------------------+-------------------------- + 192.168.1.91 | 103 | 2019-12-24 00:01:27 | 129 | 2019-12-24 00:38:18 | SELECT GET_DATE(), * F... + 192.168.1.91 | 23 | 2019-12-24 00:01:27 | -1 | 2019-12-24 00:01:27 | + 192.168.1.91 | 22 | 2019-12-24 00:01:27 | -1 | 2019-12-24 00:01:27 | + 192.168.1.91 | 26 | 2019-12-24 00:01:28 | -1 | 2019-12-24 00:01:28 | + + +The statement ID we're interested in is ``129``. We can now stop this statement: + +.. code-block:: psql + + t=> SELECT STOP_STATEMENT(129) + executed + From 19b8851e92a8bce01d1651e9664b17bd119942b2 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Wed, 23 Mar 2022 15:55:38 +0200 Subject: [PATCH 011/316] Corrected error in Release Date table --- releases/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/releases/index.rst b/releases/index.rst index 9158933a4..d06a7a8bf 100644 --- a/releases/index.rst +++ b/releases/index.rst @@ -14,7 +14,7 @@ Release Notes - Release Date * - :ref:`2022.1` - April 17, 2022 - * - :ref:`2022.1` + * - :ref:`2021.2` - September 13, 2021 * - :ref:`2021.1` - June 13, 2021 @@ -37,4 +37,4 @@ Release Notes 2021.1_index 2020.3_index 2020.2 - 2020.1 + 2020.1 \ No newline at end of file From 103d94bc1e19d29f308d464f01b91ffb26cbb5cd Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 24 Mar 2022 13:01:52 +0200 Subject: [PATCH 012/316] Updated Encryption --- feature_guides/data_encryption.rst | 3 +- feature_guides/data_encryption_flow.rst | 17 +++- feature_guides/data_encryption_methods.rst | 5 +- .../data_encryption_permissions.rst | 19 ++++ feature_guides/data_encryption_process.rst | 88 +++++++++++++++++++ feature_guides/data_encryption_syntax.rst | 25 ++++-- feature_guides/data_encryption_types.rst | 14 ++- 7 files changed, 152 insertions(+), 19 deletions(-) create mode 100644 feature_guides/data_encryption_permissions.rst create mode 100644 feature_guides/data_encryption_process.rst diff --git a/feature_guides/data_encryption.rst b/feature_guides/data_encryption.rst index e312e7fff..3e9f485fb 100644 --- a/feature_guides/data_encryption.rst +++ b/feature_guides/data_encryption.rst @@ -13,6 +13,7 @@ The **Data Encryption** page describes the following: data_encryption_overview data_encryption_methods data_encryption_types + data_encryption_permissions data_encryption_syntax - data_encryption_flow + data_encryption_process data_encryption_use_cases \ No newline at end of file diff --git a/feature_guides/data_encryption_flow.rst b/feature_guides/data_encryption_flow.rst index f65b1d240..03f60fb44 100644 --- a/feature_guides/data_encryption_flow.rst +++ b/feature_guides/data_encryption_flow.rst @@ -1,9 +1,9 @@ -.. _data_encryption_flow: +.. _data_encryption_process: *********************** -Data Encryption Flow +Data Encryption Process *********************** -The **Data Encryption Flow** page describes the following: +The **Data Encryption Process** page describes end-to-end encryption process, and describes the following: .. contents:: :local: @@ -11,8 +11,19 @@ The **Data Encryption Flow** page describes the following: Encryption ---------------- +The following describes the encryption process: +1. Users with the required encryption execution permission access the system (see Permissions & privileges section) +User will choose the specific columns he would like to encrypt in the file in which he will upload (see constraints section), the syntax will encapsulates the hint which will trigger the encryption (see syntax section) + +User will provide the location of the master key from which the encryption will be derived in the remote repository (whether KMS or IBM SKLM) see syntax section for the exact convention (this section will not be applied in the MVP scope) + +User will trigger the copy command and the data will be transported upon TLS session (not yet data at rest encryption) + +Once data arrived to Sqream database it will be encrypted and saved + +For more information, see :ref:`data_encryption_permissions`. Decryption ---------------- diff --git a/feature_guides/data_encryption_methods.rst b/feature_guides/data_encryption_methods.rst index 031f263b3..0069b161c 100644 --- a/feature_guides/data_encryption_methods.rst +++ b/feature_guides/data_encryption_methods.rst @@ -16,8 +16,11 @@ Encrypting Data in Transit For more information, see the following: * :ref:`copy_from` -* :ref:`jdbc` +* `JDBC `_ * :ref:`odbc` Encrypting Data at Rest ---------------- +For **data at rest,** housed physically on computer data, you can encrypt one or more column as needed according to your specifications. Data at rest is encrypted before being written into files, and decrypted after being read from them. All existing unencrypted historical and data inserted into this column at a later time is encrypted for the specified column values. Data at rest is encrypted (**Comment** - *And decrypted?*) using the **AES-256** algorithm. + +**Comment** - *Because the encryption keys are hidden from users, I didn't document them here. Please confirm that this is correct.* \ No newline at end of file diff --git a/feature_guides/data_encryption_permissions.rst b/feature_guides/data_encryption_permissions.rst new file mode 100644 index 000000000..309d75654 --- /dev/null +++ b/feature_guides/data_encryption_permissions.rst @@ -0,0 +1,19 @@ +.. _data_encryption_permissions: + +*********************** +Permissions +*********************** +Any user who granted with the appropriated permission privilege's for encryption + +Implementation notes +Date format is out of the scope of this feature as well as Varchar (due to upcoming deprecation) + +one method to encrypt the data with is the TDE: Transparent data encryption which employed by Microsoft/IBM/Oracle etc. + +management. The requirement is that this will be programmatic via API. + +The centralized key management store should be one of the following (R&D to choose which one in accordance to easiness of deployment): + +KMS (AWS)- https://aws.amazon.com/kms/ + +IBM- IBM Security Guardium Key Lifecycle Manager - Overview \ No newline at end of file diff --git a/feature_guides/data_encryption_process.rst b/feature_guides/data_encryption_process.rst new file mode 100644 index 000000000..b84bb2969 --- /dev/null +++ b/feature_guides/data_encryption_process.rst @@ -0,0 +1,88 @@ +.. _data_encryption_process: + +*********************** +Data Encryption Process +*********************** +The **Data Encryption Process** page describes end-to-end encryption process, and describes the following: + +.. contents:: + :local: + :depth: 1 + +The Encryption Process +---------------- +The following describes the encryption process: + +1. A user with the required encryption execution permission accesses the system. + + :: + +#. In the file to be uploaded, the user selects columns to encrypt. The syntax will (**Comment** - *"should" instead of "will"?)* includes the hint that triggers the encryption (see syntax section). + + :: + +#. The user provides the location of the master key for deriving (**Comment** - *...generating/activating?*) the encryption in the remote repository. This applies to both **KMS** and **IBM SKLM**. + + :: + + **Comment** - *The source doc says, "this section will not be applied in the MVP scope." Should it stay in this doc?* + + :: + +#. The user trigger (**Comment** - *"runs"?*) the COPY command to transport the data upon TLS session (not yet data at rest encryption) (**Comment** - *"Upon TLS session = when the TLS session is activated?"* + + :: + +#. When the data is successfully inserted into the SQream database, it is encrypted and saved. + +For more information, see the following: + +* More information on permissions, see :ref:`data_encryption_permissions`. + + :: + +* More information on which columns to encrypt, see the :ref:`Constraints` section below. + + :: + +* More information on triggering the encryption, and the master key location syntax, see :ref:`data_encryption_syntax`. + +The Decryption Process +---------------- +The following describes the encryption process: + +1. A user with the required encryption execution permission accesses the system. + + :: + +#. The user indicates the decryption. **Comment** - *"Indicates" = "triggers"?*) + + :: + +#. The user can view the data derived from a table holding the encrypted data by decrypting the data by providing the location of the master key and selecting the required fields. + + : + + **Comment** - the source doc said, "this section will not be applied in the MVP scope." Should it stay in this doc?* + +Once the specific statement ends- the user will be able to see the data in a human readable convention (plain text) + +For more information, see the following: + +* More information on triggering the decryption, see :ref:`data_encryption_syntax`. + + + + +Encrypted Columns +---------------- +Column/Table-level encryption - More granular approach, encrypt only what you really need to + + + +.. _constraints: + +Constraints +---------------- +Describe these in one of the existing sections. + diff --git a/feature_guides/data_encryption_syntax.rst b/feature_guides/data_encryption_syntax.rst index 8df3e0d33..85cef25ee 100644 --- a/feature_guides/data_encryption_syntax.rst +++ b/feature_guides/data_encryption_syntax.rst @@ -3,13 +3,14 @@ *********************** Syntax *********************** - The **Syntax** page describes the following: .. contents:: :local: :depth: 1 - + +Encrypting a New Table +---------------- The following is the correct syntax for **encrypting** a new table: .. code-block:: console @@ -24,7 +25,11 @@ The following is an example of encrypting a new table: .. code-block:: console EXAMPLE - + +**Comment** - *Please provide an actual example.* + +Decrypting a New Table +---------------- The following is the correct syntax for **decrypting** a new table: .. code-block:: console @@ -37,8 +42,16 @@ The following is an example of decrypting a new table: EXAMPLE -Usage notes - this should be included on this page. +**Comment** - *Please provide an actual example.* + +Incorrectly Encrypting or Decrypting Your Data +---------------- +Using the incorrect master key or location while encrypting or decrypting generates an error. -When inputting the wrong master key/location in encryption/decryption an error should be raised to the user +**Comment** - *Can I get an example of this error to include in the doc?* + +**Comment** - *I thought that the master key was completely hidden from users... The internal doc says, "Master Key- the key will be generated within the server side, it will reside within a repository which will be hidden from the user."* + +In logs, master keys are masked to protect user privacy. Users are responsible for maintaining their master keys for the remote repository. -The master key needs to be masked in logs to protect user privacy, the responsibility maintaining the master key for the remote repository is on the user side \ No newline at end of file +**Comment** - *I'm not sure I fully understand the part about maintaing the master keys on the remote repository.* \ No newline at end of file diff --git a/feature_guides/data_encryption_types.rst b/feature_guides/data_encryption_types.rst index 331b14f58..3da9071c2 100644 --- a/feature_guides/data_encryption_types.rst +++ b/feature_guides/data_encryption_types.rst @@ -3,14 +3,12 @@ *********************** Data Types *********************** +SQream's data encryption supports the following data types: +* INT +* BIGINT +* TEXT -Per the research done and per customer requirement the data types that should be supported are the following: +Typically speaking, this data pertains to **PII (Personally Identifiable Information)**, which is sensitive information such as credit card numbers and other information related to an identifiable person. -Int - -BigInt - -String - -On most cases this data type, if encrypted, will be populated by PII value (Personal Identifiable Information) such as credit card number and other personal and sensitive information \ No newline at end of file +For more information on the above data types, see :ref:`supported_data_types`. \ No newline at end of file From 190ce170b9c1b09401454d8c2a143ba6c6716b48 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 24 Mar 2022 14:14:25 +0200 Subject: [PATCH 013/316] Updated --- feature_guides/data_encryption.rst | 3 +- feature_guides/data_encryption_flow.rst | 43 ------------------- feature_guides/data_encryption_overview.rst | 22 +++++++++- .../data_encryption_permissions.rst | 5 ++- feature_guides/data_encryption_process.rst | 24 +++++------ feature_guides/data_encryption_use_cases.rst | 14 ------ 6 files changed, 36 insertions(+), 75 deletions(-) delete mode 100644 feature_guides/data_encryption_flow.rst delete mode 100644 feature_guides/data_encryption_use_cases.rst diff --git a/feature_guides/data_encryption.rst b/feature_guides/data_encryption.rst index 3e9f485fb..e8f919217 100644 --- a/feature_guides/data_encryption.rst +++ b/feature_guides/data_encryption.rst @@ -15,5 +15,4 @@ The **Data Encryption** page describes the following: data_encryption_types data_encryption_permissions data_encryption_syntax - data_encryption_process - data_encryption_use_cases \ No newline at end of file + data_encryption_process \ No newline at end of file diff --git a/feature_guides/data_encryption_flow.rst b/feature_guides/data_encryption_flow.rst deleted file mode 100644 index 03f60fb44..000000000 --- a/feature_guides/data_encryption_flow.rst +++ /dev/null @@ -1,43 +0,0 @@ -.. _data_encryption_process: - -*********************** -Data Encryption Process -*********************** -The **Data Encryption Process** page describes end-to-end encryption process, and describes the following: - -.. contents:: - :local: - :depth: 1 - -Encryption ----------------- -The following describes the encryption process: - -1. Users with the required encryption execution permission access the system (see Permissions & privileges section) - -User will choose the specific columns he would like to encrypt in the file in which he will upload (see constraints section), the syntax will encapsulates the hint which will trigger the encryption (see syntax section) - -User will provide the location of the master key from which the encryption will be derived in the remote repository (whether KMS or IBM SKLM) see syntax section for the exact convention (this section will not be applied in the MVP scope) - -User will trigger the copy command and the data will be transported upon TLS session (not yet data at rest encryption) - -Once data arrived to Sqream database it will be encrypted and saved - -For more information, see :ref:`data_encryption_permissions`. - -Decryption ----------------- - - - -Encrypted Columns ----------------- -Column/Table-level encryption - More granular approach, encrypt only what you really need to - - - - -Constraints ----------------- -Describe these in one of the existing sections. - diff --git a/feature_guides/data_encryption_overview.rst b/feature_guides/data_encryption_overview.rst index 5b3f3e344..4c0455291 100644 --- a/feature_guides/data_encryption_overview.rst +++ b/feature_guides/data_encryption_overview.rst @@ -3,8 +3,26 @@ *********************** Overview *********************** -**Data Encryption** helps protect sensitive data by preventing unauthorized users from reading it in the event of a breach. This is achieved by scrambling the content into an unreadable format based on encryption and decryption keys. +**Data Encryption** helps protect sensitive data by preventing unauthorized users from reading it in the event of a breach. This is achieved by scrambling the content into an unreadable format based on encryption and decryption keys. The demand for confidentiality has steadily increased to protect the growing volumes of private data stored on computer systems and transmitted over the internet. To this end, regulatory bodies such as the **General Data Protection Regulation (GDPR)** have produced requirements to standardize and enforce compliance aimed at protecting customer data. -The demand for confidentiality has steadily increased to protect the growing volumes of private data stored on computer systems and transmitted over the internet. To this end, regulatory bodies such as the **General Data Protection Regulation (GDPR)** have produced requirements to standardize and enforce compliance aimed at protecting customer data. +Encryption can be used for the following: + +* Deleting encrypted columns. + + :: + +* Creating tables with one or more encrypted columns. + + :: + +* Joining encrypted columns with other tables. + + :: + +* Encrypting existing data. + + :: + +* Selecting data from an encrypted column. For more information on GDPR compliance requirements, see the `GDPR checklist `_. \ No newline at end of file diff --git a/feature_guides/data_encryption_permissions.rst b/feature_guides/data_encryption_permissions.rst index 309d75654..16f41dc70 100644 --- a/feature_guides/data_encryption_permissions.rst +++ b/feature_guides/data_encryption_permissions.rst @@ -3,10 +3,11 @@ *********************** Permissions *********************** -Any user who granted with the appropriated permission privilege's for encryption +Users with the appropriate encryption permission privilege's can encrypt and decrypt data. + +**Comment** - *The rest of this content seems internal, correct?* Implementation notes -Date format is out of the scope of this feature as well as Varchar (due to upcoming deprecation) one method to encrypt the data with is the TDE: Transparent data encryption which employed by Microsoft/IBM/Oracle etc. diff --git a/feature_guides/data_encryption_process.rst b/feature_guides/data_encryption_process.rst index b84bb2969..e76e6a9cc 100644 --- a/feature_guides/data_encryption_process.rst +++ b/feature_guides/data_encryption_process.rst @@ -61,28 +61,28 @@ The following describes the encryption process: #. The user can view the data derived from a table holding the encrypted data by decrypting the data by providing the location of the master key and selecting the required fields. - : + :: - **Comment** - the source doc said, "this section will not be applied in the MVP scope." Should it stay in this doc?* - -Once the specific statement ends- the user will be able to see the data in a human readable convention (plain text) - -For more information, see the following: - -* More information on triggering the decryption, see :ref:`data_encryption_syntax`. - + **Comment** - *the source doc said, "this section will not be applied in the MVP scope." Should it stay in this doc?* +#. When the statement has ended, the user can view the data in a human readable format as plain text. +For more information on triggering the decryption, see :ref:`data_encryption_syntax`. Encrypted Columns ---------------- -Column/Table-level encryption - More granular approach, encrypt only what you really need to - +**Comment** - *This section and "Constraints" don't really seem like phases in a flow, at least the way they are currently described. If they really are part of a flow, we should discuss how to reword them.* +Tables with encrypted columns are tagged with the ``encrypted`` label, allowing you to select what data to encrypt. .. _constraints: Constraints ---------------- -Describe these in one of the existing sections. +The encryption will be done in the database server- data at rest as the data will be encrypted in transit based on the TLS protocol. + +**Comment** - *I need some clarification on the sentence above.* + +Users without permissions to view tables with one or more encrypted table cannot view the entire table. +**Comment** - *Please confirm that the above sentence is correct. Below is the original sentence:"* \ No newline at end of file diff --git a/feature_guides/data_encryption_use_cases.rst b/feature_guides/data_encryption_use_cases.rst deleted file mode 100644 index 9e9ddeb4a..000000000 --- a/feature_guides/data_encryption_use_cases.rst +++ /dev/null @@ -1,14 +0,0 @@ -.. _data_encryption_use_cases: - -*********************** -Use Cases -*********************** - - - - - -Use Case Considerations -============== -Include the relevant content from this section in the correct places in this document. - From 612d83f08446199608cdaf66cb36e025b7af3149 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 24 Mar 2022 14:15:14 +0200 Subject: [PATCH 014/316] Updated --- feature_guides/data_encryption.rst | 4 +- feature_guides/data_encryption_flow.rst | 32 ------- feature_guides/data_encryption_methods.rst | 5 +- feature_guides/data_encryption_process.rst | 88 ++++++++++++++++++++ feature_guides/data_encryption_syntax.rst | 25 ++++-- feature_guides/data_encryption_types.rst | 14 ++-- feature_guides/data_encryption_use_cases.rst | 14 ---- 7 files changed, 119 insertions(+), 63 deletions(-) delete mode 100644 feature_guides/data_encryption_flow.rst create mode 100644 feature_guides/data_encryption_process.rst delete mode 100644 feature_guides/data_encryption_use_cases.rst diff --git a/feature_guides/data_encryption.rst b/feature_guides/data_encryption.rst index e312e7fff..e8f919217 100644 --- a/feature_guides/data_encryption.rst +++ b/feature_guides/data_encryption.rst @@ -13,6 +13,6 @@ The **Data Encryption** page describes the following: data_encryption_overview data_encryption_methods data_encryption_types + data_encryption_permissions data_encryption_syntax - data_encryption_flow - data_encryption_use_cases \ No newline at end of file + data_encryption_process \ No newline at end of file diff --git a/feature_guides/data_encryption_flow.rst b/feature_guides/data_encryption_flow.rst deleted file mode 100644 index f65b1d240..000000000 --- a/feature_guides/data_encryption_flow.rst +++ /dev/null @@ -1,32 +0,0 @@ -.. _data_encryption_flow: - -*********************** -Data Encryption Flow -*********************** -The **Data Encryption Flow** page describes the following: - -.. contents:: - :local: - :depth: 1 - -Encryption ----------------- - - - -Decryption ----------------- - - - -Encrypted Columns ----------------- -Column/Table-level encryption - More granular approach, encrypt only what you really need to - - - - -Constraints ----------------- -Describe these in one of the existing sections. - diff --git a/feature_guides/data_encryption_methods.rst b/feature_guides/data_encryption_methods.rst index c0aae030d..0069b161c 100644 --- a/feature_guides/data_encryption_methods.rst +++ b/feature_guides/data_encryption_methods.rst @@ -16,8 +16,11 @@ Encrypting Data in Transit For more information, see the following: * :ref:`copy_from` -* `JDBC `_ +* `JDBC `_ * :ref:`odbc` Encrypting Data at Rest ---------------- +For **data at rest,** housed physically on computer data, you can encrypt one or more column as needed according to your specifications. Data at rest is encrypted before being written into files, and decrypted after being read from them. All existing unencrypted historical and data inserted into this column at a later time is encrypted for the specified column values. Data at rest is encrypted (**Comment** - *And decrypted?*) using the **AES-256** algorithm. + +**Comment** - *Because the encryption keys are hidden from users, I didn't document them here. Please confirm that this is correct.* \ No newline at end of file diff --git a/feature_guides/data_encryption_process.rst b/feature_guides/data_encryption_process.rst new file mode 100644 index 000000000..e76e6a9cc --- /dev/null +++ b/feature_guides/data_encryption_process.rst @@ -0,0 +1,88 @@ +.. _data_encryption_process: + +*********************** +Data Encryption Process +*********************** +The **Data Encryption Process** page describes end-to-end encryption process, and describes the following: + +.. contents:: + :local: + :depth: 1 + +The Encryption Process +---------------- +The following describes the encryption process: + +1. A user with the required encryption execution permission accesses the system. + + :: + +#. In the file to be uploaded, the user selects columns to encrypt. The syntax will (**Comment** - *"should" instead of "will"?)* includes the hint that triggers the encryption (see syntax section). + + :: + +#. The user provides the location of the master key for deriving (**Comment** - *...generating/activating?*) the encryption in the remote repository. This applies to both **KMS** and **IBM SKLM**. + + :: + + **Comment** - *The source doc says, "this section will not be applied in the MVP scope." Should it stay in this doc?* + + :: + +#. The user trigger (**Comment** - *"runs"?*) the COPY command to transport the data upon TLS session (not yet data at rest encryption) (**Comment** - *"Upon TLS session = when the TLS session is activated?"* + + :: + +#. When the data is successfully inserted into the SQream database, it is encrypted and saved. + +For more information, see the following: + +* More information on permissions, see :ref:`data_encryption_permissions`. + + :: + +* More information on which columns to encrypt, see the :ref:`Constraints` section below. + + :: + +* More information on triggering the encryption, and the master key location syntax, see :ref:`data_encryption_syntax`. + +The Decryption Process +---------------- +The following describes the encryption process: + +1. A user with the required encryption execution permission accesses the system. + + :: + +#. The user indicates the decryption. **Comment** - *"Indicates" = "triggers"?*) + + :: + +#. The user can view the data derived from a table holding the encrypted data by decrypting the data by providing the location of the master key and selecting the required fields. + + :: + + **Comment** - *the source doc said, "this section will not be applied in the MVP scope." Should it stay in this doc?* + +#. When the statement has ended, the user can view the data in a human readable format as plain text. + +For more information on triggering the decryption, see :ref:`data_encryption_syntax`. + +Encrypted Columns +---------------- +**Comment** - *This section and "Constraints" don't really seem like phases in a flow, at least the way they are currently described. If they really are part of a flow, we should discuss how to reword them.* + +Tables with encrypted columns are tagged with the ``encrypted`` label, allowing you to select what data to encrypt. + +.. _constraints: + +Constraints +---------------- +The encryption will be done in the database server- data at rest as the data will be encrypted in transit based on the TLS protocol. + +**Comment** - *I need some clarification on the sentence above.* + +Users without permissions to view tables with one or more encrypted table cannot view the entire table. + +**Comment** - *Please confirm that the above sentence is correct. Below is the original sentence:"* \ No newline at end of file diff --git a/feature_guides/data_encryption_syntax.rst b/feature_guides/data_encryption_syntax.rst index 8df3e0d33..85cef25ee 100644 --- a/feature_guides/data_encryption_syntax.rst +++ b/feature_guides/data_encryption_syntax.rst @@ -3,13 +3,14 @@ *********************** Syntax *********************** - The **Syntax** page describes the following: .. contents:: :local: :depth: 1 - + +Encrypting a New Table +---------------- The following is the correct syntax for **encrypting** a new table: .. code-block:: console @@ -24,7 +25,11 @@ The following is an example of encrypting a new table: .. code-block:: console EXAMPLE - + +**Comment** - *Please provide an actual example.* + +Decrypting a New Table +---------------- The following is the correct syntax for **decrypting** a new table: .. code-block:: console @@ -37,8 +42,16 @@ The following is an example of decrypting a new table: EXAMPLE -Usage notes - this should be included on this page. +**Comment** - *Please provide an actual example.* + +Incorrectly Encrypting or Decrypting Your Data +---------------- +Using the incorrect master key or location while encrypting or decrypting generates an error. -When inputting the wrong master key/location in encryption/decryption an error should be raised to the user +**Comment** - *Can I get an example of this error to include in the doc?* + +**Comment** - *I thought that the master key was completely hidden from users... The internal doc says, "Master Key- the key will be generated within the server side, it will reside within a repository which will be hidden from the user."* + +In logs, master keys are masked to protect user privacy. Users are responsible for maintaining their master keys for the remote repository. -The master key needs to be masked in logs to protect user privacy, the responsibility maintaining the master key for the remote repository is on the user side \ No newline at end of file +**Comment** - *I'm not sure I fully understand the part about maintaing the master keys on the remote repository.* \ No newline at end of file diff --git a/feature_guides/data_encryption_types.rst b/feature_guides/data_encryption_types.rst index 331b14f58..3da9071c2 100644 --- a/feature_guides/data_encryption_types.rst +++ b/feature_guides/data_encryption_types.rst @@ -3,14 +3,12 @@ *********************** Data Types *********************** +SQream's data encryption supports the following data types: +* INT +* BIGINT +* TEXT -Per the research done and per customer requirement the data types that should be supported are the following: +Typically speaking, this data pertains to **PII (Personally Identifiable Information)**, which is sensitive information such as credit card numbers and other information related to an identifiable person. -Int - -BigInt - -String - -On most cases this data type, if encrypted, will be populated by PII value (Personal Identifiable Information) such as credit card number and other personal and sensitive information \ No newline at end of file +For more information on the above data types, see :ref:`supported_data_types`. \ No newline at end of file diff --git a/feature_guides/data_encryption_use_cases.rst b/feature_guides/data_encryption_use_cases.rst deleted file mode 100644 index 9e9ddeb4a..000000000 --- a/feature_guides/data_encryption_use_cases.rst +++ /dev/null @@ -1,14 +0,0 @@ -.. _data_encryption_use_cases: - -*********************** -Use Cases -*********************** - - - - - -Use Case Considerations -============== -Include the relevant content from this section in the correct places in this document. - From 0a20c1e28ca017b7fef582d9c4415fced9174a5a Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 24 Mar 2022 14:23:43 +0200 Subject: [PATCH 015/316] Create data_encryption_permissions.rst --- .../data_encryption_permissions.rst | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 feature_guides/data_encryption_permissions.rst diff --git a/feature_guides/data_encryption_permissions.rst b/feature_guides/data_encryption_permissions.rst new file mode 100644 index 000000000..16f41dc70 --- /dev/null +++ b/feature_guides/data_encryption_permissions.rst @@ -0,0 +1,20 @@ +.. _data_encryption_permissions: + +*********************** +Permissions +*********************** +Users with the appropriate encryption permission privilege's can encrypt and decrypt data. + +**Comment** - *The rest of this content seems internal, correct?* + +Implementation notes + +one method to encrypt the data with is the TDE: Transparent data encryption which employed by Microsoft/IBM/Oracle etc. + +management. The requirement is that this will be programmatic via API. + +The centralized key management store should be one of the following (R&D to choose which one in accordance to easiness of deployment): + +KMS (AWS)- https://aws.amazon.com/kms/ + +IBM- IBM Security Guardium Key Lifecycle Manager - Overview \ No newline at end of file From f57d54e70fdf69de418df37c2c42dd0980657d62 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 24 Mar 2022 15:35:01 +0200 Subject: [PATCH 016/316] Update data_encryption_overview.rst --- feature_guides/data_encryption_overview.rst | 22 +++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/feature_guides/data_encryption_overview.rst b/feature_guides/data_encryption_overview.rst index 5b3f3e344..4c0455291 100644 --- a/feature_guides/data_encryption_overview.rst +++ b/feature_guides/data_encryption_overview.rst @@ -3,8 +3,26 @@ *********************** Overview *********************** -**Data Encryption** helps protect sensitive data by preventing unauthorized users from reading it in the event of a breach. This is achieved by scrambling the content into an unreadable format based on encryption and decryption keys. +**Data Encryption** helps protect sensitive data by preventing unauthorized users from reading it in the event of a breach. This is achieved by scrambling the content into an unreadable format based on encryption and decryption keys. The demand for confidentiality has steadily increased to protect the growing volumes of private data stored on computer systems and transmitted over the internet. To this end, regulatory bodies such as the **General Data Protection Regulation (GDPR)** have produced requirements to standardize and enforce compliance aimed at protecting customer data. -The demand for confidentiality has steadily increased to protect the growing volumes of private data stored on computer systems and transmitted over the internet. To this end, regulatory bodies such as the **General Data Protection Regulation (GDPR)** have produced requirements to standardize and enforce compliance aimed at protecting customer data. +Encryption can be used for the following: + +* Deleting encrypted columns. + + :: + +* Creating tables with one or more encrypted columns. + + :: + +* Joining encrypted columns with other tables. + + :: + +* Encrypting existing data. + + :: + +* Selecting data from an encrypted column. For more information on GDPR compliance requirements, see the `GDPR checklist `_. \ No newline at end of file From a8098779ceca48b97315f701190cc24739e506f7 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 24 Mar 2022 15:50:56 +0200 Subject: [PATCH 017/316] Update data_encryption.rst --- feature_guides/data_encryption.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/feature_guides/data_encryption.rst b/feature_guides/data_encryption.rst index e8f919217..4e51a28aa 100644 --- a/feature_guides/data_encryption.rst +++ b/feature_guides/data_encryption.rst @@ -13,6 +13,6 @@ The **Data Encryption** page describes the following: data_encryption_overview data_encryption_methods data_encryption_types + data_encryption_process data_encryption_permissions - data_encryption_syntax - data_encryption_process \ No newline at end of file + data_encryption_syntax \ No newline at end of file From b673e26fc0d5bcb1aad12e5f207642cac08a1da5 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 24 Mar 2022 15:53:11 +0200 Subject: [PATCH 018/316] Update data_encryption.rst --- feature_guides/data_encryption.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/feature_guides/data_encryption.rst b/feature_guides/data_encryption.rst index e8f919217..4e51a28aa 100644 --- a/feature_guides/data_encryption.rst +++ b/feature_guides/data_encryption.rst @@ -13,6 +13,6 @@ The **Data Encryption** page describes the following: data_encryption_overview data_encryption_methods data_encryption_types + data_encryption_process data_encryption_permissions - data_encryption_syntax - data_encryption_process \ No newline at end of file + data_encryption_syntax \ No newline at end of file From 27b3f7eb1b3aec050bb828f88ef4d39fa3845fe6 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 27 Mar 2022 15:23:30 +0300 Subject: [PATCH 019/316] Added Missing Statements (2) CLUSTER BY and DROP CLUSTERING KEYS were missing from DDL table. --- .../aggregate_functions/index.rst | 38 +++++++++---------- .../sql_functions/scalar_functions/index.rst | 1 + reference/sql/sql_statements/index.rst | 4 ++ 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/reference/sql/sql_functions/aggregate_functions/index.rst b/reference/sql/sql_functions/aggregate_functions/index.rst index 9bf0527d6..5d3dfc125 100644 --- a/reference/sql/sql_functions/aggregate_functions/index.rst +++ b/reference/sql/sql_functions/aggregate_functions/index.rst @@ -6,31 +6,27 @@ Aggregate Functions Overview =========== - Aggregate functions perform calculations based on a set of values and return a single value. Most aggregate functions ignore null values. Aggregate functions are often used with the ``GROUP BY`` clause of the :ref:`select` statement. Available Aggregate Functions =============== The following list shows the available aggregate functions: - -.. toctree:: - :maxdepth: 1 - :glob: +.. hlist:: + :columns: 2 - - avg - corr - count - covar_pop - covar_samp - max - min - mode - percentile_cont - percentile_disc - stddev_pop - stddev_samp - sum - var_pop - var_samp + * :ref:`AVG` + * :ref:`CORR` + * :ref:`COUNT` + * :ref:`COVAR_POP` + * :ref:`COVAR_SAMP` + * :ref:`MAX` + * :ref:`MIN` + * :ref:`MODE` + * :ref:`PERCENTILE_CONT` + * :ref:`PERCENTILE_DISC` + * :ref:`STDDEV_POP` + * :ref:`STDDEV_SAMP` + * :ref:`SUM` + * :ref:`VAR_POP` + * :ref:`VAR_SAMP` \ No newline at end of file diff --git a/reference/sql/sql_functions/scalar_functions/index.rst b/reference/sql/sql_functions/scalar_functions/index.rst index 114d26cd6..b21071021 100644 --- a/reference/sql/sql_functions/scalar_functions/index.rst +++ b/reference/sql/sql_functions/scalar_functions/index.rst @@ -3,6 +3,7 @@ **************** Built-In Scalar Functions **************** +FF The **Built-In Scalar Functions** page describes functions that return one value per call: diff --git a/reference/sql/sql_statements/index.rst b/reference/sql/sql_statements/index.rst index 8ecd680df..28096f16a 100644 --- a/reference/sql/sql_statements/index.rst +++ b/reference/sql/sql_statements/index.rst @@ -24,6 +24,8 @@ Data Definition Commands (DDL) - Change the default schema for a role * - :ref:`ALTER TABLE` - Change the schema of a table + * - :ref:`CLUSTER BY` + - Change clustering keys in a table * - :ref:`CREATE DATABASE` - Create a new database * - :ref:`CREATE EXTERNAL TABLE` @@ -40,6 +42,8 @@ Data Definition Commands (DDL) - Create a new table in the database using results from a select query * - :ref:`CREATE VIEW` - Create a new view in the database + * - :ref:`DROP CLUSTERING KEY` + - Drops all clustering keys in a table * - :ref:`DROP COLUMN` - Drop a column from a table * - :ref:`DROP DATABASE` From 85f8481db98e14ea9d1fddb8f75c438a7db22540 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 27 Mar 2022 16:02:44 +0300 Subject: [PATCH 020/316] Deleted DDL Files (backed up) Tried method of removing the statements from topic menu, and linking directly to them. The list in topic menu was too long. --- .../ddl_commands/add_column.rst | 91 ------ .../ddl_commands/alter_default_schema.rst | 58 ---- .../ddl_commands/alter_table.rst | 33 --- .../ddl_commands/cluster_by.rst | 69 ----- .../ddl_commands/create_database.rst | 55 ---- .../ddl_commands/create_external_table.rst | 156 ---------- .../ddl_commands/create_foreign_table.rst | 165 ----------- .../ddl_commands/create_function.rst | 103 ------- .../ddl_commands/create_schema.rst | 92 ------ .../ddl_commands/create_table.rst | 278 ------------------ .../ddl_commands/create_table_as.rst | 96 ------ .../ddl_commands/create_view.rst | 79 ----- .../ddl_commands/drop_clustering_key.rst | 64 ---- .../ddl_commands/drop_column.rst | 63 ---- .../ddl_commands/drop_database.rst | 63 ---- .../ddl_commands/drop_function.rst | 66 ----- .../ddl_commands/drop_schema.rst | 77 ----- .../ddl_commands/drop_table.rst | 70 ----- .../sql_statements/ddl_commands/drop_view.rst | 72 ----- .../ddl_commands/rename_column.rst | 65 ---- .../ddl_commands/rename_table.rst | 57 ---- reference/sql/sql_statements/index.rst | 84 +++--- 22 files changed, 42 insertions(+), 1914 deletions(-) delete mode 100644 reference/sql/sql_statements/ddl_commands/add_column.rst delete mode 100644 reference/sql/sql_statements/ddl_commands/alter_default_schema.rst delete mode 100644 reference/sql/sql_statements/ddl_commands/alter_table.rst delete mode 100644 reference/sql/sql_statements/ddl_commands/cluster_by.rst delete mode 100644 reference/sql/sql_statements/ddl_commands/create_database.rst delete mode 100644 reference/sql/sql_statements/ddl_commands/create_external_table.rst delete mode 100644 reference/sql/sql_statements/ddl_commands/create_foreign_table.rst delete mode 100644 reference/sql/sql_statements/ddl_commands/create_function.rst delete mode 100644 reference/sql/sql_statements/ddl_commands/create_schema.rst delete mode 100644 reference/sql/sql_statements/ddl_commands/create_table.rst delete mode 100644 reference/sql/sql_statements/ddl_commands/create_table_as.rst delete mode 100644 reference/sql/sql_statements/ddl_commands/create_view.rst delete mode 100644 reference/sql/sql_statements/ddl_commands/drop_clustering_key.rst delete mode 100644 reference/sql/sql_statements/ddl_commands/drop_column.rst delete mode 100644 reference/sql/sql_statements/ddl_commands/drop_database.rst delete mode 100644 reference/sql/sql_statements/ddl_commands/drop_function.rst delete mode 100644 reference/sql/sql_statements/ddl_commands/drop_schema.rst delete mode 100644 reference/sql/sql_statements/ddl_commands/drop_table.rst delete mode 100644 reference/sql/sql_statements/ddl_commands/drop_view.rst delete mode 100644 reference/sql/sql_statements/ddl_commands/rename_column.rst delete mode 100644 reference/sql/sql_statements/ddl_commands/rename_table.rst diff --git a/reference/sql/sql_statements/ddl_commands/add_column.rst b/reference/sql/sql_statements/ddl_commands/add_column.rst deleted file mode 100644 index d532c956f..000000000 --- a/reference/sql/sql_statements/ddl_commands/add_column.rst +++ /dev/null @@ -1,91 +0,0 @@ -.. _add_column: - -********************** -ADD COLUMN -********************** - -The ``ADD COLUMN`` command is used to add columns to an existing table. - - - -Syntax -========== -The following is the correct syntax for adding a table: - -.. code-block:: postgres - - alter_table_add_column_statement ::= - ALTER TABLE [schema_name.]table_name { ADD COLUMN column_def [, ...] } - ; - - table_name ::= identifier - - schema_name ::= identifier - - column_def :: = { column_name type_name [ default ] [ column_constraint ] } - - column_name ::= identifier - - column_constraint ::= - { NOT NULL | NULL } - - default ::= - DEFAULT default_value - - - -Parameters -============ -The following parameters can be used for adding a table: - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``schema_name`` - - The schema name for the table. Defaults to ``public`` if not specified. - * - ``table_name`` - - The table name to apply the change to. - * - ``ADD COLUMN column_def`` - - A comma separated list of ADD COLUMN commands - * - ``column_def`` - - A column definition. A minimal column definition includes a name identifier and a datatype. Other column constraints and default values can be added optionally. - -.. note:: - * When adding a new column to an existing table, a default (or null constraint) has to be specified, even if the table is empty. - * A new column added to the table can not contain an IDENTITY or be of the TEXT type. - - -Permissions -============= -The role must have the ``DDL`` permission at the database or table level. - -Examples -=========== -This section includes the following examples: - -.. contents:: - :local: - :depth: 1 - -Adding a Simple Column with a Default Value ------------------------------------------ -This example shows how to add a simple column with a default value: - -.. code-block:: postgres - - ALTER TABLE cool_animals - ADD COLUMN number_of_eyes INT DEFAULT 2 NOT NULL; - - -Adding Several Columns in One Command -------------------------------------------- -This example shows how to add several columns in one command: - -.. code-block:: postgres - - ALTER TABLE cool_animals - ADD COLUMN number_of_eyes INT DEFAULT 2 NOT NULL, - ADD COLUMN date_seen DATE DEFAULT '2019-08-01'; diff --git a/reference/sql/sql_statements/ddl_commands/alter_default_schema.rst b/reference/sql/sql_statements/ddl_commands/alter_default_schema.rst deleted file mode 100644 index e40a8af7c..000000000 --- a/reference/sql/sql_statements/ddl_commands/alter_default_schema.rst +++ /dev/null @@ -1,58 +0,0 @@ -.. _alter_default_schema: - -********************** -ALTER DEFAULT SCHEMA -********************** - -The ``ALTER DEFAULT SCHEMA`` command can be used to change a role's default schema. The default schema in SQream is ``public``. - -For more information, see :ref:`create_schema` and :ref:`drop_schema`. - - - -Syntax -========== -The following is the correct syntax for altering a default schema: - -.. code-block:: postgres - - alter_default_schema_statement ::= - ALTER DEFAULT SCHEMA FOR role_name TO schema_name - ; - - role_name ::= identifier - - schema_name ::= identifier - - - -Parameters -============ -The following parameters can be used when altering a default schema: - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``role_name`` - - The name of the role the change will apply to. - * - ``schema_name`` - - The new default schema name. - -Permissions -============= -No special permissions are required. - -Examples -=========== -This section includes an example of **altering the default schema for a role**: - -.. code-block:: postgres - - SELECT * FROM users; -- Refers to public.users - - ALTER DEFAULT SCHEMA FOR bgilfoyle TO staging; - - SELECT * FROM users; -- Now refers to staging.users, rather than public.users diff --git a/reference/sql/sql_statements/ddl_commands/alter_table.rst b/reference/sql/sql_statements/ddl_commands/alter_table.rst deleted file mode 100644 index 6afb84be1..000000000 --- a/reference/sql/sql_statements/ddl_commands/alter_table.rst +++ /dev/null @@ -1,33 +0,0 @@ -.. _alter_table: - -********************** -ALTER TABLE -********************** -You can use the ``ALTER TABLE`` command to make schema changes to a table, and can be used in conjunction with several sub-commands. - -Locks -======= -Making changes to a schema makes an exclusive lock on tables. While these operations do not typically take much time, other statements may have to wait until the schema changes are completed. - -Sub-Commands -============== -The following table shows the sub-commands that can be used with the ``ALTER TABLE`` command: - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Command - - Usage - * - :ref:`ADD COLUMN` - - Adds a new column to a table. - * - :ref:`DROP COLUMN` - - Drops a column from a table. - * - :ref:`RENAME COLUMN` - - Renames a column. - * - :ref:`RENAME TABLE` - - Renames a table. - * - :ref:`CLUSTER BY` - - Modifies (adds or reorders) the clustering keys in a table. - * - :ref:`DROP CLUSTERING KEY` - - Drops all clustering keys. diff --git a/reference/sql/sql_statements/ddl_commands/cluster_by.rst b/reference/sql/sql_statements/ddl_commands/cluster_by.rst deleted file mode 100644 index 1a6972b1e..000000000 --- a/reference/sql/sql_statements/ddl_commands/cluster_by.rst +++ /dev/null @@ -1,69 +0,0 @@ -.. _cluster_by: - -********************** -CLUSTER BY -********************** - -``CLUSTER BY`` can be used to change clustering keys in a table. - - -Read our :ref:`data_clustering` guide for more information. - -See also: :ref:`drop_clustering_key`, :ref:`create_table`. - - -Permissions -============= - -The role must have the ``DDL`` permission at the database or table level. - -Syntax -========== - -.. code-block:: postgres - - alter_table_rename_table_statement ::= - ALTER TABLE [schema_name.]table_name CLUSTER BY column_name [, ...] - ; - - table_name ::= identifier - - column_name ::= identifier - - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``schema_name`` - - The schema name for the table. Defaults to ``public`` if not specified. - * - ``table_name`` - - The table name to apply the change to. - * - ``column_name [, ... ]`` - - Comma separated list of columns to create clustering keys for - - -Usage notes -================= - -Removing clustering keys does not affect existing data. - -To force data to re-cluster, the table has to be recreated (i.e. with :ref:`create_table_as`). - - -Examples -=========== - -Reclustering a table ------------------------------------------ - -.. code-block:: postgres - - ALTER TABLE public.users CLUSTER BY start_date; - - diff --git a/reference/sql/sql_statements/ddl_commands/create_database.rst b/reference/sql/sql_statements/ddl_commands/create_database.rst deleted file mode 100644 index db7ffda3f..000000000 --- a/reference/sql/sql_statements/ddl_commands/create_database.rst +++ /dev/null @@ -1,55 +0,0 @@ -.. _create_database: - -***************** -CREATE DATABASE -***************** - -``CREATE DATABASE`` creates a new database in SQream DB - -Permissions -============= - -Only a superuser can create a new database - -Syntax -========== - -.. code-block:: postgres - - create_database_statement ::= - - CREATE DATABASE database_name ; - - database_name ::= identifier - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``database_name`` - - The name of the database name. The database name must be unique, and follows :ref:`Identifier rules ` - -Examples -=========== - -.. code-block:: postgres - - CREATE DATABASE raviga; - -.. code-block:: postgres - - CREATE DATABASE my_db; - -If the database already exists, an error will appear: - -.. code-block:: psql - - master=> CREATE DATABASE MY_DB; - Database 'my_db' already exists - -.. note:: SQream DB :ref:`identifiers ` are always converted to lowercase, so ``my_db`` is the same as ``MY_DB``, unless explicitly quoted as ``"MY_DB"``. \ No newline at end of file diff --git a/reference/sql/sql_statements/ddl_commands/create_external_table.rst b/reference/sql/sql_statements/ddl_commands/create_external_table.rst deleted file mode 100644 index fc05ca71e..000000000 --- a/reference/sql/sql_statements/ddl_commands/create_external_table.rst +++ /dev/null @@ -1,156 +0,0 @@ -.. _create_external_table: - -*********************** -CREATE EXTERNAL TABLE -*********************** - -.. warning:: - - The ``CREATE EXTERNAL TABLE`` syntax is deprecated, and will be removed in future versions. - - Starting with SQream DB v2020.2, external tables have been renamed to :ref:`foreign tables`, and use a more flexible foreign data wrapper concept. See :ref:`create_foreign_table` instead. - - Upgrading to a new version of SQream DB converts existing tables automatically. When creating a new external tables, use the new foreign table syntax. - - -``CREATE TABLE`` creates a new external table in an existing database. - -See more in the :ref:`External tables guide`. - -.. tip:: - - * Data in an external table can change if the sources change, and frequent access to remote files may harm performance. - - * To create a regular table, see :ref:`CREATE TABLE ` - -Permissions -============= - -The role must have the ``CREATE`` permission at the database level. - -Syntax -========== - -.. code-block:: postgres - - create_table_statement ::= - CREATE [ OR REPLACE ] EXTERNAL TABLE [schema_name].table_name ( - { column_def [, ...] } - ) - USING FORMAT format_def - WITH { external_table_option [ ...] } - ; - - schema_name ::= identifier - - table_name ::= identifier - - format_def ::= { PARQUET | ORC | CSV } - - external_table_option ::= { - PATH '{ path_spec }' - | FIELD DELIMITER '{ field_delimiter }' - | RECORD DELIMITER '{ record_delimiter }' - | AWS_ID '{ AWS ID }' - | AWS_SECRET '{ AWS SECRET }' - } - - path_spec ::= { local filepath | S3 URI | HDFS URI } - - field_delimiter ::= delimiter_character - - record_delimiter ::= delimiter_character - - column_def ::= { column_name type_name [ default ] [ column_constraint ] } - - column_name ::= identifier - - column_constraint ::= - { NOT NULL | NULL } - - default ::= - - DEFAULT default_value - | IDENTITY [ ( start_with [ , increment_by ] ) ] - -.. _cet_parameters: - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``OR REPLACE`` - - Create a new table, and overwrite any existing table by the same name. Does not return an error if the table already exists. ``CREATE OR REPLACE`` does not check the table contents or structure, only the table name. - * - ``schema_name`` - - The name of the schema in which to create the table. - * - ``table_name`` - - The name of the table to create, which must be unique inside the schema. - * - ``column_def`` - - A comma separated list of column definitions. A minimal column definition includes a name identifier and a datatype. Other column constraints and default values can be added optionally. - * - ``USING FORMAT ...`` - - Specifies the format of the source files, such as ``PARQUET``, ``ORC``, or ``CSV``. - * - ``WITH PATH ...`` - - Specifies a path or URI of the source files, such as ``/path/to/*.parquet``. - * - ``FIELD DELIMITER`` - - Specifies the field delimiter for CSV files. Defaults to ``,``. - * - ``RECORD DELIMITER`` - - Specifies the record delimiter for CSV files. Defaults to a newline, ``\n`` - * - ``AWS_ID``, ``AWS_SECRET`` - - Credentials for authenticated S3 access - - -Examples -=========== - -A simple table from Tab-delimited file (TSV) ----------------------------------------------- - -.. code-block:: postgres - - CREATE OR REPLACE EXTERNAL TABLE cool_animals - (id INT NOT NULL, name VARCHAR(30) NOT NULL, weight FLOAT NOT NULL) - USING FORMAT csv - WITH PATH '/home/rhendricks/cool_animals.csv' - FIELD DELIMITER '\t'; - - -A table from a directory of Parquet files on HDFS ------------------------------------------------------ - -.. code-block:: postgres - - CREATE EXTERNAL TABLE users - (id INT NOT NULL, name VARCHAR(30) NOT NULL, email VARCHAR(50) NOT NULL) - USING FORMAT Parquet - WITH PATH 'hdfs://hadoop-nn.piedpiper.com/rhendricks/users/*.parquet'; - -A table from a bucket of files on S3 --------------------------------------- - -.. code-block:: postgres - - CREATE EXTERNAL TABLE users - (id INT NOT NULL, name VARCHAR(30) NOT NULL, email VARCHAR(50) NOT NULL) - USING FORMAT Parquet - WITH PATH 's3://pp-secret-bucket/users/*.parquet' - AWS_ID 'our_aws_id' - AWS_SECRET 'our_aws_secret'; - - -Changing an external table to a regular table ------------------------------------------------- - -Materializes an external table into a regular table. - -.. tip: Using an external table allows you to perform ETL-like operations in SQream DB by applying SQL functions and operations to raw files - -.. code-block:: postgres - - CREATE TABLE real_table - AS SELECT * FROM external_table; - diff --git a/reference/sql/sql_statements/ddl_commands/create_foreign_table.rst b/reference/sql/sql_statements/ddl_commands/create_foreign_table.rst deleted file mode 100644 index d50e13380..000000000 --- a/reference/sql/sql_statements/ddl_commands/create_foreign_table.rst +++ /dev/null @@ -1,165 +0,0 @@ -.. _create_foreign_table: - -*********************** -CREATE FOREIGN TABLE -*********************** - -.. note:: - - Starting with SQream DB v2020.2, external tables have been renamed to foreign tables, and use a more flexible foreign data wrapper concept. - - Upgrading to a new version of SQream DB converts existing external tables automatically. - - -``CREATE FOREIGN TABLE`` creates a new foreign table in an existing database. - -See more in the :ref:`Foreign tables guide`. - -.. tip:: - - * Data in a foreign table can change if the sources change, and frequent access to remote files may harm performance. - - * To create a regular table, see :ref:`CREATE TABLE ` - -Permissions -============= - -The role must have the ``CREATE`` permission at the database level. - -Syntax -========== - -.. code-block:: postgres - - create_table_statement ::= - CREATE [ OR REPLACE ] FOREIGN TABLE [schema_name].table_name ( - { column_def [, ...] } - ) - [ FOREIGN DATA ] WRAPPER fdw_name - [ OPTIONS ( option_def [, ... ] ) ] - ; - - schema_name ::= identifier - - table_name ::= identifier - - fdw_name ::= - { csv_fdw | orc_fdw | parquet_fdw } - - option_def ::= - { - LOCATION = '{ path_spec }' - | DELIMITER = '{ field_delimiter }' -- for CSV only - | RECORD_DELIMITER = '{ record_delimiter }' -- for CSV only - | AWS_ID '{ AWS ID }' - | AWS_SECRET '{ AWS SECRET }' - } - - path_spec ::= { local filepath | S3 URI | HDFS URI } - - field_delimiter ::= delimiter_character - - record_delimiter ::= delimiter_character - - column_def ::= - { column_name type_name [ default ] [ column_constraint ] } - - column_name ::= identifier - - column_constraint ::= - { NOT NULL | NULL } - - default ::= - DEFAULT default_value - | IDENTITY [ ( start_with [ , increment_by ] ) ] - -.. _cft_parameters: - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``OR REPLACE`` - - Create a new table, and overwrite any existing table by the same name. Does not return an error if the table already exists. ``CREATE OR REPLACE`` does not check the table contents or structure, only the table name. - * - ``schema_name`` - - The name of the schema in which to create the table. - * - ``table_name`` - - The name of the table to create, which must be unique inside the schema. - * - ``column_def`` - - A comma separated list of column definitions. A minimal column definition includes a name identifier and a datatype. Other column constraints and default values can be added optionally. - * - ``WRAPPER ...`` - - Specifies the format of the source files, such as ``parquet_fdw``, ``orc_fdw``, or ``csv_fdw``. - * - ``LOCATION = ...`` - - Specifies a path or URI of the source files, such as ``/path/to/*.parquet``. - * - ``DELIMITER = ...`` - - Specifies the field delimiter for CSV files. Defaults to ``,``. - * - ``RECORD_DELIMITER = ...`` - - Specifies the record delimiter for CSV files. Defaults to a newline, ``\n`` - * - ``AWS_ID``, ``AWS_SECRET`` - - Credentials for authenticated S3 access - - -Examples -=========== - -A simple table from Tab-delimited file (TSV) ----------------------------------------------- - -.. code-block:: postgres - - CREATE OR REPLACE FOREIGN TABLE cool_animals - (id INT NOT NULL, name VARCHAR(30) NOT NULL, weight FLOAT NOT NULL) - WRAPPER csv_fdw - OPTIONS - ( LOCATION = '/home/rhendricks/cool_animals.csv', - DELIMITER = '\t' - ) - ; - - -A table from a directory of Parquet files on HDFS ------------------------------------------------------ - -.. code-block:: postgres - - CREATE FOREIGN TABLE users - (id INT NOT NULL, name VARCHAR(30) NOT NULL, email VARCHAR(50) NOT NULL) - WRAPPER parquet_fdw - OPTIONS - ( - LOCATION = 'hdfs://hadoop-nn.piedpiper.com/rhendricks/users/*.parquet' - ); - -A table from a bucket of ORC files on S3 ------------------------------------------- - -.. code-block:: postgres - - CREATE FOREIGN TABLE users - (id INT NOT NULL, name VARCHAR(30) NOT NULL, email VARCHAR(50) NOT NULL) - WRAPPER orc_fdw - OPTIONS - ( - LOCATION = 's3://pp-secret-bucket/users/*.orc', - AWS_ID = 'our_aws_id', - AWS_SECRET = 'our_aws_secret' - ); - - -Changing a foreign table to a regular table ------------------------------------------------- - -Materializes a foreign table into a regular table. - -.. tip: Using a foreign table allows you to perform ETL-like operations in SQream DB by applying SQL functions and operations to raw files - -.. code-block:: postgres - - CREATE TABLE real_table - AS SELECT * FROM some_foreign_table; - diff --git a/reference/sql/sql_statements/ddl_commands/create_function.rst b/reference/sql/sql_statements/ddl_commands/create_function.rst deleted file mode 100644 index 339543a0a..000000000 --- a/reference/sql/sql_statements/ddl_commands/create_function.rst +++ /dev/null @@ -1,103 +0,0 @@ -.. _create_function: - -***************** -CREATE FUNCTION -***************** - -``CREATE FUNCTION`` creates a new user-defined function (UDF) in an existing database. - -See more in our :ref:`Python UDF (user-defined functions)` guide. - -Permissions -============= - -The role must have the ``CREATE FUNCTION`` permission at the database level. - -Syntax -========== - -.. code-block:: postgres - - create_function_statement ::= - CREATE [ OR REPLACE ] FUNCTION function_name (argument_list) - RETURNS return_type - AS $$ - { function_body } - $$ LANGUAGE python - ; - - function_name ::= identifier - - argument_list :: = { value_name type_name [, ...] } - - value_name ::= identifier - - return_type ::= type_name - - function_body ::= Valid Python code - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``OR REPLACE`` - - Create a new function, and overwrite any existing function by the same name. Does not return an error if the function already exists. ``CREATE OR REPLACE`` does not check the function contents or structure, only the function name. - * - ``function_name`` - - The name of the function to create, which must be unique inside the database. - * - ``argument_list`` - - A comma separated list of column definitions. A column definition includes a name identifier and a datatype. - * - ``return_type`` - - The SQL datatype of the return value, such as ``INT``, ``VARCHAR``, etc. - * - ``function_body`` - - Python code, dollar-quoted (``$$``). - -Examples -=========== - -Calculate distance between two points --------------------------------------- - -.. code-block:: postgres - - CREATE OR REPLACE FUNCTION my_distance (x1 float, y1 float, x2 float, y2 float) - RETURNS FLOAT - AS $$ - import math - if y1 < x1: - return 0.0 - else: - return math.sqrt((y2 - y1) ** 2 + (x2 - x1) ** 2) - $$ LANGUAGE PYTHON; - - -- Usage: - SELECT city, my_location, my_distance(x1,y1,x2,y2) from cities; - - -Calling files from other locations ---------------------------------------- - -.. code-block:: postgres - - -- Our script my_code.py is in ~/my_python_stuff - - CREATE FUNCTION write_log() - RETURNS INT - AS $$ - import sys - sys.path.append("/home/user/my_python_stuff") - - import my_code as f - - f.main() - - return 1 - - $$ LANGUAGE PYTHON; - - -- Usage: - SELECT write_log(); diff --git a/reference/sql/sql_statements/ddl_commands/create_schema.rst b/reference/sql/sql_statements/ddl_commands/create_schema.rst deleted file mode 100644 index e85f328a9..000000000 --- a/reference/sql/sql_statements/ddl_commands/create_schema.rst +++ /dev/null @@ -1,92 +0,0 @@ -.. _create_schema: - -***************** -CREATE SCHEMA -***************** -The **CREATE SCHEMA** page describes the following: - - -.. contents:: - :local: - :depth: 2 - -Overview -============ - -``CREATE SCHEMA`` creates a new schema in an existing database. A schema is a virtual space for storing tables. - -The default schema in SQream DB is ``public``. - -.. tip:: Use schemas to separate between use-cases, such as staging and production. - -The **CREATE SCHEMA** statement can be used to query tables from different schemas without providing an alias, as in the following example: - -.. code-block:: postgres - - select .table_name.column_name from .table_name - -See also: :ref:`drop_schema`, :ref:`alter_default_schema`. - -Permissions -============= - -The role must have the ``CREATE`` permission at the database level. - -Syntax -========== -The following example shows the correct syntax for creating a schema: - -.. code-block:: postgres - - create_schema_statement ::= - CREATE SCHEMA schema_name - ; - - schema_name ::= identifier - - -Parameters -============ -The following table shows the ``schema_name`` parameters: - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``schema_name`` - - The name of the schema to create. - -Examples -=========== -This section includes the following examples: - -.. contents:: - :local: - :depth: 1 - - -Creating a Schema --------------------- -The following example shows an example of the syntax for creating a schema: - -.. code-block:: postgres - - CREATE SCHEMA staging; - - CREATE TABLE staging.users AS SELECT * FROM public.users; - - SELECT * FROM staging.users; - -Altering the Default Schema for a Role ------------------------------------------ -The following example shows an example of the syntax for altering the default schema for a role: - -.. code-block:: postgres - - SELECT * FROM users; -- Refers to public.users - - ALTER DEFAULT SCHEMA FOR bgilfoyle TO staging; - - SELECT * FROM users; -- Now refers to staging.users, rather than public.users diff --git a/reference/sql/sql_statements/ddl_commands/create_table.rst b/reference/sql/sql_statements/ddl_commands/create_table.rst deleted file mode 100644 index b660e442c..000000000 --- a/reference/sql/sql_statements/ddl_commands/create_table.rst +++ /dev/null @@ -1,278 +0,0 @@ -.. _create_table: - -***************** -CREATE TABLE -***************** - -The ``CREATE TABLE`` statement is used to create a new table in an existing database. - -.. tip:: - * To create a table based on the result of a select query, see :ref:`CREATE TABLE AS `. - * To create a table based on files like Parquet and ORC, see :ref:`CREATE FOREIGN TABLE ` - - - -Syntax -========== -The following is the correct syntax for creating a table: - -.. code-block:: postgres - - create_table_statement ::= - CREATE [ OR REPLACE ] TABLE [schema_name.]table_name ( - { column_def [, ...] } - ) - [ CLUSTER BY { column_name [, ...] } ] - ; - - schema_name ::= identifier - - table_name ::= identifier - - column_def :: = { column_name type_name [ default ] [ column_constraint ] } - - column_name ::= identifier - - column_constraint ::= - { NOT NULL | NULL } - - default ::= - DEFAULT default_value - | IDENTITY [ ( start_with [ , increment_by ] ) ] - -Parameters -============ -The following parameters can be used when creating a table: - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``OR REPLACE`` - - Creates a new tables and overwrites any existing table by the same name. Does not return an error if the table already exists. ``CREATE OR REPLACE`` does not check the table contents or structure, only the table name. - * - ``schema_name`` - - The name of the schema in which to create the table. - * - ``table_name`` - - The name of the table to create, which must be unique inside the schema. - * - ``column_def`` - - A comma separated list of column definitions. A minimal column definition includes a name identifier and a datatype. Other column constraints and default values can be added optionally. - * - ``CLUSTER BY column_name1 ...`` - - - A commma separated list of clustering column keys. - - See :ref:`data_clustering` for more information. - * - ``LIKE`` - - Duplicates the column structure of an existing table. - - -.. _default_values: - -Default Value Constraints -=============== - -The ``DEFAULT`` value constraint specifies a value to use if one is not defined in an :ref:`insert` or :ref:`copy_from` statement. - -The value may be either a literal or **GETDATE()**, which is evaluated at the time the row is created. - -.. note:: The ``DEFAULT`` constraint only applies if the column does not have a value specified in the :ref:`insert` or :ref:`copy_from` statement. You can still insert a ``NULL`` into an nullable column by explicitly inserting ``NULL``. For example, ``INSERT INTO cool_animals VALUES (1, 'Gnu', NULL)``. - -Syntax ---------- -The following is the correct syntax for using the **DEFAULT** value constraints: - - -.. code-block:: postgres - - column_def :: = { column_name type_name [ default ] [ column_constraint ] } - - column_constraint ::= - { NOT NULL | NULL } - - default ::= - DEFAULT default_value - | IDENTITY [ ( start_with [ , increment_by ] ) ] - - check_specification ::= - CHECK( 'CS compression_spec' ) - - compression_spec ::= - { "default" | "p4d" | "dict" | "rle" | "sequence" | "flat" } - - -.. _identity: - -Identity ------------------------ -The ``Identity`` (or sequence) columns can be used for generating key values. Some databases call this ``AUTOINCREMENT``. - -The **identity** property on a column guarantees that each new row inserted is generated based on the current seed & increment. - -.. warning:: - The identity property on a column does not guarantee uniqueness. The identity value can be bypassed by specifying it in an :ref:`insert` command. - -The following table describes the identity parameters: - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``start_with`` - - A value that is used for the very first row loaded into the table. - * - ``increment_by`` - - Incremental value that is added to the identity value of the previous row that was loaded. - -Examples -=========== -This section includes the following examples: - -.. contents:: - :local: - :depth: 1 - -Creating a Standard Table ------------------ -The following is an example of the syntax used to create a standard table: - -.. code-block:: postgres - - CREATE TABLE cool_animals ( - id INT NOT NULL, - name varchar(30) NOT NULL, - weight FLOAT, - is_agressive BOOL - ); - -Creating a Table with Default Value Constraints for Some Columns ---------------------------------------------------- -The following is an example of the syntax used to create a table with default value constraints for some columns: - - -.. code-block:: postgres - - CREATE TABLE cool_animals ( - id INT NOT NULL, - name varchar(30) NOT NULL, - weight FLOAT, - is_agressive BOOL DEFAULT false NOT NULL - ); - -.. note:: The nullable/non-nullable constraint appears at the end, after the default option - -Creating a Table with an Identity Column ---------------------------------------------------- -The following is an example of the syntax used to create a table with an identity (auto-increment) column: - - -.. code-block:: postgres - - CREATE TABLE users ( - id BIGINT IDENTITY(0,1) NOT NULL , -- Start with 0, increment by 1 - name VARCHAR(30) NOT NULL, - country VARCHAR(30) DEFAULT 'Unknown' NOT NULL - ); - -.. note:: - * Identity columns are supported on ``BIGINT`` columns. - - * Identity does not enforce the uniqueness of values. The identity value can be bypassed by specifying it in an :ref:`insert` command. - -Creating a Table from a SELECT Query ------------------------------------------ -The following is an example of the syntax used to create a table from a SELECT query: - -.. code-block:: postgres - - CREATE TABLE users_uk AS SELECT * FROM users WHERE country = 'United Kingdom'; - -For more information on creating a new table from the results of a SELECT query, see :ref:`CREATE TABLE AS `. - -Creating a Table with a Clustering Key ----------------------------------------------- -When data in a table is stored in a sorted order, the sorted columns are considered clustered. Good clustering can have a significant positive impact on performance. - -In the following example, we expect the ``start_date`` column to be naturally clustered, as new users sign up and get a newer start date. - -When the clustering key is set, if the incoming data isn’t naturally clustered, it will be clustered by SQream DB during insert or bulk load. - -The following is an example of the syntax used to create a table with a clustering key: - -.. code-block:: postgres - - CREATE TABLE users ( - name VARCHAR(30) NOT NULL, - start_date datetime not null, - country VARCHAR(30) DEFAULT 'Unknown' NOT NULL - ) CLUSTER BY start_date; - -For more information on data clustering, see :ref:`data_clustering`. - -Duplicating the Column Structure of an Existing Table ------------------ - -Syntax -************ -The following is the correct syntax for duplicating the column structure of an existing table: - -.. code-block:: postgres - - CREATE [OR REPLACE] TABLE table_name - { - (column_name column_type [{NULL | NOT NULL}] [,...]) - | LIKE source_table_name - } - [CLUSTER BY ...] - ; - -Examples -************** -This section includes the following examples of duplicating the column structure of an existing table using the ``LIKE`` clause: - -.. contents:: - :local: - :depth: 3 - -Creating a Table Using an Explicit Column List -~~~~~~~~~~~~ -The following is an example of creating a table using an explict column list: - -.. code-block:: postgres - - CREATE TABLE t1(x int default 0 not null, y text(10) null); - -Creating a Second Table Based on the Structure of Another Table -~~~~~~~~~~~~ -Either of the following examples can be used to create a second table based on the structure of another table. - -**Example 1** - -.. code-block:: postgres - - CREATE TABLE t2 LIKE t1; - -**Example 2** - -.. code-block:: postgres - - CREATE TABLE t2(x int default 0 not null, y text(10) null); - -The generated output of both of the statements above is identical. - -Creating a Table based on External Tables and Views -~~~~~~~~~~~~ -The following is example of creating a table based on external tables and views: - - -.. code-block:: postgres - - CREATE VIEW v as SELECT x+1,y,y || 'abc' from t1; - CREATE TABLE t3 LIKE v; - -When duplicating the column structure of an existing table, the target table of the ``LIKE`` clause can be a regular or an external table, or a view. - -Permissions -============= -The role must have the ``CREATE`` permission at the schema level. diff --git a/reference/sql/sql_statements/ddl_commands/create_table_as.rst b/reference/sql/sql_statements/ddl_commands/create_table_as.rst deleted file mode 100644 index a7f9dd4d4..000000000 --- a/reference/sql/sql_statements/ddl_commands/create_table_as.rst +++ /dev/null @@ -1,96 +0,0 @@ -.. _create_table_as: - -***************** -CREATE TABLE AS -***************** - -The ``CREATE TABLE AS`` commands creates a new table from the result of a select query. - - -Syntax -========== -The following is the correct syntax for creating a table from the result of a select query: - - -.. CREATE [ OR REPLACE ] TABLE [schema_name].table_name ( -.. { column_def [, ...] } -.. ) AS query - -.. code-block:: postgres - - create_table_statement ::= - CREATE [ OR REPLACE ] TABLE [schema_name].table_name AS query - ; - - schema_name ::= identifier - - table_name ::= identifier - - -.. _ctas_params: - -Parameters -============ -The following parameters can be used when creating a table from the result of a select query: - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``OR REPLACE`` - - Create a new table, and overwrite any existing table by the same name. Does not return an error if the table already exists. ``CREATE OR REPLACE`` does not check the table contents or structure, only the table name. - * - ``schema_name`` - - The name of the schema in which to create the table. - * - ``table_name`` - - The name of the table to create, which must be unique inside the schema. - * - ``query`` - - A select query that returns data - -.. * - ``column_def`` -.. - A comma separated list of column definitions. A minimal column definition includes a name identifier and a datatype. Other column constraints and default values can be added optionally. - -Permissions -============= -The role must have the ``CREATE`` permission at the schema level, as well as ``SELECT`` permissions for any tables referenced by the statement. - - -Examples -=========== -This section includes the following examples: - -.. contents:: - :local: - :depth: 1 - -Creating a Copy of a Foreign Table or View ---------------------------------------------------------------------------- - -.. code-block:: postgres - - CREATE TABLE users AS SELECT * FROM users_source; - -For more information, see :ref:`CREATE FOREIGN TABLE `. - -Filtering ------------- - -.. code-block:: postgres - - CREATE TABLE users_uk AS SELECT * FROM users WHERE country = 'United Kingdom'; - -Adding Columns ------------------------ - -.. code-block:: postgres - - CREATE TABLE users_uk_new AS SELECT GETDATE() as "Date",*,false as is_new FROM users_uk; - -Creating a Table From Values ------------------------------------------ - -.. code-block:: postgres - - CREATE TABLE new_users - AS VALUES(GETDATE(),'Richard','Foxworthy','1984-03-03',True) diff --git a/reference/sql/sql_statements/ddl_commands/create_view.rst b/reference/sql/sql_statements/ddl_commands/create_view.rst deleted file mode 100644 index 9812ddeec..000000000 --- a/reference/sql/sql_statements/ddl_commands/create_view.rst +++ /dev/null @@ -1,79 +0,0 @@ -.. _create_view: - -***************** -CREATE VIEW -***************** - -``CREATE VIEW`` creates a new view in an existing database. A view is a virtual table. - -.. tip:: - * Use views to simplify complex queries or present only partial data to specific roles. - * If an underlying table has changed (new columns, changed names, etc.) - a view may be invalidated. To recompile the view, see :ref:`SELECT RECOMPILE_VIEW(\)` - - -Permissions -============= - -The role must have the ``CREATE`` permission at the database level, as well as ``SELECT`` permissions for any tables referenced by the view. - -Syntax -========== - -.. code-block:: postgres - - create_view_statement ::= - CREATE VIEW [schema_name].view_name [ column_list ] - AS - query - ; - - schema_name ::= identifier - - view_name ::= identifier - - column_list ::= ( { column_name [, ...] } ) - - column_name ::= identifier - - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``schema_name`` - - The name of the schema in which to create the view. - * - ``view_name`` - - The name of the view to create, which must be unique inside the schema. - * - ``column_list`` - - An optional comma separated list of column names for the view. If specified, these column names will override the column names in the response of the query in the ``AS query`` statement. - * - ``AS query`` - - The select query to execute when the view is referenced. - -.. * - ``OR REPLACE`` -.. - Create a new view, and overwrite any existing views by the same name. Does not return an error if the view already exists. - -Examples -=========== - -A simple view ------------------ - -.. code-block:: postgres - - CREATE VIEW only_agressive_animals AS - SELECT * FROM cool_animals WHERE is_agressive=true; - - SELECT * FROM only_agressive_animals; - -Overriding default column names ---------------------------------- - -.. code-block:: postgres - - CREATE VIEW only_relaxed_animals (animal_id, animal_name, should_i_worry) AS - SELECT id, name, is_agressive FROM cool_animals WHERE is_agressive=false; diff --git a/reference/sql/sql_statements/ddl_commands/drop_clustering_key.rst b/reference/sql/sql_statements/ddl_commands/drop_clustering_key.rst deleted file mode 100644 index 41b10bdfa..000000000 --- a/reference/sql/sql_statements/ddl_commands/drop_clustering_key.rst +++ /dev/null @@ -1,64 +0,0 @@ -.. _drop_clustering_key: - -********************** -DROP CLUSTERING KEY -********************** - -``DROP CLUSTERING KEY`` drops all clustering keys in a table. - -Read our :ref:`data_clustering` guide for more information. - -See also: :ref:`cluster_by`, :ref:`create_table`. - - -Permissions -============= - -The role must have the ``DDL`` permission at the database or table level. - -Syntax -========== - -.. code-block:: postgres - - alter_table_rename_table_statement ::= - ALTER TABLE [schema_name.]table_name DROP CLUSTERING KEY - ; - - table_name ::= identifier - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``schema_name`` - - The schema name for the table. Defaults to ``public`` if not specified. - * - ``table_name`` - - The table name to apply the change to. - -Usage notes -================= - -Removing clustering keys does not affect existing data. - -To force data to re-cluster, the table has to be recreated (i.e. with :ref:`create_table_as`). - - - - -Examples -=========== - -Dropping clustering keys in a table ------------------------------------------ - -.. code-block:: postgres - - ALTER TABLE public.users DROP CLUSTERING KEY - - diff --git a/reference/sql/sql_statements/ddl_commands/drop_column.rst b/reference/sql/sql_statements/ddl_commands/drop_column.rst deleted file mode 100644 index 391367e16..000000000 --- a/reference/sql/sql_statements/ddl_commands/drop_column.rst +++ /dev/null @@ -1,63 +0,0 @@ -.. _drop_column: - -********************** -DROP COLUMN -********************** - -``DROP COLUMN`` can be used to remove columns from a table. - -Permissions -============= - -The role must have the ``DDL`` permission at the database or table level. - -Syntax -========== - -.. code-block:: postgres - - alter_table_drop_column_statement ::= - ALTER TABLE [schema_name.]table_name DROP COLUMN column_name - ; - - table_name ::= identifier - - schema_name ::= identifier - - column_name ::= identifier - - - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``schema_name`` - - The schema name for the table. Defaults to ``public`` if not specified. - * - ``table_name`` - - The table name to apply the change to. - * - ``column_name`` - - The column to remove. - -Examples -=========== - -Removing a column ------------------------------------------ - -.. code-block:: postgres - - -- Remove the 'weight' column - ALTER TABLE users DROP COLUMN weight; - -Removing a column with a quoted identifier name ----------------------------------------------------- - -.. code-block:: postgres - - ALTER TABLE users DROP COLUMN "Weight in kilograms"; \ No newline at end of file diff --git a/reference/sql/sql_statements/ddl_commands/drop_database.rst b/reference/sql/sql_statements/ddl_commands/drop_database.rst deleted file mode 100644 index 0cfbbcd30..000000000 --- a/reference/sql/sql_statements/ddl_commands/drop_database.rst +++ /dev/null @@ -1,63 +0,0 @@ -.. _drop_database: - -********************** -DROP DATABASE -********************** - -``DROP DATABASE`` can be used to remove a database and all of its objects. - -Permissions -============= - -The role must have the ``DDL`` permission at the database level. - -Syntax -========== - -.. code-block:: postgres - - drop_database_statement ::= - DROP DATABASE database_name - ; - - database_name ::= identifier - - - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``database_name`` - - The name of the database to drop. This can not be the current database in use. - -Examples -=========== - -Dropping a database and all of its objects ---------------------------------------------- - -.. code-block:: psql - - master=> DROP DATABASE raviga; - executed - - -Dropping the current database --------------------------------- - -The current database in use can't be dropped. Switch to another database first. - -.. code-block:: psql - - raviga=> DROP DATABASE raviga; - Current open database 'raviga' cannot be dropped. - - raviga=> \c master - master=> DROP DATABASE raviga; - executed \ No newline at end of file diff --git a/reference/sql/sql_statements/ddl_commands/drop_function.rst b/reference/sql/sql_statements/ddl_commands/drop_function.rst deleted file mode 100644 index 726085f9f..000000000 --- a/reference/sql/sql_statements/ddl_commands/drop_function.rst +++ /dev/null @@ -1,66 +0,0 @@ -.. _drop_function: - -********************** -DROP FUNCTION -********************** - -``DROP FUNCTION`` can be used to remove a user defined function. - -Permissions -============= - -The role must have the ``DDL`` permission at the database level. - -Syntax -========== - -.. code-block:: postgres - - drop_function_statement ::= - DROP FUNCTION [ IF EXISTS ] function_name(); - ; - - function_name ::= identifier - - - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``IF EXISTS`` - - Drop the function if it exists. Does not error if the function does not exist. - * - ``function_name()`` - - The name of the function to drop. - -Examples -=========== - -Dropping a function ---------------------------------------------- - -.. code-block:: postgres - - DROP FUNCTION my_distance(); - - -Dropping a function (always succeeds) -------------------------------------- - -.. code-block:: psql - - farm=> DROP FUNCTION my_distance(); - executed - - farm=> DROP FUNCTION my_distance(); - Function 'my_distance' not found - - -- This will succeed, even though the function does not exist - farm=> DROP FUNCTION IF EXISTS my_distance(); - executed - diff --git a/reference/sql/sql_statements/ddl_commands/drop_schema.rst b/reference/sql/sql_statements/ddl_commands/drop_schema.rst deleted file mode 100644 index c10ab7f8f..000000000 --- a/reference/sql/sql_statements/ddl_commands/drop_schema.rst +++ /dev/null @@ -1,77 +0,0 @@ -.. _drop_schema: - -********************** -DROP SCHEMA -********************** - -``DROP SCHEMA`` can be used to remove a schema. - -The schema has to be empty before removal. - -SQream DB does not support dropping a schema with objects. - -See also: :ref:`create_schema`, :ref:`alter_default_schema`. - -Permissions -============= - -The role must have the ``DDL`` permission at the database level. - -Syntax -========== - -.. code-block:: postgres - - drop_schema_statement ::= - DROP SCHEMA schema_name - ; - - schema_name ::= identifier - - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``schema_name`` - - The name of the schema to drop - -Examples -=========== - -Dropping a schema ---------------------------------------------- - -.. code-block:: postgres - - DROP SCHEMA test; - -Dropping a schema if it's not empty ----------------------------------------------- - -If a schema contains several tables, SQream DB will alert you that these tables need to be dropped first. - -This prevents accidental dropping of full schemas. - -.. code-block:: psql - - t=> DROP SCHEMA test; - Schema 'test' contains the following objects: - Tables - 'test.foo' , 'test.bar' - Please drop its content and then try again. - -To drop the schema, drop the schema's tables first, and then drop the schema: - -.. code-block:: psql - - t=> DROP TABLE test.foo; - executed - t=> DROP TABLE test.bar; - executed - t=> DROP SCHEMA test; - executed \ No newline at end of file diff --git a/reference/sql/sql_statements/ddl_commands/drop_table.rst b/reference/sql/sql_statements/ddl_commands/drop_table.rst deleted file mode 100644 index e2a704ff8..000000000 --- a/reference/sql/sql_statements/ddl_commands/drop_table.rst +++ /dev/null @@ -1,70 +0,0 @@ -.. _drop_table: - -********************** -DROP TABLE -********************** - -``DROP TABLE`` can be used to remove a table and all of its contents. - -Permissions -============= - -The role must have the ``DDL`` permission at the database or table level. - -Syntax -========== - -.. code-block:: postgres - - drop_table_statement ::= - DROP TABLE [ IF EXISTS ] [schema_name.]table_name - ; - - table_name ::= identifier - - schema_name ::= identifier - - - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``IF EXISTS`` - - Drop the table if it exists. Does not error if the table does not exist. - * - ``schema_name`` - - The name of the schema from which to drop the table. - * - ``table_name`` - - The name of the table to drop. - -Examples -=========== - -Dropping a table ---------------------------------------------- - -.. code-block:: postgres - - DROP TABLE cool_animals; - - -Dropping a table (always succeeds) -------------------------------------- - -.. code-block:: psql - - farm=> DROP TABLE cool_animals; - executed - - farm=> DROP TABLE cool_animals; - Table 'public.cool_animals' not found - - -- This will succeed, even though the table does not exist - farm=> DROP TABLE IF EXISTS cool_animals; - executed - diff --git a/reference/sql/sql_statements/ddl_commands/drop_view.rst b/reference/sql/sql_statements/ddl_commands/drop_view.rst deleted file mode 100644 index e93629ab4..000000000 --- a/reference/sql/sql_statements/ddl_commands/drop_view.rst +++ /dev/null @@ -1,72 +0,0 @@ -.. _drop_view: - -********************** -DROP VIEW -********************** - -``DROP VIEW`` can be used to remove a view. - -Because a view is logical, this does not affect any data in any of the referenced tables. - -Permissions -============= - -The role must have the ``DDL`` permission at the database level. - -Syntax -========== - -.. code-block:: postgres - - drop_view_statement ::= - DROP VIEW [ IF EXISTS ] [schema_name.]view_name - ; - - view_name ::= identifier - - schema_name ::= identifier - - - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``IF EXISTS`` - - Drop the view if it exists. Does not error if the view does not exist. - * - ``schema_name`` - - The name of the schema from which to drop the view. - * - ``view_name`` - - The name of the view to drop. - -Examples -=========== - -Dropping a table ---------------------------------------------- - -.. code-block:: postgres - - DROP VIEW angry_animals; - - -Dropping a view (always succeeds) -------------------------------------- - -.. code-block:: psql - - farm=> DROP VIEW angry_animals; - executed - - farm=> DROP VIEW angry_animals; - View 'public.angry_animals' not found - - -- This will succeed, even though the view does not exist - farm=> DROP VIEW IF EXISTS angry_animals; - executed - diff --git a/reference/sql/sql_statements/ddl_commands/rename_column.rst b/reference/sql/sql_statements/ddl_commands/rename_column.rst deleted file mode 100644 index f91933f71..000000000 --- a/reference/sql/sql_statements/ddl_commands/rename_column.rst +++ /dev/null @@ -1,65 +0,0 @@ -.. _rename_column: - -********************** -RENAME COLUMN -********************** - -``RENAME COLUMN`` can be used to rename columns in a table. - -Permissions -============= - -The role must have the ``DDL`` permission at the database or table level. - -Syntax -========== - -.. code-block:: postgres - - alter_table_rename_column_statement ::= - ALTER TABLE [schema_name.]table_name RENAME COLUMN current_name TO new_name - ; - - table_name ::= identifier - - schema_name ::= identifier - - current_name ::= identifier - - new_name ::= identifier - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``schema_name`` - - The schema name for the table. Defaults to ``public`` if not specified. - * - ``table_name`` - - The table name to apply the change to. - * - ``current_name`` - - The column to rename. - * - ``new_name`` - - The new column name. - -Examples -=========== - -Renaming a column ------------------------------------------ - -.. code-block:: postgres - - -- Remove the 'weight' column - ALTER TABLE users RENAME COLUMN weight TO mass; - -Renaming a quoted name --------------------------- - -.. code-block:: postgres - - ALTER TABLE users RENAME COLUMN "mass" TO "Mass (Kilograms); \ No newline at end of file diff --git a/reference/sql/sql_statements/ddl_commands/rename_table.rst b/reference/sql/sql_statements/ddl_commands/rename_table.rst deleted file mode 100644 index e24ba6efe..000000000 --- a/reference/sql/sql_statements/ddl_commands/rename_table.rst +++ /dev/null @@ -1,57 +0,0 @@ -.. _rename_table: - -********************** -RENAME TABLE -********************** - -``RENAME TABLE`` can be used to rename a table. - -.. warning:: Renaming a table can void existing views that use this table. See more about :ref:`recompiling views `. - -Permissions -============= - -The role must have the ``DDL`` permission at the database or table level. - -Syntax -========== - -.. code-block:: postgres - - alter_table_rename_table_statement ::= - ALTER TABLE [schema_name.]current_name RENAME TO new_name - ; - - current_name ::= identifier - - schema_name ::= identifier - - new_name ::= identifier - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``schema_name`` - - The schema name for the table. Defaults to ``public`` if not specified. - * - ``current_name`` - - The table name to apply the change to. - * - ``new_name`` - - The new table name. - -Examples -=========== - -Renaming a table ------------------------------------------ - -.. code-block:: postgres - - ALTER TABLE public.users RENAME TO former_users; - - diff --git a/reference/sql/sql_statements/index.rst b/reference/sql/sql_statements/index.rst index 28096f16a..9525955d2 100644 --- a/reference/sql/sql_statements/index.rst +++ b/reference/sql/sql_statements/index.rst @@ -18,48 +18,48 @@ Data Definition Commands (DDL) * - Command - Usage - * - :ref:`ADD COLUMN` - - Add a new column to a table - * - :ref:`ALTER DEFAULT SCHEMA` - - Change the default schema for a role - * - :ref:`ALTER TABLE` - - Change the schema of a table - * - :ref:`CLUSTER BY` - - Change clustering keys in a table - * - :ref:`CREATE DATABASE` - - Create a new database - * - :ref:`CREATE EXTERNAL TABLE` - - Create a new external table in the database (deprecated) - * - :ref:`CREATE FOREIGN TABLE` - - Create a new foreign table in the database - * - :ref:`CREATE FUNCTION ` - - Create a new user defined function in the database - * - :ref:`CREATE SCHEMA` - - Create a new schema in the database - * - :ref:`CREATE TABLE` - - Create a new table in the database - * - :ref:`CREATE TABLE AS` - - Create a new table in the database using results from a select query - * - :ref:`CREATE VIEW` - - Create a new view in the database - * - :ref:`DROP CLUSTERING KEY` - - Drops all clustering keys in a table - * - :ref:`DROP COLUMN` - - Drop a column from a table - * - :ref:`DROP DATABASE` - - Drop a database and all of its objects - * - :ref:`DROP FUNCTION` - - Drop a function - * - :ref:`DROP SCHEMA` - - Drop a schema - * - :ref:`DROP TABLE` - - Drop a table and its contents from a database - * - :ref:`DROP VIEW` - - Drop a view - * - :ref:`RENAME COLUMN` - - Rename a column - * - :ref:`RENAME TABLE` - - Rename a table + * - `ADD COLUMN `_ + - Add a new column to a table + * - `ALTER DEFAULT SCHEMA `_ + - Change the default schema for a role + * - `ALTER TABLE `_ + - Change the schema of a table + * - `CLUSTER BY `_ + - Change clustering keys in a table + * - `CREATE DATABASE `_ + - Create a new database + * - `CREATE EXTERNAL TABLE `_ + - Create a new external table in the database (deprecated) + * - `CREATE FOREIGN TABLE `_ + - Create a new foreign table in the database + * - `CREATE FUNCTION `_ + - Create a new user defined function in the database + * - `CREATE SCHEMA `_ + - Create a new schema in the database + * - `CREATE TABLE `_ + - Create a new table in the database + * - `CREATE TABLE AS `_ + - Create a new table in the database using results from a select query + * - `CREATE VIEW `_ + - Create a new view in the database + * - `DROP CLUSTERING KEY `_ + - Drops all clustering keys in a table + * - `DROP COLUMN `_ + - Drop a column from a table + * - `DROP DATABASE `_ + - Drop a database and all of its objects + * - `DROP FUNCTION `_ + - Drop a function + * - `DROP SCHEMA `_ + - Drop a schema + * - `DROP TABLE `_ + - Drop a table and its contents from a database + * - `DROP VIEW `_ + - Drop a view + * - `RENAME COLUMN `_ + - Rename a column + * - `RENAME TABLE `_ + - Rename a table Data Manipulation Commands (DML) ================================ From 8e2ae851867dcd97e61fdbc6d5b407f49813d3c9 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 27 Mar 2022 17:01:05 +0300 Subject: [PATCH 021/316] Returned deleted files --- .../ddl_commands/add_column.rst | 91 ++++++ .../ddl_commands/alter_default_schema.rst | 58 ++++ .../ddl_commands/alter_table.rst | 33 ++ .../ddl_commands/cluster_by.rst | 69 ++++ .../ddl_commands/create_database.rst | 55 ++++ .../ddl_commands/create_external_table.rst | 156 +++++++++ .../ddl_commands/create_foreign_table.rst | 165 ++++++++++ .../ddl_commands/create_function.rst | 103 ++++++ .../ddl_commands/create_schema.rst | 92 ++++++ .../ddl_commands/create_table.rst | 296 ++++++++++++++++++ .../ddl_commands/create_table_as.rst | 96 ++++++ .../ddl_commands/create_view.rst | 79 +++++ .../ddl_commands/drop_clustering_key.rst | 64 ++++ .../ddl_commands/drop_column.rst | 63 ++++ .../ddl_commands/drop_database.rst | 63 ++++ .../ddl_commands/drop_function.rst | 66 ++++ .../ddl_commands/drop_schema.rst | 77 +++++ .../ddl_commands/drop_table.rst | 70 +++++ .../sql_statements/ddl_commands/drop_view.rst | 72 +++++ .../ddl_commands/rename_column.rst | 65 ++++ .../ddl_commands/rename_table.rst | 57 ++++ reference/sql/sql_statements/index.rst | 84 ++--- 22 files changed, 1932 insertions(+), 42 deletions(-) create mode 100644 reference/sql/sql_statements/ddl_commands/add_column.rst create mode 100644 reference/sql/sql_statements/ddl_commands/alter_default_schema.rst create mode 100644 reference/sql/sql_statements/ddl_commands/alter_table.rst create mode 100644 reference/sql/sql_statements/ddl_commands/cluster_by.rst create mode 100644 reference/sql/sql_statements/ddl_commands/create_database.rst create mode 100644 reference/sql/sql_statements/ddl_commands/create_external_table.rst create mode 100644 reference/sql/sql_statements/ddl_commands/create_foreign_table.rst create mode 100644 reference/sql/sql_statements/ddl_commands/create_function.rst create mode 100644 reference/sql/sql_statements/ddl_commands/create_schema.rst create mode 100644 reference/sql/sql_statements/ddl_commands/create_table.rst create mode 100644 reference/sql/sql_statements/ddl_commands/create_table_as.rst create mode 100644 reference/sql/sql_statements/ddl_commands/create_view.rst create mode 100644 reference/sql/sql_statements/ddl_commands/drop_clustering_key.rst create mode 100644 reference/sql/sql_statements/ddl_commands/drop_column.rst create mode 100644 reference/sql/sql_statements/ddl_commands/drop_database.rst create mode 100644 reference/sql/sql_statements/ddl_commands/drop_function.rst create mode 100644 reference/sql/sql_statements/ddl_commands/drop_schema.rst create mode 100644 reference/sql/sql_statements/ddl_commands/drop_table.rst create mode 100644 reference/sql/sql_statements/ddl_commands/drop_view.rst create mode 100644 reference/sql/sql_statements/ddl_commands/rename_column.rst create mode 100644 reference/sql/sql_statements/ddl_commands/rename_table.rst diff --git a/reference/sql/sql_statements/ddl_commands/add_column.rst b/reference/sql/sql_statements/ddl_commands/add_column.rst new file mode 100644 index 000000000..cec4aec7b --- /dev/null +++ b/reference/sql/sql_statements/ddl_commands/add_column.rst @@ -0,0 +1,91 @@ +.. _add_column: + +********************** +ADD COLUMN +********************** + +The ``ADD COLUMN`` command is used to add columns to an existing table. + + + +Syntax +========== +The following is the correct syntax for adding a table: + +.. code-block:: postgres + + alter_table_add_column_statement ::= + ALTER TABLE [schema_name.]table_name { ADD COLUMN column_def [, ...] } + ; + + table_name ::= identifier + + schema_name ::= identifier + + column_def :: = { column_name type_name [ default ] [ column_constraint ] } + + column_name ::= identifier + + column_constraint ::= + { NOT NULL | NULL } + + default ::= + DEFAULT default_value + + + +Parameters +============ +The following parameters can be used for adding a table: + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``schema_name`` + - The schema name for the table. Defaults to ``public`` if not specified. + * - ``table_name`` + - The table name to apply the change to. + * - ``ADD COLUMN column_def`` + - A comma separated list of ADD COLUMN commands + * - ``column_def`` + - A column definition. A minimal column definition includes a name identifier and a datatype. Other column constraints and default values can be added optionally. + +.. note:: + * When adding a new column to an existing table, a default (or null constraint) has to be specified, even if the table is empty. + * A new column added to the table can not contain an IDENTITY or be of the TEXT type. + + +Permissions +============= +The role must have the ``DDL`` permission at the database or table level. + +Examples +=========== +This section includes the following examples: + +.. contents:: + :local: + :depth: 1 + +Adding a Simple Column with a Default Value +----------------------------------------- +This example shows how to add a simple column with a default value: + +.. code-block:: postgres + + ALTER TABLE cool_animals + ADD COLUMN number_of_eyes INT DEFAULT 2 NOT NULL; + + +Adding Several Columns in One Command +------------------------------------------- +This example shows how to add several columns in one command: + +.. code-block:: postgres + + ALTER TABLE cool_animals + ADD COLUMN number_of_eyes INT DEFAULT 2 NOT NULL, + ADD COLUMN date_seen DATE DEFAULT '2019-08-01'; diff --git a/reference/sql/sql_statements/ddl_commands/alter_default_schema.rst b/reference/sql/sql_statements/ddl_commands/alter_default_schema.rst new file mode 100644 index 000000000..bca483060 --- /dev/null +++ b/reference/sql/sql_statements/ddl_commands/alter_default_schema.rst @@ -0,0 +1,58 @@ +.. _alter_default_schema: + +********************** +ALTER DEFAULT SCHEMA +********************** + +The ``ALTER DEFAULT SCHEMA`` command can be used to change a role's default schema. The default schema in SQream is ``public``. + +For more information, see :ref:`create_schema` and :ref:`drop_schema`. + + + +Syntax +========== +The following is the correct syntax for altering a default schema: + +.. code-block:: postgres + + alter_default_schema_statement ::= + ALTER DEFAULT SCHEMA FOR role_name TO schema_name + ; + + role_name ::= identifier + + schema_name ::= identifier + + + +Parameters +============ +The following parameters can be used when altering a default schema: + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``role_name`` + - The name of the role the change will apply to. + * - ``schema_name`` + - The new default schema name. + +Permissions +============= +No special permissions are required. + +Examples +=========== +This section includes an example of **altering the default schema for a role**: + +.. code-block:: postgres + + SELECT * FROM users; -- Refers to public.users + + ALTER DEFAULT SCHEMA FOR bgilfoyle TO staging; + + SELECT * FROM users; -- Now refers to staging.users, rather than public.users diff --git a/reference/sql/sql_statements/ddl_commands/alter_table.rst b/reference/sql/sql_statements/ddl_commands/alter_table.rst new file mode 100644 index 000000000..4046a31fe --- /dev/null +++ b/reference/sql/sql_statements/ddl_commands/alter_table.rst @@ -0,0 +1,33 @@ +.. _alter_table: + +********************** +ALTER TABLE +********************** +You can use the ``ALTER TABLE`` command to make schema changes to a table, and can be used in conjunction with several sub-commands. + +Locks +======= +Making changes to a schema makes an exclusive lock on tables. While these operations do not typically take much time, other statements may have to wait until the schema changes are completed. + +Sub-Commands +============== +The following table shows the sub-commands that can be used with the ``ALTER TABLE`` command: + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Command + - Usage + * - :ref:`ADD COLUMN` + - Adds a new column to a table. + * - :ref:`DROP COLUMN` + - Drops a column from a table. + * - :ref:`RENAME COLUMN` + - Renames a column. + * - :ref:`RENAME TABLE` + - Renames a table. + * - :ref:`CLUSTER BY` + - Modifies (adds or reorders) the clustering keys in a table. + * - :ref:`DROP CLUSTERING KEY` + - Drops all clustering keys. diff --git a/reference/sql/sql_statements/ddl_commands/cluster_by.rst b/reference/sql/sql_statements/ddl_commands/cluster_by.rst new file mode 100644 index 000000000..2a389e254 --- /dev/null +++ b/reference/sql/sql_statements/ddl_commands/cluster_by.rst @@ -0,0 +1,69 @@ +.. _cluster_by: + +********************** +CLUSTER BY +********************** + +``CLUSTER BY`` can be used to change clustering keys in a table. + + +Read our :ref:`data_clustering` guide for more information. + +See also: :ref:`drop_clustering_key`, :ref:`create_table`. + + +Permissions +============= + +The role must have the ``DDL`` permission at the database or table level. + +Syntax +========== + +.. code-block:: postgres + + alter_table_rename_table_statement ::= + ALTER TABLE [schema_name.]table_name CLUSTER BY column_name [, ...] + ; + + table_name ::= identifier + + column_name ::= identifier + + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``schema_name`` + - The schema name for the table. Defaults to ``public`` if not specified. + * - ``table_name`` + - The table name to apply the change to. + * - ``column_name [, ... ]`` + - Comma separated list of columns to create clustering keys for + + +Usage notes +================= + +Removing clustering keys does not affect existing data. + +To force data to re-cluster, the table has to be recreated (i.e. with :ref:`create_table_as`). + + +Examples +=========== + +Reclustering a table +----------------------------------------- + +.. code-block:: postgres + + ALTER TABLE public.users CLUSTER BY start_date; + + diff --git a/reference/sql/sql_statements/ddl_commands/create_database.rst b/reference/sql/sql_statements/ddl_commands/create_database.rst new file mode 100644 index 000000000..a0496feb2 --- /dev/null +++ b/reference/sql/sql_statements/ddl_commands/create_database.rst @@ -0,0 +1,55 @@ +.. _create_database: + +***************** +CREATE DATABASE +***************** + +``CREATE DATABASE`` creates a new database in SQream. + +Permissions +============= + +Only a superuser can create a new database + +Syntax +========== + +.. code-block:: postgres + + create_database_statement ::= + + CREATE DATABASE database_name ; + + database_name ::= identifier + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``database_name`` + - The name of the database name. The database name must be unique, and follows :ref:`Identifier rules ` + +Examples +=========== + +.. code-block:: postgres + + CREATE DATABASE raviga; + +.. code-block:: postgres + + CREATE DATABASE my_db; + +If the database already exists, an error will appear: + +.. code-block:: psql + + master=> CREATE DATABASE MY_DB; + Database 'my_db' already exists + +.. note:: SQream DB :ref:`identifiers ` are always converted to lowercase, so ``my_db`` is the same as ``MY_DB``, unless explicitly quoted as ``"MY_DB"``. \ No newline at end of file diff --git a/reference/sql/sql_statements/ddl_commands/create_external_table.rst b/reference/sql/sql_statements/ddl_commands/create_external_table.rst new file mode 100644 index 000000000..7674889a6 --- /dev/null +++ b/reference/sql/sql_statements/ddl_commands/create_external_table.rst @@ -0,0 +1,156 @@ +.. _create_external_table: + +*********************** +CREATE EXTERNAL TABLE +*********************** + +.. warning:: + + The ``CREATE EXTERNAL TABLE`` syntax is deprecated, and will be removed in future versions. + + Starting with SQream DB v2020.2, external tables have been renamed to :ref:`foreign tables`, and use a more flexible foreign data wrapper concept. See :ref:`create_foreign_table` instead. + + Upgrading to a new version of SQream DB converts existing tables automatically. When creating a new external tables, use the new foreign table syntax. + + +``CREATE TABLE`` creates a new external table in an existing database. + +See more in the :ref:`External tables guide`. + +.. tip:: + + * Data in an external table can change if the sources change, and frequent access to remote files may harm performance. + + * To create a regular table, see :ref:`CREATE TABLE ` + +Permissions +============= + +The role must have the ``CREATE`` permission at the database level. + +Syntax +========== + +.. code-block:: postgres + + create_table_statement ::= + CREATE [ OR REPLACE ] EXTERNAL TABLE [schema_name].table_name ( + { column_def [, ...] } + ) + USING FORMAT format_def + WITH { external_table_option [ ...] } + ; + + schema_name ::= identifier + + table_name ::= identifier + + format_def ::= { PARQUET | ORC | CSV } + + external_table_option ::= { + PATH '{ path_spec }' + | FIELD DELIMITER '{ field_delimiter }' + | RECORD DELIMITER '{ record_delimiter }' + | AWS_ID '{ AWS ID }' + | AWS_SECRET '{ AWS SECRET }' + } + + path_spec ::= { local filepath | S3 URI | HDFS URI } + + field_delimiter ::= delimiter_character + + record_delimiter ::= delimiter_character + + column_def ::= { column_name type_name [ default ] [ column_constraint ] } + + column_name ::= identifier + + column_constraint ::= + { NOT NULL | NULL } + + default ::= + + DEFAULT default_value + | IDENTITY [ ( start_with [ , increment_by ] ) ] + +.. _cet_parameters: + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``OR REPLACE`` + - Create a new table, and overwrite any existing table by the same name. Does not return an error if the table already exists. ``CREATE OR REPLACE`` does not check the table contents or structure, only the table name. + * - ``schema_name`` + - The name of the schema in which to create the table. + * - ``table_name`` + - The name of the table to create, which must be unique inside the schema. + * - ``column_def`` + - A comma separated list of column definitions. A minimal column definition includes a name identifier and a datatype. Other column constraints and default values can be added optionally. + * - ``USING FORMAT ...`` + - Specifies the format of the source files, such as ``PARQUET``, ``ORC``, or ``CSV``. + * - ``WITH PATH ...`` + - Specifies a path or URI of the source files, such as ``/path/to/*.parquet``. + * - ``FIELD DELIMITER`` + - Specifies the field delimiter for CSV files. Defaults to ``,``. + * - ``RECORD DELIMITER`` + - Specifies the record delimiter for CSV files. Defaults to a newline, ``\n`` + * - ``AWS_ID``, ``AWS_SECRET`` + - Credentials for authenticated S3 access + + +Examples +=========== + +A simple table from Tab-delimited file (TSV) +---------------------------------------------- + +.. code-block:: postgres + + CREATE OR REPLACE EXTERNAL TABLE cool_animals + (id INT NOT NULL, name VARCHAR(30) NOT NULL, weight FLOAT NOT NULL) + USING FORMAT csv + WITH PATH '/home/rhendricks/cool_animals.csv' + FIELD DELIMITER '\t'; + + +A table from a directory of Parquet files on HDFS +----------------------------------------------------- + +.. code-block:: postgres + + CREATE EXTERNAL TABLE users + (id INT NOT NULL, name VARCHAR(30) NOT NULL, email VARCHAR(50) NOT NULL) + USING FORMAT Parquet + WITH PATH 'hdfs://hadoop-nn.piedpiper.com/rhendricks/users/*.parquet'; + +A table from a bucket of files on S3 +-------------------------------------- + +.. code-block:: postgres + + CREATE EXTERNAL TABLE users + (id INT NOT NULL, name VARCHAR(30) NOT NULL, email VARCHAR(50) NOT NULL) + USING FORMAT Parquet + WITH PATH 's3://pp-secret-bucket/users/*.parquet' + AWS_ID 'our_aws_id' + AWS_SECRET 'our_aws_secret'; + + +Changing an external table to a regular table +------------------------------------------------ + +Materializes an external table into a regular table. + +.. tip: Using an external table allows you to perform ETL-like operations in SQream DB by applying SQL functions and operations to raw files + +.. code-block:: postgres + + CREATE TABLE real_table + AS SELECT * FROM external_table; + diff --git a/reference/sql/sql_statements/ddl_commands/create_foreign_table.rst b/reference/sql/sql_statements/ddl_commands/create_foreign_table.rst new file mode 100644 index 000000000..3a766852a --- /dev/null +++ b/reference/sql/sql_statements/ddl_commands/create_foreign_table.rst @@ -0,0 +1,165 @@ +.. _create_foreign_table: + +*********************** +CREATE FOREIGN TABLE +*********************** + +.. note:: + + Starting with SQream DB v2020.2, external tables have been renamed to foreign tables, and use a more flexible foreign data wrapper concept. + + Upgrading to a new version of SQream DB converts existing external tables automatically. + + +``CREATE FOREIGN TABLE`` creates a new foreign table in an existing database. + +See more in the :ref:`Foreign tables guide`. + +.. tip:: + + * Data in a foreign table can change if the sources change, and frequent access to remote files may harm performance. + + * To create a regular table, see :ref:`CREATE TABLE ` + +Permissions +============= + +The role must have the ``CREATE`` permission at the database level. + +Syntax +========== + +.. code-block:: postgres + + create_table_statement ::= + CREATE [ OR REPLACE ] FOREIGN TABLE [schema_name].table_name ( + { column_def [, ...] } + ) + [ FOREIGN DATA ] WRAPPER fdw_name + [ OPTIONS ( option_def [, ... ] ) ] + ; + + schema_name ::= identifier + + table_name ::= identifier + + fdw_name ::= + { csv_fdw | orc_fdw | parquet_fdw } + + option_def ::= + { + LOCATION = '{ path_spec }' + | DELIMITER = '{ field_delimiter }' -- for CSV only + | RECORD_DELIMITER = '{ record_delimiter }' -- for CSV only + | AWS_ID '{ AWS ID }' + | AWS_SECRET '{ AWS SECRET }' + } + + path_spec ::= { local filepath | S3 URI | HDFS URI } + + field_delimiter ::= delimiter_character + + record_delimiter ::= delimiter_character + + column_def ::= + { column_name type_name [ default ] [ column_constraint ] } + + column_name ::= identifier + + column_constraint ::= + { NOT NULL | NULL } + + default ::= + DEFAULT default_value + | IDENTITY [ ( start_with [ , increment_by ] ) ] + +.. _cft_parameters: + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``OR REPLACE`` + - Create a new table, and overwrite any existing table by the same name. Does not return an error if the table already exists. ``CREATE OR REPLACE`` does not check the table contents or structure, only the table name. + * - ``schema_name`` + - The name of the schema in which to create the table. + * - ``table_name`` + - The name of the table to create, which must be unique inside the schema. + * - ``column_def`` + - A comma separated list of column definitions. A minimal column definition includes a name identifier and a datatype. Other column constraints and default values can be added optionally. + * - ``WRAPPER ...`` + - Specifies the format of the source files, such as ``parquet_fdw``, ``orc_fdw``, or ``csv_fdw``. + * - ``LOCATION = ...`` + - Specifies a path or URI of the source files, such as ``/path/to/*.parquet``. + * - ``DELIMITER = ...`` + - Specifies the field delimiter for CSV files. Defaults to ``,``. + * - ``RECORD_DELIMITER = ...`` + - Specifies the record delimiter for CSV files. Defaults to a newline, ``\n`` + * - ``AWS_ID``, ``AWS_SECRET`` + - Credentials for authenticated S3 access + + +Examples +=========== + +A simple table from Tab-delimited file (TSV) +---------------------------------------------- + +.. code-block:: postgres + + CREATE OR REPLACE FOREIGN TABLE cool_animals + (id INT NOT NULL, name VARCHAR(30) NOT NULL, weight FLOAT NOT NULL) + WRAPPER csv_fdw + OPTIONS + ( LOCATION = '/home/rhendricks/cool_animals.csv', + DELIMITER = '\t' + ) + ; + + +A table from a directory of Parquet files on HDFS +----------------------------------------------------- + +.. code-block:: postgres + + CREATE FOREIGN TABLE users + (id INT NOT NULL, name VARCHAR(30) NOT NULL, email VARCHAR(50) NOT NULL) + WRAPPER parquet_fdw + OPTIONS + ( + LOCATION = 'hdfs://hadoop-nn.piedpiper.com/rhendricks/users/*.parquet' + ); + +A table from a bucket of ORC files on S3 +------------------------------------------ + +.. code-block:: postgres + + CREATE FOREIGN TABLE users + (id INT NOT NULL, name VARCHAR(30) NOT NULL, email VARCHAR(50) NOT NULL) + WRAPPER orc_fdw + OPTIONS + ( + LOCATION = 's3://pp-secret-bucket/users/*.orc', + AWS_ID = 'our_aws_id', + AWS_SECRET = 'our_aws_secret' + ); + + +Changing a foreign table to a regular table +------------------------------------------------ + +Materializes a foreign table into a regular table. + +.. tip: Using a foreign table allows you to perform ETL-like operations in SQream DB by applying SQL functions and operations to raw files + +.. code-block:: postgres + + CREATE TABLE real_table + AS SELECT * FROM some_foreign_table; + diff --git a/reference/sql/sql_statements/ddl_commands/create_function.rst b/reference/sql/sql_statements/ddl_commands/create_function.rst new file mode 100644 index 000000000..971b51298 --- /dev/null +++ b/reference/sql/sql_statements/ddl_commands/create_function.rst @@ -0,0 +1,103 @@ +.. _create_function: + +***************** +CREATE FUNCTION +***************** + +``CREATE FUNCTION`` creates a new user-defined function (UDF) in an existing database. + +See more in our :ref:`Python UDF (user-defined functions)` guide. + +Permissions +============= + +The role must have the ``CREATE FUNCTION`` permission at the database level. + +Syntax +========== + +.. code-block:: postgres + + create_function_statement ::= + CREATE [ OR REPLACE ] FUNCTION function_name (argument_list) + RETURNS return_type + AS $$ + { function_body } + $$ LANGUAGE python + ; + + function_name ::= identifier + + argument_list :: = { value_name type_name [, ...] } + + value_name ::= identifier + + return_type ::= type_name + + function_body ::= Valid Python code + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``OR REPLACE`` + - Create a new function, and overwrite any existing function by the same name. Does not return an error if the function already exists. ``CREATE OR REPLACE`` does not check the function contents or structure, only the function name. + * - ``function_name`` + - The name of the function to create, which must be unique inside the database. + * - ``argument_list`` + - A comma separated list of column definitions. A column definition includes a name identifier and a datatype. + * - ``return_type`` + - The SQL datatype of the return value, such as ``INT``, ``VARCHAR``, etc. + * - ``function_body`` + - Python code, dollar-quoted (``$$``). + +Examples +=========== + +Calculate distance between two points +-------------------------------------- + +.. code-block:: postgres + + CREATE OR REPLACE FUNCTION my_distance (x1 float, y1 float, x2 float, y2 float) + RETURNS FLOAT + AS $$ + import math + if y1 < x1: + return 0.0 + else: + return math.sqrt((y2 - y1) ** 2 + (x2 - x1) ** 2) + $$ LANGUAGE PYTHON; + + -- Usage: + SELECT city, my_location, my_distance(x1,y1,x2,y2) from cities; + + +Calling files from other locations +--------------------------------------- + +.. code-block:: postgres + + -- Our script my_code.py is in ~/my_python_stuff + + CREATE FUNCTION write_log() + RETURNS INT + AS $$ + import sys + sys.path.append("/home/user/my_python_stuff") + + import my_code as f + + f.main() + + return 1 + + $$ LANGUAGE PYTHON; + + -- Usage: + SELECT write_log(); diff --git a/reference/sql/sql_statements/ddl_commands/create_schema.rst b/reference/sql/sql_statements/ddl_commands/create_schema.rst new file mode 100644 index 000000000..aefa64b4f --- /dev/null +++ b/reference/sql/sql_statements/ddl_commands/create_schema.rst @@ -0,0 +1,92 @@ +.. _create_schema: + +***************** +CREATE SCHEMA +***************** +The **CREATE SCHEMA** page describes the following: + + +.. contents:: + :local: + :depth: 2 + +Overview +============ + +``CREATE SCHEMA`` creates a new schema in an existing database. A schema is a virtual space for storing tables. + +The default schema in SQream DB is ``public``. + +.. tip:: Use schemas to separate between use-cases, such as staging and production. + +The **CREATE SCHEMA** statement can be used to query tables from different schemas without providing an alias, as in the following example: + +.. code-block:: postgres + + select .table_name.column_name from .table_name + +See also: :ref:`drop_schema`, :ref:`alter_default_schema`. + +Permissions +============= + +The role must have the ``CREATE`` permission at the database level. + +Syntax +========== +The following example shows the correct syntax for creating a schema: + +.. code-block:: postgres + + create_schema_statement ::= + CREATE SCHEMA schema_name + ; + + schema_name ::= identifier + + +Parameters +============ +The following table shows the ``schema_name`` parameters: + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``schema_name`` + - The name of the schema to create. + +Examples +=========== +This section includes the following examples: + +.. contents:: + :local: + :depth: 1 + + +Creating a Schema +-------------------- +The following example shows an example of the syntax for creating a schema: + +.. code-block:: postgres + + CREATE SCHEMA staging; + + CREATE TABLE staging.users AS SELECT * FROM public.users; + + SELECT * FROM staging.users; + +Altering the Default Schema for a Role +----------------------------------------- +The following example shows an example of the syntax for altering the default schema for a role: + +.. code-block:: postgres + + SELECT * FROM users; -- Refers to public.users + + ALTER DEFAULT SCHEMA FOR bgilfoyle TO staging; + + SELECT * FROM users; -- Now refers to staging.users, rather than public.users diff --git a/reference/sql/sql_statements/ddl_commands/create_table.rst b/reference/sql/sql_statements/ddl_commands/create_table.rst new file mode 100644 index 000000000..10b1a9836 --- /dev/null +++ b/reference/sql/sql_statements/ddl_commands/create_table.rst @@ -0,0 +1,296 @@ +.. _create_table: + +***************** +CREATE TABLE +***************** + +The ``CREATE TABLE`` statement is used to create a new table in an existing database. + +.. tip:: + * To create a table based on the result of a select query, see :ref:`CREATE TABLE AS `. + * To create a table based on files like Parquet and ORC, see :ref:`CREATE FOREIGN TABLE ` + + + +Syntax +========== +The following is the correct syntax for creating a table: + +.. code-block:: postgres + + create_table_statement ::= + CREATE [ OR REPLACE ] TABLE [schema_name.]table_name ( + { column_def [, ...] } + ) + [ CLUSTER BY { column_name [, ...] } ] + ; + + schema_name ::= identifier + + table_name ::= identifier + + column_def :: = { column_name type_name [ default ] [ column_constraint ] } + + column_name ::= identifier + + column_constraint ::= + { NOT NULL | NULL } + + default ::= + DEFAULT default_value + | IDENTITY [ ( start_with [ , increment_by ] ) ] + +Parameters +============ +The following parameters can be used when creating a table: + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``OR REPLACE`` + - Creates a new tables and overwrites any existing table by the same name. Does not return an error if the table already exists. ``CREATE OR REPLACE`` does not check the table contents or structure, only the table name. + * - ``schema_name`` + - The name of the schema in which to create the table. + * - ``table_name`` + - The name of the table to create, which must be unique inside the schema. + * - ``column_def`` + - A comma separated list of column definitions. A minimal column definition includes a name identifier and a datatype. Other column constraints and default values can be added optionally. + * - ``CLUSTER BY column_name1 ...`` + - + A commma separated list of clustering column keys. + + See :ref:`data_clustering` for more information. + * - ``LIKE`` + - Duplicates the column structure of an existing table. + + +.. _default_values: + +Default Value Constraints +=============== + +The ``DEFAULT`` value constraint specifies a value to use if one is not defined in an :ref:`insert` or :ref:`copy_from` statement. + +The value may be a literal, which is evaluated at the time the row is created. + +.. note:: The ``DEFAULT`` constraint only applies if the column does not have a value specified in the :ref:`insert` or :ref:`copy_from` statement. You can still insert a ``NULL`` into an nullable column by explicitly inserting ``NULL``. For example, ``INSERT INTO cool_animals VALUES (1, 'Gnu', NULL)``. + +Syntax +--------- +The following is the correct syntax for using the **DEFAULT** value constraints: + + +.. code-block:: postgres + + column_def :: = { column_name type_name [ default ] [ column_constraint ] } + + column_constraint ::= + { NOT NULL | NULL } + + default ::= + DEFAULT default_value + | IDENTITY [ ( start_with [ , increment_by ] ) ] + + check_specification ::= + CHECK( 'CS compression_spec' ) + + compression_spec ::= + { "default" | "p4d" | "dict" | "rle" | "sequence" | "flat" } + + +.. _identity: + +Identity +----------------------- +The ``Identity`` (or sequence) columns can be used for generating key values. Some databases call this ``AUTOINCREMENT``. + +The **identity** property on a column guarantees that each new row inserted is generated based on the current seed & increment. + +.. warning:: + The identity property on a column does not guarantee uniqueness. The identity value can be bypassed by specifying it in an :ref:`insert` command. + +The following table describes the identity parameters: + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``start_with`` + - A value that is used for the very first row loaded into the table. + * - ``increment_by`` + - Incremental value that is added to the identity value of the previous row that was loaded. + +Examples +=========== +This section includes the following examples: + +.. contents:: + :local: + :depth: 1 + +Creating a Standard Table +----------------- +The following is an example of the syntax used to create a standard table: + +.. code-block:: postgres + + CREATE TABLE cool_animals ( + id INT NOT NULL, + name varchar(30) NOT NULL, + weight FLOAT, + is_agressive BOOL + ); + +Creating a Table with Default Value Constraints for Some Columns +--------------------------------------------------- +The following is an example of the syntax used to create a table with default value constraints for some columns: + + +.. code-block:: postgres + + CREATE TABLE cool_animals ( + id INT NOT NULL, + name varchar(30) NOT NULL, + weight FLOAT, + is_agressive BOOL DEFAULT false NOT NULL + ); + +.. note:: The nullable/non-nullable constraint appears at the end, after the default option + +Creating a Table with an Identity Column +--------------------------------------------------- +The following is an example of the syntax used to create a table with an identity (auto-increment) column: + + +.. code-block:: postgres + + CREATE TABLE users ( + id BIGINT IDENTITY(0,1) NOT NULL , -- Start with 0, increment by 1 + name VARCHAR(30) NOT NULL, + country VARCHAR(30) DEFAULT 'Unknown' NOT NULL + ); + +.. note:: + * Identity columns are supported on ``BIGINT`` columns. + + * Identity does not enforce the uniqueness of values. The identity value can be bypassed by specifying it in an :ref:`insert` command. + +Creating a Table from a SELECT Query +----------------------------------------- +The following is an example of the syntax used to create a table from a SELECT query: + +.. code-block:: postgres + + CREATE TABLE users_uk AS SELECT * FROM users WHERE country = 'United Kingdom'; + +For more information on creating a new table from the results of a SELECT query, see :ref:`CREATE TABLE AS `. + +Creating a Table with a Clustering Key +---------------------------------------------- +When data in a table is stored in a sorted order, the sorted columns are considered clustered. Good clustering can have a significant positive impact on performance. + +In the following example, we expect the ``start_date`` column to be naturally clustered, as new users sign up and get a newer start date. + +When the clustering key is set, if the incoming data isn’t naturally clustered, it will be clustered by SQream DB during insert or bulk load. + +The following is an example of the syntax used to create a table with a clustering key: + +.. code-block:: postgres + + CREATE TABLE users ( + name VARCHAR(30) NOT NULL, + start_date datetime not null, + country VARCHAR(30) DEFAULT 'Unknown' NOT NULL + ) CLUSTER BY start_date; + +For more information on data clustering, see :ref:`data_clustering`. + +Duplicating the Column Structure of an Existing Table +----------------- + +Syntax +************ +The following is the correct syntax for duplicating the column structure of an existing table: + +.. code-block:: postgres + + CREATE [OR REPLACE] TABLE table_name + { + (column_name column_type [{NULL | NOT NULL}] [,...]) + | LIKE source_table_name + } + [CLUSTER BY ...] + ; + +Examples +************** +This section includes the following examples of duplicating the column structure of an existing table using the ``LIKE`` clause: + +.. contents:: + :local: + :depth: 3 + +Creating a Table Using an Explicit Column List +~~~~~~~~~~~~ +The following is an example of creating a table using an explict column list: + +.. code-block:: postgres + + CREATE TABLE t1(x int default 0 not null, y text(10) null); + +Creating a Second Table Based on the Structure of Another Table +~~~~~~~~~~~~ +Either of the following examples can be used to create a second table based on the structure of another table. + +**Example 1** + +.. code-block:: postgres + + CREATE TABLE t2 LIKE t1; + +**Example 2** + +.. code-block:: postgres + + CREATE TABLE t2(x int default 0 not null, y text(10) null); + +The generated output of both of the statements above is identical. + +Creating a Table based on External Tables and Views +~~~~~~~~~~~~ +The following is example of creating a table based on external tables and views: + + +.. code-block:: postgres + + CREATE VIEW v as SELECT x+1,y,y || 'abc' from t1; + CREATE TABLE t3 LIKE v; + +When duplicating the column structure of an existing table, the target table of the ``LIKE`` clause can be a regular or an external table, or a view. + +The following table describes the properties that must be copied from the target table: + ++-----------------------------+------------------+---------------------------------+---------------------------------+ +| **Property** | **Native Table** | **External Table** | **View** | ++-----------------------------+------------------+---------------------------------+---------------------------------+ +| Column names | Must be copied | Must be copied | Must be copied | ++-----------------------------+------------------+---------------------------------+---------------------------------+ +| Column types | Must be copied | Must be copied | Must be copied | ++-----------------------------+------------------+---------------------------------+---------------------------------+ +| ``NULL``/``NOT NULL`` | Must be copied | Must be copied | Must be copied | ++-----------------------------+------------------+---------------------------------+---------------------------------+ +| ``text`` length constraints | Must be copied | Must be copied | Does not exist in source object | ++-----------------------------+------------------+---------------------------------+---------------------------------+ +| Compression specification | Must be copied | Does not exist in source object | Does not exist in source object | ++-----------------------------+------------------+---------------------------------+---------------------------------+ +| Default/identity | Must be copied | Does not exist in source object | Does not exist in source object | ++-----------------------------+------------------+---------------------------------+---------------------------------+ + +Permissions +============= +The role must have the ``CREATE`` permission at the schema level. diff --git a/reference/sql/sql_statements/ddl_commands/create_table_as.rst b/reference/sql/sql_statements/ddl_commands/create_table_as.rst new file mode 100644 index 000000000..c0d941f21 --- /dev/null +++ b/reference/sql/sql_statements/ddl_commands/create_table_as.rst @@ -0,0 +1,96 @@ +.. _create_table_as: + +***************** +CREATE TABLE AS +***************** + +The ``CREATE TABLE AS`` commands creates a new table from the result of a select query. + + +Syntax +========== +The following is the correct syntax for creating a table from the result of a select query: + + +.. CREATE [ OR REPLACE ] TABLE [schema_name].table_name ( +.. { column_def [, ...] } +.. ) AS query + +.. code-block:: postgres + + create_table_statement ::= + CREATE [ OR REPLACE ] TABLE [schema_name].table_name AS query + ; + + schema_name ::= identifier + + table_name ::= identifier + + +.. _ctas_params: + +Parameters +============ +The following parameters can be used when creating a table from the result of a select query: + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``OR REPLACE`` + - Create a new table, and overwrite any existing table by the same name. Does not return an error if the table already exists. ``CREATE OR REPLACE`` does not check the table contents or structure, only the table name. + * - ``schema_name`` + - The name of the schema in which to create the table. + * - ``table_name`` + - The name of the table to create, which must be unique inside the schema. + * - ``query`` + - A select query that returns data + +.. * - ``column_def`` +.. - A comma separated list of column definitions. A minimal column definition includes a name identifier and a datatype. Other column constraints and default values can be added optionally. + +Permissions +============= +The role must have the ``CREATE`` permission at the schema level, as well as ``SELECT`` permissions for any tables referenced by the statement. + + +Examples +=========== +This section includes the following examples: + +.. contents:: + :local: + :depth: 1 + +Creating a Copy of a Foreign Table or View +--------------------------------------------------------------------------- + +.. code-block:: postgres + + CREATE TABLE users AS SELECT * FROM users_source; + +For more information, see :ref:`CREATE FOREIGN TABLE `. + +Filtering +------------ + +.. code-block:: postgres + + CREATE TABLE users_uk AS SELECT * FROM users WHERE country = 'United Kingdom'; + +Adding Columns +----------------------- + +.. code-block:: postgres + + CREATE TABLE users_uk_new AS SELECT GETDATE() as "Date",*,false as is_new FROM users_uk; + +Creating a Table From Values +----------------------------------------- + +.. code-block:: postgres + + CREATE TABLE new_users + AS VALUES(GETDATE(),'Richard','Foxworthy','1984-03-03',True) diff --git a/reference/sql/sql_statements/ddl_commands/create_view.rst b/reference/sql/sql_statements/ddl_commands/create_view.rst new file mode 100644 index 000000000..4c6a98427 --- /dev/null +++ b/reference/sql/sql_statements/ddl_commands/create_view.rst @@ -0,0 +1,79 @@ +.. _create_view: + +***************** +CREATE VIEW +***************** + +``CREATE VIEW`` creates a new view in an existing database. A view is a virtual table. + +.. tip:: + * Use views to simplify complex queries or present only partial data to specific roles. + * If an underlying table has changed (new columns, changed names, etc.) - a view may be invalidated. To recompile the view, see :ref:`SELECT RECOMPILE_VIEW(\)` + + +Permissions +============= + +The role must have the ``CREATE`` permission at the database level, as well as ``SELECT`` permissions for any tables referenced by the view. + +Syntax +========== + +.. code-block:: postgres + + create_view_statement ::= + CREATE VIEW [schema_name].view_name [ column_list ] + AS + query + ; + + schema_name ::= identifier + + view_name ::= identifier + + column_list ::= ( { column_name [, ...] } ) + + column_name ::= identifier + + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``schema_name`` + - The name of the schema in which to create the view. + * - ``view_name`` + - The name of the view to create, which must be unique inside the schema. + * - ``column_list`` + - An optional comma separated list of column names for the view. If specified, these column names will override the column names in the response of the query in the ``AS query`` statement. + * - ``AS query`` + - The select query to execute when the view is referenced. + +.. * - ``OR REPLACE`` +.. - Create a new view, and overwrite any existing views by the same name. Does not return an error if the view already exists. + +Examples +=========== + +A simple view +----------------- + +.. code-block:: postgres + + CREATE VIEW only_agressive_animals AS + SELECT * FROM cool_animals WHERE is_agressive=true; + + SELECT * FROM only_agressive_animals; + +Overriding default column names +--------------------------------- + +.. code-block:: postgres + + CREATE VIEW only_relaxed_animals (animal_id, animal_name, should_i_worry) AS + SELECT id, name, is_agressive FROM cool_animals WHERE is_agressive=false; diff --git a/reference/sql/sql_statements/ddl_commands/drop_clustering_key.rst b/reference/sql/sql_statements/ddl_commands/drop_clustering_key.rst new file mode 100644 index 000000000..06cb848ad --- /dev/null +++ b/reference/sql/sql_statements/ddl_commands/drop_clustering_key.rst @@ -0,0 +1,64 @@ +.. _drop_clustering_key: + +********************** +DROP CLUSTERING KEY +********************** + +``DROP CLUSTERING KEY`` drops all clustering keys in a table. + +Read our :ref:`data_clustering` guide for more information. + +See also: :ref:`cluster_by`, :ref:`create_table`. + + +Permissions +============= + +The role must have the ``DDL`` permission at the database or table level. + +Syntax +========== + +.. code-block:: postgres + + alter_table_rename_table_statement ::= + ALTER TABLE [schema_name.]table_name DROP CLUSTERING KEY + ; + + table_name ::= identifier + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``schema_name`` + - The schema name for the table. Defaults to ``public`` if not specified. + * - ``table_name`` + - The table name to apply the change to. + +Usage notes +================= + +Removing clustering keys does not affect existing data. + +To force data to re-cluster, the table has to be recreated (i.e. with :ref:`create_table_as`). + + + + +Examples +=========== + +Dropping clustering keys in a table +----------------------------------------- + +.. code-block:: postgres + + ALTER TABLE public.users DROP CLUSTERING KEY + + diff --git a/reference/sql/sql_statements/ddl_commands/drop_column.rst b/reference/sql/sql_statements/ddl_commands/drop_column.rst new file mode 100644 index 000000000..f4c4e4504 --- /dev/null +++ b/reference/sql/sql_statements/ddl_commands/drop_column.rst @@ -0,0 +1,63 @@ +.. _drop_column: + +********************** +DROP COLUMN +********************** + +``DROP COLUMN`` can be used to remove columns from a table. + +Permissions +============= + +The role must have the ``DDL`` permission at the database or table level. + +Syntax +========== + +.. code-block:: postgres + + alter_table_drop_column_statement ::= + ALTER TABLE [schema_name.]table_name DROP COLUMN column_name + ; + + table_name ::= identifier + + schema_name ::= identifier + + column_name ::= identifier + + + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``schema_name`` + - The schema name for the table. Defaults to ``public`` if not specified. + * - ``table_name`` + - The table name to apply the change to. + * - ``column_name`` + - The column to remove. + +Examples +=========== + +Removing a column +----------------------------------------- + +.. code-block:: postgres + + -- Remove the 'weight' column + ALTER TABLE users DROP COLUMN weight; + +Removing a column with a quoted identifier name +---------------------------------------------------- + +.. code-block:: postgres + + ALTER TABLE users DROP COLUMN "Weight in kilograms"; \ No newline at end of file diff --git a/reference/sql/sql_statements/ddl_commands/drop_database.rst b/reference/sql/sql_statements/ddl_commands/drop_database.rst new file mode 100644 index 000000000..f45b0a5c4 --- /dev/null +++ b/reference/sql/sql_statements/ddl_commands/drop_database.rst @@ -0,0 +1,63 @@ +.. _drop_database: + +********************** +DROP DATABASE +********************** + +``DROP DATABASE`` can be used to remove a database and all of its objects. + +Permissions +============= + +The role must have the ``DDL`` permission at the database level. + +Syntax +========== + +.. code-block:: postgres + + drop_database_statement ::= + DROP DATABASE database_name + ; + + database_name ::= identifier + + + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``database_name`` + - The name of the database to drop. This can not be the current database in use. + +Examples +=========== + +Dropping a database and all of its objects +--------------------------------------------- + +.. code-block:: psql + + master=> DROP DATABASE raviga; + executed + + +Dropping the current database +-------------------------------- + +The current database in use can't be dropped. Switch to another database first. + +.. code-block:: psql + + raviga=> DROP DATABASE raviga; + Current open database 'raviga' cannot be dropped. + + raviga=> \c master + master=> DROP DATABASE raviga; + executed \ No newline at end of file diff --git a/reference/sql/sql_statements/ddl_commands/drop_function.rst b/reference/sql/sql_statements/ddl_commands/drop_function.rst new file mode 100644 index 000000000..98b957ad8 --- /dev/null +++ b/reference/sql/sql_statements/ddl_commands/drop_function.rst @@ -0,0 +1,66 @@ +.. _drop_function: + +********************** +DROP FUNCTION +********************** + +``DROP FUNCTION`` can be used to remove a user defined function. + +Permissions +============= + +The role must have the ``DDL`` permission at the database level. + +Syntax +========== + +.. code-block:: postgres + + drop_function_statement ::= + DROP FUNCTION [ IF EXISTS ] function_name(); + ; + + function_name ::= identifier + + + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``IF EXISTS`` + - Drop the function if it exists. Does not error if the function does not exist. + * - ``function_name()`` + - The name of the function to drop. + +Examples +=========== + +Dropping a function +--------------------------------------------- + +.. code-block:: postgres + + DROP FUNCTION my_distance(); + + +Dropping a function (always succeeds) +------------------------------------- + +.. code-block:: psql + + farm=> DROP FUNCTION my_distance(); + executed + + farm=> DROP FUNCTION my_distance(); + Function 'my_distance' not found + + -- This will succeed, even though the function does not exist + farm=> DROP FUNCTION IF EXISTS my_distance(); + executed + diff --git a/reference/sql/sql_statements/ddl_commands/drop_schema.rst b/reference/sql/sql_statements/ddl_commands/drop_schema.rst new file mode 100644 index 000000000..0f2dfd454 --- /dev/null +++ b/reference/sql/sql_statements/ddl_commands/drop_schema.rst @@ -0,0 +1,77 @@ +.. _drop_schema: + +********************** +DROP SCHEMA +********************** + +``DROP SCHEMA`` can be used to remove a schema. + +The schema has to be empty before removal. + +SQream DB does not support dropping a schema with objects. + +See also: :ref:`create_schema`, :ref:`alter_default_schema`. + +Permissions +============= + +The role must have the ``DDL`` permission at the database level. + +Syntax +========== + +.. code-block:: postgres + + drop_schema_statement ::= + DROP SCHEMA schema_name + ; + + schema_name ::= identifier + + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``schema_name`` + - The name of the schema to drop + +Examples +=========== + +Dropping a schema +--------------------------------------------- + +.. code-block:: postgres + + DROP SCHEMA test; + +Dropping a schema if it's not empty +---------------------------------------------- + +If a schema contains several tables, SQream DB will alert you that these tables need to be dropped first. + +This prevents accidental dropping of full schemas. + +.. code-block:: psql + + t=> DROP SCHEMA test; + Schema 'test' contains the following objects: + Tables - 'test.foo' , 'test.bar' + Please drop its content and then try again. + +To drop the schema, drop the schema's tables first, and then drop the schema: + +.. code-block:: psql + + t=> DROP TABLE test.foo; + executed + t=> DROP TABLE test.bar; + executed + t=> DROP SCHEMA test; + executed \ No newline at end of file diff --git a/reference/sql/sql_statements/ddl_commands/drop_table.rst b/reference/sql/sql_statements/ddl_commands/drop_table.rst new file mode 100644 index 000000000..53fdc8445 --- /dev/null +++ b/reference/sql/sql_statements/ddl_commands/drop_table.rst @@ -0,0 +1,70 @@ +.. _drop_table: + +********************** +DROP TABLE +********************** + +``DROP TABLE`` can be used to remove a table and all of its contents. + +Permissions +============= + +The role must have the ``DDL`` permission at the database or table level. + +Syntax +========== + +.. code-block:: postgres + + drop_table_statement ::= + DROP TABLE [ IF EXISTS ] [schema_name.]table_name + ; + + table_name ::= identifier + + schema_name ::= identifier + + + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``IF EXISTS`` + - Drop the table if it exists. Does not error if the table does not exist. + * - ``schema_name`` + - The name of the schema from which to drop the table. + * - ``table_name`` + - The name of the table to drop. + +Examples +=========== + +Dropping a table +--------------------------------------------- + +.. code-block:: postgres + + DROP TABLE cool_animals; + + +Dropping a table (always succeeds) +------------------------------------- + +.. code-block:: psql + + farm=> DROP TABLE cool_animals; + executed + + farm=> DROP TABLE cool_animals; + Table 'public.cool_animals' not found + + -- This will succeed, even though the table does not exist + farm=> DROP TABLE IF EXISTS cool_animals; + executed + diff --git a/reference/sql/sql_statements/ddl_commands/drop_view.rst b/reference/sql/sql_statements/ddl_commands/drop_view.rst new file mode 100644 index 000000000..6e18254e6 --- /dev/null +++ b/reference/sql/sql_statements/ddl_commands/drop_view.rst @@ -0,0 +1,72 @@ +.. _drop_view: + +********************** +DROP VIEW +********************** + +``DROP VIEW`` can be used to remove a view. + +Because a view is logical, this does not affect any data in any of the referenced tables. + +Permissions +============= + +The role must have the ``DDL`` permission at the database level. + +Syntax +========== + +.. code-block:: postgres + + drop_view_statement ::= + DROP VIEW [ IF EXISTS ] [schema_name.]view_name + ; + + view_name ::= identifier + + schema_name ::= identifier + + + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``IF EXISTS`` + - Drop the view if it exists. Does not error if the view does not exist. + * - ``schema_name`` + - The name of the schema from which to drop the view. + * - ``view_name`` + - The name of the view to drop. + +Examples +=========== + +Dropping a table +--------------------------------------------- + +.. code-block:: postgres + + DROP VIEW angry_animals; + + +Dropping a view (always succeeds) +------------------------------------- + +.. code-block:: psql + + farm=> DROP VIEW angry_animals; + executed + + farm=> DROP VIEW angry_animals; + View 'public.angry_animals' not found + + -- This will succeed, even though the view does not exist + farm=> DROP VIEW IF EXISTS angry_animals; + executed + diff --git a/reference/sql/sql_statements/ddl_commands/rename_column.rst b/reference/sql/sql_statements/ddl_commands/rename_column.rst new file mode 100644 index 000000000..41f1e1628 --- /dev/null +++ b/reference/sql/sql_statements/ddl_commands/rename_column.rst @@ -0,0 +1,65 @@ +.. _rename_column: + +********************** +RENAME COLUMN +********************** + +``RENAME COLUMN`` can be used to rename columns in a table. + +Permissions +============= + +The role must have the ``DDL`` permission at the database or table level. + +Syntax +========== + +.. code-block:: postgres + + alter_table_rename_column_statement ::= + ALTER TABLE [schema_name.]table_name RENAME COLUMN current_name TO new_name + ; + + table_name ::= identifier + + schema_name ::= identifier + + current_name ::= identifier + + new_name ::= identifier + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``schema_name`` + - The schema name for the table. Defaults to ``public`` if not specified. + * - ``table_name`` + - The table name to apply the change to. + * - ``current_name`` + - The column to rename. + * - ``new_name`` + - The new column name. + +Examples +=========== + +Renaming a column +----------------------------------------- + +.. code-block:: postgres + + -- Remove the 'weight' column + ALTER TABLE users RENAME COLUMN weight TO mass; + +Renaming a quoted name +-------------------------- + +.. code-block:: postgres + + ALTER TABLE users RENAME COLUMN "mass" TO "Mass (Kilograms); \ No newline at end of file diff --git a/reference/sql/sql_statements/ddl_commands/rename_table.rst b/reference/sql/sql_statements/ddl_commands/rename_table.rst new file mode 100644 index 000000000..96cc7102e --- /dev/null +++ b/reference/sql/sql_statements/ddl_commands/rename_table.rst @@ -0,0 +1,57 @@ +.. _rename_table: + +********************** +RENAME TABLE +********************** + +``RENAME TABLE`` can be used to rename a table. + +.. warning:: Renaming a table can void existing views that use this table. See more about :ref:`recompiling views `. + +Permissions +============= + +The role must have the ``DDL`` permission at the database or table level. + +Syntax +========== + +.. code-block:: postgres + + alter_table_rename_table_statement ::= + ALTER TABLE [schema_name.]current_name RENAME TO new_name + ; + + current_name ::= identifier + + schema_name ::= identifier + + new_name ::= identifier + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``schema_name`` + - The schema name for the table. Defaults to ``public`` if not specified. + * - ``current_name`` + - The table name to apply the change to. + * - ``new_name`` + - The new table name. + +Examples +=========== + +Renaming a table +----------------------------------------- + +.. code-block:: postgres + + ALTER TABLE public.users RENAME TO former_users; + + diff --git a/reference/sql/sql_statements/index.rst b/reference/sql/sql_statements/index.rst index 9525955d2..a8e27cb6e 100644 --- a/reference/sql/sql_statements/index.rst +++ b/reference/sql/sql_statements/index.rst @@ -18,48 +18,48 @@ Data Definition Commands (DDL) * - Command - Usage - * - `ADD COLUMN `_ - - Add a new column to a table - * - `ALTER DEFAULT SCHEMA `_ - - Change the default schema for a role - * - `ALTER TABLE `_ - - Change the schema of a table - * - `CLUSTER BY `_ - - Change clustering keys in a table - * - `CREATE DATABASE `_ - - Create a new database - * - `CREATE EXTERNAL TABLE `_ - - Create a new external table in the database (deprecated) - * - `CREATE FOREIGN TABLE `_ - - Create a new foreign table in the database - * - `CREATE FUNCTION `_ - - Create a new user defined function in the database - * - `CREATE SCHEMA `_ - - Create a new schema in the database - * - `CREATE TABLE `_ - - Create a new table in the database - * - `CREATE TABLE AS `_ - - Create a new table in the database using results from a select query - * - `CREATE VIEW `_ - - Create a new view in the database - * - `DROP CLUSTERING KEY `_ - - Drops all clustering keys in a table - * - `DROP COLUMN `_ - - Drop a column from a table - * - `DROP DATABASE `_ - - Drop a database and all of its objects - * - `DROP FUNCTION `_ - - Drop a function - * - `DROP SCHEMA `_ - - Drop a schema - * - `DROP TABLE `_ - - Drop a table and its contents from a database - * - `DROP VIEW `_ - - Drop a view - * - `RENAME COLUMN `_ - - Rename a column - * - `RENAME TABLE `_ - - Rename a table + * - :ref:`add_column` + - Add a new column to a table + * - :ref:`alter_default_schema` + - Change the default schema for a role + * - :ref:`alter_table` + - Change the schema of a table + * - :ref:`cluster_by` + - Change clustering keys in a table + * - :ref:`create_database` + - Create a new database + * - :ref:`create_external_table` + - Create a new external table in the database (deprecated) + * - :ref:`create_foreign_table` + - Create a new foreign table in the database + * - :ref:`create_function` + - Create a new user defined function in the database + * - :ref:`create_schema` + - Create a new schema in the database + * - :ref:`create_table` + - Create a new table in the database + * - :ref:`create_table_as` + - Create a new table in the database using results from a select query + * - :ref:`create_view` + - Create a new view in the database + * - :ref:`drop_clustering_key` + - Drops all clustering keys in a table + * - :ref:`drop_column` + - Drop a column from a table + * - :ref:`drop_database` + - Drop a database and all of its objects + * - :ref:`drop_function` + - Drop a function + * - :ref:`drop_schema` + - Drop a schema + * - :ref:`drop_table` + - Drop a table and its contents from a database + * - :ref:`drop_view` + - Drop a view + * - :ref:`rename_column` + - Rename a column + * - :ref:`rename_table` + - Rename a table Data Manipulation Commands (DML) ================================ From e0d71c1e5b4446c14b394d10da6ecde5e9393316 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 27 Mar 2022 17:23:31 +0300 Subject: [PATCH 022/316] Updated Menus Used new menu documentation method. --- .../sql_functions/scalar_functions/index.rst | 3 -- .../sql_functions/system_functions/index.rst | 19 +++++----- .../user_defined_functions/index.rst | 21 +++-------- .../sql_functions/window_functions/index.rst | 35 ++++++++----------- reference/sql/sql_statements/index.rst | 16 +-------- reference/sql/sql_syntax/index.rst | 24 ++++++------- 6 files changed, 40 insertions(+), 78 deletions(-) diff --git a/reference/sql/sql_functions/scalar_functions/index.rst b/reference/sql/sql_functions/scalar_functions/index.rst index b21071021..bd05f9bbe 100644 --- a/reference/sql/sql_functions/scalar_functions/index.rst +++ b/reference/sql/sql_functions/scalar_functions/index.rst @@ -3,13 +3,10 @@ **************** Built-In Scalar Functions **************** -FF - The **Built-In Scalar Functions** page describes functions that return one value per call: .. hlist:: :columns: 5 - * `AND `_ * `NOT `_ diff --git a/reference/sql/sql_functions/system_functions/index.rst b/reference/sql/sql_functions/system_functions/index.rst index a27dfda62..ba99610ba 100644 --- a/reference/sql/sql_functions/system_functions/index.rst +++ b/reference/sql/sql_functions/system_functions/index.rst @@ -7,14 +7,13 @@ System Functions The System Functions page describes the following: -.. toctree:: - :maxdepth: 1 - :glob: +.. hlist:: + :columns: 1 - explain - show_version - show_connections - show_locks - show_node_info - show_server_status - stop_statement \ No newline at end of file + * :ref:`explain` + * :ref:`show_version` + * :ref:`show_connections` + * :ref:`show_locks` + * :ref:`show_node_info` + * :ref:`show_server_status` + * :ref:`stop_statement` \ No newline at end of file diff --git a/reference/sql/sql_functions/user_defined_functions/index.rst b/reference/sql/sql_functions/user_defined_functions/index.rst index 225c9614e..028e35a07 100644 --- a/reference/sql/sql_functions/user_defined_functions/index.rst +++ b/reference/sql/sql_functions/user_defined_functions/index.rst @@ -4,22 +4,9 @@ User-Defined Functions ******************** -The following user-defined functions are functions that can be defined and configured by users: +The following user-defined functions are functions that can be defined and configured by users. +The **User-Defined Functions** page describes the following: - -* `Python user-defined functions `_. -* `Scalar SQL user-defined functions `_. - - - - -.. toctree:: - :maxdepth: 8 - :glob: - :hidden: - - - - python_functions - scalar_sql_udf +* `Python user-defined functions `_ +* `Scalar SQL user-defined functions `_ \ No newline at end of file diff --git a/reference/sql/sql_functions/window_functions/index.rst b/reference/sql/sql_functions/window_functions/index.rst index 4061ad239..e949e0e3c 100644 --- a/reference/sql/sql_functions/window_functions/index.rst +++ b/reference/sql/sql_functions/window_functions/index.rst @@ -4,26 +4,21 @@ Window Functions ******************** -Window functions are functions applied over a subset (known as a window) of the rows returned by a :ref:`select` query. +Window functions are functions applied over a subset (known as a window) of the rows returned by a :ref:`select` query and describes the following: -Read more about :ref:`window_functions` in the :ref:`sql_syntax` section. - -.. toctree:: - :maxdepth: 1 - :caption: Window Functions: - :glob: - :hidden: +.. hlist:: + :columns: 1 - lag - lead - row_number - rank - first_value - last_value - nth_value - dense_rank - percent_rank - cume_dist - ntile - + * :ref:`lag` + * :ref:`lead` + * :ref:`row_number` + * :ref:`rank` + * :ref:`first_value` + * :ref:`last_value` + * :ref:`nth_value` + * :ref:`dense_rank` + * :ref:`percent_rank` + * :ref:`cume_dist` + * :ref:`ntile` +For more information, see :ref:`window_functions` in the :ref:`sql_syntax` section. \ No newline at end of file diff --git a/reference/sql/sql_statements/index.rst b/reference/sql/sql_statements/index.rst index a8e27cb6e..bede1de2e 100644 --- a/reference/sql/sql_statements/index.rst +++ b/reference/sql/sql_statements/index.rst @@ -204,18 +204,4 @@ Access Control Commands * - :ref:`revoke` - Revoke permissions from a role * - :ref:`rename_role` - - Rename a role - - -.. toctree:: - :maxdepth: 1 - :titlesonly: - :hidden: - :glob: - - ddl_commands/* - dml_commands/* - utility_commands/* - monitoring_commands/* - wlm_commands/* - access_control_commands/* \ No newline at end of file + - Rename a role \ No newline at end of file diff --git a/reference/sql/sql_syntax/index.rst b/reference/sql/sql_syntax/index.rst index 90caf01e5..9e0422db4 100644 --- a/reference/sql/sql_syntax/index.rst +++ b/reference/sql/sql_syntax/index.rst @@ -4,18 +4,16 @@ SQL Syntax Features ********************** -SQream DB supports SQL from the ANSI 92 syntax. +SQream DB supports SQL from the ANSI 92 syntax and describes the following: -.. toctree:: - :maxdepth: 2 - :caption: SQL Syntax Topics - :glob: +.. hlist:: + :columns: 1 - keywords_and_identifiers - literals - scalar_expressions - joins - common_table_expressions - window_functions - subqueries - null_handling + * :ref:`keywords_and_identifiers` + * :ref:`literals` + * :ref:`scalar_expressions` + * :ref:`joins` + * :ref:`common_table_expressions` + * :ref:`window_functions` + * :ref:`subqueries` + * :ref:`null_handling` \ No newline at end of file From e3dcb2d92dbf1c7415bf5dcb95dc9978ab7d77bf Mon Sep 17 00:00:00 2001 From: YanivGerowitz <82020437+YanivGerowitz@users.noreply.github.com> Date: Mon, 28 Mar 2022 14:33:25 +0300 Subject: [PATCH 023/316] Update running_sqream_in_a_docker_container.rst --- .../running_sqream_in_a_docker_container.rst | 40 ++++++++----------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/installation_guides/running_sqream_in_a_docker_container.rst b/installation_guides/running_sqream_in_a_docker_container.rst index 040223936..8e42c910d 100644 --- a/installation_guides/running_sqream_in_a_docker_container.rst +++ b/installation_guides/running_sqream_in_a_docker_container.rst @@ -1,7 +1,5 @@ .. _running_sqream_in_a_docker_container: - - *********************** Installing and Running SQream in a Docker Container *********************** @@ -519,19 +517,15 @@ Installing the Docker Engine on an IBM Power9 Processor ---------------------------------------- The x86_64 processor only supports installing the **Docker Community Edition (CE)** version 18.03. - **To install the Docker Engine on an IBM Power9 processor:** You can install the Docker Engine on an IBM Power9 processor by running the following command: .. code-block:: console - $ wget http://ftp.unicamp.br/pub/ppc64el/rhel/7_1/docker-ppc64el/container-selinux-2.9-4.el7.noarch.rpm - $ wget http://ftp.unicamp.br/pub/ppc64el/rhel/7_1/docker-ppc64el/docker-ce-18.03.1.ce-1.el7.centos.ppc64le.rpm - $ yum install -y container-selinux-2.9-4.el7.noarch.rpm - $ docker-ce-18.03.1.ce-1.el7.centos.ppc64le.rpm - - + wget http://ftp.unicamp.br/pub/ppc64el/rhel/7_1/docker-ppc64el/container-selinux-2.9-4.el7.noarch.rpm + wget http://ftp.unicamp.br/pub/ppc64el/rhel/7_1/docker-ppc64el/docker-ce-18.03.1.ce-1.el7.centos.ppc64le.rpm + yum install -y container-selinux-2.9-4.el7.noarch.rpm docker-ce-18.03.1.ce-1.el7.centos.ppc64le.rpm For more information on installing the Docker Engine CE on an IBM Power9 processor, see `Install Docker Engine on Ubuntu `_. @@ -576,8 +570,8 @@ After configuring Docker on your local machine you must install the Nvidia Docke This section describes the following: -* :ref:`Installing the NVIDIA Docker2 Toolkit on an x86_64 processor. ` -* :ref:`Installing the NVIDIA Docker2 Toolkit on a PPC64le processor. ` +* :ref:`Installing the NVIDIA Docker2 Toolkit on an x86_64 processor ` +* :ref:`Installing the NVIDIA Docker2 Toolkit on a PPC64le processor ` .. _install_nvidia_docker2_toolkit_x8664_processor: @@ -601,10 +595,9 @@ Installing the NVIDIA Docker2 Toolkit on a CentOS Operating System .. code-block:: console - $ distribution=$(. /etc/os-release;echo $ID$VERSION_ID) - $ curl -s -L - $ https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.repo | \ - $ sudo tee /etc/yum.repos.d/nvidia-docker.repo + distribution=$(. /etc/os-release;echo $ID$VERSION_ID) + curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.repo | \ + sudo tee /etc/yum.repos.d/nvidia-docker.repo 2. Install the ``nvidia-docker2`` package and reload the Docker daemon configuration: @@ -654,13 +647,10 @@ Installing the NVIDIA Docker2 Toolkit on an Ubuntu Operating System .. code-block:: console - $ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | \ - $ sudo apt-key add - - $ distribution=$(. /etc/os-release;echo $ID$VERSION_ID) - $ curl -s -L - $ https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \ - $ sudo tee /etc/apt/sources.list.d/nvidia-docker.list - $ sudo apt-get update + curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - + distribution=$(. /etc/os-release;echo $ID$VERSION_ID) + curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list + sudo apt-get update 2. Install the ``nvidia-docker2`` package and reload the Docker daemon configuration: @@ -668,7 +658,9 @@ Installing the NVIDIA Docker2 Toolkit on an Ubuntu Operating System $ sudo apt-get install nvidia-docker2 $ sudo pkill -SIGHUP dockerd + 3. Do one of the following: + * If you received an error when installing the ``nvidia-docker2`` package, skip to :ref:`Step 4 `. * If you successfully installed the ``nvidia-docker2`` package, skip to :ref:`Step 5 `. @@ -795,8 +787,8 @@ For more information about the correct directory to copy the above files into, s For related information, see the following sections: -* :ref:`Configuring the Hadoop and Kubernetes Configuration Files `. -* :ref:`Setting the Hadoop and Kubernetes Configuration Parameters `. +* :ref:`Configuring the Hadoop and Kubernetes Configuration Files ` +* :ref:`Setting the Hadoop and Kubernetes Configuration Parameters ` .. _installing_sqream_software: From 96086da570ac664009d04d989aa9541ff084ed3d Mon Sep 17 00:00:00 2001 From: YanivGerowitz <82020437+YanivGerowitz@users.noreply.github.com> Date: Mon, 28 Mar 2022 14:33:38 +0300 Subject: [PATCH 024/316] Update running_sqream_in_a_docker_container.rst --- .../running_sqream_in_a_docker_container.rst | 40 ++++++++----------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/installation_guides/running_sqream_in_a_docker_container.rst b/installation_guides/running_sqream_in_a_docker_container.rst index 040223936..8e42c910d 100644 --- a/installation_guides/running_sqream_in_a_docker_container.rst +++ b/installation_guides/running_sqream_in_a_docker_container.rst @@ -1,7 +1,5 @@ .. _running_sqream_in_a_docker_container: - - *********************** Installing and Running SQream in a Docker Container *********************** @@ -519,19 +517,15 @@ Installing the Docker Engine on an IBM Power9 Processor ---------------------------------------- The x86_64 processor only supports installing the **Docker Community Edition (CE)** version 18.03. - **To install the Docker Engine on an IBM Power9 processor:** You can install the Docker Engine on an IBM Power9 processor by running the following command: .. code-block:: console - $ wget http://ftp.unicamp.br/pub/ppc64el/rhel/7_1/docker-ppc64el/container-selinux-2.9-4.el7.noarch.rpm - $ wget http://ftp.unicamp.br/pub/ppc64el/rhel/7_1/docker-ppc64el/docker-ce-18.03.1.ce-1.el7.centos.ppc64le.rpm - $ yum install -y container-selinux-2.9-4.el7.noarch.rpm - $ docker-ce-18.03.1.ce-1.el7.centos.ppc64le.rpm - - + wget http://ftp.unicamp.br/pub/ppc64el/rhel/7_1/docker-ppc64el/container-selinux-2.9-4.el7.noarch.rpm + wget http://ftp.unicamp.br/pub/ppc64el/rhel/7_1/docker-ppc64el/docker-ce-18.03.1.ce-1.el7.centos.ppc64le.rpm + yum install -y container-selinux-2.9-4.el7.noarch.rpm docker-ce-18.03.1.ce-1.el7.centos.ppc64le.rpm For more information on installing the Docker Engine CE on an IBM Power9 processor, see `Install Docker Engine on Ubuntu `_. @@ -576,8 +570,8 @@ After configuring Docker on your local machine you must install the Nvidia Docke This section describes the following: -* :ref:`Installing the NVIDIA Docker2 Toolkit on an x86_64 processor. ` -* :ref:`Installing the NVIDIA Docker2 Toolkit on a PPC64le processor. ` +* :ref:`Installing the NVIDIA Docker2 Toolkit on an x86_64 processor ` +* :ref:`Installing the NVIDIA Docker2 Toolkit on a PPC64le processor ` .. _install_nvidia_docker2_toolkit_x8664_processor: @@ -601,10 +595,9 @@ Installing the NVIDIA Docker2 Toolkit on a CentOS Operating System .. code-block:: console - $ distribution=$(. /etc/os-release;echo $ID$VERSION_ID) - $ curl -s -L - $ https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.repo | \ - $ sudo tee /etc/yum.repos.d/nvidia-docker.repo + distribution=$(. /etc/os-release;echo $ID$VERSION_ID) + curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.repo | \ + sudo tee /etc/yum.repos.d/nvidia-docker.repo 2. Install the ``nvidia-docker2`` package and reload the Docker daemon configuration: @@ -654,13 +647,10 @@ Installing the NVIDIA Docker2 Toolkit on an Ubuntu Operating System .. code-block:: console - $ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | \ - $ sudo apt-key add - - $ distribution=$(. /etc/os-release;echo $ID$VERSION_ID) - $ curl -s -L - $ https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \ - $ sudo tee /etc/apt/sources.list.d/nvidia-docker.list - $ sudo apt-get update + curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - + distribution=$(. /etc/os-release;echo $ID$VERSION_ID) + curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list + sudo apt-get update 2. Install the ``nvidia-docker2`` package and reload the Docker daemon configuration: @@ -668,7 +658,9 @@ Installing the NVIDIA Docker2 Toolkit on an Ubuntu Operating System $ sudo apt-get install nvidia-docker2 $ sudo pkill -SIGHUP dockerd + 3. Do one of the following: + * If you received an error when installing the ``nvidia-docker2`` package, skip to :ref:`Step 4 `. * If you successfully installed the ``nvidia-docker2`` package, skip to :ref:`Step 5 `. @@ -795,8 +787,8 @@ For more information about the correct directory to copy the above files into, s For related information, see the following sections: -* :ref:`Configuring the Hadoop and Kubernetes Configuration Files `. -* :ref:`Setting the Hadoop and Kubernetes Configuration Parameters `. +* :ref:`Configuring the Hadoop and Kubernetes Configuration Files ` +* :ref:`Setting the Hadoop and Kubernetes Configuration Parameters ` .. _installing_sqream_software: From 2e9e91ce5627265a7186b6e1351099fbda087766 Mon Sep 17 00:00:00 2001 From: YanivGerowitz <82020437+YanivGerowitz@users.noreply.github.com> Date: Mon, 28 Mar 2022 14:47:15 +0300 Subject: [PATCH 025/316] Update running_sqream_in_a_docker_container.rst --- installation_guides/running_sqream_in_a_docker_container.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/installation_guides/running_sqream_in_a_docker_container.rst b/installation_guides/running_sqream_in_a_docker_container.rst index 8e42c910d..79caa9f8d 100644 --- a/installation_guides/running_sqream_in_a_docker_container.rst +++ b/installation_guides/running_sqream_in_a_docker_container.rst @@ -3,7 +3,7 @@ *********************** Installing and Running SQream in a Docker Container *********************** -The **Running SQream in a Docker Container** page describes how to prepare your machine's environment for installing and running SQream in a Docker container. +The **Installing and Running SQream in a Docker Container** page describes how to prepare your machine's environment for installing and running SQream in a Docker container. This page describes the following: @@ -102,7 +102,7 @@ You can install the required NTP packages by running the following command: .. code-block:: console - $ sudo yum install ntp pciutils python36 kernel-devel-$(uname -r) kernel-headers-$(uname -r) gcc + $ sudo yum install ntp pciutils python36 kernel-devel-$(uname -r) kernel-headers-$(uname -r) gcc Installing the Recommended Tools ---------------- From 2e48016372f05aa75032fc11670e9bc07fcdee7b Mon Sep 17 00:00:00 2001 From: YanivGerowitz <82020437+YanivGerowitz@users.noreply.github.com> Date: Mon, 28 Mar 2022 14:47:48 +0300 Subject: [PATCH 026/316] Update running_sqream_in_a_docker_container.rst --- installation_guides/running_sqream_in_a_docker_container.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/installation_guides/running_sqream_in_a_docker_container.rst b/installation_guides/running_sqream_in_a_docker_container.rst index 8e42c910d..79caa9f8d 100644 --- a/installation_guides/running_sqream_in_a_docker_container.rst +++ b/installation_guides/running_sqream_in_a_docker_container.rst @@ -3,7 +3,7 @@ *********************** Installing and Running SQream in a Docker Container *********************** -The **Running SQream in a Docker Container** page describes how to prepare your machine's environment for installing and running SQream in a Docker container. +The **Installing and Running SQream in a Docker Container** page describes how to prepare your machine's environment for installing and running SQream in a Docker container. This page describes the following: @@ -102,7 +102,7 @@ You can install the required NTP packages by running the following command: .. code-block:: console - $ sudo yum install ntp pciutils python36 kernel-devel-$(uname -r) kernel-headers-$(uname -r) gcc + $ sudo yum install ntp pciutils python36 kernel-devel-$(uname -r) kernel-headers-$(uname -r) gcc Installing the Recommended Tools ---------------- From d11076aa93cb435131a6a5708ded114e9e29f49a Mon Sep 17 00:00:00 2001 From: YanivGerowitz <82020437+YanivGerowitz@users.noreply.github.com> Date: Mon, 28 Mar 2022 15:04:08 +0300 Subject: [PATCH 027/316] Update running_sqream_in_a_docker_container.rst --- .../running_sqream_in_a_docker_container.rst | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/installation_guides/running_sqream_in_a_docker_container.rst b/installation_guides/running_sqream_in_a_docker_container.rst index 79caa9f8d..aba0d109f 100644 --- a/installation_guides/running_sqream_in_a_docker_container.rst +++ b/installation_guides/running_sqream_in_a_docker_container.rst @@ -146,7 +146,7 @@ After configuring the NTP package you must configure the performance profile. **To configure the performance profile:** -1. Switch the active profile: +1. *Optional* - Switch the active profile: .. code-block:: console @@ -337,10 +337,6 @@ For installer type, SQream recommends selecting **runfile (local)**. The availab $ sudo systemctl enable nvidia-persistenced.service && sudo systemctl start nvidia-persistenced.service -6. Create a symbolic link from the **/etc/systemd/system/multi-user.target.wants/nvidia-persistenced.service** file to the **/usr/lib/systemd/system/nvidia-persistenced.service** file. - - :: - 7. Reboot the server. :: @@ -418,10 +414,6 @@ Installing the CUDA Driver Version 10.1 for IBM Power9 .. code-block:: console $ sudo systemctl enable nvidia-persistenced.service - -#. Create a symbolic link from the **/etc/systemd/system/multi-user.target.wants/nvidia-persistenced.service** file to the **/usr/lib/systemd/system/nvidia-persistenced.service** file. - - :: #. Reboot your system to initialize the above modifications. @@ -832,7 +824,7 @@ The **sqream_installer-nnn-DBnnn-COnnn-EDnnn-.tar.gz** file includes the f $ tar -xvf sqream_installer-1.1.5-DB2019.2.1-CO1.5.4-ED3.0.0-x86_64.tar.gz -When the tarball file has been extracted, a new folder will be created. The new folder is automatically given the name of the tarball file: + When the tarball file has been extracted, a new folder will be created. The new folder is automatically given the name of the tarball file: .. code-block:: console @@ -1247,7 +1239,7 @@ You can stop your SQream Studio by running the following command: The following is an example of the expected output: -.. code-block:: console +.. code-block:: sqream_admin stopped @@ -1256,8 +1248,6 @@ The following is an example of the expected output: Using the SQream Client ~~~~~~~~~~~~~~~~~ - - You can use the embedded SQream Client on the following nodes: * Master node From a9a152bb8f169bc0e4865bd27e09b327ed854c15 Mon Sep 17 00:00:00 2001 From: YanivGerowitz <82020437+YanivGerowitz@users.noreply.github.com> Date: Mon, 28 Mar 2022 15:11:06 +0300 Subject: [PATCH 028/316] Update running_sqream_in_a_docker_container.rst --- .../running_sqream_in_a_docker_container.rst | 198 +++++++++--------- 1 file changed, 99 insertions(+), 99 deletions(-) diff --git a/installation_guides/running_sqream_in_a_docker_container.rst b/installation_guides/running_sqream_in_a_docker_container.rst index aba0d109f..e85eac925 100644 --- a/installation_guides/running_sqream_in_a_docker_container.rst +++ b/installation_guides/running_sqream_in_a_docker_container.rst @@ -34,19 +34,19 @@ To run SQream in a Docker container you must create a local user. 1. Add a local user: - .. code-block:: console + .. code-block:: $ useradd -m -U 2. Set the local user's password: - .. code-block:: console + .. code-block:: $ passwd 3. Add the local user to the ``wheel`` group: - .. code-block:: console + .. code-block:: $ usermod -aG wheel @@ -62,13 +62,13 @@ After creating a local user you must set a local language. 1. Set the local language: - .. code-block:: console + .. code-block:: $ sudo localectl set-locale LANG=en_US.UTF-8 2. Set the time stamp (time and date) of the locale: - .. code-block:: console + .. code-block:: $ sudo timedatectl set-timezone Asia/Jerusalem @@ -84,13 +84,13 @@ After setting a local language you must add the EPEL repository. 1. RedHat (RHEL 7): - .. code-block:: console + .. code-block:: $ sudo rpm -Uvh http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm 2. CentOS 7 - .. code-block:: console + .. code-block:: $ sudo yum install epel-release @@ -100,7 +100,7 @@ After adding the EPEL repository, you must install the required NTP packages. You can install the required NTP packages by running the following command: -.. code-block:: console +.. code-block:: $ sudo yum install ntp pciutils python36 kernel-devel-$(uname -r) kernel-headers-$(uname -r) gcc @@ -110,7 +110,7 @@ After installin gthe required NTP packages you must install the recommended tool SQream recommends installing the following recommended tools: -.. code-block:: console +.. code-block:: $ sudo yum install bash-completion.noarch vim-enhanced.x86_64 vim-common.x86_64 net-tools iotop htop psmisc screen xfsprogs wget yum-utils deltarpm dos2unix @@ -134,7 +134,7 @@ After updating to the current version of the operating system you must configure 2. Configure the **ntpd** service to begin running when your machine is started: - .. code-block:: console + .. code-block:: $ sudo systemctl enable ntpd $ sudo systemctl start ntpd @@ -148,13 +148,13 @@ After configuring the NTP package you must configure the performance profile. 1. *Optional* - Switch the active profile: - .. code-block:: console + .. code-block:: $ sudo tuned-adm profile throughput-performance 2. Change the multi-user's default run level: - .. code-block:: console + .. code-block:: $ sudo systemctl set-default multi-user.target @@ -166,19 +166,19 @@ After configuring the performance profile you must configure your security limit 1. Run the **bash** shell as a super-user: - .. code-block:: console + .. code-block:: $ sudo bash 2. Run the following command: - .. code-block:: console + .. code-block:: $ echo -e "sqream soft nproc 500000\nsqream hard nproc 500000\nsqream soft nofile 500000\nsqream hard nofile 500000\nsqream soft core unlimited\nsqream hard core unlimited" >> /etc/security/limits.conf 3. Run the following command: - .. code-block:: console + .. code-block:: $ echo -e "vm.dirty_background_ratio = 5 \n vm.dirty_ratio = 10 \n vm.swappiness = 10 \n vm.zone_reclaim_mode = 0 \n vm.vfs_cache_pressure = 200 \n" >> /etc/sysctl.conf @@ -194,7 +194,7 @@ After configuring your security limits you must disable the following automatic You can abort the above but-reporting tools by running the following command: -.. code-block:: console +.. code-block:: $ for i in abrt-ccpp.service abrtd.service abrt-oops.service abrt-pstoreoops.service abrt-vmcore.service abrt-xorg.service ; do sudo systemctl disable $i; sudo systemctl stop $i; done @@ -203,7 +203,7 @@ Installing the Nvidia CUDA Driver 1. Verify that the Tesla NVIDIA card has been installed and is detected by the system: - .. code-block:: console + .. code-block:: $ lspci | grep -i nvidia @@ -211,7 +211,7 @@ Installing the Nvidia CUDA Driver #. Verify that the open-source upstream Nvidia driver is running: - .. code-block:: console + .. code-block:: $ lsmod | grep nouveau @@ -221,7 +221,7 @@ Installing the Nvidia CUDA Driver 1. Disable the open-source upstream Nvidia driver: - .. code-block:: console + .. code-block:: $ sudo bash $ echo "blacklist nouveau" > /etc/modprobe.d/blacklist-nouveau.conf @@ -231,19 +231,19 @@ Installing the Nvidia CUDA Driver 2. Reboot the server and verify that the Nouveau model has not been loaded: - .. code-block:: console + .. code-block:: $ lsmod | grep nouveau #. Check if the Nvidia CUDA driver has already been installed: - .. code-block:: console + .. code-block:: $ nvidia-smi The following is an example of the correct output: - .. code-block:: console + .. code-block:: nvidia-smi Wed Oct 30 14:05:42 2019 @@ -310,14 +310,14 @@ For installer type, SQream recommends selecting **runfile (local)**. The availab 2. Download the base installer for Linux CentOS 7 x86_64: - .. code-block:: console + .. code-block:: wget http://developer.download.nvidia.com/compute/cuda/10.1/Prod/local_installers/cuda-repo-rhel7-10-1-local-10.1.243-418.87.00-1.0-1.x86_64.rpm 3. Install the base installer for Linux CentOS 7 x86_64 by running the following commands: - .. code-block:: console + .. code-block:: $ sudo yum localinstall cuda-repo-rhel7-10-1-local-10.1.243-418.87.00-1.0-1.x86_64.rpm $ sudo yum clean all @@ -333,7 +333,7 @@ For installer type, SQream recommends selecting **runfile (local)**. The availab 5. Enable the Nvidia service to start at boot and start it: - .. code-block:: console + .. code-block:: $ sudo systemctl enable nvidia-persistenced.service && sudo systemctl start nvidia-persistenced.service @@ -342,13 +342,13 @@ For installer type, SQream recommends selecting **runfile (local)**. The availab :: 8. Verify that the Nvidia driver has been installed and shows all available GPU's: - .. code-block:: console + .. code-block:: $ nvidia-smi The following is the correct output: - .. code-block:: console + .. code-block:: nvidia-smi Wed Oct 30 14:05:42 2019 @@ -381,14 +381,14 @@ Installing the CUDA Driver Version 10.1 for IBM Power9 1. Download the base installer for Linux CentOS 7 PPC64le: - .. code-block:: console + .. code-block:: wget http://developer.download.nvidia.com/compute/cuda/10.1/Prod/local_installers/cuda-repo-rhel7-10-1-local-10.1.243-418.87.00-1.0-1.ppc64le.rpm #. Install the base installer for Linux CentOS 7 x86_64 by running the following commands: - .. code-block:: console + .. code-block:: $ sudo rpm -i cuda-repo-rhel7-10-1-local-10.1.243-418.87.00-1.0-1.ppc64le.rpm $ sudo yum clean all @@ -404,14 +404,14 @@ Installing the CUDA Driver Version 10.1 for IBM Power9 4. If you are using RHEL 7 version (7.6 or later), comment out, remove, or change the hot-pluggable memory rule located in file copied to the **/etc/udev/rules.d** directory by running the following command: - .. code-block:: console + .. code-block:: $ sudo cp /lib/udev/rules.d/40-redhat.rules /etc/udev/rules.d $ sudo sed -i 's/SUBSYSTEM!="memory",.*GOTO="memory_hotplug_end"/SUBSYSTEM=="*", GOTO="memory_hotplug_end"/' /etc/udev/rules.d/40-redhat.rules #. Enable the **nvidia-persisted.service** file: - .. code-block:: console + .. code-block:: $ sudo systemctl enable nvidia-persistenced.service @@ -421,13 +421,13 @@ Installing the CUDA Driver Version 10.1 for IBM Power9 #. Verify that the Nvidia driver and the **nvidia-persistenced.service** files are running: - .. code-block:: console + .. code-block:: $ nvidia smi The following is the correct output: - .. code-block:: console + .. code-block:: nvidia-smi Wed Oct 30 14:05:42 2019 @@ -453,13 +453,13 @@ Installing the CUDA Driver Version 10.1 for IBM Power9 #. Verify that the **nvidia-persistenced** service is running: - .. code-block:: console + .. code-block:: $ systemctl status nvidia-persistenced The following is the correct output: - .. code-block:: console + .. code-block:: root@gpudb ~]systemctl status nvidia-persistenced nvidia-persistenced.service - NVIDIA Persistence Daemon @@ -513,7 +513,7 @@ The x86_64 processor only supports installing the **Docker Community Edition (CE You can install the Docker Engine on an IBM Power9 processor by running the following command: -.. code-block:: console +.. code-block:: wget http://ftp.unicamp.br/pub/ppc64el/rhel/7_1/docker-ppc64el/container-selinux-2.9-4.el7.noarch.rpm wget http://ftp.unicamp.br/pub/ppc64el/rhel/7_1/docker-ppc64el/docker-ce-18.03.1.ce-1.el7.centos.ppc64le.rpm @@ -529,13 +529,13 @@ After installing the Docker engine you must configure Docker on your local machi 1. Enable Docker to start on boot: - .. code-block:: console + .. code-block:: $ sudo systemctl enable docker && sudo systemctl start docker 2. Enable managing Docker as a non-root user: - .. code-block:: console + .. code-block:: $ sudo usermod -aG docker $USER @@ -545,7 +545,7 @@ After installing the Docker engine you must configure Docker on your local machi 4. Verify that you can run the following Docker command as a non-root user (without ``sudo``): - .. code-block:: console + .. code-block:: $ docker run hello-world @@ -585,7 +585,7 @@ Installing the NVIDIA Docker2 Toolkit on a CentOS Operating System 1. Install the repository for your distribution: - .. code-block:: console + .. code-block:: distribution=$(. /etc/os-release;echo $ID$VERSION_ID) curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.repo | \ @@ -593,7 +593,7 @@ Installing the NVIDIA Docker2 Toolkit on a CentOS Operating System 2. Install the ``nvidia-docker2`` package and reload the Docker daemon configuration: - .. code-block:: console + .. code-block:: $ sudo yum install nvidia-docker2 $ sudo pkill -SIGHUP dockerd @@ -610,7 +610,7 @@ Installing the NVIDIA Docker2 Toolkit on a CentOS Operating System 1. Run the ``sudo vi /etc/yum.repos.d/nvidia-docker.repo`` command if the following error is displayed when installing the ``nvidia-docker2`` package: - .. code-block:: console + .. code-block:: https://nvidia.github.io/nvidia-docker/centos7/ppc64le/repodata/repomd.xml: [Errno -1] repomd.xml signature could not be verified for nvidia-docker @@ -621,7 +621,7 @@ Installing the NVIDIA Docker2 Toolkit on a CentOS Operating System 5. Verify that the NVIDIA-Docker run has been installed correctly: - .. code-block:: console + .. code-block:: $ docker run --runtime=nvidia --rm nvidia/cuda:10.1-base nvidia-smi @@ -637,7 +637,7 @@ Installing the NVIDIA Docker2 Toolkit on an Ubuntu Operating System 1. Install the repository for your distribution: - .. code-block:: console + .. code-block:: curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - distribution=$(. /etc/os-release;echo $ID$VERSION_ID) @@ -646,7 +646,7 @@ Installing the NVIDIA Docker2 Toolkit on an Ubuntu Operating System 2. Install the ``nvidia-docker2`` package and reload the Docker daemon configuration: - .. code-block:: console + .. code-block:: $ sudo apt-get install nvidia-docker2 $ sudo pkill -SIGHUP dockerd @@ -662,7 +662,7 @@ Installing the NVIDIA Docker2 Toolkit on an Ubuntu Operating System 1. Run the ``sudo vi /etc/yum.repos.d/nvidia-docker.repo`` command if the following error is displayed when installing the ``nvidia-docker2`` package: - .. code-block:: console + .. code-block:: https://nvidia.github.io/nvidia-docker/centos7/ppc64le/repodata/repomd.xml: [Errno -1] repomd.xml signature could not be verified for nvidia-docker @@ -673,7 +673,7 @@ Installing the NVIDIA Docker2 Toolkit on an Ubuntu Operating System 5. Verify that the NVIDIA-Docker run has been installed correctly: - .. code-block:: console + .. code-block:: $ docker run --runtime=nvidia --rm nvidia/cuda:10.1-base nvidia-smi @@ -690,7 +690,7 @@ This section describes how to install the NVIDIA Docker2 Toolkit on an IBM RHEL 1. Import the repository and install the ``libnvidia-container`` and the ``nvidia-container-runtime`` containers. - .. code-block:: console + .. code-block:: $ distribution=$(. /etc/os-release;echo $ID$VERSION_ID) $ curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.repo | \ @@ -708,7 +708,7 @@ This section describes how to install the NVIDIA Docker2 Toolkit on an IBM RHEL 1. Run the ``sudo vi /etc/yum.repos.d/nvidia-docker.repo`` command if the following error is displayed when installing the containers: - .. code-block:: console + .. code-block:: https://nvidia.github.io/nvidia-docker/centos7/ppc64le/repodata/repomd.xml: [Errno -1] repomd.xml signature could not be verified for nvidia-docker @@ -719,7 +719,7 @@ This section describes how to install the NVIDIA Docker2 Toolkit on an IBM RHEL 3. Install the ``libnvidia-container`` container. - .. code-block:: console + .. code-block:: $ sudo yum install -y libnvidia-container* @@ -727,13 +727,13 @@ This section describes how to install the NVIDIA Docker2 Toolkit on an IBM RHEL 4. Install the ``nvidia-container-runtime`` container: - .. code-block:: console + .. code-block:: $ sudo yum install -y nvidia-container-runtime* 5. Add ``nvidia runtime`` to the Docker daemon: - .. code-block:: console + .. code-block:: $ sudo mkdir -p /etc/systemd/system/docker.service.d/ $ sudo vi /etc/systemd/system/docker.service.d/override.conf @@ -744,14 +744,14 @@ This section describes how to install the NVIDIA Docker2 Toolkit on an IBM RHEL 6. Restart Docker: - .. code-block:: console + .. code-block:: $ sudo systemctl daemon-reload $ sudo systemctl restart docker 7. Verify that the NVIDIA-Docker run has been installed correctly: - .. code-block:: console + .. code-block:: $ docker run --runtime=nvidia --rm nvidia/cuda-ppc64le nvidia-smi @@ -820,13 +820,13 @@ The **sqream_installer-nnn-DBnnn-COnnn-EDnnn-.tar.gz** file includes the f 2. Extract the tarball file: - .. code-block:: console + .. code-block:: $ tar -xvf sqream_installer-1.1.5-DB2019.2.1-CO1.5.4-ED3.0.0-x86_64.tar.gz When the tarball file has been extracted, a new folder will be created. The new folder is automatically given the name of the tarball file: - .. code-block:: console + .. code-block:: drwxrwxr-x 9 sqream sqream 4096 Aug 11 11:51 sqream_istaller-1.1.5-DB2019.2.1-CO1.5.4-ED3.0.0-x86_64/ -rw-rw-r-- 1 sqream sqream 3130398797 Aug 11 11:20 sqream_installer-1.1.5-DB2019.2.1-CO1.5.4-ED3.0.0-x86_64.tar.gz @@ -837,13 +837,13 @@ The **sqream_installer-nnn-DBnnn-COnnn-EDnnn-.tar.gz** file includes the f 4. Verify that the folder you just created contains all of the required files. - .. code-block:: console + .. code-block:: $ ls -la The following is an example of the files included in the new folder: - .. code-block:: console + .. code-block:: drwxrwxr-x. 10 sqream sqream 198 Jun 3 17:57 . drwx------. 25 sqream sqream 4096 Jun 7 18:11 .. @@ -950,7 +950,7 @@ Installing Your License ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Once you've configured your local environment, you must install your license by copying it into the SQream installation package folder located in the **./license** folder: -.. code-block:: console +.. code-block:: $ sudo ./sqream-install -k @@ -961,19 +961,19 @@ Validating Your License ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can copy your license package into the SQream console folder located in the **/license** folder by running the following command: -.. code-block:: console +.. code-block:: $ sudo ./sqream-install -K The following mandatory flags must be used in the first run: -.. code-block:: console +.. code-block:: $ sudo ./sqream-install -i -k -v The following is an example of the correct command syntax: -.. code-block:: console +.. code-block:: $ sudo ./sqream-install -i -k -c /etc/sqream -v /home/sqream/sqreamdb -l /var/log/sqream -d /home/sqream/data_ingest @@ -985,13 +985,13 @@ The information in this section is optional, and is only relevant for Hadoop use The following is the correct syntax when setting the Hadoop and Kubernetes connectivity parameters: -.. code-block:: console +.. code-block:: $ sudo ./sqream-install -p -e : The following is an example of setting the Hadoop and Kubernetes connectivity parameters: -.. code-block:: console +.. code-block:: $ sudo ./sqream-install -p -e kdc.sq.com:<192.168.1.111> @@ -1004,7 +1004,7 @@ Modifying Your Data Ingest Folder ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Once you've validated your license, you can modify your data ingest folder after the first run by running the following command: -.. code-block:: console +.. code-block:: $ sudo ./sqream-install -d /home/sqream/data_in @@ -1016,7 +1016,7 @@ Once you've modified your data ingest folder (if needed), you must validate that 1. To verify that your server network and Docker network do not overlap, run the following command: -.. code-block:: console +.. code-block:: $ ifconfig | grep 172. @@ -1025,7 +1025,7 @@ Once you've modified your data ingest folder (if needed), you must validate that * If running the above command output no results, continue the installation process. * If running the above command output results, run the following command: - .. code-block:: console + .. code-block:: $ ifconfig | grep 192.168. @@ -1036,13 +1036,13 @@ Once you've configured your network for Docker, you can check and verify your sy Running the following command shows you all the variables used by your SQream system: -.. code-block:: console +.. code-block:: $ ./sqream-install -s The following is an example of the correct output: -.. code-block:: console +.. code-block:: SQREAM_CONSOLE_TAG=1.5.4 SQREAM_TAG=2019.2.1 @@ -1092,7 +1092,7 @@ Starting Your SQream Console You can start your SQream console by running the following command: -.. code-block:: console +.. code-block:: $ ./sqream-console @@ -1105,13 +1105,13 @@ Starting the SQream Master 1. Start the metadata server (default port 3105) and picker (default port 3108) by running the following command: - .. code-block:: console + .. code-block:: $ sqream master --start The following is the correct output: - .. code-block:: console + .. code-block:: sqream-console> sqream master --start starting master server in single_host mode ... @@ -1120,7 +1120,7 @@ Starting the SQream Master 2. *Optional* - Change the metadata and server picker ports by adding ``-p `` and ``-m ``: - .. code-block:: console + .. code-block:: $ sqream-console>sqream master --start -p 4105 -m 43108 $ starting master server in single_host mode ... @@ -1137,13 +1137,13 @@ Starting SQream Workers When starting SQream workers, setting the ```` value sets how many workers to start. Leaving the ```` value unspecified runs all of the available resources. -.. code-block:: console +.. code-block:: $ sqream worker --start The following is an example of expected output when setting the ```` value to ``2``: - .. code-block:: console + .. code-block:: sqream-console>sqream worker --start 2 started sqream_single_host_worker_0 on port 5000, allocated gpu: 0 @@ -1157,13 +1157,13 @@ Listing the Running Services You can list running SQream services to look for container names and ID's by running the following command: -.. code-block:: console +.. code-block:: $ sqream master --list The following is an example of the expected output: -.. code-block:: console +.. code-block:: sqream-console>sqream master --list container name: sqream_single_host_worker_0, container id: c919e8fb78c8 @@ -1179,13 +1179,13 @@ You can stop running services either for a single SQream worker, or all SQream s The following is the command for stopping a running service for a single SQream worker: -.. code-block:: console +.. code-block:: $ sqream worker --stop The following is an example of expected output when stopping a running service for a single SQream worker: -.. code-block:: console +.. code-block:: sqream worker stop stopped container sqream_single_host_worker_0, id: 892a8f1a58c5 @@ -1193,13 +1193,13 @@ The following is an example of expected output when stopping a running service f You can stop all running SQream services (both master and worker) by running the following command: -.. code-block:: console +.. code-block:: $ sqream-console>sqream master --stop --all The following is an example of expected output when stopping all running services: -.. code-block:: console +.. code-block:: sqream-console>sqream master --stop --all stopped container sqream_single_host_worker_0, id: 892a8f1a58c5 @@ -1216,13 +1216,13 @@ SQream Studio is an SQL statement editor. 1. Run the following command: - .. code-block:: console + .. code-block:: $ sqream studio --start The following is an example of the expected output: - .. code-block:: console + .. code-block:: SQream Acceleration Studio is available at http://192.168.1.62:8080 @@ -1233,7 +1233,7 @@ The following is an example of the expected output: You can stop your SQream Studio by running the following command: -.. code-block:: console +.. code-block:: $ sqream studio --stop @@ -1261,7 +1261,7 @@ When using the SQream Client on the Master node, the following default settings The following is an example: -.. code-block:: console +.. code-block:: $ sqream client --master -u sqream -w sqream @@ -1270,7 +1270,7 @@ When using the SQream Client on a Worker node (or nodes), you should use the ``- The following is an example: -.. code-block:: console +.. code-block:: $ sqream client --worker -p 5000 -u sqream -w sqream @@ -1304,7 +1304,7 @@ From the console you can define a spool size value. The following example shows the spool size being set to ``50``: -.. code-block:: console +.. code-block:: $ sqream-console>sqream worker --start 2 -m 50 @@ -1321,7 +1321,7 @@ You can start more than one sqreamd on a single GPU by splitting it. The following example shows the GPU being split into **two** sqreamd's on the GPU in **slot 0**: -.. code-block:: console +.. code-block:: $ sqream-console>sqream worker --start 2 -g 0 @@ -1332,7 +1332,7 @@ Splitting GPU and Setting the Spool Size You can simultaneously split a GPU and set the spool size by appending the ``-m`` flag: -.. code-block:: console +.. code-block:: $ sqream-console>sqream worker --start 2 -g 0 -m 50 @@ -1349,19 +1349,19 @@ The SQream console does not validate the integrity of your external configuratio When using your custom configuration file, you can use the ``-j`` flag to define the full path to the Configuration file, as in the example below: -.. code-block:: console +.. code-block:: $ sqream-console>sqream worker --start 1 -j /etc/sqream/configfile.json .. note:: To start more than one sqream daemon, you must provide files for each daemon, as in the example below: -.. code-block:: console +.. code-block:: $ sqream worker --start 2 -j /etc/sqream/configfile.json /etc/sqream/configfile2.json .. note:: To split a specific GPU, you must also list the GPU flag, as in the example below: -.. code-block:: console +.. code-block:: $ sqream worker --start 2 -g 0 -j /etc/sqream/configfile.json /etc/sqream/configfile2.json @@ -1372,7 +1372,7 @@ Clustering Your Docker Environment SQream lets you connect to a remote Master node to start Docker in Distributed mode. If you have already connected to a Slave node server in Distributed mode, the **sqream Master** and **Client** commands are only available on the Master node. -.. code-block:: console +.. code-block:: $ --master-host $ sqream-console>sqream worker --start 1 --master-host 192.168.0.1020 @@ -1391,13 +1391,13 @@ Checking the Status of SQream Services from the SQream Console From the SQream console, you can check the status of SQream services by running the following command: -.. code-block:: console +.. code-block:: $ sqream-console>sqream master --list The following is an example of the expected output: -.. code-block:: console +.. code-block:: $ sqream-console>sqream master --list $ checking 3 sqream services: @@ -1412,7 +1412,7 @@ Checking the Status of SQream Services from Outside the SQream Console From outside the Sqream Console, you can check the status of SQream services by running the following commands: -.. code-block:: console +.. code-block:: $ sqream-status $ NAMES STATUS PORTS @@ -1438,19 +1438,19 @@ This section describes how to upgrade your SQream system. 3. Extract the following tarball file received from the SQream Support team, under it with the same user and in the same folder that you used while :ref:`Downloading the SQream Software <_download_sqream_software>`. - .. code-block:: console + .. code-block:: $ tar -xvf sqream_installer-2.0.5-DB2019.2.1-CO1.6.3-ED3.0.0-x86_64/ 4. Navigate to the new folder created as a result of extracting the tarball file: - .. code-block:: console + .. code-block:: $ cd sqream_installer-2.0.5-DB2019.2.1-CO1.6.3-ED3.0.0-x86_64/ 5. Initiate the upgrade process: - .. code-block:: console + .. code-block:: $ ./sqream-install -i From 3f69443d275bc9ddc50e3c654a3ad4f960e4a52d Mon Sep 17 00:00:00 2001 From: YanivGerowitz <82020437+YanivGerowitz@users.noreply.github.com> Date: Mon, 28 Mar 2022 15:15:39 +0300 Subject: [PATCH 029/316] Update running_sqream_in_a_docker_container.rst From 3719aa8ac4c102f462f2aa142b2d0215d455989f Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 29 Mar 2022 11:42:53 +0300 Subject: [PATCH 030/316] Modified Getting Started and Installation Guides menus Modified Getting Started and Installation Guides menus --- getting_started/creating_a_database.rst | 34 + ...eparing_your_machine_to_install_sqream.rst | 2 +- .../installing_and_launching_sqream.rst | 9 +- installation_guides/installing_monit.rst | 319 ---- .../installing_sqream_with_binary.rst | 279 ---- .../running_sqream_in_a_docker_container.rst | 1480 ----------------- 6 files changed, 36 insertions(+), 2087 deletions(-) create mode 100644 getting_started/creating_a_database.rst delete mode 100644 installation_guides/installing_monit.rst delete mode 100644 installation_guides/installing_sqream_with_binary.rst delete mode 100644 installation_guides/running_sqream_in_a_docker_container.rst diff --git a/getting_started/creating_a_database.rst b/getting_started/creating_a_database.rst new file mode 100644 index 000000000..6b208f123 --- /dev/null +++ b/getting_started/creating_a_database.rst @@ -0,0 +1,34 @@ +.. _creating_a_database: + +**************************** +Creating a Database +**************************** +Once you've installed SQream you can create a database. + +**To create a database:** + +1. Write a :ref:`create_database` statement. + + The following is an example of creating a new database: + + .. code-block:: psql + + master=> CREATE DATABASE test; + executed + +2. Reconnect to the newly created database. + + 1. Exit the client by typing ``\q`` and pressing **Enter**. + 2. From the Linux shell, restart the client with the new database name: + + .. code-block:: psql + + $ sqream sql --port=5000 --username=rhendricks -d test + Password: + + Interactive client mode + To quit, use ^D or \q. + + test=> _ + + The name of the new database that you are connected to is displayed in the prompt. \ No newline at end of file diff --git a/getting_started/preparing_your_machine_to_install_sqream.rst b/getting_started/preparing_your_machine_to_install_sqream.rst index 435f35de0..d57861b1a 100644 --- a/getting_started/preparing_your_machine_to_install_sqream.rst +++ b/getting_started/preparing_your_machine_to_install_sqream.rst @@ -32,4 +32,4 @@ To prepare your machine to install SQream, do the following: For more information, see the following: * :ref:`recommended_pre-installation_configurations` -* `Hardware Guide `_ +* :ref:`hardware_guide` \ No newline at end of file diff --git a/installation_guides/installing_and_launching_sqream.rst b/installation_guides/installing_and_launching_sqream.rst index 4ef1ef706..03d5d024f 100644 --- a/installation_guides/installing_and_launching_sqream.rst +++ b/installation_guides/installing_and_launching_sqream.rst @@ -10,11 +10,4 @@ The **Installing SQream Studio** page incudes the following installation guides: :glob: recommended_pre-installation_configurations - installing_sqream_with_binary - running_sqream_in_a_docker_container - installing_sqream_with_kubernetes - installing_monit - launching_sqream_with_monit - - - + installing_sqream_with_kubernetes \ No newline at end of file diff --git a/installation_guides/installing_monit.rst b/installation_guides/installing_monit.rst deleted file mode 100644 index b27800cce..000000000 --- a/installation_guides/installing_monit.rst +++ /dev/null @@ -1,319 +0,0 @@ -.. _installing_monit: - -********************************************* -Installing Monit -********************************************* - -Getting Started -============================== - -Before installing SQream with Monit, verify that you have followed the required :ref:`recommended pre-installation configurations `. - -The procedures in the **Installing Monit** guide must be performed on each SQream cluster node. - - - - - -.. _back_to_top: - -Overview -============================== - - -Monit is a free open source supervision utility for managing and monitoring Unix and Linux. Monit lets you view system status directly from the command line or from a native HTTP web server. Monit can be used to conduct automatic maintenance and repair, such as executing meaningful causal actions in error situations. - -SQream uses Monit as a watchdog utility, but you can use any other utility that provides the same or similar functionality. - -The **Installing Monit** procedures describes how to install, configure, and start Monit. - -You can install Monit in one of the following ways: - -* :ref:`Installing Monit on CentOS ` -* :ref:`Installing Monit on CentOS offline ` -* :ref:`Installing Monit on Ubuntu ` -* :ref:`Installing Monit on Ubuntu offline ` - - - - - - - -.. _installing-monit-on-centos: - -Installing Monit on CentOS: ------------------------------------- - - - -**To install Monit on CentOS:** - -1. Install Monit as a superuser on CentOS: - - .. code-block:: console - - $ sudo yum install monit - - -.. _installing-monit-on-centos-offline: - - - -Installing Monit on CentOS Offline: ------------------------------------- - - -Installing Monit on CentOS offline can be done in either of the following ways: - -* :ref:`Building Monit from Source Code ` -* :ref:`Building Monit from Pre-Built Binaries ` - - - - -.. _building_monit_from_source_code: - -Building Monit from Source Code -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - - -**To build Monit from source code:** - -1. Copy the Monit package for the current version: - - .. code-block:: console - - $ tar zxvf monit-.tar.gz - - The value ``x.y.z`` denotes the version numbers. - -2. Navigate to the directory where you want to store the package: - - .. code-block:: console - - $ cd monit-x.y.z - -3. Configure the files in the package: - - .. code-block:: console - - $ ./configure (use ./configure --help to view available options) - -4. Build and install the package: - - .. code-block:: console - - $ make && make install - -The following are the default storage directories: - -* The Monit package: **/usr/local/bin/** -* The **monit.1 man-file**: **/usr/local/man/man1/** - -5. **Optional** - To change the above default location(s), use the **--prefix** option to ./configure. - -.. - _**Comment - I took this line directly from the external online documentation. Is the "prefix option" referrin gto the "--help" in Step 3? URL: https://mmonit.com/wiki/Monit/Installation** - -6. **Optional** - Create an RPM package for CentOS directly from the source code: - - .. code-block:: console - - $ rpmbuild -tb monit-x.y.z.tar.gz - -.. - _**Comment - Is this an optional or mandatory step?** - - - - -.. _building_monit_from_pre_built_binaries: - -Building Monit from Pre-Built Binaries -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -**To build Monit from pre-built binaries:** - -1. Copy the Monit package for the current version: - - .. code-block:: console - - $ tar zxvf monit-x.y.z-linux-x64.tar.gz - - The value ``x.y.z`` denotes the version numbers. - -2. Navigate to the directory where you want to store the package: - - .. code-block:: console$ cd monit-x.y.z - -3. Copy the **bin/monit** and **/usr/local/bin/** directories: - - .. code-block:: console - - $ cp bin/monit /usr/local/bin/ - -4. Copy the **conf/monitrc** and **/etc/** directories: - - .. code-block:: console - - $ cp conf/monitrc /etc/ - -.. - _**Comment - please review this procedure.** - -For examples of pre-built Monit binarties, see :ref:`Download Precompiled Binaries`. - -:ref:`Back to top ` - - - -.. _installing-monit-on-ubuntu: - - - -Installing Monit on Ubuntu: ------------------------------------- - - -**To install Monit on Ubuntu:** - -1. Install Monit as a superuser on Ubuntu: - - .. code-block:: console - - $ sudo apt-get install monit - -:ref:`Back to top ` - - - -.. _installing-monit-on-ubuntu-offline: - - -Installing Monit on Ubuntu Offline: -------------------------------------- - - -You can install Monit on Ubuntu when you do not have an internet connection. - -**To install Monit on Ubuntu offline:** - -1. Compress the required file: - - .. code-block:: console - - $ tar zxvf monit--linux-x64.tar.gz - - **NOTICE:** ** denotes the version number. - -2. Navigate to the directory where you want to save the file: - - .. code-block:: console - - $ cd monit-x.y.z - -3. Copy the **bin/monit** directory into the **/usr/local/bin/** directory: - - .. code-block:: console - - $ cp bin/monit /usr/local/bin/ - -4. Copy the **conf/monitrc** directory into the **/etc/** directory: - - .. code-block:: console - - $ cp conf/monitrc /etc/ - -:ref:`Back to top ` - - -Configuring Monit -==================================== - -When the installation is complete, you can configure Monit. You configure Monit by modifying the Monit configuration file, called **monitrc**. This file contains blocks for each service that you want to monitor. - -The following is an example of a service block: - - .. code-block:: console - - $ #SQREAM1-START - $ check process sqream1 with pidfile /var/run/sqream1.pid - $ start program = "/usr/bin/systemctl start sqream1" - $ stop program = "/usr/bin/systemctl stop sqream1" - $ #SQREAM1-END - -For example, if you have 16 services, you can configure this block by copying the entire block 15 times and modifying all service names as required, as shown below: - - .. code-block:: console - - $ #SQREAM2-START - $ check process sqream2 with pidfile /var/run/sqream2.pid - $ start program = "/usr/bin/systemctl start sqream2" - $ stop program = "/usr/bin/systemctl stop sqream2" - $ #SQREAM2-END - -For servers that don't run the **metadataserver** and **serverpicker** commands, you can use the block example above, but comment out the related commands, as shown below: - - .. code-block:: console - - $ #METADATASERVER-START - $ #check process metadataserver with pidfile /var/run/metadataserver.pid - $ #start program = "/usr/bin/systemctl start metadataserver" - $ #stop program = "/usr/bin/systemctl stop metadataserver" - $ #METADATASERVER-END - -**To configure Monit:** - -1. Copy the required block for each required service. -2. Modify all service names in the block. -3. Copy the configured **monitrc** file to the **/etc/monit.d/** directory: - - .. code-block:: console - - $ cp monitrc /etc/monit.d/ - -4. Set file permissions to **600** (full read and write access): - - .. code-block:: console - - $ sudo chmod 600 /etc/monit.d/monitrc - -5. Reload the system to activate the current configurations: - - .. code-block:: console - - $ sudo systemctl daemon-reload - -6. **Optional** - Navigate to the **/etc/sqream** directory and create a symbolic link to the **monitrc** file: - - .. code-block:: console - - $ cd /etc/sqream - $ sudo ln -s /etc/monit.d/monitrc monitrc - -Starting Monit -==================================== - -After configuring Monit, you can start it. - -**To start Monit:** - -1. Start Monit as a super user: - - .. code-block:: console - - $ sudo systemctl start monit - -2. View Monit's service status: - - .. code-block:: console - - $ sudo systemctl status monit - -3. If Monit is functioning correctly, enable the Monit service to start on boot: - - .. code-block:: console - - $ sudo systemctl enable monit diff --git a/installation_guides/installing_sqream_with_binary.rst b/installation_guides/installing_sqream_with_binary.rst deleted file mode 100644 index dd1207ab7..000000000 --- a/installation_guides/installing_sqream_with_binary.rst +++ /dev/null @@ -1,279 +0,0 @@ -.. _installing_sqream_with_binary: - -********************************************* -Installing SQream Using Binary Packages -********************************************* -This procedure describes how to install SQream using Binary packages and must be done on all servers. - -**To install SQream using Binary packages:** - -1. Copy the SQream package to the **/home/sqream** directory for the current version: - - .. code-block:: console - - $ tar -xf sqream-db-v<2020.2>.tar.gz - -2. Append the version number to the name of the SQream folder. The version number in the following example is **v2020.2**: - - .. code-block:: console - - $ mv sqream sqream-db-v<2020.2> - -3. Move the new version of the SQream folder to the **/usr/local/** directory: - - .. code-block:: console - - $ sudo mv sqream-db-v<2020.2> /usr/local/ - -4. Change the ownership of the folder to **sqream folder**: - - .. code-block:: console - - $ sudo chown -R sqream:sqream /usr/local/sqream-db-v<2020.2> - -5. Navigate to the **/usr/local/** directory and create a symbolic link to SQream: - - .. code-block:: console - - $ cd /usr/local - $ sudo ln -s sqream-db-v<2020.2> sqream - -6. Verify that the symbolic link that you created points to the folder that you created: - - .. code-block:: console - - $ ls -l - -7. Verify that the symbolic link that you created points to the folder that you created: - - .. code-block:: console - - $ sqream -> sqream-db-v<2020.2> - -8. Create the SQream configuration file destination folders and set their ownership to **sqream**: - - .. code-block:: console - - $ sudo mkdir /etc/sqream - $ sudo chown -R sqream:sqream /etc/sqream - -9. Create the SQream service log destination folders and set their ownership to **sqream**: - - .. code-block:: console - - $ sudo mkdir /var/log/sqream - $ sudo chown -R sqream:sqream /var/log/sqream - -10. Navigate to the **/usr/local/** directory and copy the SQream configuration files from them: - - .. code-block:: console - - $ cd /usr/local/sqream/etc/ - $ cp * /etc/sqream - -The configuration files are **service configuration files**, and the JSON files are **SQream configuration files**, for a total of four files. The number of SQream configuration files and JSON files must be identical. - -**NOTICE** - Verify that the JSON files have been configured correctly and that all required flags have been set to the correct values. - -In each JSON file, the following parameters **must be updated**: - -* instanceId -* machineIP -* metadataServerIp -* spoolMemoryGB -* limitQueryMemoryGB -* gpu -* port -* ssl_port - -Note the following: - -* The value of the **metadataServerIp** parameter must point to the IP that the metadata is running on. -* The value of the **machineIP** parameter must point to the IP of your local machine. - -It would be same on server running metadataserver and different on other server nodes. - -11. **Optional** - To run additional SQream services, copy the required configuration files and create additional JSON files: - - .. code-block:: console - - $ cp sqream2_config.json sqream3_config.json - $ vim sqream3_config.json - -**NOTICE:** A unique **instanceID** must be used in each JSON file. IN the example above, the instanceID **sqream_2** is changed to **sqream_3**. - -12. **Optional** - If you created additional services in **Step 11**, verify that you have also created their additional configuration files: - - .. code-block:: console - - $ cp sqream2-service.conf sqream3-service.conf - $ vim sqream3-service.conf - -13. For each SQream service configuration file, do the following: - - 1. Change the **SERVICE_NAME=sqream2** value to **SERVICE_NAME=sqream3**. - - 2. Change **LOGFILE=/var/log/sqream/sqream2.log** to **LOGFILE=/var/log/sqream/sqream3.log**. - -**NOTE:** If you are running SQream on more than one server, you must configure the ``serverpicker`` and ``metadatserver`` services to start on only one of the servers. If **metadataserver** is running on the first server, the ``metadataServerIP`` value in the second server's /etc/sqream/sqream1_config.json file must point to the IP of the server on which the ``metadataserver`` service is running. - -14. Set up **servicepicker**: - - 1. Do the following: - - .. code-block:: console - - $ vim /etc/sqream/server_picker.conf - - 2. Change the IP **127.0.0.1** to the IP of the server that the **metadataserver** service is running on. - - 3. Change the **CLUSTER** to the value of the cluster path. - -15. Set up your service files: - - .. code-block:: console - - $ cd /usr/local/sqream/service/ - $ cp sqream2.service sqream3.service - $ vim sqream3.service - -16. Increment each **EnvironmentFile=/etc/sqream/sqream2-service.conf** configuration file for each SQream service file, as shown below: - - .. code-block:: console - - $ EnvironmentFile=/etc/sqream/sqream<3>-service.conf - -17. Copy and register your service files into systemd: - - .. code-block:: console - - $ sudo cp metadataserver.service /usr/lib/systemd/system/ - $ sudo cp serverpicker.service /usr/lib/systemd/system/ - $ sudo cp sqream*.service /usr/lib/systemd/system/ - -18. Verify that your service files have been copied into systemd: - - .. code-block:: console - - $ ls -l /usr/lib/systemd/system/sqream* - $ ls -l /usr/lib/systemd/system/metadataserver.service - $ ls -l /usr/lib/systemd/system/serverpicker.service - $ sudo systemctl daemon-reload - -19. Copy the license into the **/etc/license** directory: - - .. code-block:: console - - $ cp license.enc /etc/sqream/ - - -If you have an HDFS environment, see :ref:`Configuring an HDFS Environment for the User sqream `. - - - - - - -Upgrading SQream Version -------------------------- -Upgrading your SQream version requires stopping all running services while you manually upgrade SQream. - -**To upgrade your version of SQream:** - -1. Stop all actively running SQream services. - -**Notice-** All SQream services must remain stopped while the upgrade is in process. Ensuring that SQream services remain stopped depends on the tool being used. - -For an example of stopping actively running SQream services, see :ref:`Launching SQream with Monit `. - - - -2. Verify that SQream has stopped listening on ports **500X**, **510X**, and **310X**: - - .. code-block:: console - - $ sudo netstat -nltp #to make sure sqream stopped listening on 500X, 510X and 310X ports. - -3. Replace the old version ``sqream-db-v2020.2``, with the new version ``sqream-db-v2021.1``: - - .. code-block:: console - - $ cd /home/sqream - $ mkdir tempfolder - $ mv sqream-db-v2021.1.tar.gz tempfolder/ - $ tar -xf sqream-db-v2021.1.tar.gz - $ sudo mv sqream /usr/local/sqream-db-v2021.1 - $ cd /usr/local - $ sudo chown -R sqream:sqream sqream-db-v2021.1 - -4. Remove the symbolic link: - - .. code-block:: console - - $ sudo rm sqream - -5. Create a new symbolic link named "sqream" pointing to the new version: - - .. code-block:: console - - $ sudo ln -s sqream-db-v2021.1 sqream - -6. Verify that the symbolic SQream link points to the real folder: - - .. code-block:: console - - $ ls -l - - The following is an example of the correct output: - - .. code-block:: console - - $ sqream -> sqream-db-v2021.1 - -7. **Optional-** (for major versions) Upgrade your version of SQream storage cluster, as shown in the following example: - - .. code-block:: console - - $ cat /etc/sqream/sqream1_config.json |grep cluster - $ ./upgrade_storage - - The following is an example of the correct output: - - .. code-block:: console - - get_leveldb_version path{} - current storage version 23 - upgrade_v24 - upgrade_storage to 24 - upgrade_storage to 24 - Done - upgrade_v25 - upgrade_storage to 25 - upgrade_storage to 25 - Done - upgrade_v26 - upgrade_storage to 26 - upgrade_storage to 26 - Done - validate_leveldb - ... - upgrade_v37 - upgrade_storage to 37 - upgrade_storage to 37 - Done - validate_leveldb - storage has been upgraded successfully to version 37 - -8. Verify that the latest version has been installed: - - .. code-block:: console - - $ ./sqream sql --username sqream --password sqream --host localhost --databasename master -c "SELECT SHOW_VERSION();" - - The following is an example of the correct output: - - .. code-block:: console - - v2021.1 - 1 row - time: 0.050603s - -For more information, see the `upgrade_storage `_ command line program. - -For more information about installing Studio on a stand-alone server, see `Installing Studio on a Stand-Alone Server `_. \ No newline at end of file diff --git a/installation_guides/running_sqream_in_a_docker_container.rst b/installation_guides/running_sqream_in_a_docker_container.rst deleted file mode 100644 index 79caa9f8d..000000000 --- a/installation_guides/running_sqream_in_a_docker_container.rst +++ /dev/null @@ -1,1480 +0,0 @@ -.. _running_sqream_in_a_docker_container: - -*********************** -Installing and Running SQream in a Docker Container -*********************** -The **Installing and Running SQream in a Docker Container** page describes how to prepare your machine's environment for installing and running SQream in a Docker container. - -This page describes the following: - -.. contents:: - :local: - :depth: 1 - -Setting Up a Host -==================================== - -Operating System Requirements ------------------------------------- -SQream was tested and verified on the following versions of Linux: - - * x86 CentOS/RHEL 7.6 - 7.9 - * IBM RHEL 7.6 - -SQream recommends installing a clean OS on the host to avoid any installation issues. - -.. warning:: Docker-based installation supports only single host deployment and cannot be used on a multi-node cluster. Installing Docker on a single host you will not be able to scale it to a multi-node cluster. - - -Creating a Local User ----------------- -To run SQream in a Docker container you must create a local user. - -**To create a local user:** - -1. Add a local user: - - .. code-block:: console - - $ useradd -m -U - -2. Set the local user's password: - - .. code-block:: console - - $ passwd - -3. Add the local user to the ``wheel`` group: - - .. code-block:: console - - $ usermod -aG wheel - - You can remove the local user from the ``wheel`` group when you have completed the installation. - -4. Log out and log back in as the local user. - -Setting a Local Language ----------------- -After creating a local user you must set a local language. - -**To set a local language:** - -1. Set the local language: - - .. code-block:: console - - $ sudo localectl set-locale LANG=en_US.UTF-8 - -2. Set the time stamp (time and date) of the locale: - - .. code-block:: console - - $ sudo timedatectl set-timezone Asia/Jerusalem - -You can run the ``timedatectl list-timezones`` command to see your timezone. - -Adding the EPEL Repository ----------------- -After setting a local language you must add the EPEL repository. - -**To add the EPEL repository:** - -1. As a root user, upgrade the **epel-release-latest-7.noarch.rpm** repository: - - 1. RedHat (RHEL 7): - - .. code-block:: console - - $ sudo rpm -Uvh http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm - - 2. CentOS 7 - - .. code-block:: console - - $ sudo yum install epel-release - -Installing the Required NTP Packages ----------------- -After adding the EPEL repository, you must install the required NTP packages. - -You can install the required NTP packages by running the following command: - -.. code-block:: console - - $ sudo yum install ntp pciutils python36 kernel-devel-$(uname -r) kernel-headers-$(uname -r) gcc - -Installing the Recommended Tools ----------------- -After installin gthe required NTP packages you must install the recommended tools. - -SQream recommends installing the following recommended tools: - -.. code-block:: console - - $ sudo yum install bash-completion.noarch vim-enhanced.x86_64 vim-common.x86_64 net-tools iotop htop psmisc screen xfsprogs wget yum-utils deltarpm dos2unix - -Updating to the Current Version of the Operating System ----------------- -After installing the recommended tools you must update to the current version of the operating system. - -SQream recommends updating to the current version of the operating system. This is not recommended if the nvidia driver has **not been installed.** - - - -Configuring the NTP Package ----------------- -After updating to the current version of the operating system you must configure the NTP package. - -**To configure the NTP package:** - -1. Add your local servers to the NTP configuration. - - :: - -2. Configure the **ntpd** service to begin running when your machine is started: - - .. code-block:: console - - $ sudo systemctl enable ntpd - $ sudo systemctl start ntpd - $ sudo ntpq -p - -Configuring the Performance Profile ----------------- -After configuring the NTP package you must configure the performance profile. - -**To configure the performance profile:** - -1. Switch the active profile: - - .. code-block:: console - - $ sudo tuned-adm profile throughput-performance - -2. Change the multi-user's default run level: - - .. code-block:: console - - $ sudo systemctl set-default multi-user.target - -Configuring Your Security Limits ----------------- -After configuring the performance profile you must configure your security limits. Configuring your security limits refers to configuring the number of open files, processes, etc. - -**To configure your security limits:** - -1. Run the **bash** shell as a super-user: - - .. code-block:: console - - $ sudo bash - -2. Run the following command: - - .. code-block:: console - - $ echo -e "sqream soft nproc 500000\nsqream hard nproc 500000\nsqream soft nofile 500000\nsqream hard nofile 500000\nsqream soft core unlimited\nsqream hard core unlimited" >> /etc/security/limits.conf - -3. Run the following command: - - .. code-block:: console - - $ echo -e "vm.dirty_background_ratio = 5 \n vm.dirty_ratio = 10 \n vm.swappiness = 10 \n vm.zone_reclaim_mode = 0 \n vm.vfs_cache_pressure = 200 \n" >> /etc/sysctl.conf - -Disabling Automatic Bug-Reporting Tools ----------------- -After configuring your security limits you must disable the following automatic bug-reporting tools: - -* ccpp.service -* oops.service -* pstoreoops.service -* vmcore.service -* xorg.service - -You can abort the above but-reporting tools by running the following command: - -.. code-block:: console - - $ for i in abrt-ccpp.service abrtd.service abrt-oops.service abrt-pstoreoops.service abrt-vmcore.service abrt-xorg.service ; do sudo systemctl disable $i; sudo systemctl stop $i; done - -Installing the Nvidia CUDA Driver -------------------------------------- - -1. Verify that the Tesla NVIDIA card has been installed and is detected by the system: - - .. code-block:: console - - $ lspci | grep -i nvidia - - The correct output is a list of Nvidia graphic cards. If you do not receive this output, verify that an NVIDIA GPU card has been installed. - -#. Verify that the open-source upstream Nvidia driver is running: - - .. code-block:: console - - $ lsmod | grep nouveau - - No output should be generated. - -#. If you receive any output, do the following: - - 1. Disable the open-source upstream Nvidia driver: - - .. code-block:: console - - $ sudo bash - $ echo "blacklist nouveau" > /etc/modprobe.d/blacklist-nouveau.conf - $ echo "options nouveau modeset=0" >> /etc/modprobe.d/blacklist-nouveau.conf - $ dracut --force - $ modprobe --showconfig | grep nouveau - - 2. Reboot the server and verify that the Nouveau model has not been loaded: - - .. code-block:: console - - $ lsmod | grep nouveau - -#. Check if the Nvidia CUDA driver has already been installed: - - .. code-block:: console - - $ nvidia-smi - - The following is an example of the correct output: - - .. code-block:: console - - nvidia-smi - Wed Oct 30 14:05:42 2019 - +-----------------------------------------------------------------------------+ - | NVIDIA-SMI 418.87.00 Driver Version: 418.87.00 CUDA Version: 10.1 | - |-------------------------------+----------------------+----------------------+ - | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | - | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | - |===============================+======================+======================| - | 0 Tesla V100-SXM2... On | 00000004:04:00.0 Off | 0 | - | N/A 32C P0 37W / 300W | 0MiB / 16130MiB | 0% Default | - +-------------------------------+----------------------+----------------------+ - | 1 Tesla V100-SXM2... On | 00000035:03:00.0 Off | 0 | - | N/A 33C P0 37W / 300W | 0MiB / 16130MiB | 0% Default | - +-------------------------------+----------------------+----------------------+ - - +-----------------------------------------------------------------------------+ - | Processes: GPU Memory | - | GPU PID Type Process name Usage | - |=============================================================================| - | No running processes found | - +-----------------------------------------------------------------------------+ - -#. Verify that the installed CUDA version shown in the output above is ``10.1``. - - :: - - -#. Do one of the following: - - :: - - 1. If CUDA version 10.1 has already been installed, skip to Docktime Runtime (Community Edition). - :: - - 2. If CUDA version 10.1 has not been installed yet, continue with Step 7 below. - -#. Do one of the following: - - * Install :ref:`CUDA Driver version 10.1 for x86_64 `. - - :: - - * Install :ref:`CUDA driver version 10.1 for IBM Power9 `. - -.. _CUDA_10.1_x8664: - -Installing the CUDA Driver Version 10.1 for x86_64 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -**To install the CUDA driver version 10.1 for x86_64:** - -1. Make the following target platform selections: - - :: - - * **Operating system**: Linux - * **Architecture**: x86_64 - * **Distribution**: CentOS - * **Version**: 7 - * **Installer type**: the relevant installer type - -For installer type, SQream recommends selecting **runfile (local)**. The available selections shows only the supported platforms. - -2. Download the base installer for Linux CentOS 7 x86_64: - - .. code-block:: console - - wget http://developer.download.nvidia.com/compute/cuda/10.1/Prod/local_installers/cuda-repo-rhel7-10-1-local-10.1.243-418.87.00-1.0-1.x86_64.rpm - - -3. Install the base installer for Linux CentOS 7 x86_64 by running the following commands: - - .. code-block:: console - - $ sudo yum localinstall cuda-repo-rhel7-10-1-local-10.1.243-418.87.00-1.0-1.x86_64.rpm - $ sudo yum clean all - $ sudo yum install nvidia-driver-latest-dkms - -.. warning:: Verify that the output indicates that driver **418.87** will be installed. - -4. Follow the command line prompts. - - - :: - - -5. Enable the Nvidia service to start at boot and start it: - - .. code-block:: console - - $ sudo systemctl enable nvidia-persistenced.service && sudo systemctl start nvidia-persistenced.service - -6. Create a symbolic link from the **/etc/systemd/system/multi-user.target.wants/nvidia-persistenced.service** file to the **/usr/lib/systemd/system/nvidia-persistenced.service** file. - - :: - -7. Reboot the server. - - :: -8. Verify that the Nvidia driver has been installed and shows all available GPU's: - - .. code-block:: console - - $ nvidia-smi - - The following is the correct output: - - .. code-block:: console - - nvidia-smi - Wed Oct 30 14:05:42 2019 - +-----------------------------------------------------------------------------+ - | NVIDIA-SMI 418.87.00 Driver Version: 418.87.00 CUDA Version: 10.1 | - |-------------------------------+----------------------+----------------------+ - | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | - | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | - |===============================+======================+======================| - | 0 Tesla V100-SXM2... On | 00000004:04:00.0 Off | 0 | - | N/A 32C P0 37W / 300W | 0MiB / 16130MiB | 0% Default | - +-------------------------------+----------------------+----------------------+ - | 1 Tesla V100-SXM2... On | 00000035:03:00.0 Off | 0 | - | N/A 33C P0 37W / 300W | 0MiB / 16130MiB | 0% Default | - +-------------------------------+----------------------+----------------------+ - - +-----------------------------------------------------------------------------+ - | Processes: GPU Memory | - | GPU PID Type Process name Usage | - |=============================================================================| - | No running processes found | - +-----------------------------------------------------------------------------+ - -.. _CUDA_10.1_IBMPower9: - -Installing the CUDA Driver Version 10.1 for IBM Power9 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -**To install the CUDA driver version 10.1 for IBM Power9:** - -1. Download the base installer for Linux CentOS 7 PPC64le: - - .. code-block:: console - - wget http://developer.download.nvidia.com/compute/cuda/10.1/Prod/local_installers/cuda-repo-rhel7-10-1-local-10.1.243-418.87.00-1.0-1.ppc64le.rpm - - -#. Install the base installer for Linux CentOS 7 x86_64 by running the following commands: - - .. code-block:: console - - $ sudo rpm -i cuda-repo-rhel7-10-1-local-10.1.243-418.87.00-1.0-1.ppc64le.rpm - $ sudo yum clean all - $ sudo yum install nvidia-driver-latest-dkms - -.. warning:: Verify that the output indicates that driver **418.87** will be installed. - - - -3. Copy the file to the **/etc/udev/rules.d** directory. - - :: - -4. If you are using RHEL 7 version (7.6 or later), comment out, remove, or change the hot-pluggable memory rule located in file copied to the **/etc/udev/rules.d** directory by running the following command: - - .. code-block:: console - - $ sudo cp /lib/udev/rules.d/40-redhat.rules /etc/udev/rules.d - $ sudo sed -i 's/SUBSYSTEM!="memory",.*GOTO="memory_hotplug_end"/SUBSYSTEM=="*", GOTO="memory_hotplug_end"/' /etc/udev/rules.d/40-redhat.rules - -#. Enable the **nvidia-persisted.service** file: - - .. code-block:: console - - $ sudo systemctl enable nvidia-persistenced.service - -#. Create a symbolic link from the **/etc/systemd/system/multi-user.target.wants/nvidia-persistenced.service** file to the **/usr/lib/systemd/system/nvidia-persistenced.service** file. - - :: - -#. Reboot your system to initialize the above modifications. - - :: - -#. Verify that the Nvidia driver and the **nvidia-persistenced.service** files are running: - - .. code-block:: console - - $ nvidia smi - - The following is the correct output: - - .. code-block:: console - - nvidia-smi - Wed Oct 30 14:05:42 2019 - +-----------------------------------------------------------------------------+ - | NVIDIA-SMI 418.87.00 Driver Version: 418.87.00 CUDA Version: 10.1 | - |-------------------------------+----------------------+----------------------+ - | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | - | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | - |===============================+======================+======================| - | 0 Tesla V100-SXM2... On | 00000004:04:00.0 Off | 0 | - | N/A 32C P0 37W / 300W | 0MiB / 16130MiB | 0% Default | - +-------------------------------+----------------------+----------------------+ - | 1 Tesla V100-SXM2... On | 00000035:03:00.0 Off | 0 | - | N/A 33C P0 37W / 300W | 0MiB / 16130MiB | 0% Default | - +-------------------------------+----------------------+----------------------+ - - +-----------------------------------------------------------------------------+ - | Processes: GPU Memory | - | GPU PID Type Process name Usage | - |=============================================================================| - | No running processes found | - +-----------------------------------------------------------------------------+ - -#. Verify that the **nvidia-persistenced** service is running: - - .. code-block:: console - - $ systemctl status nvidia-persistenced - - The following is the correct output: - - .. code-block:: console - - root@gpudb ~]systemctl status nvidia-persistenced - nvidia-persistenced.service - NVIDIA Persistence Daemon - Loaded: loaded (/usr/lib/systemd/system/nvidia-persistenced.service; enabled; vendor preset: disabled) - Active: active (running) since Tue 2019-10-15 21:43:19 KST; 11min ago - Process: 8257 ExecStart=/usr/bin/nvidia-persistenced --verbose (code=exited, status=0/SUCCESS) - Main PID: 8265 (nvidia-persiste) - Tasks: 1 - Memory: 21.0M - CGroup: /system.slice/nvidia-persistenced.service - └─8265 /usr/bin/nvidia-persistenced --verbose - -Installing the Docker Engine (Community Edition) -======================= -After installing the Nvidia CUDA driver you must install the Docker engine. - -This section describes how to install the Docker engine using the following processors: - -* :ref:`Using x86_64 processor on CentOS ` -* :ref:`Using x86_64 processor on Ubuntu ` -* :ref:`Using IBM Power9 (PPC64le) processor ` - - -.. _dockerx8664centos: - -Installing the Docker Engine Using an x86_64 Processor on CentOS ---------------------------------- -The x86_64 processor supports installing the **Docker Community Edition (CE)** versions 18.03 and higher. - -For more information on installing the Docker Engine CE on an x86_64 processor, see `Install Docker Engine on CentOS `_ - - - -.. _dockerx8664ubuntu: - -Installing the Docker Engine Using an x86_64 Processor on Ubuntu ------------------------------------------------------ - - -The x86_64 processor supports installing the **Docker Community Edition (CE)** versions 18.03 and higher. - -For more information on installing the Docker Engine CE on an x86_64 processor, see `Install Docker Engine on Ubuntu `_ - -.. _docker_ibmpower9: - -Installing the Docker Engine on an IBM Power9 Processor ----------------------------------------- -The x86_64 processor only supports installing the **Docker Community Edition (CE)** version 18.03. - -**To install the Docker Engine on an IBM Power9 processor:** - -You can install the Docker Engine on an IBM Power9 processor by running the following command: - -.. code-block:: console - - wget http://ftp.unicamp.br/pub/ppc64el/rhel/7_1/docker-ppc64el/container-selinux-2.9-4.el7.noarch.rpm - wget http://ftp.unicamp.br/pub/ppc64el/rhel/7_1/docker-ppc64el/docker-ce-18.03.1.ce-1.el7.centos.ppc64le.rpm - yum install -y container-selinux-2.9-4.el7.noarch.rpm docker-ce-18.03.1.ce-1.el7.centos.ppc64le.rpm - -For more information on installing the Docker Engine CE on an IBM Power9 processor, see `Install Docker Engine on Ubuntu `_. - -Docker Post-Installation -================================= -After installing the Docker engine you must configure Docker on your local machine. - -**To configure Docker on your local machine:** - -1. Enable Docker to start on boot: - - .. code-block:: console - - $ sudo systemctl enable docker && sudo systemctl start docker - -2. Enable managing Docker as a non-root user: - - .. code-block:: console - - $ sudo usermod -aG docker $USER - -3. Log out and log back in via SSH. This causes Docker to re-evaluate your group membership. - - :: - -4. Verify that you can run the following Docker command as a non-root user (without ``sudo``): - - .. code-block:: console - - $ docker run hello-world - -If you can run the above Docker command as a non-root user, the following occur: - -* Docker downloads a test image and runs it in a container. -* When the container runs, it prints an informational message and exits. - -For more information on installing the Docker Post-Installation, see `Docker Post-Installation `_. - -Installing the Nvidia Docker2 ToolKit -========================================== -After configuring Docker on your local machine you must install the Nvidia Docker2 ToolKit. The NVIDIA Docker2 Toolkit lets you build and run GPU-accelerated Docker containers. The Toolkit includes a container runtime library and related utilities for automatically configuring containers to leverage NVIDIA GPU's. - -This section describes the following: - -* :ref:`Installing the NVIDIA Docker2 Toolkit on an x86_64 processor ` -* :ref:`Installing the NVIDIA Docker2 Toolkit on a PPC64le processor ` - -.. _install_nvidia_docker2_toolkit_x8664_processor: - -Installing the NVIDIA Docker2 Toolkit on an x86_64 Processor ----------------------------------------- - -This section describes the following: - -* :ref:`Installing the NVIDIA Docker2 Toolkit on a CentOS operating system ` - -* :ref:`Installing the NVIDIA Docker2 Toolkit on an Ubuntu operating system ` - -.. _install_nvidia_docker2_toolkit_centos: - -Installing the NVIDIA Docker2 Toolkit on a CentOS Operating System -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -**To install the NVIDIA Docker2 Toolkit on a CentOS operating system:** - -1. Install the repository for your distribution: - - .. code-block:: console - - distribution=$(. /etc/os-release;echo $ID$VERSION_ID) - curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.repo | \ - sudo tee /etc/yum.repos.d/nvidia-docker.repo - -2. Install the ``nvidia-docker2`` package and reload the Docker daemon configuration: - - .. code-block:: console - - $ sudo yum install nvidia-docker2 - $ sudo pkill -SIGHUP dockerd - -3. Do one of the following: - - * If you received an error when installing the ``nvidia-docker2`` package, skip to :ref:`Step 4 `. - * If you successfully installed the ``nvidia-docker2`` package, skip to :ref:`Step 5 `. - -.. _step_4_centos: - -4. Do the following: - - 1. Run the ``sudo vi /etc/yum.repos.d/nvidia-docker.repo`` command if the following error is displayed when installing the ``nvidia-docker2`` package: - - - .. code-block:: console - - https://nvidia.github.io/nvidia-docker/centos7/ppc64le/repodata/repomd.xml: - [Errno -1] repomd.xml signature could not be verified for nvidia-docker - - 2. Change ``repo_gpgcheck=1`` to ``repo_gpgcheck=0``. - -.. _step_5_centos: - -5. Verify that the NVIDIA-Docker run has been installed correctly: - - .. code-block:: console - - $ docker run --runtime=nvidia --rm nvidia/cuda:10.1-base nvidia-smi - -For more information on installing the NVIDIA Docker2 Toolkit on a CentOS operating system, see :ref:`Installing the NVIDIA Docker2 Toolkit on a CentOS operating system ` - - -.. _install_nvidia_docker2_toolkit_ubuntu: - -Installing the NVIDIA Docker2 Toolkit on an Ubuntu Operating System -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -**To install the NVIDIA Docker2 Toolkit on an Ubuntu operating system:** - -1. Install the repository for your distribution: - - .. code-block:: console - - curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - - distribution=$(. /etc/os-release;echo $ID$VERSION_ID) - curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list - sudo apt-get update - -2. Install the ``nvidia-docker2`` package and reload the Docker daemon configuration: - - .. code-block:: console - - $ sudo apt-get install nvidia-docker2 - $ sudo pkill -SIGHUP dockerd - -3. Do one of the following: - - * If you received an error when installing the ``nvidia-docker2`` package, skip to :ref:`Step 4 `. - * If you successfully installed the ``nvidia-docker2`` package, skip to :ref:`Step 5 `. - - .. _step_4_ubuntu: - -4. Do the following: - - 1. Run the ``sudo vi /etc/yum.repos.d/nvidia-docker.repo`` command if the following error is displayed when installing the ``nvidia-docker2`` package: - - .. code-block:: console - - https://nvidia.github.io/nvidia-docker/centos7/ppc64le/repodata/repomd.xml: - [Errno -1] repomd.xml signature could not be verified for nvidia-docker - - 2. Change ``repo_gpgcheck=1`` to ``repo_gpgcheck=0``. - -.. _step_5_ubuntu: - -5. Verify that the NVIDIA-Docker run has been installed correctly: - - .. code-block:: console - - $ docker run --runtime=nvidia --rm nvidia/cuda:10.1-base nvidia-smi - -For more information on installing the NVIDIA Docker2 Toolkit on a CentOS operating system, see :ref:`Installing the NVIDIA Docker2 Toolkit on an Ubuntu operating system ` - -.. _install_nvidia_docker2_toolkit_ppc64le_processor: - -Installing the NVIDIA Docker2 Toolkit on a PPC64le Processor --------------------------------------- - -This section describes how to install the NVIDIA Docker2 Toolkit on an IBM RHEL operating system: - -**To install the NVIDIA Docker2 Toolkit on an IBM RHEL operating system:** - -1. Import the repository and install the ``libnvidia-container`` and the ``nvidia-container-runtime`` containers. - - .. code-block:: console - - $ distribution=$(. /etc/os-release;echo $ID$VERSION_ID) - $ curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.repo | \ - sudo tee /etc/yum.repos.d/nvidia-docker.repo - $ sudo yum install -y libnvidia-container* - -2. Do one of the following: - - * If you received an error when installing the containers, skip to :ref:`Step 3 `. - * If you successfully installed the containers, skip to :ref:`Step 4 `. - -.. _step_3_installing_nvidia_docker2_toolkit_ppc64le_processor: - -3. Do the following: - - 1. Run the ``sudo vi /etc/yum.repos.d/nvidia-docker.repo`` command if the following error is displayed when installing the containers: - - .. code-block:: console - - https://nvidia.github.io/nvidia-docker/centos7/ppc64le/repodata/repomd.xml: - [Errno -1] repomd.xml signature could not be verified for nvidia-docker - - 2. Change ``repo_gpgcheck=1`` to ``repo_gpgcheck=0``. - - :: - - 3. Install the ``libnvidia-container`` container. - - .. code-block:: console - - $ sudo yum install -y libnvidia-container* - - .. _step_4_installing_nvidia_docker2_toolkit_ppc64le_processor: - -4. Install the ``nvidia-container-runtime`` container: - - .. code-block:: console - - $ sudo yum install -y nvidia-container-runtime* - -5. Add ``nvidia runtime`` to the Docker daemon: - - .. code-block:: console - - $ sudo mkdir -p /etc/systemd/system/docker.service.d/ - $ sudo vi /etc/systemd/system/docker.service.d/override.conf - - $ [Service] - $ ExecStart= - $ ExecStart=/usr/bin/dockerd - -6. Restart Docker: - - .. code-block:: console - - $ sudo systemctl daemon-reload - $ sudo systemctl restart docker - -7. Verify that the NVIDIA-Docker run has been installed correctly: - - .. code-block:: console - - $ docker run --runtime=nvidia --rm nvidia/cuda-ppc64le nvidia-smi - -.. _accessing_hadoop_kubernetes_configuration_files: - -Accessing the Hadoop and Kubernetes Configuration Files --------------------------------------- -The information this section is optional and is only relevant for Hadoop users. If you require Hadoop and Kubernetes (Krb5) connectivity, contact your IT department for access to the following configuration files: - -* Hadoop configuration files: - - * core-site.xml - * hdfs-site.xml - - :: - -* Kubernetes files: - - * Configuration file - krb.conf - * Kubernetes Hadoop client certificate - hdfs.keytab - -Once you have the above files, you must copy them into the correct folders in your working directory. - -For more information about the correct directory to copy the above files into, see the :ref:`Installing the SQream Software ` section below. - -For related information, see the following sections: - -* :ref:`Configuring the Hadoop and Kubernetes Configuration Files ` -* :ref:`Setting the Hadoop and Kubernetes Configuration Parameters ` - -.. _installing_sqream_software: - -Installing the SQream Software -============================== - -Preparing Your Local Environment -------------------------- -After installing the Nvidia Docker2 toolKit you must prepare your local environment. - -.. note:: You must install the SQream software under a *sqream* and not a *root* user. - -The Linux user preparing the local environment must have **read/write** access to the following directories for the SQream software to correctly read and write the required resources: - -* **Log directory** - default: /var/log/sqream/ -* **Configuration directory** - default: /etc/sqream/ -* **Cluster directory** - the location where SQream writes its DB system, such as */mnt/sqreamdb* -* **Ingest directory** - the location where the required data is loaded, such as */mnt/data_source/* - -.. _download_sqream_software: - -Deploying the SQream Software -------------------------- -After preparing your local environment you must deploy the SQream software. Deploying the SQream software requires you to access and extract the required files and to place them in the correct directory. - -**To deploy the SQream software:** - -1. Contact the SQream Support team for access to the **sqream_installer-nnn-DBnnn-COnnn-EDnnn-.tar.gz** file. - -The **sqream_installer-nnn-DBnnn-COnnn-EDnnn-.tar.gz** file includes the following parameter values: - -* **sqream_installer-nnn** - sqream installer version -* **DBnnn** - SQreamDB version -* **COnnn** - SQream console version -* **EDnnn** - SQream editor version -* **arch** - server arch (applicable to X86.64 and ppc64le) - -2. Extract the tarball file: - - .. code-block:: console - - $ tar -xvf sqream_installer-1.1.5-DB2019.2.1-CO1.5.4-ED3.0.0-x86_64.tar.gz - -When the tarball file has been extracted, a new folder will be created. The new folder is automatically given the name of the tarball file: - - .. code-block:: console - - drwxrwxr-x 9 sqream sqream 4096 Aug 11 11:51 sqream_istaller-1.1.5-DB2019.2.1-CO1.5.4-ED3.0.0-x86_64/ - -rw-rw-r-- 1 sqream sqream 3130398797 Aug 11 11:20 sqream_installer-1.1.5-DB2019.2.1-CO1.5.4-ED3.0.0-x86_64.tar.gz - -3. Change the directory to the new folder that you created in the previous step. - -:: - -4. Verify that the folder you just created contains all of the required files. - - .. code-block:: console - - $ ls -la - - The following is an example of the files included in the new folder: - - .. code-block:: console - - drwxrwxr-x. 10 sqream sqream 198 Jun 3 17:57 . - drwx------. 25 sqream sqream 4096 Jun 7 18:11 .. - drwxrwxr-x. 2 sqream sqream 226 Jun 7 18:09 .docker - drwxrwxr-x. 2 sqream sqream 64 Jun 3 12:55 .hadoop - drwxrwxr-x. 2 sqream sqream 4096 May 31 14:18 .install - drwxrwxr-x. 2 sqream sqream 39 Jun 3 12:53 .krb5 - drwxrwxr-x. 2 sqream sqream 22 May 31 14:18 license - drwxrwxr-x. 2 sqream sqream 82 May 31 14:18 .sqream - -rwxrwxr-x. 1 sqream sqream 1712 May 31 14:18 sqream-console - -rwxrwxr-x. 1 sqream sqream 4608 May 31 14:18 sqream-install - -For information relevant to Hadoop users, see the following sections: - -* :ref:`Accessing the Hadoop and Kubernetes Configuration Files `. -* :ref:`Configuring the Hadoop and Kubernetes Configuration Files `. -* :ref:`Setting the Hadoop and Kubernetes Configuration Parameters `. - -.. _configure_hadoop_kubernetes_configuration_files: - -Configuring the Hadoop and Kubernetes Configuration Files ------------------------------ -The information in this section is optional and is only relevant for Hadoop users. If you require Hadoop and Kubernetes (Krb5) connectivity, you must copy the Hadoop and Kubernetes files into the correct folders in your working directory as shown below: - -* .hadoop/core-site.xml -* .hadoop/hdfs-site.xml -* .krb5/krb5.conf -* .krb5/hdfs.keytab - -For related information, see the following sections: - -* :ref:`Accessing the Hadoop and Kubernetes Configuration Files `. -* :ref:`Setting the Hadoop and Kubernetes Configuration Parameters `. - -Configuring the SQream Software -------------------------------- -After deploying the SQream software, and optionally configuring the Hadoop and Kubernetes configuration files, you must configure the SQream software. - -Configuring the SQream software requires you to do the following: - -* Configure your local environment -* Understand the ``sqream-install`` flags -* Install your SQream license -* Validate your SQream icense -* Change your data ingest folder - -Configuring Your Local Environment -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Once you've downloaded the SQream software, you can begin configuring your local environment. The following commands must be run (as **sudo**) from the same directory that you located your packages. - -For example, you may have saved your packages in **/home/sqream/sqream-console-package/**. - -The following table shows the flags that you can use to configure your local directory: - -.. list-table:: - :widths: 10 50 40 - :header-rows: 1 - - * - Flag - - Function - - Note - * - **-i** - - Loads all software from the hidden folder **.docker**. - - Mandatory - * - **-k** - - Loads all license packages from the **/license** directory. - - Mandatory - * - **-f** - - Overwrites existing folders. **Note** Using ``-f`` overwrites **all files** located in mounted directories. - - Mandatory - * - **-c** - - Defines the origin path for writing/reading SQream configuration files. The default location is ``/etc/sqream/``. - - If you are installing the Docker version on a server that already works with SQream, do not use the default path. - * - **-v** - - The SQream cluster location. If a cluster does not exist yet, ``-v`` creates one. If a cluster already exists, ``-v`` mounts it. - - Mandatory - * - **-l** - - SQream system startup logs location, including startup logs and docker logs. The default location is ``/var/log/sqream/``. - - - * - **-d** - - The directory containing customer data to be imported and/or copied to SQream. - - - * - **-s** - - Shows system settings. - - - * - **-r** - - Resets the system configuration. This value is run without any other variables. - - Mandatory - * - **-h** - - Help. Shows the available flags. - - Mandatory - * - **-K** - - Runs license validation - - - * - **-e** - - Used for inserting your RKrb5 server DNS name. For more information on setting your Kerberos configuration parameters, see :ref:`Setting the Hadoop and Kubernetes Configuration Parameters `. - - - * - **-p** - - Used for inserting your Kerberos user name. For more information on setting your Kerberos configuration parameters, see :ref:`Setting the Hadoop and Kubernetes Configuration Parameters `. - - - - -Installing Your License -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Once you've configured your local environment, you must install your license by copying it into the SQream installation package folder located in the **./license** folder: - -.. code-block:: console - - $ sudo ./sqream-install -k - -You do not need to extract this folder after uploading into the **./license**. - - -Validating Your License -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You can copy your license package into the SQream console folder located in the **/license** folder by running the following command: - -.. code-block:: console - - $ sudo ./sqream-install -K - -The following mandatory flags must be used in the first run: - -.. code-block:: console - - $ sudo ./sqream-install -i -k -v - -The following is an example of the correct command syntax: - -.. code-block:: console - - $ sudo ./sqream-install -i -k -c /etc/sqream -v /home/sqream/sqreamdb -l /var/log/sqream -d /home/sqream/data_ingest - -.. _setting_hadoop_kubernetes_connectivity_parameters: - -Setting the Hadoop and Kubernetes Connectivity Parameters -------------------------------- -The information in this section is optional, and is only relevant for Hadoop users. If you require Hadoop and Kubernetes (Krb5) connectivity, you must set their connectivity parameters. - -The following is the correct syntax when setting the Hadoop and Kubernetes connectivity parameters: - -.. code-block:: console - - $ sudo ./sqream-install -p -e : - -The following is an example of setting the Hadoop and Kubernetes connectivity parameters: - -.. code-block:: console - - $ sudo ./sqream-install -p -e kdc.sq.com:<192.168.1.111> - -For related information, see the following sections: - -* :ref:`Accessing the Hadoop and Kubernetes Configuration Files `. -* :ref:`Configuring the Hadoop and Kubernetes Configuration Files `. - -Modifying Your Data Ingest Folder -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Once you've validated your license, you can modify your data ingest folder after the first run by running the following command: - -.. code-block:: console - - $ sudo ./sqream-install -d /home/sqream/data_in - -Configuring Your Network for Docker -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Once you've modified your data ingest folder (if needed), you must validate that the server network and Docker network that you are setting up do not overlap. - -**To configure your network for Docker:** - -1. To verify that your server network and Docker network do not overlap, run the following command: - -.. code-block:: console - - $ ifconfig | grep 172. - -2. Do one of the following: - - * If running the above command output no results, continue the installation process. - * If running the above command output results, run the following command: - - .. code-block:: console - - $ ifconfig | grep 192.168. - - -Checking and Verifying Your System Settings -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Once you've configured your network for Docker, you can check and verify your system settings. - -Running the following command shows you all the variables used by your SQream system: - -.. code-block:: console - - $ ./sqream-install -s - -The following is an example of the correct output: - -.. code-block:: console - - SQREAM_CONSOLE_TAG=1.5.4 - SQREAM_TAG=2019.2.1 - SQREAM_EDITOR_TAG=3.0.0 - license_worker_0=f0:cc: - license_worker_1=26:91: - license_worker_2=20:26: - license_worker_3=00:36: - SQREAM_VOLUME=/media/sqreamdb - SQREAM_DATA_INGEST=/media/sqreamdb/data_in - SQREAM_CONFIG_DIR=/etc/sqream/ - LICENSE_VALID=true - SQREAM_LOG_DIR=/var/log/sqream/ - SQREAM_USER=sqream - SQREAM_HOME=/home/sqream - SQREAM_ENV_PATH=/home/sqream/.sqream/env_file - PROCESSOR=x86_64 - METADATA_PORT=3105 - PICKER_PORT=3108 - NUM_OF_GPUS=2 - CUDA_VERSION=10.1 - NVIDIA_SMI_PATH=/usr/bin/nvidia-smi - DOCKER_PATH=/usr/bin/docker - NVIDIA_DRIVER=418 - SQREAM_MODE=single_host - -Using the SQream Console -========================= -After configuring the SQream software and veriying your system settings you can begin using the SQream console. - -SQream Console - Basic Commands ---------------------------------- -The SQream console offers the following basic commands: - -* :ref:`Starting your SQream console ` -* :ref:`Starting Metadata and Picker ` -* :ref:`Starting the running services ` -* :ref:`Listing the running services ` -* :ref:`Stopping the running services ` -* :ref:`Using the SQream editor ` -* :ref:`Using the SQream Client ` - -.. _starting_sqream_console: - -Starting Your SQream Console -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You can start your SQream console by running the following command: - -.. code-block:: console - - $ ./sqream-console - -.. _starting_metadata_and_picker: - -Starting the SQream Master -~~~~~~~~~~~~~~~~~ - -**To listen to metadata and picker:** - -1. Start the metadata server (default port 3105) and picker (default port 3108) by running the following command: - - .. code-block:: console - - $ sqream master --start - - The following is the correct output: - - .. code-block:: console - - sqream-console> sqream master --start - starting master server in single_host mode ... - sqream_single_host_master is up and listening on ports: 3105,3108 - - -2. *Optional* - Change the metadata and server picker ports by adding ``-p `` and ``-m ``: - - .. code-block:: console - - $ sqream-console>sqream master --start -p 4105 -m 43108 - $ starting master server in single_host mode ... - $ sqream_single_host_master is up and listening on ports: 4105,4108 - - - -.. _starting_running_services: - -Starting SQream Workers -~~~~~~~~~~~~~~~~~ - - -When starting SQream workers, setting the ```` value sets how many workers to start. Leaving the ```` value unspecified runs all of the available resources. - - -.. code-block:: console - - $ sqream worker --start - - The following is an example of expected output when setting the ```` value to ``2``: - - .. code-block:: console - - sqream-console>sqream worker --start 2 - started sqream_single_host_worker_0 on port 5000, allocated gpu: 0 - started sqream_single_host_worker_1 on port 5001, allocated gpu: 1 - - -.. _listing_running_services: - -Listing the Running Services -~~~~~~~~~~~~~~~~~ - -You can list running SQream services to look for container names and ID's by running the following command: - -.. code-block:: console - - $ sqream master --list - -The following is an example of the expected output: - -.. code-block:: console - - sqream-console>sqream master --list - container name: sqream_single_host_worker_0, container id: c919e8fb78c8 - container name: sqream_single_host_master, container id: ea7eef80e038-- - - -.. _stopping_running_services: - -Stopping the Running Services -~~~~~~~~~~~~~~~~~ - -You can stop running services either for a single SQream worker, or all SQream services for both master and worker. - -The following is the command for stopping a running service for a single SQream worker: - -.. code-block:: console - - $ sqream worker --stop - -The following is an example of expected output when stopping a running service for a single SQream worker: - -.. code-block:: console - - sqream worker stop - stopped container sqream_single_host_worker_0, id: 892a8f1a58c5 - - -You can stop all running SQream services (both master and worker) by running the following command: - -.. code-block:: console - - $ sqream-console>sqream master --stop --all - -The following is an example of expected output when stopping all running services: - -.. code-block:: console - - sqream-console>sqream master --stop --all - stopped container sqream_single_host_worker_0, id: 892a8f1a58c5 - stopped container sqream_single_host_master, id: 55cb7e38eb22 - - -.. _using_sqream_editor: - -Using SQream Studio -~~~~~~~~~~~~~~~~~ -SQream Studio is an SQL statement editor. - -**To start SQream Studio:** - -1. Run the following command: - - .. code-block:: console - - $ sqream studio --start - -The following is an example of the expected output: - - .. code-block:: console - - SQream Acceleration Studio is available at http://192.168.1.62:8080 - -2. Click the ``http://192.168.1.62:8080`` link shown in the CLI. - - -**To stop SQream Studio:** - -You can stop your SQream Studio by running the following command: - -.. code-block:: console - - $ sqream studio --stop - -The following is an example of the expected output: - -.. code-block:: console - - sqream_admin stopped - - -.. _using_sqream_client: - -Using the SQream Client -~~~~~~~~~~~~~~~~~ - - -You can use the embedded SQream Client on the following nodes: - -* Master node -* Worker node - - -When using the SQream Client on the Master node, the following default settings are used: - -* **Default port**: 3108. You can change the default port using the ``-p`` variable. -* **Default database**: master. You can change the default database using the ``-d`` variable. - -The following is an example: - -.. code-block:: console - - $ sqream client --master -u sqream -w sqream - - -When using the SQream Client on a Worker node (or nodes), you should use the ``-p`` variable for Worker ports. The default database is ``master``, but you can use the ``-d`` variable to change databases. - -The following is an example: - -.. code-block:: console - - $ sqream client --worker -p 5000 -u sqream -w sqream - - -Moving from Docker Installation to Standard On-Premises Installation ------------------------------------------------ - -Because Docker creates all files and directories on the host at the **root** level, you must grant ownership of the SQream storage folder to the working directory user. - -SQream Console - Advanced Commands ------------------------------ - -The SQream console offers the following advanced commands: - - -* :ref:`Controlling the spool size ` -* :ref:`Splitting a GPU ` -* :ref:`Splitting a GPU and setting the spool size ` -* :ref:`Using a custom configuration file ` -* :ref:`Clustering your Docker environment ` - - - - -.. _controlling_spool_size: - -Controlling the Spool Size -~~~~~~~~~~~~~~~~~~ - -From the console you can define a spool size value. - -The following example shows the spool size being set to ``50``: - -.. code-block:: console - - $ sqream-console>sqream worker --start 2 -m 50 - - -If you don't define the SQream spool size, the SQream console automatically distributes the available RAM between all running workers. - -.. _splitting_gpu: - -Splitting a GPU -~~~~~~~~~~~~~~~~~~ - -You can start more than one sqreamd on a single GPU by splitting it. - - -The following example shows the GPU being split into **two** sqreamd's on the GPU in **slot 0**: - -.. code-block:: console - - $ sqream-console>sqream worker --start 2 -g 0 - -.. _splitting_gpu_setting_spool_size: - -Splitting GPU and Setting the Spool Size -~~~~~~~~~~~~~~~~~~ - -You can simultaneously split a GPU and set the spool size by appending the ``-m`` flag: - -.. code-block:: console - - $ sqream-console>sqream worker --start 2 -g 0 -m 50 - -.. note:: The console does not validate whether the user-defined spool size is available. Before setting the spool size, verify that the requested resources are available. - -.. _using_custom_configuration_file: - -Using a Custom Configuration File -~~~~~~~~~~~~~~~~~~ - -SQream lets you use your own external custom configuration json files. You must place these json files in the path mounted in the installation. SQream recommends placing the json file in the Configuration folder. - -The SQream console does not validate the integrity of your external configuration files. - -When using your custom configuration file, you can use the ``-j`` flag to define the full path to the Configuration file, as in the example below: - -.. code-block:: console - - $ sqream-console>sqream worker --start 1 -j /etc/sqream/configfile.json - -.. note:: To start more than one sqream daemon, you must provide files for each daemon, as in the example below: - -.. code-block:: console - - $ sqream worker --start 2 -j /etc/sqream/configfile.json /etc/sqream/configfile2.json - -.. note:: To split a specific GPU, you must also list the GPU flag, as in the example below: - -.. code-block:: console - - $ sqream worker --start 2 -g 0 -j /etc/sqream/configfile.json /etc/sqream/configfile2.json - -.. _clustering_docker_environment: - -Clustering Your Docker Environment -~~~~~~~~~~~~~~~~~~ - -SQream lets you connect to a remote Master node to start Docker in Distributed mode. If you have already connected to a Slave node server in Distributed mode, the **sqream Master** and **Client** commands are only available on the Master node. - -.. code-block:: console - - $ --master-host - $ sqream-console>sqream worker --start 1 --master-host 192.168.0.1020 - -Checking the Status of SQream Services ---------------------------- -SQream lets you check the status of SQream services from the following locations: - -* :ref:`From the Sqream console ` -* :ref:`From outside the Sqream console ` - -.. _inside_sqream_console: - -Checking the Status of SQream Services from the SQream Console -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -From the SQream console, you can check the status of SQream services by running the following command: - -.. code-block:: console - - $ sqream-console>sqream master --list - -The following is an example of the expected output: - -.. code-block:: console - - $ sqream-console>sqream master --list - $ checking 3 sqream services: - $ sqream_single_host_worker_1 up, listens on port: 5001 allocated gpu: 1 - $ sqream_single_host_worker_0 up, listens on port: 5000 allocated gpu: 1 - $ sqream_single_host_master up listens on ports: 3105,3108 - -.. _outside_sqream_console: - -Checking the Status of SQream Services from Outside the SQream Console -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -From outside the Sqream Console, you can check the status of SQream services by running the following commands: - -.. code-block:: console - - $ sqream-status - $ NAMES STATUS PORTS - $ sqream_single_host_worker_1 Up 3 minutes 0.0.0.0:5001->5001/tcp - $ sqream_single_host_worker_0 Up 3 minutes 0.0.0.0:5000->5000/tcp - $ sqream_single_host_master Up 3 minutes 0.0.0.0:3105->3105/tcp, 0.0.0.0:3108->3108/tcp - $ sqream_editor_3.0.0 Up 3 hours (healthy) 0.0.0.0:3000->3000/tcp - -Upgrading Your SQream System ----------------------------- -This section describes how to upgrade your SQream system. - -**To upgrade your SQream system:** - -1. Contact the SQream Support team for access to the new SQream package tarball file. - - :: - -2. Set a maintenance window to enable stopping the system while upgrading it. - - :: - -3. Extract the following tarball file received from the SQream Support team, under it with the same user and in the same folder that you used while :ref:`Downloading the SQream Software <_download_sqream_software>`. - - - .. code-block:: console - - $ tar -xvf sqream_installer-2.0.5-DB2019.2.1-CO1.6.3-ED3.0.0-x86_64/ - -4. Navigate to the new folder created as a result of extracting the tarball file: - - .. code-block:: console - - $ cd sqream_installer-2.0.5-DB2019.2.1-CO1.6.3-ED3.0.0-x86_64/ - -5. Initiate the upgrade process: - - .. code-block:: console - - $ ./sqream-install -i - - Initiating the upgrade process checks if any SQream services are running. If any services are running, you will be prompted to stop them. - -6. Do one of the following: - - * Select **Yes** to stop all running SQream workers (Master and Editor) and continue the upgrade process. - * Select **No** to stop the upgrade process. - - SQream periodically upgrades the metadata structure. If an upgrade version includes a change to the metadata structure, you will be prompted with an approval request message. Your approval is required to finish the upgrade process. - - Because SQream supports only certain metadata versions, all SQream services must be upgraded at the same time. - -7. When the upgrade is complete, load the SQream console and restart your services. - - For assistance, contact SQream Support. From 14870eec41a11afdd0c17022438632b48b48a030 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 29 Mar 2022 12:34:57 +0300 Subject: [PATCH 031/316] Updated According to V2 Requirements ... According to Shachar's comments in SQream Documentation - Table of Contents sheet --- data_ingestion/index.rst | 3 +- data_ingestion/oracle.rst | 353 ------------ feature_guides/index.rst | 1 - getting_started/index.rst | 1 - .../performing_basic_sqream_operations.rst | 1 + index.rst | 2 - operational_guides/external_data.rst | 1 - operational_guides/hdfs.rst | 252 --------- operational_guides/index.rst | 1 - operational_guides/saved_queries.rst | 122 ----- .../client_drivers/cpp/connect_test.cpp | 34 -- .../client_drivers/cpp/index.rst | 87 --- .../client_drivers/cpp/insert_test.cpp | 39 -- third_party_tools/client_drivers/index.rst | 27 +- .../client_drivers/nodejs/index.rst | 382 ------------- .../client_drivers/nodejs/sample.js | 21 - .../client_drivers/python/api-reference.rst | 191 ------- .../client_drivers/python/index.rst | 502 ------------------ .../client_drivers/python/nba-t10.csv | 10 - .../client_drivers/python/test.py | 37 -- .../client_platforms/connect.sas | 27 - .../client_platforms/connect2.sas | 27 - .../client_platforms/connect3.sas | 17 - third_party_tools/client_platforms/index.rst | 37 -- .../client_platforms/informatica.rst | 173 ------ .../client_platforms/microstrategy.rst | 185 ------- .../client_platforms/odbc-sqream.tdc | 25 - .../client_platforms/pentaho.rst | 249 --------- third_party_tools/client_platforms/php.rst | 46 -- .../client_platforms/power_bi.rst | 143 ----- third_party_tools/client_platforms/r.rst | 151 ------ .../client_platforms/sas_viya.rst | 185 ------- .../client_platforms/sql_workbench.rst | 135 ----- .../client_platforms/tableau.rst | 453 ---------------- third_party_tools/client_platforms/talend.rst | 177 ------ third_party_tools/client_platforms/test.php | 16 - .../client_platforms/tibco_spotfire.rst | 387 -------------- third_party_tools/index.rst | 1 - troubleshooting/index.rst | 5 - troubleshooting/node_js_related_issues.rst | 54 -- troubleshooting/sas_viya_related_issues.rst | 55 -- .../solving_code_126_odbc_errors.rst | 14 - ...sqream_sql_installation_related_issues.rst | 33 -- troubleshooting/tableau_related_issues.rst | 73 --- 44 files changed, 3 insertions(+), 4732 deletions(-) delete mode 100644 data_ingestion/oracle.rst delete mode 100644 operational_guides/hdfs.rst delete mode 100644 operational_guides/saved_queries.rst delete mode 100644 third_party_tools/client_drivers/cpp/connect_test.cpp delete mode 100644 third_party_tools/client_drivers/cpp/index.rst delete mode 100644 third_party_tools/client_drivers/cpp/insert_test.cpp delete mode 100644 third_party_tools/client_drivers/nodejs/index.rst delete mode 100644 third_party_tools/client_drivers/nodejs/sample.js delete mode 100644 third_party_tools/client_drivers/python/api-reference.rst delete mode 100644 third_party_tools/client_drivers/python/index.rst delete mode 100644 third_party_tools/client_drivers/python/nba-t10.csv delete mode 100644 third_party_tools/client_drivers/python/test.py delete mode 100644 third_party_tools/client_platforms/connect.sas delete mode 100644 third_party_tools/client_platforms/connect2.sas delete mode 100644 third_party_tools/client_platforms/connect3.sas delete mode 100644 third_party_tools/client_platforms/index.rst delete mode 100644 third_party_tools/client_platforms/informatica.rst delete mode 100644 third_party_tools/client_platforms/microstrategy.rst delete mode 100644 third_party_tools/client_platforms/odbc-sqream.tdc delete mode 100644 third_party_tools/client_platforms/pentaho.rst delete mode 100644 third_party_tools/client_platforms/php.rst delete mode 100644 third_party_tools/client_platforms/power_bi.rst delete mode 100644 third_party_tools/client_platforms/r.rst delete mode 100644 third_party_tools/client_platforms/sas_viya.rst delete mode 100644 third_party_tools/client_platforms/sql_workbench.rst delete mode 100644 third_party_tools/client_platforms/tableau.rst delete mode 100644 third_party_tools/client_platforms/talend.rst delete mode 100644 third_party_tools/client_platforms/test.php delete mode 100644 third_party_tools/client_platforms/tibco_spotfire.rst delete mode 100644 troubleshooting/node_js_related_issues.rst delete mode 100644 troubleshooting/sas_viya_related_issues.rst delete mode 100644 troubleshooting/solving_code_126_odbc_errors.rst delete mode 100644 troubleshooting/sqream_sql_installation_related_issues.rst delete mode 100644 troubleshooting/tableau_related_issues.rst diff --git a/data_ingestion/index.rst b/data_ingestion/index.rst index 83aca40ea..ffcb60552 100644 --- a/data_ingestion/index.rst +++ b/data_ingestion/index.rst @@ -13,6 +13,5 @@ The **Data Ingestion Sources** provides information about the following: csv parquet orc - oracle -For information about database tools and interfaces that SQream supports, see `Third Party Tools `_. +For information about database tools and interfaces that SQream supports, see `Third Party Tools `_. \ No newline at end of file diff --git a/data_ingestion/oracle.rst b/data_ingestion/oracle.rst deleted file mode 100644 index 0b0e6d5c8..000000000 --- a/data_ingestion/oracle.rst +++ /dev/null @@ -1,353 +0,0 @@ -.. _oracle: - -********************** -Migrating Data from Oracle -********************** - -This guide covers actions required for migrating from Oracle to SQream DB with CSV files. - -.. contents:: In this topic: - :local: - - -1. Preparing the tools and login information -==================================================== - -* Migrating data from Oracle requires a username and password for your Oracle system. - -* In this guide, we'll use the `Oracle Data Pump `_ , specifically the `Data Pump Export utility `_ . - - -2. Export the desired schema -=================================== - -Use the Data Pump Export utility to export the database schema. - -The format for using the Export utility is - - ``expdp / DIRECTORY= DUMPFILE= CONTENT=metadata_only NOLOGFILE`` - -The resulting Oracle-only schema is stored in a dump file. - - -Examples ------------- - -Dump all tables -^^^^^^^^^^^^^^^^^^^^^^ - -.. code-block:: console - - $ expdp rhendricks/secretpassword DIRECTORY=dpumpdir DUMPFILE=tables.dmp CONTENT=metadata_only NOLOGFILE - - -Dump only specific tables -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -In this example, we specify two tables for dumping. - -.. code-block:: console - - $ expdp rhendricks/secretpassword DIRECTORY=dpumpdir DUMPFILE=tables.dmp CONTENT=metadata_only TABLES=employees,jobs NOLOGFILE - -3. Convert the Oracle dump to standard SQL -======================================================= - -Oracle's Data Pump Import utility will help us convert the dump from the previous step to standard SQL. - -The format for using the Import utility is - - ``impdp / DIRECTORY= DUMPFILE= SQLFILE= TRANSFORM=SEGMENT_ATTRIBUTES:N:table PARTITION_OPTIONS=MERGE`` - -* ``TRANSFORM=SEGMENT_ATTRIBUTES:N:table`` excludes segment attributes (both STORAGE and TABLESPACE) from the tables - -* ``PARTITON_OPTIONS=MERGE`` combines all partitions and subpartitions into one table. - -Example ----------- - -.. code-block:: console - - $ impdp rhendricks/secretpassword DIRECTORY=dpumpdir DUMPFILE=tables.dmp SQLFILE=sql_export.sql TRANSFORM=SEGMENT_ATTRIBUTES:N:table PARTITION_OPTIONS=MERGE - -4. Figure out the database structures -=============================================== - -Using the SQL file created in the previous step, write CREATE TABLE statements to match the schemas of the tables. - -Remove unsupported attributes ------------------------------------ - -Trim unsupported primary keys, indexes, constraints, and other unsupported Oracle attributes. - -Match data types ---------------------- - -Refer to the table below to match the Oracle source data type to a new SQream DB type: - -.. list-table:: Data types - :widths: auto - :header-rows: 1 - - * - Oracle Data type - - Precision - - SQream DB data type - * - ``CHAR(n)``, ``CHARACTER(n)`` - - Any ``n`` - - ``VARCHAR(n)`` - * - ``BLOB``, ``CLOB``, ``NCLOB``, ``LONG`` - - - - ``TEXT`` - * - ``DATE`` - - - - ``DATE`` - * - ``FLOAT(p)`` - - p <= 63 - - ``REAL`` - * - ``FLOAT(p)`` - - p > 63 - - ``FLOAT``, ``DOUBLE`` - - * - ``NCHAR(n)``, ``NVARCHAR2(n)`` - - Any ``n`` - - ``TEXT`` (alias of ``NVARCHAR``) - - * - ``NUMBER(p)``, ``NUMBER(p,0)`` - - p < 5 - - ``SMALLINT`` - - * - ``NUMBER(p)``, `NUMBER(p,0)`` - - p < 9 - - ``INT`` - - * - ``NUMBER(p)``, `NUMBER(p,0)`` - - p < 19 - - ``INT`` - - * - ``NUMBER(p)``, `NUMBER(p,0)`` - - p >= 20 - - ``BIGINT`` - - * - ``NUMBER(p,f)``, ``NUMBER(*,f)`` - - f > 0 - - ``FLOAT`` / ``DOUBLE`` - - * - ``VARCHAR(n)``, ``VARCHAR2(n)`` - - Any ``n`` - - ``VARCHAR(n)`` or ``TEXT`` - * - ``TIMESTAMP`` - - - - ``DATETIME`` - -Read more about :ref:`supported data types in SQream DB`. - -Additional considerations ------------------------------ - -* Understand how :ref:`tables are created in SQream DB` - -* Learn how :ref:`SQream DB handles null values`, particularly with regards to constraints. - -* Oracle roles and user management commands need to be rewritten to SQream DB's format. SQream DB supports :ref:`full role-based access control (RBAC)` similar to Oracle. - -5. Create the tables in SQream DB -====================================== - -After rewriting the table strucutres, create them in SQream DB. - -Example ---------- - - -Consider Oracle's ``HR.EMPLOYEES`` sample table: - -.. code-block:: sql - - CREATE TABLE employees - ( employee_id NUMBER(6) - , first_name VARCHAR2(20) - , last_name VARCHAR2(25) - CONSTRAINT emp_last_name_nn NOT NULL - , email VARCHAR2(25) - CONSTRAINT emp_email_nn NOT NULL - , phone_number VARCHAR2(20) - , hire_date DATE - CONSTRAINT emp_hire_date_nn NOT NULL - , job_id VARCHAR2(10) - CONSTRAINT emp_job_nn NOT NULL - , salary NUMBER(8,2) - , commission_pct NUMBER(2,2) - , manager_id NUMBER(6) - , department_id NUMBER(4) - , CONSTRAINT emp_salary_min - CHECK (salary > 0) - , CONSTRAINT emp_email_uk - UNIQUE (email) - ) ; - CREATE UNIQUE INDEX emp_emp_id_pk - ON employees (employee_id) ; - - ALTER TABLE employees - ADD ( CONSTRAINT emp_emp_id_pk - PRIMARY KEY (employee_id) - , CONSTRAINT emp_dept_fk - FOREIGN KEY (department_id) - REFERENCES departments - , CONSTRAINT emp_job_fk - FOREIGN KEY (job_id) - REFERENCES jobs (job_id) - , CONSTRAINT emp_manager_fk - FOREIGN KEY (manager_id) - REFERENCES employees - ) ; - -This table rewritten for SQream DB would be created like this: - -.. code-block:: postgres - - CREATE TABLE employees - ( - employee_id SMALLINT NOT NULL, - first_name VARCHAR(20), - last_name VARCHAR(25) NOT NULL, - email VARCHAR(20) NOT NULL, - phone_number VARCHAR(20), - hire_date DATE NOT NULL, - job_id VARCHAR(10) NOT NULL, - salary FLOAT, - commission_pct REAL, - manager_id SMALLINT, - department_id TINYINT - ); - - -6. Export tables to CSVs -=============================== - -Exporting CSVs from Oracle servers is not a trivial task. - -.. contents:: Options for exporting to CSVs - :local: - -Using SQL*Plus to export data lists ------------------------------------------- - -Here's a sample SQL*Plus script that will export PSVs in a format that SQream DB can read: - -:download:`Download to_csv.sql ` - -.. literalinclude:: to_csv.sql - :language: sql - :caption: Oracle SQL*Plus CSV export script - :linenos: - -Enter SQL*Plus and export tables one-by-one interactively: - -.. code-block:: console - - $ sqlplus rhendricks/secretpassword - - @spool employees - @spool jobs - [...] - EXIT - -Each table is exported as a data list file (``.lst``). - -Creating CSVs using stored procedures -------------------------------------------- - -You can use stored procedures if you have them set-up. - -Examples of `stored procedures for generating CSVs `_` can be found in the Ask The Oracle Mentors forums. - -CSV generation considerations -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -* Files should be a valid CSV. By default, SQream DB's CSV parser can handle `RFC 4180 standard CSVs `_ , but can also be modified to support non-standard CSVs (with multi-character delimiters, unquoted fields, etc). - -* Files are UTF-8 or ASCII encoded - -* Field delimiter is an ASCII character or characters - -* Record delimiter, also known as a new line separator, is a Unix-style newline (``\n``), DOS-style newline (``\r\n``), or Mac style newline (``\r``). - -* Fields are optionally enclosed by double-quotes, or mandatory quoted if they contain one of the following characters: - - * The record delimiter or field delimiter - - * A double quote character - - * A newline - -* - If a field is quoted, any double quote that appears must be double-quoted (similar to the :ref:`string literals quoting rules`. For example, to encode ``What are "birds"?``, the field should appear as ``"What are ""birds""?"``. - - Other modes of escaping are not supported (e.g. ``1,"What are \"birds\"?"`` is not a valid way of escaping CSV values). - -* ``NULL`` values can be marked in two ways in the CSV: - - - An explicit null marker. For example, ``col1,\N,col3`` - - An empty field delimited by the field delimiter. For example, ``col1,,col3`` - - .. note:: If a text field is quoted but contains no content (``""``) it is considered an empty text field. It is not considered ``NULL``. - - -7. Place CSVs where SQream DB workers can access -======================================================= - -During data load, the :ref:`copy_from` command can run on any worker (unless explicitly speficied with the :ref:`workload_manager`). -It is important that every node has the same view of the storage being used - meaning, every SQream DB worker should have access to the files. - -* For files hosted on NFS, ensure that the mount is accessible from all servers. - -* For HDFS, ensure that SQream DB servers can access the HDFS name node with the correct user-id - -* For S3, ensure network access to the S3 endpoint - -8. Bulk load the CSVs -================================= - -Issue the :ref:`copy_from` commands to SQream DB to insert a table from the CSVs created. - -Repeat the ``COPY FROM`` command for each table exported from Oracle. - -Example -------------- - -For the ``employees`` table, run the following command: - -.. code-block:: postgres - - COPY employees FROM 'employees.lst' WITH DELIMITER '|'; - -9. Rewrite Oracle queries -===================================== - -SQream DB supports a large subset of ANSI SQL. - -You will have to refactor much of Oracle's SQL and functions that often are not ANSI SQL. - -We recommend the following resources: - -* :ref:`sql_feature_support` - to understand SQream DB's SQL feature support. - -* :ref:`sql_best_practices` - to understand best practices for SQL queries and schema design. - -* :ref:`common_table_expressions` - CTEs can be used to rewrite complex queries in a compact form. - -* :ref:`concurrency_and_locks` - to understand the difference between Oracle's transactions and SQream DB's concurrency. - -* :ref:`identity` - SQream DB supports sequences, but no triggers for auto-increment. - -* :ref:`joins` - SQream DB supports ANSI join syntax. Oracle uses the ``+`` operator which SQream DB doesn't support. - -* :ref:`saved_queries` - Saved queries can be used to emulate some stored procedures. - -* :ref:`subqueries` - SQream DB supports a limited set of subqueries. - -* :ref:`python_functions` - SQream DB supports Python User Defined Functions which can be used to run complex operations in-line. - -* :ref:`Views` - SQream DB supports logical views, but does not support materialized views. - -* :ref:`window_functions` - SQream DB supports a wide array of window functions. \ No newline at end of file diff --git a/feature_guides/index.rst b/feature_guides/index.rst index c5f472785..9a5c8621d 100644 --- a/feature_guides/index.rst +++ b/feature_guides/index.rst @@ -16,7 +16,6 @@ This section describes the following features: compression flexible_data_clustering python_functions - saved_queries viewing_system_objects_as_ddl workload_manager transactions diff --git a/getting_started/index.rst b/getting_started/index.rst index f9a57a460..e799d047a 100644 --- a/getting_started/index.rst +++ b/getting_started/index.rst @@ -11,6 +11,5 @@ The **Getting Started** page describes the following things you need to start us preparing_your_machine_to_install_sqream installing_sqream - creating_a_database executing_statements_in_sqream performing_basic_sqream_operations \ No newline at end of file diff --git a/getting_started/performing_basic_sqream_operations.rst b/getting_started/performing_basic_sqream_operations.rst index ba0a6fc3f..81ea9b05f 100644 --- a/getting_started/performing_basic_sqream_operations.rst +++ b/getting_started/performing_basic_sqream_operations.rst @@ -11,6 +11,7 @@ After installing SQream you can perform the operations described on this page: running_the_sqream_sql_client creating_your_first_table + creating_a_database listing_tables inserting_rows running_queries diff --git a/index.rst b/index.rst index 26b7459ec..cb7d685b2 100644 --- a/index.rst +++ b/index.rst @@ -72,8 +72,6 @@ SQream DB easily plugs in to third-party tools like :ref:`Tableau` - :ref:`Third party tools integration` - :ref:`connect_to_tableau` - :ref:`troubleshooting` guide diff --git a/operational_guides/external_data.rst b/operational_guides/external_data.rst index 98d157ab2..576e50ea4 100644 --- a/operational_guides/external_data.rst +++ b/operational_guides/external_data.rst @@ -11,5 +11,4 @@ SQream DB supports external data sources for use with :ref:`external_tables`, :r :titlesonly: s3 - hdfs diff --git a/operational_guides/hdfs.rst b/operational_guides/hdfs.rst deleted file mode 100644 index 274926e36..000000000 --- a/operational_guides/hdfs.rst +++ /dev/null @@ -1,252 +0,0 @@ -.. _hdfs: - -.. _back_to_top_hdfs: - -Using SQream in an HDFS Environment -======================================= - -.. _configuring_an_hdfs_environment_for_the_user_sqream: - -Configuring an HDFS Environment for the User **sqream** ----------------------------------------------------------- - -This section describes how to configure an HDFS environment for the user **sqream** and is only relevant for users with an HDFS environment. - -**To configure an HDFS environment for the user sqream:** - -1. Open your **bash_profile** configuration file for editing: - - .. code-block:: console - - $ vim /home/sqream/.bash_profile - -.. - Comment: - see below; do we want to be a bit more specific on what changes we're talking about? - - .. code-block:: console - - $ #PATH=$PATH:$HOME/.local/bin:$HOME/bin - - $ #export PATH - - $ # PS1 - $ #MYIP=$(curl -s -XGET "http://ip-api.com/json" | python -c 'import json,sys; jstr=json.load(sys.stdin); print jstr["query"]') - $ #PS1="\[\e[01;32m\]\D{%F %T} \[\e[01;33m\]\u@\[\e[01;36m\]$MYIP \[\e[01;31m\]\w\[\e[37;36m\]\$ \[\e[1;37m\]" - - $ SQREAM_HOME=/usr/local/sqream - $ export SQREAM_HOME - - $ export JAVA_HOME=${SQREAM_HOME}/hdfs/jdk - $ export HADOOP_INSTALL=${SQREAM_HOME}/hdfs/hadoop - $ export CLASSPATH=`${HADOOP_INSTALL}/bin/hadoop classpath --glob` - $ export HADOOP_COMMON_LIB_NATIVE_DIR=${HADOOP_INSTALL}/lib/native - $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${SQREAM_HOME}/lib:$HADOOP_COMMON_LIB_NATIVE_DIR - - - $ PATH=$PATH:$HOME/.local/bin:$HOME/bin:${SQREAM_HOME}/bin/:${JAVA_HOME}/bin:$HADOOP_INSTALL/bin - $ export PATH - -3. Verify that the edits have been made: - - .. code-block:: console - - source /home/sqream/.bash_profile - -4. Check if you can access Hadoop from your machine: - - .. code-block:: console - - $ hadoop fs -ls hdfs://:8020/ - -.. - Comment: - - **NOTICE:** If you cannot access Hadoop from your machine because it uses Kerberos, see `Connecting a SQream Server to Cloudera Hadoop with Kerberos `_ - - -5. Verify that an HDFS environment exists for SQream services: - - .. code-block:: console - - $ ls -l /etc/sqream/sqream_env.sh - -.. _step_6: - - -6. If an HDFS environment does not exist for SQream services, create one (sqream_env.sh): - - .. code-block:: console - - $ #!/bin/bash - - $ SQREAM_HOME=/usr/local/sqream - $ export SQREAM_HOME - - $ export JAVA_HOME=${SQREAM_HOME}/hdfs/jdk - $ export HADOOP_INSTALL=${SQREAM_HOME}/hdfs/hadoop - $ export CLASSPATH=`${HADOOP_INSTALL}/bin/hadoop classpath --glob` - $ export HADOOP_COMMON_LIB_NATIVE_DIR=${HADOOP_INSTALL}/lib/native - $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${SQREAM_HOME}/lib:$HADOOP_COMMON_LIB_NATIVE_DIR - - - $ PATH=$PATH:$HOME/.local/bin:$HOME/bin:${SQREAM_HOME}/bin/:${JAVA_HOME}/bin:$HADOOP_INSTALL/bin - $ export PATH - -:ref:`Back to top ` - - -.. _authenticate_hadoop_servers_that_require_kerberos: - -Authenticating Hadoop Servers that Require Kerberos ---------------------------------------------------- - -If your Hadoop server requires Kerberos authentication, do the following: - -1. Create a principal for the user **sqream**. - - .. code-block:: console - - $ kadmin -p root/admin@SQ.COM - $ addprinc sqream@SQ.COM - -2. If you do not know yor Kerberos root credentials, connect to the Kerberos server as a root user with ssh and run **kadmin.local**: - - .. code-block:: console - - $ kadmin.local - - Running **kadmin.local** does not require a password. - -3. If a password is not required, change your password to **sqream@SQ.COM**. - - .. code-block:: console - - $ change_password sqream@SQ.COM - -4. Connect to the hadoop name node using ssh: - - .. code-block:: console - - $ cd /var/run/cloudera-scm-agent/process - -5. Check the most recently modified content of the directory above: - - .. code-block:: console - - $ ls -lrt - -5. Look for a recently updated folder containing the text **hdfs**. - -The following is an example of the correct folder name: - - .. code-block:: console - - cd -hdfs- - - This folder should contain a file named **hdfs.keytab** or another similar .keytab file. - - - -.. - Comment: - Does "something" need to be replaced with "file name" - - -6. Copy the .keytab file to user **sqream's** Home directory on the remote machines that you are planning to use Hadoop on. - -7. Copy the following files to the **sqream sqream@server:/hdfs/hadoop/etc/hadoop:** directory: - - * core-site.xml - * hdfs-site.xml - -8. Connect to the sqream server and verify that the .keytab file's owner is a user sqream and is granted the correct permissions: - - .. code-block:: console - - $ sudo chown sqream:sqream /home/sqream/hdfs.keytab - $ sudo chmod 600 /home/sqream/hdfs.keytab - -9. Log into the sqream server. - -10. Log in as the user **sqream**. - -11. Navigate to the Home directory and check the name of a Kerberos principal represented by the following .keytab file: - - .. code-block:: console - - $ klist -kt hdfs.keytab - - The following is an example of the correct output: - - .. code-block:: console - - $ sqream@Host-121 ~ $ klist -kt hdfs.keytab - $ Keytab name: FILE:hdfs.keytab - $ KVNO Timestamp Principal - $ ---- ------------------- ------------------------------------------------------ - $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM - $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM - $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM - $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM - $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM - $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM - $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM - $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM - $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM - $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM - $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM - $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM - $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM - $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM - $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM - $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM - -12. Verify that the hdfs service named **hdfs/nn1@SQ.COM** is shown in the generated output above. - -13. Run the following: - - .. code-block:: console - - $ kinit -kt hdfs.keytab hdfs/nn1@SQ.COM - - 13. Check the output: - - .. code-block:: console - - $ klist - - The following is an example of the correct output: - - .. code-block:: console - - $ Ticket cache: FILE:/tmp/krb5cc_1000 - $ Default principal: sqream@SQ.COM - $ - $ Valid starting Expires Service principal - $ 09/16/2020 13:44:18 09/17/2020 13:44:18 krbtgt/SQ.COM@SQ.COM - -14. List the files located at the defined server name or IP address: - - .. code-block:: console - - $ hadoop fs -ls hdfs://:8020/ - -15. Do one of the following: - - * If the list below is output, continue with Step 16. - * If the list is not output, verify that your environment has been set up correctly. - -If any of the following are empty, verify that you followed :ref:`Step 6 ` in the **Configuring an HDFS Environment for the User sqream** section above correctly: - - .. code-block:: console - - $ echo $JAVA_HOME - $ echo $SQREAM_HOME - $ echo $CLASSPATH - $ echo $HADOOP_COMMON_LIB_NATIVE_DIR - $ echo $LD_LIBRARY_PATH - $ echo $PATH - -16. Verify that you copied the correct keytab file. - -17. Review this procedure to verify that you have followed each step. - -:ref:`Back to top ` \ No newline at end of file diff --git a/operational_guides/index.rst b/operational_guides/index.rst index b7ea1502d..dcad76172 100644 --- a/operational_guides/index.rst +++ b/operational_guides/index.rst @@ -20,7 +20,6 @@ This section summarizes the following operational guides: logging monitoring_query_performance security - saved_queries seeing_system_objects_as_ddl configuration optimization_best_practices diff --git a/operational_guides/saved_queries.rst b/operational_guides/saved_queries.rst deleted file mode 100644 index d554b4dc8..000000000 --- a/operational_guides/saved_queries.rst +++ /dev/null @@ -1,122 +0,0 @@ -.. _saved_queries: - -*********************** -Saved Queries -*********************** - -Saved queries can be used to reuse a query plan for a query to eliminate compilation times for repeated queries. They also provide a way to implement 'parameterized views'. - -How saved queries work -========================== - -Saved queries are compiled when they are created. When a saved query is run, this query plan is used instead of compiling a query plan at query time. - -Parameters support -=========================== - -Query parameters can be used as substitutes for literal expressions in queries. - -* Parameters cannot be used to substitute things like column names and table names. - -* Query parameters of a string datatype (like ``VARCHAR``) must be of a fixed length, and can be used in equality checks, but not patterns (e.g. :ref:`like`, :ref:`rlike`, etc.) - -Creating a saved query -====================== - -A saved query is created using the :ref:`save_query` utility command. - -Saving a simple query ---------------------------- - -.. code-block:: psql - - t=> SELECT SAVE_QUERY('select_all','SELECT * FROM nba'); - executed - -Saving a parametrized query ------------------------------------------- - -Use parameters to replace them later at execution time. - - - -.. code-block:: psql - - t=> SELECT SAVE_QUERY('select_by_weight_and_team','SELECT * FROM nba WHERE Weight > ? AND Team = ?'); - executed - -.. TODO tip Use dollar quoting (`$$`) to avoid escaping strings. -.. this makes no sense unless you have a query which would otherwise need escaping -.. t=> SELECT SAVE_QUERY('select_by_weight_and_team',$$SELECT * FROM nba WHERE Weight > ? AND Team = ?$$); -.. executed - - -Listing and executing saved queries -====================================== - -Saved queries are saved as a database objects. They can be listed in one of two ways: - -Using the :ref:`catalog`: - -.. code-block:: psql - - t=> SELECT * FROM sqream_catalog.savedqueries; - name | num_parameters - --------------------------+--------------- - select_all | 0 - select_by_weight | 1 - select_by_weight_and_team | 2 - -Using the :ref:`list_saved_queries` utility function: - -.. code-block:: psql - - t=> SELECT LIST_SAVED_QUERIES(); - saved_query - ------------------------- - select_all - select_by_weight - select_by_weight_and_team - -Executing a saved query requires calling it by it's name in a :ref:`execute_saved_query` statement. A saved query with no parameter is called without parameters. - -.. code-block:: psql - - t=> SELECT EXECUTE_SAVED_QUERY('select_all'); - Name | Team | Number | Position | Age | Height | Weight | College | Salary - -------------------------+------------------------+--------+----------+-----+--------+--------+-----------------------+--------- - Avery Bradley | Boston Celtics | 0 | PG | 25 | 6-2 | 180 | Texas | 7730337 - Jae Crowder | Boston Celtics | 99 | SF | 25 | 6-6 | 235 | Marquette | 6796117 - John Holland | Boston Celtics | 30 | SG | 27 | 6-5 | 205 | Boston University | - R.J. Hunter | Boston Celtics | 28 | SG | 22 | 6-5 | 185 | Georgia State | 1148640 - [...] - -Executing a saved query with parameters requires specifying the parameters in the order they appear in the query: - -.. code-block:: psql - - t=> SELECT EXECUTE_SAVED_QUERY('select_by_weight_and_team', 240, 'Toronto Raptors'); - Name | Team | Number | Position | Age | Height | Weight | College | Salary - ------------------+-----------------+--------+----------+-----+--------+--------+-------------+-------- - Bismack Biyombo | Toronto Raptors | 8 | C | 23 | 6-9 | 245 | | 2814000 - James Johnson | Toronto Raptors | 3 | PF | 29 | 6-9 | 250 | Wake Forest | 2500000 - Jason Thompson | Toronto Raptors | 1 | PF | 29 | 6-11 | 250 | Rider | 245177 - Jonas Valanciunas | Toronto Raptors | 17 | C | 24 | 7-0 | 255 | | 4660482 - - -Dropping a saved query -============================= - -When you're done with a saved query, or would like to replace it with another, you can drop it with :ref:`drop_saved_query`: - -.. code-block:: psql - - t=> SELECT DROP_SAVED_QUERY('select_all'); - executed - t=> SELECT DROP_SAVED_QUERY('select_by_weight_and_team'); - executed - - t=> SELECT LIST_SAVED_QUERIES(); - saved_query - ------------------------- - select_by_weight diff --git a/third_party_tools/client_drivers/cpp/connect_test.cpp b/third_party_tools/client_drivers/cpp/connect_test.cpp deleted file mode 100644 index dc199f06b..000000000 --- a/third_party_tools/client_drivers/cpp/connect_test.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// Trivial example - -#include - -#include "sqream.h" - -int main () { - - sqream::driver sqc; - - // Connection parameters: Hostname, Port, Use SSL, Username, Password, - // Database name, Service name - sqc.connect("127.0.0.1", 5000, false, "rhendricks", "Tr0ub4dor&3", - "raviga", "sqream"); - - // create table with data - run_direct_query(&sqc, "CREATE TABLE test_table (x int)"); - run_direct_query(&sqc, "INSERT INTO test_table VALUES (5), (6), (7), (8)"); - - // query it - sqc.new_query("SELECT * FROM test_table"); - sqc.execute_query(); - - // See the results - while (sqc.next_query_row()) { - std::cout << "Received: " << sqc.get_int(0) << std::endl; - } - - sqc.finish_query(); - - // Close the connection completely - sqc.disconnect(); - -} diff --git a/third_party_tools/client_drivers/cpp/index.rst b/third_party_tools/client_drivers/cpp/index.rst deleted file mode 100644 index fbbf6fb39..000000000 --- a/third_party_tools/client_drivers/cpp/index.rst +++ /dev/null @@ -1,87 +0,0 @@ -.. _cpp_native: - -************************* -C++ Driver -************************* - -The SQream DB C++ driver allows C++ programs and tools to connect to SQream DB. - -This tutorial shows how to write a C++ program that uses this driver. - -.. contents:: In this topic: - :depth: 2 - :local: - - -Installing the C++ driver -================================== - -Prerequisites ----------------- - -The SQream DB C++ driver was built on 64-bit Linux, and is designed to work with RHEL 7 and Ubuntu 16.04 and newer. - -Getting the library ---------------------- - -The C++ driver is provided as a tarball containing the compiled ``libsqream.so`` file and a header ``sqream.h``. Get the driver from the `SQream Drivers page `_. The library can be integrated into your C++-based applications or projects. - - -Extract the tarball archive ------------------------------ - -Extract the library files from the tarball - -.. code-block:: console - - $ tar xf libsqream-3.0.tar.gz - -Examples -============================================== - -Assuming there is a SQream DB worker to connect to, we'll connect to it using the application and run some statements. - -Testing the connection to SQream DB --------------------------------------------- - -Download this file by right clicking and saving to your computer :download:`connect_test.cpp `. - -.. literalinclude:: connect_test.cpp - :language: cpp - :caption: Connect to SQream DB - :linenos: - - -Compiling and running the application -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -To build this code, place the library and header file in ./libsqream-3.0/ and run - -.. code-block:: console - - $ g++ -Wall -Ilibsqream-3.0 -Llibsqream-3.0 -lsqream connect_test.cpp -o connect_test - $ ./connect_test - -Modify the ``-I`` and ``-L`` arguments to match the ``.so`` library and ``.h`` file if they are in another directory. - -Creating a table and inserting values --------------------------------------------- - -Download this file by right clicking and saving to your computer :download:`insert_test.cpp `. - -.. literalinclude:: insert_test.cpp - :language: cpp - :caption: Inserting data to a SQream DB table - :linenos: - - -Compiling and running the application -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -To build this code, use - -.. code-block:: console - - $ g++ -Wall -Ilibsqream-3.0 -Llibsqream-3.0 -lsqream insert_test.cpp -o insert_test - $ ./insert_test - diff --git a/third_party_tools/client_drivers/cpp/insert_test.cpp b/third_party_tools/client_drivers/cpp/insert_test.cpp deleted file mode 100644 index 8a16618a4..000000000 --- a/third_party_tools/client_drivers/cpp/insert_test.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// Insert with parameterized statement example - -#include - -#include "sqream.h" - -int main () { - - sqream::driver sqc; - - // Connection parameters: Hostname, Port, Use SSL, Username, Password, - // Database name, Service name - sqc.connect("127.0.0.1", 5000, false, "rhendricks", "Tr0ub4dor&3", - "raviga", "sqream"); - - run_direct_query(&sqc, - "CREATE TABLE animals (id INT NOT NULL, name VARCHAR(10) NOT NULL)"); - - // prepare the statement - sqc.new_query("INSERT INTO animals VALUES (?, ?)"); - sqc.execute_query(); - - // Data to insert - int row0[] = {1,2,3}; - std::string row1[] = {"Dog","Cat","Possum"}; - int len = sizeof(row0)/sizeof(row0[0]); - - for (int i = 0; i < len; ++i) { - sqc.set_int(0, row0[i]); - sqc.set_varchar(1, row1[i]); - sqc.next_query_row(); - } - - // This commits the insert - sqc.finish_query(); - - sqc.disconnect(); - -} diff --git a/third_party_tools/client_drivers/index.rst b/third_party_tools/client_drivers/index.rst index 2b486d47f..102827f22 100644 --- a/third_party_tools/client_drivers/index.rst +++ b/third_party_tools/client_drivers/index.rst @@ -20,23 +20,6 @@ The following are applicable to all operating systems: * `JDBC .jar file `_ - sqream-jdbc-4.5.3 (.jar) * `JDBC driver `_ - -.. _python: - -* **Python** - Recommended installation via ``pip``: - - * `Python .tar file `_ - pysqream v3.1.3 (.tar.gz) - * `Python driver `_ - - -.. _nodejs: - -* **Node.JS** - Recommended installation via ``npm``: - - * `Node.JS `_ - sqream-v4.2.4 (.tar.gz) - * `Node.JS driver `_ - - .. _tableau_connector: * **Tableau**: @@ -57,7 +40,7 @@ Windows -------------- The following are applicable to Windows: -* **ODBC installer** - SQream Drivers v2020.2.0, with Tableau customizations. Please contact your `Sqream represenative `_ for this installer. +* **ODBC installer** - SQream Drivers v2020.2.0, with Tableau customizations. Please contact your `SSream represenative `_ for this installer. For more information on installing and configuring ODBC on Windows, see :ref:`Install and configure ODBC on Windows `. @@ -82,11 +65,6 @@ The following are applicable to Linux: * ODBC Installer - Please contact your SQream representative for this installer. - :: - -* C++ connector - `libsqream-4.0 `_ -* `C++ shared object library `_ - .. toctree:: :maxdepth: 4 @@ -94,10 +72,7 @@ The following are applicable to Linux: :titlesonly: jdbc/index - python/index - nodejs/index odbc/index - cpp/index diff --git a/third_party_tools/client_drivers/nodejs/index.rst b/third_party_tools/client_drivers/nodejs/index.rst deleted file mode 100644 index cb7db193b..000000000 --- a/third_party_tools/client_drivers/nodejs/index.rst +++ /dev/null @@ -1,382 +0,0 @@ -.. _nodejs: - -************************* -Node.JS -************************* - -The SQream DB Node.JS driver allows Javascript applications and tools connect to SQream DB. -This tutorial shows you how to write a Node application using the Node.JS interface. - -The driver requires Node 10 or newer. - -.. contents:: In this topic: - :local: - -Installing the Node.JS driver -================================== - -Prerequisites ----------------- - -* Node.JS 10 or newer. Follow instructions at `nodejs.org `_ . - -Install with NPM -------------------- - -Installing with npm is the easiest and most reliable method. -If you need to install the driver in an offline system, see the offline method below. - -.. code-block:: console - - $ npm install @sqream/sqreamdb - -Install from an offline package -------------------------------------- - -The Node driver is provided as a tarball for download from the `SQream Drivers page `_ . - -After downloading the tarball, use ``npm`` to install the offline package. - -.. code-block:: console - - $ sudo npm install sqreamdb-4.0.0.tgz - - -Connect to SQream DB with a Node.JS application -==================================================== - -Create a simple test ------------------------------------------- - -Replace the connection parameters with real parameters for a SQream DB installation. - -.. code-block:: javascript - :caption: sqreamdb-test.js - - const Connection = require('@sqream/sqreamdb'); - - const config = { - host: 'localhost', - port: 3109, - username: 'rhendricks', - password: 'super_secret_password', - connectDatabase: 'raviga', - cluster: true, - is_ssl: true, - service: 'sqream' - }; - - const query1 = 'SELECT 1 AS test, 2*6 AS "dozen"'; - - const sqream = new Connection(config); - sqream.execute(query1).then((data) => { - console.log(data); - }, (err) => { - console.error(err); - }); - - -Run the test ----------------- - -A successful run should look like this: - -.. code-block:: console - - $ node sqreamdb-test.js - [ { test: 1, dozen: 12 } ] - - -API reference -==================== - -Connection parameters ---------------------------- - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Item - - Optional - - Default - - Description - * - ``host`` - - ✗ - - None - - Hostname for SQream DB worker. For example, ``127.0.0.1``, ``sqream.mynetwork.co`` - * - ``port`` - - ✗ - - None - - Port for SQream DB end-point. For example, ``3108`` for the load balancer, ``5000`` for a worker. - * - ``username`` - - ✗ - - None - - Username of a role to use for connection. For example, ``rhendricks`` - * - ``password`` - - ✗ - - None - - Specifies the password of the selected role. For example, ``Tr0ub4dor&3`` - * - ``connectDatabase`` - - ✗ - - None - - Database name to connect to. For example, ``master`` - * - ``service`` - - ✓ - - ``sqream`` - - Specifices service queue to use. For example, ``etl`` - * - ``is_ssl`` - - ✓ - - ``false`` - - Specifies SSL for this connection. For example, ``true`` - * - ``cluster`` - - ✓ - - ``false`` - - Connect via load balancer (use only if exists, and check port). For example, ``true`` - -Events -------------- - -The connector handles event returns with an event emitter - -getConnectionId - The ``getConnectionId`` event returns the executing connection ID. - -getStatementId - The ``getStatementId`` event returns the executing statement ID. - -getTypes - The ``getTypes`` event returns the results columns types. - -Example -^^^^^^^^^^^^^^^^^ - -.. code-block:: javascript - - const myConnection = new Connection(config); - - myConnection.runQuery(query1, function (err, data){ - myConnection.events.on('getConnectionId', function(data){ - console.log('getConnectionId', data); - }); - - myConnection.events.on('getStatementId', function(data){ - console.log('getStatementId', data); - }); - - myConnection.events.on('getTypes', function(data){ - console.log('getTypes', data); - }); - }); - -Input placeholders -------------------------- - -The Node.JS driver can replace parameters in a statement. - -Input placeholders allow values like user input to be passed as parameters into queries, with proper escaping. - -The valid placeholder formats are provided in the table below. - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Placeholder - - Type - * - ``%i`` - - Identifier (e.g. table name, column name) - * - ``%s`` - - A text string - * - ``%d`` - - A number value - * - ``%b`` - - A boolean value - -See the :ref:`input placeholders example` below. - -Examples -=============== - -Setting configuration flags ------------------------------------ - -SQream DB configuration flags can be set per statement, as a parameter to ``runQuery``. - -For example: - -.. code-block:: javascript - - const setFlag = 'SET showfullexceptioninfo = true;'; - - const query_string = 'SELECT 1'; - - const myConnection = new Connection(config); - myConnection.runQuery(query_string, function (err, data){ - console.log(err, data); - }, setFlag); - - -Lazyloading ------------------------------------ - -To process rows without keeping them in memory, you can lazyload the rows with an async: - -.. code-block:: javascript - - - const Connection = require('@sqream/sqreamdb'); - - const config = { - host: 'localhost', - port: 3109, - username: 'rhendricks', - password: 'super_secret_password', - connectDatabase: 'raviga', - cluster: true, - is_ssl: true, - service: 'sqream' - }; - - const sqream = new Connection(config); - - const query = "SELECT * FROM public.a_very_large_table"; - - (async () => { - const cursor = await sqream.executeCursor(query); - let count = 0; - for await (let rows of cursor.fetchIterator(100)) { - // fetch rows in chunks of 100 - count += rows.length; - } - await cursor.close(); - return count; - })().then((total) => { - console.log('Total rows', total); - }, (err) => { - console.error(err); - }); - - -Reusing a connection ------------------------------------ - -It is possible to execeute multiple queries with the same connection (although only one query can be executed at a time). - -.. code-block:: javascript - - const Connection = require('@sqream/sqreamdb'); - - const config = { - host: 'localhost', - port: 3109, - username: 'rhendricks', - password: 'super_secret_password', - connectDatabase: 'raviga', - cluster: true, - is_ssl: true, - service: 'sqream' - }; - - const sqream = new Connection(config); - - (async () => { - - const conn = await sqream.connect(); - try { - const res1 = await conn.execute("SELECT 1"); - const res2 = await conn.execute("SELECT 2"); - const res3 = await conn.execute("SELECT 3"); - conn.disconnect(); - return {res1, res2, res3}; - } catch (err) { - conn.disconnect(); - throw err; - } - - })().then((res) => { - console.log('Results', res) - }, (err) => { - console.error(err); - }); - - -.. _input_placeholders_example: - -Using placeholders in queries ------------------------------------ - -Input placeholders allow values like user input to be passed as parameters into queries, with proper escaping. - -.. code-block:: javascript - - const Connection = require('@sqream/sqreamdb'); - - const config = { - host: 'localhost', - port: 3109, - username: 'rhendricks', - password: 'super_secret_password', - connectDatabase: 'raviga', - cluster: true, - is_ssl: true, - service: 'sqream' - }; - - const sqream = new Connection(config); - - const sql = "SELECT %i FROM public.%i WHERE name = %s AND num > %d AND active = %b"; - - sqream.execute(sql, "col1", "table2", "john's", 50, true); - - -The query that will run is ``SELECT col1 FROM public.table2 WHERE name = 'john''s' AND num > 50 AND active = true`` - - -Troubleshooting and recommended configuration -================================================ - - -Preventing ``heap out of memory`` errors --------------------------------------------- - -Some workloads may cause Node.JS to fail with the error: - -.. code-block:: none - - FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory - -To prevent this error, modify the heap size configuration by setting the ``--max-old-space-size`` run flag. - -For example, set the space size to 2GB: - -.. code-block:: console - - $ node --max-old-space-size=2048 my-application.js - -BIGINT support ------------------------- - -The Node.JS connector supports fetching ``BIGINT`` values from SQream DB. However, some applications may encounter an error when trying to serialize those values. - -The error that appears is: -.. code-block:: none - - TypeError: Do not know how to serialize a BigInt - -This is because JSON specification do not support BIGINT values, even when supported by Javascript engines. - -To resolve this issue, objects with BIGINT values should be converted to string before serializing, and converted back after deserializing. - -For example: - -.. code-block:: javascript - - const rows = [{test: 1n}] - const json = JSON.stringify(rows, , (key, value) => - typeof value === 'bigint' - ? value.toString() - : value // return everything else unchanged - )); - console.log(json); // [{"test": "1"}] - diff --git a/third_party_tools/client_drivers/nodejs/sample.js b/third_party_tools/client_drivers/nodejs/sample.js deleted file mode 100644 index a8ec3db66..000000000 --- a/third_party_tools/client_drivers/nodejs/sample.js +++ /dev/null @@ -1,21 +0,0 @@ -const Connection = require('@sqream/sqreamdb'); - -const config = { - host: 'localhost', - port: 3109, - username: 'rhendricks', - password: 'super_secret_password', - connectDatabase: 'raviga', - cluster: true, - is_ssl: true, - service: 'sqream' - }; - -const query1 = 'SELECT 1 AS test, 2*6 AS "dozen"'; - -const sqream = new Connection(config); -sqream.execute(query1).then((data) => { - console.log(data); -}, (err) => { - console.error(err); -}); \ No newline at end of file diff --git a/third_party_tools/client_drivers/python/api-reference.rst b/third_party_tools/client_drivers/python/api-reference.rst deleted file mode 100644 index 28e1205e6..000000000 --- a/third_party_tools/client_drivers/python/api-reference.rst +++ /dev/null @@ -1,191 +0,0 @@ -.. _pysqream_api_reference: - -************************* -pysqream API reference -************************* - -The SQream Python connector allows Python programs to connect to SQream DB. - -pysqream conforms to Python DB-API specifications `PEP-249 `_ - - -The main module is pysqream, which contains the :py:meth:`Connection` class. - -.. method:: connect(host, port, database, username, password, clustered = False, use_ssl = False, service='sqream', reconnect_attempts=3, reconnect_interval=10) - - Creates a new :py:meth:`Connection` object and connects to SQream DB. - - host - SQream DB hostname or IP - - port - SQream DB port - - database - database name - - username - Username to use for connection - - password - Password for ``username`` - - clustered - Connect through load balancer, or direct to worker (Default: false - direct to worker) - - use_ssl - use SSL connection (default: false) - - service - Optional service queue (default: 'sqream') - - reconnect_attempts - Number of reconnection attempts to attempt before closing the connection - - reconnect_interval - Time in seconds between each reconnection attempt - -.. class:: Connection - - .. attribute:: arraysize - - Specifies the number of rows to fetch at a time with :py:meth:`~Connection.fetchmany`. Defaults to 1 - one row at a time. - - .. attribute:: rowcount - - Unused, always returns -1. - - .. attribute:: description - - Read-only attribute that contains result set metadata. - - This attribute is populated after a statement is executed. - - .. list-table:: - :widths: auto - :header-rows: 1 - - * - Value - - Description - * - ``name`` - - Column name - * - ``type_code`` - - Internal type code - * - ``display_size`` - - Not used - same as ``internal_size`` - * - ``internal_size`` - - Data size in bytes - * - ``precision`` - - Precision of numeric data (not used) - * - ``scale`` - - Scale for numeric data (not used) - * - ``null_ok`` - - Specifies if ``NULL`` values are allowed for this column - - .. method:: execute(self, query, params=None) - - Execute a statement. - - Parameters are not supported - - self - :py:meth:`Connection` - - query - statement or query text - - params - Unused - - .. method:: executemany(self, query, rows_or_cols=None, data_as='rows', amount=None) - - Prepares a statement and executes it against all parameter sequences found in ``rows_or_cols``. - - self - :py:meth:`Connection` - - query - INSERT statement - - rows_or_cols - Data buffer to insert. This should be a sequence of lists or tuples. - - data_as - (Optional) Read data as rows or columns - - amount - (Optional) count of rows to insert - - .. method:: close(self) - - Close a statement and connection. - After a statement is closed, it must be reopened by creating a new cursor. - - self - :py:meth:`Connection` - - .. method:: cursor(self) - - Create a new :py:meth:`Connection` cursor. - - We recommend creating a new cursor for every statement. - - self - :py:meth:`Connection` - - .. method:: fetchall(self, data_as='rows') - - Fetch all remaining records from the result set. - - An empty sequence is returned when no more rows are available. - - self - :py:meth:`Connection` - - data_as - (Optional) Read data as rows or columns - - .. method:: fetchone(self, data_as='rows') - - Fetch one record from the result set. - - An empty sequence is returned when no more rows are available. - - self - :py:meth:`Connection` - - data_as - (Optional) Read data as rows or columns - - - .. method:: fetchmany(self, size=[Connection.arraysize], data_as='rows') - - Fetches the next several rows of a query result set. - - An empty sequence is returned when no more rows are available. - - self - :py:meth:`Connection` - - size - Number of records to fetch. If not set, fetches :py:obj:`Connection.arraysize` (1 by default) records - - data_as - (Optional) Read data as rows or columns - - .. method:: __iter__() - - Makes the cursor iterable. - - -.. attribute:: apilevel = '2.0' - - String constant stating the supported API level. The connector supports API "2.0". - -.. attribute:: threadsafety = 1 - - Level of thread safety the interface supports. pysqream currently supports level 1, which states that threads can share the module, but not connections. - -.. attribute:: paramstyle = 'qmark' - - The placeholder marker. Set to ``qmark``, which is a question mark (``?``). diff --git a/third_party_tools/client_drivers/python/index.rst b/third_party_tools/client_drivers/python/index.rst deleted file mode 100644 index 1c69752d7..000000000 --- a/third_party_tools/client_drivers/python/index.rst +++ /dev/null @@ -1,502 +0,0 @@ -.. _pysqream: - -************************* -Python (pysqream) -************************* - -The SQream Python connector is a set of packages that allows Python programs to connect to SQream DB. - -* ``pysqream`` is a pure Python connector. It can be installed with ``pip`` on any operating system, including Linux, Windows, and macOS. - -* ``pysqream-sqlalchemy`` is a SQLAlchemy dialect for ``pysqream`` - -The connector supports Python 3.6.5 and newer. - -The base ``pysqream`` package conforms to Python DB-API specifications `PEP-249 `_. - -.. contents:: In this topic: - :local: - -Installing the Python connector -================================== - -Prerequisites ----------------- - -1. Python -^^^^^^^^^^^^ - -The connector requires Python 3.6.5 or newer. To verify your version of Python: - -.. code-block:: console - - $ python --version - Python 3.7.3 - - -.. note:: If both Python 2.x and 3.x are installed, you can run ``python3`` and ``pip3`` instead of ``python`` and ``pip`` respectively for the rest of this guide - -.. warning:: If you're running on an older version, ``pip`` will fetch an older version of ``pysqream``, with version <3.0.0. This version is currently not supported. - -2. PIP -^^^^^^^^^^^^ -The Python connector is installed via ``pip``, the Python package manager and installer. - -We recommend upgrading to the latest version of ``pip`` before installing. To verify that you are on the latest version, run the following command: - -.. code-block:: console - - $ python -m pip install --upgrade pip - Collecting pip - Downloading https://files.pythonhosted.org/packages/00/b6/9cfa56b4081ad13874b0c6f96af8ce16cfbc1cb06bedf8e9164ce5551ec1/pip-19.3.1-py2.py3-none-any.whl (1.4MB) - |████████████████████████████████| 1.4MB 1.6MB/s - Installing collected packages: pip - Found existing installation: pip 19.1.1 - Uninstalling pip-19.1.1: - Successfully uninstalled pip-19.1.1 - Successfully installed pip-19.3.1 - -.. note:: - * On macOS, you may want to use virtualenv to install Python and the connector, to ensure compatibility with the built-in Python environment - * If you encounter an error including ``SSLError`` or ``WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.`` - please be sure to reinstall Python with SSL enabled, or use virtualenv or Anaconda. - -3. OpenSSL for Linux -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Some distributions of Python do not include OpenSSL. The Python connector relies on OpenSSL for secure connections to SQream DB. - -* To install OpenSSL on RHEL/CentOS - - .. code-block:: console - - $ sudo yum install -y libffi-devel openssl-devel - -* To install OpenSSL on Ubuntu - - .. code-block:: console - - $ sudo apt-get install libssl-dev libffi-dev -y - -4. Cython (optional) -^^^^^^^^^^^^^^^^^^^^^^^^ - -Optional but highly recommended is Cython, which improves performance of Python applications. - - .. code-block:: console - - $ pip install cython - -Install via pip ------------------ - -The Python connector is available via `PyPi `_. - -Install the connector with ``pip``: - -.. code-block:: console - - $ pip install pysqream pysqream-sqlalchemy - -``pip`` will automatically install all necessary libraries and modules. - -Upgrading an existing installation --------------------------------------- - -The Python drivers are updated periodically. -To upgrade an existing pysqream installation, use pip's ``-U`` flag. - -.. code-block:: console - - $ pip install pysqream pysqream-sqlalchemy -U - - -Validate the installation ------------------------------ - -Create a file called ``test.py``, containing the following: - -.. literalinclude:: test.py - :language: python - :caption: pysqream Validation Script - :linenos: - -Make sure to replace the parameters in the connection with the respective parameters for your SQream DB installation. - -Run the test file to verify that you can connect to SQream DB: - -.. code-block:: console - - $ python test.py - Version: v2020.1 - -If all went well, you are now ready to build an application using the SQream DB Python connector! - -If any connection error appears, verify that you have access to a running SQream DB and that the connection parameters are correct. - -SQLAlchemy examples -======================== - -SQLAlchemy is an ORM for Python. - -When you install the SQream DB dialect (``pysqream-sqlalchemy``) you can use frameworks like Pandas, TensorFlow, and Alembic to query SQream DB directly. - -A simple connection example ---------------------------------- - -.. code-block:: python - - import sqlalchemy as sa - from sqlalchemy.engine.url import URL - - engine_url = URL('sqream' - , username='rhendricks' - , password='secret_passwor" - , host='localhost' - , port=5000 - , database='raviga' - , query={'use_ssl': False}) - - engine = sa.create_engine(engine_url) - - res = engine.execute('create table test (ints int)') - res = engine.execute('insert into test values (5), (6)') - res = engine.execute('select * from test') - -Pulling a table into Pandas ---------------------------------- - -In this example, we use the URL method to create the connection string. - -.. code-block:: python - - import sqlalchemy as sa - import pandas as pd - from sqlalchemy.engine.url import URL - - - engine_url = URL('sqream' - , username='rhendricks' - , password='secret_passwor" - , host='localhost' - , port=5000 - , database='raviga' - , query={'use_ssl': False}) - - engine = sa.create_engine(engine_url) - - table_df = pd.read_sql("select * from nba", con=engine) - - -API Examples -=============== - -Explaining the connection example ---------------------------------------- - -First, import the package and create a connection - -.. code-block:: python - - # Import pysqream package - - import pysqream - - """ - Connection parameters include: - * IP/Hostname - * Port - * database name - * username - * password - * Connect through load balancer, or direct to worker (Default: false - direct to worker) - * use SSL connection (default: false) - * Optional service queue (default: 'sqream') - """ - - # Create a connection object - - con = pysqream.connect(host='127.0.0.1', port=3108, database='raviga' - , username='rhendricks', password='Tr0ub4dor&3' - , clustered=True) - -Then, run a query and fetch the results - -.. code-block:: python - - cur = con.cursor() # Create a new cursor - # Prepare and execute a query - cur.execute('select show_version()') - - result = cur.fetchall() # `fetchall` gets the entire data set - - print (f"Version: {result[0][0]}") - -This should print the SQream DB version. For example ``v2020.1``. - -Finally, we will close the connection - -.. code-block:: python - - con.close() - -Using the cursor --------------------------------------------- - -The DB-API specification includes several methods for fetching results from the cursor. - -We will use the ``nba`` example. Here's a peek at the table contents: - -.. csv-table:: nba - :file: nba-t10.csv - :widths: auto - :header-rows: 1 - -Like before, we will import the library and create a :py:meth:`~Connection`, followed by :py:meth:`~Connection.execute` on a simple ``SELECT *`` query. - -.. code-block:: python - - import pysqream - con = pysqream.connect(host='127.0.0.1', port=3108, database='master' - , username='rhendricks', password='Tr0ub4dor&3' - , clustered=True) - - cur = con.cursor() # Create a new cursor - # The select statement: - statement = 'SELECT * FROM nba' - cur.execute(statement) - -After executing the statement, we have a :py:meth:`Connection` cursor object waiting. A cursor is iterable, meaning that everytime we fetch, it advances the cursor to the next row. - -Use :py:meth:`~Connection.fetchone` to get one record at a time: - -.. code-block:: python - - first_row = cur.fetchone() # Fetch one row at a time (first row) - - second_row = cur.fetchone() # Fetch one row at a time (second row) - -To get several rows at a time, use :py:meth:`~Connection.fetchmany`: - -.. code-block:: python - - # executing `fetchone` twice is equivalent to this form: - third_and_fourth_rows = cur.fetchmany(2) - -To get all rows at once, use :py:meth:`~Connection.fetchall`: - -.. code-block:: python - - # To get all rows at once, use `fetchall` - remaining_rows = cur.fetchall() - - # Close the connection when done - con.close() - -Here are the contents of the row variables we used: - -.. code-block:: pycon - - >>> print(first_row) - ('Avery Bradley', 'Boston Celtics', 0, 'PG', 25, '6-2', 180, 'Texas', 7730337) - >>> print(second_row) - ('Jae Crowder', 'Boston Celtics', 99, 'SF', 25, '6-6', 235, 'Marquette', 6796117) - >>> print(third_and_fourth_rows) - [('John Holland', 'Boston Celtics', 30, 'SG', 27, '6-5', 205, 'Boston University', None), ('R.J. Hunter', 'Boston Celtics', 28, 'SG', 22, '6-5', 185, 'Georgia State', 1148640)] - >>> print(remaining_rows) - [('Jonas Jerebko', 'Boston Celtics', 8, 'PF', 29, '6-10', 231, None, 5000000), ('Amir Johnson', 'Boston Celtics', 90, 'PF', 29, '6-9', 240, None, 12000000), ('Jordan Mickey', 'Boston Celtics', 55, 'PF', 21, '6-8', 235, 'LSU', 1170960), ('Kelly Olynyk', 'Boston Celtics', 41, 'C', 25, '7-0', 238, 'Gonzaga', 2165160), - [...] - -.. note:: Calling a fetch command after all rows have been fetched will return an empty array (``[]``). - -Reading result metadata ----------------------------- - -When executing a statement, the connection object also contains metadata about the result set (e.g.column names, types, etc). - -The metadata is stored in the :py:attr:`Connection.description` object of the cursor. - -.. code-block:: pycon - - >>> import pysqream - >>> con = pysqream.connect(host='127.0.0.1', port=3108, database='master' - ... , username='rhendricks', password='Tr0ub4dor&3' - ... , clustered=True) - >>> cur = con.cursor() - >>> statement = 'SELECT * FROM nba' - >>> cur.execute(statement) - - >>> print(cur.description) - [('Name', 'STRING', 24, 24, None, None, True), ('Team', 'STRING', 22, 22, None, None, True), ('Number', 'NUMBER', 1, 1, None, None, True), ('Position', 'STRING', 2, 2, None, None, True), ('Age (as of 2018)', 'NUMBER', 1, 1, None, None, True), ('Height', 'STRING', 4, 4, None, None, True), ('Weight', 'NUMBER', 2, 2, None, None, True), ('College', 'STRING', 21, 21, None, None, True), ('Salary', 'NUMBER', 4, 4, None, None, True)] - -To get a list of column names, iterate over the ``description`` list: - -.. code-block:: pycon - - >>> [ i[0] for i in cur.description ] - ['Name', 'Team', 'Number', 'Position', 'Age (as of 2018)', 'Height', 'Weight', 'College', 'Salary'] - -Loading data into a table ---------------------------- - -This example loads 10,000 rows of dummy data to a SQream DB instance - -.. code-block:: python - - import pysqream - from datetime import date, datetime - from time import time - - con = pysqream.connect(host='127.0.0.1', port=3108, database='master' - , username='rhendricks', password='Tr0ub4dor&3' - , clustered=True) - - # Create a table for loading - create = 'create or replace table perf (b bool, t tinyint, sm smallint, i int, bi bigint, f real, d double, s varchar(12), ss text, dt date, dtt datetime)' - con.execute(create) - - # After creating the table, we can load data into it with the INSERT command - - # Create dummy data which matches the table we created - data = (False, 2, 12, 145, 84124234, 3.141, -4.3, "Marty McFly" , u"キウイは楽しい鳥です" , date(2019, 12, 17), datetime(1955, 11, 4, 1, 23, 0, 0)) - - - row_count = 10**4 - - # Get a new cursor - cur = con.cursor() - insert = 'insert into perf values (?,?,?,?,?,?,?,?,?,?,?)' - start = time() - cur.executemany(insert, [data] * row_count) - print (f"Total insert time for {row_count} rows: {time() - start} seconds") - - # Close this cursor - cur.close() - - # Verify that the data was inserted correctly - # Get a new cursor - cur = con.cursor() - cur.execute('select count(*) from perf') - result = cur.fetchall() # `fetchall` collects the entire data set - print (f"Count of inserted rows: {result[0][0]}") - - # When done, close the cursor - cur.close() - - # Close the connection - con.close() - -Reading data from a CSV file for load into a table ----------------------------------------------------------- - -We will write a helper function to create an :ref:`insert` statement, by reading an existing table's metadata. - -.. code-block:: python - - import pysqream - import datetime - - def insert_from_csv(cur, table_name, csv_filename, field_delimiter = ',', null_markers = []): - """ - We will first ask SQream DB for some table information. - This is important for understanding the number of columns, and will help - to create a matching INSERT statement - """ - - column_info = cur.execute(f"SELECT * FROM {table_name} LIMIT 0").description - - - def parse_datetime(v): - try: - return datetime.datetime.strptime(row[i], '%Y-%m-%d %H:%M:%S.%f') - except ValueError: - try: - return datetime.datetime.strptime(row[i], '%Y-%m-%d %H:%M:%S') - except ValueError: - return datetime.datetime.strptime(row[i], '%Y-%m-%d') - - # Create enough placeholders (`?`) for the INSERT query string - qstring = ','.join(['?'] * len(column_info)) - insert_statement = f"insert into {table_name} values ({qstring})" - - # Open the CSV file - with open(csv_filename, mode='r') as csv_file: - csv_reader = csv.reader(csv_file, delimiter=field_delimiter) - - # Execute the INSERT statement with the CSV data - cur.executemany(insert_statement, [row for row in csv_reader]) - - - con = pysqream.connect(host='127.0.0.1', port=3108, database='master' - , username='rhendricks', password='Tr0ub4dor&3' - , clustered=True) - - cur = con.cursor() - insert_from_csv(cur, 'nba', 'nba.csv', field_delimiter = ',', null_markers = []) - - con.close() - - -Using SQLAlchemy ORM to create tables and fill them with data ------------------------------------------------------------------------ - -You can also use the ORM to create tables and insert data to them from Python objects. - -For example: - -.. code-block:: python - - import sqlalchemy as sa - import pandas as pd - from sqlalchemy.engine.url import URL - - - engine_url = URL('sqream' - , username='rhendricks' - , password='secret_passwor" - , host='localhost' - , port=5000 - , database='raviga' - , query={'use_ssl': False}) - - engine = sa.create_engine(engine_url) - - # Build a metadata object and bind it - - metadata = sa.MetaData() - metadata.bind = engine - - # Create a table in the local metadata - - employees = sa.Table( - 'employees' - , metadata - , sa.Column('id', sa.Integer) - , sa.Column('name', sa.VARCHAR(32)) - , sa.Column('lastname', sa.VARCHAR(32)) - , sa.Column('salary', sa.Float) - ) - - # The create_all() function uses the SQream DB engine object - # to create all the defined table objects. - - metadata.create_all(engine) - - # Now that the table exists, we can insert data into it. - - # Build the data rows - insert_data = [ {'id': 1, 'name': 'Richard','lastname': 'Hendricks', 'salary': 12000.75} - ,{'id': 3, 'name': 'Bertram', 'lastname': 'Gilfoyle', 'salary': 8400.0} - ,{'id': 8, 'name': 'Donald', 'lastname': 'Dunn', 'salary': 6500.40} - ] - - # Build the insert command - ins = employees.insert(insert_data) - - # Execute the command - result = engine.execute(ins) - -.. toctree:: - :maxdepth: 8 - :caption: Further information - - api-reference diff --git a/third_party_tools/client_drivers/python/nba-t10.csv b/third_party_tools/client_drivers/python/nba-t10.csv deleted file mode 100644 index fe9ced442..000000000 --- a/third_party_tools/client_drivers/python/nba-t10.csv +++ /dev/null @@ -1,10 +0,0 @@ -Name,Team,Number,Position,Age,Height,Weight,College,Salary -Avery Bradley,Boston Celtics,0.0,PG,25.0,6-2,180.0,Texas,7730337.0 -Jae Crowder,Boston Celtics,99.0,SF,25.0,6-6,235.0,Marquette,6796117.0 -John Holland,Boston Celtics,30.0,SG,27.0,6-5,205.0,Boston University, -R.J. Hunter,Boston Celtics,28.0,SG,22.0,6-5,185.0,Georgia State,1148640.0 -Jonas Jerebko,Boston Celtics,8.0,PF,29.0,6-10,231.0,,5000000.0 -Amir Johnson,Boston Celtics,90.0,PF,29.0,6-9,240.0,,12000000.0 -Jordan Mickey,Boston Celtics,55.0,PF,21.0,6-8,235.0,LSU,1170960.0 -Kelly Olynyk,Boston Celtics,41.0,C,25.0,7-0,238.0,Gonzaga,2165160.0 -Terry Rozier,Boston Celtics,12.0,PG,22.0,6-2,190.0,Louisville,1824360.0 diff --git a/third_party_tools/client_drivers/python/test.py b/third_party_tools/client_drivers/python/test.py deleted file mode 100644 index 51d0b4a92..000000000 --- a/third_party_tools/client_drivers/python/test.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python - -import pysqream - -""" -Connection parameters include: -* IP/Hostname -* Port -* database name -* username -* password -* Connect through load balancer, or direct to worker (Default: false - direct to worker) -* use SSL connection (default: false) -* Optional service queue (default: 'sqream') -""" - -# Create a connection object - -con = pysqream.connect(host='127.0.0.1', port=5000, database='master' - , username='sqream', password='sqream' - , clustered=False) - -# Create a new cursor -cur = con.cursor() - -# Prepare and execute a query -cur.execute('select show_version()') - -result = cur.fetchall() # `fetchall` gets the entire data set - -print (f"Version: {result[0][0]}") - -# This should print the SQream DB version. For example ``Version: v2020.1``. - -# Finally, close the connection - -con.close() \ No newline at end of file diff --git a/third_party_tools/client_platforms/connect.sas b/third_party_tools/client_platforms/connect.sas deleted file mode 100644 index 78c670762..000000000 --- a/third_party_tools/client_platforms/connect.sas +++ /dev/null @@ -1,27 +0,0 @@ -options sastrace='d,d,d,d' -sastraceloc=saslog -nostsuffix -msglevel=i -sql_ip_trace=(note,source) -DEBUG=DBMS_SELECT; - -options validvarname=any; - -libname sqlib jdbc driver="com.sqream.jdbc.SQDriver" - classpath="/opt/sqream/sqream-jdbc-4.0.0.jar" - URL="jdbc:Sqream://sqream-cluster.piedpiper.com:3108/raviga;cluster=true" - user="rhendricks" - password="Tr0ub4dor3" - schema="public" - PRESERVE_TAB_NAMES=YES - PRESERVE_COL_NAMES=YES; - -proc sql; - title 'Customers table'; - select * - from sqlib.customers; -quit; - -data sqlib.customers; - set sqlib.customers; -run; \ No newline at end of file diff --git a/third_party_tools/client_platforms/connect2.sas b/third_party_tools/client_platforms/connect2.sas deleted file mode 100644 index 10fcdb0a2..000000000 --- a/third_party_tools/client_platforms/connect2.sas +++ /dev/null @@ -1,27 +0,0 @@ -options sastrace='d,d,d,d' -sastraceloc=saslog -nostsuffix -msglevel=i -sql_ip_trace=(note,source) -DEBUG=DBMS_SELECT; - -options validvarname=any; - -libname sqlib jdbc driver="com.sqream.jdbc.SQDriver" - classpath="/opt/sqream/sqream-jdbc-4.0.0.jar" - URL="jdbc:Sqream://sqream-cluster.piedpiper.com:3108/raviga;cluster=true" - user="rhendricks" - password="Tr0ub4dor3" - schema="public" - PRESERVE_TAB_NAMES=YES - PRESERVE_COL_NAMES=YES; - -proc sql; - title 'Customers table'; - select * - from sqlib.customers; -quit; - -data sqlib.customers; - set sqlib.customers; -run; \ No newline at end of file diff --git a/third_party_tools/client_platforms/connect3.sas b/third_party_tools/client_platforms/connect3.sas deleted file mode 100644 index c1bf11dcf..000000000 --- a/third_party_tools/client_platforms/connect3.sas +++ /dev/null @@ -1,17 +0,0 @@ -options sastrace='d,d,d,d' -sastraceloc=saslog -nostsuffix -msglevel=i -sql_ip_trace=(note,source) -DEBUG=DBMS_SELECT; - -options validvarname=any; - -libname sqlib jdbc driver="com.sqream.jdbc.SQDriver" - classpath="/opt/sqream/sqream-jdbc-4.0.0.jar" - URL="jdbc:Sqream://sqream-cluster.piedpiper.com:3108/raviga;cluster=true" - user="rhendricks" - password="Tr0ub4dor3" - schema="public" - PRESERVE_TAB_NAMES=YES - PRESERVE_COL_NAMES=YES; \ No newline at end of file diff --git a/third_party_tools/client_platforms/index.rst b/third_party_tools/client_platforms/index.rst deleted file mode 100644 index 30280c788..000000000 --- a/third_party_tools/client_platforms/index.rst +++ /dev/null @@ -1,37 +0,0 @@ -.. _client_platforms: - -************************************ -Client Platforms -************************************ -These topics explain how to install and connect a variety of third party tools. - -Browse the articles below, in the sidebar, or use the search to find the information you need. - -Overview -========== - -SQream DB is designed to work with most common database tools and interfaces, allowing you direct access through a variety of drivers, connectors, tools, vizualisers, and utilities. - -The tools listed have been tested and approved for use with SQream DB. Most 3\ :sup:`rd` party tools that work through JDBC, ODBC, and Python should work. - -If you are looking for a tool that is not listed, SQream and our partners can help. Go to `SQream Support `_ or contact your SQream account manager for more information. - -.. toctree:: - :maxdepth: 4 - :caption: In this section: - :titlesonly: - - power_bi - tibco_spotfire - sas_viya - sql_workbench - tableau - pentaho - microstrategy - informatica - r - php - xxtalend - xxdiagnosing_common_connectivity_issues - -.. image:: /_static/images/connectivity_ecosystem.png \ No newline at end of file diff --git a/third_party_tools/client_platforms/informatica.rst b/third_party_tools/client_platforms/informatica.rst deleted file mode 100644 index 6bc50b22a..000000000 --- a/third_party_tools/client_platforms/informatica.rst +++ /dev/null @@ -1,173 +0,0 @@ -.. _informatica: - -************************* -Connect to SQream Using Informatica Cloud Services -************************* - -Overview -========= -The **Connecting to SQream Using Informatica Cloud Services** page is quick start guide for connecting to SQream using Informatica cloud services. - -It describes the following: - -.. contents:: - :local: - -Establishing a Connection between SQream and Informatica ------------------ -The **Establishing a Connection between SQream and Informatica** page describes how to establish a connection between SQream and the Informatica data integration Cloud. - -**To establish a connection between SQream and the Informatica data integration Cloud:** - -1. Go to the `Informatica Cloud homepage `_. - - :: - -2. Do one of the following: - - 1. Log in using your credentials. - - :: - - 2. Log in using your SAML Identity Provider. - -3. From the **Services** window, select **Administrator** or click **Show all services** to show all services. - - - The SQream dashboard is displayed. - - - :: - - -4. In the menu on the left, click **Runtime Environments**. - - - The **Runtime Environments** panel is displayed. - - :: - -5. Click **Download Secure Agent**. - - :: - -6. When the **Download the Secure Agent** panel is displayed, do the following: - - 1. Select a platform (Windows 64 or Linux 64). - - :: - - - 2. Click **Copy** and save the token on your local hard drive. - - The token is used in combination with your user name to authorize the agent to access your account. - - -7. Click **Download**. - - The installation begins. - - :: - -8. When the **Informatica Cloud Secure Agent Setup** panel is displayed, click **Next**. - - - :: - - -9. Provide your **User Name** and **Install Token** and click **Register**. - - :: - - - -10. From the Runtime Environments panel, click **New Runtime Environment**. - - - The **New Secure Agent Group** window is displayed. - - :: - -11. On the New Secure Agent Group window, click **OK** to connect your Runtime Environment with the running agent. - - .. note:: If you do not download Secure Agent, you will not be able to connect your Runtime Environment with the running agent and continue establishing a connection between SQream and the Informatica data integration Cloud. - -Establishing a Connection In Your Environment ------------------ - -The **Establishing a Connection In Your Environment** describes the following: - -.. contents:: - :local: - -Establishing an ODBC DSN Connection In Your Environment -~~~~~~~~~~~~~ -After establishing a connection between SQream and Informatica you can establish an ODBC DSN connection in your environment. - -**To establish an ODBC connection in your environment:** - -1. Click **Add**. - - :: - -2. Click **Configure**. - - .. note:: Verify that **Use Server Picker** is selected. - -3. Click **Test**. - - :: - -4. Verify that the connection has tested successfully. - - :: - -5. Click **Save**. - - :: - -6. Click **Actions** > **Publish**. - -Establishing a JDBC Connection In Your Environment -~~~~~~~~~~~~~ -After establishing a connection between SQream and Informatica you can establish a JDBC connection in your environment. - -**To establish a JDBC connection in your environment:** - -1. Create a new DB connection by clicking **Connections** > **New Connection**. - - The **New Connection** window is displayed. - - :: - - -2. In the **JDBC_IC Connection Properties** section, in the **JDBC Connection URL** field, establish a JDBC connection by providing the correct connection string. - - For connection string examples, see `Connection Strings `_. - - :: - -3. Click **Test**. - - :: - -4. Verify that the connection has tested successfully. - - :: - -5. Click **Save**. - - :: - -6. Click **Actions** > **Publish**. - -Supported SQream Driver Versions ---------------- - -SQream supports the following SQream driver versions: - -* **JDBC** - Version 4.3.4 and above. - - :: - -* **ODBC** - Version 4.0.0 and above. diff --git a/third_party_tools/client_platforms/microstrategy.rst b/third_party_tools/client_platforms/microstrategy.rst deleted file mode 100644 index 6d2be281f..000000000 --- a/third_party_tools/client_platforms/microstrategy.rst +++ /dev/null @@ -1,185 +0,0 @@ -.. _microstrategy: - - -************************* -Connect to SQream Using MicroStrategy -************************* - -.. _ms_top: - -Overview ---------------- -This document is a Quick Start Guide that describes how to install MicroStrategy and connect a datasource to the MicroStrategy dasbhoard for analysis. - - - -The **Connecting to SQream Using MicroStrategy** page describes the following: - - -.. contents:: - :local: - - - - - - -What is MicroStrategy? -================ -MicroStrategy is a Business Intelligence software offering a wide variety of data analytics capabilities. SQream uses the MicroStrategy connector for reading and loading data into SQream. - -MicroStrategy provides the following: - -* Data discovery -* Advanced analytics -* Data visualization -* Embedded BI -* Banded reports and statements - - -For more information about Microstrategy, see `MicroStrategy `_. - - - -:ref:`Back to Overview ` - - - - - -Connecting a Data Source -======================= - -1. Activate the **MicroStrategy Desktop** app. The app displays the Dossiers panel to the right. - - :: - -2. Download the most current version of the `SQream JDBC driver `_. - - :: - -3. Click **Dossiers** and **New Dossier**. The **Untitled Dossier** panel is displayed. - - :: - -4. Click **New Data**. - - :: - -5. From the **Data Sources** panel, select **Databases** to access data from tables. The **Select Import Options** panel is displayed. - - :: - -6. Select one of the following: - - * Build a Query - * Type a Query - * Select Tables - - :: - -7. Click **Next**. - - :: - -8. In the Data Source panel, do the following: - - 1. From the **Database** dropdown menu, select **Generic**. The **Host Name**, **Port Number**, and **Database Name** fields are removed from the panel. - - :: - - 2. In the **Version** dropdown menu, verify that **Generic DBMS** is selected. - - :: - - 3. Click **Show Connection String**. - - :: - - 4. Select the **Edit connection string** checkbox. - - :: - - 5. From the **Driver** dropdown menu, select a driver for one of the following connectors: - - * **JDBC** - The SQream driver is not integrated with MicroStrategy and does not appear in the dropdown menu. However, to proceed, you must select an item, and in the next step you must specify the path to the SQream driver that you installed on your machine. - * **ODBC** - SQreamDB ODBC - - :: - - 6. In the **Connection String** text box, type the relevant connection string and path to the JDBC jar file using the following syntax: - - .. code-block:: console - - $ jdbc:Sqream:///;user=;password=sqream;[; ...] - - The following example shows the correct syntax for the JDBC connector: - - .. code-block:: console - - jdbc;MSTR_JDBC_JAR_FOLDER=C:\path\to\jdbc\folder;DRIVER=;URL={jdbc:Sqream:///;user=;password=;[; ...];} - - The following example shows the correct syntax for the ODBC connector: - - .. code-block:: console - - odbc:Driver={SqreamODBCDriver};DSN={SQreamDB ODBC};Server=;Port=;Database=;User=;Password=;Cluster=; - - For more information about the available **connection parameters** and other examples, see `Connection Parameters `_. - - 7. In the **User** and **Password** fields, fill out your user name and password. - - :: - - 8. In the **Data Source Name** field, type **SQreamDB**. - - :: - - 9. Click **Save**. The SQreamDB that you picked in the Data Source panel is displayed. - - -9. In the **Namespace** menu, select a namespace. The tables files are displayed. - - :: - -10. Drag and drop the tables into the panel on the right in your required order. - - :: - -11. **Recommended** - Click **Prepare Data** to customize your data for analysis. - - :: - -12. Click **Finish**. - - :: - -13. From the **Data Access Mode** dialog box, select one of the following: - - - * Connect Live - * Import as an In-memory Dataset - -Your populated dashboard is displayed and is ready for data discovery and analytics. - - - - - - -.. _supported_sqream_drivers: - -:ref:`Back to Overview ` - -Supported SQream Drivers -================ - -The following list shows the supported SQream drivers and versions: - -* **JDBC** - Version 4.3.3 and higher. -* **ODBC** - Version 4.0.0. - - -.. _supported_tools_and_operating_systems: - -:ref:`Back to Overview ` diff --git a/third_party_tools/client_platforms/odbc-sqream.tdc b/third_party_tools/client_platforms/odbc-sqream.tdc deleted file mode 100644 index f1bbe279d..000000000 --- a/third_party_tools/client_platforms/odbc-sqream.tdc +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/third_party_tools/client_platforms/pentaho.rst b/third_party_tools/client_platforms/pentaho.rst deleted file mode 100644 index 1cd95866f..000000000 --- a/third_party_tools/client_platforms/pentaho.rst +++ /dev/null @@ -1,249 +0,0 @@ -.. _pentaho_data_integration: - -************************* -Connect to SQream Using Pentaho Data Integration -************************* -.. _pentaho_top: - -Overview -========= -This document is a Quick Start Guide that describes how to install Pentaho, create a transformation, and define your output. - -The Connecting to SQream Using Pentaho page describes the following: - -* :ref:`Installing Pentaho ` -* :ref:`Installing and setting up the JDBC driver ` -* :ref:`Creating a transformation ` -* :ref:`Defining your output ` -* :ref:`Importing your data ` - -.. _install_pentaho: - -Installing Pentaho -~~~~~~~~~~~~~~~~~ -To install PDI, see the `Pentaho Community Edition (CE) Installation Guide `_. - -The **Pentaho Community Edition (CE) Installation Guide** describes how to do the following: - -* Downloading the PDI software. -* Installing the **JRE (Java Runtime Environment)** and **JDK (Java Development Kit)**. -* Setting up the JRE and JDK environment variables for PDI. - -:ref:`Back to Overview ` - -.. _install_set_up_jdbc_driver: - -Installing and Setting Up the JDBC Driver -~~~~~~~~~~~~~~~~~ -After installing Pentaho you must install and set up the JDBC driver. This section explains how to set up the JDBC driver using Pentaho. These instructions use Spoon, the graphical transformation and job designer associated with the PDI suite. - -You can install the driver by copying and pasting the SQream JDBC .jar file into your **/design-tools/data-integration/lib** directory. - -**NOTE:** Contact your SQream license account manager for the JDBC .jar file. - -:ref:`Back to Overview ` - -.. _create_transformation: - -Creating a Transformation -~~~~~~~~~~~~~~~~~~ -After installing Pentaho you can create a transformation. - -**To create a transformation:** - -1. Use the CLI to open the PDI client for your operating system (Windows): - - .. code-block:: console - - $ spoon.bat - -2. Open the spoon.bat file from its folder location. - -:: - -3. In the **View** tab, right-click **Transformations** and click **New**. - -A new transformation tab is created. - -4. In the **Design** tab, click **Input** to show its file contents. - -:: - -5. Drag and drop the **CSV file input** item to the new transformation tab that you created. - -:: - -6. Double-click **CSV file input**. The **CSV file input** panel is displayed. - -:: - -7. In the **Step name** field, type a name. - -:: - -8. To the right of the **Filename** field, click **Browse**. - -:: - -9. Select the file that you want to read from and click **OK**. - -:: - -10. In the CSV file input window, click **Get Fields**. - -:: - -11. In the **Sample data** window, enter the number of lines you want to sample and click **OK**. The default setting is **100**. - -The tool reads the file and suggests the field name and type. - -12. In the CSV file input window, click **Preview**. - -:: - -13. In the **Preview size** window, enter the number of rows you want to preview and click **OK**. The default setting is **1000**. - -:: - -14. Verify that the preview data is correct and click **Close**. - -:: - -15. Click **OK** in the **CSV file input** window. - -:ref:`Back to Overview ` - -.. _define_output: - -Defining Your Output ------------------ -After creating your transformation you must define your output. - -**To define your output:** - -1. In the **Design** tab, click **Output**. - - The Output folder is opened. - -2. Drag and drop **Table output** item to the Transformation window. - -:: - -3. Double-click **Table output** to open the **Table output** dialog box. - -:: - -4. From the **Table output** dialog box, type a **Step name** and click **New** to create a new connection. Your **steps** are the building blocks of a transformation, such as file input or a table output. - -The **Database Connection** window is displayed with the **General** tab selected by default. - -5. Enter or select the following information in the Database Connection window and click **Test**. - -The following table shows and describes the information that you need to fill out in the Database Connection window: - -.. list-table:: - :widths: 6 31 73 - :header-rows: 1 - - * - No. - - Element Name - - Description - * - 1 - - Connection name - - Enter a name that uniquely describes your connection, such as **sampledata**. - * - 2 - - Connection type - - Select **Generic database**. - * - 3 - - Access - - Select **Native (JDBC)**. - * - 4 - - Custom connection URL - - Insert **jdbc:Sqream:///;user=;password=;[; ...];**. The IP is a node in your SQream cluster and is the name or schema of the database you want to connect to. Verify that you have not used any leading or trailing spaces. - * - 5 - - Custom driver class name - - Insert **com.sqream.jdbc.SQDriver**. Verify that you have not used any leading or trailing spaces. - * - 6 - - Username - - Your SQreamdb username. If you leave this blank, you will be prompted to provide it when you connect. - * - 7 - - Password - - Your password. If you leave this blank, you will be prompted to provide it when you connect. - -The following message is displayed: - -.. image:: /_static/images/third_party_connectors/pentaho/connection_tested_successfully_2.png - -6. Click **OK** in the window above, in the Database Connection window, and Table Output window. - -:ref:`Back to Overview ` - -.. _import_data: - -Importing Data ------------------ -After defining your output you can begin importing your data. - -For more information about backing up users, permissions, or schedules, see `Backup and Restore Pentaho Repositories `_ - -**To import data:** - -1. Double-click the **Table output** connection that you just created. - -:: - -2. To the right of the **Target schema** field, click **Browse** and select a schema name. - -:: - -3. Click **OK**. The selected schema name is displayed in the **Target schema** field. - -:: - -4. Create a new hop connection between the **CSV file input** and **Table output** steps: - - 1. On the CSV file input step item, click the **new hop connection** icon. - - .. image:: /_static/images/third_party_connectors/pentaho/csv_file_input_options.png - - 2. Drag an arrow from the **CSV file input** step item to the **Table output** step item. - - .. image:: /_static/images/third_party_connectors/pentaho/csv_file_input_options_2.png - - 3. Release the mouse button. The following options are displayed. - - 4. Select **Main output of step**. - - .. image:: /_static/images/third_party_connectors/pentaho/main_output_of_step.png - -:: - -5. Double-click **Table output** to open the **Table output** dialog box. - -:: - -6. In the **Target table** field, define a target table name. - -:: - -7. Click **SQL** to open the **Simple SQL editor.** - -:: - -8. In the **Simple SQL editor**, click **Execute**. - - The system processes and displays the results of the SQL statements. - -9. Close all open dialog boxes. - -:: - -10. Click the play button to execute the transformation. - - .. image:: /_static/images/third_party_connectors/pentaho/execute_transformation.png - - The **Run Options** dialog box is displayed. - -11. Click **Run**. The **Execution Results** are displayed. - -:ref:`Back to Overview ` diff --git a/third_party_tools/client_platforms/php.rst b/third_party_tools/client_platforms/php.rst deleted file mode 100644 index 599d6a578..000000000 --- a/third_party_tools/client_platforms/php.rst +++ /dev/null @@ -1,46 +0,0 @@ -.. _php: - -***************************** -Connect to SQream Using PHP -***************************** - -You can use PHP to interact with a SQream DB cluster. - -This tutorial is a guide that will show you how to connect a PHP application to SQream DB. - -.. contents:: In this topic: - :local: - -Prerequisites -=============== - -#. Install the :ref:`SQream DB ODBC driver for Linux` and create a DSN. - -#. - Install the `uODBC `_ extension for your PHP installation. - To configure PHP to enable uODBC, configure it with ``./configure --with-pdo-odbc=unixODBC,/usr/local`` when compiling php or install ``php-odbc`` and ``php-pdo`` along with php (version 7.1 minimum for best results) using your distribution package manager. - -Testing the connection -=========================== - -#. - Create a test connection file. Be sure to use the correct parameters for your SQream DB installation. - - Download this :download:`PHP example connection file ` . - - .. literalinclude:: test.php - :language: php - :emphasize-lines: 4 - :linenos: - - .. tip:: - An example of a valid DSN line is: - - .. code:: php - - $dsn = "odbc:Driver={SqreamODBCDriver};Server=192.168.0.5;Port=5000;Database=master;User=rhendricks;Password=super_secret;Service=sqream"; - - For more information about supported DSN parameters, see :ref:`dsn_params`. - -#. Run the PHP file either directly with PHP (``php test.php``) or through a browser. - diff --git a/third_party_tools/client_platforms/power_bi.rst b/third_party_tools/client_platforms/power_bi.rst deleted file mode 100644 index 3b9f662bd..000000000 --- a/third_party_tools/client_platforms/power_bi.rst +++ /dev/null @@ -1,143 +0,0 @@ -.. _power_bi: - -************************* -Connect to SQream Using Power BI Desktop -************************* - -Overview -========= -**Power BI Desktop** lets you connect to SQream and use underlying data as with other data sources in Power BI Desktop. - -SQream integrates with Power BI Desktop to do the following: - -* Extract and transform your datasets into usable visual models in approximately one minute. - - :: - -* Use **DAX** functions **(Data Analysis Expressions)** to analyze your datasets. - - :: - -* Refresh datasets as needed or by using scheduled jobs. - -SQream uses Power BI for extracting data sets using the following methods: - -* **Direct query** - Direct queries lets you connect easily with no errors, and refreshes Power BI artifacts, such as graphs and reports, in a considerable amount of time in relation to the time taken for queries to run using the `SQream SQL CLI Reference guide `_. - - :: - -* **Import** - Lets you extract datasets from remote databases. - -The **Connect to SQream Using Power BI** page describes the following: - -.. contents:: - :local: - :depth: 1 - -Prerequisites -------------------- -To connect to SQream, the following must be installed: - -* **ODBC data source administrator** - 32 or 64, depending on your operating system. For Windows users, the ODBC data source administrator is embedded within the operating system. - -* **SQream driver** - The SQream application required for interacting with the ODBC according to the configuration specified in the ODBC administrator tool. - -Installing Power BI Desktop -------------------- -**To install Power BI Desktop:** - -1. Download `Power BI Desktop 64x `_. - - :: - -2. Download and configure your ODBC driver. - - For more information about configuring your ODBC driver, see `ODBC `_. - -3. Navigate to **Windows** > **Documents** and create a folder called **Power BI Desktop Custom Connectors**. - - :: - -4. In the **Power BI Desktop** folder, create a folder called **Custom Connectors**. - - -5. From the Client Drivers page, download the **PowerQuery.mez** file. - - :: - -5. Save the PowerQuery.mez file in the **Custom Connectors** folder you created in Step 3. - - :: - -6. Open the Power BI application. - - :: - -7. Navigate to **File** > **Options and Settings** > **Option** > **Security** > **Data Extensions**, and select **(Not Recommended) Allow any extension to load without validation or warning**. - - :: - -8. Restart the Power BI Desktop application. - - :: - -9. From the **Get Data** menu, select **SQream**. - - :: - -10. Click **Connect** and provide the information shown in the following table: - - .. list-table:: - :widths: 6 31 - :header-rows: 1 - - * - Element Name - - Description - * - Server - - Provide the network address to your database server. You can use a hostname or an IP address. - * - Port - - Provide the port that the database is responding to at the network address. - * - Database - - Provide the name of your database or the schema on your database server. - * - User - - Provide a SQreamdb username. - * - Passwords - - Provide a password for your user. - -11. Under **Data Connectivity mode**, select **DirectQuery mode**. - - :: - -12. Click **Connect**. - - :: - -13. Provide your user name and password and click **Connect**. - -Best Practices for Power BI ---------------- -SQream recommends using Power BI in the following ways for acquiring the best performance metrics: - -* Creating bar, pie, line, or plot charts when illustrating one or more columns. - - :: - -* Displaying trends and statuses using visual models. - - :: - -* Creating a unified view using **PowerQuery** to connect different data sources into a single dashboard. - -Supported SQream Driver Versions ---------------- -SQream supports the following SQream driver versions: - -* The **PowerQuery Connector** is an additional layer on top of the ODBC. - - :: - -* SQream Driver Installation (ODBC v4.1.1) - Contact your administrator for the link to download ODBC v4.1.1. - -Related Information -------------------- -For more information, see the `Glossary `_. \ No newline at end of file diff --git a/third_party_tools/client_platforms/r.rst b/third_party_tools/client_platforms/r.rst deleted file mode 100644 index 6abe27031..000000000 --- a/third_party_tools/client_platforms/r.rst +++ /dev/null @@ -1,151 +0,0 @@ -.. _r: - -***************************** -Connect to SQream Using R -***************************** - -You can use R to interact with a SQream DB cluster. - -This tutorial is a guide that will show you how to connect R to SQream DB. - -.. contents:: In this topic: - :local: - -JDBC -========= - - -#. Get the :ref:`SQream DB JDBC driver`. - -#. - In R, install RJDBC - - .. code-block:: rconsole - - > install.packages("RJDBC") - Installing package into 'C:/Users/r/...' - (as 'lib' is unspecified) - - package 'RJDBC' successfully unpacked and MD5 sums checked - -#. - Import the RJDBC library - - .. code-block:: rconsole - - > library(RJDBC) - -#. - Set the classpath and initialize the JDBC driver which was previously installed. For example, on Windows: - - .. code-block:: rconsole - - > cp = c("C:\\Program Files\\SQream Technologies\\JDBC Driver\\2020.1-3.2.0\\sqream-jdbc-3.2.jar") - > .jinit(classpath=cp) - > drv <- JDBC("com.sqream.jdbc.SQDriver","C:\\Program Files\\SQream Technologies\\JDBC Driver\\2020.1-3.2.0\\sqream-jdbc-3.2.jar") -#. - Open a connection with a :ref:`JDBC connection string` and run your first statement - - .. code-block:: rconsole - - > con <- dbConnect(drv,"jdbc:Sqream://127.0.0.1:3108/master;user=rhendricks;password=Tr0ub4dor&3;cluster=true") - - > dbGetQuery(con,"select top 5 * from t") - xint xtinyint xsmallint xbigint - 1 1 82 5067 1 - 2 2 14 1756 2 - 3 3 91 22356 3 - 4 4 84 17232 4 - 5 5 13 14315 5 - -#. - Close the connection - - .. code-block:: rconsole - - > close(con) - -A full example ------------------ - -.. code-block:: rconsole - - > library(RJDBC) - > cp = c("C:\\Program Files\\SQream Technologies\\JDBC Driver\\2020.1-3.2.0\\sqream-jdbc-3.2.jar") - > .jinit(classpath=cp) - > drv <- JDBC("com.sqream.jdbc.SQDriver","C:\\Program Files\\SQream Technologies\\JDBC Driver\\2020.1-3.2.0\\sqream-jdbc-3.2.jar") - > con <- dbConnect(drv,"jdbc:Sqream://127.0.0.1:3108/master;user=rhendricks;password=Tr0ub4dor&3;cluster=true") - > dbGetQuery(con,"select top 5 * from t") - xint xtinyint xsmallint xbigint - 1 1 82 5067 1 - 2 2 14 1756 2 - 3 3 91 22356 3 - 4 4 84 17232 4 - 5 5 13 14315 5 - > close(con) - -ODBC -========= - -#. Install the :ref:`SQream DB ODBC driver` for your operating system, and create a DSN. - -#. - In R, install RODBC - - .. code-block:: rconsole - - > install.packages("RODBC") - Installing package into 'C:/Users/r/...' - (as 'lib' is unspecified) - - package 'RODBC' successfully unpacked and MD5 sums checked - -#. - Import the RODBC library - - .. code-block:: rconsole - - > library(RODBC) - -#. - Open a connection handle to an existing DSN (``my_cool_dsn`` in this example) - - .. code-block:: rconsole - - > ch <- odbcConnect("my_cool_dsn",believeNRows=F) - -#. - Run your first statement - - .. code-block:: rconsole - - > sqlQuery(ch,"select top 5 * from t") - xint xtinyint xsmallint xbigint - 1 1 82 5067 1 - 2 2 14 1756 2 - 3 3 91 22356 3 - 4 4 84 17232 4 - 5 5 13 14315 5 - -#. - Close the connection - - .. code-block:: rconsole - - > close(ch) - -A full example ------------------ - -.. code-block:: rconsole - - > library(RODBC) - > ch <- odbcConnect("my_cool_dsn",believeNRows=F) - > sqlQuery(ch,"select top 5 * from t") - xint xtinyint xsmallint xbigint - 1 1 82 5067 1 - 2 2 14 1756 2 - 3 3 91 22356 3 - 4 4 84 17232 4 - 5 5 13 14315 5 - > close(ch) diff --git a/third_party_tools/client_platforms/sas_viya.rst b/third_party_tools/client_platforms/sas_viya.rst deleted file mode 100644 index fc0806296..000000000 --- a/third_party_tools/client_platforms/sas_viya.rst +++ /dev/null @@ -1,185 +0,0 @@ -.. _connect_to_sas_viya: - -************************* -Connect to SQream Using SAS Viya -************************* - -Overview -========== -SAS Viya is a cloud-enabled analytics engine used for producing useful insights. The **Connect to SQream Using SAS Viya** page describes how to connect to SAS Viya, and describes the following: - -.. contents:: - :local: - :depth: 1 - -Installing SAS Viya -------------------- -The **Installing SAS Viya** section describes the following: - -.. contents:: - :local: - :depth: 1 - -Downloading SAS Viya -~~~~~~~~~~~~~~~~~~ -Integrating with SQream has been tested with SAS Viya v.03.05 and newer. - -To download SAS Viya, see `SAS Viya `_. - -Installing the JDBC Driver -~~~~~~~~~~~~~~~~~~ -The SQream JDBC driver is required for establishing a connection between SAS Viya and SQream. - -**To install the JDBC driver:** - -#. Download the `JDBC driver `_. - - :: - -#. Unzip the JDBC driver into a location on the SAS Viya server. - - SQream recommends creating the directory ``/opt/sqream`` on the SAS Viya server. - -Configuring SAS Viya -------------------- -After installing the JDBC driver, you must configure the JDBC driver from the SAS Studio so that it can be used with SQream Studio. - -**To configure the JDBC driver from the SAS Studio:** - -#. Sign in to the SAS Studio. - - :: - -#. From the **New** menu, click **SAS Program**. - - :: - -#. Configure the SQream JDBC connector by adding the following rows: - - .. literalinclude:: connect3.sas - :language: php - -For more information about writing a connection string, see **Connect to SQream DB with a JDBC Application** and navigate to `Connection String `_. - -Operating SAS Viya --------------------- -The **Operating SAS Viya** section describes the following: - -.. contents:: - :local: - :depth: 1 - -Using SAS Viya Visual Analytics -~~~~~~~~~~~~~~~~~~ -This section describes how to use SAS Viya Visual Analytics. - -**To use SAS Viya Visual Analytics:** - -#. Log in to `SAS Viya Visual Analytics `_ using your credentials: - - :: - -2. Click **New Report**. - - :: - -3. Click **Data**. - - :: - -4. Click **Data Sources**. - - :: - -5. Click the **Connect** icon. - - :: - -6. From the **Type** menu, select **Database**. - - :: - -7. Provide the required information and select **Persist this connection beyond the current session**. - - :: - -8. Click **Advanced** and provide the required information. - - :: - -9. Add the following additional parameters by clicking **Add Parameters**: - -.. list-table:: - :widths: 10 90 - :header-rows: 1 - - * - Name - - Value - * - class - - com.sqream.jdbc.SQDriver - * - classPath - - ** - * - url - - \jdbc:Sqream://**:**/**;cluster=true - * - username - - - * - password - - - -10. Click **Test Connection**. - - :: - -11. If the connection is successful, click **Save**. - -If your connection is not successful, see :ref:`troubleshooting_sas_viya` below. - -.. _troubleshooting_sas_viya: - -Troubleshooting SAS Viya -------------------------- -The **Best Practices and Troubleshooting** section describes the following best practices and troubleshooting procedures when connecting to SQream using SAS Viya: - -.. contents:: - :local: - :depth: 1 - -Inserting Only Required Data -~~~~~~~~~~~~~~~~~~ -When using SAS Viya, SQream recommends using only data that you need, as described below: - -* Insert only the data sources you need into SAS Viya, excluding tables that don’t require analysis. - - :: - -* To increase query performance, add filters before analyzing. Every modification you make while analyzing data queries the SQream database, sometimes several times. Adding filters to the datasource before exploring limits the amount of data analyzed and increases query performance. - -Creating a Separate Service for SAS Viya -~~~~~~~~~~~~~~~~~~ -SQream recommends creating a separate service for SAS Viya with the DWLM. This reduces the impact that Tableau has on other applications and processes, such as ETL. In addition, this works in conjunction with the load balancer to ensure good performance. - -Locating the SQream JDBC Driver -~~~~~~~~~~~~~~~~~~ -In some cases, SAS Viya cannot locate the SQream JDBC driver, generating the following error message: - -.. code-block:: text - - java.lang.ClassNotFoundException: com.sqream.jdbc.SQDriver - -**To locate the SQream JDBC driver:** - -1. Verify that you have placed the JDBC driver in a directory that SAS Viya can access. - - :: - -2. Verify that the classpath in your SAS program is correct, and that SAS Viya can access the file that it references. - - :: - -3. Restart SAS Viya. - -For more troubleshooting assistance, see the `SQream Support Portal `_. - -Supporting TEXT -~~~~~~~~~~~~~~~~~~ -In SAS Viya versions lower than 4.0, casting ``TEXT`` to ``CHAR`` changes the size to 1,024, such as when creating a table including a ``TEXT`` column. This is resolved by casting ``TEXT`` into ``CHAR`` when using the JDBC driver. diff --git a/third_party_tools/client_platforms/sql_workbench.rst b/third_party_tools/client_platforms/sql_workbench.rst deleted file mode 100644 index d46d45ae6..000000000 --- a/third_party_tools/client_platforms/sql_workbench.rst +++ /dev/null @@ -1,135 +0,0 @@ -.. _connect_to_sql_workbench: - -***************************** -Connect to SQream Using SQL Workbench -***************************** - -You can use SQL Workbench to interact with a SQream DB cluster. SQL Workbench/J is a free SQL query tool, and is designed to run on any JRE-enabled environment. - -This tutorial is a guide that will show you how to connect SQL Workbench to SQream DB. - -.. contents:: In this topic: - :local: - -Installing SQL Workbench with the SQream DB installer (Windows only) -===================================================================== - -SQream DB's driver installer for Windows can install the Java prerequisites and SQL Workbench for you. - -#. Get the JDBC driver installer available for download from the `SQream Drivers page `_. The Windows installer takes care of the Java prerequisites and subsequent configuration. - -#. Install the driver by following the on-screen instructions in the easy-to-follow installer. - By default, the installer does not install SQL Workbench. Make sure to select the item! - - .. image:: /_static/images/jdbc_windows_installer_screen.png - -.. note:: The installer will install SQL Workbench in ``C:\Program Files\SQream Technologies\SQLWorkbench`` by default. You can change this path during the installation. - -#. Once finished, SQL Workbench is installed and contains the necessary configuration for connecting to SQream DB clusters. - -#. Start SQL Workbench from the Windows start menu. Be sure to select **SQL Workbench (64)** if you're on 64-bit Windows. - - .. image:: /_static/images/sql_workbench_launch.png - -You are now ready to create a profile for your cluster. Continue to :ref:`Creating a new connection profile `. - -Installing SQL Workbench manually (Linux, MacOS) -=================================================== - -Install Java Runtime ------------------------- - -Both SQL Workbench and the SQream DB JDBC driver require Java 1.8 or newer. You can install either Oracle Java or OpenJDK. - -**Oracle Java** - -Download and install Java 8 from Oracle for your platform - https://www.java.com/en/download/manual.jsp - -**OpenJDK** - -For Linux and BSD, see https://openjdk.java.net/install/ - -For Windows, SQream recommends Zulu 8 https://www.azul.com/downloads/zulu-community/?&version=java-8-lts&architecture=x86-64-bit&package=jdk - -Get the SQream DB JDBC driver -------------------------------- - -SQream DB's JDBC driver is provided as a zipped JAR file, available for download from the `SQream Drivers page `_. - -Download and extract the JAR file from the zip archive. - -Install SQL Workbench ------------------------ - -#. Download the latest stable release from https://www.sql-workbench.eu/downloads.html . The **Generic package for all systems** is recommended. - -#. Extract the downloaded ZIP archive into a directory of your choice. - -#. Start SQL workbench. If you are using 64 bit windows, run ``SQLWorkbench64.exe`` instead of ``SQLWOrkbench.exe``. - -Setting up the SQream DB JDBC driver profile ---------------------------------------------- - -#. Define a connection profile - :menuselection:`&File --> &Connect window (Alt+C)` - - .. image:: /_static/images/sql_workbench_connect_window1.png - -#. Open the drivers management window - :menuselection:`&Manage Drivers` - - .. image:: /_static/images/sql_workbench_manage_drivers.png - - - -#. Create the SQream DB driver profile - - .. image:: /_static/images/sql_workbench_create_driver.png - - #. Click on the Add new driver button ("New" icon) - - #. Name the driver as you see fit. We recommend calling it SQream DB , where is the version you have installed. - - #. - Add the JDBC drivers from the location where you extracted the SQream DB JDBC JAR. - - If you used the SQream installer, the file will be in ``C:\Program Files\SQream Technologies\JDBC Driver\`` - - #. Click the magnifying glass button to detect the classname automatically. Other details are purely optional - - #. Click OK to save and return to "new connection screen" - - -.. _new_connection_profile: - -Create a new connection profile for your cluster -===================================================== - - .. image:: /_static/images/sql_workbench_connection_profile.png - -#. Create new connection by clicking the New icon (top left) - -#. Give your connection a descriptive name - -#. Select the SQream Driver that was created in the previous screen - -#. Type in your connection string. To find out more about your connection string (URL), see the :ref:`Connection string documentation `. - -#. Text the connection details - -#. Click OK to save the connection profile and connect to SQream DB - -Suggested optional configuration -================================== - -If you installed SQL Workbench manually, you can set a customization to help SQL Workbench show information correctly in the DB Explorer panel. - -#. Locate your workbench.settings file - On Windows, typically: ``C:\Users\\.sqlworkbench\workbench.settings`` - On Linux, ``$HOME/.sqlworkbench`` - -#. Add the following line at the end of the file: - - .. code-block:: text - - workbench.db.sqreamdb.schema.retrieve.change.catalog=true - -#. Save the file and restart SQL Workbench diff --git a/third_party_tools/client_platforms/tableau.rst b/third_party_tools/client_platforms/tableau.rst deleted file mode 100644 index 666b2f198..000000000 --- a/third_party_tools/client_platforms/tableau.rst +++ /dev/null @@ -1,453 +0,0 @@ -.. _connect_to_tableau: - -************************* -Connecting to SQream Using Tableau -************************* - -Overview -===================== -SQream's Tableau connector plugin, based on standard JDBC, enables storing and fast querying large volumes of data. - -The **Connecting to SQream Using Tableau** page is a Quick Start Guide that describes how install Tableau and the JDBC and ODBC drivers and connect to SQream using the JDBC and ODBC drivers for data analysis. It also describes using best practices and troubleshoot issues that may occur while installing Tableau. SQream supports both Tableau Desktop and Tableau Server on Windows, MacOS, and Linux distributions. - -For more information on SQream's integration with Tableau, see `Tableau's Extension Gallery `_. - -The Connecting to SQream Using Tableau page describes the following: - -.. contents:: - :local: - -Installing the JDBC Driver and Tableau Connector Plugin -------------------- -This section describes how to install the JDBC driver using the fully-integrated Tableau connector plugin (Tableau Connector, or **.taco** file). SQream has been tested with Tableau versions 9.2 and newer. - -**To connect to SQream using Tableau:** - -#. Install the Tableau Desktop application. - - For more information about installing the Tableau Desktop application, see the `Tableau products page `_ and click **Download Free Trial**. Note that Tableau offers a 14-day trial version. - - :: - -#. Do one of the following: - - * **For Windows** - See :ref:`Installing Tableau Using the Windows Installer `. - * **For MacOS or Linux** - See :ref:`Installing the JDBC Driver Manually `. - -.. note:: For Tableau **2019.4 versions and later**, SQream recommends installing the JDBC driver instead of the previously recommended ODBC driver. - -.. _tableau_windows_installer: - -Installing the JDBC Driver Using the Windows Installer -~~~~~~~~~~~~~~~~~~ -If you are using Windows, after installing the Tableau Desktop application you can install the JDBC driver using the Windows installer. The Windows installer is an installation wizard that guides you through the JDBC driver installation steps. When the driver is installed, you can connect to SQream. - -**To install Tableau using the Windows installer**: - -#. Close Tableau Desktop. - - :: - -#. Download the most current version of the `SQream JDBC driver `_. - - :: - -#. Do the following: - - #. Start the installer. - #. Verify that the **Tableau Desktop connector** item is selected. - #. Follow the installation steps. - - :: - -You can now restart Tableau Desktop or Server to begin using the SQream driver by :ref:`connecting to SQream `. - -.. _tableau_jdbc_installer: - -Installing the JDBC Driver Manually -~~~~~~~~~~~~~ -If you are using MacOS, Linux, or the Tableau server, after installing the Tableau Desktop application you can install the JDBC driver manually. When the driver is installed, you can connect to SQream. - -**To install the JDBC driver manually:** - -1. Download the JDBC installer and SQream Tableau connector (.taco) file from the :ref:`from the client drivers page`. - - :: - -#. Install the JDBC driver by unzipping the JDBC driver into a Tableau driver directory. - - Based on the installation method that you used, your Tableau driver directory is located in one of the following places: - - * **Tableau Desktop on Windows:** *C:\\Program Files\\Tableau\\Drivers* - * **Tableau Desktop on MacOS:** *~/Library/Tableau/Drivers* - * **Tableau on Linux**: */opt/tableau/tableau_driver/jdbc* - -.. note:: If the driver includes only a single .jar file, copy it to *C:\\Program Files\\Tableau/Drivers*. If the driver includes multiple files, create a subfolder *A* in *C:\\Program Files\\Tableau/Drivers* and copy all files to folder *A*. - -Note the following when installing the JDBC driver: - -* You must have read permissions on the .jar file. -* Tableau requires a JDBC 4.0 or later driver. -* Tableau requires a Type 4 JDBC driver. -* The latest 64-bit version of Java 8 is installed. - -3. Install the **SQreamDB.taco** file by moving the SQreamDB.taco file into the Tableau connectors directory. - - Based on the installation method that you used, your Tableau driver directory is located in one of the following places: - - * **Tableau Desktop on Windows:** *C:\\Users\\\\My Tableau Repository\\Connectors* - * **Tableau Desktop on Windows:** *~/My Tableau Repository/Connectors* - - :: - -4. *Optional* - If you are using the Tableau Server, do the following: - - 1. Create a directory for Tableau connectors and give it a descriptive name, such as *C:\\tableau_connectors*. - - This directory needs to exist on all Tableau servers. - - :: - - 2. Copy the SQreamDB.taco file into the new directory. - - :: - - 3. Set the **native_api.connect_plugins_path** option to ``tsm`` as shown in the following example: - - .. code-block:: console - - $ tsm configuration set -k native_api.connect_plugins_path -v C:/tableau_connectors - - If a configuration error is displayed, add ``--force-keys`` to the end of the command as shown in the following example: - - .. code-block:: console - - $ tsm configuration set -k native_api.connect_plugins_path -v C:/tableau_connectors--force-keys - - 4. To apply the pending configuration changes, run the following command: - - .. code-block:: console - - $ tsm pending-changes apply - - .. warning:: This restarts the server. - -You can now restart Tableau Desktop or Server to begin using the SQream driver by :ref:`connecting to SQream ` as described in the section below. - -.. _tableau_connect_to_sqream: - - -Installing the ODBC Driver for Tableau Versions 2019.3 and Earlier --------------- - - -This section describes the installation method for Tableau version 2019.3 or earlier and describes the following: - -.. contents:: - :local: - -.. note:: SQream recommends installing the JDBC driver to provide improved connectivity. - -Automatically Reconfiguring the ODBC Driver After Initial Installation -~~~~~~~~~~~~~~~~~~ -If you've already installed the SQream ODBC driver and installed Tableau, SQream recommends reinstalling the ODBC driver with the **.TDC Tableau Settings for SQream DB** configuration shown in the image below: - -.. image:: /_static/images/odbc_windows_installer_tableau.png - -SQream recommends this configuration because Tableau creates temporary tables and runs several discovery queries that may impact performance. The ODBC driver installer avoids this by automatically reconfiguring Tableau. - -For more information about reinstalling the ODBC driver installer, see :ref:`Install and Configure ODBC on Windows `. - -If you want to manually reconfigure the ODBC driver, see :ref:`Manually Reconfiguring the ODBC Driver After Initial Installation ` below. - -.. _manually_reconfigure_odbc_driver: - -Manually Reconfiguring the ODBC Driver After Initial Installation -~~~~~~~~~~~~~~~~~~ -The file **Tableau Datasource Customization (TDC)** file lets you use Tableau make full use of SQream DB's features and capabilities. - -**To manually reconfigure the ODBC driver after initial installation:** - -1. Do one of the following: - - 1. Download the :download:`odbc-sqream.tdc ` file to your machine and open it in a text editor. - - :: - - 2. Copy the text below into a text editor: - - .. literalinclude:: odbc-sqream.tdc - :language: xml - :caption: SQream ODBC TDC File - :emphasize-lines: 2 - -#. Check which version of Tableau you are using. - - :: - -#. In the text of the file shown above, in the highlighted line, replace the version number with the **major** version of Tableau that you are using. - - For example, if you are using Tableau vesion **2019.2.1**, replace it with **2019.2**. - - :: - -#. Do one of the following: - - * If you are using **Tableau Desktop** - save the TDC file to *C:\\Users\\\\Documents\\My Tableau Repository\\Datasources*, where ```` is the Windows username that you have installed Tableau under. - - :: - - * If you are using the **Tableau Server** - save the TDC file to *C:\\ProgramData\\Tableau\\Tableau Server\\data\\tabsvc\\vizqlserver\\Datasources*. - -Configuring the ODBC Connection -~~~~~~~~~~~~ -The ODBC connection uses a DSN when connecting to ODBC data sources, and each DSN represents one SQream database. - -**To configure the ODBC connection:** - -1. Create an ODBC DSN. - - :: - -#. Open the Windows menu by pressing the Windows button (:kbd:`⊞ Win`) or clicking the **Windows** menu button. - - :: - -#. Type **ODBC** and select **ODBC Data Sources (64-bit)**. - - During installation, the installer created a sample user DSN named **SQreamDB**. - - :: - -#. *Optional* - Do one or both of the following: - - * Modify the DSN name. - - :: - - * Create a new DSN name by clicking **Add** and selecting **SQream ODBC Driver**. - -.. image:: /_static/images/odbc_windows_dsns.png - - -5. Click **Finish**. - - :: - -6. Enter your connection parameters. - - The following table describes the connection parameters: - - .. list-table:: - :widths: 15 38 38 - :header-rows: 1 - - * - Item - - Description - - Example - * - Data Source Name - - The Data Source Name. SQream recommends using a descriptive and easily recognizable name for referencing your DSN. Once set, the Data Source Name cannot be changed. - - - * - Description - - The description of your DSN. This field is optional. - - - * - User - - The username of a role to use for establishing the connection. - - ``rhendricks`` - * - Password - - The password of the selected role. - - ``Tr0ub4dor`` - * - Database - - The database name to connect to. For example, ``master`` - - ``master`` - * - Service - - The :ref:`service queue` to use. - - For example, ``etl``. For the default service ``sqream``, leave blank. - * - Server - - The hostname of the SQream worker. - - ``127.0.0.1`` or ``sqream.mynetwork.co`` - * - Port - - The TCP port of the SQream worker. - - ``5000`` or ``3108`` - * - User Server Picker - - Uses the load balancer when establishing a connection. Use only if exists, and check port. - - - * - SSL - - Uses SSL when establishing a connection. - - - * - Logging Options - - Lets you modify your logging options when tracking the ODBC connection for connection issues. - - - -.. tip:: Test the connection by clicking **Test** before saving your DSN. - -7. Save the DSN by clicking **OK.** - -Connecting Tableau to SQream -~~~~~~~~~~~~ -**To connect Tableau to SQream:** - -1. Start Tableau Desktop. - - :: - -#. In the **Connect** menu, in the **To a server** sub-menu, click **More Servers** and select **Other Databases (ODBC)**. - - The **Other Databases (ODBC)** window is displayed. - - :: - -#. In the Other Databases (ODBC) window, select the DSN that you created in :ref:`Setting Up SQream Tables as Data Sources `. - - Tableau may display the **Sqream ODBC Driver Connection Dialog** window and prompt you to provide your username and password. - -#. Provide your username and password and click **OK**. - -.. _tableau_connect_to_sqream_db: - - -Connecting to SQream ---------------------- -After installing the JDBC driver you can connect to SQream. - -**To connect to SQream:** - -#. Start Tableau Desktop. - - :: - -#. In the **Connect** menu, in the **To a Server** sub-menu, click **More...**. - - More connection options are displayed. - - :: - -#. Select **SQream DB by SQream Technologies**. - - The **New Connection** dialog box is displayed. - - :: - -#. In the New Connection dialog box, fill in the fields and click **Sign In**. - - The following table describes the fields: - - .. list-table:: - :widths: 15 38 38 - :header-rows: 1 - - * - Item - - Description - - Example - * - Server - - Defines the server of the SQream worker. - - ``127.0.0.1`` or ``sqream.mynetwork.co`` - * - Port - - Defines the TCP port of the SQream worker. - - ``3108`` when using a load balancer, or ``5100`` when connecting directly to a worker with SSL. - * - Database - - Defines the database to establish a connection with. - - ``master`` - * - Cluster - - Enables (``true``) or disables (``false``) the load balancer. After enabling or disabling the load balance, verify the connection. - - - * - Username - - Specifies the username of a role to use when connecting. - - ``rhendricks`` - * - Password - - Specifies the password of the selected role. - - ``Tr0ub4dor&3`` - * - Require SSL (recommended) - - Sets SSL as a requirement for establishing this connection. - - - -The connection is established and the data source page is displayed. - -.. tip:: - Tableau automatically assigns your connection a default name based on the DSN and table. SQream recommends giving the connection a more descriptive name. - -.. _set_up_sqream_tables_as_data_sources: - -Setting Up SQream Tables as Data Sources ----------------- -After connecting to SQream you must set up the SQream tables as data sources. - -**To set up SQream tables as data sources:** - -1. From the **Table** menu, select the desired database and schema. - - SQream's default schema is **public**. - - :: - -#. Drag the desired tables into the main area (labeled **Drag tables here**). - - This area is also used for specifying joins and data source filters. - - :: - -#. Open a new sheet to analyze data. - -.. tip:: - For more information about configuring data sources, joining, filtering, see Tableau's `Set Up Data Sources `_ tutorials. - -Tableau Best Practices and Troubleshooting ---------------- -This section describes the following best practices and troubleshooting procedures when connecting to SQream using Tableau: - -.. contents:: - :local: - -Inserting Only Required Data -~~~~~~~~~~~~~~~~~~ -When using Tableau, SQream recommends using only data that you need, as described below: - -* Insert only the data sources you need into Tableau, excluding tables that don't require analysis. - - :: - -* To increase query performance, add filters before analyzing. Every modification you make while analyzing data queries the SQream database, sometimes several times. Adding filters to the datasource before exploring limits the amount of data analyze and increases query performance. - -Using Tableau's Table Query Syntax -~~~~~~~~~~~~~~~~~~~ -Dragging your desired tables into the main area in Tableau builds queries based on its own syntax. This helps ensure increased performance, while using views or custom SQL may degrade performance. In addition, SQream recommends using the :ref:`create_view` to create pre-optimized views, which your datasources point to. - -Creating a Separate Service for Tableau -~~~~~~~~~~~~~~~~~~~ -SQream recommends creating a separate service for Tableau with the DWLM. This reduces the impact that Tableau has on other applications and processes, such as ETL. In addition, this works in conjunction with the load balancer to ensure good performance. - -Troubleshooting Workbook Performance Before Deploying to the Tableau Server -~~~~~~~~~~~~~~~~~~~ -Tableau has a built-in `performance recorder `_ that shows how time is being spent. If you're seeing slow performance, this could be the result of a misconfiguration such as setting concurrency too low. - -Use the Tableau Performance Recorder for viewing the performance of queries run by Tableau. You can use this information to identify queries that can be optimized by using views. - -Troubleshooting Error Codes -~~~~~~~~~~~~~~~~~~~ -Tableau may be unable to locate the SQream JDBC driver. The following message is displayed when Tableau cannot locate the driver: - -.. code-block:: console - - Error Code: 37CE01A3, No suitable driver installed or the URL is incorrect - -**To troubleshoot error codes:** - -If Tableau cannot locate the SQream JDBC driver, do the following: - - 1. Verify that the JDBC driver is located in the correct directory: - - * **Tableau Desktop on Windows:** *C:\Program Files\Tableau\Drivers* - * **Tableau Desktop on MacOS:** *~/Library/Tableau/Drivers* - * **Tableau on Linux**: */opt/tableau/tableau_driver/jdbc* - - 2. Find the file path for the JDBC driver and add it to the Java classpath: - - * **For Linux** - ``export CLASSPATH=;$CLASSPATH`` - - :: - - * **For Windows** - add an environment variable for the classpath: - - .. image:: /_static/images/third_party_connectors/tableau/envrionment_variable_for_classpath.png - -If you experience issues after restarting Tableau, see the `SQream support portal `_. diff --git a/third_party_tools/client_platforms/talend.rst b/third_party_tools/client_platforms/talend.rst deleted file mode 100644 index 6e34a7168..000000000 --- a/third_party_tools/client_platforms/talend.rst +++ /dev/null @@ -1,177 +0,0 @@ -.. _talend: - -************************* -Connecting to SQream Using Talend -************************* -.. _top: - -Overview -================= - -This page describes how to use Talend to interact with a SQream DB cluster. The Talend connector is used for reading data from a SQream DB cluster and loading data into SQream DB. - -In addition, this page provides a viability report on Talend's comptability with SQream DB for stakeholders. - -It includes the following: - -* :ref:`A Quick Start guide ` -* :ref:`Information about supported SQream drivers ` -* :ref:`Supported data sources ` and :ref:`tool and operating system versions ` -* :ref:`A description of known issues ` -* :ref:`Related links ` - -About Talend -================= -Talend is an open-source data integration platform. It provides various software and services for Big Data integration and management, enterprise application integration, data quality and cloud storage. - -For more information about Talend, see `Talend `_. - -.. _quickstart_guide: - -Quick Start Guide -======================= - -Creating a New Metadata JDBC DB Connection -------------- -**To create a new metadata JDBC DB connection:** - -1. In the **Repository** panel, nagivate to **Metadata** and right-click **Db connections**. - -:: - -2. Select **Create connection**. - -3. In the **Name** field, type a name. - -The name cannot contain spaces. - -4. In the **Purpose** field, type a purpose and click **Next**. You cannot go to the next step until you define both a Name and a Purpose. - -:: - -5. In the **DB Type** field, select **JDBC**. - -:: - -6. In the **JDBC URL** field, type the relevant connection string. - - For connection string examples, see `Connection Strings `_. - -7. In the **Drivers** field, click the **Add** button. - - The **"newLine** entry is added. - -8. One the **"newLine** entry, click the ellipsis. - -.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_8.png - -The **Module** window is displayed. - -9. From the Module window, select **Artifact repository(local m2/nexus)** and select **Install a new module**. - -:: - -10. Click the ellipsis. - -.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_9.5.png - -Your hard drive is displayed. - -11. Navigate to a **JDBC jar file** (such as **sqream-jdbc-4.4.0.jar**)and click **Open**. - -:: - -12. Click **Detect the module install status**. - -:: - -13. Click **OK**. - -The JDBC that you selected is displayed in the **Driver** field. - -14. Click **Select class name**. - -:: - -15. Click **Test connection**. - -If a driver class is not found (for example, you didn't select a JDBC jar file), the following error message is displayed: - -After creating a new metadata JDBC DB connection, you can do the following: - - * Use your new metadata connection. - * Drag it to the **job** screen. - * Build Talend components. - -For more information on loading data from JSON files to the Talend Open Studio, see `How to Load Data from JSON Files in Talend `_. - -:ref:`Back to top ` - -.. _supported_sqream_drivers: - -Supported SQream Drivers -================ - -The following list shows the supported SQream drivers and versions: - -* **JDBC** - Version 4.3.3 and higher. -* **ODBC** - Version 4.0.0. This version requires a Bridge to connect. For more information on the required Bridge, see `Connecting Talend on Windows to an ODBC Database `_. - -:ref:`Back to top ` - -.. _supported_data_sources: - -Supported Data Sources -============================ -Talend Cloud connectors let you create reusable connections with a wide variety of systems and environments, such as those shown below. This lets you access and read records of a range of diverse data. - -* **Connections:** Connections are environments or systems for storing datasets, including databases, file systems, distributed systems and platforms. Because these systems are reusable, you only need to establish connectivity with them once. - -* **Datasets:** Datasets include database tables, file names, topics (Kafka), queues (JMS) and file paths (HDFS). For more information on the complete list of connectors and datasets that Talend supports, see `Introducing Talend Connectors `_. - -:ref:`Back to top ` - -.. _supported_tools_os_sys_versions: - -Supported Tool and Operating System Versions -====================== -Talend was tested using the following: - -* Talend version 7.4.1M6 -* Windows 10 -* SQream version 2021.1 -* JDBC version - -:ref:`Back to top ` - -.. _known_issues: - -Known Issues -=========================== -The the list below describes the following known issues as of 6/1/2021: - -* Schemas not displayed for tables with identical names. - -:ref:`Back to top ` - -.. _related_links: - -Related Links -=============== -The following is a list of links relevant to the Talend connector: - -* `Talend Home page `_ -* `Talend Community page `_ -* `Talend BugTracker `_ - -Download Links -================== -The following is a list of download links relevant to the Talend connector: - -* `Talend Open Studio for Big Data `_ -* `Latest version of SQream JDBC `_ - -:ref:`Back to top ` - -.. contents:: In this topic: - :local: \ No newline at end of file diff --git a/third_party_tools/client_platforms/test.php b/third_party_tools/client_platforms/test.php deleted file mode 100644 index fef04e699..000000000 --- a/third_party_tools/client_platforms/test.php +++ /dev/null @@ -1,16 +0,0 @@ - diff --git a/third_party_tools/client_platforms/tibco_spotfire.rst b/third_party_tools/client_platforms/tibco_spotfire.rst deleted file mode 100644 index b0a707c51..000000000 --- a/third_party_tools/client_platforms/tibco_spotfire.rst +++ /dev/null @@ -1,387 +0,0 @@ -.. _tibco_spotfire: - - -************************* -Connecting to SQream Using TIBCO Spotfire -************************* -Overview -========= -The **TIBCO Spotfire** software is an analytics solution that enables visualizing and exploring data through dashboards and advanced analytics. - -This document is a Quick Start Guide that describes the following: - -.. contents:: - :local: - :depth: 1 - -Establishing a Connection between TIBCO Spotfire and SQream ------------------ -TIBCO Spotfire supports the following versions: - -* **JDBC driver** - Version 4.5.3 -* **ODBC driver** - Version 4.1.1 - -SQream supports TIBCO Spotfire version 7.12.0. - -The **Establishing a JDBC Connection between TIBCO Spotfire and SQream** section describes the following: - -.. contents:: - :local: - :depth: 1 - -Creating a JDBC Connection -~~~~~~~~~~~ -For TIBCO Spotfire to recognize SQream, you must add the correct JDBC jar file to Spotfire's loaded binary folder. The following is an example of a path to the Spotfire loaded binaries folder: ``C:\tibco\tss\7.12.0\tomcat\bin``. - -For the complete TIBCO Spotfire documentation, see `TIBCO Spotfire® JDBC Data Access Connectivity Details `_. - -Creating an ODBC Connection -~~~~~~~~~~~ -**To create an ODBC connection** - -1. Install and configure ODBC on Windows. - - For more information, see :ref:`Install and Configure ODBC on Windows`. - -#. Launch the TIBCO Spotfire application. - - :: - -#. From the **File** menu click **Add Data Tables**. - - The **Add Database Tables** window is displayed. - -#. Click **Add** and select **Database**. - - The **Open Database** window is displayed. - -#. In the **Data source type** area, select **ODBC SQream** (Odbc Data Provider) and click **Configure**. - - The **Configure Data Source and Connection** window is displayed. - -#. Select **System or user data source** and from the drop-down menu select the DSN of your data source (SQreamDB). - - :: - -#. Provide your database username and password and click **OK**. - - :: - -#. In the **Open Database** window, click **OK**. - - The **Specify Tables and Columns** window is displayed. - -#. In the **Specify Tables and Columns** window, select the checkboxes corresponding to the tables and columns that you want to include in your SQL statement. - - :: - -#. In the **Data source name** field, set your data source name and click **OK**. - - Your data source is displayed in the **Data tables** area. - -#. In the **Add Data Tables** dialog, click **OK** to load the data from your ODBC data source into Spotfire. - -.. note:: Verify that you have checked the SQL statement. - -Creating the SQream Data Source Template -~~~~~~~~~~~ -After creating a connection, you can create your SQream data source template. - -**To create your SQream data source template:** - -1. Log in to the TIBCO Spotfire Server Configuration Tool. - - :: - -#. From the **Configuration** tab, in the **Configuration Start** menu, click **Data Source Templates**. - - The **Data Source Templates** list is displayed. - -#. From the Data Source Templates list do one of the following: - - * Override an existing template: - - 1. In the template text field, select an existing template. - - :: - - 2. Copy and paste your data source template text. - - :: - - * Create a new template: - - 1. Click **New**. - - The **Add Data Source Template** window is displayed. - - .. _creating_sqream_data_source_template: - - 2. In the **Name** field, define your template name. - - :: - - 3. In the **Data Source Template** text field, copy and paste your data source template text. - - The following is an example of a data source template: - - .. code-block:: console - - - SQream - com.sqream.jdbc.SQDriver - jdbc:Sqream://<host>:<port>/database;user=sqream;password=sqream;cluster=true - true - true - false - TABLE,EXTERNAL_TABLE - - - Bool - Integer - - - VARCHAR(2048) - String - - - INT - Integer - - - BIGINT - LongInteger - - - Real - Real - - - Decimal - Float - - - Numeric - Float - - - Date - DATE - - - DateTime - DateTime - - - - - -4. Click **Save configuration**. - - :: - -5. Close and restart your Spotfire server. - -Creating a Data Source -~~~~~~~~~~~ -After creating the SQream data source template, you can create a data source. - -**To create a data source:** - -1. Launch the TIBCO Spotfire application. - - :: - -#. From the **Tools** menu, select **Information Designer**. - - The **Information Designer** window is displayed. - - :: - -#. From the **New** menu, click **Data Source**. - - The **Data Source** tab is displayed. - - :: - -#. Provide the following information: - - * **Name** - define a unique name. - - :: - - * **Type** - use the same type template name you used while configuring your template. See **Step 3** in :ref:`Creating the SQream Data Source Template`. - - :: - - * **Connection URL** - use the standard JDBC connection string, ``:/database``. - - :: - - * **No. of connections** - define a number between **1** and **100**. SQream recommends setting your number of connections to **100**. - - :: - - * **Username and Password** - define your SQream username and password. - -Creating an Information Link -~~~~~~~~~~~ -After creating a data source, you can create an information link. - -**To create an information link**: - -1. From the **Tools** menu, select **Information Designer**. - - The **Information Designer** window is displayed. - - :: - -#. From the **New** menu, click **Information Link**. - - The **Information link** tab is displayed. - -#. From the **Elements** tab, select a column type and click **Add**. - - The column type is added to the **Elements** region as a filter. - - Note the following: - - * You can select procedures from the Elements region. - - :: - - * You can remove an element by selecting an element and clicking **Remove**. - - .. tip:: If the Elements menu is not displayed, you can display it by clicking the **Elements** tab. You can simultaneously select multiple elements by pressing **Ctrl** and making additional selections, and select a range of elements by holding **Shift** and clicking two elements. - -#. If the elements you select originate from more than one data source table, specify a **Join path**. - -5. *Optional* - In the **Description** region, type the description of the information link. - - :: - -#. *Optional* - To filter your data, expand the **Filters** section and do the following: - - 1. From the **Information Link** region, select the element you added in Step 3 above. - - :: - - 2. Click **Add**. - - The **Add Column** window is displayed. - - 3. From the drop-down list, select a column to add a hard filter to and click **OK**. - - The selected column is added to the Filters list. - - 4. Repeat steps 2 and 3 to add filters to additional columns. - - :: - - 5. For each column, from the **Filter Type** drop-down list, select **range** or **values**. - - .. note:: Filtering by range means entering the upper and lower limits of the desired range. Filtering by values means entering the exact values that you want to include in the returned data, separated by semicolon. - - 6. In the **Values** field type the desired values separated with semicolons, or set the upper and lower limits in the **Min Value** and **Max Value** fields. Alternatively, you can type ``?param_name`` in the Values field to use a parameter as the filter for the selected column, where ``param_name`` is the name used to identify the parameter. - - .. note:: Because limits are inclusive, setting the lower limit to **1000** includes the value **1000** in the data table. - - .. note:: When setting upper and lower limits on **String** type columns, ``A`` precedes ``AA``, and a lone letter precedes words beginning with that latter. For example, ``S** precedes **Smith**, indicating that the name ``Smith`` will not be present when you select names from ``D`` to ``S``. The order of characters is standard ASCII. - - For more information on adding filters, see `Adding Hard Filters `_. - -7. *Optional* - To add runtime filtering prompts, expand the **Prompts** section and do the following: - - 1. Click **Add**. - - The **Add Column** window is displayed. - - #. From the **Select column** list, select a column to add a prompt to and click **OK**. - - The selected column is added to the Prompts list. - - #. Repeat **Step 1** to add prompts to additional columns. - - :: - - #. Do the following for each column: - - * Make a selection from the **Prompt Type** drop-down list. - * Select or clear **Mandatory**. - * *Optional* - Set your **Max Selections**. - - For more information on adding prompts, see `Adding Prompts `_. - -8. *Optional* - Expand the **Conditioning** section and specify one of the following conditions: - - * None - * Distinct - * Pivot - - Note that you can edit the Pivot conditioning by selecting **Pivot** and clicking **Edit**. - -9. *Optional* - Expand the **Parameters** section and define your parameters. - - :: - -10. *Optional* - Expand the **Properties** section and define your properties. - - :: - -11. *Optional* - Expand the **Caching** section and enable or disable whether your information link can be cached. - - :: - -12. Click **Save**. - - The **Save As** window is displayed. - -13. In the tree, select where you want to save the information link. - - :: - -14. In the **Name** field, type a name and description for the information link. - - :: - - -15. Click **Save**. - - The new information link is added to the library and can be accessed by other users. - -.. tip:: You can test the information link directly by clicking **Open Data**. You can also view and edit the SQL belonging to the information link by clicking **SQL**. - -For more information on the Information Link attributes, see `Information Link Tab `_. - -Troubleshooting -------------- -The **Troubleshooting** section describes the following scenarios: - -.. contents:: - :local: - :depth: 1 - -The JDBC Driver does not Support Boolean, Decimal, or Numeric Types -~~~~~~~~~~~ -When attempting to load data, the the Boolean, Decimal, or Numeric column types are not supported and generate the following error: - -.. code-block:: console - - Failed to execute query: Unsupported JDBC data type in query result: Bool (HRESULT: 80131500) - -The error above is resolved by casting the columns as follows: - -* ``Bool`` columns to ``INT``. -* ``Decimal`` and ``Numeric`` columns to ``REAL``. - -For more information, see the following: - -* **Resolving this error** - `Details on Change Data Types `_. - -* **Supported data types** - :ref:`Data Types`. - -Information Services do not Support Live Queries -~~~~~~~~~~~ -TIBCO Spotfire data connectors support live queries, but no APIs currently exist for creating custom data connectors. This is resolved by creating a customized SQream adapter using TIBCO's **Data Virtualization (TDV)** or the **Spotfire Advanced Services (ADS)**. These can be used from the built-in TDV connector to enable live queries. - -This resolution applies to JDBC and ODBC drivers. diff --git a/third_party_tools/index.rst b/third_party_tools/index.rst index 1052f9f27..ee581e337 100644 --- a/third_party_tools/index.rst +++ b/third_party_tools/index.rst @@ -12,7 +12,6 @@ This section provides information about the following third party tools: :glob: :titlesonly: - client_platforms/index client_drivers/index If you need a tool that SQream does not support, contact SQream Support or your SQream account manager for more information. \ No newline at end of file diff --git a/troubleshooting/index.rst b/troubleshooting/index.rst index efbcdd412..985008e09 100644 --- a/troubleshooting/index.rst +++ b/troubleshooting/index.rst @@ -15,11 +15,6 @@ The **Troubleshooting** page describes solutions to the following issues: examining_logs identifying_configuration_issues lock_related_issues - sas_viya_related_issues - tableau_related_issues - solving_code_126_odbc_errors log_related_issues - node_js_related_issues core_dumping_related_issues - sqream_sql_installation_related_issues information_for_support \ No newline at end of file diff --git a/troubleshooting/node_js_related_issues.rst b/troubleshooting/node_js_related_issues.rst deleted file mode 100644 index b3b95b2ed..000000000 --- a/troubleshooting/node_js_related_issues.rst +++ /dev/null @@ -1,54 +0,0 @@ -.. _node_js_related_issues: - -*********************** -Node.js Related Issues -*********************** -The **Node.js Related Issues** page describes how to resolve the following common issues: - -.. toctree:: - :maxdepth: 2 - :glob: - :titlesonly: - -Preventing Heap Out of Memory Errors --------------------------------------------- - -Some workloads may cause Node.JS to fail with the error: - -.. code-block:: none - - FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory - -To prevent this error, modify the heap size configuration by setting the ``--max-old-space-size`` run flag. - -For example, set the space size to 2GB: - -.. code-block:: console - - $ node --max-old-space-size=2048 my-application.js - -Providing Support for BIGINT Data Type ------------------------- - -The Node.JS connector supports fetching ``BIGINT`` values from SQream DB. However, some applications may encounter an error when trying to serialize those values. - -The error that appears is: -.. code-block:: none - - TypeError: Do not know how to serialize a BigInt - -This is because JSON specification do not support BIGINT values, even when supported by Javascript engines. - -To resolve this issue, objects with BIGINT values should be converted to string before serializing, and converted back after deserializing. - -For example: - -.. code-block:: javascript - - const rows = [{test: 1n}] - const json = JSON.stringify(rows, , (key, value) => - typeof value === 'bigint' - ? value.toString() - : value // return everything else unchanged - )); - console.log(json); // [{"test": "1"}] \ No newline at end of file diff --git a/troubleshooting/sas_viya_related_issues.rst b/troubleshooting/sas_viya_related_issues.rst deleted file mode 100644 index 6661dec95..000000000 --- a/troubleshooting/sas_viya_related_issues.rst +++ /dev/null @@ -1,55 +0,0 @@ -.. _sas_viya_related_issues: - -*********************** -SAS Viya Related Issues -*********************** - -This section describes the following best practices and troubleshooting procedures when connecting to SQream using SAS Viya: - -.. contents:: - :local: - -Inserting Only Required Data ------- -When using Tableau, SQream recommends using only data that you need, as described below: - -* Insert only the data sources you need into SAS Viya, excluding tables that don’t require analysis. - - :: - - -* To increase query performance, add filters before analyzing. Every modification you make while analyzing data queries the SQream database, sometimes several times. Adding filters to the datasource before exploring limits the amount of data analyze and increases query performance. - - -Creating a Separate Service for SAS Viya ------- -SQream recommends creating a separate service for SAS Viya with the DWLM. This reduces the impact that Tableau has on other applications and processes, such as ETL. In addition, this works in conjunction with the load balancer to ensure good performance. - -Locating the SQream JDBC Driver ------- -In some cases, SAS Viya cannot locate the SQream JDBC driver, generating the following error message: - -.. code-block:: text - - java.lang.ClassNotFoundException: com.sqream.jdbc.SQDriver - -**To locate the SQream JDBC driver:** - -1. Verify that you have placed the JDBC driver in a directory that SAS Viya can access. - - :: - - -2. Verify that the classpath in your SAS program is correct, and that SAS Viya can access the file that it references. - - :: - - -3. Restart SAS Viya. - -For more troubleshooting assistance, see the `SQream Support Portal `_. - - -Supporting TEXT ------- -In SAS Viya versions lower than 4.0, casting ``TEXT`` to ``CHAR`` changes the size to 1,024, such as when creating a table including a ``TEXT`` column. This is resolved by casting ``TEXT`` into ``CHAR`` when using the JDBC driver. diff --git a/troubleshooting/solving_code_126_odbc_errors.rst b/troubleshooting/solving_code_126_odbc_errors.rst deleted file mode 100644 index 2e652b113..000000000 --- a/troubleshooting/solving_code_126_odbc_errors.rst +++ /dev/null @@ -1,14 +0,0 @@ -.. _solving_code_126_odbc_errors: - -*********************** -Solving "Code 126" ODBC Errors -*********************** -After installing the ODBC driver, you may experience the following error: - -.. code-block:: none - - The setup routines for the SQreamDriver64 ODBC driver could not be loaded due to system error - code 126: The specified module could not be found. - (c:\Program Files\SQream Technologies\ODBC Driver\sqreamOdbc64.dll) - -This is an issue with the Visual Studio Redistributable packages. Verify you've correctly installed them, as described in the :ref:`Visual Studio 2015 Redistributables ` section above. diff --git a/troubleshooting/sqream_sql_installation_related_issues.rst b/troubleshooting/sqream_sql_installation_related_issues.rst deleted file mode 100644 index 8225a2f18..000000000 --- a/troubleshooting/sqream_sql_installation_related_issues.rst +++ /dev/null @@ -1,33 +0,0 @@ -.. _sqream_sql_installation_related_issues: - -*********************** -SQream SQL Installation Related Issues -*********************** - -The **SQream SQL Installation Related Issues** page describes how to resolve SQream SQL installation related issues. - -Upon running sqream sql for the first time, you may get an error ``error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory``. - -Solving this error requires installing the ncruses or libtinfo libraries, depending on your operating system. - -* Ubuntu: - - #. Install ``libtinfo``: - - ``$ sudo apt-get install -y libtinfo`` - #. Depending on your Ubuntu version, you may need to create a symbolic link to the newer libtinfo that was installed. - - For example, if ``libtinfo`` was installed as ``/lib/x86_64-linux-gnu/libtinfo.so.6.2``: - - ``$ sudo ln -s /lib/x86_64-linux-gnu/libtinfo.so.6.2 /lib/x86_64-linux-gnu/libtinfo.so.5`` - -* CentOS / RHEL: - - #. Install ``ncurses``: - - ``$ sudo yum install -y ncurses-libs`` - #. Depending on your RHEL version, you may need to create a symbolic link to the newer libtinfo that was installed. - - For example, if ``libtinfo`` was installed as ``/usr/lib64/libtinfo.so.6``: - - ``$ sudo ln -s /usr/lib64/libtinfo.so.6 /usr/lib64/libtinfo.so.5`` \ No newline at end of file diff --git a/troubleshooting/tableau_related_issues.rst b/troubleshooting/tableau_related_issues.rst deleted file mode 100644 index 99b4a04dd..000000000 --- a/troubleshooting/tableau_related_issues.rst +++ /dev/null @@ -1,73 +0,0 @@ -.. _tableau_related_issues: - -*********************** -Tableau Related Issues -*********************** -This section describes the following best practices and troubleshooting procedures when connecting to Tableau: - -.. contents:: - :local: - -Inserting Only Required Data -~~~~~~~~~~~~~~~~~~ -When using Tableau, SQream recommends using only data that you need, as described below: - -* Insert only the data sources you need into Tableau, excluding tables that don't require analysis. - - :: - -* To increase query performance, add filters before analyzing. Every modification you make while analyzing data queries the SQream database, sometimes several times. Adding filters to the datasource before exploring limits the amount of data analyze and increases query performance. - -Using Tableau's Table Query Syntax -~~~~~~~~~~~~~~~~~~~ -Dragging your desired tables into the main area in Tableau builds queries based on its own syntax. This helps ensure increased performance, while using views or custom SQL may degrade performance. In addition, SQream recommends using the :ref:`create_view` to create pre-optimized views, which your datasources point to. - -Creating a Separate Service for Tableau -~~~~~~~~~~~~~~~~~~~ -SQream recommends creating a separate service for Tableau with the DWLM. This reduces the impact that Tableau has on other applications and processes, such as ETL. In addition, this works in conjunction with the load balancer to ensure good performance. - -Error Saving Large Quantities of Data as Files -~~~~~~~~~~~~~~~~~~~ -An **FAB9A2C5** error can when saving large quantities of data as files. If you receive this error when writing a connection string, add the ``fetchSize`` parameter to ``1``, as shown below: - -.. code-block:: text - - jdbc:Sqream:///;user=;password=sqream;[; fetchSize=1...] - -For more information on troubleshooting error **FAB9A2C5**, see the `Tableau Knowledge Base `_. - -Troubleshooting Workbook Performance Before Deploying to the Tableau Server -~~~~~~~~~~~~~~~~~~~ -Tableau has a built-in `performance recorder `_ that shows how time is being spent. If you're seeing slow performance, this could be the result of a misconfiguration such as setting concurrency too low. - -Use the Tableau Performance Recorder for viewing the performance of queries run by Tableau. You can use this information to identify queries that can be optimized by using views. - -Troubleshooting Error Codes -~~~~~~~~~~~~~~~~~~~ -Tableau may be unable to locate the SQream JDBC driver. The following message is displayed when Tableau cannot locate the driver: - -.. code-block:: console - - Error Code: 37CE01A3, No suitable driver installed or the URL is incorrect - -**To troubleshoot error codes:** - -If Tableau cannot locate the SQream JDBC driver, do the following: - - 1. Verify that the JDBC driver is located in the correct directory: - - * **Tableau Desktop on Windows:** *C:\Program Files\Tableau\Drivers* - * **Tableau Desktop on MacOS:** *~/Library/Tableau/Drivers* - * **Tableau on Linux**: */opt/tableau/tableau_driver/jdbc* - - 2. Find the file path for the JDBC driver and add it to the Java classpath: - - * **For Linux** - ``export CLASSPATH=;$CLASSPATH`` - - :: - - * **For Windows** - add an environment variable for the classpath: - - - -If you experience issues after restarting Tableau, see the `SQream support portal `_. From 16da90b13dbdcf6e9eaeeacdbd1ba4aa9e290435 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 29 Mar 2022 17:05:38 +0300 Subject: [PATCH 032/316] Update sqream_studio_installation.rst --- installation_guides/sqream_studio_installation.rst | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/installation_guides/sqream_studio_installation.rst b/installation_guides/sqream_studio_installation.rst index 8d6c16546..8646a35ad 100644 --- a/installation_guides/sqream_studio_installation.rst +++ b/installation_guides/sqream_studio_installation.rst @@ -9,11 +9,7 @@ The **Installing SQream Studio** page incudes the following installation guides: :maxdepth: 1 :glob: - installing_studio_on_stand_alone_server installing_prometheus_exporters installing_prometheus_using_binary_packages installing_dashboard_data_collector - - - - + installing_studio_on_stand_alone_server \ No newline at end of file From 4e1393f438ac26520f98726880f4c54bf28dcbf7 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 29 Mar 2022 18:29:02 +0300 Subject: [PATCH 033/316] Replaced VARCHAR with TEXT Replaced *most* instances of VARCHAR with TEXT. I didn't replace all of them because I had some open questions for Shachar (about 20). I am going to merge this now into branch 2020-1 to test if it worked, and will merge it again after updating it in light of Shachar's comments. I will then merge it on the remaining branches. --- data_ingestion/csv.rst | 10 +++---- data_ingestion/inserting_data.rst | 2 +- data_ingestion/orc.rst | 16 ++++++------ data_ingestion/parquet.rst | 14 +++++----- data_type_guides/sql_data_types_string.rst | 2 +- feature_guides/compression.rst | 10 +++---- ...flexible_data_clustering_data_examples.rst | 4 +-- .../performing_basic_sqream_operations.rst | 1 + getting_started/querying_data.rst | 10 +++---- operational_guides/external_tables.rst | 10 +++---- operational_guides/logging.rst | 4 +-- .../optimization_best_practices.rst | 26 ++----------------- operational_guides/s3.rst | 10 +++---- reference/cli/sqream_sql.rst | 4 +-- .../sql_functions/aggregate_functions/avg.rst | 10 +++---- .../aggregate_functions/corr.rst | 10 +++---- .../aggregate_functions/count.rst | 10 +++---- .../aggregate_functions/covar_pop.rst | 10 +++---- .../aggregate_functions/covar_samp.rst | 10 +++---- .../sql_functions/aggregate_functions/max.rst | 10 +++---- .../sql_functions/aggregate_functions/min.rst | 10 +++---- .../aggregate_functions/stddev_pop.rst | 10 +++---- .../aggregate_functions/stddev_samp.rst | 10 +++---- .../sql_functions/aggregate_functions/sum.rst | 10 +++---- .../aggregate_functions/var_pop.rst | 10 +++---- .../aggregate_functions/var_samp.rst | 10 +++---- .../date_and_time/dateadd.rst | 2 +- .../date_and_time/datediff.rst | 2 +- .../date_and_time/datepart.rst | 2 +- .../scalar_functions/date_and_time/trunc.rst | 2 +- .../scalar_functions/numeric/crc64.rst | 5 ++-- .../scalar_functions/string/concat.rst | 17 ++++++------ .../scalar_functions/string/len.rst | 2 +- .../scalar_functions/string/like.rst | 10 +++---- .../scalar_functions/string/regexp_count.rst | 10 +++---- .../scalar_functions/string/regexp_instr.rst | 10 +++---- .../scalar_functions/string/regexp_substr.rst | 10 +++---- .../scalar_functions/string/rlike.rst | 10 +++---- .../scalar_functions/string/substring.rst | 10 +++---- .../window_functions/first_value.rst | 2 +- .../sql_functions/window_functions/lag.rst | 10 +++---- .../sql_functions/window_functions/lead.rst | 10 +++---- .../window_functions/nth_value.rst | 4 +-- .../sql_functions/window_functions/rank.rst | 10 +++---- .../window_functions/row_number.rst | 10 +++---- .../ddl_commands/create_external_table.rst | 6 ++--- .../ddl_commands/create_foreign_table.rst | 6 ++--- .../sql_statements/dml_commands/select.rst | 10 +++---- .../utility_commands/execute_saved_query.rst | 15 +++++------ .../utility_commands/get_ddl.rst | 4 +-- .../utility_commands/save_query.rst | 13 +++++----- reference/sql/sql_syntax/literals.rst | 1 - reference/sql/sql_syntax/subqueries.rst | 10 +++---- reference/sql/sql_syntax/window_functions.rst | 10 +++---- troubleshooting/log_related_issues.rst | 4 +-- 55 files changed, 217 insertions(+), 243 deletions(-) diff --git a/data_ingestion/csv.rst b/data_ingestion/csv.rst index f44c3c9e9..47c6d94a1 100644 --- a/data_ingestion/csv.rst +++ b/data_ingestion/csv.rst @@ -83,14 +83,14 @@ We will make note of the file structure to create a matching ``CREATE TABLE`` st CREATE TABLE nba ( - Name varchar(40), - Team varchar(40), + Name text(40), + Team text(40), Number tinyint, - Position varchar(2), + Position text(2), Age tinyint, - Height varchar(4), + Height text(4), Weight real, - College varchar(40), + College text(40), Salary float ); diff --git a/data_ingestion/inserting_data.rst b/data_ingestion/inserting_data.rst index 660cd61bd..86bd08103 100644 --- a/data_ingestion/inserting_data.rst +++ b/data_ingestion/inserting_data.rst @@ -98,7 +98,7 @@ Unsupported Data Types SQream DB doesn't support the entire set of features that some other database systems may have, such as ``ARRAY``, ``BLOB``, ``ENUM``, ``SET``, etc. -These data types will have to be converted before load. For example, ``ENUM`` can often be stored as a ``VARCHAR``. +These data types will have to be converted before load. For example, ``ENUM`` can often be stored as a ``TEXT``. Handing Extended Errors ---------------------------- diff --git a/data_ingestion/orc.rst b/data_ingestion/orc.rst index d199e958e..de10c5ce4 100644 --- a/data_ingestion/orc.rst +++ b/data_ingestion/orc.rst @@ -186,14 +186,14 @@ We will make note of the file structure to create a matching ``CREATE FOREIGN TA CREATE FOREIGN TABLE ext_nba ( - Name VARCHAR(40), - Team VARCHAR(40), + Name TEXT(40), + Team TEXT(40), Number BIGINT, - Position VARCHAR(2), + Position TEXT(2), Age BIGINT, - Height VARCHAR(4), + Height TEXT(4), Weight BIGINT, - College VARCHAR(40), + College TEXT(40), Salary FLOAT ) WRAPPER orc_fdw @@ -288,7 +288,7 @@ Loading a table from a directory of ORC files on HDFS .. code-block:: postgres CREATE FOREIGN TABLE ext_users - (id INT NOT NULL, name VARCHAR(30) NOT NULL, email VARCHAR(50) NOT NULL) + (id INT NOT NULL, name TEXT(30) NOT NULL, email VARCHAR(50) NOT NULL) WRAPPER orc_fdw OPTIONS ( @@ -303,7 +303,7 @@ Loading a table from a bucket of files on S3 .. code-block:: postgres CREATE FOREIGN TABLE ext_users - (id INT NOT NULL, name VARCHAR(30) NOT NULL, email VARCHAR(50) NOT NULL) + (id INT NOT NULL, name TEXT(30) NOT NULL, email VARCHAR(50) NOT NULL) WRAPPER orc_fdw OPTIONS ( LOCATION = 's3://pp-secret-bucket/users/*.ORC', @@ -312,4 +312,4 @@ Loading a table from a bucket of files on S3 ) ; - CREATE TABLE users AS SELECT * FROM ext_users; + CREATE TABLE users AS SELECT * FROM ext_users; \ No newline at end of file diff --git a/data_ingestion/parquet.rst b/data_ingestion/parquet.rst index 800c3122a..4579deb82 100644 --- a/data_ingestion/parquet.rst +++ b/data_ingestion/parquet.rst @@ -167,14 +167,14 @@ We will make note of the file structure to create a matching ``CREATE EXTERNAL T CREATE FOREIGN TABLE ext_nba ( - Name VARCHAR(40), - Team VARCHAR(40), + Name TEXT(40), + Team TEXT(40), Number BIGINT, - Position VARCHAR(2), + Position TEXT(2), Age BIGINT, - Height VARCHAR(4), + Height TEXT(4), Weight BIGINT, - College VARCHAR(40), + College TEXT(40), Salary FLOAT ) WRAPPER parquet_fdw @@ -269,7 +269,7 @@ Loading a table from a directory of Parquet files on HDFS .. code-block:: postgres CREATE FOREIGN TABLE ext_users - (id INT NOT NULL, name VARCHAR(30) NOT NULL, email VARCHAR(50) NOT NULL) + (id INT NOT NULL, name TEXT(30) NOT NULL, email TEXT(50) NOT NULL) WRAPPER parquet_fdw OPTIONS ( @@ -284,7 +284,7 @@ Loading a table from a bucket of files on S3 .. code-block:: postgres CREATE FOREIGN TABLE ext_users - (id INT NOT NULL, name VARCHAR(30) NOT NULL, email VARCHAR(50) NOT NULL) + (id INT NOT NULL, name TEXT(30) NOT NULL, email TEXT(50) NOT NULL) WRAPPER parquet_fdw OPTIONS ( LOCATION = 's3://pp-secret-bucket/users/*.parquet', diff --git a/data_type_guides/sql_data_types_string.rst b/data_type_guides/sql_data_types_string.rst index beb970b8d..0d977b6d2 100644 --- a/data_type_guides/sql_data_types_string.rst +++ b/data_type_guides/sql_data_types_string.rst @@ -3,7 +3,7 @@ ************************* String ************************* -``TEXT`` and ``VARCHAR`` are types designed for storing text or strings of characters. +``TEXT`` is designed for storing text or strings of characters. SQream separates ASCII (``VARCHAR``) and UTF-8 representations (``TEXT``). diff --git a/feature_guides/compression.rst b/feature_guides/compression.rst index 710641036..96c051ff4 100644 --- a/feature_guides/compression.rst +++ b/feature_guides/compression.rst @@ -108,7 +108,7 @@ The following two are equivalent: CREATE TABLE t ( x INT, - y VARCHAR(50) + y TEXT(50) ); In this version, the default compression is specified explicitly: @@ -117,7 +117,7 @@ In this version, the default compression is specified explicitly: CREATE TABLE t ( x INT CHECK('CS "default"'), - y VARCHAR(50) CHECK('CS "default"') + y TEXT(50) CHECK('CS "default"') ); Forcing no compression (flat) @@ -130,7 +130,7 @@ in order to reduce CPU or GPU resource utilization at the expense of increased I CREATE TABLE t ( x INT NOT NULL CHECK('CS "flat"'), -- This column won't be compressed - y VARCHAR(50) -- This column will still be compressed automatically + y TEXT(50) -- This column will still be compressed automatically ); @@ -146,8 +146,8 @@ For example: CREATE TABLE t ( id BIGINT NOT NULL CHECK('CS "sequence"'), - y VARCHAR(110) CHECK('CS "lz4"'), -- General purpose text compression - z VARCHAR(80) CHECK('CS "dict"'), -- Low cardinality column + y TEXT(110) CHECK('CS "lz4"'), -- General purpose text compression + z TEXT(80) CHECK('CS "dict"'), -- Low cardinality column ); diff --git a/feature_guides/flexible_data_clustering_data_examples.rst b/feature_guides/flexible_data_clustering_data_examples.rst index 0c720ff04..bf08a111a 100644 --- a/feature_guides/flexible_data_clustering_data_examples.rst +++ b/feature_guides/flexible_data_clustering_data_examples.rst @@ -16,7 +16,7 @@ The following is an example of syntax for creating a clustered table on a table .. code-block:: postgres CREATE TABLE users ( - name VARCHAR(30) NOT NULL, + name text(30) NOT NULL, start_date datetime not null, - country VARCHAR(30) DEFAULT 'Unknown' NOT NULL + country text(30) DEFAULT 'Unknown' NOT NULL ) CLUSTER BY country; \ No newline at end of file diff --git a/getting_started/performing_basic_sqream_operations.rst b/getting_started/performing_basic_sqream_operations.rst index 81ea9b05f..1b0f60ba3 100644 --- a/getting_started/performing_basic_sqream_operations.rst +++ b/getting_started/performing_basic_sqream_operations.rst @@ -12,6 +12,7 @@ After installing SQream you can perform the operations described on this page: running_the_sqream_sql_client creating_your_first_table creating_a_database + querying_data listing_tables inserting_rows running_queries diff --git a/getting_started/querying_data.rst b/getting_started/querying_data.rst index 36bf9e78b..7b6b46aed 100644 --- a/getting_started/querying_data.rst +++ b/getting_started/querying_data.rst @@ -11,14 +11,14 @@ To begin familiarizing yourself with querying data, you can create the following CREATE TABLE nba ( - Name varchar(40), - Team varchar(40), + Name text(40), + Team text(40), Number tinyint, - Position varchar(2), + Position text(2), Age tinyint, - Height varchar(4), + Height text(4), Weight real, - College varchar(40), + College text(40), Salary float ); diff --git a/operational_guides/external_tables.rst b/operational_guides/external_tables.rst index 005dc961f..6ee2f67a0 100644 --- a/operational_guides/external_tables.rst +++ b/operational_guides/external_tables.rst @@ -52,14 +52,14 @@ Based on the source file structure, we we :ref:`create an external table create table animals(id int not null, name varchar(30) not null, is_angry bool not null); + farm=> create table animals(id int not null, name text(30) not null, is_angry bool not null); executed time: 0.011940s @@ -303,7 +303,7 @@ Assuming a file containing SQL statements (separated by semicolons): $ cat some_queries.sql CREATE TABLE calm_farm_animals - ( id INT IDENTITY(0, 1), name VARCHAR(30) + ( id INT IDENTITY(0, 1), name TEXT(30) ); INSERT INTO calm_farm_animals (name) diff --git a/reference/sql/sql_functions/aggregate_functions/avg.rst b/reference/sql/sql_functions/aggregate_functions/avg.rst index be0294d46..4768061c8 100644 --- a/reference/sql/sql_functions/aggregate_functions/avg.rst +++ b/reference/sql/sql_functions/aggregate_functions/avg.rst @@ -62,14 +62,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - "Name" varchar(40), - "Team" varchar(40), + "Name" text(40), + "Team" text(40), "Number" tinyint, - "Position" varchar(2), + "Position" text(2), "Age" tinyint, - "Height" varchar(4), + "Height" text(4), "Weight" real, - "College" varchar(40), + "College" text(40), "Salary" float ); diff --git a/reference/sql/sql_functions/aggregate_functions/corr.rst b/reference/sql/sql_functions/aggregate_functions/corr.rst index 212ab89d2..5963c835f 100644 --- a/reference/sql/sql_functions/aggregate_functions/corr.rst +++ b/reference/sql/sql_functions/aggregate_functions/corr.rst @@ -51,14 +51,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - "Name" varchar(40), - "Team" varchar(40), + "Name" text(40), + "Team" text(40), "Number" tinyint, - "Position" varchar(2), + "Position" text(2), "Age" tinyint, - "Height" varchar(4), + "Height" text(4), "Weight" real, - "College" varchar(40), + "College" text(40), "Salary" float ); diff --git a/reference/sql/sql_functions/aggregate_functions/count.rst b/reference/sql/sql_functions/aggregate_functions/count.rst index 803e529c0..133d658f4 100644 --- a/reference/sql/sql_functions/aggregate_functions/count.rst +++ b/reference/sql/sql_functions/aggregate_functions/count.rst @@ -67,14 +67,14 @@ The examples in this section are based on a table named ``nba``, structured as f CREATE TABLE nba ( - "Name" varchar(40), - "Team" varchar(40), + "Name" text(40), + "Team" text(40), "Number" tinyint, - "Position" varchar(2), + "Position" text(2), "Age" tinyint, - "Height" varchar(4), + "Height" text(4), "Weight" real, - "College" varchar(40), + "College" text(40), "Salary" float ); diff --git a/reference/sql/sql_functions/aggregate_functions/covar_pop.rst b/reference/sql/sql_functions/aggregate_functions/covar_pop.rst index c0d7cd35d..24300b5d7 100644 --- a/reference/sql/sql_functions/aggregate_functions/covar_pop.rst +++ b/reference/sql/sql_functions/aggregate_functions/covar_pop.rst @@ -55,14 +55,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - "Name" varchar(40), - "Team" varchar(40), + "Name" text(40), + "Team" text(40), "Number" tinyint, - "Position" varchar(2), + "Position" text(2), "Age" tinyint, - "Height" varchar(4), + "Height" text(4), "Weight" real, - "College" varchar(40), + "College" text(40), "Salary" float ); diff --git a/reference/sql/sql_functions/aggregate_functions/covar_samp.rst b/reference/sql/sql_functions/aggregate_functions/covar_samp.rst index 29d7b7493..2c8451023 100644 --- a/reference/sql/sql_functions/aggregate_functions/covar_samp.rst +++ b/reference/sql/sql_functions/aggregate_functions/covar_samp.rst @@ -56,14 +56,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - "Name" varchar(40), - "Team" varchar(40), + "Name" text(40), + "Team" text(40), "Number" tinyint, - "Position" varchar(2), + "Position" text(2), "Age" tinyint, - "Height" varchar(4), + "Height" text(4), "Weight" real, - "College" varchar(40), + "College" text(40), "Salary" float ); diff --git a/reference/sql/sql_functions/aggregate_functions/max.rst b/reference/sql/sql_functions/aggregate_functions/max.rst index 529e2230d..994a3aaca 100644 --- a/reference/sql/sql_functions/aggregate_functions/max.rst +++ b/reference/sql/sql_functions/aggregate_functions/max.rst @@ -53,14 +53,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - "Name" varchar(40), - "Team" varchar(40), + "Name" text(40), + "Team" text(40), "Number" tinyint, - "Position" varchar(2), + "Position" text(2), "Age" tinyint, - "Height" varchar(4), + "Height" text(4), "Weight" real, - "College" varchar(40), + "College" text(40), "Salary" float ); diff --git a/reference/sql/sql_functions/aggregate_functions/min.rst b/reference/sql/sql_functions/aggregate_functions/min.rst index d488d87fc..dd4d39177 100644 --- a/reference/sql/sql_functions/aggregate_functions/min.rst +++ b/reference/sql/sql_functions/aggregate_functions/min.rst @@ -53,14 +53,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - "Name" varchar(40), - "Team" varchar(40), + "Name" text(40), + "Team" text(40), "Number" tinyint, - "Position" varchar(2), + "Position" text(2), "Age" tinyint, - "Height" varchar(4), + "Height" text(4), "Weight" real, - "College" varchar(40), + "College" text(40), "Salary" float ); diff --git a/reference/sql/sql_functions/aggregate_functions/stddev_pop.rst b/reference/sql/sql_functions/aggregate_functions/stddev_pop.rst index 5a8a7e677..8687c0e76 100644 --- a/reference/sql/sql_functions/aggregate_functions/stddev_pop.rst +++ b/reference/sql/sql_functions/aggregate_functions/stddev_pop.rst @@ -58,14 +58,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - "Name" varchar(40), - "Team" varchar(40), + "Name" text(40), + "Team" text(40), "Number" tinyint, - "Position" varchar(2), + "Position" text(2), "Age" tinyint, - "Height" varchar(4), + "Height" text(4), "Weight" real, - "College" varchar(40), + "College" text(40), "Salary" float ); diff --git a/reference/sql/sql_functions/aggregate_functions/stddev_samp.rst b/reference/sql/sql_functions/aggregate_functions/stddev_samp.rst index 0328e2241..81c7a1f51 100644 --- a/reference/sql/sql_functions/aggregate_functions/stddev_samp.rst +++ b/reference/sql/sql_functions/aggregate_functions/stddev_samp.rst @@ -62,14 +62,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - "Name" varchar(40), - "Team" varchar(40), + "Name" text(40), + "Team" text(40), "Number" tinyint, - "Position" varchar(2), + "Position" text(2), "Age" tinyint, - "Height" varchar(4), + "Height" text(4), "Weight" real, - "College" varchar(40), + "College" text(40), "Salary" float ); diff --git a/reference/sql/sql_functions/aggregate_functions/sum.rst b/reference/sql/sql_functions/aggregate_functions/sum.rst index e8f648894..51d7f6d97 100644 --- a/reference/sql/sql_functions/aggregate_functions/sum.rst +++ b/reference/sql/sql_functions/aggregate_functions/sum.rst @@ -65,14 +65,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - "Name" varchar(40), - "Team" varchar(40), + "Name" text(40), + "Team" text(40), "Number" tinyint, - "Position" varchar(2), + "Position" text(2), "Age" tinyint, - "Height" varchar(4), + "Height" text(4), "Weight" real, - "College" varchar(40), + "College" text(40), "Salary" float ); diff --git a/reference/sql/sql_functions/aggregate_functions/var_pop.rst b/reference/sql/sql_functions/aggregate_functions/var_pop.rst index 4ddf45a1e..de078a3ae 100644 --- a/reference/sql/sql_functions/aggregate_functions/var_pop.rst +++ b/reference/sql/sql_functions/aggregate_functions/var_pop.rst @@ -58,14 +58,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - "Name" varchar(40), - "Team" varchar(40), + "Name" text(40), + "Team" text(40), "Number" tinyint, - "Position" varchar(2), + "Position" text(2), "Age" tinyint, - "Height" varchar(4), + "Height" text(4), "Weight" real, - "College" varchar(40), + "College" text(40), "Salary" float ); diff --git a/reference/sql/sql_functions/aggregate_functions/var_samp.rst b/reference/sql/sql_functions/aggregate_functions/var_samp.rst index 6f0c91e63..cc9721225 100644 --- a/reference/sql/sql_functions/aggregate_functions/var_samp.rst +++ b/reference/sql/sql_functions/aggregate_functions/var_samp.rst @@ -63,14 +63,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - "Name" varchar(40), - "Team" varchar(40), + "Name" text(40), + "Team" text(40), "Number" tinyint, - "Position" varchar(2), + "Position" text(2), "Age" tinyint, - "Height" varchar(4), + "Height" text(4), "Weight" real, - "College" varchar(40), + "College" text(40), "Salary" float ); diff --git a/reference/sql/sql_functions/scalar_functions/date_and_time/dateadd.rst b/reference/sql/sql_functions/scalar_functions/date_and_time/dateadd.rst index cff5268e6..240b0bf2e 100644 --- a/reference/sql/sql_functions/scalar_functions/date_and_time/dateadd.rst +++ b/reference/sql/sql_functions/scalar_functions/date_and_time/dateadd.rst @@ -106,7 +106,7 @@ For these examples, consider the following table and contents: .. code-block:: postgres - CREATE TABLE cool_dates(name VARCHAR(40), d DATE, dt DATETIME); + CREATE TABLE cool_dates(name TEXT(40), d DATE, dt DATETIME); INSERT INTO cool_dates VALUES ('Marty McFly goes back to this time','1955-11-05','1955-11-05 01:21:00.000') , ('Marty McFly came from this time', '1985-10-26', '1985-10-26 01:22:00.000') diff --git a/reference/sql/sql_functions/scalar_functions/date_and_time/datediff.rst b/reference/sql/sql_functions/scalar_functions/date_and_time/datediff.rst index 5c91a88d9..1af8827de 100644 --- a/reference/sql/sql_functions/scalar_functions/date_and_time/datediff.rst +++ b/reference/sql/sql_functions/scalar_functions/date_and_time/datediff.rst @@ -100,7 +100,7 @@ For these examples, consider the following table and contents: .. code-block:: postgres - CREATE TABLE cool_dates(name VARCHAR(40), d DATE, dt DATETIME); + CREATE TABLE cool_dates(name TEXT(40), d DATE, dt DATETIME); INSERT INTO cool_dates VALUES ('Marty McFly goes back to this time','1955-11-05','1955-11-05 01:21:00.000') , ('Marty McFly came from this time', '1985-10-26', '1985-10-26 01:22:00.000') diff --git a/reference/sql/sql_functions/scalar_functions/date_and_time/datepart.rst b/reference/sql/sql_functions/scalar_functions/date_and_time/datepart.rst index 8a43a1472..a779663b5 100644 --- a/reference/sql/sql_functions/scalar_functions/date_and_time/datepart.rst +++ b/reference/sql/sql_functions/scalar_functions/date_and_time/datepart.rst @@ -109,7 +109,7 @@ For these examples, consider the following table and contents: .. code-block:: postgres - CREATE TABLE cool_dates(name VARCHAR(40), d DATE, dt DATETIME); + CREATE TABLE cool_dates(name TEXT(40), d DATE, dt DATETIME); INSERT INTO cool_dates VALUES ('Marty McFly goes back to this time','1955-11-05','1955-11-05 01:21:00.000') , ('Marty McFly came from this time', '1985-10-26', '1985-10-26 01:22:00.000') diff --git a/reference/sql/sql_functions/scalar_functions/date_and_time/trunc.rst b/reference/sql/sql_functions/scalar_functions/date_and_time/trunc.rst index d9d791cc3..1e888cfe5 100644 --- a/reference/sql/sql_functions/scalar_functions/date_and_time/trunc.rst +++ b/reference/sql/sql_functions/scalar_functions/date_and_time/trunc.rst @@ -104,7 +104,7 @@ For these examples, consider the following table and contents: .. code-block:: postgres - CREATE TABLE cool_dates(name VARCHAR(40), d DATE, dt DATETIME); + CREATE TABLE cool_dates(name TEXT(40), d DATE, dt DATETIME); INSERT INTO cool_dates VALUES ('Marty McFly goes back to this time','1955-11-05','1955-11-05 01:21:00.000') , ('Marty McFly came from this time', '1985-10-26', '1985-10-26 01:22:00.000') diff --git a/reference/sql/sql_functions/scalar_functions/numeric/crc64.rst b/reference/sql/sql_functions/scalar_functions/numeric/crc64.rst index 7dbd6ddf1..105dae47c 100644 --- a/reference/sql/sql_functions/scalar_functions/numeric/crc64.rst +++ b/reference/sql/sql_functions/scalar_functions/numeric/crc64.rst @@ -25,7 +25,7 @@ Arguments * - Parameter - Description * - ``expr`` - - Text expression (``VARCHAR``, ``TEXT``) + - Text expression (``TEXT``) Returns ============ @@ -54,5 +54,4 @@ Calculate a CRC-64 hash of a string . as t(x); crc64 -------------------- - -9085161068710498500 - + -9085161068710498500 \ No newline at end of file diff --git a/reference/sql/sql_functions/scalar_functions/string/concat.rst b/reference/sql/sql_functions/scalar_functions/string/concat.rst index 0409216cd..c612a9bdd 100644 --- a/reference/sql/sql_functions/scalar_functions/string/concat.rst +++ b/reference/sql/sql_functions/scalar_functions/string/concat.rst @@ -48,14 +48,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - Name varchar(40), - Team varchar(40), + Name text(40), + Team text(40), Number tinyint, - Position varchar(2), + Position text(2), Age tinyint, - Height varchar(4), + Height text(4), Weight real, - College varchar(40), + College text(40), Salary float ); @@ -76,7 +76,7 @@ Convert values to string types before concatenation .. code-block:: psql - nba=> SELECT ("Age" :: VARCHAR(2)) || "Name" FROM nba ORDER BY 1 DESC LIMIT 5; + nba=> SELECT ("Age" :: TEXT(2)) || "Name" FROM nba ORDER BY 1 DESC LIMIT 5; ?column? ---------------- 40Tim Duncan @@ -116,12 +116,11 @@ Add a space and concatenate it first to bypass the space trimming issue .. code-block:: psql - nba=> SELECT ("Age" :: VARCHAR(2) || (' ' || "Name")) FROM nba ORDER BY 1 DESC LIMIT 5; + nba=> SELECT ("Age" :: TEXT(2) || (' ' || "Name")) FROM nba ORDER BY 1 DESC LIMIT 5; ?column? ----------------- 40 Tim Duncan 40 Kevin Garnett 40 Andre Miller 39 Vince Carter - 39 Pablo Prigioni - + 39 Pablo Prigioni \ No newline at end of file diff --git a/reference/sql/sql_functions/scalar_functions/string/len.rst b/reference/sql/sql_functions/scalar_functions/string/len.rst index d3cba24b2..fdd671423 100644 --- a/reference/sql/sql_functions/scalar_functions/string/len.rst +++ b/reference/sql/sql_functions/scalar_functions/string/len.rst @@ -49,7 +49,7 @@ For these examples, consider the following table and contents: .. code-block:: postgres - CREATE TABLE jabberwocky(line VARCHAR(50)); + CREATE TABLE jabberwocky(line TEXT(50)); INSERT INTO jabberwocky VALUES ($$'Twas brillig, and the slithy toves$$), (' Did gyre and gimble in the wabe:') diff --git a/reference/sql/sql_functions/scalar_functions/string/like.rst b/reference/sql/sql_functions/scalar_functions/string/like.rst index 4640ba9be..ce5ca4942 100644 --- a/reference/sql/sql_functions/scalar_functions/string/like.rst +++ b/reference/sql/sql_functions/scalar_functions/string/like.rst @@ -83,14 +83,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - Name varchar(40), - Team varchar(40), + Name text(40), + Team text(40), Number tinyint, - Position varchar(2), + Position text(2), Age tinyint, - Height varchar(4), + Height text(4), Weight real, - College varchar(40), + College text(40), Salary float ); diff --git a/reference/sql/sql_functions/scalar_functions/string/regexp_count.rst b/reference/sql/sql_functions/scalar_functions/string/regexp_count.rst index 5f3bd75a0..26191eccc 100644 --- a/reference/sql/sql_functions/scalar_functions/string/regexp_count.rst +++ b/reference/sql/sql_functions/scalar_functions/string/regexp_count.rst @@ -99,14 +99,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - "Name" varchar(40), - "Team" varchar(40), + "Name" text(40), + "Team" text(40), "Number" tinyint, - "Position" varchar(2), + "Position" text(2), "Age" tinyint, - "Height" varchar(4), + "Height" text(4), "Weight" real, - "College" varchar(40), + "College" text(40), "Salary" float ); diff --git a/reference/sql/sql_functions/scalar_functions/string/regexp_instr.rst b/reference/sql/sql_functions/scalar_functions/string/regexp_instr.rst index f401fdfff..d72f0af4f 100644 --- a/reference/sql/sql_functions/scalar_functions/string/regexp_instr.rst +++ b/reference/sql/sql_functions/scalar_functions/string/regexp_instr.rst @@ -104,14 +104,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - "Name" varchar(40), - "Team" varchar(40), + "Name" text(40), + "Team" text(40), "Number" tinyint, - "Position" varchar(2), + "Position" text(2), "Age" tinyint, - "Height" varchar(4), + "Height" text(4), "Weight" real, - "College" varchar(40), + "College" text(40), "Salary" float ); diff --git a/reference/sql/sql_functions/scalar_functions/string/regexp_substr.rst b/reference/sql/sql_functions/scalar_functions/string/regexp_substr.rst index 1730d6ebf..36611424e 100644 --- a/reference/sql/sql_functions/scalar_functions/string/regexp_substr.rst +++ b/reference/sql/sql_functions/scalar_functions/string/regexp_substr.rst @@ -104,14 +104,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - "Name" varchar(40), - "Team" varchar(40), + "Name" text(40), + "Team" text(40), "Number" tinyint, - "Position" varchar(2), + "Position" text(2), "Age" tinyint, - "Height" varchar(4), + "Height" text(4), "Weight" real, - "College" varchar(40), + "College" text(40), "Salary" float ); diff --git a/reference/sql/sql_functions/scalar_functions/string/rlike.rst b/reference/sql/sql_functions/scalar_functions/string/rlike.rst index 324a6e525..3c61cb959 100644 --- a/reference/sql/sql_functions/scalar_functions/string/rlike.rst +++ b/reference/sql/sql_functions/scalar_functions/string/rlike.rst @@ -99,14 +99,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - Name varchar(40), - Team varchar(40), + Name text(40), + Team text(40), Number tinyint, - Position varchar(2), + Position text(2), Age tinyint, - Height varchar(4), + Height text(4), Weight real, - College varchar(40), + College text(40), Salary float ); diff --git a/reference/sql/sql_functions/scalar_functions/string/substring.rst b/reference/sql/sql_functions/scalar_functions/string/substring.rst index b07d951fb..6e6359167 100644 --- a/reference/sql/sql_functions/scalar_functions/string/substring.rst +++ b/reference/sql/sql_functions/scalar_functions/string/substring.rst @@ -54,14 +54,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - Name varchar(40), - Team varchar(40), + Name text(40), + Team text(40), Number tinyint, - Position varchar(2), + Position text(2), Age tinyint, - Height varchar(4), + Height text(4), Weight real, - College varchar(40), + College text(40), Salary float ); diff --git a/reference/sql/sql_functions/window_functions/first_value.rst b/reference/sql/sql_functions/window_functions/first_value.rst index 07708872d..25294040c 100644 --- a/reference/sql/sql_functions/window_functions/first_value.rst +++ b/reference/sql/sql_functions/window_functions/first_value.rst @@ -21,4 +21,4 @@ None Returns --------- -Returns the value located in the selected column of the first row of a segment. +Returns the value located in the selected column of the first row of a segment. \ No newline at end of file diff --git a/reference/sql/sql_functions/window_functions/lag.rst b/reference/sql/sql_functions/window_functions/lag.rst index e93be2821..96ea55bed 100644 --- a/reference/sql/sql_functions/window_functions/lag.rst +++ b/reference/sql/sql_functions/window_functions/lag.rst @@ -59,14 +59,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - "Name" varchar(40), - "Team" varchar(40), + "Name" text(40), + "Team" text(40), "Number" tinyint, - "Position" varchar(2), + "Position" text(2), "Age" tinyint, - "Height" varchar(4), + "Height" text(4), "Weight" real, - "College" varchar(40), + "College" text(40), "Salary" float ); diff --git a/reference/sql/sql_functions/window_functions/lead.rst b/reference/sql/sql_functions/window_functions/lead.rst index bc311689f..f1c52e1ec 100644 --- a/reference/sql/sql_functions/window_functions/lead.rst +++ b/reference/sql/sql_functions/window_functions/lead.rst @@ -59,14 +59,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - "Name" varchar(40), - "Team" varchar(40), + "Name" text(40), + "Team" text(40), "Number" tinyint, - "Position" varchar(2), + "Position" text(2), "Age" tinyint, - "Height" varchar(4), + "Height" text(4), "Weight" real, - "College" varchar(40), + "College" text(40), "Salary" float ); diff --git a/reference/sql/sql_functions/window_functions/nth_value.rst b/reference/sql/sql_functions/window_functions/nth_value.rst index a2c1dd9a6..75e97a939 100644 --- a/reference/sql/sql_functions/window_functions/nth_value.rst +++ b/reference/sql/sql_functions/window_functions/nth_value.rst @@ -22,8 +22,8 @@ The following example shows the syntax for a table named ``superstore`` used for CREATE TABLE superstore ( - "Section" varchar(40), - "Product_Name" varchar(40), + "Section" text(40), + "Product_Name" text(40), "Sales_In_K" int, ); diff --git a/reference/sql/sql_functions/window_functions/rank.rst b/reference/sql/sql_functions/window_functions/rank.rst index 28856bd04..7699fd399 100644 --- a/reference/sql/sql_functions/window_functions/rank.rst +++ b/reference/sql/sql_functions/window_functions/rank.rst @@ -48,14 +48,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - "Name" varchar(40), - "Team" varchar(40), + "Name" text(40), + "Team" text(40), "Number" tinyint, - "Position" varchar(2), + "Position" text(2), "Age" tinyint, - "Height" varchar(4), + "Height" text(4), "Weight" real, - "College" varchar(40), + "College" text(40), "Salary" float ); diff --git a/reference/sql/sql_functions/window_functions/row_number.rst b/reference/sql/sql_functions/window_functions/row_number.rst index ea5786aef..cfcc14b7b 100644 --- a/reference/sql/sql_functions/window_functions/row_number.rst +++ b/reference/sql/sql_functions/window_functions/row_number.rst @@ -48,14 +48,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - "Name" varchar(40), - "Team" varchar(40), + "Name" text(40), + "Team" text(40), "Number" tinyint, - "Position" varchar(2), + "Position" text(2), "Age" tinyint, - "Height" varchar(4), + "Height" text(4), "Weight" real, - "College" varchar(40), + "College" text(40), "Salary" float ); diff --git a/reference/sql/sql_statements/ddl_commands/create_external_table.rst b/reference/sql/sql_statements/ddl_commands/create_external_table.rst index fc05ca71e..4e2a3d952 100644 --- a/reference/sql/sql_statements/ddl_commands/create_external_table.rst +++ b/reference/sql/sql_statements/ddl_commands/create_external_table.rst @@ -113,7 +113,7 @@ A simple table from Tab-delimited file (TSV) .. code-block:: postgres CREATE OR REPLACE EXTERNAL TABLE cool_animals - (id INT NOT NULL, name VARCHAR(30) NOT NULL, weight FLOAT NOT NULL) + (id INT NOT NULL, name text(30) NOT NULL, weight FLOAT NOT NULL) USING FORMAT csv WITH PATH '/home/rhendricks/cool_animals.csv' FIELD DELIMITER '\t'; @@ -125,7 +125,7 @@ A table from a directory of Parquet files on HDFS .. code-block:: postgres CREATE EXTERNAL TABLE users - (id INT NOT NULL, name VARCHAR(30) NOT NULL, email VARCHAR(50) NOT NULL) + (id INT NOT NULL, name text(30) NOT NULL, email text(50) NOT NULL) USING FORMAT Parquet WITH PATH 'hdfs://hadoop-nn.piedpiper.com/rhendricks/users/*.parquet'; @@ -135,7 +135,7 @@ A table from a bucket of files on S3 .. code-block:: postgres CREATE EXTERNAL TABLE users - (id INT NOT NULL, name VARCHAR(30) NOT NULL, email VARCHAR(50) NOT NULL) + (id INT NOT NULL, name text(30) NOT NULL, email text(50) NOT NULL) USING FORMAT Parquet WITH PATH 's3://pp-secret-bucket/users/*.parquet' AWS_ID 'our_aws_id' diff --git a/reference/sql/sql_statements/ddl_commands/create_foreign_table.rst b/reference/sql/sql_statements/ddl_commands/create_foreign_table.rst index d50e13380..ecc39f08b 100644 --- a/reference/sql/sql_statements/ddl_commands/create_foreign_table.rst +++ b/reference/sql/sql_statements/ddl_commands/create_foreign_table.rst @@ -113,7 +113,7 @@ A simple table from Tab-delimited file (TSV) .. code-block:: postgres CREATE OR REPLACE FOREIGN TABLE cool_animals - (id INT NOT NULL, name VARCHAR(30) NOT NULL, weight FLOAT NOT NULL) + (id INT NOT NULL, name text(30) NOT NULL, weight FLOAT NOT NULL) WRAPPER csv_fdw OPTIONS ( LOCATION = '/home/rhendricks/cool_animals.csv', @@ -128,7 +128,7 @@ A table from a directory of Parquet files on HDFS .. code-block:: postgres CREATE FOREIGN TABLE users - (id INT NOT NULL, name VARCHAR(30) NOT NULL, email VARCHAR(50) NOT NULL) + (id INT NOT NULL, name text(30) NOT NULL, email text(50) NOT NULL) WRAPPER parquet_fdw OPTIONS ( @@ -141,7 +141,7 @@ A table from a bucket of ORC files on S3 .. code-block:: postgres CREATE FOREIGN TABLE users - (id INT NOT NULL, name VARCHAR(30) NOT NULL, email VARCHAR(50) NOT NULL) + (id INT NOT NULL, name text(30) NOT NULL, email text(50) NOT NULL) WRAPPER orc_fdw OPTIONS ( diff --git a/reference/sql/sql_statements/dml_commands/select.rst b/reference/sql/sql_statements/dml_commands/select.rst index f47ffaec1..03bd20d70 100644 --- a/reference/sql/sql_statements/dml_commands/select.rst +++ b/reference/sql/sql_statements/dml_commands/select.rst @@ -163,14 +163,14 @@ Assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - Name varchar(40), - Team varchar(40), + Name text(40), + Team text(40), Number tinyint, - Position varchar(2), + Position text(2), Age tinyint, - Height varchar(4), + Height text(4), Weight real, - College varchar(40), + College text(40), Salary float ); diff --git a/reference/sql/sql_statements/utility_commands/execute_saved_query.rst b/reference/sql/sql_statements/utility_commands/execute_saved_query.rst index 6fe41fa08..9232a5162 100644 --- a/reference/sql/sql_statements/utility_commands/execute_saved_query.rst +++ b/reference/sql/sql_statements/utility_commands/execute_saved_query.rst @@ -66,14 +66,14 @@ Assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - Name varchar(40), - Team varchar(40), + Name text(40), + Team text(40), Number tinyint, - Position varchar(2), + Position text(2), Age tinyint, - Height varchar(4), + Height text(4), Weight real, - College varchar(40), + College text(40), Salary float ); @@ -109,7 +109,7 @@ Use parameters to replace them later at execution time. .. tip:: Use dollar quoting (`$$`) to avoid escaping strings. - .. code-block:: psql +.. code-block:: psql t=> SELECT SAVE_QUERY('select_by_weight_and_team',$$SELECT * FROM nba WHERE Weight > ? AND Team = ?$$); executed @@ -119,5 +119,4 @@ Use parameters to replace them later at execution time. Bismack Biyombo | Toronto Raptors | 8 | C | 23 | 6-9 | 245 | | 2814000 James Johnson | Toronto Raptors | 3 | PF | 29 | 6-9 | 250 | Wake Forest | 2500000 Jason Thompson | Toronto Raptors | 1 | PF | 29 | 6-11 | 250 | Rider | 245177 - Jonas Valanciunas | Toronto Raptors | 17 | C | 24 | 7-0 | 255 | | 4660482 - + Jonas Valanciunas | Toronto Raptors | 17 | C | 24 | 7-0 | 255 | | 4660482 \ No newline at end of file diff --git a/reference/sql/sql_statements/utility_commands/get_ddl.rst b/reference/sql/sql_statements/utility_commands/get_ddl.rst index f2566e99a..bc3b9ef54 100644 --- a/reference/sql/sql_statements/utility_commands/get_ddl.rst +++ b/reference/sql/sql_statements/utility_commands/get_ddl.rst @@ -55,7 +55,7 @@ The result of the ``GET_DDL`` function is a verbose version of the :ref:`create_ farm=> CREATE TABLE cool_animals ( id INT NOT NULL, - name varchar(30) NOT NULL, + name text(30) NOT NULL, weight FLOAT, is_agressive BOOL DEFAULT false NOT NULL ); @@ -64,7 +64,7 @@ The result of the ``GET_DDL`` function is a verbose version of the :ref:`create_ farm=> SELECT GET_DDL('cool_animals'); create table "public"."cool_animals" ( "id" int not null, - "name" varchar(30) not null, + "name" text(30) not null, "weight" double null, "is_agressive" bool default false not null ) ; diff --git a/reference/sql/sql_statements/utility_commands/save_query.rst b/reference/sql/sql_statements/utility_commands/save_query.rst index be34c33ed..f71f6e025 100644 --- a/reference/sql/sql_statements/utility_commands/save_query.rst +++ b/reference/sql/sql_statements/utility_commands/save_query.rst @@ -70,14 +70,14 @@ Assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - Name varchar(40), - Team varchar(40), + Name text(40), + Team text(40), Number tinyint, - Position varchar(2), + Position text(2), Age tinyint, - Height varchar(4), + Height text(4), Weight real, - College varchar(40), + College text(40), Salary float ); @@ -123,5 +123,4 @@ Use parameters to replace them later at execution time. Bismack Biyombo | Toronto Raptors | 8 | C | 23 | 6-9 | 245 | | 2814000 James Johnson | Toronto Raptors | 3 | PF | 29 | 6-9 | 250 | Wake Forest | 2500000 Jason Thompson | Toronto Raptors | 1 | PF | 29 | 6-11 | 250 | Rider | 245177 - Jonas Valanciunas | Toronto Raptors | 17 | C | 24 | 7-0 | 255 | | 4660482 - + Jonas Valanciunas | Toronto Raptors | 17 | C | 24 | 7-0 | 255 | | 4660482 \ No newline at end of file diff --git a/reference/sql/sql_syntax/literals.rst b/reference/sql/sql_syntax/literals.rst index 906684590..bc5376dd1 100644 --- a/reference/sql/sql_syntax/literals.rst +++ b/reference/sql/sql_syntax/literals.rst @@ -239,7 +239,6 @@ The following is a syntax reference for typed literals: | REAL | DATE | DATETIME - | VARCHAR ( digits ) | TEXT ( digits ) Examples diff --git a/reference/sql/sql_syntax/subqueries.rst b/reference/sql/sql_syntax/subqueries.rst index 4cd995977..7f788ff46 100644 --- a/reference/sql/sql_syntax/subqueries.rst +++ b/reference/sql/sql_syntax/subqueries.rst @@ -28,14 +28,14 @@ The following is an example of table named ``nba`` with the following structure: CREATE TABLE nba ( - "Name" varchar(40), - "Team" varchar(40), + "Name" text(40), + "Team" text(40), "Number" tinyint, - "Position" varchar(2), + "Position" text(2), "Age" tinyint, - "Height" varchar(4), + "Height" text(4), "Weight" real, - "College" varchar(40), + "College" text(40), "Salary" float ); diff --git a/reference/sql/sql_syntax/window_functions.rst b/reference/sql/sql_syntax/window_functions.rst index cb87e085e..39d072d33 100644 --- a/reference/sql/sql_syntax/window_functions.rst +++ b/reference/sql/sql_syntax/window_functions.rst @@ -221,14 +221,14 @@ For these examples, assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - "Name" varchar(40), - "Team" varchar(40), + "Name" text(40), + "Team" text(40), "Number" tinyint, - "Position" varchar(2), + "Position" text(2), "Age" tinyint, - "Height" varchar(4), + "Height" text(4), "Weight" real, - "College" varchar(40), + "College" text(40), "Salary" float ); diff --git a/troubleshooting/log_related_issues.rst b/troubleshooting/log_related_issues.rst index a260f59d5..12623c943 100644 --- a/troubleshooting/log_related_issues.rst +++ b/troubleshooting/log_related_issues.rst @@ -18,7 +18,7 @@ Assuming logs are stored at ``/home/rhendricks/sqream_storage/logs/``, a databas CREATE FOREIGN TABLE logs ( - start_marker VARCHAR(4), + start_marker TEXT(4), row_id BIGINT, timestamp DATETIME, message_level TEXT, @@ -32,7 +32,7 @@ Assuming logs are stored at ``/home/rhendricks/sqream_storage/logs/``, a databas service_name TEXT, message_type_id INT, message TEXT, - end_message VARCHAR(5) + end_message TEXT(5) ) WRAPPER csv_fdw OPTIONS From 4996747e7e8e5ee5486b109bf89905281546867b Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 3 Apr 2022 15:16:23 +0300 Subject: [PATCH 034/316] Replaced VARCHAR with TEXT... ... according to Shachar's comments in the Slack threads. --- data_ingestion/inserting_data.rst | 81 +++++----- data_ingestion/orc.rst | 56 +++---- data_ingestion/parquet.rst | 37 +++-- data_type_guides/sql_data_types_date.rst | 2 +- .../sql_data_types_floating_point.rst | 3 +- data_type_guides/sql_data_types_integer.rst | 2 +- data_type_guides/sql_data_types_string.rst | 30 +--- .../monitoring_query_performance.rst | 4 +- .../conditionals/is_ascii.rst | 15 +- .../scalar_functions/conversion/to_hex.rst | 4 +- .../scalar_functions/numeric/crc64.rst | 19 +-- .../scalar_functions/string/octet_length.rst | 10 +- .../scalar_functions/string/replace.rst | 10 +- .../scalar_functions/string/rtrim.rst | 2 +- .../window_functions/first_value.rst | 2 +- .../window_functions/last_value.rst | 4 +- reference/sql/sql_statements/index.rst | 87 ++++------- reference/sql/sql_syntax/literals.rst | 2 +- reference/sql_feature_support.rst | 141 +++++++++--------- 19 files changed, 209 insertions(+), 302 deletions(-) diff --git a/data_ingestion/inserting_data.rst b/data_ingestion/inserting_data.rst index 86bd08103..42ac36ceb 100644 --- a/data_ingestion/inserting_data.rst +++ b/data_ingestion/inserting_data.rst @@ -53,8 +53,6 @@ SQream therefore recommends: * Applications such as :ref:`Tableau` and others have been tested, and work -* Data types were not over-provisioned (e.g. don't use VARCHAR(2000) to store a short string) - File Soure Location when Loading -------------------------------- @@ -78,20 +76,20 @@ SQream DB's :ref:`COPY FROM` syntax can be used to load CSV files, bu - ORC - Streaming data * - :ref:`copy_from` - - ✓ - - ✗ - - ✗ - - ✗ + - Supported + - Not supported + - Not supported + - Not supported * - :ref:`external_tables` - - ✓ - - ✓ - - ✓ - - ✗ + - Supported + - Supported + - Supported + - Not supported * - :ref:`insert` - - ✗ - - ✗ - - ✗ - - ✓ (Python, JDBC, Node.JS) + - Not supported + - Not supported + - Not supported + - Supported (Python, JDBC, Node.JS) Unsupported Data Types ----------------------------- @@ -262,9 +260,8 @@ Type Support and Behavior Notes * The types should match to some extent within the same "class" (see table below). .. list-table:: - :widths: auto + :widths: 5 5 70 70 70 70 5 5 5 5 5 :header-rows: 1 - :stub-columns: 1 * - SQream DB type → @@ -276,15 +273,15 @@ Type Support and Behavior Notes - ``BIGINT`` - ``REAL`` - ``DOUBLE`` - - Text [#f0]_ + - ``Text`` [#f0]_ - ``DATE`` - ``DATETIME`` * - ``boolean`` - - ✓ - - ✓ [#f5]_ - - ✓ [#f5]_ - - ✓ [#f5]_ - - ✓ [#f5]_ + - Supported + - Supported [#f5]_ + - Supported [#f5]_ + - Supported [#f5]_ + - Supported [#f5]_ - - - @@ -292,10 +289,10 @@ Type Support and Behavior Notes - * - ``tinyint`` - ○ [#f6]_ - - ✓ - - ✓ - - ✓ - - ✓ + - Supported + - Supported + - Supported + - Supported - - - @@ -304,9 +301,9 @@ Type Support and Behavior Notes * - ``smallint`` - ○ [#f6]_ - ○ [#f7]_ - - ✓ - - ✓ - - ✓ + - Supported + - Supported + - Supported - - - @@ -316,8 +313,8 @@ Type Support and Behavior Notes - ○ [#f6]_ - ○ [#f7]_ - ○ [#f7]_ - - ✓ - - ✓ + - Supported + - Supported - - - @@ -328,7 +325,7 @@ Type Support and Behavior Notes - ○ [#f7]_ - ○ [#f7]_ - ○ [#f7]_ - - ✓ + - Supported - - - @@ -340,8 +337,8 @@ Type Support and Behavior Notes - - - - - ✓ - - ✓ + - Supported + - Supported - - - @@ -351,12 +348,12 @@ Type Support and Behavior Notes - - - - - ✓ - - ✓ + - Supported + - Supported - - - - * - ``string`` / ``char`` / ``varchar`` + * - ``string`` / ``char`` / ``text`` - - - @@ -364,7 +361,7 @@ Type Support and Behavior Notes - - - - - ✓ + - Supported - - * - ``date`` @@ -376,8 +373,8 @@ Type Support and Behavior Notes - - - - - ✓ - - ✓ + - Supported + - Supported * - ``timestamp``, ``timestamp`` with timezone - - @@ -388,7 +385,7 @@ Type Support and Behavior Notes - - - - - ✓ + - Supported * If an ORC file has an unsupported type like ``binary``, ``list``, ``map``, and ``union``, but the data is not referenced in the table (it does not appear in the :ref:`SELECT` query), the statement will succeed. If the column is referenced, an error will be thrown to the user, explaining that the type is not supported, but the column may be ommited. @@ -459,7 +456,7 @@ Further Reading and Migration Guides .. rubric:: Footnotes -.. [#f0] Text values include ``TEXT``, ``VARCHAR``, and ``NVARCHAR`` +.. [#f0] Text values include ``TEXT`` .. [#f2] With UTF8 annotation diff --git a/data_ingestion/orc.rst b/data_ingestion/orc.rst index de10c5ce4..61e9237f9 100644 --- a/data_ingestion/orc.rst +++ b/data_ingestion/orc.rst @@ -13,9 +13,9 @@ This guide covers inserting data from ORC files into SQream DB using :ref:`FOREI Prepare the source ORC files, with the following requirements: .. list-table:: - :widths: auto + :widths: 5 5 70 70 70 70 5 5 5 5 5 :header-rows: 1 - :stub-columns: 1 + * - SQream DB type → @@ -27,15 +27,15 @@ Prepare the source ORC files, with the following requirements: - ``BIGINT`` - ``REAL`` - ``DOUBLE`` - - Text [#f0]_ + - ``TEXT`` [#f0]_ - ``DATE`` - ``DATETIME`` * - ``boolean`` - - ✓ - - ✓ [#f5]_ - - ✓ [#f5]_ - - ✓ [#f5]_ - - ✓ [#f5]_ + - Supported + - Supported [#f5]_ + - Supported [#f5]_ + - Supported [#f5]_ + - Supported [#f5]_ - - - @@ -43,10 +43,10 @@ Prepare the source ORC files, with the following requirements: - * - ``tinyint`` - ○ [#f6]_ - - ✓ - - ✓ - - ✓ - - ✓ + - Supported + - Supported + - Supported + - Supported - - - @@ -55,9 +55,9 @@ Prepare the source ORC files, with the following requirements: * - ``smallint`` - ○ [#f6]_ - ○ [#f7]_ - - ✓ - - ✓ - - ✓ + - Supported + - Supported + - Supported - - - @@ -67,8 +67,8 @@ Prepare the source ORC files, with the following requirements: - ○ [#f6]_ - ○ [#f7]_ - ○ [#f7]_ - - ✓ - - ✓ + - Supported + - Supported - - - @@ -79,7 +79,7 @@ Prepare the source ORC files, with the following requirements: - ○ [#f7]_ - ○ [#f7]_ - ○ [#f7]_ - - ✓ + - Supported - - - @@ -91,8 +91,8 @@ Prepare the source ORC files, with the following requirements: - - - - - ✓ - - ✓ + - Supported + - Supported - - - @@ -102,12 +102,12 @@ Prepare the source ORC files, with the following requirements: - - - - - ✓ - - ✓ + - Supported + - Supported - - - - * - ``string`` / ``char`` / ``varchar`` + * - ``string`` / ``char`` / ``text`` - - - @@ -115,7 +115,7 @@ Prepare the source ORC files, with the following requirements: - - - - - ✓ + - Supported - - * - ``date`` @@ -127,8 +127,8 @@ Prepare the source ORC files, with the following requirements: - - - - - ✓ - - ✓ + - Supported + - Supported * - ``timestamp``, ``timestamp`` with timezone - - @@ -139,13 +139,13 @@ Prepare the source ORC files, with the following requirements: - - - - - ✓ + - Supported * If an ORC file has an unsupported type like ``binary``, ``list``, ``map``, and ``union``, but the data is not referenced in the table (it does not appear in the :ref:`SELECT` query), the statement will succeed. If the column is referenced, an error will be thrown to the user, explaining that the type is not supported, but the column may be ommited. This can be worked around. See more information in the examples. .. rubric:: Footnotes -.. [#f0] Text values include ``TEXT``, ``VARCHAR``, and ``NVARCHAR`` +.. [#f0] Text values include ``TEXT`` .. [#f5] Boolean values are cast to 0, 1 diff --git a/data_ingestion/parquet.rst b/data_ingestion/parquet.rst index 4579deb82..c5971e064 100644 --- a/data_ingestion/parquet.rst +++ b/data_ingestion/parquet.rst @@ -15,9 +15,8 @@ This guide covers inserting data from Parquet files into SQream DB using :ref:`F Prepare the source Parquet files, with the following requirements: .. list-table:: - :widths: auto + :widths: 40 5 20 20 20 20 5 5 5 5 10 :header-rows: 1 - :stub-columns: 1 * - SQream DB type → @@ -29,11 +28,11 @@ Prepare the source Parquet files, with the following requirements: - ``BIGINT`` - ``REAL`` - ``DOUBLE`` - - Text [#f0]_ + - ``TEXT`` [#f0]_ - ``DATE`` - ``DATETIME`` * - ``BOOLEAN`` - - ✓ + - Supported - - - @@ -46,7 +45,7 @@ Prepare the source Parquet files, with the following requirements: * - ``INT16`` - - - - ✓ + - Supported - - - @@ -58,7 +57,7 @@ Prepare the source Parquet files, with the following requirements: - - - - - ✓ + - Supported - - - @@ -70,7 +69,7 @@ Prepare the source Parquet files, with the following requirements: - - - - - ✓ + - Supported - - - @@ -82,7 +81,7 @@ Prepare the source Parquet files, with the following requirements: - - - - - ✓ + - Supported - - - @@ -94,7 +93,7 @@ Prepare the source Parquet files, with the following requirements: - - - - - ✓ + - Supported - - - @@ -106,7 +105,7 @@ Prepare the source Parquet files, with the following requirements: - - - - - ✓ + - Supported - - * - ``INT96`` [#f3]_ @@ -119,13 +118,13 @@ Prepare the source Parquet files, with the following requirements: - - - - - ✓ [#f4]_ + - Supported [#f4]_ -* If a Parquet file has an unsupported type like ``enum``, ``uuid``, ``time``, ``json``, ``bson``, ``lists``, ``maps``, but the data is not referenced in the table (it does not appear in the :ref:`SELECT` query), the statement will succeed. If the column is referenced, an error will be thrown to the user, explaining that the type is not supported, but the column may be ommited. This can be worked around. See more information in the examples. +* If a Parquet file has an unsupported type, such as ``enum``, ``uuid``, ``time``, ``json``, ``bson``, ``lists``, ``maps``, but the data is not referenced in the table (it does not appear in the :ref:`SELECT` query), the statement will succeed. If the column is referenced, an error will be thrown to the user, explaining that the type is not Supported, but the column may be ommited. This can be worked around. See more information in the examples. .. rubric:: Footnotes -.. [#f0] Text values include ``TEXT``, ``VARCHAR``, and ``NVARCHAR`` +.. [#f0] Text values include ``TEXT`` .. [#f2] With UTF8 annotation @@ -187,7 +186,7 @@ We will make note of the file structure to create a matching ``CREATE EXTERNAL T Types in SQream DB must match Parquet types exactly. - If the column type isn't supported, a possible workaround is to set it to any arbitrary type and then exclude it from subsequent queries. + If the column type isn't Supported, a possible workaround is to set it to any arbitrary type and then exclude it from subsequent queries. 4. Verify table contents @@ -223,21 +222,21 @@ To load the data into SQream DB, use the :ref:`create_table_as` statement: CREATE TABLE nba AS SELECT * FROM ext_nba; -Working around unsupported column types +Working around unSupported column types --------------------------------------------- -Suppose you only want to load some of the columns - for example, if one of the columns isn't supported. +Suppose you only want to load some of the columns - for example, if one of the columns isn't Supported. -By ommitting unsupported columns from queries that access the ``EXTERNAL TABLE``, they will never be called, and will not cause a "type mismatch" error. +By ommitting unSupported columns from queries that access the ``EXTERNAL TABLE``, they will never be called, and will not cause a "type mismatch" error. -For this example, assume that the ``Position`` column isn't supported because of its type. +For this example, assume that the ``Position`` column isn't Supported because of its type. .. code-block:: postgres CREATE TABLE nba AS SELECT Name, Team, Number, NULL as Position, Age, Height, Weight, College, Salary FROM ext_nba; - -- We ommitted the unsupported column `Position` from this query, and replaced it with a default ``NULL`` value, to maintain the same table structure. + -- We ommitted the unSupported column `Position` from this query, and replaced it with a default ``NULL`` value, to maintain the same table structure. Modifying data during the copy process diff --git a/data_type_guides/sql_data_types_date.rst b/data_type_guides/sql_data_types_date.rst index da83f80cc..88236c113 100644 --- a/data_type_guides/sql_data_types_date.rst +++ b/data_type_guides/sql_data_types_date.rst @@ -108,5 +108,5 @@ The following table shows the possible ``DATE`` and ``DATETIME`` value conversio * - Type - Details - * - ``VARCHAR(n)`` + * - ``TEXT`` - ``'1997-01-01'`` → ``'1997-01-01'``, ``'1955-11-05 01:24'`` → ``'1955-11-05 01:24:00.000'`` \ No newline at end of file diff --git a/data_type_guides/sql_data_types_floating_point.rst b/data_type_guides/sql_data_types_floating_point.rst index 18227140c..3edc8362d 100644 --- a/data_type_guides/sql_data_types_floating_point.rst +++ b/data_type_guides/sql_data_types_floating_point.rst @@ -74,7 +74,6 @@ The following table shows the possible Floating Point value conversions: - ``1.0`` → ``true``, ``0.0`` → ``false`` * - ``TINYINT``, ``SMALLINT``, ``INT``, ``BIGINT`` - ``2.0`` → ``2``, ``3.14159265358979`` → ``3``, ``2.718281828459`` → ``2``, ``0.5`` → ``0``, ``1.5`` → ``1`` - * - ``VARCHAR(n)`` (n > 6 recommended) - - ``1`` → ``'1.0000'``, ``3.14159265358979`` → ``'3.1416'`` + .. note:: As shown in the above examples, casting ``real`` to ``int`` rounds down. \ No newline at end of file diff --git a/data_type_guides/sql_data_types_integer.rst b/data_type_guides/sql_data_types_integer.rst index 9d4210731..cd27f6956 100644 --- a/data_type_guides/sql_data_types_integer.rst +++ b/data_type_guides/sql_data_types_integer.rst @@ -79,5 +79,5 @@ The following table shows the possible Integer value conversions: - Details * - ``REAL``, ``DOUBLE`` - ``1`` → ``1.0``, ``-32`` → ``-32.0`` - * - ``VARCHAR(n)`` (All numberic values must fit in the string length) + * - ``TEXT`` (All numberic values must fit in the string length) - ``1`` → ``'1'``, ``2451`` → ``'2451'`` \ No newline at end of file diff --git a/data_type_guides/sql_data_types_string.rst b/data_type_guides/sql_data_types_string.rst index 0d977b6d2..4b1a1b406 100644 --- a/data_type_guides/sql_data_types_string.rst +++ b/data_type_guides/sql_data_types_string.rst @@ -5,30 +5,7 @@ String ************************* ``TEXT`` is designed for storing text or strings of characters. -SQream separates ASCII (``VARCHAR``) and UTF-8 representations (``TEXT``). - -.. note:: The data type ``NVARCHAR`` has been deprecated by ``TEXT`` as of version 2020.1. - -String Types -^^^^^^^^^^^^^^^^^^^^^^ -The following table describes the String types: - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Name - - Details - - Data Size (Not Null, Uncompressed) - - Example - * - ``TEXT [(n)]``, ``NVARCHAR (n)`` - - Varaiable length string - UTF-8 unicode. ``NVARCHAR`` is synonymous with ``TEXT``. - - Up to ``4*n`` bytes - - ``'キウイは楽しい鳥です'`` - * - ``VARCHAR (n)`` - - Variable length string - ASCII only - - ``n`` bytes - - ``'Kiwis have tiny wings, but cannot fly.'`` +SQream UTF-8 representations (``TEXT``). Length ^^^^^^^^^ @@ -37,8 +14,7 @@ When using ``TEXT``, specifying a size is optional. If not specified, the text f The following apply to setting the String type length: * If the data exceeds the column length limit on ``INSERT`` or ``COPY`` operations, SQream DB will return an error. -* When casting or converting, the string has to fit in the target. For example, ``'Kiwis are weird birds' :: VARCHAR(5)`` will return an error. Use ``SUBSTRING`` to truncate the length of the string. -* ``VARCHAR`` strings are padded with spaces. +* When casting or converting, the string has to fit in the target. For example, ``'Kiwis are weird birds' :: TEXT(5)`` will return an error. Use ``SUBSTRING`` to truncate the length of the string. Syntax ^^^^^^^^ @@ -47,7 +23,7 @@ String types can be written with standard SQL string literals, which are enclose Size ^^^^^^ -``VARCHAR(n)`` can occupy up to *n* bytes, whereas ``TEXT(n)`` can occupy up to *4*n* bytes. However, the size of strings is variable and is compressed by SQream. +``TEXT(n)`` can occupy up to *4*n* bytes. However, the size of strings is variable and is compressed by SQream. String Examples ^^^^^^^^^^ diff --git a/operational_guides/monitoring_query_performance.rst b/operational_guides/monitoring_query_performance.rst index a542f61e6..a38ddc6d0 100644 --- a/operational_guides/monitoring_query_performance.rst +++ b/operational_guides/monitoring_query_performance.rst @@ -200,7 +200,7 @@ Commonly Seen Nodes - Description * - ``CpuDecompress`` - CPU - - Decompression operation, common for longer ``VARCHAR`` types + - Decompression operation, common for longer ``TEXT`` types * - ``CpuLoopJoin`` - CPU - A non-indexed nested loop join, performed on the CPU @@ -621,7 +621,7 @@ Common Solutions for Improving Filtering * Use :ref:`clustering keys and naturally ordered data` in your filters. * Avoid full table scans when possible -4. Joins with ``varchar`` Keys +4. Joins with ``text`` Keys ----------------------------------- Joins on long text keys, such as ``varchar(100)`` do not perform as well as numeric data types or very short text keys. diff --git a/reference/sql/sql_functions/scalar_functions/conditionals/is_ascii.rst b/reference/sql/sql_functions/scalar_functions/conditionals/is_ascii.rst index bb9e3b2f9..495e46e76 100644 --- a/reference/sql/sql_functions/scalar_functions/conditionals/is_ascii.rst +++ b/reference/sql/sql_functions/scalar_functions/conditionals/is_ascii.rst @@ -45,20 +45,19 @@ For these examples, consider the following table and contents: .. code-block:: postgres - CREATE TABLE dictionary (id INT NOT NULL, fw TEXT(30), en VARCHAR(30)); - - INSERT INTO dictionary VALUES (1, '行こう', 'Let''s go'), (2, '乾杯', 'Cheers'), (3, 'L''chaim', 'Cheers'); + CREATE TABLE dictionary (id INT NOT NULL, text TEXT); + INSERT INTO dictionary VALUES (1, '行こう'), (2, '乾杯'), (3, 'L''chaim'); + SELECT id, text, IS_ASCII(text) FROM dictionary; IS NULL ----------- .. code-block:: psql - m=> SELECT id, en, fw, IS_ASCII(fw) FROM dictionary; - id | en | fw | is_ascii + id | text | is_ascii ---+----------+----------+--------- - 1 | Let's go | 行こう | false - 2 | Cheers | 乾杯 | false - 3 | Cheers | L'chaim | true + 1 | 行こう | false + 2 | 乾杯 | false + 3 | L'chaim | true diff --git a/reference/sql/sql_functions/scalar_functions/conversion/to_hex.rst b/reference/sql/sql_functions/scalar_functions/conversion/to_hex.rst index f3cf6fb82..d33643f22 100644 --- a/reference/sql/sql_functions/scalar_functions/conversion/to_hex.rst +++ b/reference/sql/sql_functions/scalar_functions/conversion/to_hex.rst @@ -11,7 +11,7 @@ Syntax .. code-block:: postgres - TO_HEX( expr ) --> VARCHAR + TO_HEX( expr ) --> TEXT Arguments ============ @@ -28,7 +28,7 @@ Arguments Returns ============ -* Representation of the hexadecimal number of type ``VARCHAR``. +* Representation of the hexadecimal number of type ``TEXT``. Examples diff --git a/reference/sql/sql_functions/scalar_functions/numeric/crc64.rst b/reference/sql/sql_functions/scalar_functions/numeric/crc64.rst index 105dae47c..8d067485d 100644 --- a/reference/sql/sql_functions/scalar_functions/numeric/crc64.rst +++ b/reference/sql/sql_functions/scalar_functions/numeric/crc64.rst @@ -12,8 +12,6 @@ Syntax .. code-block:: postgres CRC64( expr ) --> BIGINT - - CRC64_JOIN( expr ) --> BIGINT Arguments ============ @@ -32,14 +30,7 @@ Returns Returns a CRC-64 hash of the text input, of type ``BIGINT``. -Notes -======= - -* If the input value is NULL, the result is NULL. - -* The ``CRC64_JOIN`` can be used with ``VARCHAR`` only. It can not be used with ``TEXT``. - -* The ``CRC64_JOIN`` variant ignores leading whitespace when used as a ``JOIN`` key. +.. note:: If the input value is NULL, the result is NULL. Examples =========== @@ -49,9 +40,5 @@ Calculate a CRC-64 hash of a string .. code-block:: psql - numbers=> SELECT CRC64(x) FROM - . (VALUES ('This is a relatively long text string, that can be converted to a shorter hash' :: varchar(80))) - . as t(x); - crc64 - -------------------- - -9085161068710498500 \ No newline at end of file + SELECT CRC64(x) FROM (VALUES ('This is a relatively long text string, that can be converted to a shorter hash' :: text)) as t(x); + -8397827068206190216 \ No newline at end of file diff --git a/reference/sql/sql_functions/scalar_functions/string/octet_length.rst b/reference/sql/sql_functions/scalar_functions/string/octet_length.rst index 8bb1e3daf..0836b4685 100644 --- a/reference/sql/sql_functions/scalar_functions/string/octet_length.rst +++ b/reference/sql/sql_functions/scalar_functions/string/octet_length.rst @@ -6,14 +6,10 @@ OCTET_LENGTH Calculates the number of bytes in a string. -.. note:: +.. note:: + + * To get the length in bytes, see :ref:`octet_length`. - * This function is supported on ``TEXT`` strings only. - - * To get the length in characters, see :ref:`char_length`. - - * For ``VARCHAR`` strings, the octet length is the number of characters. Use :ref:`len` instead. - Syntax ========== The following is the correct syntax for the ``OCTET_LENGTH`` function: diff --git a/reference/sql/sql_functions/scalar_functions/string/replace.rst b/reference/sql/sql_functions/scalar_functions/string/replace.rst index 5552be269..d2fab561a 100644 --- a/reference/sql/sql_functions/scalar_functions/string/replace.rst +++ b/reference/sql/sql_functions/scalar_functions/string/replace.rst @@ -6,9 +6,6 @@ REPLACE Replaces all occurrences of a specified string value with another string value. -.. warning:: With ``VARCHAR``, a substring can only be replaced with another substring of equal **byte length**. See :ref:`octet_length`. - - Syntax ========== @@ -37,12 +34,7 @@ Returns Returns the same type as the argument supplied. -Notes -======= - -* In ``VARCHAR`` strings, the ``source_expr`` and ``replacement_expr`` must be the same **byte length**. See :ref:`octet_length`. - -* If the value is NULL, the result is NULL. +.. note:: If the value is NULL, the result is NULL. Examples =========== diff --git a/reference/sql/sql_functions/scalar_functions/string/rtrim.rst b/reference/sql/sql_functions/scalar_functions/string/rtrim.rst index 2bd5bbc38..61fdc877d 100644 --- a/reference/sql/sql_functions/scalar_functions/string/rtrim.rst +++ b/reference/sql/sql_functions/scalar_functions/string/rtrim.rst @@ -35,7 +35,7 @@ Returns the same type as the argument supplied. Notes ======= -* When using ``VARCHAR`` values, SQream DB automatically trims the trailing whitespace. Using ``RTRIM`` on ``VARCHAR`` does not affect the result. +* When using ``TEXT`` values, SQream DB automatically trims the trailing whitespace. Using ``RTRIM`` on ``TEXT`` does not affect the result. * This function is equivalent to the ANSI form ``TRIM( TRAILING FROM expr )`` diff --git a/reference/sql/sql_functions/window_functions/first_value.rst b/reference/sql/sql_functions/window_functions/first_value.rst index 25294040c..78896746a 100644 --- a/reference/sql/sql_functions/window_functions/first_value.rst +++ b/reference/sql/sql_functions/window_functions/first_value.rst @@ -5,7 +5,7 @@ FIRST_VALUE ************************** The **FIRST_VALUE** function returns the value located in the selected column of the first row of a segment. If the table is not segmented, the FIRST_VALUE function returns the value from the first row of the whole table. -This function returns the same type of variable that you input for your requested value. For example, requesting the value for the first employee in a list using an ``int`` type output returns an ``int`` type ID column. If you use a ``varchar`` type, the function returns a ``varchar`` type name column. +This function returns the same type of variable that you input for your requested value. For example, requesting the value for the first employee in a list using an ``int`` type output returns an ``int`` type ID column. If you use a ``text`` type, the function returns a ``text`` type name column. Syntax ------- diff --git a/reference/sql/sql_functions/window_functions/last_value.rst b/reference/sql/sql_functions/window_functions/last_value.rst index 3cadaa9d1..ae1276e79 100644 --- a/reference/sql/sql_functions/window_functions/last_value.rst +++ b/reference/sql/sql_functions/window_functions/last_value.rst @@ -5,7 +5,7 @@ LAST_VALUE ************************** The **LAST_VALUE** function returns the value located in the selected column of the last row of a segment. If the table is not segmented, the LAST_VALUE function returns the value from the last row of the whole table. -This function returns the same type of variable that you input for your requested value. For example, requesting the value for the last employee in a list using an ``int`` type output returns an ``int`` type ID column. If you use a ``varchar`` type, the function returns a ``varchar`` type name column. +This function returns the same type of variable that you input for your requested value. For example, requesting the value for the last employee in a list using an ``int`` type output returns an ``int`` type ID column. If you use a ``text`` type, the function returns a ``text`` type name column. Syntax ------- @@ -21,4 +21,4 @@ None Returns --------- -Returns the value located in the selected column of the last row of a segment. +Returns the value located in the selected column of the last row of a segment. \ No newline at end of file diff --git a/reference/sql/sql_statements/index.rst b/reference/sql/sql_statements/index.rst index e14041385..ae0139607 100644 --- a/reference/sql/sql_statements/index.rst +++ b/reference/sql/sql_statements/index.rst @@ -11,8 +11,6 @@ SQream DB supports commands from ANSI SQL. Data Definition Commands (DDL) ================================ - update - .. list-table:: DDL Commands :widths: auto :header-rows: 1 @@ -20,45 +18,47 @@ Data Definition Commands (DDL) * - Command - Usage - * - :ref:`ADD COLUMN` + * - :ref:`add_column` - Add a new column to a table - * - :ref:`UPDATE` - - Modify the value of certain columns in existing rows without creating a table - * - :ref:`ALTER DEFAULT SCHEMA` + * - :ref:`alter_default_schema` - Change the default schema for a role - * - :ref:`ALTER TABLE` + * - :ref:`alter_table` - Change the schema of a table - * - :ref:`CREATE DATABASE` + * - :ref:`cluster_by` + - Change clustering keys in a table + * - :ref:`create_database` - Create a new database - * - :ref:`CREATE EXTERNAL TABLE` + * - :ref:`create_external_table` - Create a new external table in the database (deprecated) - * - :ref:`CREATE FOREIGN TABLE` + * - :ref:`create_foreign_table` - Create a new foreign table in the database - * - :ref:`CREATE FUNCTION ` + * - :ref:`create_function` - Create a new user defined function in the database - * - :ref:`CREATE SCHEMA` + * - :ref:`create_schema` - Create a new schema in the database - * - :ref:`CREATE TABLE` + * - :ref:`create_table` - Create a new table in the database - * - :ref:`CREATE TABLE AS` + * - :ref:`create_table_as` - Create a new table in the database using results from a select query - * - :ref:`CREATE VIEW` + * - :ref:`create_view` - Create a new view in the database - * - :ref:`DROP COLUMN` + * - :ref:`drop_clustering_key` + - Drops all clustering keys in a table + * - :ref:`drop_column` - Drop a column from a table - * - :ref:`DROP DATABASE` + * - :ref:`drop_database` - Drop a database and all of its objects - * - :ref:`DROP FUNCTION` + * - :ref:`drop_function` - Drop a function - * - :ref:`DROP SCHEMA` + * - :ref:`drop_schema` - Drop a schema - * - :ref:`DROP TABLE` + * - :ref:`drop_table` - Drop a table and its contents from a database - * - :ref:`DROP VIEW` + * - :ref:`drop_view` - Drop a view - * - :ref:`RENAME COLUMN` + * - :ref:`rename_column` - Rename a column - * - :ref:`RENAME TABLE` + * - :ref:`rename_table` - Rename a table Data Manipulation Commands (DML) @@ -86,6 +86,8 @@ Data Manipulation Commands (DML) - Select rows and column from a table * - :ref:`TRUNCATE` - Delete all rows from a table + * - :ref:`UPDATE` + - Modify the value of certain columns in existing rows without creating a table * - :ref:`VALUES` - Return rows containing literal values @@ -111,29 +113,6 @@ Utility Commands * - :ref:`SELECT DUMP_DATABASE_DDL` - View the ``CREATE TABLE`` statement for an current database -Saved Queries -=================== - -.. list-table:: Saved Queries - :widths: auto - :header-rows: 1 - - * - Command - - Usage - * - :ref:`SELECT DROP_SAVED_QUERY` - - Drop a saved query - * - :ref:`SELECT EXECUTE_SAVED_QUERY` - - Executes a saved query - * - :ref:`SELECT LIST_SAVED_QUERIES` - - Returns a list of saved queries - * - :ref:`SELECT RECOMPILE_SAVED_QUERY` - - Recompiles a query that has been invalidated by a schema change - * - :ref:`SELECT SAVE_QUERY` - - Compiles and saves a query for re-use and sharing - * - :ref:`SELECT SHOW_SAVED_QUERY` - - Shows query text for a saved query - -For more information, see :ref:`saved_queries` Monitoring @@ -202,18 +181,4 @@ Access Control Commands * - :ref:`revoke` - Revoke permissions from a role * - :ref:`rename_role` - - Rename a role - - -.. toctree:: - :maxdepth: 1 - :titlesonly: - :hidden: - :glob: - - ddl_commands/* - dml_commands/* - utility_commands/* - monitoring_commands/* - wlm_commands/* - access_control_commands/* \ No newline at end of file + - Rename a role \ No newline at end of file diff --git a/reference/sql/sql_syntax/literals.rst b/reference/sql/sql_syntax/literals.rst index bc5376dd1..d1ec35dbe 100644 --- a/reference/sql/sql_syntax/literals.rst +++ b/reference/sql/sql_syntax/literals.rst @@ -86,7 +86,7 @@ Examples '1997-01-01' -- This is a string -The actual data type of the value changes based on context, the format used, and the value itself. In the example below, the first value is interpreted as a ``DATE``, while the second is interpreted as a ``VARCHAR``. +The actual data type of the value changes based on context, the format used, and the value itself. In the example below, the first value is interpreted as a ``DATE``, while the second is interpreted as a ``TEXT``. .. code-block:: postgres diff --git a/reference/sql_feature_support.rst b/reference/sql_feature_support.rst index ba4ca39e4..4443d631a 100644 --- a/reference/sql_feature_support.rst +++ b/reference/sql_feature_support.rst @@ -14,7 +14,7 @@ To understand which ANSI SQL and other SQL features SQream DB supports, use the Data Types and Values ========================= -Read more about :ref:`supported data types`. +Read more about :ref:`Yes data types`. .. list-table:: Data Types and Values :widths: auto @@ -24,46 +24,43 @@ Read more about :ref:`supported data types`. - Supported - Further information * - ``BOOL`` - - ✓ + - Yes - Boolean values * - ``TINTINT`` - - ✓ + - Yes - Unsigned 1 byte integer (0 - 255) * - ``SMALLINT`` - - ✓ + - Yes - 2 byte integer (-32,768 - 32,767) * - ``INT`` - - ✓ + - Yes - 4 byte integer (-2,147,483,648 - 2,147,483,647) * - ``BIGINT`` - - ✓ + - Yes - 8 byte integer (-9,223,372,036,854,775,808 - 9,223,372,036,854,775,807) * - ``REAL`` - - ✓ + - Yes - 4 byte floating point * - ``DOUBLE``, ``FLOAT`` - - ✓ + - Yes - 8 byte floating point * - ``DECIMAL``, ``NUMERIC`` - - ✓ + - Yes - Fixed-point numbers. - * - ``VARCHAR`` - - ✓ - - Variable length string - ASCII only * - ``TEXT`` - - ✓ + - Yes - Variable length string - UTF-8 encoded * - ``DATE`` - - ✓ + - Yes - Date * - ``DATETIME``, ``TIMESTAMP`` - - ✓ + - Yes - Date and time * - ``NULL`` - - ✓ + - Yes - ``NULL`` values * - ``TIME`` - - ✗ + - No - Can be stored as a text string or as part of a ``DATETIME`` @@ -77,14 +74,14 @@ Contraints * - Item - Supported - Further information - * - Not null - - ✓ + * - ``Not null`` + - Yes - ``NOT NULL`` - * - Default values - - ✓ + * - ``Default values`` + - Yes - ``DEFAULT`` * - ``AUTO INCREMENT`` - - ✓ Different name + - Yes (different name) - ``IDENTITY`` @@ -118,43 +115,43 @@ Schema Changes - Supported - Further information * - ``ALTER TABLE`` - - ✓ + - Yes - :ref:`alter_table` - Add column, alter column, drop column, rename column, rename table, modify clustering keys * - Rename database - - ✗ + - No - * - Rename table - - ✓ + - Yes - :ref:`rename_table` * - Rename column - - ✓ + - Yes - :ref:`rename_column` * - Add column - - ✓ + - Yes - :ref:`add_column` * - Remove column - - ✓ + - Yes - :ref:`drop_column` * - Alter column data type - - ✗ + - No - * - Add / modify clustering keys - - ✓ + - Yes - :ref:`cluster_by` * - Drop clustering keys - - ✓ + - Yes - :ref:`drop_clustering_key` * - Add / Remove constraints - - ✗ + - No - * - Rename schema - - ✗ + - No - * - Drop schema - - ✓ + - Yes - :ref:`drop_schema` * - Alter default schema per user - - ✓ + - Yes - :ref:`alter_default_schema` @@ -169,28 +166,28 @@ Statements - Supported - Further information * - SELECT - - ✓ + - Yes - :ref:`select` * - CREATE TABLE - - ✓ + - Yes - :ref:`create_table` * - CREATE FOREIGN / EXTERNAL TABLE - - ✓ + - Yes - :ref:`create_foreign_table` * - DELETE - - ✓ + - Yes - :ref:`delete_guide` * - INSERT - - ✓ + - Yes - :ref:`insert`, :ref:`copy_from` * - TRUNCATE - - ✓ + - Yes - :ref:`truncate` * - UPDATE - - ✗ + - No - * - VALUES - - ✓ + - Yes - :ref:`values` Clauses @@ -204,19 +201,19 @@ Clauses - Supported - Further information * - ``LIMIT`` / ``TOP`` - - ✓ + - Yes - * - ``LIMIT`` with ``OFFSET`` - - ✗ + - No - * - ``WHERE`` - - ✓ + - Yes - * - ``HAVING`` - - ✓ + - Yes - * - ``OVER`` - - ✓ + - Yes - Table Expressions @@ -230,19 +227,19 @@ Table Expressions - Supported - Further information * - Tables, Views - - ✓ + - Yes - * - Aliases, ``AS`` - - ✓ + - Yes - * - ``JOIN`` - ``INNER``, ``LEFT [ OUTER ]``, ``RIGHT [ OUTER ]``, ``CROSS`` - - ✓ + - Yes - * - Table expression subqueries - - ✓ + - Yes - * - Scalar subqueries - - ✗ + - No - @@ -259,34 +256,34 @@ Read more about :ref:`scalar_expressions`. - Supported - Further information * - Common functions - - ✓ + - Yes - ``CURRENT_TIMESTAMP``, ``SUBSTRING``, ``TRIM``, ``EXTRACT``, etc. * - Comparison operators - - ✓ + - Yes - ``<``, ``<=``, ``>``, ``>=``, ``=``, ``<>, !=``, ``IS``, ``IS NOT`` * - Boolean operators - - ✓ + - Yes - ``AND``, ``NOT``, ``OR`` * - Conditional expressions - - ✓ + - Yes - ``CASE .. WHEN`` * - Conditional functions - - ✓ + - Yes - ``COALESCE`` * - Pattern matching - - ✓ + - Yes - ``LIKE``, ``RLIKE``, ``ISPREFIXOF``, ``CHARINDEX``, ``PATINDEX`` * - REGEX POSIX pattern matching - - ✓ + - Yes - ``RLIKE``, ``REGEXP_COUNT``, ``REGEXP_INSTR``, ``REGEXP_SUBSTR``, * - ``EXISTS`` - - ✗ + - No - * - ``IN``, ``NOT IN`` - Partial - Literal values only * - Bitwise arithmetic - - ✓ + - Yes - ``&``, ``|``, ``XOR``, ``~``, ``>>``, ``<<`` @@ -304,16 +301,16 @@ Read more about :ref:`access_control` in SQream DB. - Supported - Further information * - Roles as users and groups - - ✓ + - Yes - * - Object default permissions - - ✓ + - Yes - * - Column / Row based permissions - - ✗ + - No - * - Object ownership - - ✗ + - No - @@ -329,20 +326,20 @@ Extra Functionality - Supported - Further information * - Information schema - - ✓ + - Yes - :ref:`catalog_reference` * - Views - - ✓ + - Yes - :ref:`create_view` * - Window functions - - ✓ + - Yes - :ref:`window_functions` * - CTEs - - ✓ + - Yes - :ref:`common_table_expressions` * - Saved queries, Saved queries with parameters - - ✓ + - Yes - :ref:`saved_queries` * - Sequences - - ✓ + - Yes - :ref:`identity` From b6b9249dddf1365520566271e6e727a15d6750d2 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 3 Apr 2022 17:16:14 +0300 Subject: [PATCH 035/316] Continued Updating... ... Not done... --- operational_guides/monitoring_query_performance.rst | 2 +- .../sql_functions/scalar_functions/string/char_length.rst | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/operational_guides/monitoring_query_performance.rst b/operational_guides/monitoring_query_performance.rst index a38ddc6d0..07897f585 100644 --- a/operational_guides/monitoring_query_performance.rst +++ b/operational_guides/monitoring_query_performance.rst @@ -623,7 +623,7 @@ Common Solutions for Improving Filtering 4. Joins with ``text`` Keys ----------------------------------- -Joins on long text keys, such as ``varchar(100)`` do not perform as well as numeric data types or very short text keys. +Joins on long text keys do not perform as well as numeric data types or very short text keys. Identifying the Situation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/reference/sql/sql_functions/scalar_functions/string/char_length.rst b/reference/sql/sql_functions/scalar_functions/string/char_length.rst index f89c397ab..47d517975 100644 --- a/reference/sql/sql_functions/scalar_functions/string/char_length.rst +++ b/reference/sql/sql_functions/scalar_functions/string/char_length.rst @@ -7,13 +7,9 @@ CHAR_LENGTH Calculates the number of characters in a string. .. note:: - - * This function is supported on ``TEXT`` only. - + * To get the length in bytes, see :ref:`octet_length`. - * For ``VARCHAR`` strings, the octet length is the number of characters. Use :ref:`len` instead. - Syntax ========== From 15b18684b41d04a14dcc1851f6647f48c9d9b29f Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 5 Apr 2022 13:52:01 +0300 Subject: [PATCH 036/316] Replaced VARCHAR with TEXT --- data_ingestion/avro.rst | 344 ++++++++++++++++++ data_ingestion/orc.rst | 4 +- .../converting_and_casting_types.rst | 2 +- data_type_guides/sql_data_types_string.rst | 2 +- data_type_guides/supported_data_types.rst | 6 +- ...ata_clustering_data_clustering_methods.rst | 6 +- getting_started/creating_your_first_table.rst | 6 +- .../monitoring_query_performance.rst | 36 +- .../seeing_system_objects_as_ddl.rst | 4 +- .../scalar_functions/conditionals/is_null.rst | 2 +- .../date_and_time/eomonth.rst | 2 +- .../date_and_time/extract.rst | 2 +- .../scalar_functions/string/charindex.rst | 4 +- .../scalar_functions/string/isprefixof.rst | 2 +- .../scalar_functions/string/lower.rst | 2 +- .../scalar_functions/string/patindex.rst | 2 +- .../scalar_functions/string/trim.rst | 2 +- .../scalar_functions/string/upper.rst | 2 +- .../ddl_commands/create_function.rst | 2 +- .../ddl_commands/create_table.rst | 12 +- .../monitoring_commands/show_node_info.rst | 2 +- .../utility_commands/drop_saved_query.rst | 55 --- .../utility_commands/dump_database_ddl.rst | 2 +- .../utility_commands/execute_saved_query.rst | 122 ------- .../utility_commands/list_saved_queries.rst | 77 ---- .../recompile_saved_query.rst | 88 ----- .../utility_commands/save_query.rst | 2 +- .../utility_commands/show_saved_query.rst | 61 ---- ...ts_and_running_queries_from_the_editor.rst | 2 +- 29 files changed, 398 insertions(+), 457 deletions(-) create mode 100644 data_ingestion/avro.rst delete mode 100644 reference/sql/sql_statements/utility_commands/drop_saved_query.rst delete mode 100644 reference/sql/sql_statements/utility_commands/execute_saved_query.rst delete mode 100644 reference/sql/sql_statements/utility_commands/list_saved_queries.rst delete mode 100644 reference/sql/sql_statements/utility_commands/recompile_saved_query.rst delete mode 100644 reference/sql/sql_statements/utility_commands/show_saved_query.rst diff --git a/data_ingestion/avro.rst b/data_ingestion/avro.rst new file mode 100644 index 000000000..f74d8875d --- /dev/null +++ b/data_ingestion/avro.rst @@ -0,0 +1,344 @@ +.. _avro: + +************************** +Inserting Data from Avro +************************** +The **Inserting Data from Avro** page describes inserting data from Avro into SQream and includes the following: + +.. contents:: + :local: + :depth: 1 + +Overview +=========== +**Avro** is a well-known data serialization system that relies on schemas. Due to its flexibility and nesting as an efficient data storage method, SQream supports the Avro binary data format as an alternative to JSON. + +Avro Data Types +=========== + +Avro includes the following data types: + +.. contents:: + :local: + :depth: 1 + +Primitive Data Types +-------------- +The following table shows the supported **Primitive** data types: + ++-------------+------------------------------------------------------+ +| Avro Type | SQream Type | +| +-----------+---------------+-----------+--------------+ +| | Number | Date/Datetime | String | Boolean | ++=============+===========+===============+===========+==============+ +| ``null`` | Supported | Supported | Supported | Supported | ++-------------+-----------+---------------+-----------+--------------+ +| ``boolean`` | | | Supported | Supported | ++-------------+-----------+---------------+-----------+--------------+ +| ``int`` | Supported | | Supported | | ++-------------+-----------+---------------+-----------+--------------+ +| ``long`` | Supported | | Supported | | ++-------------+-----------+---------------+-----------+--------------+ +| ``float`` | Supported | | Supported | | ++-------------+-----------+---------------+-----------+--------------+ +| ``double`` | Supported | | Supported | | ++-------------+-----------+---------------+-----------+--------------+ +| ``bytes`` | | | | | ++-------------+-----------+---------------+-----------+--------------+ +| ``string`` | | Supported | Supported | | ++-------------+-----------+---------------+-----------+--------------+ + + + + + + +Complex Data Types +-------------- +The following table shows the supported **Complex** data types: + ++------------+---------------------------------------------------+ +| | SQream Type | +| +-----------+---------------+-----------+-----------+ +|Avro Type | Number | Date/Datetime | String | Boolean | ++============+===========+===============+===========+===========+ +| ``record`` | | | | | ++------------+-----------+---------------+-----------+-----------+ +| ``enum`` | | | Supported | | ++------------+-----------+---------------+-----------+-----------+ +| ``array`` | | | | | ++------------+-----------+---------------+-----------+-----------+ +| ``map`` | | | | | ++------------+-----------+---------------+-----------+-----------+ +| ``union`` | Supported | Supported | Supported | Supported | ++------------+-----------+---------------+-----------+-----------+ +| ``fixed`` | | | | | ++------------+-----------+---------------+-----------+-----------+ + + +Logical Data Types +-------------- +The following table shows the supported **Logical** data types: + ++----------------------------+-------------------------------------------------+ +| Avro Type | SQream Type | +| +-----------+---------------+-----------+---------+ +| | Number | Date/Datetime | String | Boolean | ++============================+===========+===============+===========+=========+ +| ``decimal`` | Supported | | Supported | | ++----------------------------+-----------+---------------+-----------+---------+ +| ``uuid`` | | | Supported | | ++----------------------------+-----------+---------------+-----------+---------+ +| ``date`` | | Supported | Supported | | ++----------------------------+-----------+---------------+-----------+---------+ +| ``time-millis`` | | | | | ++----------------------------+-----------+---------------+-----------+---------+ +| ``time-micros`` | | | | | ++----------------------------+-----------+---------------+-----------+---------+ +| ``timestamp-millis`` | | Supported | Supported | | ++----------------------------+-----------+---------------+-----------+---------+ +| ``timestamp-micros`` | | Supported | Supported | | ++----------------------------+-----------+---------------+-----------+---------+ +| ``local-timestamp-millis`` | | | | | ++----------------------------+-----------+---------------+-----------+---------+ +| ``local-timestamp-micros`` | | | | | ++----------------------------+-----------+---------------+-----------+---------+ +| ``duration`` | | | | | ++----------------------------+-----------+---------------+-----------+---------+ + + +Mapping Objects to Rows +=============== +When mapping objects to rows, each Avro object or message must contain one ``record`` type object corresponding to a single row in SQream. The ``record`` fields are associated by name to their target table columns. + +Additional unmapped fields will be ignored. Note that using the JSONPath option overrides this. + +Ingesting Avro Files +==================== +This section describes how to ingest Avro files into SQream and covers the following: + + +.. contents:: + :local: + :depth: 1 + + +Preparing Your Avro Source File +---------- +Prepare your Avro source files according to the following requirements: + +* RFC 4180 standard CSV files, but can also be modified to support non-standard CSVs (with multi-character delimiters, unquoted fields, etc). + + :: + +* Files are encoded with UTF-8 or ASCII. + + :: + +* Field delimiter is an ASCII character or characters. + + :: + +* Record delimiter, also known as a new line separator, is a Unix-style newline (``\n``), DOS-style newline (``\r\n``), or Mac style newline (``\r``). + + :: + +* If a field is quoted, any double quote that appears must be double-quoted (similar to the :ref:`string literals quoting rules`. For example, to encode ``What are "birds"?``, the field should appear as ``"What are ""birds""?"``. + + :: + +* Fields can be enclosed by double-quotes (optional), or mandatory quotes if they contain one of the following characters: + + * The record delimiter or field delimiter. + + :: + + * A double quote character. + + :: + + * A newline. + +SQream does not support other modes of escaping, such as ``1,"What are \"birds\"?"``. + +``NULL`` values can be marked in the following ways in Avro files: + + * An explicit null marker. For example, ``col1,\N,col3``. + + :: + + * An empty field delimited by the field delimiter. For example, ``col1,,col3``. + + .. note:: If a text field is quoted but contains no content (``""``) it is considered an empty text field and not ``NULL``. + +For more information about standard CSV files, see `RFC 4180 standard CSVs `_. + +Making Avro Files Accessible to Workers +--------------------- +To give workers access to files every node must have the same view of the storage being used. + +The following apply for Avro files to be accessible to workers: + +* For files hosted on NFS, ensure that the mount is accessible from all servers. + +* For HDFS, ensure that SQream servers have access to the HDFS name node with the correct **user-id**. For more information, see :ref:`hdfs`. + +* For S3, ensure network access to the S3 endpoint. For more information, see :ref:`s3`. + +For more information about restricted worker access, see :ref:`workload_manager`. + +Basing Your Table Structure on Inserted Tables +--------------------- +Before loading data, you must build the ``CREATE EXTERNAL TABLE`` to correspond with the file structure of the inserted table. + +The example in this section is based on the source ``nba.parquet`` table shown below: + +.. csv-table:: nba.parquet + :file: nba-t10.csv + :widths: auto + :header-rows: 1 + +The following example shows the correct file structure used to create the ``CREATE EXTERNAL TABLE`` statement based on the **nba.parquet** table: + +.. code-block:: postgres + + CREATE FOREIGN TABLE ext_nba + ( + Name TEXT(40), + Team TEXT(40), + Number BIGINT, + Position TEXT(2), + Age BIGINT, + Height TEXT(4), + Weight BIGINT, + College TEXT(40), + Salary FLOAT + ) + WRAPPER parquet_fdw + OPTIONS + ( + LOCATION = 's3://sqream-demo-data/nba.parquet' + ); + +.. tip:: + + An exact match must exist between the SQream and Avro types. For unsupported column types, you can set the type to any type and exclude it from subsequent queries. + +.. note:: The **nba.parquet** file is stored on S3 at ``s3://sqream-demo-data/nba.parquet``. + +Verifying Your Table Output +--------------------- +Because external tables do not automatically verify the file integrity or structure, you must manually verify that the table output is identical to the original inserted table. + +The following is an example of the output based on the **nba.parquet** table: + +.. code-block:: psql + + t=> SELECT * FROM ext_nba LIMIT 10; + Name | Team | Number | Position | Age | Height | Weight | College | Salary + --------------+----------------+--------+----------+-----+--------+--------+-------------------+--------- + Avery Bradley | Boston Celtics | 0 | PG | 25 | 6-2 | 180 | Texas | 7730337 + Jae Crowder | Boston Celtics | 99 | SF | 25 | 6-6 | 235 | Marquette | 6796117 + John Holland | Boston Celtics | 30 | SG | 27 | 6-5 | 205 | Boston University | + R.J. Hunter | Boston Celtics | 28 | SG | 22 | 6-5 | 185 | Georgia State | 1148640 + Jonas Jerebko | Boston Celtics | 8 | PF | 29 | 6-10 | 231 | | 5000000 + Amir Johnson | Boston Celtics | 90 | PF | 29 | 6-9 | 240 | | 12000000 + Jordan Mickey | Boston Celtics | 55 | PF | 21 | 6-8 | 235 | LSU | 1170960 + Kelly Olynyk | Boston Celtics | 41 | C | 25 | 7-0 | 238 | Gonzaga | 2165160 + Terry Rozier | Boston Celtics | 12 | PG | 22 | 6-2 | 190 | Louisville | 1824360 + Marcus Smart | Boston Celtics | 36 | PG | 22 | 6-4 | 220 | Oklahoma State | 3431040 + +.. note:: If your table output has errors, verify that the structure of the Avro files correctly corresponds to the external table structure that you created. + +Loading Data into SQream +--------------------- + +Syntax +~~~~~~~~~~~~~~~~~~~~~ +The following is the correct syntax for loading data into SQream: + +.. code-block:: postgres + + CREATE TABLE
AS + SELECT * FROM ; + +The following is an example of loading data into SQream: + +.. code-block:: postgres + + CREATE TABLE nba AS + SELECT * FROM ext_nba; + +For more information about the **CREATE TABLE AS** statement, see :ref:`create_table_as`. + +Examples +~~~~~~~~~~~~~~~~~~~~~ + +This section includes the following examples of loading data into SQream: + +.. contents:: + :local: + :depth: 1 + +Omitting Unsupported Column Types +********************** +When loading data, you can omit columns using the ``NULL as`` argument. You can use this argument to omit unsupported columns from queries that access external tables. By omitting them, these columns will not be called and will avoid generating a "type mismatch" error. + +In the example below, the ``Position`` column is not supported due its type. + +.. code-block:: postgres + + CREATE TABLE nba AS + SELECT Name, Team, Number, NULL as Position, Age, Height, Weight, College, Salary FROM ext_nba; + + +Modifying Data Before Loading +********************** +One of the main reasons for staging data using the ``EXTERNAL TABLE`` argument is to examine and modify table contents before loading it into SQream. + +For example, we can replace pounds with kilograms using the :ref:`create_table_as` statement + +In the example below, the ``Position`` column is set to the default ``NULL``. + +.. code-block:: postgres + + CREATE TABLE nba AS + SELECT name, team, number, NULL as Position, age, height, (weight / 2.205) as weight, college, salary + FROM ext_nba + ORDER BY weight; + + +Loading a Table from a Directory of Avro Files on HDFS +********************** +The following is an example of loading a table from a directory of Avro files on HDFS: + +.. code-block:: postgres + + CREATE FOREIGN TABLE ext_users + (id INT NOT NULL, name TEXT(30) NOT NULL, email TEXT(50) NOT NULL) + WRAPPER parquet_fdw + OPTIONS + ( + LOCATION = 'hdfs://hadoop-nn.piedpiper.com/rhendricks/users/*.parquet' + ); + + CREATE TABLE users AS SELECT * FROM ext_users; + +For more configuration option examples, see the `CREATE FOREIGN TABLE parameters `_. + +Loading a Table from a Directory of Avro Files on S3 +********************** +The following is an example of loading a table from a directory of Avro files on S3: + +.. code-block:: postgres + + CREATE FOREIGN TABLE ext_users + (id INT NOT NULL, name TEXT(30) NOT NULL, email TEXT(50) NOT NULL) + WRAPPER parquet_fdw + OPTIONS + ( LOCATION = 's3://pp-secret-bucket/users/*.parquet', + AWS_ID = 'our_aws_id', + AWS_SECRET = 'our_aws_secret' + ); + + CREATE TABLE users AS SELECT * FROM ext_users; \ No newline at end of file diff --git a/data_ingestion/orc.rst b/data_ingestion/orc.rst index 61e9237f9..cfcf6c38b 100644 --- a/data_ingestion/orc.rst +++ b/data_ingestion/orc.rst @@ -288,7 +288,7 @@ Loading a table from a directory of ORC files on HDFS .. code-block:: postgres CREATE FOREIGN TABLE ext_users - (id INT NOT NULL, name TEXT(30) NOT NULL, email VARCHAR(50) NOT NULL) + (id INT NOT NULL, name TEXT(30) NOT NULL, email TEXT(50) NOT NULL) WRAPPER orc_fdw OPTIONS ( @@ -303,7 +303,7 @@ Loading a table from a bucket of files on S3 .. code-block:: postgres CREATE FOREIGN TABLE ext_users - (id INT NOT NULL, name TEXT(30) NOT NULL, email VARCHAR(50) NOT NULL) + (id INT NOT NULL, name TEXT(30) NOT NULL, email TEXT(50) NOT NULL) WRAPPER orc_fdw OPTIONS ( LOCATION = 's3://pp-secret-bucket/users/*.ORC', diff --git a/data_type_guides/converting_and_casting_types.rst b/data_type_guides/converting_and_casting_types.rst index ee5e273da..e4de6eeb7 100644 --- a/data_type_guides/converting_and_casting_types.rst +++ b/data_type_guides/converting_and_casting_types.rst @@ -15,7 +15,7 @@ You can rectify this by casting the value to a larger data type, as shown below: SQream supports the following three data conversion types: -* ``CAST( TO )``, to convert a value from one type to another. For example, ``CAST('1997-01-01' TO DATE)``, ``CAST(3.45 TO SMALLINT)``, ``CAST(some_column TO VARCHAR(30))``. +* ``CAST( TO )``, to convert a value from one type to another. For example, ``CAST('1997-01-01' TO DATE)``, ``CAST(3.45 TO SMALLINT)``, ``CAST(some_column TO TEXT(30))``. :: diff --git a/data_type_guides/sql_data_types_string.rst b/data_type_guides/sql_data_types_string.rst index 4b1a1b406..df4261d8f 100644 --- a/data_type_guides/sql_data_types_string.rst +++ b/data_type_guides/sql_data_types_string.rst @@ -9,7 +9,7 @@ SQream UTF-8 representations (``TEXT``). Length ^^^^^^^^^ -When using ``TEXT``, specifying a size is optional. If not specified, the text field carries no constraints. To limit the size of the input, use ``VARCHAR(n)`` or ``TEXT(n)``, where ``n`` is the permitted number of characters. +When using ``TEXT``, specifying a size is optional. If not specified, the text field carries no constraints. To limit the size of the input, use ``TEXT(n)``, where ``n`` is the permitted number of characters. The following apply to setting the String type length: diff --git a/data_type_guides/supported_data_types.rst b/data_type_guides/supported_data_types.rst index 2743b054b..afc735ad1 100644 --- a/data_type_guides/supported_data_types.rst +++ b/data_type_guides/supported_data_types.rst @@ -51,17 +51,17 @@ The following table shows the supported data types. - 8 bytes - ``0.000003`` - ``FLOAT``/``DOUBLE PRECISION`` - * - ``TEXT [(n)]``, ``NVARCHAR (n)`` + * - ``TEXT [(n)]`` - Variable length string - UTF-8 unicode - Up to ``4*n`` bytes - ``'キウイは楽しい鳥です'`` - - ``CHAR VARYING``, ``CHAR``, ``CHARACTER VARYING``, ``CHARACTER``, ``NATIONAL CHARACTER VARYING``, ``NATIONAL CHARACTER``, ``NCHAR VARYING``, ``NCHAR``, ``NVARCHAR`` + - ``CHAR VARYING``, ``CHAR``, ``CHARACTER VARYING``, ``CHARACTER``, ``NATIONAL CHARACTER VARYING``, ``NATIONAL CHARACTER``, ``NCHAR VARYING``, ``NCHAR`` * - ``NUMERIC`` - 38 digits - 16 bytes - ``0.123245678901234567890123456789012345678`` - ``DECIMAL`` - * - ``VARCHAR (n)`` + * - ``TEXT (n)`` - Variable length string - ASCII only - ``n`` bytes - ``'Kiwis have tiny wings, but cannot fly.'`` diff --git a/feature_guides/flexible_data_clustering_data_clustering_methods.rst b/feature_guides/flexible_data_clustering_data_clustering_methods.rst index 347be830a..6949547ba 100644 --- a/feature_guides/flexible_data_clustering_data_clustering_methods.rst +++ b/feature_guides/flexible_data_clustering_data_clustering_methods.rst @@ -63,7 +63,7 @@ Best Practices for Time-Based Management ~~~~~~~~~~ Data inserted in bulks is automatically timestamped with the insertion date and time. Therefore, inserting data through small and frequent bulks has the effect of naturally ordering data according to timestamp. Frequent bulks generally refers to short time frames, such as at 15-minute, hourly, or daily intervals. As you insert new data, SQream chunks and appends it into your existing tables according to its timestamp. -The ``DATE`` and ``DATETIME`` types were created to improve performance, minimze storage size, and maintain data integrity. SQream recommends using them instead of ``VARCHAR``. +The ``DATE`` and ``DATETIME`` types were created to improve performance, minimze storage size, and maintain data integrity. SQream recommends using them instead of ``TEXT``. Using Clustering Keys ============ @@ -76,9 +76,9 @@ A clustering key is a subset of table columns or expressions and is defined usin .. code-block:: postgres CREATE TABLE users ( - name VARCHAR(30) NOT NULL, + name TEXT(30) NOT NULL, start_date datetime not null, - country VARCHAR(30) DEFAULT 'Unknown' NOT NULL + country TEXT(30) DEFAULT 'Unknown' NOT NULL ) CLUSTER BY country; diff --git a/getting_started/creating_your_first_table.rst b/getting_started/creating_your_first_table.rst index c070b43ed..2837907f8 100644 --- a/getting_started/creating_your_first_table.rst +++ b/getting_started/creating_your_first_table.rst @@ -21,7 +21,7 @@ The ``CREATE TABLE`` syntax is used to create your first table. This table inclu CREATE TABLE cool_animals ( id INT NOT NULL, - name VARCHAR(20), + name TEXT(20), weight INT ); @@ -37,7 +37,7 @@ You can drop an existing table and create a new one by adding the ``OR REPLACE`` CREATE OR REPLACE TABLE cool_animals ( id INT NOT NULL, - name VARCHAR(20), + name TEXT(20), weight INT ); @@ -54,7 +54,7 @@ You can list the full, verbose ``CREATE TABLE`` statement for a table by using t test=> SELECT GET_DDL('cool_animals'); create table "public"."cool_animals" ( "id" int not null, - "name" varchar(20), + "name" text(20), "weight" int ); diff --git a/operational_guides/monitoring_query_performance.rst b/operational_guides/monitoring_query_performance.rst index 07897f585..057512968 100644 --- a/operational_guides/monitoring_query_performance.rst +++ b/operational_guides/monitoring_query_performance.rst @@ -47,7 +47,7 @@ First, create a foreign table for the logs .. code-block:: postgres CREATE FOREIGN TABLE logs ( - start_marker VARCHAR(4), + start_marker TEXT(4), row_id BIGINT, timestamp DATETIME, message_level TEXT, @@ -61,7 +61,7 @@ First, create a foreign table for the logs service_name TEXT, message_type_id INT, message TEXT, - end_message VARCHAR(5) + end_message TEXT(5) ) WRAPPER cdv_fdw OPTIONS @@ -636,20 +636,20 @@ For example, consider these two table structures: amt FLOAT NOT NULL, i INT NOT NULL, ts DATETIME NOT NULL, - country_code VARCHAR(3) NOT NULL, - flag VARCHAR(10) NOT NULL, - fk VARCHAR(50) NOT NULL + country_code TEXT(3) NOT NULL, + flag TEXT(10) NOT NULL, + fk TEXT(50) NOT NULL ); CREATE TABLE t_b ( - id VARCHAR(50) NOT NULL + id TEXT(50) NOT NULL prob FLOAT NOT NULL, j INT NOT NULL, ); #. Run a query. - In this example, we will join ``t_a.fk`` with ``t_b.id``, both of which are ``VARCHAR(50)``. + In this example, we will join ``t_a.fk`` with ``t_b.id``, both of which are ``TEXT(50)``. .. code-block:: postgres @@ -688,7 +688,7 @@ For example, consider these two table structures: Improving Query Performance ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -* In general, try to avoid ``VARCHAR`` as a join key. As a rule of thumb, ``BIGINT`` works best as a join key. +* In general, try to avoid ``TEXT`` as a join key. As a rule of thumb, ``BIGINT`` works best as a join key. * Convert text values on-the-fly before running the query. For example, the :ref:`crc64` function takes a text input and returns a ``BIGINT`` hash. @@ -726,10 +726,10 @@ Improving Query Performance * You can map some text values to numeric types by using a dimension table. Then, reconcile the values when you need them by joining the dimension table. -5. Sorting on big ``VARCHAR`` fields +5. Sorting on big ``TEXT`` fields --------------------------------------- In general, SQream DB automatically inserts a ``Sort`` node which arranges the data prior to reductions and aggregations. -When running a ``GROUP BY`` on large ``VARCHAR`` fields, you may see nodes for ``Sort`` and ``Reduce`` taking a long time. +When running a ``GROUP BY`` on large ``TEXT`` fields, you may see nodes for ``Sort`` and ``Reduce`` taking a long time. Identifying the Situation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -749,9 +749,9 @@ For example: i INT NOT NULL, amt DOUBLE NOT NULL, ts DATETIME NOT NULL, - country_code VARCHAR(100) NOT NULL, - flag VARCHAR(10) NOT NULL, - string_fk VARCHAR(50) NOT NULL + country_code TEXT(100) NOT NULL, + flag TEXT(10) NOT NULL, + string_fk TEXT(50) NOT NULL ); We will run a query, and inspect it's execution details: @@ -800,16 +800,16 @@ For example: max --- 3 - With a maximum string length of just 3 characters, our ``VARCHAR(100)`` is way oversized. + With a maximum string length of just 3 characters, our ``TEXT(100)`` is way oversized. #. - We can recreate the table with a more restrictive ``VARCHAR(3)``, and can examine the difference in performance: + We can recreate the table with a more restrictive ``TEXT(3)``, and can examine the difference in performance: .. code-block:: psql t=> CREATE TABLE t_efficient . AS SELECT i, . amt, . ts, - . country_code::VARCHAR(3) AS country_code, + . country_code::TEXT(3) AS country_code, . flag . FROM t_inefficient; executed @@ -832,8 +832,8 @@ For example: Improving Sort Performance on Text Keys ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -When using VARCHAR, ensure that the maximum length defined in the table structure is as small as necessary. -For example, if you're storing phone numbers, don't define the field as ``VARCHAR(255)``, as that affects sort performance. +When using TEXT, ensure that the maximum length defined in the table structure is as small as necessary. +For example, if you're storing phone numbers, don't define the field as ``TEXT(255)``, as that affects sort performance. You can run a query to get the maximum column length (e.g. ``MAX(LEN(a_column))``), and potentially modify the table structure. diff --git a/operational_guides/seeing_system_objects_as_ddl.rst b/operational_guides/seeing_system_objects_as_ddl.rst index 4f9f596dd..2aacb49e8 100644 --- a/operational_guides/seeing_system_objects_as_ddl.rst +++ b/operational_guides/seeing_system_objects_as_ddl.rst @@ -22,7 +22,7 @@ Getting the DDL for a table farm=> SELECT GET_DDL('cool_animals'); create table "public"."cool_animals" ( "id" int not null, - "name" varchar(30) not null, + "name" text(30) not null, "weight" double null, "is_agressive" bool default false not null ) ; @@ -142,7 +142,7 @@ Exporting database DDL to a client farm=> SELECT DUMP_DATABASE_DDL(); create table "public"."cool_animals" ( "id" int not null, - "name" varchar(30) not null, + "name" text(30) not null, "weight" double null, "is_agressive" bool default false not null ) diff --git a/reference/sql/sql_functions/scalar_functions/conditionals/is_null.rst b/reference/sql/sql_functions/scalar_functions/conditionals/is_null.rst index c99f4e7d1..94f8605f7 100644 --- a/reference/sql/sql_functions/scalar_functions/conditionals/is_null.rst +++ b/reference/sql/sql_functions/scalar_functions/conditionals/is_null.rst @@ -40,7 +40,7 @@ For these examples, consider the following table and contents: .. code-block:: postgres - CREATE TABLE t (id INT NOT NULL, name VARCHAR(30), weight INT); + CREATE TABLE t (id INT NOT NULL, name TEXT(30), weight INT); INSERT INTO t VALUES (1, 'Kangaroo', 120), (2, 'Koala', 20), (3, 'Wombat', 60) ,(4, 'Kappa', NULL),(5, 'Echidna', 8),(6, 'Chupacabra', NULL) diff --git a/reference/sql/sql_functions/scalar_functions/date_and_time/eomonth.rst b/reference/sql/sql_functions/scalar_functions/date_and_time/eomonth.rst index 92e3f7940..50bcf7410 100644 --- a/reference/sql/sql_functions/scalar_functions/date_and_time/eomonth.rst +++ b/reference/sql/sql_functions/scalar_functions/date_and_time/eomonth.rst @@ -48,7 +48,7 @@ For these examples, consider the following table and contents: .. code-block:: postgres - CREATE TABLE cool_dates(name VARCHAR(40), d DATE, dt DATETIME); + CREATE TABLE cool_dates(name TEXT(40), d DATE, dt DATETIME); INSERT INTO cool_dates VALUES ('Marty McFly goes back to this time','1955-11-05','1955-11-05 01:21:00.000') , ('Marty McFly came from this time', '1985-10-26', '1985-10-26 01:22:00.000') diff --git a/reference/sql/sql_functions/scalar_functions/date_and_time/extract.rst b/reference/sql/sql_functions/scalar_functions/date_and_time/extract.rst index 2fd79ca86..f0ca54a58 100644 --- a/reference/sql/sql_functions/scalar_functions/date_and_time/extract.rst +++ b/reference/sql/sql_functions/scalar_functions/date_and_time/extract.rst @@ -86,7 +86,7 @@ For these examples, consider the following table and contents: .. code-block:: postgres - CREATE TABLE cool_dates(name VARCHAR(40), d DATE, dt DATETIME); + CREATE TABLE cool_dates(name TEXT(40), d DATE, dt DATETIME); INSERT INTO cool_dates VALUES ('Marty McFly goes back to this time','1955-11-05','1955-11-05 01:21:00.000') , ('Marty McFly came from this time', '1985-10-26', '1985-10-26 01:22:00.000') diff --git a/reference/sql/sql_functions/scalar_functions/string/charindex.rst b/reference/sql/sql_functions/scalar_functions/string/charindex.rst index fa9c89027..3ad4ca1f3 100644 --- a/reference/sql/sql_functions/scalar_functions/string/charindex.rst +++ b/reference/sql/sql_functions/scalar_functions/string/charindex.rst @@ -49,7 +49,7 @@ For these examples, consider the following table and contents: .. code-block:: postgres - CREATE TABLE jabberwocky(line VARCHAR(50)); + CREATE TABLE jabberwocky(line TEXT(50)); INSERT INTO jabberwocky VALUES ('''Twas brillig, and the slithy toves '), (' Did gyre and gimble in the wabe: ') @@ -73,4 +73,4 @@ Using ``CHARINDEX`` "Beware the Jabberwock, my son! | 9 The jaws that bite, the claws that catch! | 27 Beware the Jubjub bird, and shun | 8 - The frumious Bandersnatch!" | 0 + The frumious Bandersnatch!" | 0 \ No newline at end of file diff --git a/reference/sql/sql_functions/scalar_functions/string/isprefixof.rst b/reference/sql/sql_functions/scalar_functions/string/isprefixof.rst index 4a978b1ff..3da356969 100644 --- a/reference/sql/sql_functions/scalar_functions/string/isprefixof.rst +++ b/reference/sql/sql_functions/scalar_functions/string/isprefixof.rst @@ -50,7 +50,7 @@ For these examples, consider the following table and contents: .. code-block:: postgres - CREATE TABLE jabberwocky(line VARCHAR(50)); + CREATE TABLE jabberwocky(line TEXT(50)); INSERT INTO jabberwocky VALUES ('''Twas brillig, and the slithy toves '), (' Did gyre and gimble in the wabe: ') diff --git a/reference/sql/sql_functions/scalar_functions/string/lower.rst b/reference/sql/sql_functions/scalar_functions/string/lower.rst index 69dfd4f1a..4318015dc 100644 --- a/reference/sql/sql_functions/scalar_functions/string/lower.rst +++ b/reference/sql/sql_functions/scalar_functions/string/lower.rst @@ -45,7 +45,7 @@ For these examples, consider the following table and contents: .. code-block:: postgres - CREATE TABLE jabberwocky(line VARCHAR(50)); + CREATE TABLE jabberwocky(line TEXT(50)); INSERT INTO jabberwocky VALUES ('''Twas brillig, and the slithy toves'), (' Did gyre and gimble in the wabe:') diff --git a/reference/sql/sql_functions/scalar_functions/string/patindex.rst b/reference/sql/sql_functions/scalar_functions/string/patindex.rst index 063fe6d5c..b1ffcda9b 100644 --- a/reference/sql/sql_functions/scalar_functions/string/patindex.rst +++ b/reference/sql/sql_functions/scalar_functions/string/patindex.rst @@ -69,7 +69,7 @@ Notes * If the value is NULL, the result is NULL. -* PATINDEX works on ``VARCHAR`` text types only. +* PATINDEX works on ``TEXT`` text types only. * PATINDEX does not work on all literal values - only on column values. diff --git a/reference/sql/sql_functions/scalar_functions/string/trim.rst b/reference/sql/sql_functions/scalar_functions/string/trim.rst index d6e90c2f8..d249c8952 100644 --- a/reference/sql/sql_functions/scalar_functions/string/trim.rst +++ b/reference/sql/sql_functions/scalar_functions/string/trim.rst @@ -35,7 +35,7 @@ Returns the same type as the argument supplied. Notes ======= -* When using ``VARCHAR`` values, SQream DB automatically trims the trailing whitespace. +* When using ``TEXT`` values, SQream DB automatically trims the trailing whitespace. * This function is equivalent to the ANSI form ``TRIM( BOTH FROM expr )`` diff --git a/reference/sql/sql_functions/scalar_functions/string/upper.rst b/reference/sql/sql_functions/scalar_functions/string/upper.rst index 219bc854e..1f9cc1b96 100644 --- a/reference/sql/sql_functions/scalar_functions/string/upper.rst +++ b/reference/sql/sql_functions/scalar_functions/string/upper.rst @@ -45,7 +45,7 @@ For these examples, consider the following table and contents: .. code-block:: postgres - CREATE TABLE jabberwocky(line VARCHAR(50)); + CREATE TABLE jabberwocky(line TEXT(50)); INSERT INTO jabberwocky VALUES ('''Twas brillig, and the slithy toves'), (' Did gyre and gimble in the wabe:') diff --git a/reference/sql/sql_statements/ddl_commands/create_function.rst b/reference/sql/sql_statements/ddl_commands/create_function.rst index 339543a0a..a693fc897 100644 --- a/reference/sql/sql_statements/ddl_commands/create_function.rst +++ b/reference/sql/sql_statements/ddl_commands/create_function.rst @@ -52,7 +52,7 @@ Parameters * - ``argument_list`` - A comma separated list of column definitions. A column definition includes a name identifier and a datatype. * - ``return_type`` - - The SQL datatype of the return value, such as ``INT``, ``VARCHAR``, etc. + - The SQL datatype of the return value, such as ``INT``, ``TEXT``, etc. * - ``function_body`` - Python code, dollar-quoted (``$$``). diff --git a/reference/sql/sql_statements/ddl_commands/create_table.rst b/reference/sql/sql_statements/ddl_commands/create_table.rst index b660e442c..2689c6aca 100644 --- a/reference/sql/sql_statements/ddl_commands/create_table.rst +++ b/reference/sql/sql_statements/ddl_commands/create_table.rst @@ -141,7 +141,7 @@ The following is an example of the syntax used to create a standard table: CREATE TABLE cool_animals ( id INT NOT NULL, - name varchar(30) NOT NULL, + name text(30) NOT NULL, weight FLOAT, is_agressive BOOL ); @@ -155,7 +155,7 @@ The following is an example of the syntax used to create a table with default va CREATE TABLE cool_animals ( id INT NOT NULL, - name varchar(30) NOT NULL, + name text(30) NOT NULL, weight FLOAT, is_agressive BOOL DEFAULT false NOT NULL ); @@ -171,8 +171,8 @@ The following is an example of the syntax used to create a table with an identit CREATE TABLE users ( id BIGINT IDENTITY(0,1) NOT NULL , -- Start with 0, increment by 1 - name VARCHAR(30) NOT NULL, - country VARCHAR(30) DEFAULT 'Unknown' NOT NULL + name TEXT(30) NOT NULL, + country TEXT(30) DEFAULT 'Unknown' NOT NULL ); .. note:: @@ -203,9 +203,9 @@ The following is an example of the syntax used to create a table with a clusteri .. code-block:: postgres CREATE TABLE users ( - name VARCHAR(30) NOT NULL, + name TEXT(30) NOT NULL, start_date datetime not null, - country VARCHAR(30) DEFAULT 'Unknown' NOT NULL + country TEXT(30) DEFAULT 'Unknown' NOT NULL ) CLUSTER BY start_date; For more information on data clustering, see :ref:`data_clustering`. diff --git a/reference/sql/sql_statements/monitoring_commands/show_node_info.rst b/reference/sql/sql_statements/monitoring_commands/show_node_info.rst index 345d16440..9c1e1ec11 100644 --- a/reference/sql/sql_statements/monitoring_commands/show_node_info.rst +++ b/reference/sql/sql_statements/monitoring_commands/show_node_info.rst @@ -108,7 +108,7 @@ This is a full list of node types: - Compress data with both CPU and GPU schemes * - ``CpuDecompress`` - CPU - - Decompression operation, common for longer ``VARCHAR`` types + - Decompression operation, common for longer ``TEXT`` types * - ``CpuLoopJoin`` - CPU - A non-indexed nested loop join, performed on the CPU diff --git a/reference/sql/sql_statements/utility_commands/drop_saved_query.rst b/reference/sql/sql_statements/utility_commands/drop_saved_query.rst deleted file mode 100644 index f7faef6c5..000000000 --- a/reference/sql/sql_statements/utility_commands/drop_saved_query.rst +++ /dev/null @@ -1,55 +0,0 @@ -.. _drop_saved_query: - -******************** -DROP_SAVED_QUERY -******************** - -``DROP_SAVED_QUERY`` drops a :ref:`previously saved query`. - -Read more in the :ref:`saved_queries` guide. - -See also: ref:`save_query`, :ref:`execute_saved_query`, ref:`show_saved_query`, ref:`list_saved_queries`. - -Permissions -============= - -Dropping a saved query requires no special permissions. - -Syntax -========== - -.. code-block:: postgres - - drop_saved_query_statement ::= - SELECT DROP_SAVED_QUERY(saved_query_name) - ; - - saved_query_name ::= string_literal - -Returns -========== - -If saved query is dropped successfully, returns nothing. - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``saved_query_name`` - - The name of the query to drop - -Examples -=========== - -Dropping a previously saved query ---------------------------------------- - -.. code-block:: psql - - t=> SELECT DROP_SAVED_QUERY('select_all'); - executed diff --git a/reference/sql/sql_statements/utility_commands/dump_database_ddl.rst b/reference/sql/sql_statements/utility_commands/dump_database_ddl.rst index bf246b803..fc9ca1282 100644 --- a/reference/sql/sql_statements/utility_commands/dump_database_ddl.rst +++ b/reference/sql/sql_statements/utility_commands/dump_database_ddl.rst @@ -51,7 +51,7 @@ Getting the DDL for a database farm=> SELECT DUMP_DATABASE_DDL(); create table "public"."cool_animals" ( "id" int not null, - "name" varchar(30) not null, + "name" text(30) not null, "weight" double null, "is_agressive" bool default false not null ) diff --git a/reference/sql/sql_statements/utility_commands/execute_saved_query.rst b/reference/sql/sql_statements/utility_commands/execute_saved_query.rst deleted file mode 100644 index 9232a5162..000000000 --- a/reference/sql/sql_statements/utility_commands/execute_saved_query.rst +++ /dev/null @@ -1,122 +0,0 @@ -.. _execute_saved_query: - -******************** -EXECUTE_SAVED_QUERY -******************** - -``EXECUTE_SAVED_QUERY`` executes a :ref:`previously saved query`. - -Read more in the :ref:`saved_queries` guide. - -See also: ref:`save_query`, :ref:`drop_saved_query`, ref:`show_saved_query`, ref:`list_saved_queries`. - -Permissions -============= - -Executing a saved query requires ``SELECT`` permissions to access the tables referenced in the query. - -Syntax -========== - -.. code-block:: postgres - - execute_saved_query_statement ::= - SELECT EXECUTE_SAVED_QUERY(saved_query_name, [ , argument [ , ... ] ] ) - ; - - saved_query_name ::= string_literal - - argument ::= string_literal | number_literal - -Returns -========== - -Query execution results, based on the query saved. - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``saved_query_name`` - - The name of the query to execute - * - ``argument`` - - A comma separated list of argument literal values - - -Notes -========= - -* Query parameters can be used as substitutes for literal expressions. Parameters cannot be used to substitute identifiers, column names, table names, or other parts of the query. - -* Query parameters of a string datatype (like ``VARCHAR``) must be of a fixed length, and can be used in equality checks, but not patterns (e.g. :ref:`like`, :ref:`rlike`, etc) - -* Query parameters' types are inferred at compile time. - -Examples -=========== - -Assume a table named ``nba``, with the following structure: - -.. code-block:: postgres - - CREATE TABLE nba - ( - Name text(40), - Team text(40), - Number tinyint, - Position text(2), - Age tinyint, - Height text(4), - Weight real, - College text(40), - Salary float - ); - - -Here's a peek at the table contents (:download:`Download nba.csv `): - -.. csv-table:: nba.csv - :file: nba-t10.csv - :widths: auto - :header-rows: 1 - - -Saving and executing a simple query ---------------------------------------- - -.. code-block:: psql - - t=> SELECT SAVE_QUERY('select_all','SELECT * FROM nba'); - executed - t=> SELECT EXECUTE_SAVED_QUERY('select_all'); - Name | Team | Number | Position | Age | Height | Weight | College | Salary - -------------------------+------------------------+--------+----------+-----+--------+--------+-----------------------+--------- - Avery Bradley | Boston Celtics | 0 | PG | 25 | 6-2 | 180 | Texas | 7730337 - Jae Crowder | Boston Celtics | 99 | SF | 25 | 6-6 | 235 | Marquette | 6796117 - John Holland | Boston Celtics | 30 | SG | 27 | 6-5 | 205 | Boston University | - R.J. Hunter | Boston Celtics | 28 | SG | 22 | 6-5 | 185 | Georgia State | 1148640 - [...] - -Saving and executing parametrized query ------------------------------------------- - -Use parameters to replace them later at execution time. - -.. tip:: Use dollar quoting (`$$`) to avoid escaping strings. - -.. code-block:: psql - - t=> SELECT SAVE_QUERY('select_by_weight_and_team',$$SELECT * FROM nba WHERE Weight > ? AND Team = ?$$); - executed - t=> SELECT EXECUTE_SAVED_QUERY('select_by_weight_and_team', 240, 'Toronto Raptors'); - Name | Team | Number | Position | Age | Height | Weight | College | Salary - ------------------+-----------------+--------+----------+-----+--------+--------+-------------+-------- - Bismack Biyombo | Toronto Raptors | 8 | C | 23 | 6-9 | 245 | | 2814000 - James Johnson | Toronto Raptors | 3 | PF | 29 | 6-9 | 250 | Wake Forest | 2500000 - Jason Thompson | Toronto Raptors | 1 | PF | 29 | 6-11 | 250 | Rider | 245177 - Jonas Valanciunas | Toronto Raptors | 17 | C | 24 | 7-0 | 255 | | 4660482 \ No newline at end of file diff --git a/reference/sql/sql_statements/utility_commands/list_saved_queries.rst b/reference/sql/sql_statements/utility_commands/list_saved_queries.rst deleted file mode 100644 index bb1781840..000000000 --- a/reference/sql/sql_statements/utility_commands/list_saved_queries.rst +++ /dev/null @@ -1,77 +0,0 @@ -.. _list_saved_queries: - -******************** -LIST_SAVED_QUERIES -******************** - -``LIST_SAVED_QUERIES`` lists the available :ref:`previously saved queries`. - -This is an alternative way to using the ``savedqueries`` catalog view. - -Read more in the :ref:`saved_queries` guide. - -See also: ref:`save_query`, :ref:`execute_saved_query`, ref:`drop_saved_query`, ref:`show_saved_query`. - -Permissions -============= - -Listing the saved queries requires no special permissions. - -Syntax -========== - -.. code-block:: postgres - - list_saved_queries_statement ::= - SELECT LIST_SAVED_QUERIES() - ; - -Returns -========== - -List of saved query names, one per row. - -Parameters -============ - -None - -Notes -========= - -This statement returns an empty result set if no saved queries exist in the current database. - -Examples -=========== - -Listing previously saved queries ---------------------------------------- - -.. code-block:: psql - - t=> SELECT LIST_SAVED_QUERIES(); - saved_query - ------------------------- - select_all - select_by_weight - select_by_weight_and_team - - t=> SELECT SHOW_SAVED_QUERY('select_by_weight_and_team'); - saved_query - ----------------------------------------------- - SELECT * FROM nba WHERE Weight > ? AND Team = ? - - -Listing saved queries with the catalog ---------------------------------------------- - -Using the :ref:`catalog` is also possible: - -.. code-block:: psql - - t=> SELECT * FROM sqream_catalog.savedqueries; - name | num_parameters - --------------------------+--------------- - select_all | 0 - select_by_weight | 1 - select_by_weight_and_team | 2 diff --git a/reference/sql/sql_statements/utility_commands/recompile_saved_query.rst b/reference/sql/sql_statements/utility_commands/recompile_saved_query.rst deleted file mode 100644 index d6b63e30e..000000000 --- a/reference/sql/sql_statements/utility_commands/recompile_saved_query.rst +++ /dev/null @@ -1,88 +0,0 @@ -.. _recompile_saved_query: - -************************** -RECOMPILE_SAVED_QUERY -************************** - -``RECOMPILE_SAVED_QUERY`` recompiles a saved query that has been invalidated due to a schema change. - -Permissions -============= - -Recompiling a saved query requires no special permissions. - -Syntax -========== - -.. code-block:: postgres - - recompile_saved_query_statement ::= - SELECT RECOMPILE_SAVED_QUERY(saved_query_name) - ; - - saved_query_name ::= string_literal - -Returns -========== - -If saved query is recompiled successfully, returns nothing. - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``saved_query_name`` - - The name of the query to recompile - -Examples -=========== - -Recreating a query that has been invalidated -------------------------------------------------- - -.. code-block:: psql - - t=> SELECT SAVE_QUERY('select_by_weight_and_team',$$SELECT * FROM nba WHERE Weight > ? AND Team = ?$$); - executed - t=> SELECT EXECUTE_SAVED_QUERY('select_by_weight_and_team', 240, 'Toronto Raptors'); - Name | Team | Number | Position | Age | Height | Weight | College | Salary - ------------------+-----------------+--------+----------+-----+--------+--------+-------------+-------- - Bismack Biyombo | Toronto Raptors | 8 | C | 23 | 6-9 | 245 | | 2814000 - James Johnson | Toronto Raptors | 3 | PF | 29 | 6-9 | 250 | Wake Forest | 2500000 - Jason Thompson | Toronto Raptors | 1 | PF | 29 | 6-11 | 250 | Rider | 245177 - Jonas Valanciunas | Toronto Raptors | 17 | C | 24 | 7-0 | 255 | | 4660482 - - -To invalidate the original saved query, we will change the schema without affecting our original query text: - -.. code-block:: psql - - t=> ALTER TABLE nba RENAME COLUMN age to "Age (as of 2015)"; - executed - -However, because the query was compiled previously, this change invalidates the query and causes it to fail: - -.. code-block:: psql - - t=> SELECT EXECUTE_SAVED_QUERY('select_by_weight_and_team', 240, 'Toronto Raptors'); - Error: column not found {Age@null} - column not found {Age@null} - -Recompiling the query will fix this issue - -.. code-block:: psql - - t=> SELECT RECOMPILE_SAVED_QUERY('select_by_weight_and_team'); - executed - t=> SELECT EXECUTE_SAVED_QUERY('select_by_weight_and_team', 240, 'Toronto Raptors'); - Name | Team | Number | Position | Age (as of 2015) | Height | Weight | College | Salary - ------------------+-----------------+--------+----------+------------------+--------+--------+-------------+-------- - Bismack Biyombo | Toronto Raptors | 8 | C | 23 | 6-9 | 245 | | 2814000 - James Johnson | Toronto Raptors | 3 | PF | 29 | 6-9 | 250 | Wake Forest | 2500000 - Jason Thompson | Toronto Raptors | 1 | PF | 29 | 6-11 | 250 | Rider | 245177 - Jonas Valanciunas | Toronto Raptors | 17 | C | 24 | 7-0 | 255 | | 4660482 diff --git a/reference/sql/sql_statements/utility_commands/save_query.rst b/reference/sql/sql_statements/utility_commands/save_query.rst index f71f6e025..c65cd48ba 100644 --- a/reference/sql/sql_statements/utility_commands/save_query.rst +++ b/reference/sql/sql_statements/utility_commands/save_query.rst @@ -56,7 +56,7 @@ Notes * Query parameters can be used as substitutes for literal expressions. Parameters cannot be used to substitute identifiers, column names, table names, or other parts of the query. -* Query parameters of a string datatype (like ``VARCHAR``) must be of a fixed length, and can be used in equality checks, but not patterns (e.g. :ref:`like`, :ref:`rlike`, etc) +* Query parameters of a string datatype (like ``TEXT``) must be of a fixed length, and can be used in equality checks, but not patterns (e.g. :ref:`like`, :ref:`rlike`, etc) * Query parameters' types are inferred at compile time. diff --git a/reference/sql/sql_statements/utility_commands/show_saved_query.rst b/reference/sql/sql_statements/utility_commands/show_saved_query.rst deleted file mode 100644 index 15ac4c1bd..000000000 --- a/reference/sql/sql_statements/utility_commands/show_saved_query.rst +++ /dev/null @@ -1,61 +0,0 @@ -.. _show_saved_query: - -******************** -SHOW_SAVED_QUERY -******************** - -``SHOW_SAVED_QUERY`` shows the query text for a :ref:`previously saved query`. - -Read more in the :ref:`saved_queries` guide. - -See also: ref:`save_query`, :ref:`execute_saved_query`, ref:`drop_saved_query`, ref:`list_saved_queries`. - -Permissions -============= - -Showing a saved query requires no special permissions. - -Syntax -========== - -.. code-block:: postgres - - show_saved_query_statement ::= - SELECT SHOW_SAVED_QUERY(saved_query_name) - ; - - saved_query_name ::= string_literal - -Returns -========== - -A single row result containing the saved query string. - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``saved_query_name`` - - The name of the query to show - - -Examples -=========== - -Showing a previously saved query ---------------------------------------- - -.. code-block:: psql - - t=> SELECT SAVE_QUERY('select_by_weight_and_team',$$SELECT * FROM nba WHERE Weight > ? AND Team = ?$$); - executed - t=> SELECT SHOW_SAVED_QUERY('select_by_weight_and_team'); - saved_query - ----------------------------------------------- - SELECT * FROM nba WHERE Weight > ? AND Team = ? - diff --git a/sqream_studio_5.4.3/executing_statements_and_running_queries_from_the_editor.rst b/sqream_studio_5.4.3/executing_statements_and_running_queries_from_the_editor.rst index 55369d761..72cbff97b 100644 --- a/sqream_studio_5.4.3/executing_statements_and_running_queries_from_the_editor.rst +++ b/sqream_studio_5.4.3/executing_statements_and_running_queries_from_the_editor.rst @@ -223,7 +223,7 @@ The following table describes the DDL Optimizer screen: * - Column area - Shows the column **names** and **column types** from the selected table. You can scroll down or to the right/left for long column lists. * - Optimization area - - Shows the number of rows to sample as the basis for running an optimization, the default setting (1,000,000) when running an optimization (this is also the overhead threshold used when analyzing ``VARCHAR`` fields), and the default percent buffer to add to ``VARCHAR`` lengths (10%). Attempts to determine field nullability. + - Shows the number of rows to sample as the basis for running an optimization, the default setting (1,000,000) when running an optimization (this is also the overhead threshold used when analyzing ``TEXT`` fields), and the default percent buffer to add to ``TEXT`` lengths (10%). Attempts to determine field nullability. * - Run Optimizer - Starts the optimization process. From 0f8a1b34deb2b9ba4150d81307b08cefd3d94b43 Mon Sep 17 00:00:00 2001 From: YanivGerowitz <82020437+YanivGerowitz@users.noreply.github.com> Date: Sun, 10 Apr 2022 13:26:15 +0300 Subject: [PATCH 037/316] Updated according to TPD-120 Updated according to https://sqream.atlassian.net/browse/TPD-120 (confirmed with Efrat). --- .../sql_syntax/keywords_and_identifiers.rst | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/reference/sql/sql_syntax/keywords_and_identifiers.rst b/reference/sql/sql_syntax/keywords_and_identifiers.rst index e5d1a6fcf..bc2cb1de6 100644 --- a/reference/sql/sql_syntax/keywords_and_identifiers.rst +++ b/reference/sql/sql_syntax/keywords_and_identifiers.rst @@ -13,13 +13,13 @@ Regular identifiers must follow these rules: * Must be case-insensitive. SQream converts all identifiers to lowercase unless quoted. * Does not equal any keywords, such as ``SELECT``, ``OR``, or ``AND``, etc. -To bypass the rules above you can surround an identifier with double quotes (``"``). +To bypass the rules above you can surround an identifier with double quotes (``"``) or square brackets (``[]``). Quoted identifiers must follow these rules: -* Must be surrounded with double quotes (``"``). +* Must be surrounded with double quotes (``"``) or square brackets (``[]``). * May contain any ASCII character except ``@``, ``$`` or ``"``. -* Must be case-sensitive and referenced with double quotes. +* Must be case-sensitive and referenced with double quotes or square brackets (``[]``). Identifiers are different than **keywords**, which are predefined words reserved with specific meanings in a statement. Some examples of keywords are ``SELECT``, ``CREATE``, and ``WHERE``. Note that keywords **cannot** be used as identifiers. @@ -28,43 +28,45 @@ The following table shows a full list of the reserved keywords: +-------------------------------------------------------------------------------------------------+ | **Keywords** | +-------------------+---------------------+--------------------+------------------+---------------+ +| **A - C** | **C - G** | **H - N** | **N - S** | **S - W** | ++-------------------+---------------------+--------------------+------------------+---------------+ | ``ALL`` | ``CURRENT_CATALOG`` | ``HASH`` | ``NOT`` | ``SIMILAR`` | +-------------------+---------------------+--------------------+------------------+---------------+ | ``ANALYSE`` | ``CURRENT_ROLE`` | ``HAVING`` | ``NOTNULL`` | ``SOME`` | +-------------------+---------------------+--------------------+------------------+---------------+ | ``ANALYZE`` | ``CURRENT_TIME`` | ``ILIKE`` | ``NULL`` | ``SYMMETRIC`` | +-------------------+---------------------+--------------------+------------------+---------------+ -| ``AND`` | ``CURRENT_USER`` | ``IN`` | ``OFFSET`` | ``SYMMETRIC`` | -+-------------------+---------------------+--------------------+------------------+---------------+ -| ``ANY`` | ``DEFAULT`` | ``INITIALLY`` | ``ON`` | ``TABLE`` | +| ``AND`` | ``CURRENT_USER`` | ``IN`` | ``OFFSET`` | ``TABLE`` | +-------------------+---------------------+--------------------+------------------+---------------+ -| ``ARRAY`` | ``DEFERRABLE`` | ``INNER`` | ``ONLY`` | ``THEN`` | +| ``ANY`` | ``DEFAULT`` | ``INITIALLY`` | ``ON`` | ``THEN`` | +-------------------+---------------------+--------------------+------------------+---------------+ -| ``AS`` | ``DESC`` | ``INTERSECT`` | ``OPTION`` | ``TO`` | +| ``ARRAY`` | ``DEFERRABLE`` | ``INNER`` | ``ONLY`` | ``TO`` | +-------------------+---------------------+--------------------+------------------+---------------+ -| ``ASC`` | ``DISTINCT`` | ``INTO`` | ``OR`` | ``TRAILING`` | +| ``AS`` | ``DESC`` | ``INTERSECT`` | ``OPTION`` | ``TRAILING`` | +-------------------+---------------------+--------------------+------------------+---------------+ -| ``AUTHORIZATION`` | ``DO`` | ``IS`` | ``ORDER`` | ``TRUE`` | +| ``ASC`` | ``DISTINCT`` | ``INTO`` | ``OR`` | ``TRUE`` | +-------------------+---------------------+--------------------+------------------+---------------+ -| ``BINARY`` | ``ELSE`` | ``ISNULL`` | ``OUTER`` | ``UNION`` | +| ``AUTHORIZATION`` | ``DO`` | ``IS`` | ``ORDER`` | ``UNION`` | +-------------------+---------------------+--------------------+------------------+---------------+ -| ``BOTH`` | ``END`` | ``JOIN`` | ``OVER`` | ``UNIQUE`` | +| ``BINARY`` | ``ELSE`` | ``ISNULL`` | ``OUTER`` | ``UNIQUE`` | +-------------------+---------------------+--------------------+------------------+---------------+ -| ``CASE`` | ``EXCEPT`` | ``LEADING`` | ``OVERLAPS`` | ``USER`` | +| ``BOTH`` | ``END`` | ``JOIN`` | ``OVER`` | ``USER`` | +-------------------+---------------------+--------------------+------------------+---------------+ -| ``CAST`` | ``FALSE`` | ``LEFT`` | ``PLACING`` | ``USING`` | +| ``CASE`` | ``EXCEPT`` | ``LEADING`` | ``OVERLAPS`` | ``USING`` | +-------------------+---------------------+--------------------+------------------+---------------+ -| ``CHECK`` | ``FETCH`` | ``LIKE`` | ``PRIMARY`` | ``VARIADIC`` | +| ``CAST`` | ``FALSE`` | ``LEFT`` | ``PLACING`` | ``VARIADIC`` | +-------------------+---------------------+--------------------+------------------+---------------+ -| ``COLLATE`` | ``FOR`` | ``LIMIT`` | ``REFERENCES`` | ``VERBOSE`` | +| ``CHECK`` | ``FETCH`` | ``LIKE`` | ``PRIMARY`` | ``VERBOSE`` | +-------------------+---------------------+--------------------+------------------+---------------+ -| ``COLUMN`` | ``FREEZE`` | ``LOCALTIME`` | ``RETURNING`` | ``WHEN`` | +| ``COLLATE`` | ``FOR`` | ``LIMIT`` | ``REFERENCES`` | ``WHEN`` | +-------------------+---------------------+--------------------+------------------+---------------+ -| ``CONCURRENTLY`` | ``FROM`` | ``LOCALTIMESTAMP`` | ``RIGHT`` | ``WHERE`` | +| ``COLUMN`` | ``FREEZE`` | ``LOCALTIME`` | ``RETURNING`` | ``WHERE`` | +-------------------+---------------------+--------------------+------------------+---------------+ -| ``CONSTRAINT`` | ``FULL`` | ``LOOP`` | ``RLIKE`` | ``WINDOW`` | +| ``CONCURRENTLY`` | ``FROM`` | ``LOCALTIMESTAMP`` | ``RIGHT`` | ``WINDOW`` | +-------------------+---------------------+--------------------+------------------+---------------+ -| ``CREATE`` | ``GRANT`` | ``MERGE`` | ``SELECT`` | ``WITH`` | -+-------------------+---------------------+--------------------+------------------+ | -| ``CROSS`` | ``GROUP`` | ``NATURAL`` | ``SESSION_USER`` | | +| ``CONSTRAINT`` | ``FULL`` | ``LOOP`` | ``RLIKE`` | ``WITH`` | ++-------------------+---------------------+--------------------+------------------+ | +| ``CREATE`` | ``GRANT`` | ``MERGE`` | ``SELECT`` | | ++-------------------+---------------------+--------------------+------------------+ | +| ``CROSS`` | ``GROUP`` | ``NATURAL`` | ``SESSION_USER`` | | +-------------------+---------------------+--------------------+------------------+---------------+ From 5c703a7a07a97efc6a0b3e5edb07c70511ee986c Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 10 Apr 2022 17:11:10 +0300 Subject: [PATCH 038/316] Published Key Evaluation to Private Branch --- feature_guides/index.rst | 6 +- feature_guides/key_evaluation.rst | 13 ++++ .../key_evaluation_operational_modes.rst | 70 +++++++++++++++++++ feature_guides/key_evaluation_overview.rst | 16 +++++ 4 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 feature_guides/key_evaluation.rst create mode 100644 feature_guides/key_evaluation_operational_modes.rst create mode 100644 feature_guides/key_evaluation_overview.rst diff --git a/feature_guides/index.rst b/feature_guides/index.rst index ee10e3ea4..2ba36198d 100644 --- a/feature_guides/index.rst +++ b/feature_guides/index.rst @@ -5,18 +5,18 @@ Feature Guides *********************** The **Feature Guides** section describes background processes that SQream uses to manage several areas of operation, such as data ingestion, load balancing, and access control. -This section describes the following features: +This section describes the following features: .. toctree:: :maxdepth: 1 - :titlesonly: + :titlesonly: delete_guide + key_evaluation data_encryption compression flexible_data_clustering python_functions - viewing_system_objects_as_ddl workload_manager transactions concurrency_and_locks diff --git a/feature_guides/key_evaluation.rst b/feature_guides/key_evaluation.rst new file mode 100644 index 000000000..e016e68c7 --- /dev/null +++ b/feature_guides/key_evaluation.rst @@ -0,0 +1,13 @@ +.. _key_evaluation: + +************************** +Key Evaluation +************************** +The **Key Evaluation** section describes the following: + +.. toctree:: + :maxdepth: 4 + :titlesonly: + + key_evaluation_overview + key_evaluation_operational_modes \ No newline at end of file diff --git a/feature_guides/key_evaluation_operational_modes.rst b/feature_guides/key_evaluation_operational_modes.rst new file mode 100644 index 000000000..feb4fd9c1 --- /dev/null +++ b/feature_guides/key_evaluation_operational_modes.rst @@ -0,0 +1,70 @@ +.. _key_evaluation_operational_modes: + +************************** +Operational Modes +************************** +Key Evaluation can be used to do one of the following: + +**Comment** - *Do users initiate one of these modes, or do they occur in the background on their own? The answer to this question determines whether key evaluation belongs in Feature Guides or Operational Guides.* + +.. contents:: + :local: + :depth: 1 + +View All Problematic Chunk Keys +---------- +You can use the **View** mode to find all problematic keys in the database for all databases and/or tables. + +The following shows the View command options: + +.. code-block:: + + $ select  keys_evaluate ('view'); + +.. code-block:: + + $ select  keys_evaluate ('view', 'master'); + +.. code-block:: + + $ select  keys_evaluate ('view', 'master', 'public.tbl'); + +Find and Clean Problematic Keys from Storage +---------- +You can use the **Clean Storage** mode to find all problematic keys located in the Storage for all databases. + +The following shows the Clean Storage command: + +.. code-block:: + + $ select  keys_evaluate ('clean_storage'); + +.. note:: This mode backs up the levelDB to the **backup** folder in the cluster before finding and cleaning problematic keys from your storage. + +Find and Clean Problematic Keys from a Database +---------- +You can use the **Clean Database** mode to find and clean all problematic keys located for a specific database and/or table. + +The following shows the Clean Database command options: + +.. code-block:: + + $ select keys_evaluate ('clean_database','master'); + +.. code-block:: + + $ select keys_evaluate ('clean_database','master', 'public.tbl'); + +.. note:: This mode backs up the levelDB to the **backup** folder in the cluster before finding and cleaning problematic keys from your database. + +Clean Specifically Defined Chunk Keys +---------- +**Comment** - *Currently not supported. Remove until further notice?* + +You can use the **Clean Chunk Key** mode to clean a specific problematic chunk key. **Comment** - *Note: data_diag vs keys_evaluate.* + +The following shows the Clean Chunk Key command options: + +.. code-block:: + + $ select data_diag (12, ''); \ No newline at end of file diff --git a/feature_guides/key_evaluation_overview.rst b/feature_guides/key_evaluation_overview.rst new file mode 100644 index 000000000..50e3f3eab --- /dev/null +++ b/feature_guides/key_evaluation_overview.rst @@ -0,0 +1,16 @@ +.. _key_evaluation_overview: + +************************** +Overview +************************** +The **Key Evaluation** feature resolves conflicts caused by ingesting and deleting data at the same time. Although this rarely occurs, it causes the leveldb to restore keys pointing to deleted data. In turn, this causes SQream metadata to search for deleted files. + +An indication that this conflict has occurred is SQream's inability to retrieve deleted data pointers, generating the type of error shown below: + +.. code-block:: console + + $ Internal Runtime Error *** Error opening [errno 2 No such file or directory] file name /mnt/disk1/sqream_cluster/databases/******/tables/289/17/17-391270 + +In addition, key evaluation prevents the database from creating phantom keys, which are duplicate chunk keys generated when data is ingested. Under normal circumstances ingesting data creates incrementing chunk keys. + +**Comment** - *Please confirm the reason I provided based on my understanding of the source doc.* \ No newline at end of file From e71871a44a4048c4a7e79be3a8866cba328c524d Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 10 Apr 2022 17:33:39 +0300 Subject: [PATCH 039/316] Corrected syntax --- feature_guides/key_evaluation_overview.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature_guides/key_evaluation_overview.rst b/feature_guides/key_evaluation_overview.rst index 50e3f3eab..3d3aabf8a 100644 --- a/feature_guides/key_evaluation_overview.rst +++ b/feature_guides/key_evaluation_overview.rst @@ -9,7 +9,7 @@ An indication that this conflict has occurred is SQream's inability to retrieve .. code-block:: console - $ Internal Runtime Error *** Error opening [errno 2 No such file or directory] file name /mnt/disk1/sqream_cluster/databases/******/tables/289/17/17-391270 + Internal Runtime Error *** Error opening [errno 2 No such file or directory] file name /mnt/disk1/sqream_cluster/databases/******/tables/289/17/17-391270 In addition, key evaluation prevents the database from creating phantom keys, which are duplicate chunk keys generated when data is ingested. Under normal circumstances ingesting data creates incrementing chunk keys. From d349955969ba341c2a2a6699e2f4916362245f59 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 12 Apr 2022 11:05:55 +0300 Subject: [PATCH 040/316] Updated Taco File Link --- third_party_tools/client_drivers/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party_tools/client_drivers/index.rst b/third_party_tools/client_drivers/index.rst index 102827f22..d52b41e95 100644 --- a/third_party_tools/client_drivers/index.rst +++ b/third_party_tools/client_drivers/index.rst @@ -24,7 +24,7 @@ The following are applicable to all operating systems: * **Tableau**: - * `Tableau connector `_ - SQream (.taco) + * `https://sq-ftp-public.s3.amazonaws.com/SQreamTaco.rar>`_ - SQream (.taco) * `Tableau manual installation `_ From 8645e71f82ad5833ab256eaa84bed7a4cfa63014 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Wed, 13 Apr 2022 11:30:41 +0300 Subject: [PATCH 041/316] Added Installing NGINX Proxy Over Secure Connection Private branch - I added this file to this branch to show it to Dor before publishing it on live branches. --- ...ing_nginx_proxy_over_secure_connection.rst | 427 ++++++++++++++++++ .../sqream_studio_installation.rst | 3 +- 2 files changed, 429 insertions(+), 1 deletion(-) create mode 100644 installation_guides/installing_nginx_proxy_over_secure_connection.rst diff --git a/installation_guides/installing_nginx_proxy_over_secure_connection.rst b/installation_guides/installing_nginx_proxy_over_secure_connection.rst new file mode 100644 index 000000000..4596f109e --- /dev/null +++ b/installation_guides/installing_nginx_proxy_over_secure_connection.rst @@ -0,0 +1,427 @@ +.. _installing_nginx_proxy_over_secure_connection: + +************************* +Installing an NGINX Proxy Over a Secure Connection +************************* +Configuring your NGINX server to use a strong encryption for client connections provides you with secure servers requests, preventing outside parties from gaining access to your traffic. + +The **Installing an NGINX Proxy Over a Secure Connection** page describes the following: + +.. contents:: + :local: + :depth: 1 + +Overview +============== +The Node.js platform that SQream uses with our Studio user interface is susceptible to web exposure. This page describes how to implement HTTPS access on your proxy server to establish a secure connection. + +**TLS (Transport Layer Security)**, and its predecessor **SSL (Secure Sockets Layer)**, are standard web protocols used for wrapping normal traffic in a protected, encrypted wrapper. This technology prevents the interception of server-client traffic. It also uses a certificate system for helping users verify the identity of sites they visit. The **Installing an NGINX Proxy Over a Secure Connection** guide describes how to set up a self-signed SSL certificate for use with an NGINX web server on a CentOS 7 server. + +.. note:: A self-signed certificate encrypts communication between your server and any clients. However, because it is not signed by trusted certificate authorities included with web browsers, you cannot use the certificate to automatically validate the identity of your server. + +A self-signed certificate may be appropriate if your domain name is not associated with your server, and in cases where your encrypted web interface is not user-facing. If you do have a domain name, using a CA-signed certificate is generally preferrable. + +For more information on setting up a free trusted certificate, see `How To Secure Nginx with Let's Encrypt on CentOS 7 `_. + +Prerequisites +============== +The following prerequisites are required for installing an NGINX proxy over a secure connection: + +* Super user privileges + + :: + +* A domain name to create a certificate for + +Installing NGINX and Adjusting the Firewall +============== +After verifying that you have the above preriquisites, you must verify that the NGINX web server has been installed on your machine. + +Though NGINX is not available in the default CentOS repositories, it is available from the **EPEL (Extra Packages for Enterprise Linux)** repository. + +**To install NGINX and adjust the firewall:** + +1. Enable the EPEL repository to enable server access to the NGINX package: + + .. code-block:: console + + $ sudo yum install epel-release + +2. Install NGINX: + + .. code-block:: console + + $ sudo yum install nginx + +3. Start the NGINX service: + + .. code-block:: console + + $ sudo systemctl start nginx + +4. Verify that the service is running: + + .. code-block:: console + + $ systemctl status nginx + + The following is an example of the correct output: + + .. code-block:: console + + Output● nginx.service - The nginx HTTP and reverse proxy server + Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled) + Active: active (running) since Fri 2017-01-06 17:27:50 UTC; 28s ago + + . . . + + Jan 06 17:27:50 centos-512mb-nyc3-01 systemd[1]: Started The nginx HTTP and reverse proxy server. + +5. Enable NGINX to start when your server boots up: + + .. code-block:: console + + $ sudo systemctl enable nginx + +6. Verify that access to **ports 80 and 443** are not blocked by a firewall. + + :: + +7. Do one of the following: + + * If you are not using a firewall, skip to :ref:`Creating Your SSL Certificate`. + + :: + + * If you have a running firewall, open ports 80 and 443: + + .. code-block:: console + + $ sudo firewall-cmd --add-service=http + $ sudo firewall-cmd --add-service=https + $ sudo firewall-cmd --runtime-to-permanent + +8. If have a running **iptables firewall**, for a basic rule set, add HTTP and HTTPS access: + + .. code-block:: console + + $ sudo iptables -I INPUT -p tcp -m tcp --dport 80 -j ACCEPT + $ sudo iptables -I INPUT -p tcp -m tcp --dport 443 -j ACCEPT + +**Comment** - *Is Step 8 above optional?* + + .. note:: The commands in Step 8 above are highly dependent on your current rule set. + +9. Verify that you can access the default NGINX page from a web browser. + +.. _creating_your_ssl_certificate: + +Creating Your SSL Certificate +============== +After installing NGINX and adjusting your firewall, you must create your SSL certificate. + +TLS/SSL **Comment** - *Why mention "TLS" if we are only speaking about SSL?)* combines public certificates with private keys. The SSL key, kept private on your server, is used to encrypt content sent to clients, while the SSL certificate is publicly shared with anyone requesting content. In addition, the SSL certificate can be used to decrypt the content signed by the associated SSL key. Your public certificate is located in the **/etc/ssl/certs** directory on your server. + +This section describes how to create your **/etc/ssl/private directory**, used for storing your private key file. Because the privacy of this key is essential for security, the permissions must be locked down **(Comment** - *Disabled?*) to prevent unauthorized access: + +**To create your SSL certificate:** + +1. Set the following permissions to **private**: + + .. code-block:: console + + $ sudo mkdir /etc/ssl/private + $ sudo chmod 700 /etc/ssl/private + +2. Create a self-signed key and certificate pair with OpenSSL in a single command: + + .. code-block:: console + + $ sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt + + The following list describes the elements in the command above: + + * **openssl** - The basic command line tool used for creating and managing OpenSSL certificates, keys, and other files. + + :: + + * **req** - A subcommand for using the X.509 **Certificate Signing Request (CSR)** management. A public key infrastructure standard, SSL and TLS adhere X.509 key and certificate management regulations. + + :: + + * **-x509** - Used for modifying the previous subcommand by overriding the default functionality of generating a certificate signing request with making a self-signed certificate. + + :: + + * **-nodes** - Sets **OpenSSL** to skip the option of securing our certificate with a passphrase, letting NGINX read the file without user intervention when the server is activated. If you don't use **-nodes** you must enter your passphrase after every restart. + + :: + + * **-days 365** - Sets the certificate's validation duration to one year. + + :: + + * **-newkey rsa:2048** - Simultaneously generates a new certificate and new key. Because the key required to sign the certificate was not created in the previous step **(Comment** - *Step 1?*), it must be created along with the certificate. The **rsa:2048** generates an RSA 2048 bits long. + + :: + + * **-keyout** - Determines the location of the generated private key file. + + :: + + * **-out** - Determines the location of the certificate. + + After creating a self-signed key and certificate pair with OpenSSL, a series of prompts about your server is presented (**Comment** - *By SSL?*) to correctly embed the information you provided in the certificate. + +**Comment** - *Dor, please confirm that the sentence above is correct.* + +3. Provide the information requested by the prompts. + + The most important piece of information is the **Common Name**, which is either the server **FQDN** or **your** name. You must enter the domain name associated with your server or your server’s public IP address. + + The following is an example of a filled out set of prompts: + + .. code-block:: console + + OutputCountry Name (2 letter code) [AU]:US + State or Province Name (full name) [Some-State]:New York + Locality Name (eg, city) []:New York City + Organization Name (eg, company) [Internet Widgits Pty Ltd]:Bouncy Castles, Inc. + Organizational Unit Name (eg, section) []:Ministry of Water Slides + Common Name (e.g. server FQDN or YOUR name) []:server_IP_address + Email Address []:admin@your_domain.com + + Both files you create are stored in their own subdirectories of the **/etc/ssl** directory. + + While (**Comment** - *"Although" instead of "while"?*) SQream uses OpenSSL, in addition we recommend creating a strong **Diffie-Hellman** group, used for negotiating **Perfect Forward Secrecy** with clients. + + **Comment** - *Please explain what you meant by "negotiating".* + +4. Create a strong Diffie-Hellman group: + + .. code-block:: console + + $ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 + + Creating a Diffie-Hellman group takes a few minutes, which is stored as the **dhparam.pem** file in the **/etc/ssl/certs** directory. This file can use in the configuration. + + **Comment** - *Please explain what you meant by that it can be used in the configuration.* + +Configuring NGINX to use SSL +============== +After creating your SSL certificate, you must configure NGINX to use SSL. + +The default CentOS NGINX configuration is fairly unstructured, (**Comment** - *What is the intent of "unstructured"?) with the default HTTP server block located in the main configuration file. NGINX checks for files ending in **.conf** in the **/etc/nginx/conf.d** directory for additional configuration. (**Comment** - *What did you mean by "additional configuration"? How does this work?*) + +SQream creates a new file in the **/etc/nginx/conf.d** directory to configure a server block. This block serves content using the certificate files we generated. In addition, the default server block can be optionally configured to redirect HTTP requests to HTTPS. + +.. note:: The example on this page uses the IP address **127.0.0.1**, which you should replace with your machine's IP address. + +**To configure NGINX to use SSL:** + +1. Create and open a file called **ssl.conf** in the **/etc/nginx/conf.d** directory: + + .. code-block:: console + + $ sudo vi /etc/nginx/conf.d/ssl.conf + +2. Inside, (**Comment** - *In the directory?*) open a server block: + + 1. Listen to **port 443**, which is the TLS/SSL default port. + + :: + + 2. Set the ``server_name`` to the server’s domain name or IP address you used as the Common Name when generating your certificate. + + :: + + 3. Use the ``ssl_certificate``, ``ssl_certificate_key``, and ``ssl_dhparam`` directives to set the location of the SSL files you generated, as shown in the **/etc/nginx/conf.d/ssl.conf** file below: + + **Comment** - *Please confirm Step 3 above.* + + .. code-block:: console + + upstream ui { + server 127.0.0.1:8080; + } + server { + listen 443 http2 ssl; + listen [::]:443 http2 ssl; + + server_name nginx.sq.l; + + ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt; + ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key; + ssl_dhparam /etc/ssl/certs/dhparam.pem; + + root /usr/share/nginx/html; + + # location / { + # } + + location / { + proxy_pass http://ui; + proxy_set_header X-Forwarded-Proto https; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $host; + add_header Front-End-Https on; + add_header X-Cache-Status $upstream_cache_status; + proxy_cache off; + proxy_cache_revalidate off; + proxy_cache_min_uses 1; + proxy_cache_valid 200 302 1h; + proxy_cache_valid 404 3s; + proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504; + proxy_no_cache $cookie_nocache $arg_nocache $arg_comment $http_pragma $http_authorization; + proxy_redirect default; + proxy_max_temp_file_size 0; + proxy_connect_timeout 90; + proxy_send_timeout 90; + proxy_read_timeout 90; + proxy_buffer_size 4k; + proxy_buffering on; + proxy_buffers 4 32k; + proxy_busy_buffers_size 64k; + proxy_temp_file_write_size 64k; + proxy_intercept_errors on; + + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } + + error_page 404 /404.html; + location = /404.html { + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + } + } + +4. Open and modify the **nginx.conf** file located in the **/etc/nginx/conf.d** directory as follows: + + .. code-block:: console + + $ sudo vi /etc/nginx/conf.d/nginx.conf + +**Comment** - *Why is this here (below)?* + +**/etc/nginx/nginx.conf** + + .. code-block:: console + + server { + listen 80; + listen [::]:80; + server_name _; + root /usr/share/nginx/html; + + # Load configuration files for the default server block. + include /etc/nginx/default.d/*.conf; + + error_page 404 /404.html; + location = /404.html { + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + } + } + +Redirecting Studio Access from HTTP to HTTPS +================== +After configuring NGINX to use SSL, you must redirect Studio access from HTTP to HTTPS. + +According to your current configuration, NGINX responds with encrypted content for requests on port 443, but with **unencrypted** content for requests on **port 80**. This means that our site offers encryption, but does not enforce its usage. This may be fine for some use cases, but it is usually better to require encryption. This is especially important when confidential data like passwords may be transferred between the browser and the server. + +Thankfully, the default Nginx configuration file allows us to easily add directives to the default port 80 server block by adding files in the /etc/nginx/default.d directory. + +**Comment** - *We need to discuss the paragraphs above together.* + +**To create a redirect from HTTP to HTTPS:** + +1. Create a new file called **ssl-redirect.conf** and open it for editing: + + .. code-block:: console + + $ sudo vi /etc/nginx/default.d/ssl-redirect.conf + +2. Copy and paste this line: + + .. code-block:: console + + $ /etc/nginx/default.d/ssl-redirect.conf + + $ return 301 https://$host$request_uri:8080/; + + **Comment** - *Confirm the above.* + +Enabling the Changes in NGINX +============== +**Comment** - *I suggest using "Activating" instead of "Enabling".* + +After redirecting from HTTP to HTTPs, you must restart NGINX to activate your new configuration. + +**To activate your NGINX configuration:** + +1. Verify that your files contain no syntax errors: + + .. code-block:: console + + $ sudo nginx -t + + The following output is generated if your files contain no syntax errors: + + .. code-block:: console + + nginx: the configuration file /etc/nginx/nginx.conf syntax is ok + nginx: configuration file /etc/nginx/nginx.conf test is successful + +2. Restart NGINX to activate your configuration: + + **Comment** - *We need to tell them what to do if they do have syntax errors, i.e., to correct their syntax errors. If it is not obvious how to do this, we should tell them how.* + + .. code-block:: console + + $ sudo systemctl restart nginx + +Verifying that NGINX is Running +============== +After activating your NGINX configuration, you must verify that NGINX is running correctly. + +**To verify that NGINX is running correctly:** + +1. Check that the service is up and running: + + .. code-block:: console + + $ systemctl status nginx + + The following is an example of the correct output: + + .. code-block:: console + + Output● nginx.service - The nginx HTTP and reverse proxy server + Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled) + Active: active (running) since Fri 2017-01-06 17:27:50 UTC; 28s ago + + . . . + + Jan 06 17:27:50 centos-512mb-nyc3-01 systemd[1]: Started The nginx HTTP and reverse proxy server. + +2. Run the following command: + + .. code-block:: console + + $ sudo netstat -nltp |grep nginx + + The following is an example of the correct output: + + .. code-block:: console + + [sqream@dorb-pc etc]$ sudo netstat -nltp |grep nginx + tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 15486/nginx: master + tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 15486/nginx: master + tcp6 0 0 :::80 :::* LISTEN 15486/nginx: master + tcp6 0 0 :::443 :::* LISTEN 15486/nginx: master \ No newline at end of file diff --git a/installation_guides/sqream_studio_installation.rst b/installation_guides/sqream_studio_installation.rst index 8646a35ad..53c89772d 100644 --- a/installation_guides/sqream_studio_installation.rst +++ b/installation_guides/sqream_studio_installation.rst @@ -12,4 +12,5 @@ The **Installing SQream Studio** page incudes the following installation guides: installing_prometheus_exporters installing_prometheus_using_binary_packages installing_dashboard_data_collector - installing_studio_on_stand_alone_server \ No newline at end of file + installing_studio_on_stand_alone_server + installing_nginx_proxy_over_secure_connection \ No newline at end of file From c0fb6c5939d61cd93e75f704f3fc6f28d5e761cf Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Wed, 13 Apr 2022 17:43:05 +0300 Subject: [PATCH 042/316] Published Removed all remaining comments and published. --- ...ing_nginx_proxy_over_secure_connection.rst | 48 +++++-------------- 1 file changed, 12 insertions(+), 36 deletions(-) diff --git a/installation_guides/installing_nginx_proxy_over_secure_connection.rst b/installation_guides/installing_nginx_proxy_over_secure_connection.rst index 4596f109e..5aef5eaff 100644 --- a/installation_guides/installing_nginx_proxy_over_secure_connection.rst +++ b/installation_guides/installing_nginx_proxy_over_secure_connection.rst @@ -101,15 +101,13 @@ Though NGINX is not available in the default CentOS repositories, it is availabl $ sudo firewall-cmd --add-service=https $ sudo firewall-cmd --runtime-to-permanent -8. If have a running **iptables firewall**, for a basic rule set, add HTTP and HTTPS access: +8. If you have a running **iptables firewall**, for a basic rule set, add HTTP and HTTPS access: .. code-block:: console $ sudo iptables -I INPUT -p tcp -m tcp --dport 80 -j ACCEPT $ sudo iptables -I INPUT -p tcp -m tcp --dport 443 -j ACCEPT -**Comment** - *Is Step 8 above optional?* - .. note:: The commands in Step 8 above are highly dependent on your current rule set. 9. Verify that you can access the default NGINX page from a web browser. @@ -120,9 +118,9 @@ Creating Your SSL Certificate ============== After installing NGINX and adjusting your firewall, you must create your SSL certificate. -TLS/SSL **Comment** - *Why mention "TLS" if we are only speaking about SSL?)* combines public certificates with private keys. The SSL key, kept private on your server, is used to encrypt content sent to clients, while the SSL certificate is publicly shared with anyone requesting content. In addition, the SSL certificate can be used to decrypt the content signed by the associated SSL key. Your public certificate is located in the **/etc/ssl/certs** directory on your server. +TLS/SSL combines public certificates with private keys. The SSL key, kept private on your server, is used to encrypt content sent to clients, while the SSL certificate is publicly shared with anyone requesting content. In addition, the SSL certificate can be used to decrypt the content signed by the associated SSL key. Your public certificate is located in the **/etc/ssl/certs** directory on your server. -This section describes how to create your **/etc/ssl/private directory**, used for storing your private key file. Because the privacy of this key is essential for security, the permissions must be locked down **(Comment** - *Disabled?*) to prevent unauthorized access: +This section describes how to create your **/etc/ssl/private directory**, used for storing your private key file. Because the privacy of this key is essential for security, the permissions must be locked down to prevent unauthorized access: **To create your SSL certificate:** @@ -133,7 +131,7 @@ This section describes how to create your **/etc/ssl/private directory**, used f $ sudo mkdir /etc/ssl/private $ sudo chmod 700 /etc/ssl/private -2. Create a self-signed key and certificate pair with OpenSSL in a single command: +2. Create a self-signed key and certificate pair with OpenSSL with the following command: .. code-block:: console @@ -161,7 +159,7 @@ This section describes how to create your **/etc/ssl/private directory**, used f :: - * **-newkey rsa:2048** - Simultaneously generates a new certificate and new key. Because the key required to sign the certificate was not created in the previous step **(Comment** - *Step 1?*), it must be created along with the certificate. The **rsa:2048** generates an RSA 2048 bits long. + * **-newkey rsa:2048** - Simultaneously generates a new certificate and new key. Because the key required to sign the certificate was not created in the previous step, it must be created along with the certificate. The **rsa:2048** generates an RSA 2048 bits long. :: @@ -171,9 +169,7 @@ This section describes how to create your **/etc/ssl/private directory**, used f * **-out** - Determines the location of the certificate. - After creating a self-signed key and certificate pair with OpenSSL, a series of prompts about your server is presented (**Comment** - *By SSL?*) to correctly embed the information you provided in the certificate. - -**Comment** - *Dor, please confirm that the sentence above is correct.* + After creating a self-signed key and certificate pair with OpenSSL, a series of prompts about your server is presented to correctly embed the information you provided in the certificate. 3. Provide the information requested by the prompts. @@ -193,9 +189,7 @@ This section describes how to create your **/etc/ssl/private directory**, used f Both files you create are stored in their own subdirectories of the **/etc/ssl** directory. - While (**Comment** - *"Although" instead of "while"?*) SQream uses OpenSSL, in addition we recommend creating a strong **Diffie-Hellman** group, used for negotiating **Perfect Forward Secrecy** with clients. - - **Comment** - *Please explain what you meant by "negotiating".* + Although SQream uses OpenSSL, in addition we recommend creating a strong **Diffie-Hellman** group, used for negotiating **Perfect Forward Secrecy** with clients. 4. Create a strong Diffie-Hellman group: @@ -205,13 +199,11 @@ This section describes how to create your **/etc/ssl/private directory**, used f Creating a Diffie-Hellman group takes a few minutes, which is stored as the **dhparam.pem** file in the **/etc/ssl/certs** directory. This file can use in the configuration. - **Comment** - *Please explain what you meant by that it can be used in the configuration.* - Configuring NGINX to use SSL ============== After creating your SSL certificate, you must configure NGINX to use SSL. -The default CentOS NGINX configuration is fairly unstructured, (**Comment** - *What is the intent of "unstructured"?) with the default HTTP server block located in the main configuration file. NGINX checks for files ending in **.conf** in the **/etc/nginx/conf.d** directory for additional configuration. (**Comment** - *What did you mean by "additional configuration"? How does this work?*) +The default CentOS NGINX configuration is fairly unstructured, with the default HTTP server block located in the main configuration file. NGINX checks for files ending in **.conf** in the **/etc/nginx/conf.d** directory for additional configuration. SQream creates a new file in the **/etc/nginx/conf.d** directory to configure a server block. This block serves content using the certificate files we generated. In addition, the default server block can be optionally configured to redirect HTTP requests to HTTPS. @@ -225,7 +217,7 @@ SQream creates a new file in the **/etc/nginx/conf.d** directory to configure a $ sudo vi /etc/nginx/conf.d/ssl.conf -2. Inside, (**Comment** - *In the directory?*) open a server block: +2. In the file you created in Step 1 above, open a server block: 1. Listen to **port 443**, which is the TLS/SSL default port. @@ -237,8 +229,6 @@ SQream creates a new file in the **/etc/nginx/conf.d** directory to configure a 3. Use the ``ssl_certificate``, ``ssl_certificate_key``, and ``ssl_dhparam`` directives to set the location of the SSL files you generated, as shown in the **/etc/nginx/conf.d/ssl.conf** file below: - **Comment** - *Please confirm Step 3 above.* - .. code-block:: console upstream ui { @@ -304,11 +294,7 @@ SQream creates a new file in the **/etc/nginx/conf.d** directory to configure a .. code-block:: console $ sudo vi /etc/nginx/conf.d/nginx.conf - -**Comment** - *Why is this here (below)?* - -**/etc/nginx/nginx.conf** - + .. code-block:: console server { @@ -335,9 +321,7 @@ After configuring NGINX to use SSL, you must redirect Studio access from HTTP to According to your current configuration, NGINX responds with encrypted content for requests on port 443, but with **unencrypted** content for requests on **port 80**. This means that our site offers encryption, but does not enforce its usage. This may be fine for some use cases, but it is usually better to require encryption. This is especially important when confidential data like passwords may be transferred between the browser and the server. -Thankfully, the default Nginx configuration file allows us to easily add directives to the default port 80 server block by adding files in the /etc/nginx/default.d directory. - -**Comment** - *We need to discuss the paragraphs above together.* +The default NGINX configuration file allows us to easily add directives to the default port 80 server block by adding files in the /etc/nginx/default.d directory. **To create a redirect from HTTP to HTTPS:** @@ -351,16 +335,10 @@ Thankfully, the default Nginx configuration file allows us to easily add directi .. code-block:: console - $ /etc/nginx/default.d/ssl-redirect.conf - $ return 301 https://$host$request_uri:8080/; - **Comment** - *Confirm the above.* - -Enabling the Changes in NGINX +Activating Your NGINX Configuration ============== -**Comment** - *I suggest using "Activating" instead of "Enabling".* - After redirecting from HTTP to HTTPs, you must restart NGINX to activate your new configuration. **To activate your NGINX configuration:** @@ -380,8 +358,6 @@ After redirecting from HTTP to HTTPs, you must restart NGINX to activate your ne 2. Restart NGINX to activate your configuration: - **Comment** - *We need to tell them what to do if they do have syntax errors, i.e., to correct their syntax errors. If it is not obvious how to do this, we should tell them how.* - .. code-block:: console $ sudo systemctl restart nginx From 0a3b758916c1f37d7288b37f3abf8558ae5e9195 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 17 Apr 2022 10:45:19 +0300 Subject: [PATCH 043/316] Update installing_studio_on_stand_alone_server.rst Added lines 159-192 based on discussion with Slavi and Dor. --- ...nstalling_studio_on_stand_alone_server.rst | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/installation_guides/installing_studio_on_stand_alone_server.rst b/installation_guides/installing_studio_on_stand_alone_server.rst index 874adba8d..ecec67c7f 100644 --- a/installation_guides/installing_studio_on_stand_alone_server.rst +++ b/installation_guides/installing_studio_on_stand_alone_server.rst @@ -5,8 +5,6 @@ *********************** Installing Studio on a Stand-Alone Server *********************** - - The **Installing Studio on a Stand-Alone Server** guide describes how to install SQream Studio on a stand-alone server. A stand-alone server is a server that does not run SQream based on binary files, Docker, or Kubernetes. The Installing Studio on a Stand-Alone Server guide includes the following sections: @@ -147,7 +145,7 @@ After installing the Dashboard Data Collector, you can install Studio. .. code-block:: console - $ npm run setup -- -y --host= --port=3108 + $ npm run setup -- -y --host= --port=3108 --data-collector-url=http://:8100/api/dashboard/data The above command creates the **sqream-admin-config.json** configuration file in the **sqream-admin** folder and shows the following output: @@ -158,6 +156,40 @@ After installing the Dashboard Data Collector, you can install Studio. For more information about the available set-up arguments, see :ref:`Set-Up Arguments`. :: + +5. To access Studio over a secure connection, in your configuration file do the following: + + #. Change your ``port`` value to **3109**. + + :: + + #. Change your ``ssl`` flag value to **true**. + + The following is an example of the correctly modified configuration file: + + .. code-block:: console + + { + "debugSqream": false, + "webHost": "localhost", + "webPort": 8080, + "webSslPort": 8443, + "logsDirectory": "", + "clusterType": "standalone", + "dataCollectorUrl": "", + "connections": [ + { + "host": "127.0.0.1", + "port":3109, + "isCluster": true, + "name": "default", + "service": "sqream", + "ssl":true, + "networkTimeout": 60000, + "connectionTimeout": 3000 + } + ] + } 5. If you have installed Studio on a server where SQream is already installed, move the **sqream-admin-config.json** file to **/etc/sqream/**: @@ -575,4 +607,4 @@ Back to :ref:`Installing Studio in a Docker Container` +Back to :ref:`Installing Studio on a Stand-Alone Server` \ No newline at end of file From f0220f55206229027444bcfbfc82f953d417b99b Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 17 Apr 2022 13:41:20 +0300 Subject: [PATCH 044/316] Update data_encryption_permissions.rst --- .../data_encryption_permissions.rst | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/feature_guides/data_encryption_permissions.rst b/feature_guides/data_encryption_permissions.rst index 16f41dc70..d7c655ad5 100644 --- a/feature_guides/data_encryption_permissions.rst +++ b/feature_guides/data_encryption_permissions.rst @@ -3,18 +3,14 @@ *********************** Permissions *********************** -Users with the appropriate encryption permission privilege's can encrypt and decrypt data. +The **Permissions** tells you how to create a table with encrypted columns as a superuser. -**Comment** - *The rest of this content seems internal, correct?* +Users with the appropriate encryption permission privilege's can encrypt and decrypt data. In addition, only superusers granted permission can view encrypted tables in the **sqream_catalog**. -Implementation notes +You can create a table with encrypted columns as a superuser as follows: -one method to encrypt the data with is the TDE: Transparent data encryption which employed by Microsoft/IBM/Oracle etc. - -management. The requirement is that this will be programmatic via API. - -The centralized key management store should be one of the following (R&D to choose which one in accordance to easiness of deployment): - -KMS (AWS)- https://aws.amazon.com/kms/ - -IBM- IBM Security Guardium Key Lifecycle Manager - Overview \ No newline at end of file +.. code-block:: console + + $ create or replace table t_enc(c1 int encrypt); + +For more information about the SQream catalog, see the :ref:`catalog_reference`. \ No newline at end of file From 2e37e000af4f732b2cb3da95c37e34e852a8cddc Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 17 Apr 2022 14:14:45 +0300 Subject: [PATCH 045/316] Update data_encryption_permissions.rst Added missing word. --- feature_guides/data_encryption_permissions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature_guides/data_encryption_permissions.rst b/feature_guides/data_encryption_permissions.rst index d7c655ad5..d9a132b45 100644 --- a/feature_guides/data_encryption_permissions.rst +++ b/feature_guides/data_encryption_permissions.rst @@ -3,7 +3,7 @@ *********************** Permissions *********************** -The **Permissions** tells you how to create a table with encrypted columns as a superuser. +The **Permissions** page tells you how to create a table with encrypted columns as a superuser. Users with the appropriate encryption permission privilege's can encrypt and decrypt data. In addition, only superusers granted permission can view encrypted tables in the **sqream_catalog**. From 3ef220402188cbb4c03debd4becb8d28ee133b75 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 17 Apr 2022 17:41:53 +0300 Subject: [PATCH 046/316] Added DECODE Function --- reference/sql/sql_functions/index.rst | 6 +-- .../scalar_functions/string/decode.rst | 47 +++++++++++++++++++ 2 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 reference/sql/sql_functions/scalar_functions/string/decode.rst diff --git a/reference/sql/sql_functions/index.rst b/reference/sql/sql_functions/index.rst index 46d643308..395cdfd59 100644 --- a/reference/sql/sql_functions/index.rst +++ b/reference/sql/sql_functions/index.rst @@ -223,6 +223,8 @@ The following table shows the **string* functions: - Calculates the position where a string starts inside another string * - :ref:`concat` - Concatenates two strings + * - :ref:`decode` + - Decodes or extracts binary data from a textual input string * - :ref:`isprefixof` - Matches if a string is the prefix of another string * - :ref:`left` @@ -416,6 +418,4 @@ The following table shows the **workload management** functions: user_defined_functions/index aggregate_functions/index window_functions/index - system_functions/index - - + system_functions/index \ No newline at end of file diff --git a/reference/sql/sql_functions/scalar_functions/string/decode.rst b/reference/sql/sql_functions/scalar_functions/string/decode.rst new file mode 100644 index 000000000..1ed10e399 --- /dev/null +++ b/reference/sql/sql_functions/scalar_functions/string/decode.rst @@ -0,0 +1,47 @@ +.. _decode: + +******************** +DECODE +******************** +The **DECODE** function is a PostgreSQL function used for decoding or extracting binary data from a textual input string. + +Syntax +========== +The following shows the correct syntax for the DECODE function: + +.. code-block:: postgres + + decode(string input_text, format type_text) + +Parameters +============ +The following table shows the DECODE parameters: + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``input_text`` + - Defines the input text string. + * - ``type_text`` + - Defines the format used for decoding the input text. + +Returns +========= +**Comment** - *What does it return?* + +Notes +=========== +**Comment** - *Are there any relevant notes?* + +Examples +=========== +**Comment** - *What does the actual output look like? Can you provide an example?* + +Permissions +============= +**Comment** - *Please confirm what permissions the role requires.* + +The role must have the ``SUPERUSER`` permissions. \ No newline at end of file From a9de45732ef39b5cc7f93e9efb715dfbc6268f9b Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 17 Apr 2022 17:47:59 +0300 Subject: [PATCH 047/316] Update index.rst Added DECODE --- reference/sql/sql_functions/scalar_functions/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/reference/sql/sql_functions/scalar_functions/index.rst b/reference/sql/sql_functions/scalar_functions/index.rst index bd05f9bbe..ae70874e3 100644 --- a/reference/sql/sql_functions/scalar_functions/index.rst +++ b/reference/sql/sql_functions/scalar_functions/index.rst @@ -17,6 +17,7 @@ The **Built-In Scalar Functions** page describes functions that return one value * :ref:`between` * :ref:`case` * :ref:`coalesce` + * :ref:`decode` * :ref:`in` * :ref:`is_ascii` * :ref:`is_null` From b2ea112fa7386044871feb78dfc1ae2f1a245560 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 17 Apr 2022 18:16:47 +0300 Subject: [PATCH 048/316] Update index.rst --- reference/sql/sql_statements/index.rst | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/reference/sql/sql_statements/index.rst b/reference/sql/sql_statements/index.rst index ae0139607..eab8d8f84 100644 --- a/reference/sql/sql_statements/index.rst +++ b/reference/sql/sql_statements/index.rst @@ -100,6 +100,8 @@ Utility Commands * - Command - Usage + * - :ref:`EXPLAIN` + - Returns a static query plan, which can be used to debug query plans * - :ref:`SELECT GET_LICENSE_INFO` - View a user's license information * - :ref:`SELECT GET_DDL` @@ -112,7 +114,18 @@ Utility Commands - Recreate a view after schema changes * - :ref:`SELECT DUMP_DATABASE_DDL` - View the ``CREATE TABLE`` statement for an current database - + * - :ref:`SHOW CONNECTIONS` + - Returns a list of active sessions on the current worker + * - :ref:`SHOW LOCKS` + - Returns a list of locks from across the cluster + * - :ref:`SHOW NODE INFO` + - Returns a snapshot of the current query plan, similar to ``EXPLAIN ANALYZE`` from other databases + * - :ref:`SHOW SERVER STATUS` + - Returns a list of active sessions across the cluster + * - :ref:`SHOW VERSION` + - Returns the system version for SQream DB + * - :ref:`STOP STATEMENT` + - Stops or aborts an active statement Monitoring From ab85fac18708fa16c1029524dc9f2c020f0e1929 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 24 Apr 2022 13:13:01 +0300 Subject: [PATCH 049/316] Moved System Functions to SQL Statements > Utility Commands Deleted System Functions section from SQL functions. Deleted System Functions folder (all system functions moved to SQL Syntax > Utility Commands)> --- reference/sql/sql_functions/index.rst | 27 -- .../utility_commands/explain.rst | 59 ++++ .../utility_commands/show_connections.rst | 78 +++++ .../utility_commands/show_locks.rst | 79 +++++ .../utility_commands/show_node_info.rst | 310 ++++++++++++++++++ .../utility_commands/show_server_status.rst | 108 ++++++ .../utility_commands/show_version.rst | 46 +++ .../utility_commands/stop_statement.rst | 77 +++++ 8 files changed, 757 insertions(+), 27 deletions(-) create mode 100644 reference/sql/sql_statements/utility_commands/explain.rst create mode 100644 reference/sql/sql_statements/utility_commands/show_connections.rst create mode 100644 reference/sql/sql_statements/utility_commands/show_locks.rst create mode 100644 reference/sql/sql_statements/utility_commands/show_node_info.rst create mode 100644 reference/sql/sql_statements/utility_commands/show_server_status.rst create mode 100644 reference/sql/sql_statements/utility_commands/show_version.rst create mode 100644 reference/sql/sql_statements/utility_commands/stop_statement.rst diff --git a/reference/sql/sql_functions/index.rst b/reference/sql/sql_functions/index.rst index 395cdfd59..5ef0a7c5f 100644 --- a/reference/sql/sql_functions/index.rst +++ b/reference/sql/sql_functions/index.rst @@ -363,32 +363,6 @@ For more information about window functions, see :ref:`window_functions`. - Returns an integer ranging between ``1`` and the argument value, dividing the partitions as equally as possible -System Functions ------------------- -System functions allow you to execute actions in the system, such as aborting a query or get information about system processes. - -The following table shows the **system** functions: - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Function - - Description - * - :ref:`explain` - - Returns a static query plan for a statement - * - :ref:`show_connections` - - Returns a list of jobs and statements on the current worker - * - :ref:`show_locks` - - Returns any existing locks in the database - * - :ref:`show_node_info` - - Returns a query plan for an actively running statement with timing information - * - :ref:`show_server_status` - - Shows running statements across the cluster - * - :ref:`show_version` - - Returns the version of SQream DB - * - :ref:`stop_statement` - - Stops a query (or statement) if it is currently running Workload Management Functions --------------------------------- @@ -418,4 +392,3 @@ The following table shows the **workload management** functions: user_defined_functions/index aggregate_functions/index window_functions/index - system_functions/index \ No newline at end of file diff --git a/reference/sql/sql_statements/utility_commands/explain.rst b/reference/sql/sql_statements/utility_commands/explain.rst new file mode 100644 index 000000000..e9b7e7ee9 --- /dev/null +++ b/reference/sql/sql_statements/utility_commands/explain.rst @@ -0,0 +1,59 @@ +.. _explain: + +***************** +EXPLAIN +***************** + +``EXPLAIN`` returns a static query plan, which can be used to debug query plans. + +To see an actively running query or statement, use :ref:`show_node_info` instead. + +See also :ref:`show_node_info`, :ref:`show_server_status`. + + +Permissions +============= + +The role must have the ``SELECT`` permissions for any tables referenced by the query. + +Syntax +========== + +.. code-block:: postgres + + explain_statement ::= + SELECT EXPLAIN(query_stmt) + ; + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``query_stmt`` + - The select query to generate the plan for. + +Notes +=========== + +Use dollar-quoting to escape the query text + +Examples +=========== + +Generating a static query plan +---------------------------------- + +.. code-block:: psql + + t=> SELECT EXPLAIN($$SELECT DATEADD(hour,1,dt) FROM cool_dates$$); + Select + Specific (TTNative Gpu) (dateadd@null := dt@null, + dateadd@val := (pure_if dt@null "0" (addHoursdt2dt dt@val "1"))) + Table Scan + public.cool_dates ("dt@null", "dt@val") [] + diff --git a/reference/sql/sql_statements/utility_commands/show_connections.rst b/reference/sql/sql_statements/utility_commands/show_connections.rst new file mode 100644 index 000000000..1bd320a4c --- /dev/null +++ b/reference/sql/sql_statements/utility_commands/show_connections.rst @@ -0,0 +1,78 @@ +.. _show_connections: + +******************** +SHOW_CONNECTIONS +******************** + +``SHOW_CONNECTIONS`` returns a list of active sessions on the current worker. + +To see sessions across the cluster, see :ref:`show_server_status`. + +Permissions +============= + +The role must have the ``SUPERUSER`` permissions. + +Syntax +========== + +.. code-block:: postgres + + show_connections_statement ::= + SELECT SHOW_CONNECTIONS() + ; + +Parameters +============ + +None + +Returns +========= + +This function returns a list of active sessions. If no sessions are active on the worker, the result set will be empty. + +.. list-table:: Result columns + :widths: auto + :header-rows: 1 + + * - ``ip`` + - The worker hostname or IP + * - ``conn_id`` + - Connection ID + * - ``conn_start_time`` + - Connection start timestamp + * - ``stmt_id`` + - Statement ID. Connections with no active statement display ``-1``. + * - ``stmt_start_time`` + - Statement start timestamp + * - ``stmt`` + - Statement text + + +Notes +=========== + +* This utility shows the active connections. Some sessions may be actively connected, but not currently running a statement. + +* A connection is typically reused. There could be many statements under a single connection ID. + +Examples +=========== + +Using ``SHOW_CONNECTIONS`` to get statement IDs +---------------------------------------------------- + + +.. code-block:: psql + + t=> SELECT SHOW_CONNECTIONS(); + ip | conn_id | conn_start_time | stmt_id | stmt_start_time | stmt + -------------+---------+---------------------+---------+---------------------+-------------------------- + 192.168.1.91 | 103 | 2019-12-24 00:01:27 | 129 | 2019-12-24 00:38:18 | SELECT GET_DATE(), * F... + 192.168.1.91 | 23 | 2019-12-24 00:01:27 | -1 | 2019-12-24 00:01:27 | + 192.168.1.91 | 22 | 2019-12-24 00:01:27 | -1 | 2019-12-24 00:01:27 | + 192.168.1.91 | 26 | 2019-12-24 00:01:28 | -1 | 2019-12-24 00:01:28 | + + +The statement ID we're interested in is ``129``. We can see the connection started at 00:01:27, while the statement started at 00:38:18. \ No newline at end of file diff --git a/reference/sql/sql_statements/utility_commands/show_locks.rst b/reference/sql/sql_statements/utility_commands/show_locks.rst new file mode 100644 index 000000000..d5e7c02ec --- /dev/null +++ b/reference/sql/sql_statements/utility_commands/show_locks.rst @@ -0,0 +1,79 @@ +.. _show_locks: + +******************** +SHOW_LOCKS +******************** + +``SHOW_LOCKS`` returns a list of locks from across the cluster. + +Read more about locks in :ref:`concurrency_and_locks`. + +Permissions +============= + +The role must have the ``SUPERUSER`` permissions. + +Syntax +========== + +.. code-block:: postgres + + show_locks_statement ::= + SELECT SHOW_LOCKS() + ; + +Parameters +============ + +None + +Returns +========= + +This function returns a list of active locks. If no locks are active in the cluster, the result set will be empty. + +.. list-table:: Result columns + :widths: auto + :header-rows: 1 + + * - ``stmt_id`` + - Statement ID that caused the lock. + * - ``stmt_string`` + - Statement text + * - ``username`` + - The role that executed the statement + * - ``server`` + - The worker node's IP + * - ``port`` + - The worker node's port + * - ``locked_object`` + - The full qualified name of the object being locked, separated with ``$`` (e.g. ``table$t$public$nba2`` for table ``nba2`` in schema ``public``, in database ``t`` + * - ``lockmode`` + - The locking mode (:ref:`inclusive` or :ref:`exclusive`). + * - ``statement_start_time`` + - Timestamp the statement started + * - ``lock_start_time`` + - Timestamp the lock was obtained + + +Examples +=========== + +Using ``SHOW_LOCKS`` to see active locks +--------------------------------------------------- + +In this example, we create a table based on results (:ref:`create_table_as`), but we are also effectively dropping the previous table (by using ``OR REPLACE``). Thus, SQream DB applies locks during the table creation process to prevent the table from being altered during it's creation. + + +.. code-block:: psql + + t=> SELECT SHOW_LOCKS(); + statement_id | statement_string | username | server | port | locked_object | lockmode | statement_start_time | lock_start_time + -------------+-------------------------------------------------------------------------------------------------+----------+--------------+------+---------------------------------+-----------+----------------------+-------------------- + 287 | CREATE OR REPLACE TABLE nba2 AS SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | sqream | 192.168.1.91 | 5000 | database$t | Inclusive | 2019-12-26 00:03:30 | 2019-12-26 00:03:30 + 287 | CREATE OR REPLACE TABLE nba2 AS SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | sqream | 192.168.1.91 | 5000 | globalpermission$ | Exclusive | 2019-12-26 00:03:30 | 2019-12-26 00:03:30 + 287 | CREATE OR REPLACE TABLE nba2 AS SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | sqream | 192.168.1.91 | 5000 | schema$t$public | Inclusive | 2019-12-26 00:03:30 | 2019-12-26 00:03:30 + 287 | CREATE OR REPLACE TABLE nba2 AS SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | sqream | 192.168.1.91 | 5000 | table$t$public$nba2$Insert | Exclusive | 2019-12-26 00:03:30 | 2019-12-26 00:03:30 + 287 | CREATE OR REPLACE TABLE nba2 AS SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | sqream | 192.168.1.91 | 5000 | table$t$public$nba2$Update | Exclusive | 2019-12-26 00:03:30 | 2019-12-26 00:03:30 + + diff --git a/reference/sql/sql_statements/utility_commands/show_node_info.rst b/reference/sql/sql_statements/utility_commands/show_node_info.rst new file mode 100644 index 000000000..345d16440 --- /dev/null +++ b/reference/sql/sql_statements/utility_commands/show_node_info.rst @@ -0,0 +1,310 @@ +.. _show_node_info: + +******************** +SHOW_NODE_INFO +******************** + +``SHOW_NODE_INFO`` returns a snapshot of the current query plan, similar to ``EXPLAIN ANALYZE`` from other databases. + +The snapshot provides information about execution which can be used for monitoring and troubleshooting slow running statements by helping identify long-running execution nodes (components that process data), etc. + +See also :ref:`explain`, :ref:`show_server_status`. + +Permissions +============= + +The role must have the ``SUPERUSER`` permissions. + +Syntax +========== + +.. code-block:: postgres + + show_node_info_statement ::= + SELECT SHOW_NODE_INFO(stmt_id) + ; + + stmt_id ::= bigint + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``stmt_id`` + - The statement ID to explore + +Returns +========= + +This utility returns details of the execution nodes, if the statement is still running. + +If the statement has finished, or the statment ID does not exist, the utility returns an empty result set. + +.. list-table:: Result columns + :widths: auto + :header-rows: 1 + + * - Column name + - Description + * - ``stmt_id`` + - The ID for the statement + * - ``node_id`` + - This node's ID in this execution plan + * - ``node_type`` + - The node type + * - ``rows`` + - Total number of rows this node has processed + * - ``chunks`` + - Number of chunks this node has processed + * - ``avg_rows_in_chunk`` + - Average amount of rows that this node processes in each chunk (``rows / chunks``) + * - ``time`` + - Timestamp for this node's creation + * - ``parent_node_id`` + - The ``node_id`` of this node's parent + * - ``read`` + - Total data read from disk + * - ``write`` + - Total data written to disk + * - ``comment`` + - Additional information (e.g. table name for ``ReadTable``) + * - ``timesum`` + - Total elapsed time for this execution node's processing + + +.. _node_types: + +Node types +============= + +This is a full list of node types: + +.. list-table:: Node types + :widths: auto + :header-rows: 1 + + * - Column name + - Execution location + - Description + * - ``AddChunkId`` + - + - Used during insert operations + * - ``AddSequences`` + - + - Used during insert operations, with :ref:`identity columns` + * - ``AddMinMaxMetadata`` + - + - Used to calculate ranges for the :ref:`chunk metadata system` + * - ``AddTopSortFilters`` + - + - An operation to optimize ``LIMIT`` when used alongside ``ORDER BY`` + * - ``Compress`` + - CPU and GPU + - Compress data with both CPU and GPU schemes + * - ``CpuDecompress`` + - CPU + - Decompression operation, common for longer ``VARCHAR`` types + * - ``CpuLoopJoin`` + - CPU + - A non-indexed nested loop join, performed on the CPU + * - ``CpuReduce`` + - CPU + - A reduce process performed on the CPU, primarily with ``DISTINCT`` aggregates (e.g. ``COUNT(DISTINCT ...)``) + * - ``CpuToGpu``, ``GpuToCpu`` + - + - An operation that moves data to or from the GPU for processing + * - ``CpuTransform`` + - CPU + - A transform operation performed on the CPU, usually a :ref:`scalar function` + * - ``CrossJoin`` + - + - A join without a join condition + * - ``DeferredGather`` + - CPU + - Merges the results of GPU operations with a result set [#f0]_ + * - ``Distinct`` + - GPU + - Removes duplicate rows (usually as part of the ``DISTINCT`` operation) + * - ``Distinct_Merge`` + - CPU + - The merge operation of the ``Distinct`` operation + * - ``Filter`` + - GPU + - A filtering operation, such as a ``WHERE`` or ``JOIN`` clause + * - ``GpuCopy`` + - GPU + - Copies data between GPUs or within a single GPU + * - ``GpuDecompress`` + - GPU + - Decompression operation + * - ``GpuReduceMerge`` + - GPU + - An operation to optimize part of the merger phases in the GPU + * - ``GpuTransform`` + - GPU + - A transformation operation such as a type cast or :ref:`scalar function` + * - ``Hash`` + - CPU + - Hashes the output result. Used internally. + * - ``JoinSideMarker`` + - + - Used internally. + * - ``LiteralValues`` + - CPU + - Creates a virtual relation (table), when :ref:`values` is used + * - ``LocateFiles`` + - CPU + - Validates external file paths for foreign data wrappers, expanding directories and GLOB patterns + * - ``LoopJoin`` + - GPU + - A non-indexed nested loop join, performed on the GPU + * - ``MarkMatchedJoinRows`` + - + - Used in outer joins, matches rows for larger join operations + * - ``NullifyDuplicates`` + - + - Replaces duplicate values with ``NULL`` to calculate distinct aggregates + * - ``NullSink`` + - CPU + - Used internally + * - ``ParseCsv`` + - CPU + - A CSV parser, used after ``ReadFiles`` to convert the CSV into columnar data + * - ``PopNetworkQueue`` + - CPU + - Fetches data from the network queue (e.g. when used with :ref:`insert`) + * - ``PushToNetworkQueue`` + - CPU + - Sends result sets to a client connected over the network + * - ``ReadCatalog`` + - CPU + - Converts the :ref:`catalog` into a relation (table) + * - ``ReadFiles`` + - CPU + - Reads external flat-files + * - ``ReadOrc`` + - CPU + - Reads data from an ORC file + * - ``ReadParquet`` + - CPU + - Reads data from a Parquet file + * - ``ReadTable`` + - CPU + - Reads data from a standard table stored on disk + * - ``ReadTableMetadata`` + - CPU + - Reads only table metadata as an optimization + * - ``Rechunk`` + - + - Reorganize multiple small :ref:`chunks` into a full chunk. Commonly found after joins and when :ref:`HIGH_SELECTIVITY` is used + * - ``Reduce`` + - GPU + - A reduction operation, such as a ``GROUP BY`` + * - ``ReduceMerge`` + - GPU + - A merge operation of a reduction operation, helps operate on larger-than-RAM data + * - ``ReorderInput`` + - + - Change the order of arguments in preparation for the next operation + * - ``SeparatedGather`` + - GPU + - Gathers additional columns for the result + * - ``Sort`` + - GPU + - Sort operation [#f1]_ + * - ``SortMerge`` + - CPU + - A merge operation of a sort operation, helps operate on larger-than-RAM data + * - ``SortMergeJoin`` + - GPU + - A sort-merge join, performed on the GPU + * - ``TakeRowsFromChunk`` + - + - Take the first N rows from each chunk, to optimize ``LIMIT`` when used alongside ``ORDER BY`` + * - ``Top`` + - + - Limits the input size, when used with ``LIMIT`` (or its alias ``TOP``) + * - ``UdfTransform`` + - CPU + - Executes a :ref:`user defined function` + * - ``UnionAll`` + - + - Combines two sources of data when ``UNION ALL`` is used + * - ``VarCharJoiner`` + - + - Used internally + * - ``VarCharSplitter`` + - + - Used intenrally + * - ``Window`` + - GPU + - Executes a non-ranking :ref:`window function` + * - ``WindowRanking`` + - GPU + - Executes a ranking :ref:`window function` + * - ``WriteTable`` + - CPU + - Writes the result set to a standard table stored on disk + +.. rubric:: Footnotes + +.. [#f0] Gathers columns which should be returned. This node typically spends most of the time on decompressing additional columns. + +.. [#f1] A GPU sort operation can be added by the statement compiler before ``GROUP BY`` or ``JOIN`` operations. + +Statement statuses +======================= + +.. include:: /reference/sql/sql_statements/monitoring_commands/show_server_status.rst + :start-line: 67 + :end-line: 84 + +Notes +=========== + +* This utility shows the execution information for active statements. Once a query has finished execution, the information is no longer available using this utility. See :ref:`logging` for more information about extracting the information from the logs. + +* This utility is primarily intended for troubleshooting with SQream support. + +Examples +=========== + +Getting execution details for a statement +------------------------------------------------ + + +.. code-block:: psql + + t=> SELECT SHOW_SERVER_STATUS(); + service | instanceid | connection_id | serverip | serverport | database_name | user_name | clientip | statementid | statement | statementstarttime | statementstatus | statementstatusstart + --------+------------+---------------+--------------+------------+---------------+-----------+--------------+-------------+-----------------------------------------------------------------+---------------------+-----------------+--------------------- + sqream | | 152 | 192.168.1.91 | 5000 | t | sqream | 192.168.1.91 | 176 | SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | 25-12-2019 23:53:13 | Executing | 25-12-2019 23:53:13 + sqream | | 151 | 192.168.1.91 | 5000 | t | sqream | 192.168.0.1 | 177 | SELECT show_server_status() | 25-12-2019 23:51:31 | Executing | 25-12-2019 23:53:13 + + +The statement ID we want to reserach is ``176``, running on worker ``192.168.1.91``. + +The query text is ``SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1;`` + +.. code-block:: psql + + t=> SELECT SHOW_NODE_INFO(176); + stmt_id | node_id | node_type | rows | chunks | avg_rows_in_chunk | time | parent_node_id | read | write | comment | timeSum + --------+---------+--------------------+------+--------+-------------------+---------------------+----------------+------+-------+------------+-------- + 176 | 1 | PushToNetworkQueue | 1 | 1 | 1 | 2019-12-25 23:53:13 | -1 | | | | 0.0025 + 176 | 2 | Rechunk | 1 | 1 | 1 | 2019-12-25 23:53:13 | 1 | | | | 0 + 176 | 3 | GpuToCpu | 1 | 1 | 1 | 2019-12-25 23:53:13 | 2 | | | | 0 + 176 | 4 | ReorderInput | 1 | 1 | 1 | 2019-12-25 23:53:13 | 3 | | | | 0 + 176 | 5 | Filter | 1 | 1 | 1 | 2019-12-25 23:53:13 | 4 | | | | 0.0002 + 176 | 6 | GpuTransform | 457 | 1 | 457 | 2019-12-25 23:53:13 | 5 | | | | 0.0002 + 176 | 7 | GpuDecompress | 457 | 1 | 457 | 2019-12-25 23:53:13 | 6 | | | | 0 + 176 | 8 | CpuToGpu | 457 | 1 | 457 | 2019-12-25 23:53:13 | 7 | | | | 0.0003 + 176 | 9 | Rechunk | 457 | 1 | 457 | 2019-12-25 23:53:13 | 8 | | | | 0 + 176 | 10 | CpuDecompress | 457 | 1 | 457 | 2019-12-25 23:53:13 | 9 | | | | 0 + 176 | 11 | ReadTable | 457 | 1 | 457 | 2019-12-25 23:53:13 | 10 | 4MB | | public.nba | 0.0004 + diff --git a/reference/sql/sql_statements/utility_commands/show_server_status.rst b/reference/sql/sql_statements/utility_commands/show_server_status.rst new file mode 100644 index 000000000..f59f79ccc --- /dev/null +++ b/reference/sql/sql_statements/utility_commands/show_server_status.rst @@ -0,0 +1,108 @@ +.. _show_server_status: + +******************** +SHOW_SERVER_STATUS +******************** + +``SHOW_SERVER_STATUS`` returns a list of active sessions across the cluster. + +To list active statements on the current worker only, see :ref:`show_connections`. + +Permissions +============= + +The role must have the ``SUPERUSER`` permissions. + +Syntax +========== + +.. code-block:: postgres + + show_server_status_statement ::= + SELECT SHOW_SERVER_STATUS() + ; + +Parameters +============ + +None + +Returns +========= + +This function returns a list of active sessions. If no sessions are active across the cluster, the result set will be empty. + +.. list-table:: Result columns + :widths: auto + :header-rows: 1 + + * - ``service`` + - The service name for the statement + * - ``instance`` + - The worker ID + * - ``connection_id`` + - Connection ID + * - ``serverip`` + - Worker end-point IP + * - ``serverport`` + - Worker end-point port + * - ``database_name`` + - Database name for the statement + * - ``user_name`` + - Username running the statement + * - ``clientip`` + - Client IP + * - ``statementid`` + - Statement ID + * - ``statement`` + - Statement text + * - ``statementstarttime`` + - Statement start timestamp + * - ``statementstatus`` + - Statement status (see table below) + * - ``statementstatusstart`` + - Last updated timestamp + +.. include from here: 66 + + +.. list-table:: Statement status values + :widths: auto + :header-rows: 1 + + * - Status + - Description + * - ``Preparing`` + - Statement is being prepared + * - ``In queue`` + - Statement is waiting for execution + * - ``Initializing`` + - Statement has entered execution checks + * - ``Executing`` + - Statement is executing + * - ``Stopping`` + - Statement is in the process of stopping + + +.. include until here 86 + +Notes +=========== + +* This utility shows the active sessions. Some sessions may be actively connected, but not running any statements. + +Examples +=========== + +Using ``SHOW_SERVER_STATUS`` to get statement IDs +---------------------------------------------------- + + +.. code-block:: psql + + t=> SELECT SHOW_SERVER_STATUS(); + service | instanceid | connection_id | serverip | serverport | database_name | user_name | clientip | statementid | statement | statementstarttime | statementstatus | statementstatusstart + --------+------------+---------------+--------------+------------+---------------+------------+-------------+-------------+-----------------------------+---------------------+-----------------+--------------------- + sqream | | 102 | 192.168.1.91 | 5000 | t | rhendricks | 192.168.0.1 | 128 | SELECT SHOW_SERVER_STATUS() | 24-12-2019 00:14:53 | Executing | 24-12-2019 00:14:53 + +The statement ID is ``128``, running on worker ``192.168.1.91``. diff --git a/reference/sql/sql_statements/utility_commands/show_version.rst b/reference/sql/sql_statements/utility_commands/show_version.rst new file mode 100644 index 000000000..8c3e7565e --- /dev/null +++ b/reference/sql/sql_statements/utility_commands/show_version.rst @@ -0,0 +1,46 @@ +.. _show_version: + +***************** +SHOW_VERSION +***************** + +``SHOW_VERSION()`` is a function that returns the system version for SQream DB. + +Permissions +============= + +No special permissions are required. + +Syntax +========== + +.. code-block:: postgres + + show_version_statement ::= + SELECT SHOW_VERSION() + ; + +Parameters +============ + +None + +Notes +========== + +To check the SQream DB version from the shell, run ``$ sqreamd --version`` + +Examples +=========== + +Getting the current SQream DB version +--------------------------------------- + + +.. code-block:: psql + + t=> SELECT SHOW_VERSION(); + bytesread + --------- + v2019.3 + diff --git a/reference/sql/sql_statements/utility_commands/stop_statement.rst b/reference/sql/sql_statements/utility_commands/stop_statement.rst new file mode 100644 index 000000000..30efc25b5 --- /dev/null +++ b/reference/sql/sql_statements/utility_commands/stop_statement.rst @@ -0,0 +1,77 @@ +.. _stop_statement: + +******************** +STOP_STATEMENT +******************** + +``STOP_STATEMENT`` stops or aborts an active statement. + +To find a statement by ID, see :ref:`show_server_status` and :ref:`show_connections`. + +.. tip:: Some DBMSs call this process killing a session, terminating a job, or kill query + +Permissions +============= + +The role must have the ``SUPERUSER`` permissions. + +Syntax +========== + +.. code-block:: postgres + + stop_statement_statement ::= + SELECT STOP_STATEMENT(stmt_id) + ; + + stmt_id ::= bigint + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``stmt_id`` + - The statement ID to stop + +Returns +========= + +This utility does not return any value, and always succeeds even if the statement does not exist, or has already stopped. + + +Notes +=========== + +* This utility always succeeds even if the statement does not exist, or has already stopped. + +Examples +=========== + +Using :ref:`show_connections` to get statement IDs +---------------------------------------------------- + +.. tip:: Use :ref:`show_server_status` to find statments from across the entire cluster, or :ref:`show_connections` to show statements from the current worker the client is connected to. + +.. code-block:: psql + + t=> SELECT SHOW_CONNECTIONS(); + ip | conn_id | conn_start_time | stmt_id | stmt_start_time | stmt + -------------+---------+---------------------+---------+---------------------+-------------------------- + 192.168.1.91 | 103 | 2019-12-24 00:01:27 | 129 | 2019-12-24 00:38:18 | SELECT GET_DATE(), * F... + 192.168.1.91 | 23 | 2019-12-24 00:01:27 | -1 | 2019-12-24 00:01:27 | + 192.168.1.91 | 22 | 2019-12-24 00:01:27 | -1 | 2019-12-24 00:01:27 | + 192.168.1.91 | 26 | 2019-12-24 00:01:28 | -1 | 2019-12-24 00:01:28 | + + +The statement ID we're interested in is ``129``. We can now stop this statement: + +.. code-block:: psql + + t=> SELECT STOP_STATEMENT(129) + executed + From 784aaf0099a629ffe684863c51fe63a6f78ae479 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 24 Apr 2022 13:22:18 +0300 Subject: [PATCH 050/316] Moved System Functions to SQL Statements > Utility Commands Deleted System Functions section from SQL functions. Deleted System Functions folder (all system functions moved to SQL Syntax > Utility Commands)> --- reference/sql/sql_functions/index.rst | 3 +- .../system_functions/explain.rst | 59 ---- .../sql_functions/system_functions/index.rst | 19 -- .../system_functions/show_connections.rst | 78 ----- .../system_functions/show_locks.rst | 79 ----- .../system_functions/show_node_info.rst | 310 ------------------ .../system_functions/show_server_status.rst | 108 ------ .../system_functions/show_version.rst | 46 --- .../system_functions/stop_statement.rst | 77 ----- 9 files changed, 2 insertions(+), 777 deletions(-) delete mode 100644 reference/sql/sql_functions/system_functions/explain.rst delete mode 100644 reference/sql/sql_functions/system_functions/index.rst delete mode 100644 reference/sql/sql_functions/system_functions/show_connections.rst delete mode 100644 reference/sql/sql_functions/system_functions/show_locks.rst delete mode 100644 reference/sql/sql_functions/system_functions/show_node_info.rst delete mode 100644 reference/sql/sql_functions/system_functions/show_server_status.rst delete mode 100644 reference/sql/sql_functions/system_functions/show_version.rst delete mode 100644 reference/sql/sql_functions/system_functions/stop_statement.rst diff --git a/reference/sql/sql_functions/index.rst b/reference/sql/sql_functions/index.rst index 5ef0a7c5f..51d969f40 100644 --- a/reference/sql/sql_functions/index.rst +++ b/reference/sql/sql_functions/index.rst @@ -364,6 +364,7 @@ For more information about window functions, see :ref:`window_functions`. + Workload Management Functions --------------------------------- The following table shows the **workload management** functions: @@ -391,4 +392,4 @@ The following table shows the **workload management** functions: scalar_functions/index user_defined_functions/index aggregate_functions/index - window_functions/index + window_functions/index \ No newline at end of file diff --git a/reference/sql/sql_functions/system_functions/explain.rst b/reference/sql/sql_functions/system_functions/explain.rst deleted file mode 100644 index e9b7e7ee9..000000000 --- a/reference/sql/sql_functions/system_functions/explain.rst +++ /dev/null @@ -1,59 +0,0 @@ -.. _explain: - -***************** -EXPLAIN -***************** - -``EXPLAIN`` returns a static query plan, which can be used to debug query plans. - -To see an actively running query or statement, use :ref:`show_node_info` instead. - -See also :ref:`show_node_info`, :ref:`show_server_status`. - - -Permissions -============= - -The role must have the ``SELECT`` permissions for any tables referenced by the query. - -Syntax -========== - -.. code-block:: postgres - - explain_statement ::= - SELECT EXPLAIN(query_stmt) - ; - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``query_stmt`` - - The select query to generate the plan for. - -Notes -=========== - -Use dollar-quoting to escape the query text - -Examples -=========== - -Generating a static query plan ----------------------------------- - -.. code-block:: psql - - t=> SELECT EXPLAIN($$SELECT DATEADD(hour,1,dt) FROM cool_dates$$); - Select - Specific (TTNative Gpu) (dateadd@null := dt@null, - dateadd@val := (pure_if dt@null "0" (addHoursdt2dt dt@val "1"))) - Table Scan - public.cool_dates ("dt@null", "dt@val") [] - diff --git a/reference/sql/sql_functions/system_functions/index.rst b/reference/sql/sql_functions/system_functions/index.rst deleted file mode 100644 index ba99610ba..000000000 --- a/reference/sql/sql_functions/system_functions/index.rst +++ /dev/null @@ -1,19 +0,0 @@ -.. _system_functions_functions: - -******************** -System Functions -******************** -**System functions** are used for returning system information, such as version and node information, and for maintenance operations that are not regularly accessed from any interface. - -The System Functions page describes the following: - -.. hlist:: - :columns: 1 - - * :ref:`explain` - * :ref:`show_version` - * :ref:`show_connections` - * :ref:`show_locks` - * :ref:`show_node_info` - * :ref:`show_server_status` - * :ref:`stop_statement` \ No newline at end of file diff --git a/reference/sql/sql_functions/system_functions/show_connections.rst b/reference/sql/sql_functions/system_functions/show_connections.rst deleted file mode 100644 index 1bd320a4c..000000000 --- a/reference/sql/sql_functions/system_functions/show_connections.rst +++ /dev/null @@ -1,78 +0,0 @@ -.. _show_connections: - -******************** -SHOW_CONNECTIONS -******************** - -``SHOW_CONNECTIONS`` returns a list of active sessions on the current worker. - -To see sessions across the cluster, see :ref:`show_server_status`. - -Permissions -============= - -The role must have the ``SUPERUSER`` permissions. - -Syntax -========== - -.. code-block:: postgres - - show_connections_statement ::= - SELECT SHOW_CONNECTIONS() - ; - -Parameters -============ - -None - -Returns -========= - -This function returns a list of active sessions. If no sessions are active on the worker, the result set will be empty. - -.. list-table:: Result columns - :widths: auto - :header-rows: 1 - - * - ``ip`` - - The worker hostname or IP - * - ``conn_id`` - - Connection ID - * - ``conn_start_time`` - - Connection start timestamp - * - ``stmt_id`` - - Statement ID. Connections with no active statement display ``-1``. - * - ``stmt_start_time`` - - Statement start timestamp - * - ``stmt`` - - Statement text - - -Notes -=========== - -* This utility shows the active connections. Some sessions may be actively connected, but not currently running a statement. - -* A connection is typically reused. There could be many statements under a single connection ID. - -Examples -=========== - -Using ``SHOW_CONNECTIONS`` to get statement IDs ----------------------------------------------------- - - -.. code-block:: psql - - t=> SELECT SHOW_CONNECTIONS(); - ip | conn_id | conn_start_time | stmt_id | stmt_start_time | stmt - -------------+---------+---------------------+---------+---------------------+-------------------------- - 192.168.1.91 | 103 | 2019-12-24 00:01:27 | 129 | 2019-12-24 00:38:18 | SELECT GET_DATE(), * F... - 192.168.1.91 | 23 | 2019-12-24 00:01:27 | -1 | 2019-12-24 00:01:27 | - 192.168.1.91 | 22 | 2019-12-24 00:01:27 | -1 | 2019-12-24 00:01:27 | - 192.168.1.91 | 26 | 2019-12-24 00:01:28 | -1 | 2019-12-24 00:01:28 | - - -The statement ID we're interested in is ``129``. We can see the connection started at 00:01:27, while the statement started at 00:38:18. \ No newline at end of file diff --git a/reference/sql/sql_functions/system_functions/show_locks.rst b/reference/sql/sql_functions/system_functions/show_locks.rst deleted file mode 100644 index d5e7c02ec..000000000 --- a/reference/sql/sql_functions/system_functions/show_locks.rst +++ /dev/null @@ -1,79 +0,0 @@ -.. _show_locks: - -******************** -SHOW_LOCKS -******************** - -``SHOW_LOCKS`` returns a list of locks from across the cluster. - -Read more about locks in :ref:`concurrency_and_locks`. - -Permissions -============= - -The role must have the ``SUPERUSER`` permissions. - -Syntax -========== - -.. code-block:: postgres - - show_locks_statement ::= - SELECT SHOW_LOCKS() - ; - -Parameters -============ - -None - -Returns -========= - -This function returns a list of active locks. If no locks are active in the cluster, the result set will be empty. - -.. list-table:: Result columns - :widths: auto - :header-rows: 1 - - * - ``stmt_id`` - - Statement ID that caused the lock. - * - ``stmt_string`` - - Statement text - * - ``username`` - - The role that executed the statement - * - ``server`` - - The worker node's IP - * - ``port`` - - The worker node's port - * - ``locked_object`` - - The full qualified name of the object being locked, separated with ``$`` (e.g. ``table$t$public$nba2`` for table ``nba2`` in schema ``public``, in database ``t`` - * - ``lockmode`` - - The locking mode (:ref:`inclusive` or :ref:`exclusive`). - * - ``statement_start_time`` - - Timestamp the statement started - * - ``lock_start_time`` - - Timestamp the lock was obtained - - -Examples -=========== - -Using ``SHOW_LOCKS`` to see active locks ---------------------------------------------------- - -In this example, we create a table based on results (:ref:`create_table_as`), but we are also effectively dropping the previous table (by using ``OR REPLACE``). Thus, SQream DB applies locks during the table creation process to prevent the table from being altered during it's creation. - - -.. code-block:: psql - - t=> SELECT SHOW_LOCKS(); - statement_id | statement_string | username | server | port | locked_object | lockmode | statement_start_time | lock_start_time - -------------+-------------------------------------------------------------------------------------------------+----------+--------------+------+---------------------------------+-----------+----------------------+-------------------- - 287 | CREATE OR REPLACE TABLE nba2 AS SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | sqream | 192.168.1.91 | 5000 | database$t | Inclusive | 2019-12-26 00:03:30 | 2019-12-26 00:03:30 - 287 | CREATE OR REPLACE TABLE nba2 AS SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | sqream | 192.168.1.91 | 5000 | globalpermission$ | Exclusive | 2019-12-26 00:03:30 | 2019-12-26 00:03:30 - 287 | CREATE OR REPLACE TABLE nba2 AS SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | sqream | 192.168.1.91 | 5000 | schema$t$public | Inclusive | 2019-12-26 00:03:30 | 2019-12-26 00:03:30 - 287 | CREATE OR REPLACE TABLE nba2 AS SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | sqream | 192.168.1.91 | 5000 | table$t$public$nba2$Insert | Exclusive | 2019-12-26 00:03:30 | 2019-12-26 00:03:30 - 287 | CREATE OR REPLACE TABLE nba2 AS SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | sqream | 192.168.1.91 | 5000 | table$t$public$nba2$Update | Exclusive | 2019-12-26 00:03:30 | 2019-12-26 00:03:30 - - diff --git a/reference/sql/sql_functions/system_functions/show_node_info.rst b/reference/sql/sql_functions/system_functions/show_node_info.rst deleted file mode 100644 index 345d16440..000000000 --- a/reference/sql/sql_functions/system_functions/show_node_info.rst +++ /dev/null @@ -1,310 +0,0 @@ -.. _show_node_info: - -******************** -SHOW_NODE_INFO -******************** - -``SHOW_NODE_INFO`` returns a snapshot of the current query plan, similar to ``EXPLAIN ANALYZE`` from other databases. - -The snapshot provides information about execution which can be used for monitoring and troubleshooting slow running statements by helping identify long-running execution nodes (components that process data), etc. - -See also :ref:`explain`, :ref:`show_server_status`. - -Permissions -============= - -The role must have the ``SUPERUSER`` permissions. - -Syntax -========== - -.. code-block:: postgres - - show_node_info_statement ::= - SELECT SHOW_NODE_INFO(stmt_id) - ; - - stmt_id ::= bigint - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``stmt_id`` - - The statement ID to explore - -Returns -========= - -This utility returns details of the execution nodes, if the statement is still running. - -If the statement has finished, or the statment ID does not exist, the utility returns an empty result set. - -.. list-table:: Result columns - :widths: auto - :header-rows: 1 - - * - Column name - - Description - * - ``stmt_id`` - - The ID for the statement - * - ``node_id`` - - This node's ID in this execution plan - * - ``node_type`` - - The node type - * - ``rows`` - - Total number of rows this node has processed - * - ``chunks`` - - Number of chunks this node has processed - * - ``avg_rows_in_chunk`` - - Average amount of rows that this node processes in each chunk (``rows / chunks``) - * - ``time`` - - Timestamp for this node's creation - * - ``parent_node_id`` - - The ``node_id`` of this node's parent - * - ``read`` - - Total data read from disk - * - ``write`` - - Total data written to disk - * - ``comment`` - - Additional information (e.g. table name for ``ReadTable``) - * - ``timesum`` - - Total elapsed time for this execution node's processing - - -.. _node_types: - -Node types -============= - -This is a full list of node types: - -.. list-table:: Node types - :widths: auto - :header-rows: 1 - - * - Column name - - Execution location - - Description - * - ``AddChunkId`` - - - - Used during insert operations - * - ``AddSequences`` - - - - Used during insert operations, with :ref:`identity columns` - * - ``AddMinMaxMetadata`` - - - - Used to calculate ranges for the :ref:`chunk metadata system` - * - ``AddTopSortFilters`` - - - - An operation to optimize ``LIMIT`` when used alongside ``ORDER BY`` - * - ``Compress`` - - CPU and GPU - - Compress data with both CPU and GPU schemes - * - ``CpuDecompress`` - - CPU - - Decompression operation, common for longer ``VARCHAR`` types - * - ``CpuLoopJoin`` - - CPU - - A non-indexed nested loop join, performed on the CPU - * - ``CpuReduce`` - - CPU - - A reduce process performed on the CPU, primarily with ``DISTINCT`` aggregates (e.g. ``COUNT(DISTINCT ...)``) - * - ``CpuToGpu``, ``GpuToCpu`` - - - - An operation that moves data to or from the GPU for processing - * - ``CpuTransform`` - - CPU - - A transform operation performed on the CPU, usually a :ref:`scalar function` - * - ``CrossJoin`` - - - - A join without a join condition - * - ``DeferredGather`` - - CPU - - Merges the results of GPU operations with a result set [#f0]_ - * - ``Distinct`` - - GPU - - Removes duplicate rows (usually as part of the ``DISTINCT`` operation) - * - ``Distinct_Merge`` - - CPU - - The merge operation of the ``Distinct`` operation - * - ``Filter`` - - GPU - - A filtering operation, such as a ``WHERE`` or ``JOIN`` clause - * - ``GpuCopy`` - - GPU - - Copies data between GPUs or within a single GPU - * - ``GpuDecompress`` - - GPU - - Decompression operation - * - ``GpuReduceMerge`` - - GPU - - An operation to optimize part of the merger phases in the GPU - * - ``GpuTransform`` - - GPU - - A transformation operation such as a type cast or :ref:`scalar function` - * - ``Hash`` - - CPU - - Hashes the output result. Used internally. - * - ``JoinSideMarker`` - - - - Used internally. - * - ``LiteralValues`` - - CPU - - Creates a virtual relation (table), when :ref:`values` is used - * - ``LocateFiles`` - - CPU - - Validates external file paths for foreign data wrappers, expanding directories and GLOB patterns - * - ``LoopJoin`` - - GPU - - A non-indexed nested loop join, performed on the GPU - * - ``MarkMatchedJoinRows`` - - - - Used in outer joins, matches rows for larger join operations - * - ``NullifyDuplicates`` - - - - Replaces duplicate values with ``NULL`` to calculate distinct aggregates - * - ``NullSink`` - - CPU - - Used internally - * - ``ParseCsv`` - - CPU - - A CSV parser, used after ``ReadFiles`` to convert the CSV into columnar data - * - ``PopNetworkQueue`` - - CPU - - Fetches data from the network queue (e.g. when used with :ref:`insert`) - * - ``PushToNetworkQueue`` - - CPU - - Sends result sets to a client connected over the network - * - ``ReadCatalog`` - - CPU - - Converts the :ref:`catalog` into a relation (table) - * - ``ReadFiles`` - - CPU - - Reads external flat-files - * - ``ReadOrc`` - - CPU - - Reads data from an ORC file - * - ``ReadParquet`` - - CPU - - Reads data from a Parquet file - * - ``ReadTable`` - - CPU - - Reads data from a standard table stored on disk - * - ``ReadTableMetadata`` - - CPU - - Reads only table metadata as an optimization - * - ``Rechunk`` - - - - Reorganize multiple small :ref:`chunks` into a full chunk. Commonly found after joins and when :ref:`HIGH_SELECTIVITY` is used - * - ``Reduce`` - - GPU - - A reduction operation, such as a ``GROUP BY`` - * - ``ReduceMerge`` - - GPU - - A merge operation of a reduction operation, helps operate on larger-than-RAM data - * - ``ReorderInput`` - - - - Change the order of arguments in preparation for the next operation - * - ``SeparatedGather`` - - GPU - - Gathers additional columns for the result - * - ``Sort`` - - GPU - - Sort operation [#f1]_ - * - ``SortMerge`` - - CPU - - A merge operation of a sort operation, helps operate on larger-than-RAM data - * - ``SortMergeJoin`` - - GPU - - A sort-merge join, performed on the GPU - * - ``TakeRowsFromChunk`` - - - - Take the first N rows from each chunk, to optimize ``LIMIT`` when used alongside ``ORDER BY`` - * - ``Top`` - - - - Limits the input size, when used with ``LIMIT`` (or its alias ``TOP``) - * - ``UdfTransform`` - - CPU - - Executes a :ref:`user defined function` - * - ``UnionAll`` - - - - Combines two sources of data when ``UNION ALL`` is used - * - ``VarCharJoiner`` - - - - Used internally - * - ``VarCharSplitter`` - - - - Used intenrally - * - ``Window`` - - GPU - - Executes a non-ranking :ref:`window function` - * - ``WindowRanking`` - - GPU - - Executes a ranking :ref:`window function` - * - ``WriteTable`` - - CPU - - Writes the result set to a standard table stored on disk - -.. rubric:: Footnotes - -.. [#f0] Gathers columns which should be returned. This node typically spends most of the time on decompressing additional columns. - -.. [#f1] A GPU sort operation can be added by the statement compiler before ``GROUP BY`` or ``JOIN`` operations. - -Statement statuses -======================= - -.. include:: /reference/sql/sql_statements/monitoring_commands/show_server_status.rst - :start-line: 67 - :end-line: 84 - -Notes -=========== - -* This utility shows the execution information for active statements. Once a query has finished execution, the information is no longer available using this utility. See :ref:`logging` for more information about extracting the information from the logs. - -* This utility is primarily intended for troubleshooting with SQream support. - -Examples -=========== - -Getting execution details for a statement ------------------------------------------------- - - -.. code-block:: psql - - t=> SELECT SHOW_SERVER_STATUS(); - service | instanceid | connection_id | serverip | serverport | database_name | user_name | clientip | statementid | statement | statementstarttime | statementstatus | statementstatusstart - --------+------------+---------------+--------------+------------+---------------+-----------+--------------+-------------+-----------------------------------------------------------------+---------------------+-----------------+--------------------- - sqream | | 152 | 192.168.1.91 | 5000 | t | sqream | 192.168.1.91 | 176 | SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | 25-12-2019 23:53:13 | Executing | 25-12-2019 23:53:13 - sqream | | 151 | 192.168.1.91 | 5000 | t | sqream | 192.168.0.1 | 177 | SELECT show_server_status() | 25-12-2019 23:51:31 | Executing | 25-12-2019 23:53:13 - - -The statement ID we want to reserach is ``176``, running on worker ``192.168.1.91``. - -The query text is ``SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1;`` - -.. code-block:: psql - - t=> SELECT SHOW_NODE_INFO(176); - stmt_id | node_id | node_type | rows | chunks | avg_rows_in_chunk | time | parent_node_id | read | write | comment | timeSum - --------+---------+--------------------+------+--------+-------------------+---------------------+----------------+------+-------+------------+-------- - 176 | 1 | PushToNetworkQueue | 1 | 1 | 1 | 2019-12-25 23:53:13 | -1 | | | | 0.0025 - 176 | 2 | Rechunk | 1 | 1 | 1 | 2019-12-25 23:53:13 | 1 | | | | 0 - 176 | 3 | GpuToCpu | 1 | 1 | 1 | 2019-12-25 23:53:13 | 2 | | | | 0 - 176 | 4 | ReorderInput | 1 | 1 | 1 | 2019-12-25 23:53:13 | 3 | | | | 0 - 176 | 5 | Filter | 1 | 1 | 1 | 2019-12-25 23:53:13 | 4 | | | | 0.0002 - 176 | 6 | GpuTransform | 457 | 1 | 457 | 2019-12-25 23:53:13 | 5 | | | | 0.0002 - 176 | 7 | GpuDecompress | 457 | 1 | 457 | 2019-12-25 23:53:13 | 6 | | | | 0 - 176 | 8 | CpuToGpu | 457 | 1 | 457 | 2019-12-25 23:53:13 | 7 | | | | 0.0003 - 176 | 9 | Rechunk | 457 | 1 | 457 | 2019-12-25 23:53:13 | 8 | | | | 0 - 176 | 10 | CpuDecompress | 457 | 1 | 457 | 2019-12-25 23:53:13 | 9 | | | | 0 - 176 | 11 | ReadTable | 457 | 1 | 457 | 2019-12-25 23:53:13 | 10 | 4MB | | public.nba | 0.0004 - diff --git a/reference/sql/sql_functions/system_functions/show_server_status.rst b/reference/sql/sql_functions/system_functions/show_server_status.rst deleted file mode 100644 index f59f79ccc..000000000 --- a/reference/sql/sql_functions/system_functions/show_server_status.rst +++ /dev/null @@ -1,108 +0,0 @@ -.. _show_server_status: - -******************** -SHOW_SERVER_STATUS -******************** - -``SHOW_SERVER_STATUS`` returns a list of active sessions across the cluster. - -To list active statements on the current worker only, see :ref:`show_connections`. - -Permissions -============= - -The role must have the ``SUPERUSER`` permissions. - -Syntax -========== - -.. code-block:: postgres - - show_server_status_statement ::= - SELECT SHOW_SERVER_STATUS() - ; - -Parameters -============ - -None - -Returns -========= - -This function returns a list of active sessions. If no sessions are active across the cluster, the result set will be empty. - -.. list-table:: Result columns - :widths: auto - :header-rows: 1 - - * - ``service`` - - The service name for the statement - * - ``instance`` - - The worker ID - * - ``connection_id`` - - Connection ID - * - ``serverip`` - - Worker end-point IP - * - ``serverport`` - - Worker end-point port - * - ``database_name`` - - Database name for the statement - * - ``user_name`` - - Username running the statement - * - ``clientip`` - - Client IP - * - ``statementid`` - - Statement ID - * - ``statement`` - - Statement text - * - ``statementstarttime`` - - Statement start timestamp - * - ``statementstatus`` - - Statement status (see table below) - * - ``statementstatusstart`` - - Last updated timestamp - -.. include from here: 66 - - -.. list-table:: Statement status values - :widths: auto - :header-rows: 1 - - * - Status - - Description - * - ``Preparing`` - - Statement is being prepared - * - ``In queue`` - - Statement is waiting for execution - * - ``Initializing`` - - Statement has entered execution checks - * - ``Executing`` - - Statement is executing - * - ``Stopping`` - - Statement is in the process of stopping - - -.. include until here 86 - -Notes -=========== - -* This utility shows the active sessions. Some sessions may be actively connected, but not running any statements. - -Examples -=========== - -Using ``SHOW_SERVER_STATUS`` to get statement IDs ----------------------------------------------------- - - -.. code-block:: psql - - t=> SELECT SHOW_SERVER_STATUS(); - service | instanceid | connection_id | serverip | serverport | database_name | user_name | clientip | statementid | statement | statementstarttime | statementstatus | statementstatusstart - --------+------------+---------------+--------------+------------+---------------+------------+-------------+-------------+-----------------------------+---------------------+-----------------+--------------------- - sqream | | 102 | 192.168.1.91 | 5000 | t | rhendricks | 192.168.0.1 | 128 | SELECT SHOW_SERVER_STATUS() | 24-12-2019 00:14:53 | Executing | 24-12-2019 00:14:53 - -The statement ID is ``128``, running on worker ``192.168.1.91``. diff --git a/reference/sql/sql_functions/system_functions/show_version.rst b/reference/sql/sql_functions/system_functions/show_version.rst deleted file mode 100644 index 8c3e7565e..000000000 --- a/reference/sql/sql_functions/system_functions/show_version.rst +++ /dev/null @@ -1,46 +0,0 @@ -.. _show_version: - -***************** -SHOW_VERSION -***************** - -``SHOW_VERSION()`` is a function that returns the system version for SQream DB. - -Permissions -============= - -No special permissions are required. - -Syntax -========== - -.. code-block:: postgres - - show_version_statement ::= - SELECT SHOW_VERSION() - ; - -Parameters -============ - -None - -Notes -========== - -To check the SQream DB version from the shell, run ``$ sqreamd --version`` - -Examples -=========== - -Getting the current SQream DB version ---------------------------------------- - - -.. code-block:: psql - - t=> SELECT SHOW_VERSION(); - bytesread - --------- - v2019.3 - diff --git a/reference/sql/sql_functions/system_functions/stop_statement.rst b/reference/sql/sql_functions/system_functions/stop_statement.rst deleted file mode 100644 index 30efc25b5..000000000 --- a/reference/sql/sql_functions/system_functions/stop_statement.rst +++ /dev/null @@ -1,77 +0,0 @@ -.. _stop_statement: - -******************** -STOP_STATEMENT -******************** - -``STOP_STATEMENT`` stops or aborts an active statement. - -To find a statement by ID, see :ref:`show_server_status` and :ref:`show_connections`. - -.. tip:: Some DBMSs call this process killing a session, terminating a job, or kill query - -Permissions -============= - -The role must have the ``SUPERUSER`` permissions. - -Syntax -========== - -.. code-block:: postgres - - stop_statement_statement ::= - SELECT STOP_STATEMENT(stmt_id) - ; - - stmt_id ::= bigint - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``stmt_id`` - - The statement ID to stop - -Returns -========= - -This utility does not return any value, and always succeeds even if the statement does not exist, or has already stopped. - - -Notes -=========== - -* This utility always succeeds even if the statement does not exist, or has already stopped. - -Examples -=========== - -Using :ref:`show_connections` to get statement IDs ----------------------------------------------------- - -.. tip:: Use :ref:`show_server_status` to find statments from across the entire cluster, or :ref:`show_connections` to show statements from the current worker the client is connected to. - -.. code-block:: psql - - t=> SELECT SHOW_CONNECTIONS(); - ip | conn_id | conn_start_time | stmt_id | stmt_start_time | stmt - -------------+---------+---------------------+---------+---------------------+-------------------------- - 192.168.1.91 | 103 | 2019-12-24 00:01:27 | 129 | 2019-12-24 00:38:18 | SELECT GET_DATE(), * F... - 192.168.1.91 | 23 | 2019-12-24 00:01:27 | -1 | 2019-12-24 00:01:27 | - 192.168.1.91 | 22 | 2019-12-24 00:01:27 | -1 | 2019-12-24 00:01:27 | - 192.168.1.91 | 26 | 2019-12-24 00:01:28 | -1 | 2019-12-24 00:01:28 | - - -The statement ID we're interested in is ``129``. We can now stop this statement: - -.. code-block:: psql - - t=> SELECT STOP_STATEMENT(129) - executed - From 5f125bc08e51aec194d0482ea0277823adbf99d0 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Wed, 27 Apr 2022 10:08:16 +0300 Subject: [PATCH 051/316] Update index.rst Improved page structure. --- reference/sql/sql_functions/index.rst | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/reference/sql/sql_functions/index.rst b/reference/sql/sql_functions/index.rst index 51d969f40..a66760b7f 100644 --- a/reference/sql/sql_functions/index.rst +++ b/reference/sql/sql_functions/index.rst @@ -117,9 +117,7 @@ The following table shows the **date and time** functions: Numeric ^^^^^^^^^^^ -The following table shows the **arithmetic operators** - -For more information about arithmetic operator, see :ref:`arithmetic_operators`. +The following table shows the **arithmetic operators**: .. list-table:: Arithmetic Operators :widths: auto @@ -150,6 +148,8 @@ For more information about arithmetic operator, see :ref:`arithmetic_operators`. - ``a % b`` - Modulu of ``a`` by ``b``. See also :ref:`mod` +For more information about arithmetic operators, see :ref:`arithmetic_operators`. + The following table shows the **arithmetic operator** functions: .. list-table:: Arithemtic Operator Functions @@ -209,7 +209,7 @@ The following table shows the **arithmetic operator** functions: Strings ^^^^^^^^^^^ -The following table shows the **string* functions: +The following table shows the **string** functions: .. list-table:: :widths: auto @@ -270,15 +270,13 @@ The following table shows the **string* functions: User-Defined Scalar Functions --------------------- -For more information about user-defined scalar functions, see :ref:`scalar_sql_udf` +For more information about user-defined scalar functions, see :ref:`scalar_sql_udf`. Aggregate Functions --------------------- The following table shows the **aggregate** functions: -For more information about aggregate functions, see :ref:`aggregate_functions`. - .. list-table:: :widths: auto :header-rows: 1 @@ -323,12 +321,12 @@ For more information about aggregate functions, see :ref:`aggregate_functions`. - ``varp`` - Calculates population variance of values +For more information about aggregate functions, see :ref:`aggregate_functions`. + Window Functions ------------------- The following table shows the **window** functions: -For more information about window functions, see :ref:`window_functions`. - .. list-table:: :widths: auto :header-rows: 1 @@ -362,8 +360,7 @@ For more information about window functions, see :ref:`window_functions`. * - :ref:`ntile` - Returns an integer ranging between ``1`` and the argument value, dividing the partitions as equally as possible - - +For more information about window functions, see :ref:`window_functions`. Workload Management Functions --------------------------------- From 981085951fca474428c7b8a4b80090b706d249a0 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Apr 2022 17:48:10 +0300 Subject: [PATCH 052/316] Removed System Functions Moved System Functions to SQL Statements > Utilities, and removed System Functions --- reference/sql/sql_statements/index.rst | 5 + .../utility_commands/drop_saved_query.rst | 55 ++++++++ .../utility_commands/execute_saved_query.rst | 123 ++++++++++++++++++ .../utility_commands/list_saved_queries.rst | 77 +++++++++++ .../recompile_saved_query.rst | 88 +++++++++++++ .../utility_commands/show_saved_query.rst | 61 +++++++++ 6 files changed, 409 insertions(+) create mode 100644 reference/sql/sql_statements/utility_commands/drop_saved_query.rst create mode 100644 reference/sql/sql_statements/utility_commands/execute_saved_query.rst create mode 100644 reference/sql/sql_statements/utility_commands/list_saved_queries.rst create mode 100644 reference/sql/sql_statements/utility_commands/recompile_saved_query.rst create mode 100644 reference/sql/sql_statements/utility_commands/show_saved_query.rst diff --git a/reference/sql/sql_statements/index.rst b/reference/sql/sql_statements/index.rst index eab8d8f84..6845ae7cd 100644 --- a/reference/sql/sql_statements/index.rst +++ b/reference/sql/sql_statements/index.rst @@ -3,6 +3,11 @@ *************** SQL Statements *************** +The **SQL Statements** page describes the following commands: + +.. contents:: + :local: + :depth: 1 SQream DB supports commands from ANSI SQL. diff --git a/reference/sql/sql_statements/utility_commands/drop_saved_query.rst b/reference/sql/sql_statements/utility_commands/drop_saved_query.rst new file mode 100644 index 000000000..f7faef6c5 --- /dev/null +++ b/reference/sql/sql_statements/utility_commands/drop_saved_query.rst @@ -0,0 +1,55 @@ +.. _drop_saved_query: + +******************** +DROP_SAVED_QUERY +******************** + +``DROP_SAVED_QUERY`` drops a :ref:`previously saved query`. + +Read more in the :ref:`saved_queries` guide. + +See also: ref:`save_query`, :ref:`execute_saved_query`, ref:`show_saved_query`, ref:`list_saved_queries`. + +Permissions +============= + +Dropping a saved query requires no special permissions. + +Syntax +========== + +.. code-block:: postgres + + drop_saved_query_statement ::= + SELECT DROP_SAVED_QUERY(saved_query_name) + ; + + saved_query_name ::= string_literal + +Returns +========== + +If saved query is dropped successfully, returns nothing. + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``saved_query_name`` + - The name of the query to drop + +Examples +=========== + +Dropping a previously saved query +--------------------------------------- + +.. code-block:: psql + + t=> SELECT DROP_SAVED_QUERY('select_all'); + executed diff --git a/reference/sql/sql_statements/utility_commands/execute_saved_query.rst b/reference/sql/sql_statements/utility_commands/execute_saved_query.rst new file mode 100644 index 000000000..6fe41fa08 --- /dev/null +++ b/reference/sql/sql_statements/utility_commands/execute_saved_query.rst @@ -0,0 +1,123 @@ +.. _execute_saved_query: + +******************** +EXECUTE_SAVED_QUERY +******************** + +``EXECUTE_SAVED_QUERY`` executes a :ref:`previously saved query`. + +Read more in the :ref:`saved_queries` guide. + +See also: ref:`save_query`, :ref:`drop_saved_query`, ref:`show_saved_query`, ref:`list_saved_queries`. + +Permissions +============= + +Executing a saved query requires ``SELECT`` permissions to access the tables referenced in the query. + +Syntax +========== + +.. code-block:: postgres + + execute_saved_query_statement ::= + SELECT EXECUTE_SAVED_QUERY(saved_query_name, [ , argument [ , ... ] ] ) + ; + + saved_query_name ::= string_literal + + argument ::= string_literal | number_literal + +Returns +========== + +Query execution results, based on the query saved. + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``saved_query_name`` + - The name of the query to execute + * - ``argument`` + - A comma separated list of argument literal values + + +Notes +========= + +* Query parameters can be used as substitutes for literal expressions. Parameters cannot be used to substitute identifiers, column names, table names, or other parts of the query. + +* Query parameters of a string datatype (like ``VARCHAR``) must be of a fixed length, and can be used in equality checks, but not patterns (e.g. :ref:`like`, :ref:`rlike`, etc) + +* Query parameters' types are inferred at compile time. + +Examples +=========== + +Assume a table named ``nba``, with the following structure: + +.. code-block:: postgres + + CREATE TABLE nba + ( + Name varchar(40), + Team varchar(40), + Number tinyint, + Position varchar(2), + Age tinyint, + Height varchar(4), + Weight real, + College varchar(40), + Salary float + ); + + +Here's a peek at the table contents (:download:`Download nba.csv `): + +.. csv-table:: nba.csv + :file: nba-t10.csv + :widths: auto + :header-rows: 1 + + +Saving and executing a simple query +--------------------------------------- + +.. code-block:: psql + + t=> SELECT SAVE_QUERY('select_all','SELECT * FROM nba'); + executed + t=> SELECT EXECUTE_SAVED_QUERY('select_all'); + Name | Team | Number | Position | Age | Height | Weight | College | Salary + -------------------------+------------------------+--------+----------+-----+--------+--------+-----------------------+--------- + Avery Bradley | Boston Celtics | 0 | PG | 25 | 6-2 | 180 | Texas | 7730337 + Jae Crowder | Boston Celtics | 99 | SF | 25 | 6-6 | 235 | Marquette | 6796117 + John Holland | Boston Celtics | 30 | SG | 27 | 6-5 | 205 | Boston University | + R.J. Hunter | Boston Celtics | 28 | SG | 22 | 6-5 | 185 | Georgia State | 1148640 + [...] + +Saving and executing parametrized query +------------------------------------------ + +Use parameters to replace them later at execution time. + +.. tip:: Use dollar quoting (`$$`) to avoid escaping strings. + + .. code-block:: psql + + t=> SELECT SAVE_QUERY('select_by_weight_and_team',$$SELECT * FROM nba WHERE Weight > ? AND Team = ?$$); + executed + t=> SELECT EXECUTE_SAVED_QUERY('select_by_weight_and_team', 240, 'Toronto Raptors'); + Name | Team | Number | Position | Age | Height | Weight | College | Salary + ------------------+-----------------+--------+----------+-----+--------+--------+-------------+-------- + Bismack Biyombo | Toronto Raptors | 8 | C | 23 | 6-9 | 245 | | 2814000 + James Johnson | Toronto Raptors | 3 | PF | 29 | 6-9 | 250 | Wake Forest | 2500000 + Jason Thompson | Toronto Raptors | 1 | PF | 29 | 6-11 | 250 | Rider | 245177 + Jonas Valanciunas | Toronto Raptors | 17 | C | 24 | 7-0 | 255 | | 4660482 + diff --git a/reference/sql/sql_statements/utility_commands/list_saved_queries.rst b/reference/sql/sql_statements/utility_commands/list_saved_queries.rst new file mode 100644 index 000000000..bb1781840 --- /dev/null +++ b/reference/sql/sql_statements/utility_commands/list_saved_queries.rst @@ -0,0 +1,77 @@ +.. _list_saved_queries: + +******************** +LIST_SAVED_QUERIES +******************** + +``LIST_SAVED_QUERIES`` lists the available :ref:`previously saved queries`. + +This is an alternative way to using the ``savedqueries`` catalog view. + +Read more in the :ref:`saved_queries` guide. + +See also: ref:`save_query`, :ref:`execute_saved_query`, ref:`drop_saved_query`, ref:`show_saved_query`. + +Permissions +============= + +Listing the saved queries requires no special permissions. + +Syntax +========== + +.. code-block:: postgres + + list_saved_queries_statement ::= + SELECT LIST_SAVED_QUERIES() + ; + +Returns +========== + +List of saved query names, one per row. + +Parameters +============ + +None + +Notes +========= + +This statement returns an empty result set if no saved queries exist in the current database. + +Examples +=========== + +Listing previously saved queries +--------------------------------------- + +.. code-block:: psql + + t=> SELECT LIST_SAVED_QUERIES(); + saved_query + ------------------------- + select_all + select_by_weight + select_by_weight_and_team + + t=> SELECT SHOW_SAVED_QUERY('select_by_weight_and_team'); + saved_query + ----------------------------------------------- + SELECT * FROM nba WHERE Weight > ? AND Team = ? + + +Listing saved queries with the catalog +--------------------------------------------- + +Using the :ref:`catalog` is also possible: + +.. code-block:: psql + + t=> SELECT * FROM sqream_catalog.savedqueries; + name | num_parameters + --------------------------+--------------- + select_all | 0 + select_by_weight | 1 + select_by_weight_and_team | 2 diff --git a/reference/sql/sql_statements/utility_commands/recompile_saved_query.rst b/reference/sql/sql_statements/utility_commands/recompile_saved_query.rst new file mode 100644 index 000000000..d6b63e30e --- /dev/null +++ b/reference/sql/sql_statements/utility_commands/recompile_saved_query.rst @@ -0,0 +1,88 @@ +.. _recompile_saved_query: + +************************** +RECOMPILE_SAVED_QUERY +************************** + +``RECOMPILE_SAVED_QUERY`` recompiles a saved query that has been invalidated due to a schema change. + +Permissions +============= + +Recompiling a saved query requires no special permissions. + +Syntax +========== + +.. code-block:: postgres + + recompile_saved_query_statement ::= + SELECT RECOMPILE_SAVED_QUERY(saved_query_name) + ; + + saved_query_name ::= string_literal + +Returns +========== + +If saved query is recompiled successfully, returns nothing. + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``saved_query_name`` + - The name of the query to recompile + +Examples +=========== + +Recreating a query that has been invalidated +------------------------------------------------- + +.. code-block:: psql + + t=> SELECT SAVE_QUERY('select_by_weight_and_team',$$SELECT * FROM nba WHERE Weight > ? AND Team = ?$$); + executed + t=> SELECT EXECUTE_SAVED_QUERY('select_by_weight_and_team', 240, 'Toronto Raptors'); + Name | Team | Number | Position | Age | Height | Weight | College | Salary + ------------------+-----------------+--------+----------+-----+--------+--------+-------------+-------- + Bismack Biyombo | Toronto Raptors | 8 | C | 23 | 6-9 | 245 | | 2814000 + James Johnson | Toronto Raptors | 3 | PF | 29 | 6-9 | 250 | Wake Forest | 2500000 + Jason Thompson | Toronto Raptors | 1 | PF | 29 | 6-11 | 250 | Rider | 245177 + Jonas Valanciunas | Toronto Raptors | 17 | C | 24 | 7-0 | 255 | | 4660482 + + +To invalidate the original saved query, we will change the schema without affecting our original query text: + +.. code-block:: psql + + t=> ALTER TABLE nba RENAME COLUMN age to "Age (as of 2015)"; + executed + +However, because the query was compiled previously, this change invalidates the query and causes it to fail: + +.. code-block:: psql + + t=> SELECT EXECUTE_SAVED_QUERY('select_by_weight_and_team', 240, 'Toronto Raptors'); + Error: column not found {Age@null} + column not found {Age@null} + +Recompiling the query will fix this issue + +.. code-block:: psql + + t=> SELECT RECOMPILE_SAVED_QUERY('select_by_weight_and_team'); + executed + t=> SELECT EXECUTE_SAVED_QUERY('select_by_weight_and_team', 240, 'Toronto Raptors'); + Name | Team | Number | Position | Age (as of 2015) | Height | Weight | College | Salary + ------------------+-----------------+--------+----------+------------------+--------+--------+-------------+-------- + Bismack Biyombo | Toronto Raptors | 8 | C | 23 | 6-9 | 245 | | 2814000 + James Johnson | Toronto Raptors | 3 | PF | 29 | 6-9 | 250 | Wake Forest | 2500000 + Jason Thompson | Toronto Raptors | 1 | PF | 29 | 6-11 | 250 | Rider | 245177 + Jonas Valanciunas | Toronto Raptors | 17 | C | 24 | 7-0 | 255 | | 4660482 diff --git a/reference/sql/sql_statements/utility_commands/show_saved_query.rst b/reference/sql/sql_statements/utility_commands/show_saved_query.rst new file mode 100644 index 000000000..15ac4c1bd --- /dev/null +++ b/reference/sql/sql_statements/utility_commands/show_saved_query.rst @@ -0,0 +1,61 @@ +.. _show_saved_query: + +******************** +SHOW_SAVED_QUERY +******************** + +``SHOW_SAVED_QUERY`` shows the query text for a :ref:`previously saved query`. + +Read more in the :ref:`saved_queries` guide. + +See also: ref:`save_query`, :ref:`execute_saved_query`, ref:`drop_saved_query`, ref:`list_saved_queries`. + +Permissions +============= + +Showing a saved query requires no special permissions. + +Syntax +========== + +.. code-block:: postgres + + show_saved_query_statement ::= + SELECT SHOW_SAVED_QUERY(saved_query_name) + ; + + saved_query_name ::= string_literal + +Returns +========== + +A single row result containing the saved query string. + +Parameters +============ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``saved_query_name`` + - The name of the query to show + + +Examples +=========== + +Showing a previously saved query +--------------------------------------- + +.. code-block:: psql + + t=> SELECT SAVE_QUERY('select_by_weight_and_team',$$SELECT * FROM nba WHERE Weight > ? AND Team = ?$$); + executed + t=> SELECT SHOW_SAVED_QUERY('select_by_weight_and_team'); + saved_query + ----------------------------------------------- + SELECT * FROM nba WHERE Weight > ? AND Team = ? + From 0b0604a184e022cedd87a3894bf097a399fce9ed Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 1 May 2022 09:53:06 +0300 Subject: [PATCH 053/316] Removed Global Locks: SQ-10436 https://sqream.atlassian.net/browse/SQ-10436 Capitalized headers --- feature_guides/concurrency_and_locks.rst | 27 ++++-------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/feature_guides/concurrency_and_locks.rst b/feature_guides/concurrency_and_locks.rst index e18dea015..2a85d2642 100644 --- a/feature_guides/concurrency_and_locks.rst +++ b/feature_guides/concurrency_and_locks.rst @@ -10,7 +10,7 @@ Read only transactions are never blocked, and never block anything. Even if you .. _locking_modes: -Locking modes +Locking Modes ================ SQream DB has two kinds of locks: @@ -27,7 +27,7 @@ SQream DB has two kinds of locks: This lock allows other statements to insert or delete data from a table, but they'll have to wait in order to run DDL. -When are locks obtained? +When are Locks Obtained? ============================ .. list-table:: @@ -64,23 +64,7 @@ When are locks obtained? Statements that wait will exit with an error if they hit the lock timeout. The default timeout is 3 seconds, see ``statementLockTimeout``. -Global locks ----------------- - -Some operations require exclusive global locks at the cluster level. These usually short-lived locks will be obtained for the following operations: - - * :ref:`create_database` - * :ref:`create_role` - * :ref:`create_table` - * :ref:`alter_role` - * :ref:`alter_table` - * :ref:`drop_database` - * :ref:`drop_role` - * :ref:`drop_table` - * :ref:`grant` - * :ref:`revoke` - -Monitoring locks +Monitoring Locks =================== Monitoring locks across the cluster can be useful when transaction contention takes place, and statements appear "stuck" while waiting for a previous statement to release locks. @@ -101,7 +85,4 @@ In this example, we create a table based on results (:ref:`create_table_as`), bu 287 | CREATE OR REPLACE TABLE nba2 AS SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | sqream | 192.168.1.91 | 5000 | table$t$public$nba2$Insert | Exclusive | 2019-12-26 00:03:30 | 2019-12-26 00:03:30 287 | CREATE OR REPLACE TABLE nba2 AS SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | sqream | 192.168.1.91 | 5000 | table$t$public$nba2$Update | Exclusive | 2019-12-26 00:03:30 | 2019-12-26 00:03:30 -For more information on troubleshooting lock related issues, see - - - +For more information on troubleshooting lock related issues, see :ref:`lock_related_issues`. \ No newline at end of file From b6b65d51a12db74a757a769d622f766bc9bdc2f7 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 2 May 2022 11:31:21 +0300 Subject: [PATCH 054/316] TPD-123 --- .../ddl_commands/cluster_by.rst | 49 ++++++++++++------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/reference/sql/sql_statements/ddl_commands/cluster_by.rst b/reference/sql/sql_statements/ddl_commands/cluster_by.rst index 2a389e254..3f6023533 100644 --- a/reference/sql/sql_statements/ddl_commands/cluster_by.rst +++ b/reference/sql/sql_statements/ddl_commands/cluster_by.rst @@ -3,28 +3,38 @@ ********************** CLUSTER BY ********************** +The ``CLUSTER BY`` command is used for changing clustering keys in a table. -``CLUSTER BY`` can be used to change clustering keys in a table. +For more information, see the following: +* :ref:`flexible_data_clustering` -Read our :ref:`data_clustering` guide for more information. + :: -See also: :ref:`drop_clustering_key`, :ref:`create_table`. +* :ref:`drop_clustering_key` - -Permissions -============= - -The role must have the ``DDL`` permission at the database or table level. + :: + +* :ref:`create_table` Syntax ========== +The following is the correct syntax for the CLUSTER BY command: .. code-block:: postgres alter_table_rename_table_statement ::= ALTER TABLE [schema_name.]table_name CLUSTER BY column_name [, ...] ; + + create_table_statement ::= + CREATE [ OR REPLACE ] TABLE [schema_name.]table_name ( + { column_def [, ...] } + ) + [ CLUSTER BY { column_name [, ...] } ] + ; + + column_def :: = { column_name type_name [ default ] [ column_constraint ] } table_name ::= identifier @@ -33,6 +43,7 @@ Syntax Parameters ============ +The following table shows the CLUSTER BY parameters: .. list-table:: :widths: auto @@ -42,28 +53,32 @@ Parameters - Description * - ``schema_name`` - The schema name for the table. Defaults to ``public`` if not specified. + * - ``OR REPLACE`` + - Creates a new tables and overwrites any existing table by the same name. Does not return an error if the table already exists. ``CREATE OR REPLACE`` does not check the table contents or structure, only the table name. + * - ``column_def`` + - A comma separated list of column definitions. A minimal column definition includes a name identifier and a datatype. Other column constraints and default values can be added optionally. * - ``table_name`` - The table name to apply the change to. * - ``column_name [, ... ]`` - - Comma separated list of columns to create clustering keys for + - Comma separated list of columns to create clustering keys for. - -Usage notes +Usage Notes ================= - Removing clustering keys does not affect existing data. -To force data to re-cluster, the table has to be recreated (i.e. with :ref:`create_table_as`). +To force data to re-cluster, the table has to be recreated (i.e. with :ref:`create_table`). -Examples +Example =========== - -Reclustering a table +Reclustering a Table ----------------------------------------- +The following example shows how to recluster a table: .. code-block:: postgres ALTER TABLE public.users CLUSTER BY start_date; - +Permissions +============= +The role must have the ``DDL`` permission at the database or table level. \ No newline at end of file From 5c9c1288a0ff89c313474415560bf6d3930235bf Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 2 May 2022 15:23:28 +0300 Subject: [PATCH 055/316] Update executing_statements_and_running_queries_from_the_editor.rst --- ...ts_and_running_queries_from_the_editor.rst | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/sqream_studio_5.4.3/executing_statements_and_running_queries_from_the_editor.rst b/sqream_studio_5.4.3/executing_statements_and_running_queries_from_the_editor.rst index 72cbff97b..8fa91d945 100644 --- a/sqream_studio_5.4.3/executing_statements_and_running_queries_from_the_editor.rst +++ b/sqream_studio_5.4.3/executing_statements_and_running_queries_from_the_editor.rst @@ -188,23 +188,23 @@ The database object functions are used to perform the following: * - Function - Description * - Insert statement - - Generates an `INSERT `_ statement for the selected table in the editing area. + - Generates an `INSERT `_ statement for the selected table in the editing area. * - Delete statement - - Generates a `DELETE `_ statement for the selected table in the editing area. + - Generates a `DELETE `_ statement for the selected table in the editing area. * - Create Table As statement - - Generates a `CREATE TABLE AS `_ statement for the selected table in the editing area. + - Generates a `CREATE TABLE AS `_ statement for the selected table in the editing area. * - Rename statement - - Generates an `RENAME TABLE AS `_ statement for renaming the selected table in the editing area. + - Generates an `RENAME TABLE AS `_ statement for renaming the selected table in the editing area. * - Adding column statement - - Generates an `ADD COLUMN `_ statement for adding columns to the selected table in the editing area. + - Generates an `ADD COLUMN `_ statement for adding columns to the selected table in the editing area. * - Truncate table statement - - Generates a `TRUNCATE_IF_EXISTS `_ statement for the selected table in the editing area. + - Generates a `TRUNCATE_IF_EXISTS `_ statement for the selected table in the editing area. * - Drop table statement - Generates a ``DROP`` statement for the selected object in the editing area. * - Table DDL - - Generates a DDL statement for the selected object in the editing area. To get the entire database DDL, click the |icon-ddl-edit| icon next to the database name in the tree root. See `Seeing System Objects as DDL `_. + - Generates a DDL statement for the selected object in the editing area. To get the entire database DDL, click the |icon-ddl-edit| icon next to the database name in the tree root. See `Seeing System Objects as DDL `_. * - DDL Optimizer - - The `DDL Optimizer `_ lets you analyze database tables and recommends possible optimizations. + - The `DDL Optimizer `_ lets you analyze database tables and recommends possible optimizations. Optimizing Database Tables Using the DDL Optimizer ----------------------- @@ -223,23 +223,23 @@ The following table describes the DDL Optimizer screen: * - Column area - Shows the column **names** and **column types** from the selected table. You can scroll down or to the right/left for long column lists. * - Optimization area - - Shows the number of rows to sample as the basis for running an optimization, the default setting (1,000,000) when running an optimization (this is also the overhead threshold used when analyzing ``TEXT`` fields), and the default percent buffer to add to ``TEXT`` lengths (10%). Attempts to determine field nullability. + - Shows the number of rows to sample as the basis for running an optimization, the default setting (1,000,000) when running an optimization (this is also the overhead threshold used when analyzing ``VARCHAR`` fields), and the default percent buffer to add to ``VARCHAR`` lengths (10%). Attempts to determine field nullability. * - Run Optimizer - Starts the optimization process. Clicking **Run Optimizer** adds a tab to the Statement panel showing the optimized results of the selected object. -For more information, see `Optimization and Best Practices `_. +For more information, see `Optimization and Best Practices `_. Executing Pre-Defined Queries from the System Queries Panel --------------- The **System Queries** panel lets you execute predefined queries and includes the following system query types: -* **Catalog queries** - used for analyzing table compression rates, users and permissions, etc. +* **Catalog queries** - Used for analyzing table compression rates, users and permissions, etc. :: -* **Admin queries** - queries related to available (describe the functionality in a general way). Queries useful for SQream database management. +* **Admin queries** - Queries useful for SQream database management. Clicking an item pastes the query into the Statement pane, and you can undo a previous operation by pressing **Ctrl + Z**. @@ -274,7 +274,7 @@ You can add and name new tabs for each statement that you need to execute, and S You can also rename the default tab name by double-clicking it and typing a new name and write multiple statements in tandem in the same tab by separating them with semicolons (``;``).If too many tabs to fit into the Statement Pane are open at the same time, the tab arrows are displayed. You can scroll through the tabs by clicking |icon-left| or |icon-right|, and close tabs by clicking |icon-close|. You can also close all tabs at once by clicking **Close all** located to the right of the tabs. -.. tip:: If this is your first time using SQream, see `Getting Started `_. +.. tip:: If this is your first time using SQream, see `Getting Started `_. .. Keyboard shortcuts From 7bb5c634915b411365f9cb244f45681a54dbcf5a Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 10 May 2022 14:10:37 +0300 Subject: [PATCH 056/316] TPD-106 --- .../ddl_commands/rename_column.rst | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/reference/sql/sql_statements/ddl_commands/rename_column.rst b/reference/sql/sql_statements/ddl_commands/rename_column.rst index 41f1e1628..1022ce0f2 100644 --- a/reference/sql/sql_statements/ddl_commands/rename_column.rst +++ b/reference/sql/sql_statements/ddl_commands/rename_column.rst @@ -3,16 +3,11 @@ ********************** RENAME COLUMN ********************** - -``RENAME COLUMN`` can be used to rename columns in a table. - -Permissions -============= - -The role must have the ``DDL`` permission at the database or table level. +The ``RENAME COLUMN`` command can be used to rename columns in a table. Syntax ========== +The following is the correct syntax for the ``RENAME_COLUMN`` command: .. code-block:: postgres @@ -30,6 +25,7 @@ Syntax Parameters ============ +The following table describes the `RENAME_COLUMN`` parameters: .. list-table:: :widths: auto @@ -48,18 +44,29 @@ Parameters Examples =========== +The **Examples** section includes the following examples: -Renaming a column +.. contents:: + :local: + :depth: 1 + +Renaming a Column ----------------------------------------- +The following is an example of renaming a column: .. code-block:: postgres -- Remove the 'weight' column ALTER TABLE users RENAME COLUMN weight TO mass; -Renaming a quoted name +Renaming a Quoted Name -------------------------- +The following is an example of renaming a quoted name: .. code-block:: postgres - ALTER TABLE users RENAME COLUMN "mass" TO "Mass (Kilograms); \ No newline at end of file + ALTER TABLE users RENAME COLUMN "mass" TO "Mass (Kilograms); + +Permissions +============= +The role must have the ``DDL`` permission at the database or table level. \ No newline at end of file From dd7d6cfecfa88b7ae19632d67e450c8dded1ce7b Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 10 May 2022 14:42:30 +0300 Subject: [PATCH 057/316] TPD-155 --- .../ddl_commands/add_column.rst | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/reference/sql/sql_statements/ddl_commands/add_column.rst b/reference/sql/sql_statements/ddl_commands/add_column.rst index cec4aec7b..bac71bd2c 100644 --- a/reference/sql/sql_statements/ddl_commands/add_column.rst +++ b/reference/sql/sql_statements/ddl_commands/add_column.rst @@ -3,14 +3,11 @@ ********************** ADD COLUMN ********************** - -The ``ADD COLUMN`` command is used to add columns to an existing table. - - +The ``ADD COLUMN`` command is used to add columns to an existing table. Syntax ========== -The following is the correct syntax for adding a table: +The following is the correct syntax for adding a column to an existing table: .. code-block:: postgres @@ -32,8 +29,6 @@ The following is the correct syntax for adding a table: default ::= DEFAULT default_value - - Parameters ============ The following parameters can be used for adding a table: @@ -52,19 +47,20 @@ The following parameters can be used for adding a table: - A comma separated list of ADD COLUMN commands * - ``column_def`` - A column definition. A minimal column definition includes a name identifier and a datatype. Other column constraints and default values can be added optionally. + +Usage Notes +=========== +The following usage notes apply when adding a column to an existing table: -.. note:: * When adding a new column to an existing table, a default (or null constraint) has to be specified, even if the table is empty. - * A new column added to the table can not contain an IDENTITY or be of the TEXT type. - -Permissions -============= -The role must have the ``DDL`` permission at the database or table level. + :: + + * New columns you add to the table cannot be TEXT or contain an IDENTITY. Examples =========== -This section includes the following examples: +The **Examples** section includes the following examples: .. contents:: :local: @@ -77,8 +73,7 @@ This example shows how to add a simple column with a default value: .. code-block:: postgres ALTER TABLE cool_animals - ADD COLUMN number_of_eyes INT DEFAULT 2 NOT NULL; - + ADD COLUMN number_of_eyes INT DEFAULT 2 NOT NULL; Adding Several Columns in One Command ------------------------------------------- @@ -88,4 +83,8 @@ This example shows how to add several columns in one command: ALTER TABLE cool_animals ADD COLUMN number_of_eyes INT DEFAULT 2 NOT NULL, - ADD COLUMN date_seen DATE DEFAULT '2019-08-01'; + ADD COLUMN date_seen DATE DEFAULT '2019-08-01'; + +Permissions +============= +The role must have the ``DDL`` permission at the database or table level. \ No newline at end of file From 832934365ee43872388a3501a20eeda2b3a04a31 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 10 May 2022 17:31:35 +0300 Subject: [PATCH 058/316] TPD-88 --- reference/sql/sql_statements/ddl_commands/cluster_by.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/reference/sql/sql_statements/ddl_commands/cluster_by.rst b/reference/sql/sql_statements/ddl_commands/cluster_by.rst index 3f6023533..e4cf42ad4 100644 --- a/reference/sql/sql_statements/ddl_commands/cluster_by.rst +++ b/reference/sql/sql_statements/ddl_commands/cluster_by.rst @@ -40,6 +40,7 @@ The following is the correct syntax for the CLUSTER BY command: column_name ::= identifier +.. note:: SQream does not support clustering by TEXT columns. Parameters ============ From 2a34788254b4702b4d1e4c9f41f3fe1a704fa344 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 12 May 2022 15:50:45 +0300 Subject: [PATCH 059/316] TPD-154: Partial implementation Implemented some of Nadia's comments. Questions remain about others. --- feature_guides/workload_manager.rst | 7 +++---- reference/configuration.rst | 5 ----- reference/sql/sql_statements/index.rst | 2 +- .../sql_statements/wlm_commands/unsubscribe_service.rst | 2 +- .../configuring_your_instance_of_sqream.rst | 2 +- 5 files changed, 6 insertions(+), 12 deletions(-) delete mode 100644 reference/configuration.rst diff --git a/feature_guides/workload_manager.rst b/feature_guides/workload_manager.rst index c8eb2468d..aece3d11f 100644 --- a/feature_guides/workload_manager.rst +++ b/feature_guides/workload_manager.rst @@ -4,12 +4,11 @@ Workload Manager *********************** -The **Workload Manager** allows SQream DB workers to identify their availability to clients with specific service names. The load balancer uses that information to route statements to specific workers. +The **Workload Manager** allows SQream workers to identify their availability to clients with specific service names. The load balancer uses that information to route statements to specific workers. Overview =============================== - -The Workload Manager allows a system engineer or database administrator to allocate specific workers and compute resoucres for various tasks. +The Workload Manager allows a system engineer or database administrator to allocate specific workers and compute resources for various tasks. For example: @@ -60,7 +59,7 @@ The configuration in this example allocates resources as shown below: - ✓ - ✓ -This configuration gives the ETL queue dedicated access to two workers, one of which cannot be used by regular queries. +This configuration gives the ETL queue dedicated access to one worker, which cannot be used.. Queries from management uses any available worker. diff --git a/reference/configuration.rst b/reference/configuration.rst deleted file mode 100644 index bf487496e..000000000 --- a/reference/configuration.rst +++ /dev/null @@ -1,5 +0,0 @@ -.. _configuration_reference: - -************************* -Configuration -************************* diff --git a/reference/sql/sql_statements/index.rst b/reference/sql/sql_statements/index.rst index 6845ae7cd..04b24a58f 100644 --- a/reference/sql/sql_statements/index.rst +++ b/reference/sql/sql_statements/index.rst @@ -171,7 +171,7 @@ Workload Management * - :ref:`subscribe_service` - Add a SQream DB worker to a service queue * - :ref:`unsubscribe_service` - - Remove a SQream DB worker to a service queue + - Remove a SQream DB worker from a service queue * - :ref:`show_subscribed_instances` - Return a list of service queues and workers diff --git a/reference/sql/sql_statements/wlm_commands/unsubscribe_service.rst b/reference/sql/sql_statements/wlm_commands/unsubscribe_service.rst index a26df0554..939d8918a 100644 --- a/reference/sql/sql_statements/wlm_commands/unsubscribe_service.rst +++ b/reference/sql/sql_statements/wlm_commands/unsubscribe_service.rst @@ -47,7 +47,7 @@ Notes * If the service name does not currently exist, it will be created -.. warning:: ``UNSUBSCRIBE_SERVICE`` applies the service subscription immediately, but the setting applies for the duration of the session. To apply a persistent setting, use the ``initialSubscribedServices`` configuration setting. Read the :ref:`Workload manager guide` for more information. +.. warning:: ``UNSUBSCRIBE_SERVICE`` removes the service subscription immediately, but the setting applies for the duration of the session. To apply a persistent setting, use the ``initialSubscribedServices`` configuration setting. Read the :ref:`Workload manager guide` for more information. Examples =========== diff --git a/sqream_studio_5.4.3/configuring_your_instance_of_sqream.rst b/sqream_studio_5.4.3/configuring_your_instance_of_sqream.rst index 2a60146e0..e5f4b11e5 100644 --- a/sqream_studio_5.4.3/configuring_your_instance_of_sqream.rst +++ b/sqream_studio_5.4.3/configuring_your_instance_of_sqream.rst @@ -20,4 +20,4 @@ Exporting and Importing Configuration Files ------------------------- You can also export and import your configuration settings into a .json file. This allows you to easily edit your parameters and to share this file with other users if required. -For more information about configuring your instance of SQream, see `Configuration Guides `_. +For more information about configuring your instance of SQream, see `Configuration Guides `_. \ No newline at end of file From 6e3cfd2bf5f06ef1c97c1b155aa7258cf75773ec Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 15 May 2022 11:21:40 +0300 Subject: [PATCH 060/316] SQ-10052 --- data_type_guides/converting_and_casting_types.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/data_type_guides/converting_and_casting_types.rst b/data_type_guides/converting_and_casting_types.rst index e4de6eeb7..bb6475646 100644 --- a/data_type_guides/converting_and_casting_types.rst +++ b/data_type_guides/converting_and_casting_types.rst @@ -15,7 +15,7 @@ You can rectify this by casting the value to a larger data type, as shown below: SQream supports the following three data conversion types: -* ``CAST( TO )``, to convert a value from one type to another. For example, ``CAST('1997-01-01' TO DATE)``, ``CAST(3.45 TO SMALLINT)``, ``CAST(some_column TO TEXT(30))``. +* ``CAST( TO )``, to convert a value from one type to another. For example, ``CAST('1997-01-01' TO DATE)``, ``CAST(3.45 TO SMALLINT)``, ``CAST(some_column TO VARCHAR(30))``. :: @@ -23,4 +23,6 @@ SQream supports the following three data conversion types: :: -* See the :ref:`SQL functions reference ` for additional functions that convert from a specific value which is not an SQL type, such as :ref:`from_unixts`, etc. \ No newline at end of file +* See the :ref:`SQL functions reference ` for additional functions that convert from a specific value which is not an SQL type, such as :ref:`from_unixts`, etc. + +.. note:: SQream interprets integer constants exceeding the maximum bigint value as float constants, which may cause precision loss. \ No newline at end of file From e648c7b600be1453493cf0e417c0bf819f964f70 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 15 May 2022 11:52:00 +0300 Subject: [PATCH 061/316] Moved show_server_status to Utility Commands --- reference/sql/sql_statements/index.rst | 2 - .../show_server_status.rst | 108 ------------------ 2 files changed, 110 deletions(-) delete mode 100644 reference/sql/sql_statements/monitoring_commands/show_server_status.rst diff --git a/reference/sql/sql_statements/index.rst b/reference/sql/sql_statements/index.rst index 04b24a58f..cdaf8a94f 100644 --- a/reference/sql/sql_statements/index.rst +++ b/reference/sql/sql_statements/index.rst @@ -152,8 +152,6 @@ Monitoring statements allow a database administrator to execute actions in the s - Returns any existing locks in the database * - :ref:`show_node_info` - Returns a query plan for an actively running statement with timing information - * - :ref:`show_server_status` - - Shows running statements across the cluster * - :ref:`show_version` - Returns the version of SQream DB * - :ref:`stop_statement` diff --git a/reference/sql/sql_statements/monitoring_commands/show_server_status.rst b/reference/sql/sql_statements/monitoring_commands/show_server_status.rst deleted file mode 100644 index f59f79ccc..000000000 --- a/reference/sql/sql_statements/monitoring_commands/show_server_status.rst +++ /dev/null @@ -1,108 +0,0 @@ -.. _show_server_status: - -******************** -SHOW_SERVER_STATUS -******************** - -``SHOW_SERVER_STATUS`` returns a list of active sessions across the cluster. - -To list active statements on the current worker only, see :ref:`show_connections`. - -Permissions -============= - -The role must have the ``SUPERUSER`` permissions. - -Syntax -========== - -.. code-block:: postgres - - show_server_status_statement ::= - SELECT SHOW_SERVER_STATUS() - ; - -Parameters -============ - -None - -Returns -========= - -This function returns a list of active sessions. If no sessions are active across the cluster, the result set will be empty. - -.. list-table:: Result columns - :widths: auto - :header-rows: 1 - - * - ``service`` - - The service name for the statement - * - ``instance`` - - The worker ID - * - ``connection_id`` - - Connection ID - * - ``serverip`` - - Worker end-point IP - * - ``serverport`` - - Worker end-point port - * - ``database_name`` - - Database name for the statement - * - ``user_name`` - - Username running the statement - * - ``clientip`` - - Client IP - * - ``statementid`` - - Statement ID - * - ``statement`` - - Statement text - * - ``statementstarttime`` - - Statement start timestamp - * - ``statementstatus`` - - Statement status (see table below) - * - ``statementstatusstart`` - - Last updated timestamp - -.. include from here: 66 - - -.. list-table:: Statement status values - :widths: auto - :header-rows: 1 - - * - Status - - Description - * - ``Preparing`` - - Statement is being prepared - * - ``In queue`` - - Statement is waiting for execution - * - ``Initializing`` - - Statement has entered execution checks - * - ``Executing`` - - Statement is executing - * - ``Stopping`` - - Statement is in the process of stopping - - -.. include until here 86 - -Notes -=========== - -* This utility shows the active sessions. Some sessions may be actively connected, but not running any statements. - -Examples -=========== - -Using ``SHOW_SERVER_STATUS`` to get statement IDs ----------------------------------------------------- - - -.. code-block:: psql - - t=> SELECT SHOW_SERVER_STATUS(); - service | instanceid | connection_id | serverip | serverport | database_name | user_name | clientip | statementid | statement | statementstarttime | statementstatus | statementstatusstart - --------+------------+---------------+--------------+------------+---------------+------------+-------------+-------------+-----------------------------+---------------------+-----------------+--------------------- - sqream | | 102 | 192.168.1.91 | 5000 | t | rhendricks | 192.168.0.1 | 128 | SELECT SHOW_SERVER_STATUS() | 24-12-2019 00:14:53 | Executing | 24-12-2019 00:14:53 - -The statement ID is ``128``, running on worker ``192.168.1.91``. From 4c0b91d170ef76eb295441588e972819d336a086 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 15 May 2022 12:21:33 +0300 Subject: [PATCH 062/316] Moved show_server_status to Utility Commands --- reference/sql/sql_statements/index.rst | 22 -- .../monitoring_commands/explain.rst | 59 ---- .../monitoring_commands/show_connections.rst | 78 ----- .../monitoring_commands/show_locks.rst | 79 ----- .../monitoring_commands/show_node_info.rst | 310 ------------------ .../monitoring_commands/stop_statement.rst | 77 ----- 6 files changed, 625 deletions(-) delete mode 100644 reference/sql/sql_statements/monitoring_commands/explain.rst delete mode 100644 reference/sql/sql_statements/monitoring_commands/show_connections.rst delete mode 100644 reference/sql/sql_statements/monitoring_commands/show_locks.rst delete mode 100644 reference/sql/sql_statements/monitoring_commands/show_node_info.rst delete mode 100644 reference/sql/sql_statements/monitoring_commands/stop_statement.rst diff --git a/reference/sql/sql_statements/index.rst b/reference/sql/sql_statements/index.rst index cdaf8a94f..d0a6c04c8 100644 --- a/reference/sql/sql_statements/index.rst +++ b/reference/sql/sql_statements/index.rst @@ -133,29 +133,7 @@ Utility Commands - Stops or aborts an active statement -Monitoring -=============== -Monitoring statements allow a database administrator to execute actions in the system, such as aborting a query or get information about system processes. - -.. list-table:: Monitoring - :widths: auto - :header-rows: 1 - - * - Command - - Usage - * - :ref:`explain` - - Returns a static query plan for a statement - * - :ref:`show_connections` - - Returns a list of jobs and statements on the current worker - * - :ref:`show_locks` - - Returns any existing locks in the database - * - :ref:`show_node_info` - - Returns a query plan for an actively running statement with timing information - * - :ref:`show_version` - - Returns the version of SQream DB - * - :ref:`stop_statement` - - Stops a query (or statement) if it is currently running Workload Management ====================== diff --git a/reference/sql/sql_statements/monitoring_commands/explain.rst b/reference/sql/sql_statements/monitoring_commands/explain.rst deleted file mode 100644 index e9b7e7ee9..000000000 --- a/reference/sql/sql_statements/monitoring_commands/explain.rst +++ /dev/null @@ -1,59 +0,0 @@ -.. _explain: - -***************** -EXPLAIN -***************** - -``EXPLAIN`` returns a static query plan, which can be used to debug query plans. - -To see an actively running query or statement, use :ref:`show_node_info` instead. - -See also :ref:`show_node_info`, :ref:`show_server_status`. - - -Permissions -============= - -The role must have the ``SELECT`` permissions for any tables referenced by the query. - -Syntax -========== - -.. code-block:: postgres - - explain_statement ::= - SELECT EXPLAIN(query_stmt) - ; - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``query_stmt`` - - The select query to generate the plan for. - -Notes -=========== - -Use dollar-quoting to escape the query text - -Examples -=========== - -Generating a static query plan ----------------------------------- - -.. code-block:: psql - - t=> SELECT EXPLAIN($$SELECT DATEADD(hour,1,dt) FROM cool_dates$$); - Select - Specific (TTNative Gpu) (dateadd@null := dt@null, - dateadd@val := (pure_if dt@null "0" (addHoursdt2dt dt@val "1"))) - Table Scan - public.cool_dates ("dt@null", "dt@val") [] - diff --git a/reference/sql/sql_statements/monitoring_commands/show_connections.rst b/reference/sql/sql_statements/monitoring_commands/show_connections.rst deleted file mode 100644 index 1bd320a4c..000000000 --- a/reference/sql/sql_statements/monitoring_commands/show_connections.rst +++ /dev/null @@ -1,78 +0,0 @@ -.. _show_connections: - -******************** -SHOW_CONNECTIONS -******************** - -``SHOW_CONNECTIONS`` returns a list of active sessions on the current worker. - -To see sessions across the cluster, see :ref:`show_server_status`. - -Permissions -============= - -The role must have the ``SUPERUSER`` permissions. - -Syntax -========== - -.. code-block:: postgres - - show_connections_statement ::= - SELECT SHOW_CONNECTIONS() - ; - -Parameters -============ - -None - -Returns -========= - -This function returns a list of active sessions. If no sessions are active on the worker, the result set will be empty. - -.. list-table:: Result columns - :widths: auto - :header-rows: 1 - - * - ``ip`` - - The worker hostname or IP - * - ``conn_id`` - - Connection ID - * - ``conn_start_time`` - - Connection start timestamp - * - ``stmt_id`` - - Statement ID. Connections with no active statement display ``-1``. - * - ``stmt_start_time`` - - Statement start timestamp - * - ``stmt`` - - Statement text - - -Notes -=========== - -* This utility shows the active connections. Some sessions may be actively connected, but not currently running a statement. - -* A connection is typically reused. There could be many statements under a single connection ID. - -Examples -=========== - -Using ``SHOW_CONNECTIONS`` to get statement IDs ----------------------------------------------------- - - -.. code-block:: psql - - t=> SELECT SHOW_CONNECTIONS(); - ip | conn_id | conn_start_time | stmt_id | stmt_start_time | stmt - -------------+---------+---------------------+---------+---------------------+-------------------------- - 192.168.1.91 | 103 | 2019-12-24 00:01:27 | 129 | 2019-12-24 00:38:18 | SELECT GET_DATE(), * F... - 192.168.1.91 | 23 | 2019-12-24 00:01:27 | -1 | 2019-12-24 00:01:27 | - 192.168.1.91 | 22 | 2019-12-24 00:01:27 | -1 | 2019-12-24 00:01:27 | - 192.168.1.91 | 26 | 2019-12-24 00:01:28 | -1 | 2019-12-24 00:01:28 | - - -The statement ID we're interested in is ``129``. We can see the connection started at 00:01:27, while the statement started at 00:38:18. \ No newline at end of file diff --git a/reference/sql/sql_statements/monitoring_commands/show_locks.rst b/reference/sql/sql_statements/monitoring_commands/show_locks.rst deleted file mode 100644 index d5e7c02ec..000000000 --- a/reference/sql/sql_statements/monitoring_commands/show_locks.rst +++ /dev/null @@ -1,79 +0,0 @@ -.. _show_locks: - -******************** -SHOW_LOCKS -******************** - -``SHOW_LOCKS`` returns a list of locks from across the cluster. - -Read more about locks in :ref:`concurrency_and_locks`. - -Permissions -============= - -The role must have the ``SUPERUSER`` permissions. - -Syntax -========== - -.. code-block:: postgres - - show_locks_statement ::= - SELECT SHOW_LOCKS() - ; - -Parameters -============ - -None - -Returns -========= - -This function returns a list of active locks. If no locks are active in the cluster, the result set will be empty. - -.. list-table:: Result columns - :widths: auto - :header-rows: 1 - - * - ``stmt_id`` - - Statement ID that caused the lock. - * - ``stmt_string`` - - Statement text - * - ``username`` - - The role that executed the statement - * - ``server`` - - The worker node's IP - * - ``port`` - - The worker node's port - * - ``locked_object`` - - The full qualified name of the object being locked, separated with ``$`` (e.g. ``table$t$public$nba2`` for table ``nba2`` in schema ``public``, in database ``t`` - * - ``lockmode`` - - The locking mode (:ref:`inclusive` or :ref:`exclusive`). - * - ``statement_start_time`` - - Timestamp the statement started - * - ``lock_start_time`` - - Timestamp the lock was obtained - - -Examples -=========== - -Using ``SHOW_LOCKS`` to see active locks ---------------------------------------------------- - -In this example, we create a table based on results (:ref:`create_table_as`), but we are also effectively dropping the previous table (by using ``OR REPLACE``). Thus, SQream DB applies locks during the table creation process to prevent the table from being altered during it's creation. - - -.. code-block:: psql - - t=> SELECT SHOW_LOCKS(); - statement_id | statement_string | username | server | port | locked_object | lockmode | statement_start_time | lock_start_time - -------------+-------------------------------------------------------------------------------------------------+----------+--------------+------+---------------------------------+-----------+----------------------+-------------------- - 287 | CREATE OR REPLACE TABLE nba2 AS SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | sqream | 192.168.1.91 | 5000 | database$t | Inclusive | 2019-12-26 00:03:30 | 2019-12-26 00:03:30 - 287 | CREATE OR REPLACE TABLE nba2 AS SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | sqream | 192.168.1.91 | 5000 | globalpermission$ | Exclusive | 2019-12-26 00:03:30 | 2019-12-26 00:03:30 - 287 | CREATE OR REPLACE TABLE nba2 AS SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | sqream | 192.168.1.91 | 5000 | schema$t$public | Inclusive | 2019-12-26 00:03:30 | 2019-12-26 00:03:30 - 287 | CREATE OR REPLACE TABLE nba2 AS SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | sqream | 192.168.1.91 | 5000 | table$t$public$nba2$Insert | Exclusive | 2019-12-26 00:03:30 | 2019-12-26 00:03:30 - 287 | CREATE OR REPLACE TABLE nba2 AS SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | sqream | 192.168.1.91 | 5000 | table$t$public$nba2$Update | Exclusive | 2019-12-26 00:03:30 | 2019-12-26 00:03:30 - - diff --git a/reference/sql/sql_statements/monitoring_commands/show_node_info.rst b/reference/sql/sql_statements/monitoring_commands/show_node_info.rst deleted file mode 100644 index 9c1e1ec11..000000000 --- a/reference/sql/sql_statements/monitoring_commands/show_node_info.rst +++ /dev/null @@ -1,310 +0,0 @@ -.. _show_node_info: - -******************** -SHOW_NODE_INFO -******************** - -``SHOW_NODE_INFO`` returns a snapshot of the current query plan, similar to ``EXPLAIN ANALYZE`` from other databases. - -The snapshot provides information about execution which can be used for monitoring and troubleshooting slow running statements by helping identify long-running execution nodes (components that process data), etc. - -See also :ref:`explain`, :ref:`show_server_status`. - -Permissions -============= - -The role must have the ``SUPERUSER`` permissions. - -Syntax -========== - -.. code-block:: postgres - - show_node_info_statement ::= - SELECT SHOW_NODE_INFO(stmt_id) - ; - - stmt_id ::= bigint - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``stmt_id`` - - The statement ID to explore - -Returns -========= - -This utility returns details of the execution nodes, if the statement is still running. - -If the statement has finished, or the statment ID does not exist, the utility returns an empty result set. - -.. list-table:: Result columns - :widths: auto - :header-rows: 1 - - * - Column name - - Description - * - ``stmt_id`` - - The ID for the statement - * - ``node_id`` - - This node's ID in this execution plan - * - ``node_type`` - - The node type - * - ``rows`` - - Total number of rows this node has processed - * - ``chunks`` - - Number of chunks this node has processed - * - ``avg_rows_in_chunk`` - - Average amount of rows that this node processes in each chunk (``rows / chunks``) - * - ``time`` - - Timestamp for this node's creation - * - ``parent_node_id`` - - The ``node_id`` of this node's parent - * - ``read`` - - Total data read from disk - * - ``write`` - - Total data written to disk - * - ``comment`` - - Additional information (e.g. table name for ``ReadTable``) - * - ``timesum`` - - Total elapsed time for this execution node's processing - - -.. _node_types: - -Node types -============= - -This is a full list of node types: - -.. list-table:: Node types - :widths: auto - :header-rows: 1 - - * - Column name - - Execution location - - Description - * - ``AddChunkId`` - - - - Used during insert operations - * - ``AddSequences`` - - - - Used during insert operations, with :ref:`identity columns` - * - ``AddMinMaxMetadata`` - - - - Used to calculate ranges for the :ref:`chunk metadata system` - * - ``AddTopSortFilters`` - - - - An operation to optimize ``LIMIT`` when used alongside ``ORDER BY`` - * - ``Compress`` - - CPU and GPU - - Compress data with both CPU and GPU schemes - * - ``CpuDecompress`` - - CPU - - Decompression operation, common for longer ``TEXT`` types - * - ``CpuLoopJoin`` - - CPU - - A non-indexed nested loop join, performed on the CPU - * - ``CpuReduce`` - - CPU - - A reduce process performed on the CPU, primarily with ``DISTINCT`` aggregates (e.g. ``COUNT(DISTINCT ...)``) - * - ``CpuToGpu``, ``GpuToCpu`` - - - - An operation that moves data to or from the GPU for processing - * - ``CpuTransform`` - - CPU - - A transform operation performed on the CPU, usually a :ref:`scalar function` - * - ``CrossJoin`` - - - - A join without a join condition - * - ``DeferredGather`` - - CPU - - Merges the results of GPU operations with a result set [#f0]_ - * - ``Distinct`` - - GPU - - Removes duplicate rows (usually as part of the ``DISTINCT`` operation) - * - ``Distinct_Merge`` - - CPU - - The merge operation of the ``Distinct`` operation - * - ``Filter`` - - GPU - - A filtering operation, such as a ``WHERE`` or ``JOIN`` clause - * - ``GpuCopy`` - - GPU - - Copies data between GPUs or within a single GPU - * - ``GpuDecompress`` - - GPU - - Decompression operation - * - ``GpuReduceMerge`` - - GPU - - An operation to optimize part of the merger phases in the GPU - * - ``GpuTransform`` - - GPU - - A transformation operation such as a type cast or :ref:`scalar function` - * - ``Hash`` - - CPU - - Hashes the output result. Used internally. - * - ``JoinSideMarker`` - - - - Used internally. - * - ``LiteralValues`` - - CPU - - Creates a virtual relation (table), when :ref:`values` is used - * - ``LocateFiles`` - - CPU - - Validates external file paths for foreign data wrappers, expanding directories and GLOB patterns - * - ``LoopJoin`` - - GPU - - A non-indexed nested loop join, performed on the GPU - * - ``MarkMatchedJoinRows`` - - - - Used in outer joins, matches rows for larger join operations - * - ``NullifyDuplicates`` - - - - Replaces duplicate values with ``NULL`` to calculate distinct aggregates - * - ``NullSink`` - - CPU - - Used internally - * - ``ParseCsv`` - - CPU - - A CSV parser, used after ``ReadFiles`` to convert the CSV into columnar data - * - ``PopNetworkQueue`` - - CPU - - Fetches data from the network queue (e.g. when used with :ref:`insert`) - * - ``PushToNetworkQueue`` - - CPU - - Sends result sets to a client connected over the network - * - ``ReadCatalog`` - - CPU - - Converts the :ref:`catalog` into a relation (table) - * - ``ReadFiles`` - - CPU - - Reads external flat-files - * - ``ReadOrc`` - - CPU - - Reads data from an ORC file - * - ``ReadParquet`` - - CPU - - Reads data from a Parquet file - * - ``ReadTable`` - - CPU - - Reads data from a standard table stored on disk - * - ``ReadTableMetadata`` - - CPU - - Reads only table metadata as an optimization - * - ``Rechunk`` - - - - Reorganize multiple small :ref:`chunks` into a full chunk. Commonly found after joins and when :ref:`HIGH_SELECTIVITY` is used - * - ``Reduce`` - - GPU - - A reduction operation, such as a ``GROUP BY`` - * - ``ReduceMerge`` - - GPU - - A merge operation of a reduction operation, helps operate on larger-than-RAM data - * - ``ReorderInput`` - - - - Change the order of arguments in preparation for the next operation - * - ``SeparatedGather`` - - GPU - - Gathers additional columns for the result - * - ``Sort`` - - GPU - - Sort operation [#f1]_ - * - ``SortMerge`` - - CPU - - A merge operation of a sort operation, helps operate on larger-than-RAM data - * - ``SortMergeJoin`` - - GPU - - A sort-merge join, performed on the GPU - * - ``TakeRowsFromChunk`` - - - - Take the first N rows from each chunk, to optimize ``LIMIT`` when used alongside ``ORDER BY`` - * - ``Top`` - - - - Limits the input size, when used with ``LIMIT`` (or its alias ``TOP``) - * - ``UdfTransform`` - - CPU - - Executes a :ref:`user defined function` - * - ``UnionAll`` - - - - Combines two sources of data when ``UNION ALL`` is used - * - ``VarCharJoiner`` - - - - Used internally - * - ``VarCharSplitter`` - - - - Used intenrally - * - ``Window`` - - GPU - - Executes a non-ranking :ref:`window function` - * - ``WindowRanking`` - - GPU - - Executes a ranking :ref:`window function` - * - ``WriteTable`` - - CPU - - Writes the result set to a standard table stored on disk - -.. rubric:: Footnotes - -.. [#f0] Gathers columns which should be returned. This node typically spends most of the time on decompressing additional columns. - -.. [#f1] A GPU sort operation can be added by the statement compiler before ``GROUP BY`` or ``JOIN`` operations. - -Statement statuses -======================= - -.. include:: /reference/sql/sql_statements/monitoring_commands/show_server_status.rst - :start-line: 67 - :end-line: 84 - -Notes -=========== - -* This utility shows the execution information for active statements. Once a query has finished execution, the information is no longer available using this utility. See :ref:`logging` for more information about extracting the information from the logs. - -* This utility is primarily intended for troubleshooting with SQream support. - -Examples -=========== - -Getting execution details for a statement ------------------------------------------------- - - -.. code-block:: psql - - t=> SELECT SHOW_SERVER_STATUS(); - service | instanceid | connection_id | serverip | serverport | database_name | user_name | clientip | statementid | statement | statementstarttime | statementstatus | statementstatusstart - --------+------------+---------------+--------------+------------+---------------+-----------+--------------+-------------+-----------------------------------------------------------------+---------------------+-----------------+--------------------- - sqream | | 152 | 192.168.1.91 | 5000 | t | sqream | 192.168.1.91 | 176 | SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1; | 25-12-2019 23:53:13 | Executing | 25-12-2019 23:53:13 - sqream | | 151 | 192.168.1.91 | 5000 | t | sqream | 192.168.0.1 | 177 | SELECT show_server_status() | 25-12-2019 23:51:31 | Executing | 25-12-2019 23:53:13 - - -The statement ID we want to reserach is ``176``, running on worker ``192.168.1.91``. - -The query text is ``SELECT "Name" FROM nba WHERE REGEXP_COUNT("Name", '( )+', 8)>1;`` - -.. code-block:: psql - - t=> SELECT SHOW_NODE_INFO(176); - stmt_id | node_id | node_type | rows | chunks | avg_rows_in_chunk | time | parent_node_id | read | write | comment | timeSum - --------+---------+--------------------+------+--------+-------------------+---------------------+----------------+------+-------+------------+-------- - 176 | 1 | PushToNetworkQueue | 1 | 1 | 1 | 2019-12-25 23:53:13 | -1 | | | | 0.0025 - 176 | 2 | Rechunk | 1 | 1 | 1 | 2019-12-25 23:53:13 | 1 | | | | 0 - 176 | 3 | GpuToCpu | 1 | 1 | 1 | 2019-12-25 23:53:13 | 2 | | | | 0 - 176 | 4 | ReorderInput | 1 | 1 | 1 | 2019-12-25 23:53:13 | 3 | | | | 0 - 176 | 5 | Filter | 1 | 1 | 1 | 2019-12-25 23:53:13 | 4 | | | | 0.0002 - 176 | 6 | GpuTransform | 457 | 1 | 457 | 2019-12-25 23:53:13 | 5 | | | | 0.0002 - 176 | 7 | GpuDecompress | 457 | 1 | 457 | 2019-12-25 23:53:13 | 6 | | | | 0 - 176 | 8 | CpuToGpu | 457 | 1 | 457 | 2019-12-25 23:53:13 | 7 | | | | 0.0003 - 176 | 9 | Rechunk | 457 | 1 | 457 | 2019-12-25 23:53:13 | 8 | | | | 0 - 176 | 10 | CpuDecompress | 457 | 1 | 457 | 2019-12-25 23:53:13 | 9 | | | | 0 - 176 | 11 | ReadTable | 457 | 1 | 457 | 2019-12-25 23:53:13 | 10 | 4MB | | public.nba | 0.0004 - diff --git a/reference/sql/sql_statements/monitoring_commands/stop_statement.rst b/reference/sql/sql_statements/monitoring_commands/stop_statement.rst deleted file mode 100644 index 30efc25b5..000000000 --- a/reference/sql/sql_statements/monitoring_commands/stop_statement.rst +++ /dev/null @@ -1,77 +0,0 @@ -.. _stop_statement: - -******************** -STOP_STATEMENT -******************** - -``STOP_STATEMENT`` stops or aborts an active statement. - -To find a statement by ID, see :ref:`show_server_status` and :ref:`show_connections`. - -.. tip:: Some DBMSs call this process killing a session, terminating a job, or kill query - -Permissions -============= - -The role must have the ``SUPERUSER`` permissions. - -Syntax -========== - -.. code-block:: postgres - - stop_statement_statement ::= - SELECT STOP_STATEMENT(stmt_id) - ; - - stmt_id ::= bigint - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``stmt_id`` - - The statement ID to stop - -Returns -========= - -This utility does not return any value, and always succeeds even if the statement does not exist, or has already stopped. - - -Notes -=========== - -* This utility always succeeds even if the statement does not exist, or has already stopped. - -Examples -=========== - -Using :ref:`show_connections` to get statement IDs ----------------------------------------------------- - -.. tip:: Use :ref:`show_server_status` to find statments from across the entire cluster, or :ref:`show_connections` to show statements from the current worker the client is connected to. - -.. code-block:: psql - - t=> SELECT SHOW_CONNECTIONS(); - ip | conn_id | conn_start_time | stmt_id | stmt_start_time | stmt - -------------+---------+---------------------+---------+---------------------+-------------------------- - 192.168.1.91 | 103 | 2019-12-24 00:01:27 | 129 | 2019-12-24 00:38:18 | SELECT GET_DATE(), * F... - 192.168.1.91 | 23 | 2019-12-24 00:01:27 | -1 | 2019-12-24 00:01:27 | - 192.168.1.91 | 22 | 2019-12-24 00:01:27 | -1 | 2019-12-24 00:01:27 | - 192.168.1.91 | 26 | 2019-12-24 00:01:28 | -1 | 2019-12-24 00:01:28 | - - -The statement ID we're interested in is ``129``. We can now stop this statement: - -.. code-block:: psql - - t=> SELECT STOP_STATEMENT(129) - executed - From 2fdcb0647adb8d2a30bcd41521be1b18d80b218e Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 19 May 2022 16:09:58 +0300 Subject: [PATCH 063/316] Avro, Encryption, Update Published to private 2022.1 branch to share with Product team. --- _static/images/new.png | Bin 0 -> 1503 bytes _static/images/new_2022.1.png | Bin 0 -> 2056 bytes data_ingestion/avro.rst | 182 +++++++----------- feature_guides/data_encryption.rst | 6 +- .../sql_statements/dml_commands/update.rst | 9 +- 5 files changed, 83 insertions(+), 114 deletions(-) create mode 100644 _static/images/new.png create mode 100644 _static/images/new_2022.1.png diff --git a/_static/images/new.png b/_static/images/new.png new file mode 100644 index 0000000000000000000000000000000000000000..a0df8ff0fc2fc25204895ade1d958e69c4651696 GIT binary patch literal 1503 zcmV<51t9u~P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGqB>(^xB>_oNB=7(L1$0S7K~!i%<(fTc z6hRcnCqanuBgq-Run=P5MLdHZpDr-+_E{v2;-X6J6-zIktUlO}7esmjx*=FS~+ z|Gs(s+8vfkQR}}+vFJVv1+#0HIe5??W&HA6>m_SFEs0m+E;NPq_V^o%Y;0`~JPZ_Jt(*2t$iSyL`ExtFg6svF+-z zQ&Zjv0Wlw85QeJr{~xVdWhW-QD=IAX5gfF3tv)SLBO`Wt+UeOd+uN&qLye93kv%=S z>+cjY%=ox>NJQWxEV29%6f!%jdqcrHLSLWm`fG(~3Km_nFK_enX5T(DHRTU$qP^XW zjd{B$xS-b6194ESE$57m_+JcJDmHM>>! z=~EP2^>Y2XdGf^DhYx!r52%JH9{?-;!2@&YlGDwb=IvY8xO%nAcOk4Q+qZjzV40)5 z3L7?fBZQ|sdgP5feEeu`+%R_cZtc80B5c9B6Vx(Eiz7xKPK?I|&kAQ_EW|?$!$RWA zjZvoBtE#KZ*v*@DYaS7{aMh?SWtxu=^Fm_kp$C;acqhU}h_eZ5PTT__Eth4et{Y%%Iu{b}M>RE@Z{Pgd`*lV~y-{^b+1u;3 zR6u2%kPjccfx(0+Y0DOG0M3S7Be`tjM)yg!ZS%&xd)}ytI-l~1YRA$L7)pt81Uo+} z0EI9B878o~+Z~Ycf1q2kV-?gQD@xmLz^XKjpfy4OPw8?$S zj(>dIeS)o9y)iK0jfW4tQ4@tilRa|83=aC^{J47-(bVJ(GCgh9uXhGE1jXXdL)7&% zXPg20`poIm&cM>3TN8nUu(t>q88HVAI0M^-9Xp&MKj!XTvv;pE@Mr}OVySj?xWiJ( zueB2=^i+Ak^Mf57{nb6BQn;mroxRr3%f_5iC67~aer9gj0Z8sw)i$S=EV2Fl#=Y3D zRg@QeK(z~KU%trvBTT^ao z7;3N=fk3S}N!p~sK?~(k^pSv=>hHJR-R=dr`i_5Bt*tI_E?-XkN09|s`vX%AH1)Cb8WaEk002ovPDHLk FV1f&!$;JQx literal 0 HcmV?d00001 diff --git a/_static/images/new_2022.1.png b/_static/images/new_2022.1.png new file mode 100644 index 0000000000000000000000000000000000000000..fc043757cd3728088194fbb6951830f5bf7fcc0c GIT binary patch literal 2056 zcmV+j2>17iP)X1^@s6uYt=p00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGqB>(^xB>_oNB=7(L2c1boK~#8N?OaVx z<1iF<3P%A6q`5#A9H2;L#{pPm!G;C1n*+>_F4%OzVh+HLNb~?*^a3MMi5>-#dCz{& zdHHeT)ak%5`6R1p+800D@852tx3{-kN!*{Q$;+k67B_Tb#E20FTcxhA)I|LN{g~1{ zr7B9aRFlJ*id3w!%}V7*bbG{z5rAg>n3xyB{ZIG;Ao)>NAn;BHhllFm?4E9TV0#Z8 z0?px>ia>$?X)IwZXEX<&bxd2dk`P5$9-#rxlk256pqE&1*1>NVeVo90Hqdd~cmKijy~*EW`8*g;Zo`7|tH(ws$zGn~SGM+1#H1+<5?GuH%=<$I^vv!h4Xz5&mAOOH}o;a-U z@>(4@=@Uc0eozN4`q2JE={o^ycm^`NrnkWm-sp}L!Dv^Zsg0gScp}q0H2EudqE9~t zVPR_)lbRhv)7r9C-IYGH|4{mlCTMXDvxMb1#1lcY&o$2>PxPuHt*J1g^A;1E%vFX; zsK7Gy$&W_t2is@6ZrLwKHTCF5Wr?|rUS7=wgQJfwdTn_z3c1s-7NPxz(zgLT?BwK@ zJX``EZl$tQ{Yf~E&Q(r&fKi!IBF|7x{RZ{>MJ{%Is}3;f3q>tyKZN(-x~s_~h8*ClAh7>n`gYh5akT)!*S7}3k;=c(v5<_diXQ1X>qkfR3tZm(0BwAsx-rc=y|({LPj^(8ECU-?&ydR5zb``R_l0AM zR@N`5M8aM60todgwF1&BKO%vzZR$#J_y$Z`*w`FHAbmmLP!7D>cT$jANaq{M^#G3p z7ue-FWMbT;*noWgovsE3=7>DzRCv$7h0y*#nty~x2wC<-y)iB4M~#-Y3Kn<((3BGK zQp4jF2%#`GHm`(h?DBPj3_NL;s^4J?I+R5d`R8!W1A$5ekonQ=)o%HbH;Rz1WYsy8;{^GFLP1#)wcc-_P_7T`f>b@|o=_FQ zq4Fz)PjVmH|33NO13-xal19eOO1+cy@3XUv6I4pX8(Zac0EcuoToa)j?{RS`Xmh8+ zYkaEYbRX~)z$2jyuU(oA^XD7#e-#BfHaU+^v90WhIw!LQ3(Ai=H)0E=?X`KvkRhEW zr;Xy$UI&MCR1UWlo)1b+c?&^(^V<*E6}<$I=g6I_S@>4SzKQ}NFqZ`*?&RV1#Y8so zDJhYtdG8Kb6j_P7bHx7$&JmibY@HAx9hSPOY+c*y;E)c#BL+Mi3O+i=L0bsJ_Fus+ z0!VY@-d7{Y0*XtAzLEm@KqEs9aY5tO@R<{Z`B;CYxx-jwzk7~ zO)bG^aqD;{v@A*U(oy?On!od5!Nxu-N84R|`S8)!>_Nj8TG2-~hjGZyYP8~XJG9#RSh*^l;s$UI(UoL+0rCYtsM?0bO1*DV zmB*A@FyMVY$0Ib=(+mO}&o_l~3>&V%i1!sr!B|_zfk&F~G{Qc>xt7M-9X@wKpR7n# zmH@wWOGEPCG{vF)htgv>t*0FL9CUrL=t655&+B<0r3buSBK~7xsm$-kLEzH2kEvpf z81d=BdSZ^OVYOA1xIz24C}7X4jTkYagoghias1oQ=#55boezEA AS + SELECT * FROM ; + +After creating a table you can ingest data from an Avro file into SQream using the following syntax: + +.. code-block:: postgres + + avro_fdw [OPTIONS(option=value[,...])] + +Example +----------- +The following is an example of creating a table: + +.. code-block:: postgres + + CREATE TABLE nba AS + SELECT * FROM ext_nba; + +The following is an example of loading data from an Avro file into SQream: + +.. code-block:: postgres + + WRAPPER avro_fdw + OPTIONS + ( + LOCATION = 's3://sqream-demo-data/nba.avro' + ); + +For more examples, see :ref:`additional_examples`. + +Avro Data Types +=========== Avro includes the following data types: .. contents:: @@ -48,12 +90,6 @@ The following table shows the supported **Primitive** data types: | ``string`` | | Supported | Supported | | +-------------+-----------+---------------+-----------+--------------+ - - - - - - Complex Data Types -------------- The following table shows the supported **Complex** data types: @@ -76,8 +112,6 @@ The following table shows the supported **Complex** data types: | ``fixed`` | | | | | +------------+-----------+---------------+-----------+-----------+ - - Logical Data Types -------------- The following table shows the supported **Logical** data types: @@ -107,72 +141,20 @@ The following table shows the supported **Logical** data types: +----------------------------+-----------+---------------+-----------+---------+ | ``duration`` | | | | | +----------------------------+-----------+---------------+-----------+---------+ + +.. note:: Number types include **tinyint**, **smallint**, **int**, **bigint**, **real** and **float**, and **numeric**. String types include **text**. Mapping Objects to Rows =============== -When mapping objects to rows, each Avro object or message must contain one ``record`` type object corresponding to a single row in SQream. The ``record`` fields are associated by name to their target table columns. - -Additional unmapped fields will be ignored. Note that using the JSONPath option overrides this. +When mapping objects to rows, each Avro object or message must contain one ``record`` type object corresponding to a single row in SQream. The ``record`` fields are associated by name to their target table columns. Additional unmapped fields will be ignored. Note that using the JSONPath option overrides this. -Ingesting Avro Files +Best Practices ==================== -This section describes how to ingest Avro files into SQream and covers the following: - +This section describes the best practices when ingesting Avro files into SQream: .. contents:: :local: :depth: 1 - - -Preparing Your Avro Source File ----------- -Prepare your Avro source files according to the following requirements: - -* RFC 4180 standard CSV files, but can also be modified to support non-standard CSVs (with multi-character delimiters, unquoted fields, etc). - - :: - -* Files are encoded with UTF-8 or ASCII. - - :: - -* Field delimiter is an ASCII character or characters. - - :: - -* Record delimiter, also known as a new line separator, is a Unix-style newline (``\n``), DOS-style newline (``\r\n``), or Mac style newline (``\r``). - - :: - -* If a field is quoted, any double quote that appears must be double-quoted (similar to the :ref:`string literals quoting rules`. For example, to encode ``What are "birds"?``, the field should appear as ``"What are ""birds""?"``. - - :: - -* Fields can be enclosed by double-quotes (optional), or mandatory quotes if they contain one of the following characters: - - * The record delimiter or field delimiter. - - :: - - * A double quote character. - - :: - - * A newline. - -SQream does not support other modes of escaping, such as ``1,"What are \"birds\"?"``. - -``NULL`` values can be marked in the following ways in Avro files: - - * An explicit null marker. For example, ``col1,\N,col3``. - - :: - - * An empty field delimited by the field delimiter. For example, ``col1,,col3``. - - .. note:: If a text field is quoted but contains no content (``""``) it is considered an empty text field and not ``NULL``. - -For more information about standard CSV files, see `RFC 4180 standard CSVs `_. Making Avro Files Accessible to Workers --------------------- @@ -190,16 +172,16 @@ For more information about restricted worker access, see :ref:`workload_manager` Basing Your Table Structure on Inserted Tables --------------------- -Before loading data, you must build the ``CREATE EXTERNAL TABLE`` to correspond with the file structure of the inserted table. +Before loading data, you must build the ``CREATE FOREIGN TABLE`` to correspond with the file structure of the inserted table. -The example in this section is based on the source ``nba.parquet`` table shown below: +The example in this section is based on the source ``nba.avro`` table shown below: -.. csv-table:: nba.parquet +.. csv-table:: nba.avro :file: nba-t10.csv :widths: auto :header-rows: 1 -The following example shows the correct file structure used to create the ``CREATE EXTERNAL TABLE`` statement based on the **nba.parquet** table: +The following example shows the correct file structure used to create the ``CREATE FOREIGN TABLE`` statement based on the **nba.avro** table: .. code-block:: postgres @@ -216,23 +198,23 @@ The following example shows the correct file structure used to create the ``CREA College TEXT(40), Salary FLOAT ) - WRAPPER parquet_fdw + WRAPPER avro_fdw OPTIONS ( - LOCATION = 's3://sqream-demo-data/nba.parquet' + LOCATION = 's3://sqream-demo-data/nba.avro' ); .. tip:: An exact match must exist between the SQream and Avro types. For unsupported column types, you can set the type to any type and exclude it from subsequent queries. -.. note:: The **nba.parquet** file is stored on S3 at ``s3://sqream-demo-data/nba.parquet``. +.. note:: The **nba.avro** file is stored on S3 at ``s3://sqream-demo-data/nba.avro``. Verifying Your Table Output --------------------- Because external tables do not automatically verify the file integrity or structure, you must manually verify that the table output is identical to the original inserted table. -The following is an example of the output based on the **nba.parquet** table: +The following is an example of the output based on the **nba.avro** table: .. code-block:: psql @@ -252,38 +234,18 @@ The following is an example of the output based on the **nba.parquet** table: .. note:: If your table output has errors, verify that the structure of the Avro files correctly corresponds to the external table structure that you created. -Loading Data into SQream ---------------------- +.. _additional_examples: -Syntax -~~~~~~~~~~~~~~~~~~~~~ -The following is the correct syntax for loading data into SQream: - -.. code-block:: postgres - - CREATE TABLE
AS - SELECT * FROM ; - -The following is an example of loading data into SQream: - -.. code-block:: postgres - - CREATE TABLE nba AS - SELECT * FROM ext_nba; - -For more information about the **CREATE TABLE AS** statement, see :ref:`create_table_as`. - -Examples -~~~~~~~~~~~~~~~~~~~~~ - -This section includes the following examples of loading data into SQream: +Additional Examples +=============== +This section includes the following additional examples of loading data into SQream: .. contents:: :local: :depth: 1 Omitting Unsupported Column Types -********************** +-------------- When loading data, you can omit columns using the ``NULL as`` argument. You can use this argument to omit unsupported columns from queries that access external tables. By omitting them, these columns will not be called and will avoid generating a "type mismatch" error. In the example below, the ``Position`` column is not supported due its type. @@ -291,11 +253,10 @@ In the example below, the ``Position`` column is not supported due its type. .. code-block:: postgres CREATE TABLE nba AS - SELECT Name, Team, Number, NULL as Position, Age, Height, Weight, College, Salary FROM ext_nba; - + SELECT Name, Team, Number, NULL as Position, Age, Height, Weight, College, Salary FROM ext_nba; Modifying Data Before Loading -********************** +-------------- One of the main reasons for staging data using the ``EXTERNAL TABLE`` argument is to examine and modify table contents before loading it into SQream. For example, we can replace pounds with kilograms using the :ref:`create_table_as` statement @@ -309,19 +270,18 @@ In the example below, the ``Position`` column is set to the default ``NULL``. FROM ext_nba ORDER BY weight; - Loading a Table from a Directory of Avro Files on HDFS -********************** +-------------- The following is an example of loading a table from a directory of Avro files on HDFS: .. code-block:: postgres CREATE FOREIGN TABLE ext_users (id INT NOT NULL, name TEXT(30) NOT NULL, email TEXT(50) NOT NULL) - WRAPPER parquet_fdw + WRAPPER avro_fdw OPTIONS ( - LOCATION = 'hdfs://hadoop-nn.piedpiper.com/rhendricks/users/*.parquet' + LOCATION = 'hdfs://hadoop-nn.piedpiper.com/rhendricks/users/*.avro' ); CREATE TABLE users AS SELECT * FROM ext_users; @@ -329,16 +289,16 @@ The following is an example of loading a table from a directory of Avro files on For more configuration option examples, see the `CREATE FOREIGN TABLE parameters `_. Loading a Table from a Directory of Avro Files on S3 -********************** +-------------- The following is an example of loading a table from a directory of Avro files on S3: .. code-block:: postgres CREATE FOREIGN TABLE ext_users (id INT NOT NULL, name TEXT(30) NOT NULL, email TEXT(50) NOT NULL) - WRAPPER parquet_fdw + WRAPPER avro_fdw OPTIONS - ( LOCATION = 's3://pp-secret-bucket/users/*.parquet', + ( LOCATION = 's3://pp-secret-bucket/users/*.avro', AWS_ID = 'our_aws_id', AWS_SECRET = 'our_aws_secret' ); diff --git a/feature_guides/data_encryption.rst b/feature_guides/data_encryption.rst index 4e51a28aa..e5b30c94a 100644 --- a/feature_guides/data_encryption.rst +++ b/feature_guides/data_encryption.rst @@ -4,8 +4,12 @@ Data Encryption *********************** -The **Data Encryption** page describes the following: +The **Data Encryption** page |icon-new_2022.1| describes the following: +.. |icon-new_2022.1| image:: /_static/images/new_2022.1.png + :align: middle + :width: 110 + .. toctree:: :maxdepth: 1 :titlesonly: diff --git a/reference/sql/sql_statements/dml_commands/update.rst b/reference/sql/sql_statements/dml_commands/update.rst index 143363b3b..82262d884 100644 --- a/reference/sql/sql_statements/dml_commands/update.rst +++ b/reference/sql/sql_statements/dml_commands/update.rst @@ -3,8 +3,11 @@ ********************** UPDATE ********************** +The **UPDATE** statement page |icon-new_2022.1| describes the following: -The **UPDATE** statement page describes the following: +.. |icon-new_2022.1| image:: /_static/images/new_2022.1.png + :align: middle + :width: 110 .. contents:: :local: @@ -12,7 +15,7 @@ The **UPDATE** statement page describes the following: Overview ========== -The ``UPDATE`` command is used to modify the value of certain columns in existing rows without creating a table. +The ``UPDATE`` statement is used to modify the value of certain columns in existing rows without creating a table. It can be used to do the following: @@ -20,6 +23,8 @@ It can be used to do the following: * Setting columns based on the values of others. +The ``UPDATE`` statement cannot be used to reference other tables in the ``WHERE`` or ``SET`` clauses. + Syntax ========== The following is the correct syntax for the ``UPDATE`` command: From f9cd06dfe305ce662960b59f3858208641f8e19c Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 19 May 2022 16:12:34 +0300 Subject: [PATCH 064/316] Encryption, Update, Avro Published the 2022.1 features and updated the respective pages on the private 2022.1 branch to show Product team. --- releases/2022.1.rst | 42 ++++++++---------------------------------- 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/releases/2022.1.rst b/releases/2022.1.rst index 51a7333cc..b1b6a61ae 100644 --- a/releases/2022.1.rst +++ b/releases/2022.1.rst @@ -13,10 +13,9 @@ Version Content ---------- The 2022.1 Release Notes describes the following: -* Example - Major feature release targeted for all on-premises customers. -* Example - Basic Cloud functionality. - -**Comment** - *This will be done at the end.* +* Enhanced security features. +* New data manipulation command. +* Additional data ingestion format. New Features ---------- @@ -32,6 +31,8 @@ SQream now supports data encryption mechanisms in accordance with **General Data For more information, see `Data Encryption `_. +**Comment** - *Information regarding performance degradation, pending.* + Update Feature ************ SQream now supports the DML **Update** feature, which is used for modifying the value of certain columns in existing rows without creating a table. @@ -44,18 +45,9 @@ SQream now supports ingesting data from Avro files. For more information, see `Inserting Data from Avro `_. -Main Features --------- -The following list describes the main features: - -* Main feature -* Main feature - -**Comment** - *This will be done at the end.* - Resolved Issues --------- -The following table lists the issues that were resolved in Version 2021.2: +The following table lists the issues that were resolved in Version 2022.1: .. list-table:: :widths: 17 200 @@ -70,36 +62,18 @@ The following table lists the issues that were resolved in Version 2021.2: * - SQ-xxxx - Text -**Comment** - *I will be updated regarding which resolved issues to include.* +**Comment** - *The table above will be updated regarding which resolved issues to include.* Operations and Configuration Changes -------- -**Comment** - *TBD* - - -Subject -************ -Text - - - - -Subject -************ -Text - - +No relevant operations and configuration changes were made. Naming Changes ------- -**Comment** - *TBD* - No relevant naming changes were made. Deprecated Features ------- -**Comment** - *TBD* - No features were depecrated. Known Issues and Limitations From 0bb07df6dc07046aeb3d5f5ca8dd8bc2e73b3366 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 19 May 2022 16:21:29 +0300 Subject: [PATCH 065/316] Added date Needs to be updated on release date --- feature_guides/data_encryption.rst | 1 - releases/index.rst | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/feature_guides/data_encryption.rst b/feature_guides/data_encryption.rst index e5b30c94a..82e1bf657 100644 --- a/feature_guides/data_encryption.rst +++ b/feature_guides/data_encryption.rst @@ -3,7 +3,6 @@ *********************** Data Encryption *********************** - The **Data Encryption** page |icon-new_2022.1| describes the following: .. |icon-new_2022.1| image:: /_static/images/new_2022.1.png diff --git a/releases/index.rst b/releases/index.rst index d06a7a8bf..e23036f7a 100644 --- a/releases/index.rst +++ b/releases/index.rst @@ -13,7 +13,7 @@ Release Notes * - Version - Release Date * - :ref:`2022.1` - - April 17, 2022 + - MM DD, YYYY * - :ref:`2021.2` - September 13, 2021 * - :ref:`2021.1` From b65615c5287cef86975ff8d2f2c605f099777f42 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 22 May 2022 14:25:50 +0300 Subject: [PATCH 066/316] Replaced missed instances of VARCHAR with TEXT --- data_type_guides/converting_and_casting_types.rst | 2 +- .../utility_commands/execute_saved_query.rst | 14 +++++++------- .../utility_commands/show_node_info.rst | 2 +- ...tements_and_running_queries_from_the_editor.rst | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/data_type_guides/converting_and_casting_types.rst b/data_type_guides/converting_and_casting_types.rst index bb6475646..44579a068 100644 --- a/data_type_guides/converting_and_casting_types.rst +++ b/data_type_guides/converting_and_casting_types.rst @@ -15,7 +15,7 @@ You can rectify this by casting the value to a larger data type, as shown below: SQream supports the following three data conversion types: -* ``CAST( TO )``, to convert a value from one type to another. For example, ``CAST('1997-01-01' TO DATE)``, ``CAST(3.45 TO SMALLINT)``, ``CAST(some_column TO VARCHAR(30))``. +* ``CAST( TO )``, to convert a value from one type to another. For example, ``CAST('1997-01-01' TO DATE)``, ``CAST(3.45 TO SMALLINT)``, ``CAST(some_column TO TEXT(30))``. :: diff --git a/reference/sql/sql_statements/utility_commands/execute_saved_query.rst b/reference/sql/sql_statements/utility_commands/execute_saved_query.rst index 6fe41fa08..39675d47f 100644 --- a/reference/sql/sql_statements/utility_commands/execute_saved_query.rst +++ b/reference/sql/sql_statements/utility_commands/execute_saved_query.rst @@ -8,7 +8,7 @@ EXECUTE_SAVED_QUERY Read more in the :ref:`saved_queries` guide. -See also: ref:`save_query`, :ref:`drop_saved_query`, ref:`show_saved_query`, ref:`list_saved_queries`. +See also: :ref:`save_query`, :ref:`drop_saved_query`, :ref:`show_saved_query`, :ref:`list_saved_queries`. Permissions ============= @@ -53,7 +53,7 @@ Notes * Query parameters can be used as substitutes for literal expressions. Parameters cannot be used to substitute identifiers, column names, table names, or other parts of the query. -* Query parameters of a string datatype (like ``VARCHAR``) must be of a fixed length, and can be used in equality checks, but not patterns (e.g. :ref:`like`, :ref:`rlike`, etc) +* Query parameters of a string datatype (like ``text``) must be of a fixed length, and can be used in equality checks, but not patterns (e.g. :ref:`like`, :ref:`rlike`, etc) * Query parameters' types are inferred at compile time. @@ -66,14 +66,14 @@ Assume a table named ``nba``, with the following structure: CREATE TABLE nba ( - Name varchar(40), - Team varchar(40), + Name text(40), + Team text(40), Number tinyint, - Position varchar(2), + Position text(2), Age tinyint, - Height varchar(4), + Height text(4), Weight real, - College varchar(40), + College text(40), Salary float ); diff --git a/reference/sql/sql_statements/utility_commands/show_node_info.rst b/reference/sql/sql_statements/utility_commands/show_node_info.rst index 345d16440..9c1e1ec11 100644 --- a/reference/sql/sql_statements/utility_commands/show_node_info.rst +++ b/reference/sql/sql_statements/utility_commands/show_node_info.rst @@ -108,7 +108,7 @@ This is a full list of node types: - Compress data with both CPU and GPU schemes * - ``CpuDecompress`` - CPU - - Decompression operation, common for longer ``VARCHAR`` types + - Decompression operation, common for longer ``TEXT`` types * - ``CpuLoopJoin`` - CPU - A non-indexed nested loop join, performed on the CPU diff --git a/sqream_studio_5.4.3/executing_statements_and_running_queries_from_the_editor.rst b/sqream_studio_5.4.3/executing_statements_and_running_queries_from_the_editor.rst index 8fa91d945..e1b6765eb 100644 --- a/sqream_studio_5.4.3/executing_statements_and_running_queries_from_the_editor.rst +++ b/sqream_studio_5.4.3/executing_statements_and_running_queries_from_the_editor.rst @@ -223,7 +223,7 @@ The following table describes the DDL Optimizer screen: * - Column area - Shows the column **names** and **column types** from the selected table. You can scroll down or to the right/left for long column lists. * - Optimization area - - Shows the number of rows to sample as the basis for running an optimization, the default setting (1,000,000) when running an optimization (this is also the overhead threshold used when analyzing ``VARCHAR`` fields), and the default percent buffer to add to ``VARCHAR`` lengths (10%). Attempts to determine field nullability. + - Shows the number of rows to sample as the basis for running an optimization, the default setting (1,000,000) when running an optimization (this is also the overhead threshold used when analyzing ``TEXT`` fields), and the default percent buffer to add to ``TEXT`` lengths (10%). Attempts to determine field nullability. * - Run Optimizer - Starts the optimization process. From 89e6037be32c759df3487a23fe2af2fc09490b9e Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 22 May 2022 16:06:18 +0300 Subject: [PATCH 067/316] Fixed broken links. --- configuration_guides/current_configuration_method.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configuration_guides/current_configuration_method.rst b/configuration_guides/current_configuration_method.rst index e7ca5c0d3..078e2dac2 100644 --- a/configuration_guides/current_configuration_method.rst +++ b/configuration_guides/current_configuration_method.rst @@ -704,8 +704,8 @@ Configuration Roles =========== SQream divides flags into the following roles, each with their own set of permissions: -* **`Administration flags `_**: can be modified by administrators on a session and cluster basis using the ``ALTER SYSTEM SET`` command. -* **`Generic flags `_**: can be modified by standard users on a session basis. +* `Administration flags `_: can be modified by administrators on a session and cluster basis using the ``ALTER SYSTEM SET`` command. +* `Generic flags `_: can be modified by standard users on a session basis. Showing All Flags in the Catalog Table ======= From 842860c092fce79c3df27f875cddee91b45a8f80 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 22 May 2022 17:02:43 +0300 Subject: [PATCH 068/316] Update 2022.1.rst --- releases/2022.1.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/releases/2022.1.rst b/releases/2022.1.rst index b1b6a61ae..9a2de884e 100644 --- a/releases/2022.1.rst +++ b/releases/2022.1.rst @@ -35,7 +35,7 @@ For more information, see `Data Encryption `_. @@ -87,8 +87,7 @@ The the list below describes the following known issues and limitations: End of Support ------- -**Comment** - *TBD* - +This section is not relevant to the 2022.1 release notes. Upgrading to v2022.1 ------- From 1fa25d21a222683e65d8d352c691290fbd57cfa4 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 22 May 2022 17:12:48 +0300 Subject: [PATCH 069/316] Updated .Net Driver Link --- third_party_tools/client_drivers/index.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/third_party_tools/client_drivers/index.rst b/third_party_tools/client_drivers/index.rst index d52b41e95..91cb94e8f 100644 --- a/third_party_tools/client_drivers/index.rst +++ b/third_party_tools/client_drivers/index.rst @@ -44,8 +44,7 @@ The following are applicable to Windows: For more information on installing and configuring ODBC on Windows, see :ref:`Install and configure ODBC on Windows `. - -* **Net driver** - `SQream .Net driver v3.0.2 `_ +* **Net driver** - `SQream .Net driver v3.0.2 `_ From 2a4ae2eef990dfd1e7b3c6dfa88ff2b25e5d97d3 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 24 May 2022 10:34:50 +0300 Subject: [PATCH 070/316] Updated --- .../sql_statements/dml_commands/update.rst | 104 +----------------- 1 file changed, 4 insertions(+), 100 deletions(-) diff --git a/reference/sql/sql_statements/dml_commands/update.rst b/reference/sql/sql_statements/dml_commands/update.rst index 82262d884..19881d62c 100644 --- a/reference/sql/sql_statements/dml_commands/update.rst +++ b/reference/sql/sql_statements/dml_commands/update.rst @@ -3,7 +3,7 @@ ********************** UPDATE ********************** -The **UPDATE** statement page |icon-new_2022.1| describes the following: +The **UPDATE** statement page |icon-new_2022.1| describes the following: .. |icon-new_2022.1| image:: /_static/images/new_2022.1.png :align: middle @@ -15,7 +15,7 @@ The **UPDATE** statement page |icon-new_2022.1| describes the following: Overview ========== -The ``UPDATE`` statement is used to modify the value of certain columns in existing rows without creating a table. +The ``UPDATE`` command is used to modify the value of certain columns in existing rows without creating a table. It can be used to do the following: @@ -23,8 +23,6 @@ It can be used to do the following: * Setting columns based on the values of others. -The ``UPDATE`` statement cannot be used to reference other tables in the ``WHERE`` or ``SET`` clauses. - Syntax ========== The following is the correct syntax for the ``UPDATE`` command: @@ -33,7 +31,6 @@ The following is the correct syntax for the ``UPDATE`` command: UPDATE target_table_name [[AS] alias1] SET column_name = expression [,...] - [FROM additional_table_name [[AS] alias2][,...]] [WHERE condition] The following is the correct syntax for triggering a clean-up: @@ -74,30 +71,6 @@ The **Examples** section includes the following examples: :local: :depth: 1 -Updating an Entire Table ------------------ -The Examples section shows how to modify the value of certain columns in existing rows without creating a table. The examples are based on the following tables: - -.. image:: /_static/images/delete_optimization.png - -The following methods for updating an entire table generate the same output, and result with the ``bands`` record set to ``NULL``: - -.. code-block:: postgres - - UPDATE bands SET records_sold = 0; - -.. code-block:: postgres - - UPDATE bands SET records_sold = 0 WHERE true; - -.. code-block:: postgres - - UPDATE bands SET records_sold = 0 USING countries; - -.. code-block:: postgres - - UPDATE bands SET records_sold = 0 USING countries WHERE 1=1; - Performing Simple Updates ----------------- The following is an example of performing a simple update: @@ -106,72 +79,6 @@ The following is an example of performing a simple update: UPDATE bands SET records_sold = records_sold + 1 WHERE name LIKE 'The %'; -Updating Tables that Contain Multi-Table Conditions ------------------ -The following shows an example of updating tables that contain multi-table conditions: - -.. code-block:: postgres - - UPDATE bands - SET records_sold = records_sold + 1 - WHERE EXISTS ( - SELECT 1 FROM countries - WHERE countries.id=bands.country_id - AND country.name = 'Sweden' - ); - -You can also write the statement above using the FROM clause: - -.. code-block:: psql - - UPDATE bands - SET records_sold = records_sold + 1 - FROM countries - WHERE countries.id=bands.country_id AND country.name = 'Sweden'; - -Updating Tables that Contain Multi-Table Expressions ------------------ -The following shows an example of updating tables that contain multi-table expressions: - -.. code-block:: postgres - - UPDATE bands - SET records_sold = records_sold + - CASE - WHEN c.name = 'Israel' THEN 2 - ELSE 1 - END - FROM countries c - -Configuring Update Behavior ------------------ -The ``failOnNondeterministicUpdate`` flag is used to configure ``UPDATE`` behavior when updating tables containing multi-table expressions. This flag is needed when you use the ``FROM`` clause along with a set expression containing columns from additional tables. Doing this can cause a match to occur between a row from the target table with multiple rows from the additional tables. - -**Note to self** - *Check if the Studio documentation must be updated for this flag.* - -For instance, the example in the previous section sets the records sold to ``2`` when the country name is Israel. If you were to insert a new entry into this table with Israel spelled in Hebrew (using the same country ID), you would have two rows with identical country ID's. - -When this happens, both rows 5 and 6 in the ``bands`` table match both Israel entries. Because no algorithm exists for determining which entry to use, updating this table may either increase ``records_sold`` by 2 (for Israel in English) or 1 (for Israel in Hebrew). - -You must set the ``failOnNondeterministicUpdate`` flag to ``FALSE`` to prevent an error from occuring. - -**Comment** - *Does the system actually choose one, or does it generate an error?* - -Note that a similar ambiguity can occur when the Hebrew spelling is used in the following example: - -.. code-block:: postgres - - UPDATE bands - SET record_count = record_count + 1 - FROM countries c - WHERE c.name = 'Israel' - -However, the ``WHERE`` clause above prevents a match with any entry other than the defined one. Because the target table row must match with the ``WHERE`` condition at least once to be included in the UPDATE statment, this scenario does not require configuring the ``failOnNondeterministicUpdate`` flag. - -**Comment** - *Please review the paragraph above. I'm pretty sure I described this correctly.* - -For more information, see `SQream Acceleration Studio `_. - Identifying and Cleaning Up Tables --------------------------------------- **Comment** - *I copied and pasted this entire section from "DELETE". Does anything have to adjusted here for "UPDATE"?* @@ -240,11 +147,8 @@ The following shows an example of triggering a clean-up: Permissions ============= -Executing an ``UPDATE`` statement requires the following permissions: - -* Both ``UPDATE`` and ``SELECT`` permissions on the target table. -* The ``SELECT`` permission for each additional table you reference in the statement (in ither the ``FROM`` clause or ``WHERE`` subquery section). +Executing an ``UPDATE`` statement requires both ``UPDATE`` and ``SELECT`` permissions on the target table. Locking and Concurrency ============= -Executing the ``UPDATE`` statement obtains an exclusive UPDATE lock on the target table, but does not lock the destination tables. \ No newline at end of file +Executing the ``UPDATE`` statement obtains an exclusive UPDATE lock on the target table. \ No newline at end of file From 0be3b83caec8bdc6ac8f569104f3fafdfd1a4257 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 24 May 2022 12:18:54 +0300 Subject: [PATCH 071/316] Updated Encryption Pages based on Inon/Maya Meeting --- feature_guides/data_encryption.rst | 2 - feature_guides/data_encryption_methods.rst | 14 +-- feature_guides/data_encryption_overview.rst | 8 +- .../data_encryption_permissions.rst | 16 ---- feature_guides/data_encryption_process.rst | 88 ------------------- feature_guides/data_encryption_syntax.rst | 56 +++--------- feature_guides/data_encryption_types.rst | 6 +- 7 files changed, 26 insertions(+), 164 deletions(-) delete mode 100644 feature_guides/data_encryption_permissions.rst delete mode 100644 feature_guides/data_encryption_process.rst diff --git a/feature_guides/data_encryption.rst b/feature_guides/data_encryption.rst index 82e1bf657..dbc6152ed 100644 --- a/feature_guides/data_encryption.rst +++ b/feature_guides/data_encryption.rst @@ -16,6 +16,4 @@ The **Data Encryption** page |icon-new_2022.1| describes the following: data_encryption_overview data_encryption_methods data_encryption_types - data_encryption_process - data_encryption_permissions data_encryption_syntax \ No newline at end of file diff --git a/feature_guides/data_encryption_methods.rst b/feature_guides/data_encryption_methods.rst index 0069b161c..dc6e7c122 100644 --- a/feature_guides/data_encryption_methods.rst +++ b/feature_guides/data_encryption_methods.rst @@ -3,7 +3,7 @@ *********************** Encryption Methods *********************** -The **Encryption Methods** section describes the following: +Data exists in one of following states and determines the encryption method: .. contents:: :local: @@ -11,16 +11,10 @@ The **Encryption Methods** section describes the following: Encrypting Data in Transit ---------------- -**In-transit data** refers to data files inserted from customer repositories using the COPY FROM command, and is transmitted to SQream over a TLS-encrypted channel using a JDBC or ODBC connection. +**Data in transit** refers to data you use on a regular basis, usually stored on a database and accessed through applications or programs. This data is typically transferred between several physical or remote locations through email or uploading documents to the cloud. This type of data must therefore be protected while **in transit**. SQream encrypts data in transit using SSL when, for example, users insert data files from external repositories over a JDBC or ODBC connection. -For more information, see the following: - -* :ref:`copy_from` -* `JDBC `_ -* :ref:`odbc` +For more information, see :ref:`installing_nginx_proxy_over_secure_connection`. Encrypting Data at Rest ---------------- -For **data at rest,** housed physically on computer data, you can encrypt one or more column as needed according to your specifications. Data at rest is encrypted before being written into files, and decrypted after being read from them. All existing unencrypted historical and data inserted into this column at a later time is encrypted for the specified column values. Data at rest is encrypted (**Comment** - *And decrypted?*) using the **AES-256** algorithm. - -**Comment** - *Because the encryption keys are hidden from users, I didn't document them here. Please confirm that this is correct.* \ No newline at end of file +**Data at rest** refers to data stored on your hard drive or on the cloud. Because this data can be potentially intercepted **physically**, it requires a form of encryption that protects your data wherever you store it. SQream faciliates encryption by letting you encrypt any columns located in your database that you want to keep private. \ No newline at end of file diff --git a/feature_guides/data_encryption_overview.rst b/feature_guides/data_encryption_overview.rst index 4c0455291..58bb7ea40 100644 --- a/feature_guides/data_encryption_overview.rst +++ b/feature_guides/data_encryption_overview.rst @@ -3,7 +3,11 @@ *********************** Overview *********************** -**Data Encryption** helps protect sensitive data by preventing unauthorized users from reading it in the event of a breach. This is achieved by scrambling the content into an unreadable format based on encryption and decryption keys. The demand for confidentiality has steadily increased to protect the growing volumes of private data stored on computer systems and transmitted over the internet. To this end, regulatory bodies such as the **General Data Protection Regulation (GDPR)** have produced requirements to standardize and enforce compliance aimed at protecting customer data. +**Data Encryption** helps protect sensitive data at rest by concealing it from unauthorized users in the event of a breach. This is achieved by scrambling the content into an unreadable format based on encryption and decryption keys. Typically speaking, this data pertains to **PII (Personally Identifiable Information)**, which is sensitive information such as credit card numbers and other information related to an identifiable person. + +Users encrypt their data on a column basis by specifying ``column_name`` in the encryption syntax. + +The demand for confidentiality has steadily increased to protect the growing volumes of private data stored on computer systems and transmitted over the internet. To this end, regulatory bodies such as the **General Data Protection Regulation (GDPR)** have produced requirements to standardize and enforce compliance aimed at protecting customer data. Encryption can be used for the following: @@ -25,4 +29,6 @@ Encryption can be used for the following: * Selecting data from an encrypted column. +For more information on the encryption syntax, see :ref:`data_encryption_syntax`. + For more information on GDPR compliance requirements, see the `GDPR checklist `_. \ No newline at end of file diff --git a/feature_guides/data_encryption_permissions.rst b/feature_guides/data_encryption_permissions.rst deleted file mode 100644 index d9a132b45..000000000 --- a/feature_guides/data_encryption_permissions.rst +++ /dev/null @@ -1,16 +0,0 @@ -.. _data_encryption_permissions: - -*********************** -Permissions -*********************** -The **Permissions** page tells you how to create a table with encrypted columns as a superuser. - -Users with the appropriate encryption permission privilege's can encrypt and decrypt data. In addition, only superusers granted permission can view encrypted tables in the **sqream_catalog**. - -You can create a table with encrypted columns as a superuser as follows: - -.. code-block:: console - - $ create or replace table t_enc(c1 int encrypt); - -For more information about the SQream catalog, see the :ref:`catalog_reference`. \ No newline at end of file diff --git a/feature_guides/data_encryption_process.rst b/feature_guides/data_encryption_process.rst deleted file mode 100644 index e76e6a9cc..000000000 --- a/feature_guides/data_encryption_process.rst +++ /dev/null @@ -1,88 +0,0 @@ -.. _data_encryption_process: - -*********************** -Data Encryption Process -*********************** -The **Data Encryption Process** page describes end-to-end encryption process, and describes the following: - -.. contents:: - :local: - :depth: 1 - -The Encryption Process ----------------- -The following describes the encryption process: - -1. A user with the required encryption execution permission accesses the system. - - :: - -#. In the file to be uploaded, the user selects columns to encrypt. The syntax will (**Comment** - *"should" instead of "will"?)* includes the hint that triggers the encryption (see syntax section). - - :: - -#. The user provides the location of the master key for deriving (**Comment** - *...generating/activating?*) the encryption in the remote repository. This applies to both **KMS** and **IBM SKLM**. - - :: - - **Comment** - *The source doc says, "this section will not be applied in the MVP scope." Should it stay in this doc?* - - :: - -#. The user trigger (**Comment** - *"runs"?*) the COPY command to transport the data upon TLS session (not yet data at rest encryption) (**Comment** - *"Upon TLS session = when the TLS session is activated?"* - - :: - -#. When the data is successfully inserted into the SQream database, it is encrypted and saved. - -For more information, see the following: - -* More information on permissions, see :ref:`data_encryption_permissions`. - - :: - -* More information on which columns to encrypt, see the :ref:`Constraints` section below. - - :: - -* More information on triggering the encryption, and the master key location syntax, see :ref:`data_encryption_syntax`. - -The Decryption Process ----------------- -The following describes the encryption process: - -1. A user with the required encryption execution permission accesses the system. - - :: - -#. The user indicates the decryption. **Comment** - *"Indicates" = "triggers"?*) - - :: - -#. The user can view the data derived from a table holding the encrypted data by decrypting the data by providing the location of the master key and selecting the required fields. - - :: - - **Comment** - *the source doc said, "this section will not be applied in the MVP scope." Should it stay in this doc?* - -#. When the statement has ended, the user can view the data in a human readable format as plain text. - -For more information on triggering the decryption, see :ref:`data_encryption_syntax`. - -Encrypted Columns ----------------- -**Comment** - *This section and "Constraints" don't really seem like phases in a flow, at least the way they are currently described. If they really are part of a flow, we should discuss how to reword them.* - -Tables with encrypted columns are tagged with the ``encrypted`` label, allowing you to select what data to encrypt. - -.. _constraints: - -Constraints ----------------- -The encryption will be done in the database server- data at rest as the data will be encrypted in transit based on the TLS protocol. - -**Comment** - *I need some clarification on the sentence above.* - -Users without permissions to view tables with one or more encrypted table cannot view the entire table. - -**Comment** - *Please confirm that the above sentence is correct. Below is the original sentence:"* \ No newline at end of file diff --git a/feature_guides/data_encryption_syntax.rst b/feature_guides/data_encryption_syntax.rst index 85cef25ee..a7cb3e68d 100644 --- a/feature_guides/data_encryption_syntax.rst +++ b/feature_guides/data_encryption_syntax.rst @@ -3,55 +3,23 @@ *********************** Syntax *********************** -The **Syntax** page describes the following: - -.. contents:: - :local: - :depth: 1 - -Encrypting a New Table ----------------- -The following is the correct syntax for **encrypting** a new table: +The following is the syntax for encrypting a new table: .. code-block:: console - CREATE TABLE client_name ( - first_name TEXT(128), - last_name TEXT(128), - salary INT(6) ENCRYPT); + CREATE TABLE ( + <(maximum string length)>, + + last_name <(maximum string length)>, + salary (<(maximum string length)>) ENCRYPT); The following is an example of encrypting a new table: .. code-block:: console - EXAMPLE - -**Comment** - *Please provide an actual example.* - -Decrypting a New Table ----------------- -The following is the correct syntax for **decrypting** a new table: - -.. code-block:: console - - SELECT * FROM TABLE; - -The following is an example of decrypting a new table: - -.. code-block:: console - - EXAMPLE - -**Comment** - *Please provide an actual example.* - -Incorrectly Encrypting or Decrypting Your Data ----------------- -Using the incorrect master key or location while encrypting or decrypting generates an error. - -**Comment** - *Can I get an example of this error to include in the doc?* - -**Comment** - *I thought that the master key was completely hidden from users... The internal doc says, "Master Key- the key will be generated within the server side, it will reside within a repository which will be hidden from the user."* - -In logs, master keys are masked to protect user privacy. Users are responsible for maintaining their master keys for the remote repository. - -**Comment** - *I'm not sure I fully understand the part about maintaing the master keys on the remote repository.* \ No newline at end of file + CREATE TABLE client_name ( + first_name TEXT(128), + last_name TEXT(128), + salary INT(6) ENCRYPT); + +.. note:: Users without permissions cannot view the entire table as long as at least one column is encrypted. The (unique) encryption/decryption key is relevant only at the system level and is not held by users. \ No newline at end of file diff --git a/feature_guides/data_encryption_types.rst b/feature_guides/data_encryption_types.rst index 3da9071c2..ad6d96dc3 100644 --- a/feature_guides/data_encryption_types.rst +++ b/feature_guides/data_encryption_types.rst @@ -3,12 +3,12 @@ *********************** Data Types *********************** -SQream's data encryption supports the following data types: +Typically speaking, sensitive pertains to **PII (Personally Identifiable Information)**, which is sensitive information such as credit card numbers and other information related to an identifiable person. + +SQream's data encryption feature supports encrypting column-based data belonging to the following data types: * INT * BIGINT * TEXT -Typically speaking, this data pertains to **PII (Personally Identifiable Information)**, which is sensitive information such as credit card numbers and other information related to an identifiable person. - For more information on the above data types, see :ref:`supported_data_types`. \ No newline at end of file From f312568993019bb8eaecdf772fccbfb5dff60566 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 24 May 2022 18:43:11 +0300 Subject: [PATCH 072/316] Updated Updated according to comments by: Avro: Ben Esh, Maya Faibish Update: Maayan Kurz Data Encryption: Inon Maman, Alex Karpov --- data_ingestion/avro.rst | 238 +++++++++++------- feature_guides/data_encryption_methods.rst | 2 +- feature_guides/flexible_data_clustering.rst | 16 -- .../flexible_data_clustering_chunks.rst | 18 -- ...ata_clustering_data_clustering_methods.rst | 180 ------------- ...flexible_data_clustering_data_examples.rst | 22 -- ...e_data_clustering_data_rechunking_data.rst | 11 - .../flexible_data_clustering_overview.rst | 16 -- feature_guides/index.rst | 1 - .../sql_statements/dml_commands/update.rst | 73 +----- releases/2022.1.rst | 38 ++- 11 files changed, 199 insertions(+), 416 deletions(-) delete mode 100644 feature_guides/flexible_data_clustering.rst delete mode 100644 feature_guides/flexible_data_clustering_chunks.rst delete mode 100644 feature_guides/flexible_data_clustering_data_clustering_methods.rst delete mode 100644 feature_guides/flexible_data_clustering_data_examples.rst delete mode 100644 feature_guides/flexible_data_clustering_data_rechunking_data.rst delete mode 100644 feature_guides/flexible_data_clustering_overview.rst diff --git a/data_ingestion/avro.rst b/data_ingestion/avro.rst index 776d44bba..e943fe41c 100644 --- a/data_ingestion/avro.rst +++ b/data_ingestion/avro.rst @@ -17,48 +17,113 @@ Overview =========== **Avro** is a well-known data serialization system that relies on schemas. Due to its flexibility as an efficient data storage method, SQream supports the Avro binary data format as an alternative to JSON. Avro files are represented using the **Object Container File** format, in which the Avro schema is encoded alongside binary data. Multiple files loaded in the same transaction are serialized using the same schema. If they are not serialized using the same schema, an error message is displayed. SQream uses the **.avro** extension for ingested Avro files. -Loading Data into SQream -=========== +Making Avro Files Accessible to Workers +================ +To give workers access to files every node must have the same view of the storage being used. -Syntax ------------ -Before ingesting data into SQream from an Avro file, you must create a table using the following syntax: +The following apply for Avro files to be accessible to workers: -.. code-block:: postgres - - CREATE TABLE
AS - SELECT * FROM ; - -After creating a table you can ingest data from an Avro file into SQream using the following syntax: +* For files hosted on NFS, ensure that the mount is accessible from all servers. -.. code-block:: postgres +* For HDFS, ensure that SQream servers have access to the HDFS name node with the correct **user-id**. For more information, see :ref:`hdfs`. + +* For S3, ensure network access to the S3 endpoint. For more information, see :ref:`s3`. + +For more information about restricted worker access, see :ref:`workload_manager`. + +Preparing Your Table +=============== +You can build your table structure on both local and foreign tables: - avro_fdw [OPTIONS(option=value[,...])] +.. contents:: + :local: + :depth: 1 -Example ------------ -The following is an example of creating a table: +Creating a Table +--------------------- +Before loading data, you must build the ``CREATE TABLE`` to correspond with the file structure of the inserted table. + +The example in this section is based on the source ``nba.avro`` table shown below: + +.. csv-table:: nba.avro + :file: nba-t10.csv + :widths: auto + :header-rows: 1 + +The following example shows the correct file structure used to create the ``CREATE TABLE`` statement based on the **nba.avro** table: .. code-block:: postgres - CREATE TABLE nba AS - SELECT * FROM ext_nba; + CREATE TABLE ext_nba + ( -The following is an example of loading data from an Avro file into SQream: + Name TEXT(40), + Team TEXT(40), + Number BIGINT, + Position TEXT(2), + Age BIGINT, + Height TEXT(4), + Weight BIGINT, + College TEXT(40), + Salary FLOAT + ) + WRAPPER avro_fdw + OPTIONS + ( + LOCATION = 's3://sqream-demo-data/nba.avro' + ); + +.. tip:: + + An exact match must exist between the SQream and Avro types. For unsupported column types, you can set the type to any type and exclude it from subsequent queries. + +.. note:: The **nba.avro** file is stored on S3 at ``s3://sqream-demo-data/nba.avro``. + +Creating a Foreign Table +--------------------- +Before loading data, you must build the ``CREATE FOREIGN TABLE`` to correspond with the file structure of the inserted table. + +The example in this section is based on the source ``nba.avro`` table shown below: + +.. csv-table:: nba.avro + :file: nba-t10.csv + :widths: auto + :header-rows: 1 + +The following example shows the correct file structure used to create the ``CREATE FOREIGN TABLE`` statement based on the **nba.avro** table: .. code-block:: postgres + + CREATE FOREIGN TABLE ext_nba + ( + Name TEXT(40), + Team TEXT(40), + Number BIGINT, + Position TEXT(2), + Age BIGINT, + Height TEXT(4), + Weight BIGINT, + College TEXT(40), + Salary FLOAT + ) WRAPPER avro_fdw OPTIONS ( LOCATION = 's3://sqream-demo-data/nba.avro' ); - -For more examples, see :ref:`additional_examples`. -Avro Data Types -=========== -Avro includes the following data types: +.. tip:: + + An exact match must exist between the SQream and Avro types. For unsupported column types, you can set the type to any type and exclude it from subsequent queries. + +.. note:: The **nba.avro** file is stored on S3 at ``s3://sqream-demo-data/nba.avro``. + +.. note:: The examples in the sections above are identical except for the syntax used to create the tables. + +Mapping Between SQream and Avro Data Types +================= +Mapping between SQream and Avro data types depends on the Avro data type: .. contents:: :local: @@ -94,23 +159,23 @@ Complex Data Types -------------- The following table shows the supported **Complex** data types: -+------------+---------------------------------------------------+ -| | SQream Type | -| +-----------+---------------+-----------+-----------+ -|Avro Type | Number | Date/Datetime | String | Boolean | -+============+===========+===============+===========+===========+ -| ``record`` | | | | | -+------------+-----------+---------------+-----------+-----------+ -| ``enum`` | | | Supported | | -+------------+-----------+---------------+-----------+-----------+ -| ``array`` | | | | | -+------------+-----------+---------------+-----------+-----------+ -| ``map`` | | | | | -+------------+-----------+---------------+-----------+-----------+ -| ``union`` | Supported | Supported | Supported | Supported | -+------------+-----------+---------------+-----------+-----------+ -| ``fixed`` | | | | | -+------------+-----------+---------------+-----------+-----------+ ++------------+-------------------------------------------------------+ +| | SQream Type | +| +---------------+---------------+-----------+-----------+ +|Avro Type | Number | Date/Datetime | String | Boolean | ++============+============+================+=============+===========+ +| ``record`` | | | | | ++------------+------------+----------------+-------------+-----------+ +| ``enum`` | | | Supported | | ++------------+------------+----------------+-------------+-----------+ +| ``array`` | | | | | ++------------+------------+----------------+-------------+-----------+ +| ``map`` | | | | | ++------------+------------+----------------+-------------+-----------+ +| ``union`` | Supported | Supported | Supported | Supported | ++------------+------------+----------------+-------------+-----------+ +| ``fixed`` | | | | | ++------------+------------+----------------+-------------+-----------+ Logical Data Types -------------- @@ -143,76 +208,77 @@ The following table shows the supported **Logical** data types: +----------------------------+-----------+---------------+-----------+---------+ .. note:: Number types include **tinyint**, **smallint**, **int**, **bigint**, **real** and **float**, and **numeric**. String types include **text**. - + Mapping Objects to Rows =============== When mapping objects to rows, each Avro object or message must contain one ``record`` type object corresponding to a single row in SQream. The ``record`` fields are associated by name to their target table columns. Additional unmapped fields will be ignored. Note that using the JSONPath option overrides this. -Best Practices -==================== -This section describes the best practices when ingesting Avro files into SQream: +Ingesting Data into SQream +============== +This section includes the following: .. contents:: :local: :depth: 1 -Making Avro Files Accessible to Workers ---------------------- -To give workers access to files every node must have the same view of the storage being used. - -The following apply for Avro files to be accessible to workers: - -* For files hosted on NFS, ensure that the mount is accessible from all servers. - -* For HDFS, ensure that SQream servers have access to the HDFS name node with the correct **user-id**. For more information, see :ref:`hdfs`. - -* For S3, ensure network access to the S3 endpoint. For more information, see :ref:`s3`. +Syntax +----------- +Before ingesting data into SQream from an Avro file, you must create a table using the following syntax: -For more information about restricted worker access, see :ref:`workload_manager`. +.. code-block:: postgres + + COPY [schema name.]table_name + FROM WRAPPER fdw_name + ; + +After creating a table you can ingest data from an Avro file into SQream using the following syntax: -Basing Your Table Structure on Inserted Tables ---------------------- -Before loading data, you must build the ``CREATE FOREIGN TABLE`` to correspond with the file structure of the inserted table. +.. code-block:: postgres -The example in this section is based on the source ``nba.avro`` table shown below: + avro_fdw + +Example +----------- +The following is an example of creating a table: -.. csv-table:: nba.avro - :file: nba-t10.csv - :widths: auto - :header-rows: 1 +.. code-block:: postgres + + COPY t + FROM WRAPPER fdw_name + OPTIONS + ( + [ copy_from_option [, ...] ] + ) + ; -The following example shows the correct file structure used to create the ``CREATE FOREIGN TABLE`` statement based on the **nba.avro** table: +The following is an example of loading data from an Avro file into SQream: .. code-block:: postgres - - CREATE FOREIGN TABLE ext_nba - ( - Name TEXT(40), - Team TEXT(40), - Number BIGINT, - Position TEXT(2), - Age BIGINT, - Height TEXT(4), - Weight BIGINT, - College TEXT(40), - Salary FLOAT - ) WRAPPER avro_fdw OPTIONS ( LOCATION = 's3://sqream-demo-data/nba.avro' ); + +For more examples, see :ref:`additional_examples`. -.. tip:: - - An exact match must exist between the SQream and Avro types. For unsupported column types, you can set the type to any type and exclude it from subsequent queries. +Parameters +=================== +The following table shows the Avro parameter: -.. note:: The **nba.avro** file is stored on S3 at ``s3://sqream-demo-data/nba.avro``. +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``schema_name`` + - The schema name for the table. Defaults to ``public`` if not specified. -Verifying Your Table Output ---------------------- -Because external tables do not automatically verify the file integrity or structure, you must manually verify that the table output is identical to the original inserted table. +Best Practices +============ +Because external tables do not automatically verify the file integrity or structure, SQream recommends manually verifying your table output when ingesting Avro files into SQream. This lets you determine if your table output is identical to your originally inserted table. The following is an example of the output based on the **nba.avro** table: diff --git a/feature_guides/data_encryption_methods.rst b/feature_guides/data_encryption_methods.rst index dc6e7c122..0e5638058 100644 --- a/feature_guides/data_encryption_methods.rst +++ b/feature_guides/data_encryption_methods.rst @@ -13,7 +13,7 @@ Encrypting Data in Transit ---------------- **Data in transit** refers to data you use on a regular basis, usually stored on a database and accessed through applications or programs. This data is typically transferred between several physical or remote locations through email or uploading documents to the cloud. This type of data must therefore be protected while **in transit**. SQream encrypts data in transit using SSL when, for example, users insert data files from external repositories over a JDBC or ODBC connection. -For more information, see :ref:`installing_nginx_proxy_over_secure_connection`. +For more information, see `Use TLS/SSL When Possible `_. Encrypting Data at Rest ---------------- diff --git a/feature_guides/flexible_data_clustering.rst b/feature_guides/flexible_data_clustering.rst deleted file mode 100644 index ce0f3d321..000000000 --- a/feature_guides/flexible_data_clustering.rst +++ /dev/null @@ -1,16 +0,0 @@ -.. _flexible_data_clustering: - -*********************** -Flexible Data Clustering -*********************** -The **Flexible Data Clustering** section describes the following: - -.. toctree:: - :maxdepth: 4 - :titlesonly: - - flexible_data_clustering_overview - flexible_data_clustering_chunks - flexible_data_clustering_data_clustering_methods - flexible_data_clustering_data_rechunking_data - flexible_data_clustering_data_examples \ No newline at end of file diff --git a/feature_guides/flexible_data_clustering_chunks.rst b/feature_guides/flexible_data_clustering_chunks.rst deleted file mode 100644 index b8146d0fc..000000000 --- a/feature_guides/flexible_data_clustering_chunks.rst +++ /dev/null @@ -1,18 +0,0 @@ -.. _flexible_data_clustering_chunks: - -*********************** -What are Chunks? -*********************** -Chunks, sometimes referred to as **partitions**, are a contiguous number of rows in a specific column. SQream relies on an advanced partitioning method called **chunking**, which provides all static partitioning capabilities without the known limitations. - -The following figure shows a table rows grouped as chunks: - -.. figure:: /_static/images/chunking2.png - :scale: 75 % - :align: center - -The following figure shows the rows from the table above converted into chunks: - -.. figure:: /_static/images/chunking_metadata2.png - :scale: 75 % - :align: center \ No newline at end of file diff --git a/feature_guides/flexible_data_clustering_data_clustering_methods.rst b/feature_guides/flexible_data_clustering_data_clustering_methods.rst deleted file mode 100644 index 6949547ba..000000000 --- a/feature_guides/flexible_data_clustering_data_clustering_methods.rst +++ /dev/null @@ -1,180 +0,0 @@ -.. _flexible_data_clustering_data_clustering_methods: - -*********************** -Data Clustering Methods -*********************** -The following data clustering methods can be used in tandem or separately to enhance query performance: - -.. contents:: - :local: - :depth: 1 - -Using Time-Based Data Management -============ -Overview -~~~~~~~~~~ -**Time-based data management** refers to sorting table data along naturally occuring dimensions. The most common and naturally occuring sorting mechanism is a **timestamp**, which indicates the point in time at which data was inserted into SQream. Because SQream is a columnar storage system, timestamped metadata facilitates quick and easy query processing. - -The following is the correct syntax for timestamping a chunk: - -.. code-block:: postgres - - SELECT DATEPART(HOUR, timestamp), - MIN(transaction_amount), - MAX(transaction_amount), - avg(transaction_amount) - FROM transactions - WHERE timestamp BETWEEN (CURRENT_TIMESTAMP AND DATEADD(MONTH,-3,CURRENT_TIMESTAMP)) - GROUP BY 1; - -Timestamping data includes the following properties: - -* Data is loaded in a natural order while being inserted. - - :: - -* Updates are infrequent or non-existent. Updates occur by inserting new rows, which have their own timestamps. - - :: - -* Queries on timestamped data is typically on continuous time range. - - :: - -* Inserting and reading data are performed independently, not in the operation or transaction. - - :: - -* Timestamped data has a high data volume and accumulates faster than typical online transactional processing workloads. - -The following are some scenarios ideal for timestamping: - -* Running analytical queries spanning specific date ranges (such as the sum of transactions during August-July 2020 versus August-July 2019). - - :: - -* Deleting data older than a specific number of months old. - - :: - -* Regulations require you to maintain several years of data that you do not need to query on a regular basis. - -Best Practices for Time-Based Management -~~~~~~~~~~ -Data inserted in bulks is automatically timestamped with the insertion date and time. Therefore, inserting data through small and frequent bulks has the effect of naturally ordering data according to timestamp. Frequent bulks generally refers to short time frames, such as at 15-minute, hourly, or daily intervals. As you insert new data, SQream chunks and appends it into your existing tables according to its timestamp. - -The ``DATE`` and ``DATETIME`` types were created to improve performance, minimze storage size, and maintain data integrity. SQream recommends using them instead of ``TEXT``. - -Using Clustering Keys -============ -Overview -~~~~~~~~~~ -While data clustering occurs relatively naturally within a table, certain practices can be used to actively enhance query performance and runtime. Defining **clustering keys** increases performance by explicitly co-locating your data, enabling SQream to avoid processing irrelevant chunks. - -A clustering key is a subset of table columns or expressions and is defined using the ``CLUSTER BY`` statement, as shown below: - -.. code-block:: postgres - - CREATE TABLE users ( - name TEXT(30) NOT NULL, - start_date datetime not null, - country TEXT(30) DEFAULT 'Unknown' NOT NULL - ) CLUSTER BY country; - - - -The ``CLUSTER BY`` statement splits ingested data based on the range of data corresponding to the clustering key. This helps create chunks based on specific or related data, avoiding mixed chunks as much as possible. For example, instead of creating chunks based on a fixed number of rows, the ``CLUSTER_BY`` statement creates them based on common values. This optimizes the ``DELETE`` command as well, which deletes rows based on their location in a table. - -For more information, see the following: - -* `The CLUSTER_BY statement `_ -* `The DELETE statement `_ -* `The Deleting Data Guide `_ - -Inspecting Clustered Table Health -~~~~~~~~~~ -You can use the ``clustering_health`` utility function to check how well a table is clustered, as shown below: - -.. code-block:: postgres - - SELECT CLUSTERING_HEALTH('table_name','clustering_keys'); - -The ``CLUSTERING_HEALTH`` function returns the average clustering depth of your table relative to the clustering keys. A lower value indicates a well-clustered table. - -Clustering keys are useful for restructuring large tables not optimally ordered when inserted or as a result of extensive DML. A table that uses clustering keys is referred to as a **clustered table**. Tables that are not clustered require SQream's query optimizer to scan entire tables while running queries, dramatically increasing runtime. Some queries significantly benefit from clustering, such as filtering or joining extensively on clustered columns. - -SQream partially sorts data that you load into a clustered table. Note that while clustering tables increases query performance, clustering during the insertion stage can decrease performance by 75%. Nevertheless, once a table is clustered subsequent queries run more quickly. - -.. note:: - - To determine whether clustering will enhance performance, SQream recommends end-to-end testing your clustering keys on a small subset of your data before committing them to permanent use. This is relevant for testing insert and query performance. - -For more information, see the following: - -* **Data Manipulation commands (DML)** - see `Data Manipulation Commands (DML) `_. - -* **Creating tables** - see :ref:`create_table`. When you create a table, all new data is clustered upon insert. - -* **Modifying tables** - see :ref:`cluster_by`. - -* **Modifying a table schema** - see :ref:`alter_table`. - -Using Metadata -============ -SQream uses an automated and transparent system for collecting metadata describing each chunk. This metadata enables skipping unnecessary chunks and extents during query runtime. The system collects chunk metadata when data is inserted into SQream. This is done by splitting data into chunks and collecting and storing specific parameters to be used later. - -Because collecting metadata is not process-heavy and does not contribute significantly to query processing, it occurs continuously as a background process. Most metadata collection is typically performed by the GPU. For example, for a 10TB dataset, the metadata storage overhead is approximately 0.5GB. - -When a query includes a filter (such as a ``WHERE`` or ``JOIN`` condition) on a range of values spanning a fraction of the table values, SQream scans only the filtered segment of the table. - -Once collected, several metadata parameters are stored for later use, including: - -* The range of values on each column chunk (minimum, maximum). - - :: - -* The number of values. - - :: - -* Additional information for query optimization. - -Data is collected automatically and transparently on every column type. - -Queries filtering highly granular date and time ranges are the most effective, particularly when data is timestamped, and when tables contain a large amount of historical data. - -Using Chunks and Extents -============ -SQream stores data in logical tables made up of rows spanning one or more columns. Internally, data is stored in vertical partitions by column, and horizontally by chunks. The **Using Chunks and Extents** section describes how to leverge chunking to optimize query performance. - -A **chunk** is a contiguous number of rows in a specific column. Depending on data type, a chunk's uncompressed size typically ranges between 1MB and a few hundred megabytes. This size range is suitable for filtering and deleting data from large tables, which may contain between hundreds, millions, or billions of chunks. - -An **extent** is a specific number of contiguous chunks. Extents optimize disk access patterns, at around 20MB uncompressed, on-disk. Extents typically include between one and 25 chunks based on the compressed size of each chunk. - -.. note:: - - SQream compresses all data. In addition, all tables are automatically and transparently chunked. - -Unlike node-partitioning (or sharding), chunks are: - -* Small enough to be read concurrently by multiple workers. - - :: - -* Optimized for inserting data quickly. - - :: - -* Capable of carrying metadata, which narrows down their contents for the query optimizer. - - :: - -* Ideal for data retension because they can be deleted in bulk. - - :: - -* Optimized for reading into RAM and the GPU. - - :: - -* Compressed individually to improve compression and data locality. \ No newline at end of file diff --git a/feature_guides/flexible_data_clustering_data_examples.rst b/feature_guides/flexible_data_clustering_data_examples.rst deleted file mode 100644 index bf08a111a..000000000 --- a/feature_guides/flexible_data_clustering_data_examples.rst +++ /dev/null @@ -1,22 +0,0 @@ -.. _flexible_data_clustering_data_examples: - -*********************** -Examples -*********************** -The **Examples** includes the following examples: - -.. contents:: - :local: - :depth: 1 - -Creating a Clustered Table ------------------------------ -The following is an example of syntax for creating a clustered table on a table naturally ordered by ``start_date``. An alternative cluster key can be defined on such a table to improve performance on queries already ordered by ``country``: - -.. code-block:: postgres - - CREATE TABLE users ( - name text(30) NOT NULL, - start_date datetime not null, - country text(30) DEFAULT 'Unknown' NOT NULL - ) CLUSTER BY country; \ No newline at end of file diff --git a/feature_guides/flexible_data_clustering_data_rechunking_data.rst b/feature_guides/flexible_data_clustering_data_rechunking_data.rst deleted file mode 100644 index 30a74bbaa..000000000 --- a/feature_guides/flexible_data_clustering_data_rechunking_data.rst +++ /dev/null @@ -1,11 +0,0 @@ -.. _flexible_data_clustering_data_rechunking_data: - -*********************** -Rechunking Data -*********************** -SQream performs background storage reorganization operations to optimize I/O and read patterns. - -For example, when small batches of data are inserted, SQream runs two background processes called **rechunk** and **reextent** to reorganize the data into larger contiguous chunks and extents. This is also what happens when data is deleted. - - -Instead of overwriting data, SQream writes new optimized chunks and extents to replace old ones. After rewriting all old data, SQream switches to the new optimized chunks and extents and deletes the old data. \ No newline at end of file diff --git a/feature_guides/flexible_data_clustering_overview.rst b/feature_guides/flexible_data_clustering_overview.rst deleted file mode 100644 index 3ba59a603..000000000 --- a/feature_guides/flexible_data_clustering_overview.rst +++ /dev/null @@ -1,16 +0,0 @@ -.. _flexible_data_clustering_overview: - -*********************** -Overeview -*********************** -**Flexible data clustering** refers to sorting table data along naturally occuring dimensions, such as name, date, or location. Data clustering optimizes table structure to significantly improve query performance, especially on very large tables. A well-clustered table increases the effectivity of the metadata collected by focusing on a specific and limited range of rows, called **chunks**. - -The following are some scenarios ideal for data clustering: - -* Queries containg a ``WHERE`` predicate written as ``column COMPARISON value``, such as ``date_column > '2019-01-01'`` or ``id = 107`` when the columns referenced are clustering keys. - - In such a case SQream reads the portion of data that contain values matching these predicates only. - -* Two clustered tables joined by their respective clustering keys. - - In such a case SQream uses metadata to more easily identify matching chunks. \ No newline at end of file diff --git a/feature_guides/index.rst b/feature_guides/index.rst index 2ba36198d..fb663a336 100644 --- a/feature_guides/index.rst +++ b/feature_guides/index.rst @@ -15,7 +15,6 @@ This section describes the following features: key_evaluation data_encryption compression - flexible_data_clustering python_functions workload_manager transactions diff --git a/reference/sql/sql_statements/dml_commands/update.rst b/reference/sql/sql_statements/dml_commands/update.rst index 19881d62c..f16d90337 100644 --- a/reference/sql/sql_statements/dml_commands/update.rst +++ b/reference/sql/sql_statements/dml_commands/update.rst @@ -31,7 +31,7 @@ The following is the correct syntax for the ``UPDATE`` command: UPDATE target_table_name [[AS] alias1] SET column_name = expression [,...] - [WHERE condition] + [WHERE condition] The following is the correct syntax for triggering a clean-up: @@ -39,9 +39,8 @@ The following is the correct syntax for triggering a clean-up: SELECT cleanup_chunks('schema_name','table_name'); SELECT cleanup_extents('schema_name','table_name'); + SELECT cleanup_discarded_chunks(‘public’,’t’); -**Comment** - *The cleanup example above is different than the one used on the DELETED page. Is this correct?* - Parameters ============ The following table describes the ``UPDATE`` parameters: @@ -79,71 +78,21 @@ The following is an example of performing a simple update: UPDATE bands SET records_sold = records_sold + 1 WHERE name LIKE 'The %'; -Identifying and Cleaning Up Tables +Triggering a Clean-Up --------------------------------------- -**Comment** - *I copied and pasted this entire section from "DELETE". Does anything have to adjusted here for "UPDATE"?* - -The following section shows examples of each phase required for cleaning up tables: - -* :ref:`Listing tables that require clean-up` -* :ref:`Identifying clean-up predicates` -* :ref:`Triggering a clean-up` - -.. _listing_tables_that_require_cleanup: - -Listing Tables that Require Clean-Up -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The following shows an example of listing tables that require clean-up: +The following section shows an example of triggering a clean-up: .. code-block:: psql - - farm=> SELECT t.table_name FROM sqream_catalog.delete_predicates dp - JOIN sqream_catalog.tables t - ON dp.table_id = t.table_id - GROUP BY 1; - cool_animals - - 1 row -.. _identifying_cleanup_predicates: + SELECT * FROM sqream_catalog.discarded_chunks; + SELECT cleanup_discarded_chunks('public','t'); -Identifying Clean-Up Predicates -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The following shows an example of listing the clean-up predicates: +The following is an output example: -.. code-block:: psql - - farm=> SELECT delete_predicate FROM sqream_catalog.delete_predicates dp - JOIN sqream_catalog.tables t - ON dp.table_id = t.table_id - WHERE t.table_name = 'cool_animals'; - weight > 1000 - - 1 row - -.. _triggering_a_cleanup: - -Triggering a Clean-Up -^^^^^^^^^^^^^^^^^^^^^^ -The following shows an example of triggering a clean-up: - -.. code-block:: psql - - -- Chunk reorganization (SWEEP) - farm=> SELECT CLEANUP_CHUNKS('public','cool_animals'); - executed - - -- Delete leftover files (VACUUM) - farm=> SELECT CLEANUP_EXTENTS('public','cool_animals'); - executed - - - farm=> SELECT delete_predicate FROM sqream_catalog.delete_predicates dp - JOIN sqream_catalog.tables t - ON dp.table_id = t.table_id - WHERE t.table_name = 'cool_animals'; - - 0 rows +* **database_name** - _discarded_master +* **table_id** - 24 +* **column_id** - 1 +* **extent_ID** - 0 Permissions ============= diff --git a/releases/2022.1.rst b/releases/2022.1.rst index 9a2de884e..7b2d9d4dd 100644 --- a/releases/2022.1.rst +++ b/releases/2022.1.rst @@ -29,9 +29,9 @@ Data Encryption ************ SQream now supports data encryption mechanisms in accordance with **General Data Protection Regulation (GDPR)** standards. -For more information, see `Data Encryption `_. +Using the data encryption feature may lead to a maximum of a 40% increase in performance degradation. -**Comment** - *Information regarding performance degradation, pending.* +For more information, see `Data Encryption `_. Update Feature ************ @@ -91,4 +91,36 @@ This section is not relevant to the 2022.1 release notes. Upgrading to v2022.1 ------- -**Comment** - *TBD* \ No newline at end of file +1. Generate a back-up of the metadata by running the following command: + + .. code-block:: console + + $ select backup_metadata('out_path'); + + .. tip:: SQream recommends storing the generated back-up locally in case needed. + + SQream runs the Garbage Collector and creates a clean backup tarball package. + +2. Shut down all SQream services. + + :: + +3. Extract the recently created back-up file. + + :: + +4. Replace your current metadata with the metadata you stored in the back-up file. + + :: + +5. Navigate to the new SQream package bin folder. + + :: + +6. Run the following command: + + .. code-block:: console + + $ ./upgrade_storage + + .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in **Step 7** of the Upgrading SQream Version procedure. \ No newline at end of file From 5c07b951cb154b32c279d12c2342f6b7dfebae6c Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 24 May 2022 19:15:54 +0300 Subject: [PATCH 073/316] Update new_2022.1.png --- _static/images/new_2022.1.png | Bin 2056 -> 882 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/_static/images/new_2022.1.png b/_static/images/new_2022.1.png index fc043757cd3728088194fbb6951830f5bf7fcc0c..4861ba76a5b6c7d35703267596db1f4c0a8c9fb5 100644 GIT binary patch delta 845 zcmV-T1G4;x5b_2giBL{Q4GJ0x0000DNk~Le0001S0000E2m$~A0GDWFlaV1be**_e zL_t(oN9~tAa_TS;$N%^&K*4YVa{@?1mG*U_Oqz5l)1@&bK0+#**e8fjz))b{#cx+y z%aXA2!6TV@Gx?1QX|>4O)vi{cB?{H18FzjXg%;G(widyENZqDrRiXO@o1?qrQ$1ni zgfTU93?+&D?0VGMzj~8bFsBl1e@~kuQ%Yn+Oh3BL8SEKnLB{oI+h(chCum+#DJ3tW~MlW#m*acZ#|Lt z&oK`(rDT>0Zc3Hie|h!>cy(WwOS`NovP}Pq9)Q%sDopr0bZr^de|MeWWfH6Vy+dR; z_?B|)Fi+y(XC#s4e1q2MU0~FPY%qjxDeXSf0$)3O>2V+G((IdQXsMWfbRFNP?DumW zBJinfctq>!cklb9;FnK8F9+?(L|1L6&i-;SUHuqQ$nwklBWZTwCH;#)|4>$->|f$9 XQ>c)1B;vX600000NkvXXu0mjf(aoL- delta 2028 zcmVPUA2Xb_z!U38c9|795~RWyb+nWWk07vzr6VjxN}A!D0@;j!5(XUGxGY zQHdS}l6lX5&w2TA;?(KDF!>~_Y1$V*+wb3Qqqn!WTuI!YsmaTw$`&_tW5kFN23w`B zuhc~S0R5QKJ*6s2v{aMBnTk}bf3nR=fr32Zg^mO4;=!{;hBm+f&XbNVJv4f2cLCJTeOl8MOYr80nd}`r8c0Q*e+GnM8EVL zXmJ05^ge*+n`d9sjTSV@{8VN07+%+EawYDgCo(O~Go|ue#rgY&?@^n_e{df^Q+YPu zls|K|&D{OGf2pO39edF}*_ePwGuN)x!EYCRoWOcE&~e*$|H1RU$=_r7JQz>o_e5iv zkLQ)o>UvUmqUDqELh)s57#H21fOVobUmoDTXAkBwo-3F%_5OzK6NS3y@qtIPc9KVE z>0E&z0KjsdIIQpTS{*p)e-lH$eozN4`q2JE={o^ycm^`NrnkWm-sp}L!Dv^Zsg0gS zcp}q0H2EudqE9~tVPR_)lbRhv)7r9C-IYGH|4{mlCTMXDvxMb1#1lcY&o$2>PxPuH zt*J1g^A;1E%vFX;sK7Gy$&W_t2is@6ZrLwKHTCF5Wr?|rUS7=we}kisE_!WwF$%fU zuNI;GhtjtJJnZD;mONYn9&V+wQ~gOej?Pt1dVo=xQ6kS!PW=Y;`$aBxeX9;I=?g_I zX+MPb;JT~HB!(SbNuf^xdat=XR(S#; zSG5r2!taU@K5?kpf3fc8@VUM)LQ^2H|6uxd*bs5G0KwO{2EvibztQFEmXzofv;*<& z*u1s@Ed#{L8V|F8{K!;e4rU;z>vF&v=@=Z8>0Sun^un=_jID|u={f61NA(N@mEa!M8f0Zv5r9F!}U|wi>%j+xV z;_}>FxL_?Wtj&{{{Gk2;q4aH-E=*pv+S7jLDS2n`jz)=I%;I@190D0+7eCvv+!osZQZ6|D3F&8C$_jR!2DqY z%f_(dfcZ;OfAJk?GBI!Qj?onu5*>0BwAsx-rc=y|({LPj^(8ECU-Gy?WidNPys6@hD_5uj?DzyUAD?cKEuWjl|aQFsHTG-eeLm+)Y z;7|^{+ILcrT1e*`%Jl$`0~grkIb>qoq}YIb{++G{2Ih!7=2UpkzlG5LKbn7pM+jN= zM7=RBf9FSymbMBOcmU9p67f>Q;}r;@Fg7-?glp{bb%G2$X_l(rVGBBxMHA!b@@y18 zmkfeLp9sJgD1f(yKkX&|wiOTU|D*ZmaLogON(7Mk(e2f4`H?q@kgjCaIh5lB`GP`0 zSrWD0Z=g`F5A1?eJ?NfL6~LkLD}+ySAKL#ufBD}7K#2m9M#jxby_5Ctv$Kp7R7%7f zTjg{Bhjcbv6QLaMad9YUbEm>-R*V{SQgsw7w-H+R|#Y;&eN-+WJ_z zDxKm6a1POxWO@Pe1wN?ShQ&&~e{WKi$CO(z;C(*FBQ(|13<4a_H-&Nx8?L~J_Z3RP zSX;+|N1E_7!al&cmd4s0K6gQ%tVmUs0KargL-OA=#i9L&(qlNSryTekbbYbtLTee% z>vOVvej~wN;e3LHoEUV9%?KLKrckgoghi zas1oQ=#55boezEA Date: Sun, 29 May 2022 11:01:15 +0300 Subject: [PATCH 074/316] Update copy_to.rst Added Avro to COPY TO page. --- reference/sql/sql_statements/dml_commands/copy_to.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference/sql/sql_statements/dml_commands/copy_to.rst b/reference/sql/sql_statements/dml_commands/copy_to.rst index 61e6b35b2..85632904f 100644 --- a/reference/sql/sql_statements/dml_commands/copy_to.rst +++ b/reference/sql/sql_statements/dml_commands/copy_to.rst @@ -29,7 +29,7 @@ Syntax ) ; - fdw_name ::= csw_fdw | parquet_fdw | orc_fdw + fdw_name ::= csw_fdw | parquet_fdw | orc_fdw | avro_fdw schema_name ::= identifer From 1cbd8ce0cb4973a7809f40137dbc1c358eb19dab Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 29 May 2022 11:23:56 +0300 Subject: [PATCH 075/316] Updated Delete Guide Moved delete_guide from Feature Guides to Operational guides. Delete delete page and replaced with delete_guide. --- operational_guides/delete.rst | 214 ------------------ .../delete_guide.rst | 0 operational_guides/index.rst | 1 + 3 files changed, 1 insertion(+), 214 deletions(-) delete mode 100644 operational_guides/delete.rst rename {feature_guides => operational_guides}/delete_guide.rst (100%) diff --git a/operational_guides/delete.rst b/operational_guides/delete.rst deleted file mode 100644 index 24ab5a218..000000000 --- a/operational_guides/delete.rst +++ /dev/null @@ -1,214 +0,0 @@ -.. _delete_guide: - -*********************** -Deleting Data -*********************** - -SQream DB supports deleting data, but it's important to understand how this works and how to maintain deleted data. - -How does deleting in SQream DB work? -======================================== - -In SQream DB, when you run a delete statement, any rows that match the delete predicate will no longer be returned when running subsequent queries. -Deleted rows are tracked in a separate location, in *delete predicates*. - -After the delete statement, a separate process can be used to reclaim the space occupied by these rows, and to remove the small overhead that queries will have until this is done. - -Some benefits to this design are: - -#. Delete transactions complete quickly - -#. The total disk footprint overhead at any time for a delete transaction or cleanup process is small and bounded (while the system still supports low overhead commit, rollback and recovery for delete transactions). - - -Phase 1: Delete ---------------------------- - -.. TODO: isn't the delete cleanup able to complete a certain amount of work transactionally, so that you can do a massive cleanup in stages? - -.. TODO: our current best practices is to use a cron job with sqream sql to run the delete cleanup. we should document how to do this, we have customers with very different delete schedules so we can give a few extreme examples and when/why you'd use them - -When a :ref:`delete` statement is run, SQream DB records the delete predicates used. These predicates will be used to filter future statements on this table until all this delete predicate's matching rows have been physically cleaned up. - -This filtering process takes full advantage of SQream's zone map feature. - -Phase 2: Clean-up --------------------- - -The cleanup process is not automatic. This gives control to the user or DBA, and gives flexibility on when to run the clean up. - -Files marked for deletion during the logical deletion stage are removed from disk. This is achieved by calling both utility function commands: ``CLEANUP_CHUNKS`` and ``CLEANUP_EXTENTS`` sequentially. - -.. note:: - * :ref:`alter_table` and other DDL operations are blocked on tables that require clean-up. See more in the :ref:`concurrency_and_locks` guide. - * If the estimated time for a cleanup processs is beyond a threshold, you will get an error message about it. The message will explain how to override this limitation and run the process anywhere. - -Notes on data deletion -========================================= - -.. note:: - * If the number of deleted records crosses the threshold defined by the ``mixedColumnChunksThreshold`` parameter, the delete operation will be aborted. - * This is intended to alert the user that the large number of deleted records may result in a large number of mixed chuncks. - * To circumvent this alert, replace XXX with the desired number of records before running the delete operation: - -.. code-block:: postgres - - set mixedColumnChunksThreshold=XXX; - - -Deleting data does not free up space ------------------------------------------ - -With the exception of a full table delete (:ref:`TRUNCATE`), deleting data does not free up disk space. To free up disk space, trigger the cleanup process. - -``SELECT`` performance on deleted rows ----------------------------------------- - -Queries on tables that have deleted rows may have to scan data that hasn't been cleaned up. -In some cases, this can cause queries to take longer than expected. To solve this issue, trigger the cleanup process. - -Use ``TRUNCATE`` instead of ``DELETE`` ---------------------------------------- -For tables that are frequently emptied entirely, consider using :ref:`truncate` rather than :ref:`delete`. TRUNCATE removes the entire content of the table immediately, without requiring a subsequent cleanup to free up disk space. - -Cleanup is I/O intensive -------------------------------- - -The cleanup process actively compacts tables by writing a complete new version of column chunks with no dead space. This minimizes the size of the table, but can take a long time. It also requires extra disk space for the new copy of the table, until the operation completes. - -Cleanup operations can create significant I/O load on the database. Consider this when planning the best time for the cleanup process. - -If this is an issue with your environment, consider using ``CREATE TABLE AS`` to create a new table and then rename and drop the old table. - - -Example -============= - -Deleting values from a table ------------------------------- - -.. code-block:: psql - - farm=> SELECT * FROM cool_animals; - 1,Dog ,7 - 2,Possum ,3 - 3,Cat ,5 - 4,Elephant ,6500 - 5,Rhinoceros ,2100 - 6,\N,\N - - 6 rows - - farm=> DELETE FROM cool_animals WHERE weight > 1000; - executed - - farm=> SELECT * FROM cool_animals; - 1,Dog ,7 - 2,Possum ,3 - 3,Cat ,5 - 6,\N,\N - - 4 rows - -Deleting values based on more complex predicates ---------------------------------------------------- - -.. code-block:: psql - - farm=> SELECT * FROM cool_animals; - 1,Dog ,7 - 2,Possum ,3 - 3,Cat ,5 - 4,Elephant ,6500 - 5,Rhinoceros ,2100 - 6,\N,\N - - 6 rows - - farm=> DELETE FROM cool_animals WHERE weight > 1000; - executed - - farm=> SELECT * FROM cool_animals; - 1,Dog ,7 - 2,Possum ,3 - 3,Cat ,5 - 6,\N,\N - - 4 rows - -Identifying and cleaning up tables ---------------------------------------- - -List tables that haven't been cleaned up -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. code-block:: psql - - farm=> SELECT t.table_name FROM sqream_catalog.delete_predicates dp - JOIN sqream_catalog.tables t - ON dp.table_id = t.table_id - GROUP BY 1; - cool_animals - - 1 row - -Identify predicates for clean-up -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. code-block:: psql - - farm=> SELECT delete_predicate FROM sqream_catalog.delete_predicates dp - JOIN sqream_catalog.tables t - ON dp.table_id = t.table_id - WHERE t.table_name = 'cool_animals'; - weight > 1000 - - 1 row - -Triggering a cleanup -^^^^^^^^^^^^^^^^^^^^^^ - -.. code-block:: psql - - -- Chunk reorganization (aka SWEEP) - farm=> SELECT CLEANUP_CHUNKS('public','cool_animals'); - executed - - -- Delete leftover files (aka VACUUM) - farm=> SELECT CLEANUP_EXTENTS('public','cool_animals'); - executed - - - farm=> SELECT delete_predicate FROM sqream_catalog.delete_predicates dp - JOIN sqream_catalog.tables t - ON dp.table_id = t.table_id - WHERE t.table_name = 'cool_animals'; - - 0 rows - - - -Best practices for data deletion -===================================== - -* Run ``CLEANUP_CHUNKS`` and ``CLEANUP_EXTENTS`` after large ``DELETE`` operations. - -* When deleting large proportions of data from very large tables, consider running a ``CREATE TABLE AS`` operation instead, then rename and drop the original table. - -* Avoid killing ``CLEANUP_EXTENTS`` operations after they've started. - -* SQream DB is optimised for time-based data. When data is naturally ordered by a date or timestamp, deleting based on those columns will perform best. For more information, see our :ref:`time based data management guide`. - - - -.. soft update concept - -.. delete cleanup and it's properties. automatic/manual, in transaction or background - -.. automatic background gives fast delete, minimal transaction overhead, -.. small cost to queries until background reorganised - -.. when does delete use the metadata effectively - -.. more examples - diff --git a/feature_guides/delete_guide.rst b/operational_guides/delete_guide.rst similarity index 100% rename from feature_guides/delete_guide.rst rename to operational_guides/delete_guide.rst diff --git a/operational_guides/index.rst b/operational_guides/index.rst index dcad76172..b6d3e50f4 100644 --- a/operational_guides/index.rst +++ b/operational_guides/index.rst @@ -16,6 +16,7 @@ This section summarizes the following operational guides: creating_or_cloning_a_storage_cluster external_data external_tables + delete_guide exporting_data logging monitoring_query_performance From 5ac738294af255e8afaf3185bc8582ff09335cc8 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 29 May 2022 11:38:02 +0300 Subject: [PATCH 076/316] Updated External Tables Page Replaced External Tables with Foreign Tables. Modified content on Foreign Tables page (replaced external tables with foreign tables). In Index, replaced external_tables with foreign_tables. Copied nba-t10.csv file into operational_guides folder (table was missing and therefore causing syntax error). --- ...external_tables.rst => foreign_tables.rst} | 33 ++++++++++--------- operational_guides/index.rst | 2 +- operational_guides/nba-t10.csv | 10 ++++++ 3 files changed, 29 insertions(+), 16 deletions(-) rename operational_guides/{external_tables.rst => foreign_tables.rst} (94%) create mode 100644 operational_guides/nba-t10.csv diff --git a/operational_guides/external_tables.rst b/operational_guides/foreign_tables.rst similarity index 94% rename from operational_guides/external_tables.rst rename to operational_guides/foreign_tables.rst index 6ee2f67a0..b914d7b3c 100644 --- a/operational_guides/external_tables.rst +++ b/operational_guides/foreign_tables.rst @@ -1,37 +1,39 @@ -.. _external_tables: +.. _foreign_tables: *********************** -External Tables +Foreign Tables *********************** -External tables can be used to run queries directly on data without inserting it into SQream DB first. +Foreign tables can be used to run queries directly on data without inserting it into SQream DB first. SQream DB supports read only external tables, so you can query from external tables, but you cannot insert to them, or run deletes or updates on them. + Running queries directly on external data is most effectively used for things like one off querying. If you will be repeatedly querying data, the performance will usually be better if you insert the data into SQream DB first. + Although external tables can be used without inserting data into SQream DB, one of their main use cases is to help with the insertion process. An insert select statement on an external table can be used to insert data into SQream using the full power of the query engine to perform ETL. .. contents:: In this topic: :local: -What kind of data is supported? +Supported Data Formats ===================================== SQream DB supports external tables over: -* text files (e.g. CSV, PSV, TSV) +* Text files (e.g. CSV, PSV, TSV) * ORC * Parquet -What kind of data staging is supported? +Supported Data Staging ============================================ -SQream DB can stage data from: +SQream can stage data from: * a local filesystem (e.g. ``/mnt/storage/....``) * :ref:`s3` buckets (e.g. ``s3://pp-secret-bucket/users/*.parquet``) * :ref:`hdfs` (e.g. ``hdfs://hadoop-nn.piedpiper.com/rhendricks/*.csv``) -Using external tables - a practical example +Using External Tables ============================================== Use an external table to stage data before loading from CSV, Parquet or ORC files. -Planning for data staging +Planning for Data Staging -------------------------------- For the following examples, we will want to interact with a CSV file. Here's a peek at the table contents: @@ -44,7 +46,7 @@ For the following examples, we will want to interact with a CSV file. Here's a p The file is stored on :ref:`s3`, at ``s3://sqream-demo-data/nba_players.csv``. We will make note of the file structure, to create a matching ``CREATE_EXTERNAL_TABLE`` statement. -Creating the external table +Creating an External Table ----------------------------- Based on the source file structure, we we :ref:`create an external table` with the appropriate structure, and point it to the file. @@ -68,7 +70,8 @@ Based on the source file structure, we we :ref:`create an external table SELECT * FROM nba; master=> select * from nba; Record delimiter mismatch during CSV parsing. User defined line delimiter \n does not match the first delimiter \r\n found in s3://sqream-demo-data/nba.csv -* Since the data for an external table is not stored in SQream DB, it can be changed or removed at any time by an external process. As a result, the same query can return different results each time it runs against an external table. Similarly, a query might fail if the external data is moved, removed, or has changed structure. +* Since the data for an external table is not stored in SQream DB, it can be changed or removed at any time by an external process. As a result, the same query can return different results each time it runs against an external table. Similarly, a query might fail if the external data is moved, removed, or has changed structure. \ No newline at end of file diff --git a/operational_guides/index.rst b/operational_guides/index.rst index b6d3e50f4..aca578e8b 100644 --- a/operational_guides/index.rst +++ b/operational_guides/index.rst @@ -15,7 +15,7 @@ This section summarizes the following operational guides: access_control creating_or_cloning_a_storage_cluster external_data - external_tables + foreign_tables delete_guide exporting_data logging diff --git a/operational_guides/nba-t10.csv b/operational_guides/nba-t10.csv new file mode 100644 index 000000000..024530355 --- /dev/null +++ b/operational_guides/nba-t10.csv @@ -0,0 +1,10 @@ +Name,Team,Number,Position,Age,Height,Weight,College,Salary +Avery Bradley,Boston Celtics,0.0,PG,25.0,6-2,180.0,Texas,7730337.0 +Jae Crowder,Boston Celtics,99.0,SF,25.0,6-6,235.0,Marquette,6796117.0 +John Holland,Boston Celtics,30.0,SG,27.0,6-5,205.0,Boston University, +R.J. Hunter,Boston Celtics,28.0,SG,22.0,6-5,185.0,Georgia State,1148640.0 +Jonas Jerebko,Boston Celtics,8.0,PF,29.0,6-10,231.0,,5000000.0 +Amir Johnson,Boston Celtics,90.0,PF,29.0,6-9,240.0,,12000000.0 +Jordan Mickey,Boston Celtics,55.0,PF,21.0,6-8,235.0,LSU,1170960.0 +Kelly Olynyk,Boston Celtics,41.0,C,25.0,7-0,238.0,Gonzaga,2165160.0 +Terry Rozier,Boston Celtics,12.0,PG,22.0,6-2,190.0,Louisville,1824360.0 From 732df57cd53c332b0de03641102ca92382fc5ac5 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 29 May 2022 12:21:57 +0300 Subject: [PATCH 077/316] Modified nba-t10.csv syntax. Tried to get nba-t10.csv file to display properly. --- operational_guides/foreign_tables.rst | 5 +- .../ddl_commands/create_external_table.rst | 156 ------------------ 2 files changed, 2 insertions(+), 159 deletions(-) delete mode 100644 reference/sql/sql_statements/ddl_commands/create_external_table.rst diff --git a/operational_guides/foreign_tables.rst b/operational_guides/foreign_tables.rst index b914d7b3c..739652bfa 100644 --- a/operational_guides/foreign_tables.rst +++ b/operational_guides/foreign_tables.rst @@ -36,12 +36,11 @@ Use an external table to stage data before loading from CSV, Parquet or ORC file Planning for Data Staging -------------------------------- For the following examples, we will want to interact with a CSV file. Here's a peek at the table contents: - + .. csv-table:: nba.csv - :file: nba-t10.csv :widths: auto - :header-rows: 1 + :header-rows: 1 The file is stored on :ref:`s3`, at ``s3://sqream-demo-data/nba_players.csv``. We will make note of the file structure, to create a matching ``CREATE_EXTERNAL_TABLE`` statement. diff --git a/reference/sql/sql_statements/ddl_commands/create_external_table.rst b/reference/sql/sql_statements/ddl_commands/create_external_table.rst deleted file mode 100644 index e877a3983..000000000 --- a/reference/sql/sql_statements/ddl_commands/create_external_table.rst +++ /dev/null @@ -1,156 +0,0 @@ -.. _create_external_table: - -*********************** -CREATE EXTERNAL TABLE -*********************** - -.. warning:: - - The ``CREATE EXTERNAL TABLE`` syntax is deprecated, and will be removed in future versions. - - Starting with SQream DB v2020.2, external tables have been renamed to :ref:`foreign tables`, and use a more flexible foreign data wrapper concept. See :ref:`create_foreign_table` instead. - - Upgrading to a new version of SQream DB converts existing tables automatically. When creating a new external tables, use the new foreign table syntax. - - -``CREATE TABLE`` creates a new external table in an existing database. - -See more in the :ref:`External tables guide`. - -.. tip:: - - * Data in an external table can change if the sources change, and frequent access to remote files may harm performance. - - * To create a regular table, see :ref:`CREATE TABLE ` - -Permissions -============= - -The role must have the ``CREATE`` permission at the database level. - -Syntax -========== - -.. code-block:: postgres - - create_table_statement ::= - CREATE [ OR REPLACE ] EXTERNAL TABLE [schema_name].table_name ( - { column_def [, ...] } - ) - USING FORMAT format_def - WITH { external_table_option [ ...] } - ; - - schema_name ::= identifier - - table_name ::= identifier - - format_def ::= { PARQUET | ORC | CSV } - - external_table_option ::= { - PATH '{ path_spec }' - | FIELD DELIMITER '{ field_delimiter }' - | RECORD DELIMITER '{ record_delimiter }' - | AWS_ID '{ AWS ID }' - | AWS_SECRET '{ AWS SECRET }' - } - - path_spec ::= { local filepath | S3 URI | HDFS URI } - - field_delimiter ::= delimiter_character - - record_delimiter ::= delimiter_character - - column_def ::= { column_name type_name [ default ] [ column_constraint ] } - - column_name ::= identifier - - column_constraint ::= - { NOT NULL | NULL } - - default ::= - - DEFAULT default_value - | IDENTITY [ ( start_with [ , increment_by ] ) ] - -.. _cet_parameters: - -Parameters -============ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - * - ``OR REPLACE`` - - Create a new table, and overwrite any existing table by the same name. Does not return an error if the table already exists. ``CREATE OR REPLACE`` does not check the table contents or structure, only the table name. - * - ``schema_name`` - - The name of the schema in which to create the table. - * - ``table_name`` - - The name of the table to create, which must be unique inside the schema. - * - ``column_def`` - - A comma separated list of column definitions. A minimal column definition includes a name identifier and a datatype. Other column constraints and default values can be added optionally. - * - ``USING FORMAT ...`` - - Specifies the format of the source files, such as ``PARQUET``, ``ORC``, or ``CSV``. - * - ``WITH PATH ...`` - - Specifies a path or URI of the source files, such as ``/path/to/*.parquet``. - * - ``FIELD DELIMITER`` - - Specifies the field delimiter for CSV files. Defaults to ``,``. - * - ``RECORD DELIMITER`` - - Specifies the record delimiter for CSV files. Defaults to a newline, ``\n`` - * - ``AWS_ID``, ``AWS_SECRET`` - - Credentials for authenticated S3 access - - -Examples -=========== - -A simple table from Tab-delimited file (TSV) ----------------------------------------------- - -.. code-block:: postgres - - CREATE OR REPLACE EXTERNAL TABLE cool_animals - (id INT NOT NULL, name text(30) NOT NULL, weight FLOAT NOT NULL) - USING FORMAT csv - WITH PATH '/home/rhendricks/cool_animals.csv' - FIELD DELIMITER '\t'; - - -A table from a directory of Parquet files on HDFS ------------------------------------------------------ - -.. code-block:: postgres - - CREATE EXTERNAL TABLE users - (id INT NOT NULL, name text(30) NOT NULL, email text(50) NOT NULL) - USING FORMAT Parquet - WITH PATH 'hdfs://hadoop-nn.piedpiper.com/rhendricks/users/*.parquet'; - -A table from a bucket of files on S3 --------------------------------------- - -.. code-block:: postgres - - CREATE EXTERNAL TABLE users - (id INT NOT NULL, name text(30) NOT NULL, email text(50) NOT NULL) - USING FORMAT Parquet - WITH PATH 's3://pp-secret-bucket/users/*.parquet' - AWS_ID 'our_aws_id' - AWS_SECRET 'our_aws_secret'; - - -Changing an external table to a regular table ------------------------------------------------- - -Materializes an external table into a regular table. - -.. tip: Using an external table allows you to perform ETL-like operations in SQream DB by applying SQL functions and operations to raw files - -.. code-block:: postgres - - CREATE TABLE real_table - AS SELECT * FROM external_table; - From fd1e61a64a2dca4ebf60e00d4e5921c457dbc674 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 29 May 2022 13:12:36 +0300 Subject: [PATCH 078/316] Update update.rst TPD-171: Update - Support Clustering Key --- .../sql/sql_statements/dml_commands/update.rst | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/reference/sql/sql_statements/dml_commands/update.rst b/reference/sql/sql_statements/dml_commands/update.rst index f16d90337..d0f545017 100644 --- a/reference/sql/sql_statements/dml_commands/update.rst +++ b/reference/sql/sql_statements/dml_commands/update.rst @@ -19,10 +19,14 @@ The ``UPDATE`` command is used to modify the value of certain columns in existin It can be used to do the following: -* Perform localized changes in existing data, such as correcting mistakes discovered after ingesting data. +* Performing localized changes in existing data, such as correcting mistakes discovered after ingesting data. + + :: * Setting columns based on the values of others. +.. warning:: Using the ``UPDATE`` command on column clustered using a cluster key can undo your clustering. + Syntax ========== The following is the correct syntax for the ``UPDATE`` command: @@ -60,7 +64,7 @@ The following table describes the ``UPDATE`` parameters: * - ``condition`` - Specifies the condition for updating the data. -.. note:: Similar to a DELETE statement, an UPDATE statement may leave some uncleaned data behind, which requires a cleanup operation. +.. note:: Similar to a ``DELETE`` statement, an ``UPDATE`` statement may leave some uncleaned data behind, which requires a clean-up operation. Examples =========== @@ -87,17 +91,17 @@ The following section shows an example of triggering a clean-up: SELECT * FROM sqream_catalog.discarded_chunks; SELECT cleanup_discarded_chunks('public','t'); -The following is an output example: +The following is an example of the output generated from the above: * **database_name** - _discarded_master * **table_id** - 24 * **column_id** - 1 * **extent_ID** - 0 -Permissions +Locking and Concurrency ============= -Executing an ``UPDATE`` statement requires both ``UPDATE`` and ``SELECT`` permissions on the target table. +Executing the ``UPDATE`` statement obtains an exclusive ``UPDATE`` lock on the target table. -Locking and Concurrency +Permissions ============= -Executing the ``UPDATE`` statement obtains an exclusive UPDATE lock on the target table. \ No newline at end of file +Executing an ``UPDATE`` statement requires both ``UPDATE`` and ``SELECT`` permissions on the target table. \ No newline at end of file From 138e683d0caea04d0534de8e86be73ea539b6fe5 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 29 May 2022 13:33:33 +0300 Subject: [PATCH 079/316] Modified Delete Guide Moved delete_guide from feature_guides to operational_guides --- feature_guides/delete.rst | 214 -------------------------------------- feature_guides/index.rst | 1 - 2 files changed, 215 deletions(-) delete mode 100644 feature_guides/delete.rst diff --git a/feature_guides/delete.rst b/feature_guides/delete.rst deleted file mode 100644 index 24ab5a218..000000000 --- a/feature_guides/delete.rst +++ /dev/null @@ -1,214 +0,0 @@ -.. _delete_guide: - -*********************** -Deleting Data -*********************** - -SQream DB supports deleting data, but it's important to understand how this works and how to maintain deleted data. - -How does deleting in SQream DB work? -======================================== - -In SQream DB, when you run a delete statement, any rows that match the delete predicate will no longer be returned when running subsequent queries. -Deleted rows are tracked in a separate location, in *delete predicates*. - -After the delete statement, a separate process can be used to reclaim the space occupied by these rows, and to remove the small overhead that queries will have until this is done. - -Some benefits to this design are: - -#. Delete transactions complete quickly - -#. The total disk footprint overhead at any time for a delete transaction or cleanup process is small and bounded (while the system still supports low overhead commit, rollback and recovery for delete transactions). - - -Phase 1: Delete ---------------------------- - -.. TODO: isn't the delete cleanup able to complete a certain amount of work transactionally, so that you can do a massive cleanup in stages? - -.. TODO: our current best practices is to use a cron job with sqream sql to run the delete cleanup. we should document how to do this, we have customers with very different delete schedules so we can give a few extreme examples and when/why you'd use them - -When a :ref:`delete` statement is run, SQream DB records the delete predicates used. These predicates will be used to filter future statements on this table until all this delete predicate's matching rows have been physically cleaned up. - -This filtering process takes full advantage of SQream's zone map feature. - -Phase 2: Clean-up --------------------- - -The cleanup process is not automatic. This gives control to the user or DBA, and gives flexibility on when to run the clean up. - -Files marked for deletion during the logical deletion stage are removed from disk. This is achieved by calling both utility function commands: ``CLEANUP_CHUNKS`` and ``CLEANUP_EXTENTS`` sequentially. - -.. note:: - * :ref:`alter_table` and other DDL operations are blocked on tables that require clean-up. See more in the :ref:`concurrency_and_locks` guide. - * If the estimated time for a cleanup processs is beyond a threshold, you will get an error message about it. The message will explain how to override this limitation and run the process anywhere. - -Notes on data deletion -========================================= - -.. note:: - * If the number of deleted records crosses the threshold defined by the ``mixedColumnChunksThreshold`` parameter, the delete operation will be aborted. - * This is intended to alert the user that the large number of deleted records may result in a large number of mixed chuncks. - * To circumvent this alert, replace XXX with the desired number of records before running the delete operation: - -.. code-block:: postgres - - set mixedColumnChunksThreshold=XXX; - - -Deleting data does not free up space ------------------------------------------ - -With the exception of a full table delete (:ref:`TRUNCATE`), deleting data does not free up disk space. To free up disk space, trigger the cleanup process. - -``SELECT`` performance on deleted rows ----------------------------------------- - -Queries on tables that have deleted rows may have to scan data that hasn't been cleaned up. -In some cases, this can cause queries to take longer than expected. To solve this issue, trigger the cleanup process. - -Use ``TRUNCATE`` instead of ``DELETE`` ---------------------------------------- -For tables that are frequently emptied entirely, consider using :ref:`truncate` rather than :ref:`delete`. TRUNCATE removes the entire content of the table immediately, without requiring a subsequent cleanup to free up disk space. - -Cleanup is I/O intensive -------------------------------- - -The cleanup process actively compacts tables by writing a complete new version of column chunks with no dead space. This minimizes the size of the table, but can take a long time. It also requires extra disk space for the new copy of the table, until the operation completes. - -Cleanup operations can create significant I/O load on the database. Consider this when planning the best time for the cleanup process. - -If this is an issue with your environment, consider using ``CREATE TABLE AS`` to create a new table and then rename and drop the old table. - - -Example -============= - -Deleting values from a table ------------------------------- - -.. code-block:: psql - - farm=> SELECT * FROM cool_animals; - 1,Dog ,7 - 2,Possum ,3 - 3,Cat ,5 - 4,Elephant ,6500 - 5,Rhinoceros ,2100 - 6,\N,\N - - 6 rows - - farm=> DELETE FROM cool_animals WHERE weight > 1000; - executed - - farm=> SELECT * FROM cool_animals; - 1,Dog ,7 - 2,Possum ,3 - 3,Cat ,5 - 6,\N,\N - - 4 rows - -Deleting values based on more complex predicates ---------------------------------------------------- - -.. code-block:: psql - - farm=> SELECT * FROM cool_animals; - 1,Dog ,7 - 2,Possum ,3 - 3,Cat ,5 - 4,Elephant ,6500 - 5,Rhinoceros ,2100 - 6,\N,\N - - 6 rows - - farm=> DELETE FROM cool_animals WHERE weight > 1000; - executed - - farm=> SELECT * FROM cool_animals; - 1,Dog ,7 - 2,Possum ,3 - 3,Cat ,5 - 6,\N,\N - - 4 rows - -Identifying and cleaning up tables ---------------------------------------- - -List tables that haven't been cleaned up -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. code-block:: psql - - farm=> SELECT t.table_name FROM sqream_catalog.delete_predicates dp - JOIN sqream_catalog.tables t - ON dp.table_id = t.table_id - GROUP BY 1; - cool_animals - - 1 row - -Identify predicates for clean-up -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. code-block:: psql - - farm=> SELECT delete_predicate FROM sqream_catalog.delete_predicates dp - JOIN sqream_catalog.tables t - ON dp.table_id = t.table_id - WHERE t.table_name = 'cool_animals'; - weight > 1000 - - 1 row - -Triggering a cleanup -^^^^^^^^^^^^^^^^^^^^^^ - -.. code-block:: psql - - -- Chunk reorganization (aka SWEEP) - farm=> SELECT CLEANUP_CHUNKS('public','cool_animals'); - executed - - -- Delete leftover files (aka VACUUM) - farm=> SELECT CLEANUP_EXTENTS('public','cool_animals'); - executed - - - farm=> SELECT delete_predicate FROM sqream_catalog.delete_predicates dp - JOIN sqream_catalog.tables t - ON dp.table_id = t.table_id - WHERE t.table_name = 'cool_animals'; - - 0 rows - - - -Best practices for data deletion -===================================== - -* Run ``CLEANUP_CHUNKS`` and ``CLEANUP_EXTENTS`` after large ``DELETE`` operations. - -* When deleting large proportions of data from very large tables, consider running a ``CREATE TABLE AS`` operation instead, then rename and drop the original table. - -* Avoid killing ``CLEANUP_EXTENTS`` operations after they've started. - -* SQream DB is optimised for time-based data. When data is naturally ordered by a date or timestamp, deleting based on those columns will perform best. For more information, see our :ref:`time based data management guide`. - - - -.. soft update concept - -.. delete cleanup and it's properties. automatic/manual, in transaction or background - -.. automatic background gives fast delete, minimal transaction overhead, -.. small cost to queries until background reorganised - -.. when does delete use the metadata effectively - -.. more examples - diff --git a/feature_guides/index.rst b/feature_guides/index.rst index fb663a336..2ca100a0f 100644 --- a/feature_guides/index.rst +++ b/feature_guides/index.rst @@ -11,7 +11,6 @@ This section describes the following features: :maxdepth: 1 :titlesonly: - delete_guide key_evaluation data_encryption compression From e2be508ed8dec82a2fa18a5dc91c318a2804d074 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 30 May 2022 12:06:21 +0300 Subject: [PATCH 080/316] Update data_encryption_overview.rst Integrated Raz Tamir's comments on this page. --- feature_guides/data_encryption_overview.rst | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/feature_guides/data_encryption_overview.rst b/feature_guides/data_encryption_overview.rst index 58bb7ea40..a37325e52 100644 --- a/feature_guides/data_encryption_overview.rst +++ b/feature_guides/data_encryption_overview.rst @@ -11,11 +11,7 @@ The demand for confidentiality has steadily increased to protect the growing vol Encryption can be used for the following: -* Deleting encrypted columns. - - :: - -* Creating tables with one or more encrypted columns. +* Creating tables up to three encrypted columns. :: @@ -23,10 +19,6 @@ Encryption can be used for the following: :: -* Encrypting existing data. - - :: - * Selecting data from an encrypted column. For more information on the encryption syntax, see :ref:`data_encryption_syntax`. From ce49d1129f120de98bb8308fa40df062d2243f31 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 30 May 2022 12:08:48 +0300 Subject: [PATCH 081/316] Updated for 2022.1 --- index.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/index.rst b/index.rst index cb7d685b2..29ea038b0 100644 --- a/index.rst +++ b/index.rst @@ -4,7 +4,7 @@ SQream DB Documentation ************************* -The **2022.3 Preview** branch is a private branch designed for internal use only. +The **v2022.1** branch is a private branch designed for internal use only until the release date. .. only:: html @@ -57,7 +57,9 @@ SQream DB easily plugs in to third-party tools like :ref:`Tableau` + :ref:`2022.1<2022.1>` + + :ref:`2021.2<2021.2>` :ref:`2021.1<2021.1>` @@ -87,7 +89,7 @@ If you couldn't find what you're looking for, we're always happy to help. Visit .. rubric:: Looking for older versions? -This version of the documentation is for SQream DB Version 2021.2. +This version of the documentation is for SQream DB Version 2022.1. If you're looking for an older version of the documentation, versions 1.10 through 2019.2.1 are available at http://previous.sqream.com . From c675e002792e47bc2c5e9c392c7ca47e13f56095 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 30 May 2022 13:18:40 +0300 Subject: [PATCH 082/316] Changed 40% to 30% Degradation Raz Tamar email. --- releases/2022.1.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releases/2022.1.rst b/releases/2022.1.rst index 7b2d9d4dd..53c314faf 100644 --- a/releases/2022.1.rst +++ b/releases/2022.1.rst @@ -29,7 +29,7 @@ Data Encryption ************ SQream now supports data encryption mechanisms in accordance with **General Data Protection Regulation (GDPR)** standards. -Using the data encryption feature may lead to a maximum of a 40% increase in performance degradation. +Using the data encryption feature may lead to a maximum of a 30% increase in performance degradation. For more information, see `Data Encryption `_. From fa271aa442ddc9638db3f6950676a19bc93d4d09 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 30 May 2022 15:01:47 +0300 Subject: [PATCH 083/316] Update cluster_by.rst --- reference/sql/sql_statements/ddl_commands/cluster_by.rst | 4 ---- 1 file changed, 4 deletions(-) diff --git a/reference/sql/sql_statements/ddl_commands/cluster_by.rst b/reference/sql/sql_statements/ddl_commands/cluster_by.rst index e4cf42ad4..7dcedaaf1 100644 --- a/reference/sql/sql_statements/ddl_commands/cluster_by.rst +++ b/reference/sql/sql_statements/ddl_commands/cluster_by.rst @@ -7,10 +7,6 @@ The ``CLUSTER BY`` command is used for changing clustering keys in a table. For more information, see the following: -* :ref:`flexible_data_clustering` - - :: - * :ref:`drop_clustering_key` :: From 49bb8df32937b571e8af6e37d3f2669e6b20873c Mon Sep 17 00:00:00 2001 From: YanivGerowitz <82020437+YanivGerowitz@users.noreply.github.com> Date: Tue, 7 Jun 2022 14:37:41 +0300 Subject: [PATCH 084/316] Update show_server_status.rst TPD-128 --- .../utility_commands/show_server_status.rst | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/reference/sql/sql_statements/utility_commands/show_server_status.rst b/reference/sql/sql_statements/utility_commands/show_server_status.rst index f59f79ccc..73902a046 100644 --- a/reference/sql/sql_statements/utility_commands/show_server_status.rst +++ b/reference/sql/sql_statements/utility_commands/show_server_status.rst @@ -3,18 +3,13 @@ ******************** SHOW_SERVER_STATUS ******************** - ``SHOW_SERVER_STATUS`` returns a list of active sessions across the cluster. To list active statements on the current worker only, see :ref:`show_connections`. -Permissions -============= - -The role must have the ``SUPERUSER`` permissions. - Syntax ========== +The following is the correct syntax when showing your server status: .. code-block:: postgres @@ -24,85 +19,90 @@ Syntax Parameters ============ - -None +The Parameters section is not relevant for the ``SHOW_SERVER_STATUS`` statement. Returns ========= +The ``SHOW_SERVER_STATUS`` function returns a list of active sessions. If no sessions are active across the cluster, the result set will be empty. -This function returns a list of active sessions. If no sessions are active across the cluster, the result set will be empty. +The following table shows the ``SHOW_SERVER_STATUS`` result columns; -.. list-table:: Result columns +.. list-table:: Result Columns :widths: auto :header-rows: 1 - * - ``service`` - - The service name for the statement + * - service + - Statement Service Name * - ``instance`` - - The worker ID + - Shows the worker ID. * - ``connection_id`` - - Connection ID + - Shows the connection ID. * - ``serverip`` - - Worker end-point IP + - Shows the worker end-point IP. * - ``serverport`` - - Worker end-point port + - Shows the worker end-point port. * - ``database_name`` - - Database name for the statement + - Shows the statement's database name. * - ``user_name`` - - Username running the statement + - Shows the username running the statement. * - ``clientip`` - - Client IP + - Shows the client IP. * - ``statementid`` - - Statement ID + - Shows the statement ID. * - ``statement`` - - Statement text + - Shows the statement text. * - ``statementstarttime`` - - Statement start timestamp + - Shows the statement start timestamp. * - ``statementstatus`` - - Statement status (see table below) + - Shows the statement status (see table below). * - ``statementstatusstart`` - - Last updated timestamp + - Shows the most recently updated timestamp. .. include from here: 66 +The following table shows the statement status values: -.. list-table:: Statement status values +.. list-table:: Statement Status Values :widths: auto :header-rows: 1 * - Status - Description * - ``Preparing`` - - Statement is being prepared + - The statement is being prepared. * - ``In queue`` - - Statement is waiting for execution + - The statement is waiting for execution. * - ``Initializing`` - - Statement has entered execution checks + - The statement has entered execution checks. * - ``Executing`` - - Statement is executing + - The statement is executing. * - ``Stopping`` - - Statement is in the process of stopping - + - The statement is in the process of stopping. .. include until here 86 Notes =========== +This utility shows the active sessions. Some sessions may be actively connected, but not running any statements. -* This utility shows the active sessions. Some sessions may be actively connected, but not running any statements. - -Examples +Example =========== -Using ``SHOW_SERVER_STATUS`` to get statement IDs +Using SHOW_SERVER_STATUS to Get Statement IDs ---------------------------------------------------- - +The following example shows how to use the ``SHOW_SERVER_STATUS`` statement to get statement IDs: .. code-block:: psql t=> SELECT SHOW_SERVER_STATUS(); - service | instanceid | connection_id | serverip | serverport | database_name | user_name | clientip | statementid | statement | statementstarttime | statementstatus | statementstatusstart - --------+------------+---------------+--------------+------------+---------------+------------+-------------+-------------+-----------------------------+---------------------+-----------------+--------------------- - sqream | | 102 | 192.168.1.91 | 5000 | t | rhendricks | 192.168.0.1 | 128 | SELECT SHOW_SERVER_STATUS() | 24-12-2019 00:14:53 | Executing | 24-12-2019 00:14:53 + service | instanceid | connection_id | serverip | serverport | database_name | user_name | clientip | statementid | statement | statementstarttime | statementstatus | statementstatusstart + --------+------------+---------------+---------------+------------+---------------+------------------+---------------+-------------+-------------------------------------------------------------------------------------------------------+---------------------+-----------------+--------------------- + sqream | sqream_2 | 19 | 192.168.0.111 | 5000 | master | etl | 192.168.0.011 |2484923 | SELECT t1.account, t1.msisd from table a t1 join table b t2 on t1.id = t2.id where t1.msid='123123'; | 17-01-2022 16:19:31 | Executing | 17-01-2022 16:19:32 + sqream | sqream_1 | 2 | 192.168.1.112 | 5000 | master | etl | 192.168.1.112 |2484924 | select show_server_status(); | 17-01-2022 16:19:39 | Executing | 17-01-2022 16:19:39 + sqream | None | 248 | 192.168.1.112 | 5007 | master | maintenance_user | 192.168.1.112 |2484665 | select * from sqream_catalog.tables; | 17-01-2022 15:55:01 | In Queue | 17-01-2022 15:55:02 The statement ID is ``128``, running on worker ``192.168.1.91``. + +Permissions +============= +The role must have the ``SUPERUSER`` permissions. From 1025d496f917f67922b863891adbb1a8949f85da Mon Sep 17 00:00:00 2001 From: YanivGerowitz <82020437+YanivGerowitz@users.noreply.github.com> Date: Sun, 12 Jun 2022 10:44:51 +0300 Subject: [PATCH 085/316] TPD-67 --- .../client_drivers/jdbc/index.rst | 127 ++++++++++-------- 1 file changed, 68 insertions(+), 59 deletions(-) diff --git a/third_party_tools/client_drivers/jdbc/index.rst b/third_party_tools/client_drivers/jdbc/index.rst index 42a04548f..4c35c3eff 100644 --- a/third_party_tools/client_drivers/jdbc/index.rst +++ b/third_party_tools/client_drivers/jdbc/index.rst @@ -3,160 +3,169 @@ ************************* JDBC ************************* +The SQream JDBC driver lets you connect to SQream using many Java applications and tools. This page describes how to write a Java application using the JDBC interface. The JDBC driver requires Java 1.8 or newer. -The SQream DB JDBC driver allows many Java applications and tools connect to SQream DB. -This tutorial shows how to write a Java application using the JDBC interface. +The JDBC page includes the following sections: -The JDBC driver requires Java 1.8 or newer. - -.. contents:: In this topic: +.. contents:: :local: + :depth: 1 -Installing the JDBC driver +Installing the JDBC Driver ================================== +The **Installing the JDBC Driver** section describes the following: + +.. contents:: + :local: + :depth: 1 Prerequisites ---------------- +The SQream JDBC driver requires Java 1.8 or newer, and SQream recommends using Oracle Java or OpenJDK.: -The SQream DB JDBC driver requires Java 1.8 or newer. We recommend either Oracle Java or OpenJDK. - -**Oracle Java** - -Download and install Java 8 from Oracle for your platform +* **Oracle Java** - Download and install `Java 8 `_ from Oracle for your platform. -https://www.java.com/en/download/manual.jsp - -**OpenJDK** - -For Linux and BSD, see https://openjdk.java.net/install/ - -For Windows, SQream recommends Zulu 8 https://www.azul.com/downloads/zulu-community/?&version=java-8-lts&architecture=x86-64-bit&package=jdk + :: + +* **OpenJDK** - Install `OpenJDK `_ -.. _get_jdbc_jar: + :: + +* **Windows** - SQream recommends installing `Zulu 8 `_ Getting the JAR file --------------------- +SQream provides the JDBC driver as a zipped JAR file, available for download from the :ref:`client drivers download page`. This JAR file can be integrated into your Java-based applications or projects. -The JDBC driver is provided as a zipped JAR file, available for download from the :ref:`client drivers download page`. This JAR file can integrate into your Java-based applications or projects. - - -Extract the zip archive +Extracting the ZIP Archive ------------------------- - -Extract the JAR file from the zip archive +Run the following command to extract the JAR file from the ZIP archive: .. code-block:: console $ unzip sqream-jdbc-4.3.0.zip -Setting up the Class Path +Setting Up the Class Path ---------------------------- +To use the driver, you must include the JAR named ``sqream-jdbc-.jar`` in the class path, either by inserting it in the ``CLASSPATH`` environment variable, or by using flags on the relevant Java command line. -To use the driver, the JAR named ``sqream-jdbc-.jar`` (for example, ``sqream-jdbc-4.3.0.jar``) needs to be included in the class path, either by putting it in the ``CLASSPATH`` environment variable, or by using flags on the relevant Java command line. - -For example, if the JDBC driver has been unzipped to ``/home/sqream/sqream-jdbc-4.3.0.jar``, the application should be run as follows: +For example, if the JDBC driver has been unzipped to ``/home/sqream/sqream-jdbc-4.3.0.jar``, the following command is used to run application: .. code-block:: console $ export CLASSPATH=/home/sqream/sqream-jdbc-4.3.0.jar:$CLASSPATH $ java my_java_app -An alternative method is to pass ``-classpath`` to the Java executable: +Alternatively, you can pass ``-classpath`` to the Java executable file: .. code-block:: console $ java -classpath .:/home/sqream/sqream-jdbc-4.3.0.jar my_java_app - -Connect to SQream DB with a JDBC application +Connecting to SQream Using a JDBC Application ============================================== +You can connect to SQream using one of the following JDBC applications: -Driver class +.. contents:: + :local: + :depth: 1 + +Driver Class -------------- - Use ``com.sqream.jdbc.SQDriver`` as the driver class in the JDBC application. - -.. _connection_string: - -Connection string +Connection String -------------------- +JDBC drivers rely on a connection string. -JDBC drivers rely on a connection string. Use the following syntax for SQream DB +The following is the syntax for SQream: .. code-block:: text jdbc:Sqream:///;user=;password=sqream;[; ...] -Connection parameters +Connection Parameters ^^^^^^^^^^^^^^^^^^^^^^^^ +The following table shows the connection string parameters: .. list-table:: :widths: auto :header-rows: 1 * - Item - - Optional + - State - Default - Description * - ```` - - ✗ + - Mandatory - None - Hostname and port of the SQream DB worker. For example, ``127.0.0.1:5000``, ``sqream.mynetwork.co:3108`` * - ```` - - ✗ + - Mandatory - None - Database name to connect to. For example, ``master`` * - ``username=`` - - ✗ + - Mandatory - None - Username of a role to use for connection. For example, ``username=rhendricks`` * - ``password=`` - - ✗ + - Mandatory - None - Specifies the password of the selected role. For example, ``password=Tr0ub4dor&3`` * - ``service=`` - - ✓ + - Optional - ``sqream`` - Specifices service queue to use. For example, ``service=etl`` * - ```` - - ✓ + - Optional - ``false`` - Specifies SSL for this connection. For example, ``ssl=true`` * - ```` - - ✓ + - Optional - ``true`` - Connect via load balancer (use only if exists, and check port). + * - ```` + - Optional + - ``true`` + - Enables on-demand loading, and defines double buffer size for result. The ``fetchSize`` parameter is rounded according to chunk size. For example, ``fetchSize=1`` loads one row and is rounded to one chunk. If the fetchSize is 100,600, a chunk size of 100,000 loads, and is rounded to, two chunks. + * - ```` + - Optional + - ``true`` + - Defines the bytes size for inserting a buffer before flushing data to the server. Clients running a parameterized insert (network insert) can define the amount of data to collect before flushing the buffer. + * - ```` + - Optional + - ``true`` + - Defines the logger level as either ``debug`` or ``trace``. + * - ```` + - Optional + - ``true`` + - Enables the file appender and defines the file name. The file name can be set as either the file name or the file path. -Connection string examples +Connection String Examples ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -For a SQream DB cluster with load balancer and no service queues, with SSL +The following is an example of a SQream cluster with load balancer and no service queues (with SSL): .. code-block:: text jdbc:Sqream://sqream.mynetwork.co:3108/master;user=rhendricks;password=Tr0ub4dor&3;ssl=true;cluster=true -Minimal example for a local, standalone SQream DB +The following is a minimal example for a local standalone SQream database: .. code-block:: text jdbc:Sqream://127.0.0.1:5000/master;user=rhendricks;password=Tr0ub4dor&3 -For a SQream DB cluster with load balancer and a specific service queue named ``etl``, to the database named ``raviga`` +The following is an example of a SQream cluster with load balancer and a specific service queue named ``etl``, to the database named ``raviga`` .. code-block:: text jdbc:Sqream://sqream.mynetwork.co:3108/raviga;user=rhendricks;password=Tr0ub4dor&3;cluster=true;service=etl - -Sample Java program +Sample Java Program -------------------- - -Download this file by right clicking and saving to your computer :download:`sample.java `. +You can download the :download:`JDBC Application Sample File ` below by right-clicking and saving it to your computer. .. literalinclude:: sample.java :language: java - :caption: JDBC application sample + :caption: JDBC Application Sample :linenos: - From 3abe6527279c7dfd15a3ce07cdcebc5e2b4bf194 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 23 Jun 2022 11:08:59 +0300 Subject: [PATCH 086/316] Added missing table --- .../ddl_commands/create_table.rst | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/reference/sql/sql_statements/ddl_commands/create_table.rst b/reference/sql/sql_statements/ddl_commands/create_table.rst index 788c71b31..51f46582b 100644 --- a/reference/sql/sql_statements/ddl_commands/create_table.rst +++ b/reference/sql/sql_statements/ddl_commands/create_table.rst @@ -3,7 +3,7 @@ ***************** CREATE TABLE ***************** - + The ``CREATE TABLE`` statement is used to create a new table in an existing database. .. tip:: @@ -62,7 +62,7 @@ The following parameters can be used when creating a table: - A commma separated list of clustering column keys. - See :ref:`data_clustering` for more information. + See :ref:`flexible_data_clustering` for more information. * - ``LIKE`` - Duplicates the column structure of an existing table. @@ -141,7 +141,7 @@ The following is an example of the syntax used to create a standard table: CREATE TABLE cool_animals ( id INT NOT NULL, - name text(30) NOT NULL, + name varchar(30) NOT NULL, weight FLOAT, is_agressive BOOL ); @@ -155,7 +155,7 @@ The following is an example of the syntax used to create a table with default va CREATE TABLE cool_animals ( id INT NOT NULL, - name text(30) NOT NULL, + name varchar(30) NOT NULL, weight FLOAT, is_agressive BOOL DEFAULT false NOT NULL ); @@ -171,8 +171,8 @@ The following is an example of the syntax used to create a table with an identit CREATE TABLE users ( id BIGINT IDENTITY(0,1) NOT NULL , -- Start with 0, increment by 1 - name TEXT(30) NOT NULL, - country TEXT(30) DEFAULT 'Unknown' NOT NULL + name VARCHAR(30) NOT NULL, + country VARCHAR(30) DEFAULT 'Unknown' NOT NULL ); .. note:: @@ -203,9 +203,9 @@ The following is an example of the syntax used to create a table with a clusteri .. code-block:: postgres CREATE TABLE users ( - name TEXT(30) NOT NULL, + name VARCHAR(30) NOT NULL, start_date datetime not null, - country TEXT(30) DEFAULT 'Unknown' NOT NULL + country VARCHAR(30) DEFAULT 'Unknown' NOT NULL ) CLUSTER BY start_date; For more information on data clustering, see :ref:`data_clustering`. @@ -261,9 +261,9 @@ Either of the following examples can be used to create a second table based on t The generated output of both of the statements above is identical. -Creating a Table based on External Tables and Views +Creating a Table based on Foreign Tables and Views ~~~~~~~~~~~~ -The following is example of creating a table based on external tables and views: +The following is example of creating a table based on foreign tables and views: .. code-block:: postgres @@ -272,7 +272,7 @@ The following is example of creating a table based on external tables and views: CREATE TABLE t3 LIKE v; When duplicating the column structure of an existing table, the target table of the ``LIKE`` clause can be a regular or an external table, or a view. - + The following table describes the properties that must be copied from the target table: +-----------------------------+------------------+---------------------------------+---------------------------------+ @@ -293,4 +293,4 @@ The following table describes the properties that must be copied from the target Permissions ============= -The role must have the ``CREATE`` permission at the schema level. +The role must have the ``CREATE`` permission at the schema level. \ No newline at end of file From cadff73cb4b1bd196ba74fffc98c00dda54fdad5 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 23 Jun 2022 11:21:16 +0300 Subject: [PATCH 087/316] Added missing varchar --- reference/sql/sql_syntax/literals.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/reference/sql/sql_syntax/literals.rst b/reference/sql/sql_syntax/literals.rst index d1ec35dbe..906684590 100644 --- a/reference/sql/sql_syntax/literals.rst +++ b/reference/sql/sql_syntax/literals.rst @@ -86,7 +86,7 @@ Examples '1997-01-01' -- This is a string -The actual data type of the value changes based on context, the format used, and the value itself. In the example below, the first value is interpreted as a ``DATE``, while the second is interpreted as a ``TEXT``. +The actual data type of the value changes based on context, the format used, and the value itself. In the example below, the first value is interpreted as a ``DATE``, while the second is interpreted as a ``VARCHAR``. .. code-block:: postgres @@ -239,6 +239,7 @@ The following is a syntax reference for typed literals: | REAL | DATE | DATETIME + | VARCHAR ( digits ) | TEXT ( digits ) Examples From 0c1373094a37eb668559673b03df0c7974132758 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 28 Jun 2022 11:06:27 +0300 Subject: [PATCH 088/316] Update 2022.1.rst Changed 30% to 10%. --- releases/2022.1.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releases/2022.1.rst b/releases/2022.1.rst index 53c314faf..45479026d 100644 --- a/releases/2022.1.rst +++ b/releases/2022.1.rst @@ -29,7 +29,7 @@ Data Encryption ************ SQream now supports data encryption mechanisms in accordance with **General Data Protection Regulation (GDPR)** standards. -Using the data encryption feature may lead to a maximum of a 30% increase in performance degradation. +Using the data encryption feature may lead to a maximum of a 10% increase in performance degradation. For more information, see `Data Encryption `_. From b456263b75d53f853c33e27592592f2ace13e152 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 30 Jun 2022 16:10:36 +0300 Subject: [PATCH 089/316] Update 2022.1.rst --- releases/2022.1.rst | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/releases/2022.1.rst b/releases/2022.1.rst index 45479026d..a98a397f8 100644 --- a/releases/2022.1.rst +++ b/releases/2022.1.rst @@ -74,7 +74,31 @@ No relevant naming changes were made. Deprecated Features ------- -No features were depecrated. +In SQream version 2022.1 the ``VARCHAR`` data type has been deprecated and replaced with ``TEXT``. ``VARCHAR`` will be maintained in all previous versions until migration to ``TEXT`` is complete, at which point it will be deprecated in all earlier versions. + +If you are using an earlier version of SQream, see `Using Legacy String Literals `_. + +An automated process is being used to facilitate migration from ``VARCHAR`` to ``TEXT``. For more information, contact SQream. + +**Comment** - *Below is the original text of the VARCHAR deprecation email. I don't think that we need to necessarily expose our logic to our customers, but focus on certain aspects of it (see the first paragraph above). However, I can use more/all of this content if deemed necessary.* + +* SQream has decided to deprecated support in varchar data type, the decision made out of SQream effort to enhance its core functionalities and with respect to ever changing eco system requirements. + + :: + +* For new customers Varchar data type is not supported + + :: + +* The supported data type that will replace this data type is text as all different functionalities encapsulated within this data type + + :: + +* SQream will maintain varchar data type support until the last customer will be fully migrated + + :: + +* In order to enhance the conversion mechanism to be as fast as possible SQream will provide an automated and secured tool to help customers with the conversion phase from VARCHAR to TEXT data type, please address delivery for further information Known Issues and Limitations -------- @@ -87,6 +111,8 @@ The the list below describes the following known issues and limitations: End of Support ------- +**Comment** - *We need to know what to put here.* + This section is not relevant to the 2022.1 release notes. Upgrading to v2022.1 From 24011e664692d0116fd4875a93a980acc7b30bc0 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 3 Jul 2022 11:10:24 +0300 Subject: [PATCH 090/316] Removed FULL OUTER JOIN https://sqream.atlassian.net/browse/SQ-10996 --- reference/sql/sql_syntax/joins.rst | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/reference/sql/sql_syntax/joins.rst b/reference/sql/sql_syntax/joins.rst index 2563e7a5d..b12b08875 100644 --- a/reference/sql/sql_syntax/joins.rst +++ b/reference/sql/sql_syntax/joins.rst @@ -46,8 +46,8 @@ The following shows the correct syntax for creating an **inner join**: .. code-block:: postgres - left_side [ INNER ] JOIN right_side ON value_expr - left_side [ INNER ] JOIN right_side USING ( join_column [, ... ] ) + left_side [ INNER ] JOIN left_side ON value_expr + left_side [ INNER ] JOIN left_side USING ( join_column [, ... ] ) Inner joins are the default join type and return rows from the ``left_side`` and ``right_side`` based on a matching condition. @@ -60,7 +60,6 @@ An inner join can also be specified by listing several tables in the ``FROM`` cl [ { INNER JOIN | LEFT [OUTER] JOIN | RIGHT [OUTER] JOIN - | FULL [OUTER] JOIN } table2 ON table1.column1 = table2.column1 ] Omitting the ``ON`` or ``WHERE`` clause creates a ``CROSS JOIN``, where every ``left_side`` row is matched with every ``right_side`` row. @@ -117,7 +116,7 @@ The ``CROSS JOIN`` clause cannot have an ``ON`` clause, but the ``WHERE`` clause The following is an example of two tables that will be used as the basis for a cross join: -.. image:: /_static/images/joins/color_table.png +.. image:: /_static/images/color_table.png The following is the output result of the cross join: @@ -323,4 +322,4 @@ The following is an example of using a join hint: --+--- 2 | 2 4 | 4 - 5 | 5 + 5 | 5 \ No newline at end of file From dd2da3b8656204245f2349bf8b832df7547c9638 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 3 Jul 2022 11:22:40 +0300 Subject: [PATCH 091/316] Create color_table.png --- _static/images/color_table.png | Bin 0 -> 5672 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 _static/images/color_table.png diff --git a/_static/images/color_table.png b/_static/images/color_table.png new file mode 100644 index 0000000000000000000000000000000000000000..b815f96167688d7c5b770dc427a358bc6169789a GIT binary patch literal 5672 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 literal 0 HcmV?d00001 From 823c64e552c995b1006ac98af4ba145630fbd03a Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 3 Jul 2022 14:11:33 +0300 Subject: [PATCH 092/316] Updated Tableau Connector Link --- third_party_tools/client_drivers/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party_tools/client_drivers/index.rst b/third_party_tools/client_drivers/index.rst index 91cb94e8f..eebeeb003 100644 --- a/third_party_tools/client_drivers/index.rst +++ b/third_party_tools/client_drivers/index.rst @@ -24,7 +24,7 @@ The following are applicable to all operating systems: * **Tableau**: - * `https://sq-ftp-public.s3.amazonaws.com/SQreamTaco.rar>`_ - SQream (.taco) + * `Tableau connector `_ - SQream (.taco) * `Tableau manual installation `_ From bceda57ad26b51c5bd2731796f5d4eae3456f0f7 Mon Sep 17 00:00:00 2001 From: YanivGerowitz <82020437+YanivGerowitz@users.noreply.github.com> Date: Wed, 6 Jul 2022 11:46:13 +0300 Subject: [PATCH 093/316] Tables: https://sqream.atlassian.net/browse/TPD-208 --- .../sql_statements/dml_commands/copy_to.rst | 376 ++++++++++++++++-- 1 file changed, 345 insertions(+), 31 deletions(-) diff --git a/reference/sql/sql_statements/dml_commands/copy_to.rst b/reference/sql/sql_statements/dml_commands/copy_to.rst index 85632904f..bd32a325f 100644 --- a/reference/sql/sql_statements/dml_commands/copy_to.rst +++ b/reference/sql/sql_statements/dml_commands/copy_to.rst @@ -3,20 +3,23 @@ ********************** COPY TO ********************** +The **COPY TO** page includes the following sections: +.. contents:: + :local: + :depth: 1 + +Overview +========== ``COPY ... TO`` is a statement that can be used to export data from a SQream database table or query to a file on the filesystem. In general, ``COPY`` moves data between filesystem files and SQream DB tables. .. note:: To copy data from a file to a table, see :ref:`COPY FROM`. -Permissions -============= - -The role must have the ``SELECT`` permission on every table or schema that is referenced by the statement. - Syntax ========== +The following is the correct syntax for using the **COPY TO** statement: .. code-block:: postgres @@ -29,7 +32,7 @@ Syntax ) ; - fdw_name ::= csw_fdw | parquet_fdw | orc_fdw | avro_fdw + fdw_name ::= csw_fdw | parquet_fdw | orc_fdw schema_name ::= identifer @@ -48,6 +51,11 @@ Syntax | AWS_ID = '{ AWS ID }' | AWS_SECRET = '{ AWS Secret }' + + | MAX_FILE_SIZE = '{ size_in_bytes }' + + | ENFORCE_SINGLE_FILE = { true | false } + delimiter ::= string @@ -57,8 +65,13 @@ Syntax AWS Secret ::= string +.. note:: The DELIMITER is applicable to the CSV format only. + +.. note:: In Studio, you must write the parameters using lower case letters. Using upper case letters generates an error. + Elements ============ +The following table shows the ``COPY_TO`` elements: .. list-table:: :widths: auto @@ -80,41 +93,332 @@ Elements - Specifies the character that separates fields (columns) within each row of the file. The default is a comma character (``,``). * - ``AWS_ID``, ``AWS_SECRET`` - Specifies the authentication details for secured S3 buckets + * - ``MAX_FILE_SIZE`` + - Sets the maximum file size (bytes). Default value: 16*2^20 (16MB). + * - ``ENFORCE_SINGLE_FILE`` + - Enforces the maximum file size (bytes). Permitted values: ``true`` - creates one file of unlimited size, ``false`` - permits creating several files together limited by the ``MAX_FILE_SIZE``. When set to ``true``, the single file size is not limited by the ``MAX_FILE_SIZE`` setting. When set to ``false``, the combined file sizes cannot exceed the ``MAX_FILE_SIZE``. Default value: ``FALSE``. -Usage notes +Usage Notes =============== +The **Usage Notes** describes the following: + +.. contents:: + :local: + :depth: 1 -Supported field delimiters +Supported Field Delimiters ------------------------------ +The **Supported Field Delimiters** section describes the following: -Printable characters -^^^^^^^^^^^^^^^^^^^^^ +.. contents:: + :local: + :depth: 1 +Printable ASCII Characters +^^^^^^^^^^^^^^^^^^^^^ Any printable ASCII character can be used as a delimiter without special syntax. The default CSV field delimiter is a comma (``,``). -A printable character is any ASCII character in the range 32 - 126. - -Non-printable characters +The following table shows the supported printable ASCII characters: + ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| **Character** | **Description** | **ASCII** | **Octal** | **Hex** | **Binary** | **HTML Code** | **HTML Name** | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| (Space) | Space | 32 | 40 | 20 | 100000 | | | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| ! | Exclamation Mark | 33 | 41 | 21 | 100001 | ! | ! | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| # | Hash or Number | 35 | 43 | 23 | 100011 | # | # | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| $ | Dollar Sign | 36 | 44 | 24 | 100100 | $ | $ | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| % | Percentage | 37 | 45 | 25 | 100101 | % | % | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| & | Ampersand | 38 | 46 | 26 | 100110 | & | & | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| ( | Left Parenthesis | 40 | 50 | 28 | 101000 | ( | ( | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| ) | Right Parenthesis | 41 | 51 | 29 | 101001 | ) | ) | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| * | Asterisk | 42 | 52 | 2A | 101010 | * | * | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| + | Plus Sign | 43 | 53 | 2B | 101011 | + | + | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| , | Comma | 44 | 54 | 2C | 101100 | , | , | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| / | Slash | 47 | 57 | 2F | 101111 | / | / | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| ; | Semicolon | 59 | 73 | 3B | 111011 | ; | ; | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| < | Less Than | 60 | 74 | 3C | 111100 | < | < | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| = | Equals Sign | 61 | 75 | 3D | 111101 | = | = | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| > | Greater Than | 62 | 76 | 3E | 111110 | > | > | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| ? | Question Mark | 63 | 77 | 3F | 111111 | ? | ? | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| @ | At Sign | 64 | 100 | 40 | 1000000 | @ | @ | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| [ | Left Square Bracket | 91 | 133 | 5B | 1011011 | [ | [ | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| \ | Backslash | 92 | 134 | 5C | 1011100 | \ | \ | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| ] | Right Square Bracket | 93 | 135 | 5D | 1011101 | ] | ] | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| ^ | Caret or Circumflex | 94 | 136 | 5E | 1011110 | ^ | &hat; | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| _ | Underscore | 95 | 137 | 5F | 1011111 | _ | _ | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| ` | Grave Accent | 96 | 140 | 60 | 1100000 | ` | ` | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| { | Left Curly Bracket | 123 | 173 | 7B | 1111011 | { | { | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| | | Vertical Bar | 124 | 174 | 7C | 1111100 | | | | | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| } | Right Curly Bracket | 125 | 175 | 7D | 1111101 | } | } | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ +| ~ | Tilde | 126 | 176 | 7E | 1111110 | ~ | ˜ | ++---------------+----------------------+-----------+-----------+---------+------------+---------------+---------------+ + +Non-Printable ASCII Characters ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -A non-printable character (1 - 31, 127) can be used in its octal form. - +The following table shows the supported non-printable ASCII characters: + ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| **Character** | **Description** | **Octal** | **ASCII** | **Hex** | **Binary** | **HTML Code** | **HTML Name** | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| NUL | Null | 0 | 0 | 0 | 0 | � | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| SOH | Start of Heading | 1 | 1 | 1 | 1 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| STX | Start of Text | 2 | 2 | 2 | 10 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| ETX | End of Text | 3 | 3 | 3 | 11 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| EOT | End of Transmission | 4 | 4 | 4 | 100 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| ENQ | Enquiry | 5 | 5 | 5 | 101 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| ACK | Acknowledge | 6 | 6 | 6 | 110 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| BEL | Bell | 7 | 7 | 7 | 111 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| BS | Backspace | 10 | 8 | 8 | 1000 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| HT | Horizontal Tab | 11 | 9 | 9 | 1001 | | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| VT | Vertical Tab | 13 | 11 | 0B | 1011 | | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| FF | NP Form Feed, New Page | 14 | 12 | 0C | 1100 | | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| SO | Shift Out | 16 | 14 | 0E | 1110 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| SI | Shift In | 17 | 15 | 0F | 1111 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| DLE | Data Link Escape | 20 | 16 | 10 | 10000 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| DC1 | Device Control 1 | 21 | 17 | 11 | 10001 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| DC2 | Device Control 2 | 22 | 18 | 12 | 10010 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| DC3 | Device Control 3 | 23 | 19 | 13 | 10011 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| DC4 | Device Control 4 | 24 | 20 | 14 | 10100 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| NAK | Negative Acknowledge | 25 | 21 | 15 | 10101 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| SYN | Synchronous Idle | 26 | 22 | 16 | 10110 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| ETB | End of Transmission Block | 27 | 23 | 17 | 10111 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| CAN | Cancel | 30 | 24 | 18 | 11000 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| EM | End of Medium | 31 | 25 | 19 | 11001 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| SUB | Substitute | 32 | 26 | 1A | 11010 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| ESC | Escape | 33 | 27 | 1B | 11011 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| FS | File Separator | 34 | 28 | 1C | 11100 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| GS | Group Separator | 35 | 29 | 1D | 11101 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| RS | Record Separator | 36 | 30 | 1E | 11110 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| US | Unit Separator | 37 | 31 | 1F | 11111 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ +| DEL | Delete | 177 | 127 | 7F | 1111111 |  | | ++---------------+---------------------------+-----------+-----------+---------+------------+---------------+---------------+ + A tab can be specified by escaping it, for example ``\t``. Other non-printable characters can be specified using their octal representations, by using the ``E'\000'`` format, where ``000`` is the octal value of the character. For example, ASCII character ``15``, known as "shift in", can be specified using ``E'\017'``. +.. note:: Delimiters are only applicable to the CSV file format. -Date format +Unsupported ASCII Field Delimiters +------------------------------ +The following table shows the unsupported ASCII field delimiters: + ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| **ASCII** | **Character** | **Description** | **Octal** | **Hex** | **Binary** | **HTML Code** | **HTML Name** | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 10 | LF | NL Line Feed, New Line | 12 | 0A | 1010 | | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 13 | CR | Carriage Return | 15 | 0D | 1101 | | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 34 | " | Double Quote | 42 | 22 | 100010 | " | " | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 39 | ' | Single Quote | 47 | 27 | 100111 | ' | ' | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 45 | - | Minus Sign | 55 | 2D | 101101 | - | − | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 46 | . | Period | 56 | 2E | 101110 | . | . | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 48 | 0 | Zero | 60 | 30 | 110000 | 0 | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 49 | 1 | Number One | 61 | 31 | 110001 | 1 | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 50 | 2 | Number Two | 62 | 32 | 110010 | 2 | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 51 | 3 | Number Three | 63 | 33 | 110011 | 3 | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 52 | 4 | Number Four | 64 | 34 | 110100 | 4 | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 53 | 5 | Number Five | 65 | 35 | 110101 | 5 | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 54 | 6 | Number Six | 66 | 36 | 110110 | 6 | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 55 | 7 | Number Seven | 67 | 37 | 110111 | 7 | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 56 | 8 | Number Eight | 70 | 38 | 111000 | 8 | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 57 | 9 | Number Nine | 71 | 39 | 111001 | 9 | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 58 | : | Colon | 72 | 3A | 111010 | : | : | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 65 | A | Upper Case Letter A | 101 | 41 | 1000001 | A | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 66 | B | Upper Case Letter B | 102 | 42 | 1000010 | B | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 67 | C | Upper Case Letter C | 103 | 43 | 1000011 | C | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 68 | D | Upper Case Letter D | 104 | 44 | 1000100 | D | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 69 | E | Upper Case Letter E | 105 | 45 | 1000101 | E | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 70 | F | Upper Case Letter F | 106 | 46 | 1000110 | F | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 71 | G | Upper Case Letter G | 107 | 47 | 1000111 | G | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 72 | H | Upper Case Letter H | 110 | 48 | 1001000 | H | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 73 | I | Upper Case Letter I | 111 | 49 | 1001001 | I | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 74 | J | Upper Case Letter J | 112 | 4A | 1001010 | J | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 75 | K | Upper Case Letter K | 113 | 4B | 1001011 | K | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 76 | L | Upper Case Letter L | 114 | 4C | 1001100 | L | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 77 | M | Upper Case Letter M | 115 | 4D | 1001101 | M | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 78 | N | Upper Case Letter N | 116 | 4E | 1001110 | N | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 79 | O | Upper Case Letter O | 117 | 4F | 1001111 | O | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 80 | P | Upper Case Letter P | 120 | 50 | 1010000 | P | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 81 | Q | Upper Case Letter Q | 121 | 51 | 1010001 | Q | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 82 | R | Upper Case Letter R | 122 | 52 | 1010010 | R | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 83 | S | Upper Case Letter S | 123 | 53 | 1010011 | S | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 84 | T | Upper Case Letter T | 124 | 54 | 1010100 | T | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 85 | U | Upper Case Letter U | 125 | 55 | 1010101 | U | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 86 | V | Upper Case Letter V | 126 | 56 | 1010110 | V | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 87 | W | Upper Case Letter W | 127 | 57 | 1010111 | W | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 88 | X | Upper Case Letter X | 130 | 58 | 1011000 | X | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 89 | Y | Upper Case Letter Y | 131 | 59 | 1011001 | Y | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 90 | Z | Upper Case Letter Z | 132 | 5A | 1011010 | Z | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 97 | a | Lower Case Letter a | 141 | 61 | 1100001 | a | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 98 | b | Lower Case Letter b | 142 | 62 | 1100010 | b | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 99 | c | Lower Case Letter c | 143 | 63 | 1100011 | c | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 100 | d | Lower Case Letter d | 144 | 64 | 1100100 | d | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 101 | e | Lower Case Letter e | 145 | 65 | 1100101 | e | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 102 | f | Lower Case Letter f | 146 | 66 | 1100110 | f | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 103 | g | Lower Case Letter g | 147 | 67 | 1100111 | g | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 104 | h | Lower Case Letter h | 150 | 68 | 1101000 | h | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 105 | i | Lower Case Letter i | 151 | 69 | 1101001 | i | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 106 | j | Lower Case Letter j | 152 | 6A | 1101010 | j | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 107 | k | Lower Case Letter k | 153 | 6B | 1101011 | k | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 108 | l | Lower Case Letter l | 154 | 6C | 1101100 | l | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 109 | m | Lower Case Letter m | 155 | 6D | 1101101 | m | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 110 | n | Lower Case Letter n | 156 | 6E | 1101110 | n | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 111 | o | Lower Case Letter o | 157 | 6F | 1101111 | o | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 112 | p | Lower Case Letter p | 160 | 70 | 1110000 | p | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 113 | q | Lower Case Letter q | 161 | 71 | 1110001 | q | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 114 | r | Lower Case Letter r | 162 | 72 | 1110010 | r | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 115 | s | Lower Case Letter s | 163 | 73 | 1110011 | s | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 116 | t | Lower Case Letter t | 164 | 74 | 1110100 | t | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 117 | u | Lower Case Letter u | 165 | 75 | 1110101 | u | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 118 | v | Lower Case Letter v | 166 | 76 | 1110110 | v | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 119 | w | Lower Case Letter w | 167 | 77 | 1110111 | w | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 120 | x | Lower Case Letter x | 170 | 78 | 1111000 | x | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 121 | y | Lower Case Letter y | 171 | 79 | 1111001 | y | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ +| 122 | z | Lower Case Letter z | 172 | 7A | 1111010 | z | | ++-----------+---------------+------------------------+-----------+---------+------------+---------------+---------------+ + +Date Format --------------- - The date format in the output CSV is formatted as ISO 8601 (``2019-12-31 20:30:55.123``), regardless of how it was parsed initially with :ref:`COPY FROM date parsers`. +For more information on the ``datetime`` format, see :ref:`sql_data_types_date`. Examples =========== +The **Examples** section shows the following examples: + +.. contents:: + :local: + :depth: 1 -Export table to a CSV without HEADER +Exporting a Table to a CSV File without a HEADER Row ------------------------------------ +The following is an example of exporting a table to a CSV file without a HEADER row: .. code-block:: psql @@ -130,8 +434,9 @@ Export table to a CSV without HEADER Jonas Jerebko,Boston Celtics,8,PF,29,6-10,231,\N,5000000 Amir Johnson,Boston Celtics,90,PF,29,6-9,240,\N,12000000 -Export table to a CSV with a HEADER row +Exporting a Table to a CSV with a HEADER Row ----------------------------------------- +The following is an example of exporting a table to a CSV file with a HEADER row: .. code-block:: psql @@ -147,8 +452,9 @@ Export table to a CSV with a HEADER row R.J. Hunter,Boston Celtics,28,SG,22,6-5,185,Georgia State,1148640 Jonas Jerebko,Boston Celtics,8,PF,29,6-10,231,\N,5000000 -Export table to a TSV with a header row +Exporting a Table to TSV with a HEADER Row ----------------------------------------- +The following is an example of exporting a table to a TSV file with a HEADER row: .. code-block:: psql @@ -164,8 +470,9 @@ Export table to a TSV with a header row R.J. Hunter Boston Celtics 28 SG 22 6-5 185 Georgia State 1148640 Jonas Jerebko Boston Celtics 8 PF 29 6-10 231 \N 5000000 -Use non-printable ASCII characters as delimiter +Using Non-Printable ASCII Characters as Delimiters ------------------------------------------------------- +The following is an example of using non-printable ASCII characters as delimiters: Non-printable characters can be specified using their octal representations, by using the ``E'\000'`` format, where ``000`` is the octal value of the character. @@ -179,8 +486,9 @@ For example, ASCII character ``15``, known as "shift in", can be specified using COPY nba TO WRAPPER csv_fdw OPTIONS (LOCATION = '/tmp/nba_export.csv', DELIMITER = E'\011'); -- 011 is a tab character -Exporting the result of a query to a CSV +Exporting the Result of a Query to CSV File -------------------------------------------- +The following is an example of exporting the result of a query to a CSV file: .. code-block:: psql @@ -195,40 +503,46 @@ Exporting the result of a query to a CSV Charlotte Hornets,5222728 Chicago Bulls,5785558 -Saving files to an authenticated S3 bucket +Saving Files to an Authenticated S3 Bucket -------------------------------------------- +The following is an example of saving files to an authenticated S3 bucket: .. code-block:: psql COPY (SELECT "Team", AVG("Salary") FROM nba GROUP BY 1) TO WRAPPER csv_fdw OPTIONS (LOCATION = 's3://my_bucket/salaries/nba_export.csv', AWS_ID = 'my_aws_id', AWS_SECRET = 'my_aws_secret'); -Saving files to an HDFS path +Saving Files to an HDFS Path -------------------------------------------- +The following is an example of saving files to an HDFS path: .. code-block:: psql COPY (SELECT "Team", AVG("Salary") FROM nba GROUP BY 1) TO WRAPPER csv_fdw OPTIONS (LOCATION = 'hdfs://pp_namenode:8020/nba_export.csv'); - -Export table to a parquet file +Exporting a Table to a Parquet File ------------------------------ +The following is an example of exporting a table to a Parquet file: .. code-block:: psql COPY nba TO WRAPPER parquet_fdw OPTIONS (LOCATION = '/tmp/nba_export.parquet'); - -Export a query to a parquet file +Exporting a Query to a Parquet File -------------------------------- +The following is an example of exporting a query to a Parquet file: .. code-block:: psql COPY (select x,y from t where z=0) TO WRAPPER parquet_fdw OPTIONS (LOCATION = '/tmp/file.parquet'); - -Export table to a ORC file +Exporting a Table to an ORC File ------------------------------ +The following is an example of exporting a table to an ORC file: .. code-block:: psql COPY nba TO WRAPPER orc_fdw OPTIONS (LOCATION = '/tmp/nba_export.orc'); + +Permissions +============= +The role must have the ``SELECT`` permission on every table or schema that is referenced by the statement. From 315d0c7895a5a3d03da00c9a133e0a1de35d82c6 Mon Sep 17 00:00:00 2001 From: YanivGerowitz <82020437+YanivGerowitz@users.noreply.github.com> Date: Wed, 6 Jul 2022 16:04:20 +0300 Subject: [PATCH 094/316] Updated with Slavi --- operational_guides/hardware_guide.rst | 83 +++++++++++++++++++++------ 1 file changed, 65 insertions(+), 18 deletions(-) diff --git a/operational_guides/hardware_guide.rst b/operational_guides/hardware_guide.rst index d66797223..571d6a6a3 100644 --- a/operational_guides/hardware_guide.rst +++ b/operational_guides/hardware_guide.rst @@ -3,9 +3,7 @@ *********************** Hardware Guide *********************** - -This guide describes the SQream reference architecture, emphasizing the benefits to the technical audience, and provides guidance for end-users on selecting the right configuration for a SQream installation. - +The **Hardware Guide** describes the SQream reference architecture, emphasizing the benefits to the technical audience, and provides guidance for end-users on selecting the right configuration for a SQream installation. .. rubric:: Need help? @@ -15,20 +13,22 @@ Visit `SQream's support portal Date: Wed, 6 Jul 2022 16:19:35 +0300 Subject: [PATCH 095/316] Update hardware_guide.rst From 8127a478798529ae4ae830ecf2f272dedb4fb1a9 Mon Sep 17 00:00:00 2001 From: YanivGerowitz <82020437+YanivGerowitz@users.noreply.github.com> Date: Wed, 6 Jul 2022 16:23:57 +0300 Subject: [PATCH 096/316] Update hardware_guide.rst --- operational_guides/hardware_guide.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/operational_guides/hardware_guide.rst b/operational_guides/hardware_guide.rst index 571d6a6a3..252b71fc2 100644 --- a/operational_guides/hardware_guide.rst +++ b/operational_guides/hardware_guide.rst @@ -78,7 +78,7 @@ The following table shows SQream's recommended hardware specifications: .. list-table:: :widths: 15 65 - :header-rows: 2 + :header-rows: 1 * - Component - Type From 9eb8a69c627052e3d887030fbd173a8b2dbed647 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Wed, 6 Jul 2022 17:08:18 +0300 Subject: [PATCH 097/316] https://sqream.atlassian.net/browse/TPD-168 --- operational_guides/external_data.rst | 15 +- operational_guides/hdfs.rst | 252 +++++++++++++++++++++++++++ operational_guides/s3.rst | 26 +-- 3 files changed, 272 insertions(+), 21 deletions(-) create mode 100644 operational_guides/hdfs.rst diff --git a/operational_guides/external_data.rst b/operational_guides/external_data.rst index 576e50ea4..8bf51f108 100644 --- a/operational_guides/external_data.rst +++ b/operational_guides/external_data.rst @@ -3,12 +3,23 @@ ********************************** Working with External Data ********************************** - -SQream DB supports external data sources for use with :ref:`external_tables`, :ref:`copy_from`, and :ref:`copy_to`. +SQream supports the following external data sources: .. toctree:: :maxdepth: 1 :titlesonly: s3 + hdfs + +For more information, see the following: + +* :ref:`external_tables` + + :: + +* :ref:`copy_from` + + :: +* :ref:`copy_to` \ No newline at end of file diff --git a/operational_guides/hdfs.rst b/operational_guides/hdfs.rst new file mode 100644 index 000000000..a6ffe0ead --- /dev/null +++ b/operational_guides/hdfs.rst @@ -0,0 +1,252 @@ +.. _hdfs: + +.. _back_to_top_hdfs: + +Using SQream in an HDFS Environment +======================================= + +.. _configuring_an_hdfs_environment_for_the_user_sqream: + +Configuring an HDFS Environment for the User **sqream** +---------------------------------------------------------- + +This section describes how to configure an HDFS environment for the user **sqream** and is only relevant for users with an HDFS environment. + +**To configure an HDFS environment for the user sqream:** + +1. Open your **bash_profile** configuration file for editing: + + .. code-block:: console + + $ vim /home/sqream/.bash_profile + +.. + Comment: - see below; do we want to be a bit more specific on what changes we're talking about? + + .. code-block:: console + + $ #PATH=$PATH:$HOME/.local/bin:$HOME/bin + + $ #export PATH + + $ # PS1 + $ #MYIP=$(curl -s -XGET "http://ip-api.com/json" | python -c 'import json,sys; jstr=json.load(sys.stdin); print jstr["query"]') + $ #PS1="\[\e[01;32m\]\D{%F %T} \[\e[01;33m\]\u@\[\e[01;36m\]$MYIP \[\e[01;31m\]\w\[\e[37;36m\]\$ \[\e[1;37m\]" + + $ SQREAM_HOME=/usr/local/sqream + $ export SQREAM_HOME + + $ export JAVA_HOME=${SQREAM_HOME}/hdfs/jdk + $ export HADOOP_INSTALL=${SQREAM_HOME}/hdfs/hadoop + $ export CLASSPATH=`${HADOOP_INSTALL}/bin/hadoop classpath --glob` + $ export HADOOP_COMMON_LIB_NATIVE_DIR=${HADOOP_INSTALL}/lib/native + $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${SQREAM_HOME}/lib:$HADOOP_COMMON_LIB_NATIVE_DIR + + + $ PATH=$PATH:$HOME/.local/bin:$HOME/bin:${SQREAM_HOME}/bin/:${JAVA_HOME}/bin:$HADOOP_INSTALL/bin + $ export PATH + +2. Verify that the edits have been made: + + .. code-block:: console + + source /home/sqream/.bash_profile + +3. Check if you can access Hadoop from your machine: + + .. code-block:: console + + $ hadoop fs -ls hdfs://:8020/ + +.. + Comment: - + **NOTICE:** If you cannot access Hadoop from your machine because it uses Kerberos, see `Connecting a SQream Server to Cloudera Hadoop with Kerberos `_ + + +4. Verify that an HDFS environment exists for SQream services: + + .. code-block:: console + + $ ls -l /etc/sqream/sqream_env.sh + +.. _step_6: + + +5. If an HDFS environment does not exist for SQream services, create one (sqream_env.sh): + + .. code-block:: console + + $ #!/bin/bash + + $ SQREAM_HOME=/usr/local/sqream + $ export SQREAM_HOME + + $ export JAVA_HOME=${SQREAM_HOME}/hdfs/jdk + $ export HADOOP_INSTALL=${SQREAM_HOME}/hdfs/hadoop + $ export CLASSPATH=`${HADOOP_INSTALL}/bin/hadoop classpath --glob` + $ export HADOOP_COMMON_LIB_NATIVE_DIR=${HADOOP_INSTALL}/lib/native + $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${SQREAM_HOME}/lib:$HADOOP_COMMON_LIB_NATIVE_DIR + + + $ PATH=$PATH:$HOME/.local/bin:$HOME/bin:${SQREAM_HOME}/bin/:${JAVA_HOME}/bin:$HADOOP_INSTALL/bin + $ export PATH + +:ref:`Back to top ` + + +.. _authenticate_hadoop_servers_that_require_kerberos: + +Authenticating Hadoop Servers that Require Kerberos +--------------------------------------------------- + +If your Hadoop server requires Kerberos authentication, do the following: + +1. Create a principal for the user **sqream**. + + .. code-block:: console + + $ kadmin -p root/admin@SQ.COM + $ addprinc sqream@SQ.COM + +2. If you do not know yor Kerberos root credentials, connect to the Kerberos server as a root user with ssh and run **kadmin.local**: + + .. code-block:: console + + $ kadmin.local + + Running **kadmin.local** does not require a password. + +3. If a password is not required, change your password to **sqream@SQ.COM**. + + .. code-block:: console + + $ change_password sqream@SQ.COM + +4. Connect to the hadoop name node using ssh: + + .. code-block:: console + + $ cd /var/run/cloudera-scm-agent/process + +5. Check the most recently modified content of the directory above: + + .. code-block:: console + + $ ls -lrt + +6. Look for a recently updated folder containing the text **hdfs**. + +The following is an example of the correct folder name: + + .. code-block:: console + + cd -hdfs- + + This folder should contain a file named **hdfs.keytab** or another similar .keytab file. + + + +.. + Comment: - Does "something" need to be replaced with "file name" + + +7. Copy the .keytab file to user **sqream's** Home directory on the remote machines that you are planning to use Hadoop on. + +8. Copy the following files to the **sqream sqream@server:/hdfs/hadoop/etc/hadoop:** directory: + + * core-site.xml + * hdfs-site.xml + +9. Connect to the sqream server and verify that the .keytab file's owner is a user sqream and is granted the correct permissions: + + .. code-block:: console + + $ sudo chown sqream:sqream /home/sqream/hdfs.keytab + $ sudo chmod 600 /home/sqream/hdfs.keytab + +10. Log into the sqream server. + +11. Log in as the user **sqream**. + +12. Navigate to the Home directory and check the name of a Kerberos principal represented by the following .keytab file: + + .. code-block:: console + + $ klist -kt hdfs.keytab + + The following is an example of the correct output: + + .. code-block:: console + + $ sqream@Host-121 ~ $ klist -kt hdfs.keytab + $ Keytab name: FILE:hdfs.keytab + $ KVNO Timestamp Principal + $ ---- ------------------- ------------------------------------------------------ + $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM + +13. Verify that the hdfs service named **hdfs/nn1@SQ.COM** is shown in the generated output above. + +14. Run the following: + + .. code-block:: console + + $ kinit -kt hdfs.keytab hdfs/nn1@SQ.COM + +15. Check the output: + + .. code-block:: console + + $ klist + + The following is an example of the correct output: + + .. code-block:: console + + $ Ticket cache: FILE:/tmp/krb5cc_1000 + $ Default principal: sqream@SQ.COM + $ + $ Valid starting Expires Service principal + $ 09/16/2020 13:44:18 09/17/2020 13:44:18 krbtgt/SQ.COM@SQ.COM + +16. List the files located at the defined server name or IP address: + + .. code-block:: console + + $ hadoop fs -ls hdfs://:8020/ + +17. Do one of the following: + + * If the list below is output, continue with Step 16. + * If the list is not output, verify that your environment has been set up correctly. + +If any of the following are empty, verify that you followed :ref:`Step 6 ` in the **Configuring an HDFS Environment for the User sqream** section above correctly: + + .. code-block:: console + + $ echo $JAVA_HOME + $ echo $SQREAM_HOME + $ echo $CLASSPATH + $ echo $HADOOP_COMMON_LIB_NATIVE_DIR + $ echo $LD_LIBRARY_PATH + $ echo $PATH + +18. Verify that you copied the correct keytab file. + +19. Review this procedure to verify that you have followed each step. + +:ref:`Back to top ` \ No newline at end of file diff --git a/operational_guides/s3.rst b/operational_guides/s3.rst index 699f35401..f8bb2dab6 100644 --- a/operational_guides/s3.rst +++ b/operational_guides/s3.rst @@ -1,9 +1,8 @@ .. _s3: *********************** -Amazon S3 +Inserting Data Using Amazon S3 *********************** - SQream uses a native S3 connector for inserting data. The ``s3://`` URI specifies an external file path on an S3 bucket. File names may contain wildcard characters, and the files can be in CSV or columnar format, such as Parquet and ORC. The **Amazon S3** describes the following topics: @@ -13,12 +12,10 @@ The **Amazon S3** describes the following topics: S3 Configuration ============================== - Any database host with access to S3 endpoints can access S3 without any configuration. To read files from an S3 bucket, the database must have listable files. S3 URI Format =============== - With S3, specify a location for a file (or files) when using :ref:`copy_from` or :ref:`external_tables`. The following is an example of the general S3 syntax: @@ -29,12 +26,10 @@ The following is an example of the general S3 syntax: Authentication ================= - SQream supports ``AWS ID`` and ``AWS SECRET`` authentication. These should be specified when executing a statement. Examples ========== - Use a foreign table to stage data from S3 before loading from CSV, Parquet, or ORC files. The **Examples** section includes the following examples: @@ -42,12 +37,8 @@ The **Examples** section includes the following examples: .. contents:: :local: :depth: 1 - - - Planning for Data Staging -------------------------------- - The examples in this section are based on a CSV file, as shown in the following table: .. csv-table:: nba.csv @@ -59,21 +50,20 @@ The file is stored on Amazon S3, and this bucket is public and listable. To crea Creating a Foreign Table ----------------------------- - Based on the source file's structure, you can create a foreign table with the appropriate structure, and point it to your file as shown in the following example: .. code-block:: postgres CREATE FOREIGN TABLE nba ( - Name text(40), - Team text(40), + Name varchar(40), + Team varchar(40), Number tinyint, - Position text(2), + Position varchar(2), Age tinyint, - Height text(4), + Height varchar(4), Weight real, - College text(40), + College varchar(40), Salary float ) WRAPPER csv_fdw @@ -93,7 +83,6 @@ For more information, see the following: Querying Foreign Tables ------------------------------ - The following shows the data in the foreign table: .. code-block:: psql @@ -114,7 +103,6 @@ The following shows the data in the foreign table: Bulk Loading a File from a Public S3 Bucket ---------------------------------------------- - The ``COPY FROM`` command can also be used to load data without staging it first. .. note:: The bucket must be publicly available and objects can be listed. @@ -135,4 +123,4 @@ The following is an example of loading fles from an authenticated S3 bucket: COPY nba FROM 's3://secret-bucket/*.csv' WITH OFFSET 2 RECORD DELIMITER '\r\n' AWS_ID '12345678' - AWS_SECRET 'super_secretive_secret'; + AWS_SECRET 'super_secretive_secret'; \ No newline at end of file From 2b2b6b90a15652d1625f7a19d4a2765ad5bc588d Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Wed, 6 Jul 2022 17:23:22 +0300 Subject: [PATCH 098/316] TPD-221 --- operational_guides/hardware_guide.rst | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/operational_guides/hardware_guide.rst b/operational_guides/hardware_guide.rst index 252b71fc2..5337db9cd 100644 --- a/operational_guides/hardware_guide.rst +++ b/operational_guides/hardware_guide.rst @@ -126,27 +126,6 @@ The following table shows SQream's recommended metadata server specifications: * - Operating System - Red Hat Enterprise Linux v7.x or CentOS v7.x or Amazon Linux -Web User Interface Specifications -~~~~~~~~~~~~~~~~~~~~~~~~~ -The following table shows SQream's recommended web user interface server specifications: - -.. list-table:: - :widths: 15 90 - :header-rows: 1 - - * - Component - - Type - * - Processors - - One Intel i7 16C processor or similar - * - RAM - - 64 GB DDR4 RAM 2x32 GB RDIMM or similar - * - Discs - - 256 GB SATA 6Gb SSD drive or similar - * - Network Card (Corporate) - - Two 1 GbE cards or similar - * - Operating System - - Red Hat Enterprise Linux v7.x or CentOS v7.x or Amazon Linux - .. note:: With a NAS connected over GPFS, Lustre, or NFS, each SQream worker can read data at up to 5GB/s. SQream Studio Server Example @@ -246,4 +225,4 @@ For clustered scale-out installations, SQream relies on NAS/SAN storage. For sta SQream recommends using enterprise-grade SAS SSD or NVMe drives. For a 32-user configuration, the number of GPUs should roughly match the number of users. SQream recommends 1 Tesla V100 or A100 GPU per 2 users, for full, uninterrupted dedicated access. -Download the full `SQream Reference Architecture `_ document. +Download the full `SQream Reference Architecture `_ document. \ No newline at end of file From 3e5001a32c650f5189080787903707661cc7f10f Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Wed, 6 Jul 2022 18:26:42 +0300 Subject: [PATCH 099/316] Update index.rst --- third_party_tools/client_drivers/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party_tools/client_drivers/index.rst b/third_party_tools/client_drivers/index.rst index eebeeb003..d0c60d804 100644 --- a/third_party_tools/client_drivers/index.rst +++ b/third_party_tools/client_drivers/index.rst @@ -1,7 +1,7 @@ .. _client_drivers: ************************************ -Client Drivers for |latest_version| +Client Drivers for 2022.1 ************************************ The guides on this page describe how to use the Sqream DB client drivers and client applications with SQream. From 711ae8192c2def0e86346b295e1eeb75916e7db2 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 7 Jul 2022 15:43:23 +0300 Subject: [PATCH 100/316] Updated the following: Delete Guide: improvements SQL Statements > Index: improved tables SQL Statements: created get_extents_file_list_for_chunk page (in review) SQL Statements: created get_metadata_chunk_key page (in review) --- operational_guides/delete_guide.rst | 272 +++++++++++------- reference/sql/sql_statements/index.rst | 84 +++--- .../get_extents_file_list_for_chunk.rst | 60 ++++ .../get_metadata_chunk_key.rst | 59 ++++ 4 files changed, 325 insertions(+), 150 deletions(-) create mode 100644 reference/sql/sql_statements/utility_commands/get_extents_file_list_for_chunk.rst create mode 100644 reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst diff --git a/operational_guides/delete_guide.rst b/operational_guides/delete_guide.rst index 24ab5a218..c24079f8c 100644 --- a/operational_guides/delete_guide.rst +++ b/operational_guides/delete_guide.rst @@ -3,144 +3,183 @@ *********************** Deleting Data *********************** +The **Deleting Data** page describes how the **Delete** statement works and how to maintain data that you delete: -SQream DB supports deleting data, but it's important to understand how this works and how to maintain deleted data. +.. contents:: + :local: + :depth: 1 -How does deleting in SQream DB work? +Overview ======================================== +Deleting data typically refers to deleting rows, but can refer to deleting other table content as well. The general workflow for deleting data is to delete data followed by triggering a cleanup operation. The cleanup operation reclaims the space occupied by the deleted rows, discussed further below. -In SQream DB, when you run a delete statement, any rows that match the delete predicate will no longer be returned when running subsequent queries. -Deleted rows are tracked in a separate location, in *delete predicates*. +The **DELETE** statement deletes rows defined by a predicate that you have specified, preventing them from appearing in subsequent queries. -After the delete statement, a separate process can be used to reclaim the space occupied by these rows, and to remove the small overhead that queries will have until this is done. +For example, the predicate below defines and deletes rows containing animals heavier than 1000 weight units: -Some benefits to this design are: - -#. Delete transactions complete quickly +.. code-block:: psql -#. The total disk footprint overhead at any time for a delete transaction or cleanup process is small and bounded (while the system still supports low overhead commit, rollback and recovery for delete transactions). + farm=> DELETE FROM cool_animals WHERE weight > 1000; +The major benefit of the DELETE statement is that it deletes transactions simply and quickly. -Phase 1: Delete ---------------------------- +The Deletion Process +========== +Deleting rows occurs in the following two phases: -.. TODO: isn't the delete cleanup able to complete a certain amount of work transactionally, so that you can do a massive cleanup in stages? +* **Phase 1 - Deletion** - All rows you mark for deletion are ignored when you run any query. These rows are not deleted until the clean-up phase. -.. TODO: our current best practices is to use a cron job with sqream sql to run the delete cleanup. we should document how to do this, we have customers with very different delete schedules so we can give a few extreme examples and when/why you'd use them + :: -When a :ref:`delete` statement is run, SQream DB records the delete predicates used. These predicates will be used to filter future statements on this table until all this delete predicate's matching rows have been physically cleaned up. +* **Phase 2 - Clean-up** - The rows you marked for deletion in Phase 1 are physically deleted. The clean-up phase is not automated, letting users or DBAs control when to activate it. The files you marked for deletion during Phase 1 are removed from disk, which you do by by sequentially running the utility function commands ``CLEANUP_CHUNKS`` and ``CLEANUP_EXTENTS``. -This filtering process takes full advantage of SQream's zone map feature. +.. TODO: isn't the delete cleanup able to complete a certain amount of work transactionally, so that you can do a massive cleanup in stages? -Phase 2: Clean-up --------------------- +.. TODO: our current best practices is to use a cron job with sqream sql to run the delete cleanup. we should document how to do this, we have customers with very different delete schedules so we can give a few extreme examples and when/why you'd use them. -The cleanup process is not automatic. This gives control to the user or DBA, and gives flexibility on when to run the clean up. +Usage Notes +===================== +The **Usage Notes** section includes important information about the DELETE statement: -Files marked for deletion during the logical deletion stage are removed from disk. This is achieved by calling both utility function commands: ``CLEANUP_CHUNKS`` and ``CLEANUP_EXTENTS`` sequentially. +.. contents:: + :local: + :depth: 1 + +General Notes +---------------- +This section describes the general notes applicable when deleting rows: -.. note:: - * :ref:`alter_table` and other DDL operations are blocked on tables that require clean-up. See more in the :ref:`concurrency_and_locks` guide. - * If the estimated time for a cleanup processs is beyond a threshold, you will get an error message about it. The message will explain how to override this limitation and run the process anywhere. +* The :ref:`alter_table` command and other DDL operations are locked on tables that require clean-up. If the estimated clean-up time exceeds the permitted threshold, an error message is displayed describing how to override the threshold limitation. For more information, see :ref:`concurrency_and_locks`. -Notes on data deletion -========================================= + :: -.. note:: - * If the number of deleted records crosses the threshold defined by the ``mixedColumnChunksThreshold`` parameter, the delete operation will be aborted. - * This is intended to alert the user that the large number of deleted records may result in a large number of mixed chuncks. - * To circumvent this alert, replace XXX with the desired number of records before running the delete operation: +* If the number of deleted records exceeds the threshold defined by the ``mixedColumnChunksThreshold`` parameter, the delete operation is aborted. This alerts users that the large number of deleted records may result in a large number of mixed chunks. To circumvent this alert, use the following syntax (replacing ``XXX`` with the desired number of records) before running the delete operation: -.. code-block:: postgres + .. code-block:: postgres - set mixedColumnChunksThreshold=XXX; + set mixedColumnChunksThreshold=XXX; - -Deleting data does not free up space +Deleting Data does not Free Space ----------------------------------------- +With the exception of running a full table delete, deleting data does not free unused disk space. To free unused disk space you must trigger the clean-up process. -With the exception of a full table delete (:ref:`TRUNCATE`), deleting data does not free up disk space. To free up disk space, trigger the cleanup process. - -``SELECT`` performance on deleted rows ----------------------------------------- - -Queries on tables that have deleted rows may have to scan data that hasn't been cleaned up. -In some cases, this can cause queries to take longer than expected. To solve this issue, trigger the cleanup process. +For more information on running a full table delete, see :ref:`TRUNCATE`. -Use ``TRUNCATE`` instead of ``DELETE`` ---------------------------------------- -For tables that are frequently emptied entirely, consider using :ref:`truncate` rather than :ref:`delete`. TRUNCATE removes the entire content of the table immediately, without requiring a subsequent cleanup to free up disk space. + :: + +For more information on freeing disk space, see :ref:`Triggering a Clean-Up`. -Cleanup is I/O intensive +Clean-Up Operations Are I/O Intensive ------------------------------- +The clean-up process reduces table size by removing all unused space from column chunks. While this reduces query time, it is a time-costly operation occupying disk space for the new copy of the table until the operation is complete. -The cleanup process actively compacts tables by writing a complete new version of column chunks with no dead space. This minimizes the size of the table, but can take a long time. It also requires extra disk space for the new copy of the table, until the operation completes. - -Cleanup operations can create significant I/O load on the database. Consider this when planning the best time for the cleanup process. +.. tip:: Because clean-up operations can create significant I/O load on your database, consider using them sparingly during ideal times. If this is an issue with your environment, consider using ``CREATE TABLE AS`` to create a new table and then rename and drop the old table. - -Example +Examples ============= +The **Examples** section includes the following examples: -Deleting values from a table +.. contents:: + :local: + :depth: 1 + +Deleting Rows from a Table ------------------------------ +The following example shows how to delete rows from a table. -.. code-block:: psql +1. Display the table: + + .. code-block:: psql - farm=> SELECT * FROM cool_animals; - 1,Dog ,7 - 2,Possum ,3 - 3,Cat ,5 - 4,Elephant ,6500 - 5,Rhinoceros ,2100 - 6,\N,\N + farm=> SELECT * FROM cool_animals; - 6 rows + The following table is displayed: + + .. code-block:: psql + + 1,Dog ,7 + 2,Possum ,3 + 3,Cat ,5 + 4,Elephant ,6500 + 5,Rhinoceros ,2100 + 6,\N,\N - farm=> DELETE FROM cool_animals WHERE weight > 1000; - executed +2. Delete rows from the table: + + .. code-block:: psql + + farm=> DELETE FROM cool_animals WHERE weight > 1000; + +3. Display the table: + + .. code-block:: psql + + farm=> SELECT * FROM cool_animals; - farm=> SELECT * FROM cool_animals; - 1,Dog ,7 - 2,Possum ,3 - 3,Cat ,5 - 6,\N,\N + The following table is displayed: + + .. code-block:: psql + + 1,Dog ,7 + 2,Possum ,3 + 3,Cat ,5 + 6,\N,\N - 4 rows - -Deleting values based on more complex predicates +Deleting Values Based on Complex Predicates --------------------------------------------------- +The following example shows how to delete values based on complex predicates. -.. code-block:: psql +1. Display the table: + + .. code-block:: psql - farm=> SELECT * FROM cool_animals; - 1,Dog ,7 - 2,Possum ,3 - 3,Cat ,5 - 4,Elephant ,6500 - 5,Rhinoceros ,2100 - 6,\N,\N + farm=> SELECT * FROM cool_animals; - 6 rows + The following table is displayed: + + .. code-block:: psql + + 1,Dog ,7 + 2,Possum ,3 + 3,Cat ,5 + 4,Elephant ,6500 + 5,Rhinoceros ,2100 + 6,\N,\N - farm=> DELETE FROM cool_animals WHERE weight > 1000; - executed +2. Delete rows from the table: + + .. code-block:: psql + + farm=> DELETE FROM cool_animals WHERE weight > 1000; + +3. Display the table: + + .. code-block:: psql + + farm=> SELECT * FROM cool_animals; - farm=> SELECT * FROM cool_animals; - 1,Dog ,7 - 2,Possum ,3 - 3,Cat ,5 - 6,\N,\N + The following table is displayed: + + .. code-block:: psql + + 1,Dog ,7 + 2,Possum ,3 + 3,Cat ,5 + 6,\N,\N - 4 rows - -Identifying and cleaning up tables +Identifying and Cleaning Up Tables --------------------------------------- +The **Identifying and Cleaning Up Tables** section includes the following examples: -List tables that haven't been cleaned up +.. contents:: + :local: + :depth: 1 + +Listing Tables that Have Not Been Cleaned Up ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The following example shows how to list tables that have not been cleaned up: .. code-block:: psql @@ -152,8 +191,9 @@ List tables that haven't been cleaned up 1 row -Identify predicates for clean-up +Identifying Predicates for Clean-Up ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The following example shows how to identify predicates for clean-up: .. code-block:: psql @@ -164,42 +204,55 @@ Identify predicates for clean-up weight > 1000 1 row + +.. _trigger_cleanup: -Triggering a cleanup +Triggering a Clean-Up ^^^^^^^^^^^^^^^^^^^^^^ +The following example shows how to trigger a clean-up: -.. code-block:: psql +1. Run the chunk ``CLEANUP_CHUNKS`` command (also known as ``SWEEP``) to reorganize the chunks: + + .. code-block:: psql + + farm=> SELECT CLEANUP_CHUNKS('public','cool_animals'); - -- Chunk reorganization (aka SWEEP) - farm=> SELECT CLEANUP_CHUNKS('public','cool_animals'); - executed +2. Run the ``CLEANUP_EXTENTS`` command (also known as ``VACUUM``) to delete the leftover files: - -- Delete leftover files (aka VACUUM) - farm=> SELECT CLEANUP_EXTENTS('public','cool_animals'); - executed + .. code-block:: psql + farm=> SELECT CLEANUP_EXTENTS('public','cool_animals'); - farm=> SELECT delete_predicate FROM sqream_catalog.delete_predicates dp - JOIN sqream_catalog.tables t - ON dp.table_id = t.table_id - WHERE t.table_name = 'cool_animals'; +3. Display the table: + + .. code-block:: psql - 0 rows + farm=> SELECT delete_predicate FROM sqream_catalog.delete_predicates dp + JOIN sqream_catalog.tables t + ON dp.table_id = t.table_id + WHERE t.table_name = 'cool_animals'; + +Best Practices +===================================== +This section includes the best practices when deleting rows: +* Run ``CLEANUP_CHUNKS`` and ``CLEANUP_EXTENTS`` after running large ``DELETE`` operations. + :: -Best practices for data deletion -===================================== +* When you delete large segments of data from very large tables, consider running a ``CREATE TABLE AS`` operation instead, renaming, and dropping the original table. -* Run ``CLEANUP_CHUNKS`` and ``CLEANUP_EXTENTS`` after large ``DELETE`` operations. + :: -* When deleting large proportions of data from very large tables, consider running a ``CREATE TABLE AS`` operation instead, then rename and drop the original table. +* Avoid killing ``CLEANUP_EXTENTS`` operations in progress. -* Avoid killing ``CLEANUP_EXTENTS`` operations after they've started. + :: -* SQream DB is optimised for time-based data. When data is naturally ordered by a date or timestamp, deleting based on those columns will perform best. For more information, see our :ref:`time based data management guide`. +* SQream is optimized for time-based data, which is data naturally ordered according to date or timestamp. Deleting rows based on such columns leads to increased performance. + :: +For more information, see `Time-Based Data Management `_. .. soft update concept @@ -210,5 +263,4 @@ Best practices for data deletion .. when does delete use the metadata effectively -.. more examples - +.. more examples \ No newline at end of file diff --git a/reference/sql/sql_statements/index.rst b/reference/sql/sql_statements/index.rst index d0a6c04c8..67c9db172 100644 --- a/reference/sql/sql_statements/index.rst +++ b/reference/sql/sql_statements/index.rst @@ -9,81 +9,81 @@ The **SQL Statements** page describes the following commands: :local: :depth: 1 -SQream DB supports commands from ANSI SQL. +SQream supports commands from ANSI SQL. .. _ddl_commands_list: Data Definition Commands (DDL) ================================ +The following table shows the Data Definition commands: -.. list-table:: DDL Commands - :widths: auto +.. list-table:: + :widths: 10 100 :header-rows: 1 :name: ddl_commands * - Command - Usage - * - :ref:`add_column` + * - :ref:`ADD_COLUMN` - Add a new column to a table - * - :ref:`alter_default_schema` + * - :ref:`ALTER_DEFAULT_SCHEMA` - Change the default schema for a role - * - :ref:`alter_table` + * - :ref:`ALTER_TABLE` - Change the schema of a table - * - :ref:`cluster_by` + * - :ref:`CLUSTER_BY` - Change clustering keys in a table - * - :ref:`create_database` + * - :ref:`CREATE_DATABASE` - Create a new database - * - :ref:`create_external_table` - - Create a new external table in the database (deprecated) - * - :ref:`create_foreign_table` + * - :ref:`CREATE_FOREIGN_TABLE` - Create a new foreign table in the database - * - :ref:`create_function` + * - :ref:`CREATE_FUNCTION` - Create a new user defined function in the database - * - :ref:`create_schema` + * - :ref:`CREATE_SCHEMA` - Create a new schema in the database - * - :ref:`create_table` + * - :ref:`CREATE_TABLE` - Create a new table in the database - * - :ref:`create_table_as` + * - :ref:`CREATE_TABLE_AS` - Create a new table in the database using results from a select query - * - :ref:`create_view` + * - :ref:`CREATE_VIEW` - Create a new view in the database - * - :ref:`drop_clustering_key` + * - :ref:`DROP_CLUSTERING_KEY` - Drops all clustering keys in a table - * - :ref:`drop_column` + * - :ref:`DROP_COLUMN` - Drop a column from a table - * - :ref:`drop_database` + * - :ref:`DROP_DATABASE` - Drop a database and all of its objects - * - :ref:`drop_function` + * - :ref:`DROP_FUNCTION` - Drop a function - * - :ref:`drop_schema` + * - :ref:`DROP_SCHEMA` - Drop a schema - * - :ref:`drop_table` + * - :ref:`DROP_TABLE` - Drop a table and its contents from a database - * - :ref:`drop_view` + * - :ref:`DROP_VIEW` - Drop a view - * - :ref:`rename_column` + * - :ref:`RENAME_COLUMN` - Rename a column - * - :ref:`rename_table` + * - :ref:`RENAME_TABLE` - Rename a table + Data Manipulation Commands (DML) ================================ +The following table shows the Data Manipulation commands: -.. list-table:: DML Commands - :widths: auto +.. list-table:: + :widths: 10 100 :header-rows: 1 :name: dml_commands - * - Command - Usage - * - :ref:`CREATE TABLE AS` + * - :ref:`CREATE_TABLE_AS` - Create a new table in the database using results from a select query * - :ref:`DELETE` - Delete specific rows from a table - * - :ref:`COPY FROM` + * - :ref:`COPY_FROM` - Bulk load CSV data into an existing table - * - :ref:`COPY TO` + * - :ref:`COPY_TO` - Export a select query or entire table to CSV files * - :ref:`INSERT` - Insert rows into a table @@ -98,15 +98,20 @@ Data Manipulation Commands (DML) Utility Commands ================== +The following table shows the Utility commands: -.. list-table:: Utility Commands - :widths: auto +.. list-table:: + :widths: 10 100 :header-rows: 1 * - Command - Usage * - :ref:`EXPLAIN` - Returns a static query plan, which can be used to debug query plans + * - :ref:`GET_EXTENTS_FILE_FOR_CHUNK` + - Points to all files that contain data related to a specific chunk + * - :ref:`GET_METADATA_CHUNK_KEY` + - Returns a list of metadata key values for the chunks that you specify * - :ref:`SELECT GET_LICENSE_INFO` - View a user's license information * - :ref:`SELECT GET_DDL` @@ -132,14 +137,12 @@ Utility Commands * - :ref:`STOP STATEMENT` - Stops or aborts an active statement - - - Workload Management ====================== +The following table shows the Workload Management commands: -.. list-table:: Workload Management - :widths: auto +.. list-table:: + :widths: 10 100 :header-rows: 1 * - Command @@ -153,9 +156,10 @@ Workload Management Access Control Commands ================================ +The following table shows the Access Control commands: -.. list-table:: Access Control Commands - :widths: auto +.. list-table:: + :widths: 10 100 :header-rows: 1 * - Command diff --git a/reference/sql/sql_statements/utility_commands/get_extents_file_list_for_chunk.rst b/reference/sql/sql_statements/utility_commands/get_extents_file_list_for_chunk.rst new file mode 100644 index 000000000..2f872812a --- /dev/null +++ b/reference/sql/sql_statements/utility_commands/get_extents_file_list_for_chunk.rst @@ -0,0 +1,60 @@ +.. _get_extents_file_list_for_chunk: + +******************** +GET_EXTENTS_FILE_FOR_CHUNK +******************** +The ``GET_EXTENTS_FILE_FOR_CHUNK`` command points to all files that contain data related to a specific chunk. This command is used for debugging purposes. + +This reference page includes the following information: + +.. contents:: + :local: + :depth: 1 + +Syntax +========== +The following is the syntax for the ``GET_EXTENTS_FILE_FOR_CHUNK`` command: + +.. code-block:: postgres + + select get_extents_file_list_for_chunk(database_name, " + "table_id, chunk_id);" + +Output +========== +The following is an example of the output generated by the ``GET_EXTENTS_FILE_FOR_CHUNK`` command: + +.. code-block:: postgres + + EXAMPLE NEEDED + +Parameters +============ +The following table shows the ``GET_EXTENTS_FILE_FOR_CHUNK`` parameters: + +.. list-table:: + :widths: 10 100 + :header-rows: 1 + + * - Parameter + - Description + * - ``database_name`` + - The name of the database where the chunk is located. + * - ``table_id`` + - The ID of the table where the chunk is located. + * - ``chunk_id`` + - The ID of the chunk. + +Examples +=========== +The following is an example of the ``GET_EXTENTS_FILE_FOR_CHUNK`` command: + +.. code-block:: postgres + + Example - pending from Eyal W. + +Permissions +============= +The ``GET_EXTENTS_FILE_FOR_CHUNK`` requires no special permissions. + +**Comment** - *Does it require any special permissions?* \ No newline at end of file diff --git a/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst b/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst new file mode 100644 index 000000000..2ccc59132 --- /dev/null +++ b/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst @@ -0,0 +1,59 @@ +.. _get_metadata_chunk_key: + +******************** +GET_METADATA_CHUNK_KEY +******************** +The ``GET_METADATA_CHUNK_KEY`` command returns specific metadata key values for user-specified chunks. + +This reference page includes the following information: + +.. contents:: + :local: + :depth: 1 + +Syntax +========== +The following is the syntax for the ``GET_METADATA_CHUNK_KEY`` command: + +.. code-block:: postgres + + get_metadata_chunk_key(database_name, table_id, chunk_id); + +Output +========== +The following is an example of the output generated by the ``GET_METADATA_CHUNK_KEY`` command: + +.. code-block:: postgres + + EXAMPLE NEEDED + +Parameters +============ +The following table shows the ``GET_METADATA_CHUNK_KEY`` parameters: + +.. list-table:: + :widths: 10 100 + :header-rows: 1 + + * - Parameter + - Description + * - ``database_name`` + - The name of the database where the chunk is located. + * - ``table_id`` + - The ID of the table where the chunk is located. + * - ``chunk_id`` + - The ID of the chunk. + +Examples +=========== +The following is an example of the ``GET_METADATA_CHUNK_KEY`` command: + +.. code-block:: postgres + + Example - pending from Eyal W. + +Permissions +============= +The ``GET_METADATA_CHUNK_KEY`` requires no special permissions. + +**Comment** - *Does it require any special permissions?* \ No newline at end of file From f9eed2503c2e2281f3b861f394aed69ad83f7e49 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 7 Jul 2022 15:52:41 +0300 Subject: [PATCH 101/316] Removed link to uncreated page. This uncreated page is related to Flexible Data Clustering, which is not released yet. The content for Flexible Data Clustering is saved locally for future use. --- operational_guides/delete_guide.rst | 4 ---- 1 file changed, 4 deletions(-) diff --git a/operational_guides/delete_guide.rst b/operational_guides/delete_guide.rst index c24079f8c..0d6c4a41c 100644 --- a/operational_guides/delete_guide.rst +++ b/operational_guides/delete_guide.rst @@ -250,10 +250,6 @@ This section includes the best practices when deleting rows: * SQream is optimized for time-based data, which is data naturally ordered according to date or timestamp. Deleting rows based on such columns leads to increased performance. - :: - -For more information, see `Time-Based Data Management `_. - .. soft update concept .. delete cleanup and it's properties. automatic/manual, in transaction or background From f9a3e9586fe5082fda571f47eace77207331eba0 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 7 Jul 2022 16:22:53 +0300 Subject: [PATCH 102/316] Prepared for 2022.1 release --- _static/images/New_Dark_Gray.png | Bin 0 -> 1073 bytes _static/images/new_2022.1.png | Bin 882 -> 1085 bytes operational_guides/foreign_tables.rst | 10 +++++----- reference/sql/sql_statements/index.rst | 12 ++++++++++-- .../get_extents_file_list_for_chunk.rst | 6 +++++- .../get_metadata_chunk_key.rst | 6 +++++- releases/2022.1.rst | 12 +++++++++++- 7 files changed, 36 insertions(+), 10 deletions(-) create mode 100644 _static/images/New_Dark_Gray.png diff --git a/_static/images/New_Dark_Gray.png b/_static/images/New_Dark_Gray.png new file mode 100644 index 0000000000000000000000000000000000000000..34ac016ebccc01827492455680537addf4b08c9e GIT binary patch literal 1073 zcmV-11kU@3P)m00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGqB>(^xB>_oNB=7(L1I9^2K~z{r?O3gH zB0&&t)+M!X5E~+>JOO7Am=J@CJ-3m;#36Ap8yVbLR7^G|0&_e8g@D*R!EJ%u`?_al znO&BdP^37jE??D9^Vc)e|Gm`yESFh0?hy?dl)goDYzTX&L__X1i59;pJzL5A|Ag@5 zgXl+{=rW-+Zectos&$BxjMCPM0@*Ntl=^p?L|=yXVO-YIwB-mwX1=tJ;3q00M3V33nT5BngE;kAx>Bwd~HlM0ZK z$|Uo5C~=C8?WQ)a?v*!I#PmY4HK8M(t`*1buB}(_3fGTtt8J0b*c)~Apa^D6EE5(g z=SxDbxRXO&!4M$qjtOV}JgPhoo$i&In6p62z@2bT7FZb@^dbx)A=j?A2jM4B!Tr zz*2;n5kgdpLx2{ztDrg*OaWsX#YHJ@3BV8=`^C8$8dTBS@U4Fl0tpii*xo3fQvisi z{8ynZZ$>eB1;rs$7bsnv#icP9R9iynA)vlLVMOIzROfdhE!dIgeU2aS$~w{5O0VHt z-xZQKBk010u4e*Cn6Ao+VZ4#8(ZGbuN)OeLJxB<*P^2lISV&WhN1)v`Ph7FmOF3Fs zcDs0VE?}#Q%u&VH1Bb+Zo?o5xfNPzjk`!iE(dR=>WAQD~%{WySH?yo6XZ+8NX<0;Q zNpWrwXBoEJ^OyuJ=6F7DQIU?%=lLWn(G>SpwJeD?-^K^o_gU-tn!c;5<$P>3yc188 zJ+3=E^xk#DzkMdld&_?H9!*n_{hHSrU#dP%tF7uA#|f!=wcY~x80F6hySn?v@x!Vq rRCUUQ%ivME-#C8AUwb`MQxN?HAc-16j1ijA00000NkvXXu0mjfU~=nV literal 0 HcmV?d00001 diff --git a/_static/images/new_2022.1.png b/_static/images/new_2022.1.png index 4861ba76a5b6c7d35703267596db1f4c0a8c9fb5..27b2d285af4bee0337de2888e4bfcf8dbbcc77b1 100644 GIT binary patch delta 1025 zcmV+c1pfQ-2E7Q783+ad000;Y^Td%MHGk4cL_t(oN9|a>YAQh#KJMm40x^Z;3A~U} zh-s|S-fjg6BuzTYbZIOkV7jzcX|jT4;Q9n&p+a87W$$;+%#O3`IukK?g_{pXc4qd> znK?h-9Ji7JG-?w))+qV7rDH?bIU#!Cr#jK%4<)CGjQ>vv!%w1LRicZSlII5cV}GJb zlPFG!u80DnB^(GVb?>x@GF*6q)`zeK8Sh|$10nqE!-4F)l#gm4mGfn-a3(fd zcxla_bo7jZSKc$f4a)9$U1dm;22l@oc^gSTpyfN!B%-8IVxapc{qT>lnBnK*TeDB1 zxH>~ntfbMRhd^oO1GbH*Cyaxnq<=*(a4G@{@X3E^{Q_8qovj$hfg0~i(CMNi(kaqIey@EBx69c34)ymiojSGi#oE=MLS{t(nK#Ki#9tb!hdlmCu2kI z!X`F3xmR+UlAJn42lS3JI>R#zzY}!!)0yfD#9*+K!w>r)c}CVc>X9Tll`Yv2N@btV zmvG_~4|bZ`xO!08SiT-bqV>dH8^WUQ?^MCNrLWRJXvq6f0P9!HAtcVTy0(|p(1NIE~%-bLlz}fin zxEaxMm*Qj(*5>ZIYsZ~k<= zJkSqr$R2**BM?yamDL0u_~iFp--{aTKb^ygK1epg8BeMb$^+xo3V+JotbyA#?MMLJ zKnWs64l_i7(qIbE26q)yhk`C(ILi&r3%n)3fjHRDZH@)X|0jZ|co$W9pE#(^oXa_Wa8~w-##VU^ z-~6tSd-E2)u%YXjKz}YwSLMXWvXP@PLq?aS8LA=g;6iA_ky-J?Mw+5OgzT>O#1%W8 z*Ryo$%5Im8HU_q;NQ1I-JuxMA&Hd_>2VC>aN>Z3vMV}8w#;Q$(-Lj-gd-XJ}_tMpB zWm+1cWQgMY*rKOO32PjKkToTSZc$#2*XQv#Ey(2GD{E;SZEo(37qazP^JY%#Dr@E( z8x8x!*5n?-KHRa{1 vyB{1steT?234Y8Uz<;m_`Lt&~fD`=%VF?q}GPb_U00000NkvXXu0mjfk%{+R delta 821 zcmV-51Iqlp2=WGy83+OZ005V0WRsC0HGc<5L_t(oN9~tAa_TS;$N%^&K*4YVa{@?1 zmG*U_Oqz5l)1@&bK0+#**e8fjz))b{#cx+y%aXA2!6TV@Gx?1QX|>4O)vi{cB?{H1 z8FzjXg%;G(widyENZqDrRiXO@o1?qrQ$1nigfTU93?+&D?0VGMzj~8bFsBl1Pk);u zQ%Yn+Oh3BL8SEKnLB{oI+h(chCum+#DJ3tW~MlW#m*acZ#|Lt&oK`(rDT>0Zc3Hid4Ki>cy(WwOS`No zvP}Pq9)Q%sDopr0bZr^de|MeWWfH6Vy+dR;_?B|)Fi+y(XC#s4e1q2MU0~FPY%qjx zDeXSf0$)3O>2V+G((IdQXsMWfbRFNP?DumWBJinfctq>!cklb9;FnK8F9+?(L|1L6 z&i-;SUHuqQ$nwklX(D#vCH;#)|4>$->|f$9Q>c)1B;vX600000NkvXXu0mjf_%54Y diff --git a/operational_guides/foreign_tables.rst b/operational_guides/foreign_tables.rst index 739652bfa..74c476331 100644 --- a/operational_guides/foreign_tables.rst +++ b/operational_guides/foreign_tables.rst @@ -53,14 +53,14 @@ Based on the source file structure, we we :ref:`create an external table` - Returns a static query plan, which can be used to debug query plans * - :ref:`GET_EXTENTS_FILE_FOR_CHUNK` - - Points to all files that contain data related to a specific chunk + - Points to all files that contain data related to a specific chunk |icon-new_2022.1| * - :ref:`GET_METADATA_CHUNK_KEY` - - Returns a list of metadata key values for the chunks that you specify + - Returns a list of metadata key values for the chunks that you specify |icon-New_Dark_Gray| * - :ref:`SELECT GET_LICENSE_INFO` - View a user's license information * - :ref:`SELECT GET_DDL` @@ -137,6 +137,14 @@ The following table shows the Utility commands: * - :ref:`STOP STATEMENT` - Stops or aborts an active statement +.. |icon-new_2022.1| image:: /_static/images/new_2022.1.png + :align: middle + :width: 110 + +.. |icon-New_Dark_Gray| image:: /_static/images/New_Dark_Gray.png + :align: middle + :width: 110 + Workload Management ====================== The following table shows the Workload Management commands: diff --git a/reference/sql/sql_statements/utility_commands/get_extents_file_list_for_chunk.rst b/reference/sql/sql_statements/utility_commands/get_extents_file_list_for_chunk.rst index 2f872812a..5679e508e 100644 --- a/reference/sql/sql_statements/utility_commands/get_extents_file_list_for_chunk.rst +++ b/reference/sql/sql_statements/utility_commands/get_extents_file_list_for_chunk.rst @@ -3,7 +3,11 @@ ******************** GET_EXTENTS_FILE_FOR_CHUNK ******************** -The ``GET_EXTENTS_FILE_FOR_CHUNK`` command points to all files that contain data related to a specific chunk. This command is used for debugging purposes. +The ``GET_EXTENTS_FILE_FOR_CHUNK`` |icon-new_2022.1| command points to all files that contain data related to a specific chunk. This command is used for debugging purposes. + +.. |icon-new_2022.1| image:: /_static/images/new_2022.1.png + :align: middle + :width: 110 This reference page includes the following information: diff --git a/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst b/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst index 2ccc59132..ee641e3b1 100644 --- a/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst +++ b/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst @@ -3,7 +3,11 @@ ******************** GET_METADATA_CHUNK_KEY ******************** -The ``GET_METADATA_CHUNK_KEY`` command returns specific metadata key values for user-specified chunks. +The ``GET_METADATA_CHUNK_KEY`` |icon-new_2022.1| command returns specific metadata key values for user-specified chunks. + +.. |icon-new_2022.1| image:: /_static/images/new_2022.1.png + :align: middle + :width: 110 This reference page includes the following information: diff --git a/releases/2022.1.rst b/releases/2022.1.rst index a98a397f8..dbf061797 100644 --- a/releases/2022.1.rst +++ b/releases/2022.1.rst @@ -45,6 +45,16 @@ SQream now supports ingesting data from Avro files. For more information, see `Inserting Data from Avro `_. +New Utility Commands +************ +The following two new utility commands have been created: + +* `GET EXTENTS FILE FOR CHUNK `_ - points to all files that contain data related to a specific chunk. This command is used for debugging purposes. + + :: + +* `GET_METADATA_CHUNK_KEY `_ - returns specific metadata key values for user-specified chunks. + Resolved Issues --------- The following table lists the issues that were resolved in Version 2022.1: @@ -76,7 +86,7 @@ Deprecated Features ------- In SQream version 2022.1 the ``VARCHAR`` data type has been deprecated and replaced with ``TEXT``. ``VARCHAR`` will be maintained in all previous versions until migration to ``TEXT`` is complete, at which point it will be deprecated in all earlier versions. -If you are using an earlier version of SQream, see `Using Legacy String Literals `_. +If you are using an earlier version of SQream, see `Using Legacy String Literals `_. An automated process is being used to facilitate migration from ``VARCHAR`` to ``TEXT``. For more information, contact SQream. From 482a45f7b6fd7a5415888ebb7426ef05c160ef02 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Fri, 8 Jul 2022 17:46:17 +0300 Subject: [PATCH 103/316] Two New Utility Commands --- .../get_extents_file_list_for_chunk.rst | 71 +++++++++-- .../get_metadata_chunk_key.rst | 110 ++++++++++++++++-- 2 files changed, 159 insertions(+), 22 deletions(-) diff --git a/reference/sql/sql_statements/utility_commands/get_extents_file_list_for_chunk.rst b/reference/sql/sql_statements/utility_commands/get_extents_file_list_for_chunk.rst index 5679e508e..3c05a48fe 100644 --- a/reference/sql/sql_statements/utility_commands/get_extents_file_list_for_chunk.rst +++ b/reference/sql/sql_statements/utility_commands/get_extents_file_list_for_chunk.rst @@ -23,15 +23,7 @@ The following is the syntax for the ``GET_EXTENTS_FILE_FOR_CHUNK`` command: select get_extents_file_list_for_chunk(database_name, " "table_id, chunk_id);" - -Output -========== -The following is an example of the output generated by the ``GET_EXTENTS_FILE_FOR_CHUNK`` command: - -.. code-block:: postgres - - EXAMPLE NEEDED - + Parameters ============ The following table shows the ``GET_EXTENTS_FILE_FOR_CHUNK`` parameters: @@ -47,15 +39,70 @@ The following table shows the ``GET_EXTENTS_FILE_FOR_CHUNK`` parameters: * - ``table_id`` - The ID of the table where the chunk is located. * - ``chunk_id`` - - The ID of the chunk. + - The ID of the chunk. -Examples +Example =========== The following is an example of the ``GET_EXTENTS_FILE_FOR_CHUNK`` command: .. code-block:: postgres - Example - pending from Eyal W. + master=> select get_extents_file_list_for_chunk('master', 0, 3); + +Output +========== +The following table describes the output generated from the ``GET_EXTENTS_FILE_FOR_CHUNK`` command: + +Database name. table name, table id, column id, chunk id, file path + +.. list-table:: + :widths: 25 25 25 25 + :header-rows: 1 + + * - Parameter + - Description + - Type + - Example + + * - ``database_name`` + - The name of the database where the chunk is located. + - Text + - ``master`` + + * - ``table_name`` + - The ID of the table where the chunk is located. + - Numeric + - ``0`` + + * - ``table_id`` + - The ID of the column. + - Numeric + - ``0`` + + * - ``column_id`` + - The status of the chunk. + - **Comment** - *What is the type?* + - ``1`` + + * - ``chunk_id`` + - Describes the state of the chunk. + - **Comment** - *What is the type?* + - ``chunk_state::`` + + * - ``file_path`` + - Shows the path of the file. + - Text + - **Comment** - *Provide example + +The following is an example of the output generated from the ``GET_EXTENTS_FILE_FOR_CHUNK`` command: + +.. code-block:: postgres + + master,public.t_1,0,0,3,/home/eyalw/sqream_testing_temp/sqreamdb/databases/master/tables/0/0/0-2 + master,public.t_1,0,1,3,/home/eyalw/sqream_testing_temp/sqreamdb/databases/master/tables/0/1/1-2 + master,public.t_1,0,2,3,/home/eyalw/sqream_testing_temp/sqreamdb/databases/master/tables/0/2/2-2 + master,public.t_1,0,3,3,/home/eyalw/sqream_testing_temp/sqreamdb/databases/master/tables/0/3/3-2 + master,public.t_1,0,4,3,/home/eyalw/sqream_testing_temp/sqreamdb/databases/master/tables/0/4/4-2 Permissions ============= diff --git a/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst b/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst index ee641e3b1..c43775de7 100644 --- a/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst +++ b/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst @@ -23,14 +23,6 @@ The following is the syntax for the ``GET_METADATA_CHUNK_KEY`` command: get_metadata_chunk_key(database_name, table_id, chunk_id); -Output -========== -The following is an example of the output generated by the ``GET_METADATA_CHUNK_KEY`` command: - -.. code-block:: postgres - - EXAMPLE NEEDED - Parameters ============ The following table shows the ``GET_METADATA_CHUNK_KEY`` parameters: @@ -48,13 +40,111 @@ The following table shows the ``GET_METADATA_CHUNK_KEY`` parameters: * - ``chunk_id`` - The ID of the chunk. -Examples +Example =========== The following is an example of the ``GET_METADATA_CHUNK_KEY`` command: .. code-block:: postgres - Example - pending from Eyal W. + master=> select get_metadata_chunk_key('master', 0, 1); + +Output +========== +The following table describes the output generated from the ``GET_METADATA_CHUNK_KEY`` command: + +.. list-table:: + :widths: 25 25 25 25 + :header-rows: 1 + + * - Parameter + - Description + - Type + - Example + + * - ``database_name`` + - The name of the database where the chunk is located. + - Text + - ``master`` + + * - ``table_id`` + - The ID of the table where the chunk is located. + - Numeric + - ``0`` + + * - ``column_id`` + - The ID of the column. + - Numeric + - ``0`` + + * - ``chunk_status`` + - The status of the chunk. + - **Comment** - *What is the type?* + - ``1`` + + * - ``chunk_aligned`` + - Describes the state of the chunk. + - **Comment** - *What is the type?* + - ``chunk_state::`` + + * - ``offset_in_file`` + - Shows the file's offset setting. + - Numeric + - ``-1`` + + * - ``compressed_size`` + - Shows the file's compressed size. + - Numeric + - ``0`` + + * - ``uncompressed_size`` + - Shows the file's uncompressed size. + - Numeric + - ``2`` + + * - ``compression_type`` + - Shows the file's compression type. + - Numeric + - ``2`` + + * - ``min_long`` + - **Comment** - What is it? + - **Comment** - What is it? + - ``flat`` + + * - ``max_long`` + - **Comment** - What is it? + - **Comment** - What is it? + - **Comment** - What is it? + + * - ``min_string_max_string`` + - **Comment** - What is it? + - **Comment** - What is it? + - **Comment** - What is it? + + * - ``min_numeric`` + - **Comment** - What is it? + - **Comment** - What is it? + - **Comment** - What is it? + + * - ``max_numeric`` + - **Comment** - What is it? + - **Comment** - What is it? + - **Comment** - What is it? + + * - ``column_aligned`` + - **Comment** - What is it? + - **Comment** - What is it? + - **Comment** - What is it? + +The following is an example of the output generated from the ``GET_METADATA_CHUNK_KEY`` command: + +.. code-block:: postgres + + master,0,0,1,chunk_state::clean,1,0,2,2,flat,0,0,,,0x7f722ffb7c60,0x7f722ffb7c70,1 + master,0,1,1,chunk_state::clean,1,0,8,8,flat,1,2,,,0x7f722ffb7c60,0x7f722ffb7c70,1 + master,0,2,1,chunk_state::clean,1,0,2,2,flat,0,0,,,0x7f722ffb7c60,0x7f722ffb7c70,1 + master,0,3,1,chunk_state::clean,1,0,8,8,flat,3,3,,,0x7f722ffb7c60,0x7f722ffb7c70,1 + master,0,4,1,chunk_state::clean,1,0,16,16,flat,0,0,abc,dfg,0x7f722ffb7c60,0x7f722ffb7c70,1 Permissions ============= From b37d0c0ce6d30e461ae2b63cdba66c969063d9e4 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 10 Jul 2022 13:10:10 +0300 Subject: [PATCH 104/316] Updated Replaced External Tables with Foreign Tables Finalized VARCHAR deprecation text --- operational_guides/foreign_tables.rst | 35 ++++++++++++++------------- releases/2022.1.rst | 27 +++------------------ 2 files changed, 21 insertions(+), 41 deletions(-) diff --git a/operational_guides/foreign_tables.rst b/operational_guides/foreign_tables.rst index 74c476331..bc8c401a6 100644 --- a/operational_guides/foreign_tables.rst +++ b/operational_guides/foreign_tables.rst @@ -4,18 +4,18 @@ Foreign Tables *********************** Foreign tables can be used to run queries directly on data without inserting it into SQream DB first. -SQream DB supports read only external tables, so you can query from external tables, but you cannot insert to them, or run deletes or updates on them. +SQream DB supports read only foreign tables, so you can query from foreign tables, but you cannot insert to them, or run deletes or updates on them. Running queries directly on external data is most effectively used for things like one off querying. If you will be repeatedly querying data, the performance will usually be better if you insert the data into SQream DB first. -Although external tables can be used without inserting data into SQream DB, one of their main use cases is to help with the insertion process. An insert select statement on an external table can be used to insert data into SQream using the full power of the query engine to perform ETL. +Although foreign tables can be used without inserting data into SQream DB, one of their main use cases is to help with the insertion process. An insert select statement on a foreign table can be used to insert data into SQream using the full power of the query engine to perform ETL. .. contents:: In this topic: :local: Supported Data Formats ===================================== -SQream DB supports external tables over: +SQream DB supports foreign tables over: * Text files (e.g. CSV, PSV, TSV) * ORC @@ -29,9 +29,9 @@ SQream can stage data from: * :ref:`s3` buckets (e.g. ``s3://pp-secret-bucket/users/*.parquet``) * :ref:`hdfs` (e.g. ``hdfs://hadoop-nn.piedpiper.com/rhendricks/*.csv``) -Using External Tables +Using Foreign Tables ============================================== -Use an external table to stage data before loading from CSV, Parquet or ORC files. +Use a foreign table to stage data before loading from CSV, Parquet or ORC files. Planning for Data Staging -------------------------------- @@ -45,13 +45,13 @@ For the following examples, we will want to interact with a CSV file. Here's a p The file is stored on :ref:`s3`, at ``s3://sqream-demo-data/nba_players.csv``. We will make note of the file structure, to create a matching ``CREATE_EXTERNAL_TABLE`` statement. -Creating an External Table +Creating a Foreign Table ----------------------------- -Based on the source file structure, we we :ref:`create an external table` with the appropriate structure, and point it to the file. +Based on the source file structure, we we :ref:`create a foreign table` with the appropriate structure, and point it to the file. .. code-block:: postgres - CREATE EXTERNAL TABLE nba + CREATE foreign table nba ( Name varchar, Team varchar, @@ -68,12 +68,13 @@ Based on the source file structure, we we :ref:`create an external table SELECT * FROM nba; master=> select * from nba; Record delimiter mismatch during CSV parsing. User defined line delimiter \n does not match the first delimiter \r\n found in s3://sqream-demo-data/nba.csv -* Since the data for an external table is not stored in SQream DB, it can be changed or removed at any time by an external process. As a result, the same query can return different results each time it runs against an external table. Similarly, a query might fail if the external data is moved, removed, or has changed structure. \ No newline at end of file +* Since the data for a foreign table is not stored in SQream DB, it can be changed or removed at any time by an external process. As a result, the same query can return different results each time it runs against a foreign table. Similarly, a query might fail if the external data is moved, removed, or has changed structure. \ No newline at end of file diff --git a/releases/2022.1.rst b/releases/2022.1.rst index dbf061797..ac180206c 100644 --- a/releases/2022.1.rst +++ b/releases/2022.1.rst @@ -16,6 +16,7 @@ The 2022.1 Release Notes describes the following: * Enhanced security features. * New data manipulation command. * Additional data ingestion format. +* New utility commands. New Features ---------- @@ -84,31 +85,9 @@ No relevant naming changes were made. Deprecated Features ------- -In SQream version 2022.1 the ``VARCHAR`` data type has been deprecated and replaced with ``TEXT``. ``VARCHAR`` will be maintained in all previous versions until migration to ``TEXT`` is complete, at which point it will be deprecated in all earlier versions. +In SQream version 2022.1 the ``VARCHAR`` data type has been deprecated and replaced with ``TEXT``. SQream will maintain ``VARCHAR`` in all previous versions until completing the migration to ``TEXT``, at which point it will be deprecated in all earlier versions. SQream also provides an automated and secure tool to facilitate and simplify migration from ``VARCHAR`` to ``TEXT``. -If you are using an earlier version of SQream, see `Using Legacy String Literals `_. - -An automated process is being used to facilitate migration from ``VARCHAR`` to ``TEXT``. For more information, contact SQream. - -**Comment** - *Below is the original text of the VARCHAR deprecation email. I don't think that we need to necessarily expose our logic to our customers, but focus on certain aspects of it (see the first paragraph above). However, I can use more/all of this content if deemed necessary.* - -* SQream has decided to deprecated support in varchar data type, the decision made out of SQream effort to enhance its core functionalities and with respect to ever changing eco system requirements. - - :: - -* For new customers Varchar data type is not supported - - :: - -* The supported data type that will replace this data type is text as all different functionalities encapsulated within this data type - - :: - -* SQream will maintain varchar data type support until the last customer will be fully migrated - - :: - -* In order to enhance the conversion mechanism to be as fast as possible SQream will provide an automated and secured tool to help customers with the conversion phase from VARCHAR to TEXT data type, please address delivery for further information +If you are using an earlier version of SQream, see the `Using Legacy String Literals `_ configuration flag. Known Issues and Limitations -------- From 1e77017a98e3734dcf60ab1a4d6eeac6494d5006 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 10 Jul 2022 17:33:10 +0300 Subject: [PATCH 105/316] Added Loading and Unloading Data section to menu Modified menu. Added links to Performing Basic SQream Operations page. --- .../performing_basic_sqream_operations.rst | 9 +++-- index.rst | 15 ++++---- loading_and_unloading_data/index.rst | 36 +++++++++++++++++++ 3 files changed, 50 insertions(+), 10 deletions(-) create mode 100644 loading_and_unloading_data/index.rst diff --git a/getting_started/performing_basic_sqream_operations.rst b/getting_started/performing_basic_sqream_operations.rst index 1b0f60ba3..0808c22dd 100644 --- a/getting_started/performing_basic_sqream_operations.rst +++ b/getting_started/performing_basic_sqream_operations.rst @@ -11,10 +11,13 @@ After installing SQream you can perform the operations described on this page: running_the_sqream_sql_client creating_your_first_table - creating_a_database - querying_data listing_tables inserting_rows running_queries deleting_rows - saving_query_results_to_a_csv_or_psv_file \ No newline at end of file + saving_query_results_to_a_csv_or_psv_file + +For more information on other basic SQream operations, see the following: + +* `Creating a Database `_ +* :ref:`data_ingestion` \ No newline at end of file diff --git a/index.rst b/index.rst index 29ea038b0..72731e378 100644 --- a/index.rst +++ b/index.rst @@ -10,7 +10,7 @@ The **v2022.1** branch is a private branch designed for internal use only until .. tip:: Want to read this offline? - `Download the documentation as a single PDF `_ . + `Download the documentation as a single PDF `_ . .. only:: pdf or latex @@ -35,7 +35,7 @@ SQream DB easily plugs in to third-party tools like :ref:`Tableau`_ + `Getting Started `_ :ref:`sql_feature_support` @@ -47,7 +47,7 @@ SQream DB easily plugs in to third-party tools like :ref:`Tableau`_ + `Setting up SQream `_ :ref:`Best practices` @@ -59,7 +59,7 @@ SQream DB easily plugs in to third-party tools like :ref:`Tableau` - :ref:`2021.2<2021.2>` + :ref:`2021.2<2021.2>` :ref:`2021.1<2021.1>` @@ -103,7 +103,8 @@ If you're looking for an older version of the documentation, versions 1.10 throu getting_started/index installation_guides/index data_ingestion/index - third_party_tools/index + connecting_to_sqream/index + loading_and_unloading/index feature_guides/index operational_guides/index sqream_studio_5.4.3/index @@ -116,9 +117,9 @@ If you're looking for an older version of the documentation, versions 1.10 throu glossary .. - Indices and tables + Indices and Tables ================== * :ref:`genindex` * :ref:`modindex` - * :ref:`search` + * :ref:`search` \ No newline at end of file diff --git a/loading_and_unloading_data/index.rst b/loading_and_unloading_data/index.rst new file mode 100644 index 000000000..ae5c506bb --- /dev/null +++ b/loading_and_unloading_data/index.rst @@ -0,0 +1,36 @@ +.. _loading_and_unloading_data: + +*********************** +Loading and Unloading Data +*********************** +The **Loading Data** section describes concepts and operations related to importing data into your SQream database: + +* `Overview of loading data `_ - Describes best practices and considerations for loading data into SQream from a variety of sources and locations. + +* `Alternatives to loading data (foreign tables) `_ - Useful for running queries directly on external data without importing into your SQream database. + +* `Supported data types `_ - Overview of supported data types, including descriptions, examples, and relevant aliases. + +* `Ingesting data from external sources `_ - List of data ingestion sources that SQream supports. + +* `Inserting data from external tables `_ - Inserts one or more rows into a table. + +* `Ingesting data from third party client platforms `_ - Gives you direct access to a variety of drivers, connectors, tools, vizualisers, and utilities.. + +* `Using the COPY FROM statement `_ - Used for loading data from files located on a filesystem into SQream tables. + +* `Importing data using Studio `_ - SQream's web-based client providing users with all functionality available from the command line in an intuitive and easy-to-use format. + +* `Loading data using Amazon S3 `_ - Used for loading data from Amazon S3. + +* Troubleshooting - Describes troubleshooting solutions related to importing data from the following: + + * `SAS Viya `_ + + * `Tableau `_ + +The **Unloading Data** section describes concepts and operations related to exporting data from your SQream database: + +* `Overview of unloading data `_ - Describes best practices and considerations for unloading data from SQream to a variety of sources and locations. + +* `The COPY TO statement `_ - Used for unloading data from a SQream database table or query to a file on a filesystem. \ No newline at end of file From 5889fbaa833656f3bd364d7c011c2574831f7144 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 10 Jul 2022 17:45:18 +0300 Subject: [PATCH 106/316] Corrected the menu --- .../client_drivers/index.rst | 166 +++--- .../client_drivers/jdbc/index.rst | 342 ++++++------ .../client_drivers/jdbc/sample.java | 132 ++--- .../client_drivers/odbc/index.rst | 114 ++-- .../odbc/install_configure_odbc_linux.rst | 506 +++++++++--------- .../odbc/install_configure_odbc_windows.rst | 268 +++++----- .../connectivity_ecosystem.jpg | Bin .../index.rst | 32 +- index.rst | 2 +- 9 files changed, 781 insertions(+), 781 deletions(-) rename {third_party_tools => connecting_to_sqream}/client_drivers/index.rst (97%) rename {third_party_tools => connecting_to_sqream}/client_drivers/jdbc/index.rst (97%) rename {third_party_tools => connecting_to_sqream}/client_drivers/jdbc/sample.java (97%) rename {third_party_tools => connecting_to_sqream}/client_drivers/odbc/index.rst (96%) rename {third_party_tools => connecting_to_sqream}/client_drivers/odbc/install_configure_odbc_linux.rst (96%) rename {third_party_tools => connecting_to_sqream}/client_drivers/odbc/install_configure_odbc_windows.rst (97%) rename {third_party_tools => connecting_to_sqream}/connectivity_ecosystem.jpg (100%) rename {third_party_tools => connecting_to_sqream}/index.rst (95%) diff --git a/third_party_tools/client_drivers/index.rst b/connecting_to_sqream/client_drivers/index.rst similarity index 97% rename from third_party_tools/client_drivers/index.rst rename to connecting_to_sqream/client_drivers/index.rst index d0c60d804..79d1fd176 100644 --- a/third_party_tools/client_drivers/index.rst +++ b/connecting_to_sqream/client_drivers/index.rst @@ -1,84 +1,84 @@ -.. _client_drivers: - -************************************ -Client Drivers for 2022.1 -************************************ - -The guides on this page describe how to use the Sqream DB client drivers and client applications with SQream. - -Client Driver Downloads -============================= - -All Operating Systems ---------------------------- -The following are applicable to all operating systems: - -.. _jdbc: - -* **JDBC** - recommended installation via ``mvn``: - - * `JDBC .jar file `_ - sqream-jdbc-4.5.3 (.jar) - * `JDBC driver `_ - -.. _tableau_connector: - -* **Tableau**: - - * `Tableau connector `_ - SQream (.taco) - * `Tableau manual installation `_ - - -.. _powerbi_connector: - -* **Power BI**: - - * `Power BI PowerQuery connector `_ - SQream (.mez) - * `Power BI manual installation `_ - - -Windows --------------- -The following are applicable to Windows: - -* **ODBC installer** - SQream Drivers v2020.2.0, with Tableau customizations. Please contact your `SSream represenative `_ for this installer. - - For more information on installing and configuring ODBC on Windows, see :ref:`Install and configure ODBC on Windows `. - -* **Net driver** - `SQream .Net driver v3.0.2 `_ - - - -Linux --------------- -The following are applicable to Linux: - -* `SQream SQL (x86_64) `_ - sqream-sql-v2020.1.1_stable.x86_64.tar.gz -* `Sqream SQL CLI Reference `_ - Interactive command-line SQL client for Intel-based machines - - :: - -* `SQream SQL*(IBM POWER9) `_ - sqream-sql-v2020.1.1_stable.ppc64le.tar.gz -* `Sqream SQL CLI Reference `_ - Interactive command-line SQL client for IBM POWER9-based machines - - :: - -* ODBC Installer - Please contact your SQream representative for this installer. - - -.. toctree:: - :maxdepth: 4 - :caption: Client Driver Documentation: - :titlesonly: - - jdbc/index - odbc/index - - - -.. rubric:: Need help? - -If you couldn't find what you're looking for, we're always happy to help. Visit `SQream's support portal `_ for additional support. - -.. rubric:: Looking for older drivers? - +.. _client_drivers: + +************************************ +Client Drivers for 2022.1 +************************************ + +The guides on this page describe how to use the Sqream DB client drivers and client applications with SQream. + +Client Driver Downloads +============================= + +All Operating Systems +--------------------------- +The following are applicable to all operating systems: + +.. _jdbc: + +* **JDBC** - recommended installation via ``mvn``: + + * `JDBC .jar file `_ - sqream-jdbc-4.5.3 (.jar) + * `JDBC driver `_ + +.. _tableau_connector: + +* **Tableau**: + + * `Tableau connector `_ - SQream (.taco) + * `Tableau manual installation `_ + + +.. _powerbi_connector: + +* **Power BI**: + + * `Power BI PowerQuery connector `_ - SQream (.mez) + * `Power BI manual installation `_ + + +Windows +-------------- +The following are applicable to Windows: + +* **ODBC installer** - SQream Drivers v2020.2.0, with Tableau customizations. Please contact your `SSream represenative `_ for this installer. + + For more information on installing and configuring ODBC on Windows, see :ref:`Install and configure ODBC on Windows `. + +* **Net driver** - `SQream .Net driver v3.0.2 `_ + + + +Linux +-------------- +The following are applicable to Linux: + +* `SQream SQL (x86_64) `_ - sqream-sql-v2020.1.1_stable.x86_64.tar.gz +* `Sqream SQL CLI Reference `_ - Interactive command-line SQL client for Intel-based machines + + :: + +* `SQream SQL*(IBM POWER9) `_ - sqream-sql-v2020.1.1_stable.ppc64le.tar.gz +* `Sqream SQL CLI Reference `_ - Interactive command-line SQL client for IBM POWER9-based machines + + :: + +* ODBC Installer - Please contact your SQream representative for this installer. + + +.. toctree:: + :maxdepth: 4 + :caption: Client Driver Documentation: + :titlesonly: + + jdbc/index + odbc/index + + + +.. rubric:: Need help? + +If you couldn't find what you're looking for, we're always happy to help. Visit `SQream's support portal `_ for additional support. + +.. rubric:: Looking for older drivers? + If you're looking for an older version of SQream DB drivers, versions 1.10 through 2019.2.1 are available at https://sqream.com/product/client-drivers/. \ No newline at end of file diff --git a/third_party_tools/client_drivers/jdbc/index.rst b/connecting_to_sqream/client_drivers/jdbc/index.rst similarity index 97% rename from third_party_tools/client_drivers/jdbc/index.rst rename to connecting_to_sqream/client_drivers/jdbc/index.rst index 4c35c3eff..832987efa 100644 --- a/third_party_tools/client_drivers/jdbc/index.rst +++ b/connecting_to_sqream/client_drivers/jdbc/index.rst @@ -1,171 +1,171 @@ -.. _java_jdbc: - -************************* -JDBC -************************* -The SQream JDBC driver lets you connect to SQream using many Java applications and tools. This page describes how to write a Java application using the JDBC interface. The JDBC driver requires Java 1.8 or newer. - -The JDBC page includes the following sections: - -.. contents:: - :local: - :depth: 1 - -Installing the JDBC Driver -================================== -The **Installing the JDBC Driver** section describes the following: - -.. contents:: - :local: - :depth: 1 - -Prerequisites ----------------- -The SQream JDBC driver requires Java 1.8 or newer, and SQream recommends using Oracle Java or OpenJDK.: - -* **Oracle Java** - Download and install `Java 8 `_ from Oracle for your platform. - - :: - -* **OpenJDK** - Install `OpenJDK `_ - - :: - -* **Windows** - SQream recommends installing `Zulu 8 `_ - -Getting the JAR file ---------------------- -SQream provides the JDBC driver as a zipped JAR file, available for download from the :ref:`client drivers download page`. This JAR file can be integrated into your Java-based applications or projects. - -Extracting the ZIP Archive -------------------------- -Run the following command to extract the JAR file from the ZIP archive: - -.. code-block:: console - - $ unzip sqream-jdbc-4.3.0.zip - -Setting Up the Class Path ----------------------------- -To use the driver, you must include the JAR named ``sqream-jdbc-.jar`` in the class path, either by inserting it in the ``CLASSPATH`` environment variable, or by using flags on the relevant Java command line. - -For example, if the JDBC driver has been unzipped to ``/home/sqream/sqream-jdbc-4.3.0.jar``, the following command is used to run application: - -.. code-block:: console - - $ export CLASSPATH=/home/sqream/sqream-jdbc-4.3.0.jar:$CLASSPATH - $ java my_java_app - -Alternatively, you can pass ``-classpath`` to the Java executable file: - -.. code-block:: console - - $ java -classpath .:/home/sqream/sqream-jdbc-4.3.0.jar my_java_app - -Connecting to SQream Using a JDBC Application -============================================== -You can connect to SQream using one of the following JDBC applications: - -.. contents:: - :local: - :depth: 1 - -Driver Class --------------- -Use ``com.sqream.jdbc.SQDriver`` as the driver class in the JDBC application. - -Connection String --------------------- -JDBC drivers rely on a connection string. - -The following is the syntax for SQream: - -.. code-block:: text - - jdbc:Sqream:///;user=;password=sqream;[; ...] - -Connection Parameters -^^^^^^^^^^^^^^^^^^^^^^^^ -The following table shows the connection string parameters: - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Item - - State - - Default - - Description - * - ```` - - Mandatory - - None - - Hostname and port of the SQream DB worker. For example, ``127.0.0.1:5000``, ``sqream.mynetwork.co:3108`` - * - ```` - - Mandatory - - None - - Database name to connect to. For example, ``master`` - * - ``username=`` - - Mandatory - - None - - Username of a role to use for connection. For example, ``username=rhendricks`` - * - ``password=`` - - Mandatory - - None - - Specifies the password of the selected role. For example, ``password=Tr0ub4dor&3`` - * - ``service=`` - - Optional - - ``sqream`` - - Specifices service queue to use. For example, ``service=etl`` - * - ```` - - Optional - - ``false`` - - Specifies SSL for this connection. For example, ``ssl=true`` - * - ```` - - Optional - - ``true`` - - Connect via load balancer (use only if exists, and check port). - * - ```` - - Optional - - ``true`` - - Enables on-demand loading, and defines double buffer size for result. The ``fetchSize`` parameter is rounded according to chunk size. For example, ``fetchSize=1`` loads one row and is rounded to one chunk. If the fetchSize is 100,600, a chunk size of 100,000 loads, and is rounded to, two chunks. - * - ```` - - Optional - - ``true`` - - Defines the bytes size for inserting a buffer before flushing data to the server. Clients running a parameterized insert (network insert) can define the amount of data to collect before flushing the buffer. - * - ```` - - Optional - - ``true`` - - Defines the logger level as either ``debug`` or ``trace``. - * - ```` - - Optional - - ``true`` - - Enables the file appender and defines the file name. The file name can be set as either the file name or the file path. - -Connection String Examples -^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The following is an example of a SQream cluster with load balancer and no service queues (with SSL): - -.. code-block:: text - - jdbc:Sqream://sqream.mynetwork.co:3108/master;user=rhendricks;password=Tr0ub4dor&3;ssl=true;cluster=true - -The following is a minimal example for a local standalone SQream database: - -.. code-block:: text - - jdbc:Sqream://127.0.0.1:5000/master;user=rhendricks;password=Tr0ub4dor&3 - -The following is an example of a SQream cluster with load balancer and a specific service queue named ``etl``, to the database named ``raviga`` - -.. code-block:: text - - jdbc:Sqream://sqream.mynetwork.co:3108/raviga;user=rhendricks;password=Tr0ub4dor&3;cluster=true;service=etl - -Sample Java Program --------------------- -You can download the :download:`JDBC Application Sample File ` below by right-clicking and saving it to your computer. - -.. literalinclude:: sample.java - :language: java - :caption: JDBC Application Sample - :linenos: +.. _java_jdbc: + +************************* +JDBC +************************* +The SQream JDBC driver lets you connect to SQream using many Java applications and tools. This page describes how to write a Java application using the JDBC interface. The JDBC driver requires Java 1.8 or newer. + +The JDBC page includes the following sections: + +.. contents:: + :local: + :depth: 1 + +Installing the JDBC Driver +================================== +The **Installing the JDBC Driver** section describes the following: + +.. contents:: + :local: + :depth: 1 + +Prerequisites +---------------- +The SQream JDBC driver requires Java 1.8 or newer, and SQream recommends using Oracle Java or OpenJDK.: + +* **Oracle Java** - Download and install `Java 8 `_ from Oracle for your platform. + + :: + +* **OpenJDK** - Install `OpenJDK `_ + + :: + +* **Windows** - SQream recommends installing `Zulu 8 `_ + +Getting the JAR file +--------------------- +SQream provides the JDBC driver as a zipped JAR file, available for download from the :ref:`client drivers download page`. This JAR file can be integrated into your Java-based applications or projects. + +Extracting the ZIP Archive +------------------------- +Run the following command to extract the JAR file from the ZIP archive: + +.. code-block:: console + + $ unzip sqream-jdbc-4.3.0.zip + +Setting Up the Class Path +---------------------------- +To use the driver, you must include the JAR named ``sqream-jdbc-.jar`` in the class path, either by inserting it in the ``CLASSPATH`` environment variable, or by using flags on the relevant Java command line. + +For example, if the JDBC driver has been unzipped to ``/home/sqream/sqream-jdbc-4.3.0.jar``, the following command is used to run application: + +.. code-block:: console + + $ export CLASSPATH=/home/sqream/sqream-jdbc-4.3.0.jar:$CLASSPATH + $ java my_java_app + +Alternatively, you can pass ``-classpath`` to the Java executable file: + +.. code-block:: console + + $ java -classpath .:/home/sqream/sqream-jdbc-4.3.0.jar my_java_app + +Connecting to SQream Using a JDBC Application +============================================== +You can connect to SQream using one of the following JDBC applications: + +.. contents:: + :local: + :depth: 1 + +Driver Class +-------------- +Use ``com.sqream.jdbc.SQDriver`` as the driver class in the JDBC application. + +Connection String +-------------------- +JDBC drivers rely on a connection string. + +The following is the syntax for SQream: + +.. code-block:: text + + jdbc:Sqream:///;user=;password=sqream;[; ...] + +Connection Parameters +^^^^^^^^^^^^^^^^^^^^^^^^ +The following table shows the connection string parameters: + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Item + - State + - Default + - Description + * - ```` + - Mandatory + - None + - Hostname and port of the SQream DB worker. For example, ``127.0.0.1:5000``, ``sqream.mynetwork.co:3108`` + * - ```` + - Mandatory + - None + - Database name to connect to. For example, ``master`` + * - ``username=`` + - Mandatory + - None + - Username of a role to use for connection. For example, ``username=rhendricks`` + * - ``password=`` + - Mandatory + - None + - Specifies the password of the selected role. For example, ``password=Tr0ub4dor&3`` + * - ``service=`` + - Optional + - ``sqream`` + - Specifices service queue to use. For example, ``service=etl`` + * - ```` + - Optional + - ``false`` + - Specifies SSL for this connection. For example, ``ssl=true`` + * - ```` + - Optional + - ``true`` + - Connect via load balancer (use only if exists, and check port). + * - ```` + - Optional + - ``true`` + - Enables on-demand loading, and defines double buffer size for result. The ``fetchSize`` parameter is rounded according to chunk size. For example, ``fetchSize=1`` loads one row and is rounded to one chunk. If the fetchSize is 100,600, a chunk size of 100,000 loads, and is rounded to, two chunks. + * - ```` + - Optional + - ``true`` + - Defines the bytes size for inserting a buffer before flushing data to the server. Clients running a parameterized insert (network insert) can define the amount of data to collect before flushing the buffer. + * - ```` + - Optional + - ``true`` + - Defines the logger level as either ``debug`` or ``trace``. + * - ```` + - Optional + - ``true`` + - Enables the file appender and defines the file name. The file name can be set as either the file name or the file path. + +Connection String Examples +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The following is an example of a SQream cluster with load balancer and no service queues (with SSL): + +.. code-block:: text + + jdbc:Sqream://sqream.mynetwork.co:3108/master;user=rhendricks;password=Tr0ub4dor&3;ssl=true;cluster=true + +The following is a minimal example for a local standalone SQream database: + +.. code-block:: text + + jdbc:Sqream://127.0.0.1:5000/master;user=rhendricks;password=Tr0ub4dor&3 + +The following is an example of a SQream cluster with load balancer and a specific service queue named ``etl``, to the database named ``raviga`` + +.. code-block:: text + + jdbc:Sqream://sqream.mynetwork.co:3108/raviga;user=rhendricks;password=Tr0ub4dor&3;cluster=true;service=etl + +Sample Java Program +-------------------- +You can download the :download:`JDBC Application Sample File ` below by right-clicking and saving it to your computer. + +.. literalinclude:: sample.java + :language: java + :caption: JDBC Application Sample + :linenos: diff --git a/third_party_tools/client_drivers/jdbc/sample.java b/connecting_to_sqream/client_drivers/jdbc/sample.java similarity index 97% rename from third_party_tools/client_drivers/jdbc/sample.java rename to connecting_to_sqream/client_drivers/jdbc/sample.java index 1b7af5804..3ff670747 100644 --- a/third_party_tools/client_drivers/jdbc/sample.java +++ b/connecting_to_sqream/client_drivers/jdbc/sample.java @@ -1,67 +1,67 @@ -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.DriverManager; -import java.sql.Statement; -import java.sql.ResultSet; - -import java.io.IOException; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.sql.SQLException; - - - -public class SampleTest { - - // Replace with your connection string - static final String url = "jdbc:Sqream://sqream.mynetwork.co:3108/master;user=rhendricks;password=Tr0ub4dor&3;ssl=true;cluster=true"; - - // Allocate objects for result set and metadata - Connection conn = null; - Statement stmt = null; - ResultSet rs = null; - DatabaseMetaData dbmeta = null; - - int res = 0; - - public void testJDBC() throws SQLException, IOException { - - // Create a connection - conn = DriverManager.getConnection(url,"rhendricks","Tr0ub4dor&3"); - - // Create a table with a single integer column - String sql = "CREATE TABLE test (x INT)"; - stmt = conn.createStatement(); // Prepare the statement - stmt.execute(sql); // Execute the statement - stmt.close(); // Close the statement handle - - // Insert some values into the newly created table - sql = "INSERT INTO test VALUES (5),(6)"; - stmt = conn.createStatement(); - stmt.execute(sql); - stmt.close(); - - // Get values from the table - sql = "SELECT * FROM test"; - stmt = conn.createStatement(); - rs = stmt.executeQuery(sql); - // Fetch all results one-by-one - while(rs.next()) { - res = rs.getInt(1); - System.out.println(res); // Print results to screen - } - rs.close(); // Close the result set - stmt.close(); // Close the statement handle - } - - - public static void main(String[] args) throws SQLException, KeyManagementException, NoSuchAlgorithmException, IOException, ClassNotFoundException{ - - // Load SQream DB JDBC driver - Class.forName("com.sqream.jdbc.SQDriver"); - - // Create test object and run - SampleTest test = new SampleTest(); - test.testJDBC(); - } +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.DriverManager; +import java.sql.Statement; +import java.sql.ResultSet; + +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.sql.SQLException; + + + +public class SampleTest { + + // Replace with your connection string + static final String url = "jdbc:Sqream://sqream.mynetwork.co:3108/master;user=rhendricks;password=Tr0ub4dor&3;ssl=true;cluster=true"; + + // Allocate objects for result set and metadata + Connection conn = null; + Statement stmt = null; + ResultSet rs = null; + DatabaseMetaData dbmeta = null; + + int res = 0; + + public void testJDBC() throws SQLException, IOException { + + // Create a connection + conn = DriverManager.getConnection(url,"rhendricks","Tr0ub4dor&3"); + + // Create a table with a single integer column + String sql = "CREATE TABLE test (x INT)"; + stmt = conn.createStatement(); // Prepare the statement + stmt.execute(sql); // Execute the statement + stmt.close(); // Close the statement handle + + // Insert some values into the newly created table + sql = "INSERT INTO test VALUES (5),(6)"; + stmt = conn.createStatement(); + stmt.execute(sql); + stmt.close(); + + // Get values from the table + sql = "SELECT * FROM test"; + stmt = conn.createStatement(); + rs = stmt.executeQuery(sql); + // Fetch all results one-by-one + while(rs.next()) { + res = rs.getInt(1); + System.out.println(res); // Print results to screen + } + rs.close(); // Close the result set + stmt.close(); // Close the statement handle + } + + + public static void main(String[] args) throws SQLException, KeyManagementException, NoSuchAlgorithmException, IOException, ClassNotFoundException{ + + // Load SQream DB JDBC driver + Class.forName("com.sqream.jdbc.SQDriver"); + + // Create test object and run + SampleTest test = new SampleTest(); + test.testJDBC(); + } } \ No newline at end of file diff --git a/third_party_tools/client_drivers/odbc/index.rst b/connecting_to_sqream/client_drivers/odbc/index.rst similarity index 96% rename from third_party_tools/client_drivers/odbc/index.rst rename to connecting_to_sqream/client_drivers/odbc/index.rst index 7623b4e99..3ee093692 100644 --- a/third_party_tools/client_drivers/odbc/index.rst +++ b/connecting_to_sqream/client_drivers/odbc/index.rst @@ -1,58 +1,58 @@ -.. _odbc: - -************************* -ODBC -************************* - -.. toctree:: - :maxdepth: 1 - :titlesonly: - :hidden: - - install_configure_odbc_windows - install_configure_odbc_linux - -SQream has an ODBC driver to connect to SQream DB. This tutorial shows how to install the ODBC driver for Linux or Windows for use with applications like Tableau, PHP, and others that use ODBC. - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Platform - - Versions supported - - * - Windows - - * Windows 7 (64 bit) - * Windows 8 (64 bit) - * Windows 10 (64 bit) - * Windows Server 2008 R2 (64 bit) - * Windows Server 2012 - * Windows Server 2016 - * Windows Server 2019 - - * - Linux - - * Red Hat Enterprise Linux (RHEL) 7 - * CentOS 7 - * Ubuntu 16.04 - * Ubuntu 18.04 - -Other distributions may also work, but are not officially supported by SQream. - -.. contents:: In this topic: - :local: - -Downloading the ODBC driver -================================== - -The SQream DB ODBC driver is distributed by your SQream account manager. Before contacting your account manager, verify which platform the ODBC driver will be used on. Go to `SQream Support `_ or contact your SQream account manager to get the driver. - -The driver is provided as an executable installer for Windows, or a compressed tarball for Linux platforms. -After downloading the driver, follow the relevant instructions to install and configure the driver for your platform: - -Install and configure the ODBC driver -======================================= - -Continue based on your platform: - -* :ref:`install_odbc_windows` +.. _odbc: + +************************* +ODBC +************************* + +.. toctree:: + :maxdepth: 1 + :titlesonly: + :hidden: + + install_configure_odbc_windows + install_configure_odbc_linux + +SQream has an ODBC driver to connect to SQream DB. This tutorial shows how to install the ODBC driver for Linux or Windows for use with applications like Tableau, PHP, and others that use ODBC. + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Platform + - Versions supported + + * - Windows + - * Windows 7 (64 bit) + * Windows 8 (64 bit) + * Windows 10 (64 bit) + * Windows Server 2008 R2 (64 bit) + * Windows Server 2012 + * Windows Server 2016 + * Windows Server 2019 + + * - Linux + - * Red Hat Enterprise Linux (RHEL) 7 + * CentOS 7 + * Ubuntu 16.04 + * Ubuntu 18.04 + +Other distributions may also work, but are not officially supported by SQream. + +.. contents:: In this topic: + :local: + +Downloading the ODBC driver +================================== + +The SQream DB ODBC driver is distributed by your SQream account manager. Before contacting your account manager, verify which platform the ODBC driver will be used on. Go to `SQream Support `_ or contact your SQream account manager to get the driver. + +The driver is provided as an executable installer for Windows, or a compressed tarball for Linux platforms. +After downloading the driver, follow the relevant instructions to install and configure the driver for your platform: + +Install and configure the ODBC driver +======================================= + +Continue based on your platform: + +* :ref:`install_odbc_windows` * :ref:`install_odbc_linux` \ No newline at end of file diff --git a/third_party_tools/client_drivers/odbc/install_configure_odbc_linux.rst b/connecting_to_sqream/client_drivers/odbc/install_configure_odbc_linux.rst similarity index 96% rename from third_party_tools/client_drivers/odbc/install_configure_odbc_linux.rst rename to connecting_to_sqream/client_drivers/odbc/install_configure_odbc_linux.rst index 737768756..61919f161 100644 --- a/third_party_tools/client_drivers/odbc/install_configure_odbc_linux.rst +++ b/connecting_to_sqream/client_drivers/odbc/install_configure_odbc_linux.rst @@ -1,253 +1,253 @@ -.. _install_odbc_linux: - -**************************************** -Install and configure ODBC on Linux -**************************************** - -.. toctree:: - :maxdepth: 1 - :titlesonly: - :hidden: - - -The ODBC driver for Windows is provided as a shared library. - -This tutorial shows how to install and configure ODBC on Linux. - -.. contents:: In this topic: - :local: - :depth: 2 - -Prerequisites -============== - -.. _unixODBC: - -unixODBC ------------- - -The ODBC driver requires a driver manager to manage the DSNs. SQream DB's driver is built for unixODBC. - -Verify unixODBC is installed by running: - -.. code-block:: console - - $ odbcinst -j - unixODBC 2.3.4 - DRIVERS............: /etc/odbcinst.ini - SYSTEM DATA SOURCES: /etc/odbc.ini - FILE DATA SOURCES..: /etc/ODBCDataSources - USER DATA SOURCES..: /home/rhendricks/.odbc.ini - SQLULEN Size.......: 8 - SQLLEN Size........: 8 - SQLSETPOSIROW Size.: 8 - -Take note of the location of ``.odbc.ini`` and ``.odbcinst.ini``. In this case, ``/etc``. If ``odbcinst`` is not installed, follow the instructions for your platform below: - -.. contents:: Install unixODBC on: - :local: - :depth: 1 - -Install unixODBC on RHEL 7 / CentOS 7 -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. code-block:: console - - $ yum install -y unixODBC unixODBC-devel - -Install unixODBC on Ubuntu -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. code-block:: console - - $ sudo apt-get install unixodbc unixodbc-dev - - -Install the ODBC driver with a script -======================================= - -Use this method if you have never used ODBC on your machine before. If you have existing DSNs, see the manual install process below. - -#. Unpack the tarball - Copy the downloaded file to any directory, and untar it to a new directory: - - .. code-block:: console - - $ mkdir -p sqream_odbc64 - $ tar xf sqream_2019.2.1_odbc_3.0.0_x86_64_linux.tar.gz -C sqream_odbc64 - -#. Run the first-time installer. The installer will create an editable DSN. - - .. code-block:: console - - $ cd sqream_odbc64 - ./odbc_install.sh --install - - -#. Edit the DSN created by editing ``/etc/.odbc.ini``. See the parameter explanation in the section :ref:`ODBC DSN Parameters `. - - -Install the ODBC driver manually -======================================= - -Use this method when you have existing ODBC DSNs on your machine. - -#. Unpack the tarball - Copy the file you downloaded to the directory where you want to install it, and untar it: - - .. code-block:: console - - $ tar xf sqream_2019.2.1_odbc_3.0.0_x86_64_linux.tar.gz -C sqream_odbc64 - - Take note of the directory where the driver was unpacked. For example, ``/home/rhendricks/sqream_odbc64`` - -#. Locate the ``.odbc.ini`` and ``.odbcinst.ini`` files, using ``odbcinst -j``. - - #. In ``.odbcinst.ini``, add the following lines to register the driver (change the highlighted paths to match your specific driver): - - .. code-block:: ini - :emphasize-lines: 6,7 - - [ODBC Drivers] - SqreamODBCDriver=Installed - - [SqreamODBCDriver] - Description=Driver DSII SqreamODBC 64bit - Driver=/home/rhendricks/sqream_odbc64/sqream_odbc64.so - Setup=/home/rhendricks/sqream_odbc64/sqream_odbc64.so - APILevel=1 - ConnectFunctions=YYY - DriverODBCVer=03.80 - SQLLevel=1 - IconvEncoding=UCS-4LE - - #. In ``.odbc.ini``, add the following lines to configure the DSN (change the highlighted parameters to match your installation): - - .. code-block:: ini - :emphasize-lines: 6,7,8,9,10,11,12,13,14 - - [ODBC Data Sources] - MyTest=SqreamODBCDriver - - [MyTest] - Description=64-bit Sqream ODBC - Driver=/home/rhendricks/sqream_odbc64/sqream_odbc64.so - Server="127.0.0.1" - Port="5000" - Database="raviga" - Service="" - User="rhendricks" - Password="Tr0ub4dor&3" - Cluster=false - Ssl=false - - Parameters are in the form of ``parameter = value``. For details about the parameters that can be set for each DSN, see the section :ref:`ODBC DSN Parameters `. - - - #. Create a file called ``.sqream_odbc.ini`` for managing the driver settings and logging. - This file should be created alongside the other files, and add the following lines (change the highlighted parameters to match your installation): - - .. code-block:: ini - :emphasize-lines: 5,7 - - # Note that this default DriverManagerEncoding of UTF-32 is for iODBC. unixODBC uses UTF-16 by default. - # If unixODBC was compiled with -DSQL_WCHART_CONVERT, then UTF-32 is the correct value. - # Execute 'odbc_config --cflags' to determine if you need UTF-32 or UTF-16 on unixODBC - [Driver] - DriverManagerEncoding=UTF-16 - DriverLocale=en-US - ErrorMessagesPath=/home/rhendricks/sqream_odbc64/ErrorMessages - LogLevel=0 - LogNamespace= - LogPath=/tmp/ - ODBCInstLib=libodbcinst.so - - -Install the driver dependencies -================================== - -Add the ODBC driver path to ``LD_LIBRARY_PATH``: - -.. code-block:: console - - $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/rhendricks/sqream_odbc64/lib - -You can also add this previous command line to your ``~/.bashrc`` file in order to keep this installation working between reboots without re-entering the command manually - -Testing the connection -======================== - -Test the driver using ``isql``. - -If the DSN created is called ``MyTest`` as the example, run isql in this format: - -.. code-block:: console - - $ isql MyTest - - -.. _dsn_params: - -ODBC DSN Parameters -======================= - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Item - - Default - - Description - * - Data Source Name - - None - - An easily recognizable name that you'll use to reference this DSN. - * - Description - - None - - A description of this DSN for your convenience. This field can be left blank - * - User - - None - - Username of a role to use for connection. For example, ``User="rhendricks"`` - * - Password - - None - - Specifies the password of the selected role. For example, ``User="Tr0ub4dor&3"`` - * - Database - - None - - Specifies the database name to connect to. For example, ``Database="master"`` - * - Service - - ``sqream`` - - Specifices :ref:`service queue` to use. For example, ``Service="etl"``. Leave blank (``Service=""``) for default service ``sqream``. - * - Server - - None - - Hostname of the SQream DB worker. For example, ``Server="127.0.0.1"`` or ``Server="sqream.mynetwork.co"`` - * - Port - - None - - TCP port of the SQream DB worker. For example, ``Port="5000"`` or ``Port="3108"`` for the load balancer - * - Cluster - - ``false`` - - Connect via load balancer (use only if exists, and check port). For example, ``Cluster=true`` - * - Ssl - - ``false`` - - Specifies SSL for this connection. For example, ``Ssl=true`` - * - DriverManagerEncoding - - ``UTF-16`` - - Depending on how unixODBC is installed, you may need to change this to ``UTF-32``. - * - ErrorMessagesPath - - None - - Location where the driver was installed. For example, ``ErrorMessagePath=/home/rhendricks/sqream_odbc64/ErrorMessages``. - * - LogLevel - - 0 - - Set to 0-6 for logging. Use this setting when instructed to by SQream Support. For example, ``LogLevel=1`` - - .. hlist:: - :columns: 3 - - * 0 = Disable tracing - * 1 = Fatal only error tracing - * 2 = Error tracing - * 3 = Warning tracing - * 4 = Info tracing - * 5 = Debug tracing - * 6 = Detailed tracing - - - +.. _install_odbc_linux: + +**************************************** +Install and configure ODBC on Linux +**************************************** + +.. toctree:: + :maxdepth: 1 + :titlesonly: + :hidden: + + +The ODBC driver for Windows is provided as a shared library. + +This tutorial shows how to install and configure ODBC on Linux. + +.. contents:: In this topic: + :local: + :depth: 2 + +Prerequisites +============== + +.. _unixODBC: + +unixODBC +------------ + +The ODBC driver requires a driver manager to manage the DSNs. SQream DB's driver is built for unixODBC. + +Verify unixODBC is installed by running: + +.. code-block:: console + + $ odbcinst -j + unixODBC 2.3.4 + DRIVERS............: /etc/odbcinst.ini + SYSTEM DATA SOURCES: /etc/odbc.ini + FILE DATA SOURCES..: /etc/ODBCDataSources + USER DATA SOURCES..: /home/rhendricks/.odbc.ini + SQLULEN Size.......: 8 + SQLLEN Size........: 8 + SQLSETPOSIROW Size.: 8 + +Take note of the location of ``.odbc.ini`` and ``.odbcinst.ini``. In this case, ``/etc``. If ``odbcinst`` is not installed, follow the instructions for your platform below: + +.. contents:: Install unixODBC on: + :local: + :depth: 1 + +Install unixODBC on RHEL 7 / CentOS 7 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: console + + $ yum install -y unixODBC unixODBC-devel + +Install unixODBC on Ubuntu +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: console + + $ sudo apt-get install unixodbc unixodbc-dev + + +Install the ODBC driver with a script +======================================= + +Use this method if you have never used ODBC on your machine before. If you have existing DSNs, see the manual install process below. + +#. Unpack the tarball + Copy the downloaded file to any directory, and untar it to a new directory: + + .. code-block:: console + + $ mkdir -p sqream_odbc64 + $ tar xf sqream_2019.2.1_odbc_3.0.0_x86_64_linux.tar.gz -C sqream_odbc64 + +#. Run the first-time installer. The installer will create an editable DSN. + + .. code-block:: console + + $ cd sqream_odbc64 + ./odbc_install.sh --install + + +#. Edit the DSN created by editing ``/etc/.odbc.ini``. See the parameter explanation in the section :ref:`ODBC DSN Parameters `. + + +Install the ODBC driver manually +======================================= + +Use this method when you have existing ODBC DSNs on your machine. + +#. Unpack the tarball + Copy the file you downloaded to the directory where you want to install it, and untar it: + + .. code-block:: console + + $ tar xf sqream_2019.2.1_odbc_3.0.0_x86_64_linux.tar.gz -C sqream_odbc64 + + Take note of the directory where the driver was unpacked. For example, ``/home/rhendricks/sqream_odbc64`` + +#. Locate the ``.odbc.ini`` and ``.odbcinst.ini`` files, using ``odbcinst -j``. + + #. In ``.odbcinst.ini``, add the following lines to register the driver (change the highlighted paths to match your specific driver): + + .. code-block:: ini + :emphasize-lines: 6,7 + + [ODBC Drivers] + SqreamODBCDriver=Installed + + [SqreamODBCDriver] + Description=Driver DSII SqreamODBC 64bit + Driver=/home/rhendricks/sqream_odbc64/sqream_odbc64.so + Setup=/home/rhendricks/sqream_odbc64/sqream_odbc64.so + APILevel=1 + ConnectFunctions=YYY + DriverODBCVer=03.80 + SQLLevel=1 + IconvEncoding=UCS-4LE + + #. In ``.odbc.ini``, add the following lines to configure the DSN (change the highlighted parameters to match your installation): + + .. code-block:: ini + :emphasize-lines: 6,7,8,9,10,11,12,13,14 + + [ODBC Data Sources] + MyTest=SqreamODBCDriver + + [MyTest] + Description=64-bit Sqream ODBC + Driver=/home/rhendricks/sqream_odbc64/sqream_odbc64.so + Server="127.0.0.1" + Port="5000" + Database="raviga" + Service="" + User="rhendricks" + Password="Tr0ub4dor&3" + Cluster=false + Ssl=false + + Parameters are in the form of ``parameter = value``. For details about the parameters that can be set for each DSN, see the section :ref:`ODBC DSN Parameters `. + + + #. Create a file called ``.sqream_odbc.ini`` for managing the driver settings and logging. + This file should be created alongside the other files, and add the following lines (change the highlighted parameters to match your installation): + + .. code-block:: ini + :emphasize-lines: 5,7 + + # Note that this default DriverManagerEncoding of UTF-32 is for iODBC. unixODBC uses UTF-16 by default. + # If unixODBC was compiled with -DSQL_WCHART_CONVERT, then UTF-32 is the correct value. + # Execute 'odbc_config --cflags' to determine if you need UTF-32 or UTF-16 on unixODBC + [Driver] + DriverManagerEncoding=UTF-16 + DriverLocale=en-US + ErrorMessagesPath=/home/rhendricks/sqream_odbc64/ErrorMessages + LogLevel=0 + LogNamespace= + LogPath=/tmp/ + ODBCInstLib=libodbcinst.so + + +Install the driver dependencies +================================== + +Add the ODBC driver path to ``LD_LIBRARY_PATH``: + +.. code-block:: console + + $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/rhendricks/sqream_odbc64/lib + +You can also add this previous command line to your ``~/.bashrc`` file in order to keep this installation working between reboots without re-entering the command manually + +Testing the connection +======================== + +Test the driver using ``isql``. + +If the DSN created is called ``MyTest`` as the example, run isql in this format: + +.. code-block:: console + + $ isql MyTest + + +.. _dsn_params: + +ODBC DSN Parameters +======================= + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Item + - Default + - Description + * - Data Source Name + - None + - An easily recognizable name that you'll use to reference this DSN. + * - Description + - None + - A description of this DSN for your convenience. This field can be left blank + * - User + - None + - Username of a role to use for connection. For example, ``User="rhendricks"`` + * - Password + - None + - Specifies the password of the selected role. For example, ``User="Tr0ub4dor&3"`` + * - Database + - None + - Specifies the database name to connect to. For example, ``Database="master"`` + * - Service + - ``sqream`` + - Specifices :ref:`service queue` to use. For example, ``Service="etl"``. Leave blank (``Service=""``) for default service ``sqream``. + * - Server + - None + - Hostname of the SQream DB worker. For example, ``Server="127.0.0.1"`` or ``Server="sqream.mynetwork.co"`` + * - Port + - None + - TCP port of the SQream DB worker. For example, ``Port="5000"`` or ``Port="3108"`` for the load balancer + * - Cluster + - ``false`` + - Connect via load balancer (use only if exists, and check port). For example, ``Cluster=true`` + * - Ssl + - ``false`` + - Specifies SSL for this connection. For example, ``Ssl=true`` + * - DriverManagerEncoding + - ``UTF-16`` + - Depending on how unixODBC is installed, you may need to change this to ``UTF-32``. + * - ErrorMessagesPath + - None + - Location where the driver was installed. For example, ``ErrorMessagePath=/home/rhendricks/sqream_odbc64/ErrorMessages``. + * - LogLevel + - 0 + - Set to 0-6 for logging. Use this setting when instructed to by SQream Support. For example, ``LogLevel=1`` + + .. hlist:: + :columns: 3 + + * 0 = Disable tracing + * 1 = Fatal only error tracing + * 2 = Error tracing + * 3 = Warning tracing + * 4 = Info tracing + * 5 = Debug tracing + * 6 = Detailed tracing + + + diff --git a/third_party_tools/client_drivers/odbc/install_configure_odbc_windows.rst b/connecting_to_sqream/client_drivers/odbc/install_configure_odbc_windows.rst similarity index 97% rename from third_party_tools/client_drivers/odbc/install_configure_odbc_windows.rst rename to connecting_to_sqream/client_drivers/odbc/install_configure_odbc_windows.rst index 7749b44ab..4972e3057 100644 --- a/third_party_tools/client_drivers/odbc/install_configure_odbc_windows.rst +++ b/connecting_to_sqream/client_drivers/odbc/install_configure_odbc_windows.rst @@ -1,134 +1,134 @@ -.. _install_odbc_windows: - -**************************************** -Install and Configure ODBC on Windows -**************************************** - -The ODBC driver for Windows is provided as a self-contained installer. - -This tutorial shows you how to install and configure ODBC on Windows. - -.. contents:: In this topic: - :local: - :depth: 2 - -Installing the ODBC Driver -================================== - -Prerequisites ----------------- - -.. _vcredist: - -Visual Studio 2015 Redistributables -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -To install the ODBC driver you must first install Microsoft's **Visual C++ Redistributable for Visual Studio 2015**. To install Visual C++ Redistributable for Visual Studio 2015, see the `Install Instructions `_. - -Administrator Privileges -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The SQream DB ODBC driver requires administrator privileges on your computer to add the DSNs (data source names). - - -1. Run the Windows installer ------------------------------- - -Install the driver by following the on-screen instructions in the easy-to-follow installer. - -.. image:: /_static/images/odbc_windows_installer_screen1.png - -.. note:: The installer will install the driver in ``C:\Program Files\SQream Technologies\ODBC Driver`` by default. This path is changable during the installation. - -2. Selecting Components -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The installer includes additional components, like JDBC and Tableau customizations. - -.. image:: /_static/images/odbc_windows_installer_screen2.png - -You can deselect items you don't want to install, but the items named **ODBC Driver DLL** and **ODBC Driver Registry Keys** must remain selected for a complete installation of the ODBC driver. - -Once the installer finishes, you will be ready to configure the DSN for connection. - -.. _create_windows_odbc_dsn: - -3. Configuring the ODBC Driver DSN -====================================== - -ODBC driver configurations are done via DSNs. Each DSN represents one SQream DB database. - -#. Open up the Windows menu by clicking the Windows button on your keyboard (:kbd:`⊞ Win`) or pressing the Windows button with your mouse. - -#. Type **ODBC** and select **ODBC Data Sources (64-bit)**. Click the item to open up the setup window. - - .. image:: /_static/images/odbc_windows_startmenu.png - -#. The installer has created a sample User DSN named **SQreamDB** - - You can modify this DSN, or create a new one (:menuselection:`Add --> SQream ODBC Driver --> Next`) - - .. image:: /_static/images/odbc_windows_dsns.png - -#. Enter your connection parameters. See the reference below for a description of the parameters. - - .. image:: /_static/images/odbc_windows_dsn_config.png - -#. When completed, save the DSN by selecting :menuselection:`OK` - -.. tip:: Test the connection by clicking :menuselection:`Test` before saving. A successful test looks like this: - - .. image:: /_static/images/odbc_windows_dsn_test.png - -#. You can now use this DSN in ODBC applications like :ref:`Tableau `. - - - -Connection Parameters ------------------------ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Item - - Description - * - Data Source Name - - An easily recognizable name that you'll use to reference this DSN. Once you set this, it can not be changed. - * - Description - - A description of this DSN for your convenience. You can leave this blank. - * - User - - Username of a role to use for connection. For example, ``rhendricks`` - * - Password - - Specifies the password of the selected role. For example, ``Tr0ub4dor&3`` - * - Database - - Specifies the database name to connect to. For example, ``master`` - * - Service - - Specifices :ref:`service queue` to use. For example, ``etl``. Leave blank for default service ``sqream``. - * - Server - - Hostname of the SQream DB worker. For example, ``127.0.0.1`` or ``sqream.mynetwork.co`` - * - Port - - TCP port of the SQream DB worker. For example, ``5000`` or ``3108`` - * - User server picker - - Connect via load balancer (use only if exists, and check port) - * - SSL - - Specifies SSL for this connection - * - Logging options - - Use this screen to alter logging options when tracing the ODBC connection for possible connection issues. - - -Troubleshooting -================== - -Solving "Code 126" ODBC errors ---------------------------------- - -After installing the ODBC driver, you may experience the following error: - -.. code-block:: none - - The setup routines for the SQreamDriver64 ODBC driver could not be loaded due to system error - code 126: The specified module could not be found. - (c:\Program Files\SQream Technologies\ODBC Driver\sqreamOdbc64.dll) - -This is an issue with the Visual Studio Redistributable packages. Verify you've correctly installed them, as described in the :ref:`Visual Studio 2015 Redistributables ` section above. +.. _install_odbc_windows: + +**************************************** +Install and Configure ODBC on Windows +**************************************** + +The ODBC driver for Windows is provided as a self-contained installer. + +This tutorial shows you how to install and configure ODBC on Windows. + +.. contents:: In this topic: + :local: + :depth: 2 + +Installing the ODBC Driver +================================== + +Prerequisites +---------------- + +.. _vcredist: + +Visual Studio 2015 Redistributables +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To install the ODBC driver you must first install Microsoft's **Visual C++ Redistributable for Visual Studio 2015**. To install Visual C++ Redistributable for Visual Studio 2015, see the `Install Instructions `_. + +Administrator Privileges +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The SQream DB ODBC driver requires administrator privileges on your computer to add the DSNs (data source names). + + +1. Run the Windows installer +------------------------------ + +Install the driver by following the on-screen instructions in the easy-to-follow installer. + +.. image:: /_static/images/odbc_windows_installer_screen1.png + +.. note:: The installer will install the driver in ``C:\Program Files\SQream Technologies\ODBC Driver`` by default. This path is changable during the installation. + +2. Selecting Components +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The installer includes additional components, like JDBC and Tableau customizations. + +.. image:: /_static/images/odbc_windows_installer_screen2.png + +You can deselect items you don't want to install, but the items named **ODBC Driver DLL** and **ODBC Driver Registry Keys** must remain selected for a complete installation of the ODBC driver. + +Once the installer finishes, you will be ready to configure the DSN for connection. + +.. _create_windows_odbc_dsn: + +3. Configuring the ODBC Driver DSN +====================================== + +ODBC driver configurations are done via DSNs. Each DSN represents one SQream DB database. + +#. Open up the Windows menu by clicking the Windows button on your keyboard (:kbd:`⊞ Win`) or pressing the Windows button with your mouse. + +#. Type **ODBC** and select **ODBC Data Sources (64-bit)**. Click the item to open up the setup window. + + .. image:: /_static/images/odbc_windows_startmenu.png + +#. The installer has created a sample User DSN named **SQreamDB** + + You can modify this DSN, or create a new one (:menuselection:`Add --> SQream ODBC Driver --> Next`) + + .. image:: /_static/images/odbc_windows_dsns.png + +#. Enter your connection parameters. See the reference below for a description of the parameters. + + .. image:: /_static/images/odbc_windows_dsn_config.png + +#. When completed, save the DSN by selecting :menuselection:`OK` + +.. tip:: Test the connection by clicking :menuselection:`Test` before saving. A successful test looks like this: + + .. image:: /_static/images/odbc_windows_dsn_test.png + +#. You can now use this DSN in ODBC applications like :ref:`Tableau `. + + + +Connection Parameters +----------------------- + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Item + - Description + * - Data Source Name + - An easily recognizable name that you'll use to reference this DSN. Once you set this, it can not be changed. + * - Description + - A description of this DSN for your convenience. You can leave this blank. + * - User + - Username of a role to use for connection. For example, ``rhendricks`` + * - Password + - Specifies the password of the selected role. For example, ``Tr0ub4dor&3`` + * - Database + - Specifies the database name to connect to. For example, ``master`` + * - Service + - Specifices :ref:`service queue` to use. For example, ``etl``. Leave blank for default service ``sqream``. + * - Server + - Hostname of the SQream DB worker. For example, ``127.0.0.1`` or ``sqream.mynetwork.co`` + * - Port + - TCP port of the SQream DB worker. For example, ``5000`` or ``3108`` + * - User server picker + - Connect via load balancer (use only if exists, and check port) + * - SSL + - Specifies SSL for this connection + * - Logging options + - Use this screen to alter logging options when tracing the ODBC connection for possible connection issues. + + +Troubleshooting +================== + +Solving "Code 126" ODBC errors +--------------------------------- + +After installing the ODBC driver, you may experience the following error: + +.. code-block:: none + + The setup routines for the SQreamDriver64 ODBC driver could not be loaded due to system error + code 126: The specified module could not be found. + (c:\Program Files\SQream Technologies\ODBC Driver\sqreamOdbc64.dll) + +This is an issue with the Visual Studio Redistributable packages. Verify you've correctly installed them, as described in the :ref:`Visual Studio 2015 Redistributables ` section above. diff --git a/third_party_tools/connectivity_ecosystem.jpg b/connecting_to_sqream/connectivity_ecosystem.jpg similarity index 100% rename from third_party_tools/connectivity_ecosystem.jpg rename to connecting_to_sqream/connectivity_ecosystem.jpg diff --git a/third_party_tools/index.rst b/connecting_to_sqream/index.rst similarity index 95% rename from third_party_tools/index.rst rename to connecting_to_sqream/index.rst index ee581e337..a790f085d 100644 --- a/third_party_tools/index.rst +++ b/connecting_to_sqream/index.rst @@ -1,17 +1,17 @@ -.. _third_party_tools: - -************************* -Third Party Tools -************************* -SQream supports the most common database tools and interfaces, giving you direct access through a variety of drivers, connectors, and visualiztion tools and utilities. The tools described on this page have been tested and approved for use with SQream. Most third party tools that work through JDBC, ODBC, and Python should work. - -This section provides information about the following third party tools: - -.. toctree:: - :maxdepth: 2 - :glob: - :titlesonly: - - client_drivers/index - +.. _third_party_tools: + +************************* +Connecting to SQream +************************* +SQream supports the most common database tools and interfaces, giving you direct access through a variety of drivers, connectors, and visualiztion tools and utilities. The tools described on this page have been tested and approved for use with SQream. Most third party tools that work through JDBC, ODBC, and Python should work. + +This section provides information about the following third party tools: + +.. toctree:: + :maxdepth: 2 + :glob: + :titlesonly: + + client_drivers/index + If you need a tool that SQream does not support, contact SQream Support or your SQream account manager for more information. \ No newline at end of file diff --git a/index.rst b/index.rst index 72731e378..db8e0fa2a 100644 --- a/index.rst +++ b/index.rst @@ -104,7 +104,7 @@ If you're looking for an older version of the documentation, versions 1.10 throu installation_guides/index data_ingestion/index connecting_to_sqream/index - loading_and_unloading/index + loading_and_unloading_data/index feature_guides/index operational_guides/index sqream_studio_5.4.3/index From 5c18f92de9ad9a0f7427c43a33ff3f0124d40daf Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 10 Jul 2022 17:50:53 +0300 Subject: [PATCH 107/316] Corrected links. --- loading_and_unloading_data/index.rst | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/loading_and_unloading_data/index.rst b/loading_and_unloading_data/index.rst index ae5c506bb..bc515f023 100644 --- a/loading_and_unloading_data/index.rst +++ b/loading_and_unloading_data/index.rst @@ -5,32 +5,32 @@ Loading and Unloading Data *********************** The **Loading Data** section describes concepts and operations related to importing data into your SQream database: -* `Overview of loading data `_ - Describes best practices and considerations for loading data into SQream from a variety of sources and locations. +* `Overview of loading data `_ - Describes best practices and considerations for loading data into SQream from a variety of sources and locations. -* `Alternatives to loading data (foreign tables) `_ - Useful for running queries directly on external data without importing into your SQream database. +* `Alternatives to loading data (foreign tables) `_ - Useful for running queries directly on external data without importing into your SQream database. -* `Supported data types `_ - Overview of supported data types, including descriptions, examples, and relevant aliases. +* `Supported data types `_ - Overview of supported data types, including descriptions, examples, and relevant aliases. -* `Ingesting data from external sources `_ - List of data ingestion sources that SQream supports. +* `Ingesting data from external sources `_ - List of data ingestion sources that SQream supports. -* `Inserting data from external tables `_ - Inserts one or more rows into a table. +* `Inserting data from external tables `_ - Inserts one or more rows into a table. -* `Ingesting data from third party client platforms `_ - Gives you direct access to a variety of drivers, connectors, tools, vizualisers, and utilities.. +* `Ingesting data from third party client platforms `_ - Gives you direct access to a variety of drivers, connectors, tools, vizualisers, and utilities.. -* `Using the COPY FROM statement `_ - Used for loading data from files located on a filesystem into SQream tables. +* `Using the COPY FROM statement `_ - Used for loading data from files located on a filesystem into SQream tables. -* `Importing data using Studio `_ - SQream's web-based client providing users with all functionality available from the command line in an intuitive and easy-to-use format. +* `Importing data using Studio `_ - SQream's web-based client providing users with all functionality available from the command line in an intuitive and easy-to-use format. -* `Loading data using Amazon S3 `_ - Used for loading data from Amazon S3. +* `Loading data using Amazon S3 `_ - Used for loading data from Amazon S3. * Troubleshooting - Describes troubleshooting solutions related to importing data from the following: - * `SAS Viya `_ + * `SAS Viya `_ - * `Tableau `_ + * `Tableau `_ The **Unloading Data** section describes concepts and operations related to exporting data from your SQream database: -* `Overview of unloading data `_ - Describes best practices and considerations for unloading data from SQream to a variety of sources and locations. +* `Overview of unloading data `_ - Describes best practices and considerations for unloading data from SQream to a variety of sources and locations. -* `The COPY TO statement `_ - Used for unloading data from a SQream database table or query to a file on a filesystem. \ No newline at end of file +* `The COPY TO statement `_ - Used for unloading data from a SQream database table or query to a file on a filesystem. \ No newline at end of file From 97c150d3d44aaadc2f7585f52887673b0b6dced8 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 10 Jul 2022 18:54:57 +0300 Subject: [PATCH 108/316] Update inserting_data.rst --- data_ingestion/inserting_data.rst | 196 ++++++++++++++++-------------- 1 file changed, 103 insertions(+), 93 deletions(-) diff --git a/data_ingestion/inserting_data.rst b/data_ingestion/inserting_data.rst index 42ac36ceb..e20e37920 100644 --- a/data_ingestion/inserting_data.rst +++ b/data_ingestion/inserting_data.rst @@ -3,138 +3,161 @@ *************************** Inserting Data Overview *************************** +The **Inserting Data Overview** page provides basic information useful when ingesting data into SQream from a variety of sources and locations, and describes the following: -The **Inserting Data Overview** page describes how to insert data into SQream, specifically how to insert data from a variety of sources and locations. - -.. contents:: In this topic: +.. contents:: :local: - - + :depth: 1 + Getting Started ================================ +SQream supports ingesting data using the following methods: -SQream supports importing data from the following sources: +* Executing the ``INSERT`` statement using a client driver. -* Using :ref:`insert` with :ref:`a client driver` -* Using :ref:`copy_from`: + :: + +* Executing the ``COPY FROM`` statement or ingesting data from foreign tables: - - Local filesystem and locally mounted network filesystems - - :ref:`s3` - - :ref:`hdfs` + * Local filesystem and locally mounted network filesystems + * Inserting Data using the Amazon S3 object storage service + * Inserting Data using an HDFS data storage system -* Using :ref:`external_tables`: +SQream supports loading files from the following formats: - - Local filesystem and locally mounted network filesystems - - :ref:`s3` - - :ref:`hdfs` +* Text - CSV, TSV, and PSV +* Parquet +* ORC +For more information, see the following: -SQream DB supports loading files in the following formats: +* Using the ``INSERT`` statement - :ref:`insert` -* Text - CSV, TSV, PSV -* Parquet -* ORC +* Using client drivers - :ref:`Client drivers` + +* Using the ``COPY FROM`` statement - :ref:`copy_from` + +* Using the Amazon S3 object storage service - :ref:`s3` + +* Using the HDFS data storage system - :ref:`hdfs` + +* Loading data from foreign tables - :ref:`foreign_tables` Data Loading Considerations ================================ +The **Data Loading Considerations** section describes the following: +.. contents:: + :local: + :depth: 1 + Verifying Data and Performance after Loading ----------------------------------------- +Like many RDBMSs, SQream recommends its own set of best practices for table design and query optimization. When using SQream, verify the following: -Like other RDBMSs, SQream DB has its own set of best practcies for table design and query optimization. - -SQream therefore recommends: +* That your data is structured as you expect (row counts, data types, formatting, content). -* Verify that the data is as you expect it (e.g. row counts, data types, formatting, content) +* That your query performance is adequate. -* The performance of your queries is adequate +* That you followed the table design best practices (:ref:`Optimization and Best Practices`). -* :ref:`Best practices` were followed for table design +* That you've tested and verified that your applications work (such as :ref:`Tableau`). -* Applications such as :ref:`Tableau` and others have been tested, and work +* That your data types have not been not over-provisioned. File Soure Location when Loading -------------------------------- +While you are loading data, you can use the ``COPY FROM`` command to let statements run on any worker. If you are running multiple nodes, verify that all nodes can see the source the same. Loading data from a local file that is only on one node and not on shared storage may cause it to fail. If required, you can also control which node a statement runs on using the Workload Manager). -During loading using :ref:`copy_from`, the statement can run on any worker. If you are running multiple nodes, make sure that all nodes can see the source the same. If you load from a local file which is only on 1 node and not on shared storage, it will fail some of the time. (If you need to, you can also control which node a statement runs on using the :ref:`workload_manager`). +For more information, see the following: -Supported load methods +* :ref:`copy_from` + +* :ref:`workload_manager` + +Supported Load Methods ------------------------------- +You can use the ``COPY FROM`` syntax to load CSV files. -SQream DB's :ref:`COPY FROM` syntax can be used to load CSV files, but can't be used for Parquet and ORC. +.. note:: The ``COPY FROM`` cannot be used for loading data from Parquet and ORC files. -:ref:`FOREIGN TABLE` can be used to load text files, Parquet, and ORC files, and can also transform the data prior to materialization as a full table. +You can use foreign tables to load text files, Parquet, and ORC files, and to transform your data before generating a full table, as described in the following table: .. list-table:: :widths: auto :header-rows: 1 :stub-columns: 1 - * - Method / File type + * - Method/File Type - Text (CSV) - Parquet - ORC - - Streaming data - * - :ref:`copy_from` + - Streaming Data + * - COPY FROM - Supported - Not supported - Not supported - Not supported - * - :ref:`external_tables` + * - Foreign tables - Supported - Supported - Supported - Not supported - * - :ref:`insert` + * - INSERT - Not supported - Not supported - Not supported - Supported (Python, JDBC, Node.JS) + +For more information, see the following: -Unsupported Data Types ------------------------------ +* :ref:`COPY FROM` + +* :ref:`Foreign tables` -SQream DB doesn't support the entire set of features that some other database systems may have, such as ``ARRAY``, ``BLOB``, ``ENUM``, ``SET``, etc. +* :ref:`INSERT` -These data types will have to be converted before load. For example, ``ENUM`` can often be stored as a ``TEXT``. +Unsupported Data Types +----------------------------- +SQream does not support certain features that are supported by other databases, such as ``ARRAY``, ``BLOB``, ``ENUM``, and ``SET``. You must convert these data types before loading them. For example, you can store ``ENUM`` as ``TEXT``. Handing Extended Errors ---------------------------- +While you can use foreign tables to load CSVs, the ``COPY FROM`` statement provides more fine-grained error handling options and extended support for non-standard CSVs with multi-character delimiters, alternate timestamp formats, and more. -While :ref:`external tables` can be used to load CSVs, the ``COPY FROM`` statement provides more fine-grained error handling options, as well as extended support for non-standard CSVs with multi-character delimiters, alternate timestamp formats, and more. +For more information, see :ref:`foreign tables`. Best Practices for CSV ------------------------------ +Text files, such as CSV, rarely conform to `RFC 4180 `_ , so you may need to make the following modifications: -Text files like CSV rarely conform to `RFC 4180 `_ , so alterations may be required: - -* Use ``OFFSET 2`` for files containing header rows +* Use ``OFFSET 2`` for files containing header rows. -* Failed rows can be captured in a log file for later analysis, or just to skip them. See :ref:`capturing_rejected_rows` for information on skipping rejected rows. +* You can capture failed rows in a log file for later analysis, or skip them. See :ref:`capturing_rejected_rows` for information on skipping rejected rows. -* Record delimiters (new lines) can be modified with the :ref:`RECORD DELIMITER` syntax. +* You can modify record delimiters (new lines) using the :ref:`RECORD DELIMITER` syntax. -* If the date formats differ from ISO 8601, refer to the :ref:`copy_date_parsers` section to see how to override default parsing. +* If the date formats deviate from ISO 8601, refer to the :ref:`copy_date_parsers` section for overriding the default parsing. -* - Fields in a CSV can be optionally quoted with double-quotes (``"``). However, any field containing a newline or another double-quote character must be quoted. +* *(Optional)* You can quote fields in a CSV using double-quotes (``"``). - If a field is quoted, any double quote that appears must be double-quoted (similar to the :ref:`string literals quoting rules`. For example, to encode ``What are "birds"?``, the field should appear as ``"What are ""birds""?"``. +.. note:: You must quote any field containing a new line or another double-quote character. -* Field delimiters don't have a to be a displayable ASCII character. See :ref:`field_delimiters` for all options. +* If a field is quoted, you must double quote any double quote, similar to the **string literals quoting rules**. For example, to encode ``What are "birds"?``, the field should appear as ``"What are ""birds""?"``. For more information, see :ref:`string literals quoting rules`. +* Field delimiters do not have to be a displayable ASCII character. For all supported field delimiters, see :ref:`field_delimiters`. Best Practices for Parquet -------------------------------- +The following list shows the best practices when inserting data from Parquet files: -* Parquet files are loaded through :ref:`external_tables`. The destination table structure has to match in number of columns between the source files. +* You must load Parquet files through :ref:`foreign_tables`. Note that the destination table structure must be identical to the number of columns between the source files. -* Parquet files support predicate pushdown. When a query is issued over Parquet files, SQream DB uses row-group metadata to determine which row-groups in a file need to be read for a particular query and the row indexes can narrow the search to a particular set of rows. +* Parquet files support **predicate pushdown**. When a query is issued over Parquet files, SQream uses row-group metadata to determine which row-groups in a file must be read for a particular query and the row indexes can narrow the search to a particular set of rows. -Type Support and Behavior Notes +Supported Types and Behavior Notes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -* Unlike ORC, the column types should match the data types exactly (see table below). +Unlike the ORC format, the column types should match the data types exactly, as shown in the table below: .. list-table:: :widths: auto @@ -155,7 +178,7 @@ Type Support and Behavior Notes - ``DATE`` - ``DATETIME`` * - ``BOOLEAN`` - - ✓ + - Supported - - - @@ -168,7 +191,7 @@ Type Support and Behavior Notes * - ``INT16`` - - - - ✓ + - Supported - - - @@ -180,7 +203,7 @@ Type Support and Behavior Notes - - - - - ✓ + - Supported - - - @@ -192,7 +215,7 @@ Type Support and Behavior Notes - - - - - ✓ + - Supported - - - @@ -204,7 +227,7 @@ Type Support and Behavior Notes - - - - - ✓ + - Supported - - - @@ -216,7 +239,7 @@ Type Support and Behavior Notes - - - - - ✓ + - Supported - - - @@ -228,7 +251,7 @@ Type Support and Behavior Notes - - - - - ✓ + - Supported - - * - ``INT96`` [#f3]_ @@ -241,31 +264,34 @@ Type Support and Behavior Notes - - - - - ✓ [#f4]_ + - Supported [#f4]_ -* If a Parquet file has an unsupported type like ``enum``, ``uuid``, ``time``, ``json``, ``bson``, ``lists``, ``maps``, but the data is not referenced in the table (it does not appear in the :ref:`SELECT` query), the statement will succeed. If the column is referenced, an error will be thrown to the user, explaining that the type is not supported, but the column may be ommited. +If a Parquet file has an unsupported type, such as ``enum``, ``uuid``, ``time``, ``json``, ``bson``, ``lists``, ``maps``, but the table does not reference this data (i.e., the data does not appear in the :ref:`SELECT` query), the statement will succeed. If the table **does** reference a column, an error will be displayed explaining that the type is not supported, but the column may be omitted. Best Practices for ORC -------------------------------- +The following list shows the best practices when inserting data from ORC files: -* ORC files are loaded through :ref:`external_tables`. The destination table structure has to match in number of columns between the source files. +* You must load ORC files through :ref:`foreign_tables`. Note that the destination table structure must be identical to the number of columns between the source files. -* ORC files support predicate pushdown. When a query is issued over ORC files, SQream DB uses ORC metadata to determine which stripes in a file need to be read for a particular query and the row indexes can narrow the search to a particular set of 10,000 rows. +* ORC files support **predicate pushdown**. When a query is issued over ORC files, SQream uses ORC metadata to determine which stripes in a file need to be read for a particular query and the row indexes can narrow the search to a particular set of 10,000 rows. Type Support and Behavior Notes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +You must load ORC files through foreign table. Note that the destination table structure must be identical to the number of columns between the source files. -* ORC files are loaded through :ref:`external_tables`. The destination table structure has to match in number of columns between the source files. +For more information, see :ref:`foreign_tables`. -* The types should match to some extent within the same "class" (see table below). +The types should match to some extent within the same "class", as shown in the following table: .. list-table:: - :widths: 5 5 70 70 70 70 5 5 5 5 5 + :widths: auto :header-rows: 1 + :stub-columns: 1 - * - SQream DB type → + * - SQream DB Type → - ORC source + ORC Source - ``BOOL`` - ``TINYINT`` - ``SMALLINT`` @@ -273,7 +299,7 @@ Type Support and Behavior Notes - ``BIGINT`` - ``REAL`` - ``DOUBLE`` - - ``Text`` [#f0]_ + - Text [#f0]_ - ``DATE`` - ``DATETIME`` * - ``boolean`` @@ -353,7 +379,7 @@ Type Support and Behavior Notes - - - - * - ``string`` / ``char`` / ``text`` + * - ``string`` / ``char`` / ``varchar`` - - - @@ -432,31 +458,15 @@ Type Support and Behavior Notes Further Reading and Migration Guides ======================================= - -.. toctree:: - :caption: Data loading guides - :titlesonly: - - migration/csv - migration/parquet - migration/orc - -.. toctree:: - :caption: Migration guides - :titlesonly: - - migration/oracle - - -.. rubric:: See also: +For more information, see the following: * :ref:`copy_from` * :ref:`insert` -* :ref:`external_tables` +* :ref:`foreign_tables` .. rubric:: Footnotes -.. [#f0] Text values include ``TEXT`` +.. [#f0] Text values include ``TEXT``, ``VARCHAR``, and ``NVARCHAR`` .. [#f2] With UTF8 annotation @@ -468,4 +478,4 @@ Further Reading and Migration Guides .. [#f6] Will succeed if all values are 0, 1 -.. [#f7] Will succeed if all values fit the destination type +.. [#f7] Will succeed if all values fit the destination type \ No newline at end of file From 00aeb5eed444ba49cdeea40ce957d88c05abc4e9 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 12 Jul 2022 18:21:00 +0300 Subject: [PATCH 109/316] SQ-10818 --- reference/sql/sql_statements/index.rst | 8 +- .../get_role_database_ddl.rst | 61 +++++++++++++++ .../utility_commands/get_role_global_ddl.rst | 61 +++++++++++++++ .../utility_commands/get_role_permissions.rst | 74 +++++++++++++++++++ 4 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 reference/sql/sql_statements/utility_commands/get_role_database_ddl.rst create mode 100644 reference/sql/sql_statements/utility_commands/get_role_global_ddl.rst create mode 100644 reference/sql/sql_statements/utility_commands/get_role_permissions.rst diff --git a/reference/sql/sql_statements/index.rst b/reference/sql/sql_statements/index.rst index e3ebf5aae..1a075f69e 100644 --- a/reference/sql/sql_statements/index.rst +++ b/reference/sql/sql_statements/index.rst @@ -168,7 +168,7 @@ The following table shows the Access Control commands: .. list-table:: :widths: 10 100 - :header-rows: 1 + :header-rows: 1 * - Command - Usage @@ -180,6 +180,12 @@ The following table shows the Access Control commands: - Creates a roles, which lets a database administrator control permissions on tables and databases * - :ref:`drop_role` - Removes roles + * - :ref:`get_role_permissions` + - Returns all permissions granted to a role in table format + * - :ref:`get_role_global_ddl` + - Returns the definition of a global role in DDL format + * - :ref:`get_role_database_ddl` + - Returns the definition of a database role in DDL format * - :ref:`get_statement_permissions` - Returns a list of permissions required to run a statement or query * - :ref:`grant` diff --git a/reference/sql/sql_statements/utility_commands/get_role_database_ddl.rst b/reference/sql/sql_statements/utility_commands/get_role_database_ddl.rst new file mode 100644 index 000000000..e6b806244 --- /dev/null +++ b/reference/sql/sql_statements/utility_commands/get_role_database_ddl.rst @@ -0,0 +1,61 @@ +.. _get_role_database_ddl: + +******************** +GET_ROLE_DATABASE_DDL +******************** +The ``GET_ROLE_DATABASE_DDL`` statement returns the definition of a global role in DDL format. + +The ``GET_ROLE_DATABASE_DDL`` page describes the following: + +.. contents:: + :local: + :depth: 1 + +Syntax +========== +The following is the correct syntax for using the ``GET_ROLE_DATABASE_DDL`` statement: + +.. code-block:: postgres + + select get_role_database_ddl(<'role_name'>) + +Example +=========== +The following is an example of using the ``GET_ROLE_GLOBAL_DDL`` statement: + +.. code-block:: psql + + select get_role_global_ddl('public'); + +Parameters +============ +The following table shows the ``GET_ROLE_DATABASE_DDL`` parameters: + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``role_name`` + - The definition of the database role in DDL format. + +Output +========== +The following is an example of the output of the ``GET_ROLE_DATABASE_DDL`` statement: + +.. code-block:: postgres + + grant create, usage on schema "public" to "public" ; alter default schema for "public" to "public"; alter default permissions for "public" for schemas grant superuser to creator_role ; alter default permissions for "public" for tables grant select, insert, delete, ddl to creator_role ; + +Permissions +============= +Using the ``GET_ROLE_DATABASE_DDL`` statement requires no special permissions. + +For more information, see the following: + +* :ref:`get_role_global_ddl` + + :: + +* :ref:`get_role_permissions` \ No newline at end of file diff --git a/reference/sql/sql_statements/utility_commands/get_role_global_ddl.rst b/reference/sql/sql_statements/utility_commands/get_role_global_ddl.rst new file mode 100644 index 000000000..3ba0255d3 --- /dev/null +++ b/reference/sql/sql_statements/utility_commands/get_role_global_ddl.rst @@ -0,0 +1,61 @@ +.. _get_role_global_ddl: + +******************** +GET_ROLE_GLOBAL_DDL +******************** +The ``GET_ROLE_GLOBAL_DDL`` statement returns the definition of a global role in DDL format. + +The ``GET_ROLE_GLOBAL_DDL`` page describes the following: + +.. contents:: + :local: + :depth: 1 + +Syntax +========== +The following is the correct syntax for using the ``GET_ROLE_GLOBAL_DDL`` statement: + +.. code-block:: postgres + + select get_role_global_ddl(<'role_name'>) + +Example +=========== +The following is an example of using the ``GET_ROLE_GLOBAL_DDL`` statement: + +.. code-block:: psql + + select get_role_global_ddl('public'); + +Parameters +============ +The following table shows the ``GET_ROLE_GLOBAL_DDL`` parameters: + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``role_name`` + - The definition of the global role in DDL format. + +Output +========== +The following is an example of the output of the ``GET_ROLE_GLOBAL_DDL`` statement: + +.. code-block:: postgres + + create role "public"; + +Permissions +============= +Using the ``GET_ROLE_GLOBAL_DDL`` statement requires no special permissions. + +For more information, see the following: + +* :ref:`get_role_database_ddl` + + :: + +* :ref:`get_role_permissions` \ No newline at end of file diff --git a/reference/sql/sql_statements/utility_commands/get_role_permissions.rst b/reference/sql/sql_statements/utility_commands/get_role_permissions.rst new file mode 100644 index 000000000..8723f98c8 --- /dev/null +++ b/reference/sql/sql_statements/utility_commands/get_role_permissions.rst @@ -0,0 +1,74 @@ +.. _get_role_permissions: + +******************** +GET_ROLE_PERMISSIONS +******************** +The ``GET_ROLE_PERMISSIONS`` statement returns all permissions granted to a role in table format. + +The ``GET_ROLE_PERMISSIONS`` page describes the following: + +.. contents:: + :local: + :depth: 1 + +Syntax +========== +The following is the correct syntax for using the ``GET_ROLE_PERMISSIONS`` statement: + +.. code-block:: postgres + + select get_role_permissions() + +Example +=========== +The following is an example of using the ``GET_ROLE_PERMISSIONS`` statement: + +.. code-block:: psql + + select get_role_permissions(); + +Parameters +============ +The following table shows the ``GET_ROLE_PERMISSIONS`` parameters: + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + * - ``()`` + - The permissions belonging to the role. + +Output +========== +The following is an example of the output of the ``GET_ROLE_PERMISSIONS`` statement: + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + - Example + * - ``permission_type`` + - The permission type granted to the role. + - SUPERUSER + * - ``object_type`` + - The data object type. + - table + * - ``object_name`` + - The name of the object. + - master.public.nba + +Permissions +============= +Using the ``GET_ROLE_PERMISSIONS`` statement requires no special permissions. + +For more information, see the following: + +* :ref:`get_role_database_ddl` + + :: + +* :ref:`get_role_global_ddl` \ No newline at end of file From 90d7637f7116d0399b99fecfb07d00c662936c7f Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Wed, 13 Jul 2022 08:11:03 +0300 Subject: [PATCH 110/316] Update create_table.rst --- .../sql_statements/ddl_commands/create_table.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/reference/sql/sql_statements/ddl_commands/create_table.rst b/reference/sql/sql_statements/ddl_commands/create_table.rst index 51f46582b..eb25baa8a 100644 --- a/reference/sql/sql_statements/ddl_commands/create_table.rst +++ b/reference/sql/sql_statements/ddl_commands/create_table.rst @@ -74,7 +74,7 @@ Default Value Constraints The ``DEFAULT`` value constraint specifies a value to use if one is not defined in an :ref:`insert` or :ref:`copy_from` statement. -The value may be a literal, which is evaluated at the time the row is created. +The value may either be a literal, **GETDATE()**, or Null, which is evaluated at the time the row is created. .. note:: The ``DEFAULT`` constraint only applies if the column does not have a value specified in the :ref:`insert` or :ref:`copy_from` statement. You can still insert a ``NULL`` into an nullable column by explicitly inserting ``NULL``. For example, ``INSERT INTO cool_animals VALUES (1, 'Gnu', NULL)``. @@ -141,7 +141,7 @@ The following is an example of the syntax used to create a standard table: CREATE TABLE cool_animals ( id INT NOT NULL, - name varchar(30) NOT NULL, + name text(30) NOT NULL, weight FLOAT, is_agressive BOOL ); @@ -155,7 +155,7 @@ The following is an example of the syntax used to create a table with default va CREATE TABLE cool_animals ( id INT NOT NULL, - name varchar(30) NOT NULL, + name text(30) NOT NULL, weight FLOAT, is_agressive BOOL DEFAULT false NOT NULL ); @@ -171,8 +171,8 @@ The following is an example of the syntax used to create a table with an identit CREATE TABLE users ( id BIGINT IDENTITY(0,1) NOT NULL , -- Start with 0, increment by 1 - name VARCHAR(30) NOT NULL, - country VARCHAR(30) DEFAULT 'Unknown' NOT NULL + name TEXT(30) NOT NULL, + country TEXT(30) DEFAULT 'Unknown' NOT NULL ); .. note:: @@ -203,9 +203,9 @@ The following is an example of the syntax used to create a table with a clusteri .. code-block:: postgres CREATE TABLE users ( - name VARCHAR(30) NOT NULL, + name TEXT(30) NOT NULL, start_date datetime not null, - country VARCHAR(30) DEFAULT 'Unknown' NOT NULL + country TEXT(30) DEFAULT 'Unknown' NOT NULL ) CLUSTER BY start_date; For more information on data clustering, see :ref:`data_clustering`. From 012d0e9f4debe6c5f58e70ac04ba64916e36b7e0 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 14 Jul 2022 11:56:35 +0300 Subject: [PATCH 111/316] Update 2021.2.1.rst Added Resolved Issues and Known Issues for minor patches: 2021.2.1.1 and 2021.2.1.23. NOTE: These bugs have NOT YET been filtered for external vs internal, which Eyal W is working on now. This means that I will remove some of these bugs once he's created the filter. THIS IS NOT PUBLISHED. --- releases/2021.2.1.rst | 57 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/releases/2021.2.1.rst b/releases/2021.2.1.rst index f17bdd516..063143529 100644 --- a/releases/2021.2.1.rst +++ b/releases/2021.2.1.rst @@ -45,7 +45,6 @@ For more information, see `Deleting Values that Contain Multi-Table Conditions < For more information, see :ref:`regexp_replace`. - Performance Enhancements ------ The **Performance Enhancements** section is not relevant to Version 2021.2.1. @@ -61,13 +60,65 @@ The following table lists the issues that were resolved in Version 2021.2.1: * - SQ No. - Description * - SQ-8267 - - A method has been provided for including the ``GROUP BY`` and ``DISTINCT COUNT`` statements. - + - A method has been provided for including the ``GROUP BY`` and ``DISTINCT COUNT`` statements. + +The following table lists the issues that were resolved in Version 2021.2.1.1: + +.. list-table:: + :widths: 17 200 + :header-rows: 1 + + * - SQ No. + - Description + * - SQ-9114 + - `cleanup_extents` on empty texts results in a missing file + * - SQ-8849 + - Unclear "Map:at" error for invalid column mapping of Parquet files + +The following table lists the issues that were resolved in Version 2021.2.1.23: + +.. list-table:: + :widths: 17 200 + :header-rows: 1 + + * - SQ No. + - Description + * - SQ-10703 + - it implements a FILTER on delete statements which means that delete statements would not scan the entire metadata but only according to the filter Known Issues ------ The **Known Issues** section is not relevant to 2021.2.1. +The following table lists the issues that were resolved in Version 2021.2.1.1: + +.. list-table:: + :widths: 17 200 + :header-rows: 1 + + * - SQ No. + - Description + * - SQ-9003 + - Insert as Select with Order By - Internal Runtime Error + * - SQ-9121 + - Support cleanup_extents with empty text columns for cloud environment + * - SQ-8954 + - GCP one worker crash when copying a table using 8 workers + * - SQ-5485 + - The compiler has an issue with count being used as an alias and in the select list + * - SQ-7732 + - Fail to read numeric (38,0) from parquet + * - SQ-7800 + - AWS - Creating 4,000,000 chunks in leveldb by a copy operation causes segmentation fault in leveldb + * - SQ-7903 + - Filters and metadata_filters doesn't work well for numeric/float literals without an explicit cast + * - SQ-7931 + - Difference to Postgres when comparing literal float4 and float8 + * - SQ-8274 + - Cast to numeric with default precision doesn't work + +The **Known Issues** section is not relevant to Version 2021.2.1.23. + Naming Convention Modifications ------ The **Naming Convention Modifications** section is not relevant to Version 2021.2.1. From 4e85d0bb5994f907e74d6927ec3bf69f257c5226 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 14 Jul 2022 13:59:38 +0300 Subject: [PATCH 112/316] Made release table on all index pages Improved menu functionality (by adding toctree at bottom of each page to relevant pages) --- releases/2020.1.rst | 9 +++++- releases/2020.2.rst | 7 +++++ releases/2020.3.1.rst | 9 +++++- releases/2020.3.2.1.rst | 9 +++++- releases/2020.3.rst | 7 +++++ releases/2020.3_index.rst | 17 ++++++----- releases/2021.1.1.rst | 9 +++++- releases/2021.1.2.rst | 9 +++++- releases/2021.1.rst | 7 +++++ releases/2021.1_index.rst | 17 ++++++----- releases/2021.2.1.1.rst | 28 ++++++++++++++++++ releases/2021.2.1.23.rst | 26 ++++++++++++++++ releases/2021.2.1.rst | 62 +++++---------------------------------- releases/2021.2.rst | 9 +++++- releases/2021.2_index.rst | 17 +++++++---- releases/2022.1.rst | 9 +++++- releases/2022.1_index.rst | 19 ++++++++++++ releases/index.rst | 39 ++++++++++++------------ 18 files changed, 208 insertions(+), 101 deletions(-) create mode 100644 releases/2021.2.1.1.rst create mode 100644 releases/2021.2.1.23.rst create mode 100644 releases/2022.1_index.rst diff --git a/releases/2020.1.rst b/releases/2020.1.rst index e4928855e..86b619d54 100644 --- a/releases/2020.1.rst +++ b/releases/2020.1.rst @@ -185,4 +185,11 @@ Upgrading to v2020.1 Versions are available for IBM POWER9, RedHat (CentOS) 7, Ubuntu 18.04, and other OSs via Docker. -Contact your account manager to get the latest release of SQream DB. +Contact your account manager to get the latest release of SQream. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2020.1 \ No newline at end of file diff --git a/releases/2020.2.rst b/releases/2020.2.rst index 3dc25b78a..917d80800 100644 --- a/releases/2020.2.rst +++ b/releases/2020.2.rst @@ -113,3 +113,10 @@ Upgrading to Version 2020.2 Versions are available for IBM POWER9, RedHat (CentOS) 7, Ubuntu 18.04, and other OSs via Docker. Contact your account manager to get the latest release of SQream. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2020.2 \ No newline at end of file diff --git a/releases/2020.3.1.rst b/releases/2020.3.1.rst index 0667306d7..b66454c75 100644 --- a/releases/2020.3.1.rst +++ b/releases/2020.3.1.rst @@ -69,4 +69,11 @@ Upgrading to v2020.3.1 Versions are available for IBM POWER9, RedHat (CentOS) 7, Ubuntu 18.04, and other OSs via Docker. -Contact your account manager to get the latest release of SQream DB. \ No newline at end of file +Contact your account manager to get the latest release of SQream. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2020.3.1 \ No newline at end of file diff --git a/releases/2020.3.2.1.rst b/releases/2020.3.2.1.rst index 3c551b636..8fef047f6 100644 --- a/releases/2020.3.2.1.rst +++ b/releases/2020.3.2.1.rst @@ -28,4 +28,11 @@ Upgrading to v2020.3.2.1 Versions are available for IBM POWER9, RedHat (CentOS) 7, Ubuntu 18.04, and other OSs via Docker. -Contact your account manager to get the latest release of SQream DB. \ No newline at end of file +Contact your account manager to get the latest release of SQream. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2020.3.2.1 \ No newline at end of file diff --git a/releases/2020.3.rst b/releases/2020.3.rst index d072b15da..b51a9955d 100644 --- a/releases/2020.3.rst +++ b/releases/2020.3.rst @@ -100,3 +100,10 @@ Upgrading to v2020.3 Versions are available for IBM POWER9, RedHat (CentOS) 7, Ubuntu 18.04, and other OSs via Docker. Contact your account manager to get the latest release of SQream. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2020.3 diff --git a/releases/2020.3_index.rst b/releases/2020.3_index.rst index b13340b52..19bf3bd79 100644 --- a/releases/2020.3_index.rst +++ b/releases/2020.3_index.rst @@ -3,16 +3,19 @@ ************************** Release Notes 2020.3 ************************** -The 2020.3 Release Notes describe the following releases: +SQream releases notes are specific to each version of the application. Select your version from the table below to see the related release notes. -.. contents:: - :local: - :depth: 1 ++---------------------------------+----------------------------------+------------------------------------------------------------------+ +| **Major Release** | **Minor Releases** | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+ +| :ref:`2020.3<2020.3>` | :ref:`2020.3.1<2020.3.1>` | :ref:`2020.3.2.1<2020.3.2.1>` | | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+ .. toctree:: - :maxdepth: 1 + :maxdepth: 2 :glob: + :hidden: - 2020.3.2.1 + 2020.3 2020.3.1 - 2020.3 \ No newline at end of file + 2020.3.2.1 \ No newline at end of file diff --git a/releases/2021.1.1.rst b/releases/2021.1.1.rst index 8e6417a43..992b2f850 100644 --- a/releases/2021.1.1.rst +++ b/releases/2021.1.1.rst @@ -61,4 +61,11 @@ The following list describes the resolved issues: * The Decimal column was not supported when inserting data from Parquet files. This was fixed. * Values in Parquet Numeric columns were not being converted correctly. This was fixed. * Converting ``string`` data type to ``datetime`` was not working correctly. This was fixed. -* Casting ``datetime`` to ``text`` truncated the time. This was fixed. \ No newline at end of file +* Casting ``datetime`` to ``text`` truncated the time. This was fixed. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2021.1.1 \ No newline at end of file diff --git a/releases/2021.1.2.rst b/releases/2021.1.2.rst index 43ce6db7d..448b047df 100644 --- a/releases/2021.1.2.rst +++ b/releases/2021.1.2.rst @@ -58,4 +58,11 @@ The following list describes the resolved issues: * In Parquet files, ``float`` columns could not be mapped to SQream ``double`` columns. This was fixed. * The ``REPLACE`` function only supported constant values as arguments. This was fixed. -* The ``LIKE`` function did not check for incorrect patterns or handle escape characters. This was fixed. \ No newline at end of file +* The ``LIKE`` function did not check for incorrect patterns or handle escape characters. This was fixed. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2021.1.2 \ No newline at end of file diff --git a/releases/2021.1.rst b/releases/2021.1.rst index b2b0dcfd8..15824d5d5 100644 --- a/releases/2021.1.rst +++ b/releases/2021.1.rst @@ -211,3 +211,10 @@ The the list below describes the following known issues and limitations: Upgrading to v2021.1 ------- Due to the known issue of a limitation on the amount of access requests that can be simultaneously sent to AWS, deploying S3 requires setting the ``ObjectStoreClients`` parameter to ``40``. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2021.1 \ No newline at end of file diff --git a/releases/2021.1_index.rst b/releases/2021.1_index.rst index 64b06e1d1..5ba66f511 100644 --- a/releases/2021.1_index.rst +++ b/releases/2021.1_index.rst @@ -3,16 +3,19 @@ ************************** Release Notes 2021.1 ************************** -The 2021.1 Release Notes describe the following releases: +SQream releases notes are specific to each version of the application. Select your version from the table below to see the related release notes. -.. contents:: - :local: - :depth: 1 ++---------------------------------+----------------------------------+------------------------------------------------------------------+ +| **Major Release** | **Minor Releases** | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+ +| :ref:`2021.1<2021.1>` | :ref:`2021.1.1<2021.1.1>` | :ref:`2021.1.2<2021.1.2>` | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+ .. toctree:: - :maxdepth: 1 + :maxdepth: 2 :glob: + :hidden: - 2021.1.2 + 2021.1 2021.1.1 - 2021.1 \ No newline at end of file + 2021.1.2 \ No newline at end of file diff --git a/releases/2021.2.1.1.rst b/releases/2021.2.1.1.rst new file mode 100644 index 000000000..a1137e418 --- /dev/null +++ b/releases/2021.2.1.1.rst @@ -0,0 +1,28 @@ +.. _2021.2.1.1: + +****************************** +Release Notes 2021.2.1.1 +****************************** +The 2021.2.1.1 release notes is a patch version released on 9/12/2021. + +The following table lists the issues that were resolved in Version 2021.2.1.1: + +.. list-table:: + :widths: 17 200 + :header-rows: 1 + + * - SQ No. + - Description + * - SQ-9114 + - `cleanup_extents` on empty texts results in a missing file + * - SQ-8849 + - `Unclear "Map:at" error for invalid column mapping of Parquet files + +Version 2021.2.1.1 has no unresolved issues. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2021.2.1.1 \ No newline at end of file diff --git a/releases/2021.2.1.23.rst b/releases/2021.2.1.23.rst new file mode 100644 index 000000000..ca5e2dcbe --- /dev/null +++ b/releases/2021.2.1.23.rst @@ -0,0 +1,26 @@ +.. _2021.2.1.23: + +****************************** +Release Notes 2021.2.1.23 +****************************** +The 2021.2.1.23 release notes is a patch version released on 27/6/2022. + +The following table lists the issues that were resolved in Version 2021.2.1.23: + +.. list-table:: + :widths: 17 200 + :header-rows: 1 + + * - SQ No. + - Description + * - SQ-10703 + - When the clause is specified, all existing permissions granted on source_table_name are granted on table_name as well. + +Version 2021.2.1.23 has no unresolved issues. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2021.2.1.23 \ No newline at end of file diff --git a/releases/2021.2.1.rst b/releases/2021.2.1.rst index 063143529..3afba3093 100644 --- a/releases/2021.2.1.rst +++ b/releases/2021.2.1.rst @@ -62,63 +62,10 @@ The following table lists the issues that were resolved in Version 2021.2.1: * - SQ-8267 - A method has been provided for including the ``GROUP BY`` and ``DISTINCT COUNT`` statements. -The following table lists the issues that were resolved in Version 2021.2.1.1: - -.. list-table:: - :widths: 17 200 - :header-rows: 1 - - * - SQ No. - - Description - * - SQ-9114 - - `cleanup_extents` on empty texts results in a missing file - * - SQ-8849 - - Unclear "Map:at" error for invalid column mapping of Parquet files - -The following table lists the issues that were resolved in Version 2021.2.1.23: - -.. list-table:: - :widths: 17 200 - :header-rows: 1 - - * - SQ No. - - Description - * - SQ-10703 - - it implements a FILTER on delete statements which means that delete statements would not scan the entire metadata but only according to the filter - Known Issues ------ The **Known Issues** section is not relevant to 2021.2.1. -The following table lists the issues that were resolved in Version 2021.2.1.1: - -.. list-table:: - :widths: 17 200 - :header-rows: 1 - - * - SQ No. - - Description - * - SQ-9003 - - Insert as Select with Order By - Internal Runtime Error - * - SQ-9121 - - Support cleanup_extents with empty text columns for cloud environment - * - SQ-8954 - - GCP one worker crash when copying a table using 8 workers - * - SQ-5485 - - The compiler has an issue with count being used as an alias and in the select list - * - SQ-7732 - - Fail to read numeric (38,0) from parquet - * - SQ-7800 - - AWS - Creating 4,000,000 chunks in leveldb by a copy operation causes segmentation fault in leveldb - * - SQ-7903 - - Filters and metadata_filters doesn't work well for numeric/float literals without an explicit cast - * - SQ-7931 - - Difference to Postgres when comparing literal float4 and float8 - * - SQ-8274 - - Cast to numeric with default precision doesn't work - -The **Known Issues** section is not relevant to Version 2021.2.1.23. - Naming Convention Modifications ------ The **Naming Convention Modifications** section is not relevant to Version 2021.2.1. @@ -129,4 +76,11 @@ The **End of Support** section is not relevant to Version 2021.2.1. Deprecated Features ------ -The **Deprecated Components** section is not relevant to Version 2021.2.1. \ No newline at end of file +The **Deprecated Components** section is not relevant to Version 2021.2.1. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2021.2.1 \ No newline at end of file diff --git a/releases/2021.2.rst b/releases/2021.2.rst index ec4773669..1bd6c6223 100644 --- a/releases/2021.2.rst +++ b/releases/2021.2.rst @@ -169,4 +169,11 @@ Configuring Your Instance of SQream ************ A new configuration method is used starting with Version 2021.2. -For more information about configuring your instance of SQream, see :ref:`configuration`. \ No newline at end of file +For more information about configuring your instance of SQream, see :ref:`configuration`. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2021.2 \ No newline at end of file diff --git a/releases/2021.2_index.rst b/releases/2021.2_index.rst index 77a22b0ae..6e207ee73 100644 --- a/releases/2021.2_index.rst +++ b/releases/2021.2_index.rst @@ -3,15 +3,20 @@ ************************** Release Notes 2021.2 ************************** -The 2021.2 Release Notes describe the following releases: +SQream releases notes are specific to each version of the application. Select your version from the table below to see the related release notes. -.. contents:: - :local: - :depth: 1 ++---------------------------------+---------------------------------+------------------------------------------------------------------+ +| **Major Release** | **Minor Release** | ++---------------------------------+---------------------------------+--------------------------------+---------------------------------+ +| :ref:`2021.2<2021.2>` | :ref:`2021.2.1<2021.2.1>` | :ref:`2021.2.1.1<2021.2.1.1>` | :ref:`2021.2.1.23<2021.2.1.23>` | ++---------------------------------+---------------------------------+--------------------------------+---------------------------------+ .. toctree:: - :maxdepth: 1 + :maxdepth: 2 :glob: + :hidden: + 2021.2 2021.2.1 - 2021.2 \ No newline at end of file + 2021.2.1.1 + 2021.2.1.23 \ No newline at end of file diff --git a/releases/2022.1.rst b/releases/2022.1.rst index ac180206c..52a6722e5 100644 --- a/releases/2022.1.rst +++ b/releases/2022.1.rst @@ -138,4 +138,11 @@ Upgrading to v2022.1 $ ./upgrade_storage - .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in **Step 7** of the Upgrading SQream Version procedure. \ No newline at end of file + .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in **Step 7** of the Upgrading SQream Version procedure. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2022.1 \ No newline at end of file diff --git a/releases/2022.1_index.rst b/releases/2022.1_index.rst new file mode 100644 index 000000000..c40867102 --- /dev/null +++ b/releases/2022.1_index.rst @@ -0,0 +1,19 @@ +.. _2022.1_index: + +************************** +Release Notes 2022.1 +************************** +The 2022.1 Release Notes describe the following releases: + ++---------------------------------+----------------------------------+------------------------------------------------------------------+ +| **Major Release** | **Minor Releases** | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+ +| :ref:`2022.1<2022.1>` | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+ + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2022.1 \ No newline at end of file diff --git a/releases/index.rst b/releases/index.rst index e23036f7a..d68e0b55b 100644 --- a/releases/index.rst +++ b/releases/index.rst @@ -3,27 +3,26 @@ ********** Release Notes ********** +SQream releases notes are specific to each version of the application. Select your version from the table below to see the related release notes. + ++---------------------------------+----------------------------------+------------------------------------------------------------------+ +| **Major Release** | **Minor Releases** | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+ +| :ref:`2022.1<2022.1>` | | | | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+ +| :ref:`2021.2<2021.2>` | :ref:`2021.2.1<2021.2.1>` | :ref:`2021.2.1.1<2021.2.1.1>` | :ref:`2021.2.1.23<2021.2.1.23>` | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+ +| :ref:`2021.1<2021.1>` | :ref:`2021.1.1<2021.1.1>` | :ref:`2021.1.2<2021.1.2>` | | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+ +| :ref:`2020.3<2020.3>` | :ref:`2020.3.1<2020.3.1>` | :ref:`2020.3.2.1<2020.3.2.1>` | | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+ +| :ref:`2020.2<2020.2>` | | | | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+ +| :ref:`2020.1<2020.1>` | | | | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+ -.. list-table:: - :widths: auto - :header-rows: 1 - - - * - Version - - Release Date - * - :ref:`2022.1` - - MM DD, YYYY - * - :ref:`2021.2` - - September 13, 2021 - * - :ref:`2021.1` - - June 13, 2021 - * - :ref:`2020.3` - - October 8, 2020 - * - :ref:`2020.2` - - July 22, 2020 - * - :ref:`2020.1` - - January 15, 2020 + @@ -32,7 +31,7 @@ Release Notes :glob: :hidden: - 2022.1 + 2022.1_index 2021.2_index 2021.1_index 2020.3_index From 3cc5089a27da69132444777c105a7f3e5d41132d Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 14 Jul 2022 16:04:36 +0300 Subject: [PATCH 113/316] Update index.rst --- releases/index.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/releases/index.rst b/releases/index.rst index d68e0b55b..17fdbb529 100644 --- a/releases/index.rst +++ b/releases/index.rst @@ -8,17 +8,17 @@ SQream releases notes are specific to each version of the application. Select yo +---------------------------------+----------------------------------+------------------------------------------------------------------+ | **Major Release** | **Minor Releases** | +---------------------------------+----------------------------------+--------------------------------+---------------------------------+ -| :ref:`2022.1<2022.1>` | | | | +| :ref:`2022.1<2022.1>` | +---------------------------------+----------------------------------+--------------------------------+---------------------------------+ | :ref:`2021.2<2021.2>` | :ref:`2021.2.1<2021.2.1>` | :ref:`2021.2.1.1<2021.2.1.1>` | :ref:`2021.2.1.23<2021.2.1.23>` | +---------------------------------+----------------------------------+--------------------------------+---------------------------------+ -| :ref:`2021.1<2021.1>` | :ref:`2021.1.1<2021.1.1>` | :ref:`2021.1.2<2021.1.2>` | | +| :ref:`2021.1<2021.1>` | :ref:`2021.1.1<2021.1.1>` | :ref:`2021.1.2<2021.1.2>` | +---------------------------------+----------------------------------+--------------------------------+---------------------------------+ -| :ref:`2020.3<2020.3>` | :ref:`2020.3.1<2020.3.1>` | :ref:`2020.3.2.1<2020.3.2.1>` | | +| :ref:`2020.3<2020.3>` | :ref:`2020.3.1<2020.3.1>` | :ref:`2020.3.2.1<2020.3.2.1>` | +---------------------------------+----------------------------------+--------------------------------+---------------------------------+ -| :ref:`2020.2<2020.2>` | | | | +| :ref:`2020.2<2020.2>` | +---------------------------------+----------------------------------+--------------------------------+---------------------------------+ -| :ref:`2020.1<2020.1>` | | | | +| :ref:`2020.1<2020.1>` | +---------------------------------+----------------------------------+--------------------------------+---------------------------------+ From 708d6676e6db6437a5e751e548832dfb1e07f2c8 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Fri, 15 Jul 2022 01:11:17 +0300 Subject: [PATCH 114/316] Added all bugs (not filtered) --- releases/2021.2.1.22.rst | 26 ++++++ releases/2022.1.rst | 195 ++++++++++++++++++++++++++++++++++++--- releases/index.rst | 30 +++--- 3 files changed, 222 insertions(+), 29 deletions(-) create mode 100644 releases/2021.2.1.22.rst diff --git a/releases/2021.2.1.22.rst b/releases/2021.2.1.22.rst new file mode 100644 index 000000000..029ad0178 --- /dev/null +++ b/releases/2021.2.1.22.rst @@ -0,0 +1,26 @@ +.. _2021.2.1.22: + +****************************** +Release Notes 2021.2.1.22 +****************************** +The 2021.2.1.22 release notes is a patch version released on 27/6/2022. + +The following table lists the issues that were resolved in Version 2021.2.1.23: + +.. list-table:: + :widths: 17 200 + :header-rows: 1 + + * - SQ No. + - Description + * - SQ-10776 + - Out Of Memory invoked during copy from with multiple files. + +Version 2021.2.1.23 has no unresolved issues. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2021.2.1.22 \ No newline at end of file diff --git a/releases/2022.1.rst b/releases/2022.1.rst index 52a6722e5..74e568fad 100644 --- a/releases/2022.1.rst +++ b/releases/2022.1.rst @@ -60,20 +60,187 @@ Resolved Issues --------- The following table lists the issues that were resolved in Version 2022.1: -.. list-table:: - :widths: 17 200 - :header-rows: 1 - - * - SQ No. - - Description - * - SQ-xxxx - - Text - * - SQ-xxxx - - Text - * - SQ-xxxx - - Text - -**Comment** - *The table above will be updated regarding which resolved issues to include.* +**Comment** - *The items in the table below must be filtered according to external and internal bugs. We CANNOT expose internal bugs to external users.* + ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-7490 | Native Avro file access via a dedicated FDW | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-7718 | Certify LTS Ubuntu versions (18.04 & 20.04) for production usage | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-7732 | Fail to read numeric columns from an external generated parquet file | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-8163 | Performance degradation - tpch1t_external_table_parquet - cases #6079 & #6105 | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-8182 | Encryption Function | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-8984 | Update statement MVP: literal assignment | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-9221 | [Mobicom] PBI - External Tables are not shown on the tables list. | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-9611 | Create a WIN-874 to UTF-8 conversion function | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-9634 | identifier not found | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-9644 | [ACL] Incomplete logs query causing Internal Runtime Error | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-9671 | Trying to read Thai UTF-8 csv file in TEXT column and it not shows Thai | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-9764 | No error when create a foreign table with difference in the column numbers in the table and the file | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-9790 | Encryption - MVP scope | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-9808 | Allowing to set deferredValueIOThresholdFactor flag not in developer Mode=true | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-9823 | [AIS] The user can't use literals when using sqream with Thai varchar | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-9889 | [AIS] Internal runtime Error receive | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-9952 | Removing temp files takes too long - timeout issue at LGU+ | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-9988 | Find a proper solution for data lost during copy from parquet - without reverting previous optimization | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-9990 | Merge v2021.2.1_stable into develop | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10005 | Go / No Go approvals | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10011 | Delete filter optimization chicken flag | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10055 | [SamsungDisplay] Slow loading of sqream after backup compacting | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10061 | compiler side - Implement MVP scope | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10071 | error on exists subqueries with text and varchar equality condition | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10111 | Parquet numeric - Sqream can't import parquet numeric columns from other sources | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10191 | [LGE] ALTER DEFAULT SCHEMA command has a problem. | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10216 | Performance degradation - tpch1t_1mchunk - case #1326 #1345 | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10242 | socket 11 error from "Create as Select~" | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10269 | cleanup_chunk error with text(X) column | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10314 | Unable to load avro file to sqream v1 + v2 from s3 | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10319 | Error on copy from avro file with numeric data | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10425 | Lot of time in copy from, external table parquet file | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10428 | [LGU] Can not execute cleanup_extents on table because there are mixed chunks | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10470 | count distinct on 0 rows doesn't return any value | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10478 | get_ddl disregards encrypted columns | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10479 | create a table with more than three encrypted column with no error | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10492 | Wrong values when select from table have encrypted column and regular column | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10494 | No “encrypted” label when read from table with encrypted column | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10496 | Not able to insert data to encrypted column after performing delete on the column | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10514 | No error when create table with encrypted column for the unsupported data types | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10515 | Run time error when decrypt 1 million rows | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10518 | create foreign table with encrypted column with no error | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10532 | Get Read time out error when try to read avro to wrong ddl (Frozen client) | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10534 | Wrong error message when copy null values from avro file to not null ddl (Overflow case instead null to not null) | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10551 | No error when add encrypt column to already existing table | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10585 | [V1] ORC Numeric reading - Overflow error | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10586 | SQream crashed when encrypt 1 billion rows | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10593 | Seg fault when inserting AVRO non-decimal value to Numeric type | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10594 | Some of configuration flags are displaced in default config | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10613 | Samsung test fail on branch v2022.1_stable | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10629 | Different join type between SELECT (Left) vs INSERT INTO SELECT (Left cross) | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10631 | Performance degradation - copies - copy_nvarchar40.sql - case #4556 | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10632 | Performance degradation - insert_as_select - insert_as_select_parquet_int.sql - case #4971 | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10655 | Performance degradation- some queries that perform COPY FROM - case #4624 | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10656 | Performance degradation - insert_as_select - #4971 & #4984 | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10659 | [SDC] Compile Error when using comment | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10665 | AWS V2 - Files are not deleted from S3 storage after DROP database and DROP table | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10667 | Log file not created when execute copy from avro | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10677 | Different results between subquery and physical table | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10692 | Internal Runtime Error when decrypt 1 million rows of text data type | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10695 | when ingest 100 million data into table with 3 encrypted column it took time more than expected | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10716 | Error on copy from avro (Expected auto cast) | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10734 | nvarchar_backward_comp1 failed in regression on branch v2022.1_stable | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10735 | numeric_upgrade_storage has failed in regression on v2022.1_stable | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10738 | Sqream worker on GPU id 1 consume also from GPU id 0 | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10745 | compiler_tests failed in regression on v2022.1_stable | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10776 | Out Of Memory invoked during copy from with multiple files | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10813 | Copy To - The statement doesn't working when I use with 'Avro' format for location='s3....' | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10823 | window_functions_part1 failed in regression in develop | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10855 | CLONE - UF - list all files related to chunk id, Get specific chunk key values | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10869 | Enable/Disable encryption by default | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10871 | Copy To - Getting an error when missing file_name in the end of the path at the location field(This happen only at Avro format) | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10877 | Avro not implemented on stable version v2022 s3 | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10885 | Filter on Delete - should be tested | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10889 | v2022.1_stable => Internal compiler error: Bad encryption type | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10895 | [AIS] behavior is not consistent when the user using Literals with Thai varchar WIN-874 or Thai text UTF-8 | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10902 | test_copy_null_to_not_null[all_types-parquet] (from Generic Copy From) crashes sqreamd | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10916 | [AIS] varcharEncoding": "WINDOWS-874" Flag should work NOT ONLY in Developer mode | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10938 | REGEXP_REPLACE is not supported in 2022 version | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10962 | Using Thai Literals on v2022 with Text type output shows bad results ONLY ON Clientcmd | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10987 | [AIS] The system not allowing to control the update permissions - Grant update permission | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10999 | File tracker error logs on Sqream with MD - insert & select queries | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11043 | correlated_subqueries_v1 test failed | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11063 | Migration of Varchar to Text - keep the size of Varchar after the migration to the text type. | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11101 | Show locks test failed in regression for v2022.1 | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11109 | User can't change his own password using the UI | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11168 | Migration script on 1B rows table and 8 columns output with Internal run time error. | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11170 | Create a tool for migrating a Varchar table to Text | ++------------+-------------------------------------------------------------------------------------------------------------------------------------+ Operations and Configuration Changes -------- diff --git a/releases/index.rst b/releases/index.rst index 17fdbb529..d07b22632 100644 --- a/releases/index.rst +++ b/releases/index.rst @@ -5,21 +5,21 @@ Release Notes ********** SQream releases notes are specific to each version of the application. Select your version from the table below to see the related release notes. -+---------------------------------+----------------------------------+------------------------------------------------------------------+ -| **Major Release** | **Minor Releases** | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+ -| :ref:`2022.1<2022.1>` | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+ -| :ref:`2021.2<2021.2>` | :ref:`2021.2.1<2021.2.1>` | :ref:`2021.2.1.1<2021.2.1.1>` | :ref:`2021.2.1.23<2021.2.1.23>` | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+ -| :ref:`2021.1<2021.1>` | :ref:`2021.1.1<2021.1.1>` | :ref:`2021.1.2<2021.1.2>` | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+ -| :ref:`2020.3<2020.3>` | :ref:`2020.3.1<2020.3.1>` | :ref:`2020.3.2.1<2020.3.2.1>` | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+ -| :ref:`2020.2<2020.2>` | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+ -| :ref:`2020.1<2020.1>` | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+ ++---------------------------------+----------------------------------+----------------------------------------------------------------------------------------------------+---------------------------------+ +| **Major Release** | **Minor Releases** | ++---------------------------------+----------------------------------+--------------------------------+-------------------------------------------------------------------+---------------------------------+ +| :ref:`2022.1<2022.1>` | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+---------------------------------+ +| :ref:`2021.2<2021.2>` | :ref:`2021.2.0.1<2021.2.0.1>` | :ref:`2021.2.1<2021.2.1>` | :ref:`2021.2.1.1<2021.2.1.1>` | :ref:`2021.2.1.22<2021.2.1.22>` | :ref:`2021.2.1.23<2021.2.1.23>` | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+---------------------------------+ +| :ref:`2021.1<2021.1>` | :ref:`2021.1.1<2021.1.1>` | :ref:`2021.1.2<2021.1.2>` | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+---------------------------------+ +| :ref:`2020.3<2020.3>` | :ref:`2020.3.1<2020.3.1>` | :ref:`2020.3.2.1<2020.3.2.1>` | ++---------------------------------+----------------------------------+--------------------------------+-------------------------------------------------------------------+---------------------------------+ +| :ref:`2020.2<2020.2>` | ++---------------------------------+----------------------------------+--------------------------------+-------------------------------------------------------------------+---------------------------------+ +| :ref:`2020.1<2020.1>` | ++---------------------------------+----------------------------------+--------------------------------+-------------------------------------------------------------------+---------------------------------+ From c9207316e925b96f08bfbe0ac8cd483c97546038 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Fri, 15 Jul 2022 16:41:58 +0300 Subject: [PATCH 115/316] Started adding all patches --- releases/2021.1.1.1.rst | 32 +++++++++++++++++++++++++++++++ releases/2021.1_index.rst | 11 ++++++----- releases/2021.2.0.1.rst | 40 +++++++++++++++++++++++++++++++++++++++ releases/2021.2.1.24.rst | 26 +++++++++++++++++++++++++ releases/2021.2.1.25.rst | 26 +++++++++++++++++++++++++ releases/index.rst | 31 +++++++++++++++--------------- 6 files changed, 145 insertions(+), 21 deletions(-) create mode 100644 releases/2021.1.1.1.rst create mode 100644 releases/2021.2.0.1.rst create mode 100644 releases/2021.2.1.24.rst create mode 100644 releases/2021.2.1.25.rst diff --git a/releases/2021.1.1.1.rst b/releases/2021.1.1.1.rst new file mode 100644 index 000000000..2e562c858 --- /dev/null +++ b/releases/2021.1.1.1.rst @@ -0,0 +1,32 @@ +.. _2021.1.1.1: + +************************** +Release Notes 2021.1.1.1 +************************** +The 2021.1.1.1 release notes is a patch version released on 27/6/2022. + +The following table lists the issues that were resolved in Version 2021.1.1.1: + +.. list-table:: + :widths: 17 200 + :header-rows: 1 + + * - SQ No. + - Description + * - SQ-7045 + - Replace function doesn't support column value + * - SQ-7640 + - Some dates can't be recognized as a standard date format + * - SQ-7658 + - Can't perform "=" function between varchar(1) and text argument + * - SQ-7588 + - A thread that removes stuck open snapshots + +Version 2021.1.1.1 has no unresolved issues. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2021.1.1.1 \ No newline at end of file diff --git a/releases/2021.1_index.rst b/releases/2021.1_index.rst index 5ba66f511..0e9960d99 100644 --- a/releases/2021.1_index.rst +++ b/releases/2021.1_index.rst @@ -5,11 +5,11 @@ Release Notes 2021.1 ************************** SQream releases notes are specific to each version of the application. Select your version from the table below to see the related release notes. -+---------------------------------+----------------------------------+------------------------------------------------------------------+ -| **Major Release** | **Minor Releases** | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+ -| :ref:`2021.1<2021.1>` | :ref:`2021.1.1<2021.1.1>` | :ref:`2021.1.2<2021.1.2>` | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+ ++---------------------------------+----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Major Release** | **Minor Releases** | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------------+ +| :ref:`2021.2<2021.2>` | :ref:`2021.2.0.1<2021.2.0.1>` | :ref:`2021.2.1<2021.2.1>` | :ref:`2021.2.1.1<2021.2.1.1>` | :ref:`2021.2.1.22<2021.2.1.22>` | :ref:`2021.2.1.23<2021.2.1.23>` | :ref:`2021.2.1.24<2021.2.1.24>` | :ref:`2021.2.1.25<2021.2.1.25>` | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------------+ .. toctree:: :maxdepth: 2 @@ -18,4 +18,5 @@ SQream releases notes are specific to each version of the application. Select yo 2021.1 2021.1.1 + 2021.1.1.1 2021.1.2 \ No newline at end of file diff --git a/releases/2021.2.0.1.rst b/releases/2021.2.0.1.rst new file mode 100644 index 000000000..41cbd96d3 --- /dev/null +++ b/releases/2021.2.0.1.rst @@ -0,0 +1,40 @@ +.. _2021.2.0.1: + +************************** +Release Notes 2021.2.0.1 +************************** +The 2021.2.0.1 release notes were released on x/x/xxxx and describe the following: + +The following table lists the issues that were resolved in Version 2021.2.0.1: + +.. list-table:: + :widths: 17 200 + :header-rows: 1 + + * - SQ No. + - Description + * - SQ-8345 + - Studio-How does a publicUser connect to a specified service? + * - SQ-8343 + - Running SQream from docker does not show configuration extended info + * - SQ-8294 + - Quote qualifier is not present in exported file thus file cannot be reloaded + * - SQ-8288 + - Support parameter TEXT casts + * - SQ-8272 + - `cleanup_chunk` creates garbage metadata, potentially leading to wrong results + * - SQ-8271 + - Saved query parameters of type text are not supported + * - SQ-8266 + - [LGE] Data loading issue depending to column order. // bad syntax (datetime type) + * - SQ-8266 + - [LGE] Data loading issue depending to column order. // bad syntax (datetime type) + +Version 2021.2.0.1 has no unresolved issues. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2021.2.0.1 \ No newline at end of file diff --git a/releases/2021.2.1.24.rst b/releases/2021.2.1.24.rst new file mode 100644 index 000000000..8f0f9d26b --- /dev/null +++ b/releases/2021.2.1.24.rst @@ -0,0 +1,26 @@ +.. _2021.2.1.24: + +****************************** +Release Notes 2021.2.1.24 +****************************** +The 2021.2.1.24 release notes is a patch version released on xxxxxxxxxxxx. + +The following table lists the issues that were resolved in Version 2021.2.1.24.rst: + +.. list-table:: + :widths: 17 200 + :header-rows: 1 + + * - SQ No. + - Description + * - SQ-xxxxx + - Description + +Version 2021.2.1.24 has no unresolved issues. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2021.2.1.24 \ No newline at end of file diff --git a/releases/2021.2.1.25.rst b/releases/2021.2.1.25.rst new file mode 100644 index 000000000..6b6e1db03 --- /dev/null +++ b/releases/2021.2.1.25.rst @@ -0,0 +1,26 @@ +.. _2021.2.1.25: + +****************************** +Release Notes 2021.2.1.25 +****************************** +The 2021.2.1.25 release notes is a patch version released on xxxxxxxxxxxx. + +The following table lists the issues that were resolved in Version 2021.2.1.25.rst: + +.. list-table:: + :widths: 17 200 + :header-rows: 1 + + * - SQ No. + - Description + * - SQ-xxxxx + - Description + +Version 2021.2.1.25 has no unresolved issues. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2021.2.1.25 \ No newline at end of file diff --git a/releases/index.rst b/releases/index.rst index d07b22632..8f8933ce4 100644 --- a/releases/index.rst +++ b/releases/index.rst @@ -5,22 +5,21 @@ Release Notes ********** SQream releases notes are specific to each version of the application. Select your version from the table below to see the related release notes. -+---------------------------------+----------------------------------+----------------------------------------------------------------------------------------------------+---------------------------------+ -| **Major Release** | **Minor Releases** | -+---------------------------------+----------------------------------+--------------------------------+-------------------------------------------------------------------+---------------------------------+ -| :ref:`2022.1<2022.1>` | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+---------------------------------+ -| :ref:`2021.2<2021.2>` | :ref:`2021.2.0.1<2021.2.0.1>` | :ref:`2021.2.1<2021.2.1>` | :ref:`2021.2.1.1<2021.2.1.1>` | :ref:`2021.2.1.22<2021.2.1.22>` | :ref:`2021.2.1.23<2021.2.1.23>` | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+---------------------------------+ -| :ref:`2021.1<2021.1>` | :ref:`2021.1.1<2021.1.1>` | :ref:`2021.1.2<2021.1.2>` | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+---------------------------------+ -| :ref:`2020.3<2020.3>` | :ref:`2020.3.1<2020.3.1>` | :ref:`2020.3.2.1<2020.3.2.1>` | -+---------------------------------+----------------------------------+--------------------------------+-------------------------------------------------------------------+---------------------------------+ -| :ref:`2020.2<2020.2>` | -+---------------------------------+----------------------------------+--------------------------------+-------------------------------------------------------------------+---------------------------------+ -| :ref:`2020.1<2020.1>` | -+---------------------------------+----------------------------------+--------------------------------+-------------------------------------------------------------------+---------------------------------+ - ++---------------------------------+----------------------------------+----------------------------------------------------------------------------------------------------+---------------------------------+---------------------------------+----------------------------------+ +| **Major Release** | **Minor Releases** | ++---------------------------------+----------------------------------+--------------------------------+-------------------------------------------------------------------+---------------------------------+---------------------------------+----------------------------------+ +| :ref:`2022.1<2022.1>` | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------------+ +| :ref:`2021.2<2021.2>` | :ref:`2021.2.0.1<2021.2.0.1>` | :ref:`2021.2.1<2021.2.1>` | :ref:`2021.2.1.1<2021.2.1.1>` | :ref:`2021.2.1.22<2021.2.1.22>` | :ref:`2021.2.1.23<2021.2.1.23>` | :ref:`2021.2.1.24<2021.2.1.24>` | :ref:`2021.2.1.25<2021.2.1.25>` | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------------+ +| :ref:`2021.1<2021.1>` | :ref:`2021.1.1<2021.1.1>` | :ref:`2021.1.1.1<2021.1.1.1>` | :ref:`2021.1.2<2021.1.2>` | | | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+------------------------------------------------------------------------------------------------------+ +| :ref:`2020.3<2020.3>` | :ref:`2020.3.1<2020.3.1>` | :ref:`2020.3.2.1<2020.3.2.1>` | ++---------------------------------+----------------------------------+--------------------------------+-------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+ +| :ref:`2020.2<2020.2>` | ++---------------------------------+----------------------------------+--------------------------------+-------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+ +| :ref:`2020.1<2020.1>` | ++---------------------------------+----------------------------------+--------------------------------+-------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+ From 1b201a083e4358af66d7a53d034424e104a74158 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 18 Jul 2022 13:08:45 +0300 Subject: [PATCH 116/316] Preparing for 2022.1 Built table for all minor patches (2022.1, 2021.1, and 2021.2) --- releases/2021.1_index.rst | 4 +- releases/2021.2.0.1.rst | 2 +- releases/2021.2.1.1.rst | 2 +- releases/2021.2.1.22.rst | 8 ++-- releases/2021.2.1.24.rst | 47 ++++++++++++++++++++---- releases/2021.2.1.25.rst | 26 ------------- releases/2021.2_index.rst | 12 +++--- releases/2022.1.1.rst | 77 +++++++++++++++++++++++++++++++++++++++ releases/2022.1_index.rst | 15 ++++---- releases/index.rst | 41 +++++++++++---------- 10 files changed, 161 insertions(+), 73 deletions(-) delete mode 100644 releases/2021.2.1.25.rst create mode 100644 releases/2022.1.1.rst diff --git a/releases/2021.1_index.rst b/releases/2021.1_index.rst index 0e9960d99..0fa9d6ccf 100644 --- a/releases/2021.1_index.rst +++ b/releases/2021.1_index.rst @@ -8,8 +8,8 @@ SQream releases notes are specific to each version of the application. Select yo +---------------------------------+----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | **Major Release** | **Minor Releases** | +---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------------+ -| :ref:`2021.2<2021.2>` | :ref:`2021.2.0.1<2021.2.0.1>` | :ref:`2021.2.1<2021.2.1>` | :ref:`2021.2.1.1<2021.2.1.1>` | :ref:`2021.2.1.22<2021.2.1.22>` | :ref:`2021.2.1.23<2021.2.1.23>` | :ref:`2021.2.1.24<2021.2.1.24>` | :ref:`2021.2.1.25<2021.2.1.25>` | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------------+ +| :ref:`2021.1<2021.1>` | :ref:`2021.1.1<2021.1.1>` | :ref:`2021.1.1.1<2021.1.1.1>` | :ref:`2021.1.2<2021.1.2>` | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+------------------------------------------------------------------------------------------------------+ .. toctree:: :maxdepth: 2 diff --git a/releases/2021.2.0.1.rst b/releases/2021.2.0.1.rst index 41cbd96d3..03edcad4e 100644 --- a/releases/2021.2.0.1.rst +++ b/releases/2021.2.0.1.rst @@ -33,7 +33,7 @@ The following table lists the issues that were resolved in Version 2021.2.0.1: Version 2021.2.0.1 has no unresolved issues. .. toctree:: - :maxdepth: 2 + :maxdepth: 3 :glob: :hidden: diff --git a/releases/2021.2.1.1.rst b/releases/2021.2.1.1.rst index a1137e418..65cf1b8a1 100644 --- a/releases/2021.2.1.1.rst +++ b/releases/2021.2.1.1.rst @@ -21,7 +21,7 @@ The following table lists the issues that were resolved in Version 2021.2.1.1: Version 2021.2.1.1 has no unresolved issues. .. toctree:: - :maxdepth: 2 + :maxdepth: 3 :glob: :hidden: diff --git a/releases/2021.2.1.22.rst b/releases/2021.2.1.22.rst index 029ad0178..62346a3c8 100644 --- a/releases/2021.2.1.22.rst +++ b/releases/2021.2.1.22.rst @@ -3,9 +3,9 @@ ****************************** Release Notes 2021.2.1.22 ****************************** -The 2021.2.1.22 release notes is a patch version released on 27/6/2022. +The 2021.2.1.22 release notes is a patch version released on 13/6/2022. -The following table lists the issues that were resolved in Version 2021.2.1.23: +The following table lists the issues that were resolved in Version 2021.2.1.22: .. list-table:: :widths: 17 200 @@ -16,10 +16,10 @@ The following table lists the issues that were resolved in Version 2021.2.1.23: * - SQ-10776 - Out Of Memory invoked during copy from with multiple files. -Version 2021.2.1.23 has no unresolved issues. +Version 2021.2.1.22 has no unresolved issues. .. toctree:: - :maxdepth: 2 + :maxdepth: 4 :glob: :hidden: diff --git a/releases/2021.2.1.24.rst b/releases/2021.2.1.24.rst index 8f0f9d26b..cf4a2f391 100644 --- a/releases/2021.2.1.24.rst +++ b/releases/2021.2.1.24.rst @@ -7,14 +7,45 @@ The 2021.2.1.24 release notes is a patch version released on xxxxxxxxxxxx. The following table lists the issues that were resolved in Version 2021.2.1.24.rst: -.. list-table:: - :widths: 17 200 - :header-rows: 1 - - * - SQ No. - - Description - * - SQ-xxxxx - - Description ++-------------+----------------------------------------------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+==================================================================================================================================+ +| SQ-9721 | pysqream - not finishing query | ++-------------+----------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10071 | error on exists subqueries with text and varchar equality condition | ++-------------+----------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10606 | [ACL] Queries getting stuck in the queue for a long time (Executing status) | ++-------------+----------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10691 | DB Schema identifier causes an error running some queries from joins suite - v2021.2.1_stable | ++-------------+----------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10843 | When getting "illegal memory access was encountered" error message worker does not crash, but fails every query afterwards. | ++-------------+----------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10879 | Performance | degradations in insert as select from ORC files | ++-------------+----------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10902 | test_copy_null_to_not_null[all_types-parquet] (from Generic Copy From) crashes sqreamd | ++-------------+----------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10918 | [SDC] WLM only assings jobs sequentially and it causes delay on user sqls when they are assigned to a worker running a huge job | ++-------------+----------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10955 | No metadata filters when filtering by nullable date using dateadd (LGU+) | ++-------------+----------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10963 | Extract File Reaper Mechanism To Separated Process | ++-------------+----------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10975 | Merging ACL's open snapshot functionality from V2021.1.1 to V2021.2.1.x | ++-------------+----------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10976 | Merging all V2021.1.X fixes/features to V2021.2&V2022.1.X | ++-------------+----------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11000 | DROP DATABASE fails to remove database path under sqreamdb and following creation commands is stuck | ++-------------+----------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11043 | correlated_subqueries_v1 test failed | ++-------------+----------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11055 | performance degradation - tpch10t - cases #1299, #1315, #1307 & #1297 | ++-------------+----------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11088 | specific worker compiling causes low performance | ++-------------+----------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11090 | SQream keeps the configuration flags where the query compiled and use it when the query is executed on a different worker | ++-------------+----------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11159 | Redesign the heartbeat timers, worker and metadata. | ++-------------+----------------------------------------------------------------------------------------------------------------------------------+ Version 2021.2.1.24 has no unresolved issues. diff --git a/releases/2021.2.1.25.rst b/releases/2021.2.1.25.rst deleted file mode 100644 index 6b6e1db03..000000000 --- a/releases/2021.2.1.25.rst +++ /dev/null @@ -1,26 +0,0 @@ -.. _2021.2.1.25: - -****************************** -Release Notes 2021.2.1.25 -****************************** -The 2021.2.1.25 release notes is a patch version released on xxxxxxxxxxxx. - -The following table lists the issues that were resolved in Version 2021.2.1.25.rst: - -.. list-table:: - :widths: 17 200 - :header-rows: 1 - - * - SQ No. - - Description - * - SQ-xxxxx - - Description - -Version 2021.2.1.25 has no unresolved issues. - -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2021.2.1.25 \ No newline at end of file diff --git a/releases/2021.2_index.rst b/releases/2021.2_index.rst index 6e207ee73..98a256bc2 100644 --- a/releases/2021.2_index.rst +++ b/releases/2021.2_index.rst @@ -5,11 +5,11 @@ Release Notes 2021.2 ************************** SQream releases notes are specific to each version of the application. Select your version from the table below to see the related release notes. -+---------------------------------+---------------------------------+------------------------------------------------------------------+ -| **Major Release** | **Minor Release** | -+---------------------------------+---------------------------------+--------------------------------+---------------------------------+ -| :ref:`2021.2<2021.2>` | :ref:`2021.2.1<2021.2.1>` | :ref:`2021.2.1.1<2021.2.1.1>` | :ref:`2021.2.1.23<2021.2.1.23>` | -+---------------------------------+---------------------------------+--------------------------------+---------------------------------+ ++---------------------------------+----------------------------------+----------------------------------------------------------------------------------------------------+---------------------------------+---------------------------------+----------------------------------+ +| **Major Release** | **Minor Releases** | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+------------------------------------------------------------------------------------------------------+ +| :ref:`2021.2<2021.2>` | :ref:`2021.2.0.1<2021.2.0.1>` | :ref:`2021.2.1<2021.2.1>` | :ref:`2021.2.1.1<2021.2.1.1>` | :ref:`2021.2.1.22<2021.2.1.22>` | :ref:`2021.2.1.23<2021.2.1.23>` | ++---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------------+ .. toctree:: :maxdepth: 2 @@ -17,6 +17,8 @@ SQream releases notes are specific to each version of the application. Select yo :hidden: 2021.2 + 2021.2.0.1 2021.2.1 2021.2.1.1 + 2021.2.1.22 2021.2.1.23 \ No newline at end of file diff --git a/releases/2022.1.1.rst b/releases/2022.1.1.rst new file mode 100644 index 000000000..081d608f2 --- /dev/null +++ b/releases/2022.1.1.rst @@ -0,0 +1,77 @@ +.. _2022.1.1: + +************************** +Release Notes 2022.1.1 +************************** +The 2022.1.1 release notes were released on x/x/xxxx and describe the following: + +The following table lists the issues that were resolved in Version 2022.1.1: + ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+==================================================================================================================================================+ +| SQ-6419 | Internal compiler error when casting numeric literal in aggregation function | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-9771 | The error returns different value when trying to insert date value without quotes. | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10100 | Implicit/Explicit cast from int/tinyint/bigint to bool is not working | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10741 | Got difference in execution time when ingesting data | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10772 | Internal Runtime Error when creating a text column with a limit characters size >= 1 and 30 zeros | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10790 | copy from with '*' (wildcard) from parquet is 3X slower than CSV | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10793 | Implement "Brute Force" Protection policy for the system login | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10816 | Data management on Big Table | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10838 | Repeat function throws an exception when entered a negative number | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10840 | UF - list all files related to chunk id, Get specific chunk key values | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10852 | Password Strength Check | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10863 | Performance | LGU | high SD in the duration of 'insert as select' query | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10873 | Inserting 100K bytes to a text column results in unclear error message | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10886 | Error in compilation process: : "Internal compiler error: | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10892 | Update || change error message when trying to run update on foreign table | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10899 | Cannot change the value of diskSpaceMinFreePercent - it is hard coded to 10% | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10919 | Automatic Foreign Table DDL Resolution | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10955 | No metadata filters when filtering by nullable date using dateadd (LGU+) | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10956 | Exception: "Could not read view.." - recompile and recreate doesn't help | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10963 | Extract File Reaper Mechanism To Separated Process | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10976 | Merging all V2021.1.X fixes/features to V2021.2&V2022.1.X | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10980 | sqream crashing when executing copy from avro (negative case copy file to unmatched column table) | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10988 | [SDC] stop_statement() doesn't work on jobs in queue | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11014 | Different float values between sqream and postgress | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11121 | Merging ACL's open snapshot functionality from V2021.1.1 to v2022.1.x code line | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11137 | CLONE - When getting "illegal memory access was encountered" error message worker does not crash, but fails every query afterwards. - AUTOMATIC | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11154 | After SQ-10980 fix, there is wrong error raised ("OVERFLOW exception") instead of "Tried inserting AVRO non-decimal" | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11158 | [ACL] Datediff doesn't work with specific dates - returns "Cast overflow" | ++-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ + +Version 2022.1.1 has no unresolved issues. + +.. toctree:: + :maxdepth: 3 + :glob: + :hidden: + + 2022.1.1 \ No newline at end of file diff --git a/releases/2022.1_index.rst b/releases/2022.1_index.rst index c40867102..6393d5511 100644 --- a/releases/2022.1_index.rst +++ b/releases/2022.1_index.rst @@ -3,17 +3,18 @@ ************************** Release Notes 2022.1 ************************** -The 2022.1 Release Notes describe the following releases: +The 2022.1 Release Notes describe the following releases: -+---------------------------------+----------------------------------+------------------------------------------------------------------+ -| **Major Release** | **Minor Releases** | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+ -| :ref:`2022.1<2022.1>` | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+ ++---------------------------------+----------------------------------+ +| **Major Release** | **Minor Releases** | ++---------------------------------+----------------------------------+ +| :ref:`2022.1<2022.1>` | :ref:`2022.1.1<2022.1.1>` | ++---------------------------------+----------------------------------+ .. toctree:: :maxdepth: 2 :glob: :hidden: - 2022.1 \ No newline at end of file + 2022.1 + 2022.1.1 \ No newline at end of file diff --git a/releases/index.rst b/releases/index.rst index 8f8933ce4..5e442a689 100644 --- a/releases/index.rst +++ b/releases/index.rst @@ -3,26 +3,29 @@ ********** Release Notes ********** -SQream releases notes are specific to each version of the application. Select your version from the table below to see the related release notes. - -+---------------------------------+----------------------------------+----------------------------------------------------------------------------------------------------+---------------------------------+---------------------------------+----------------------------------+ -| **Major Release** | **Minor Releases** | -+---------------------------------+----------------------------------+--------------------------------+-------------------------------------------------------------------+---------------------------------+---------------------------------+----------------------------------+ -| :ref:`2022.1<2022.1>` | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------------+ -| :ref:`2021.2<2021.2>` | :ref:`2021.2.0.1<2021.2.0.1>` | :ref:`2021.2.1<2021.2.1>` | :ref:`2021.2.1.1<2021.2.1.1>` | :ref:`2021.2.1.22<2021.2.1.22>` | :ref:`2021.2.1.23<2021.2.1.23>` | :ref:`2021.2.1.24<2021.2.1.24>` | :ref:`2021.2.1.25<2021.2.1.25>` | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------------+ -| :ref:`2021.1<2021.1>` | :ref:`2021.1.1<2021.1.1>` | :ref:`2021.1.1.1<2021.1.1.1>` | :ref:`2021.1.2<2021.1.2>` | | | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+------------------------------------------------------------------------------------------------------+ -| :ref:`2020.3<2020.3>` | :ref:`2020.3.1<2020.3.1>` | :ref:`2020.3.2.1<2020.3.2.1>` | -+---------------------------------+----------------------------------+--------------------------------+-------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+ -| :ref:`2020.2<2020.2>` | -+---------------------------------+----------------------------------+--------------------------------+-------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+ -| :ref:`2020.1<2020.1>` | -+---------------------------------+----------------------------------+--------------------------------+-------------------------------------------------------------------+------------------------------------------------------------------------------------------------------+ - - +SQream releases notes are specific to each version of the application. Select your version from the table below to see the related release notes. ++---------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Major Release** | **Minor Releases** | ++---------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| :ref:`2022.1<2022.1>` | :ref:`2022.1.1<2022.1.1>` | ++---------------------------------+----------------------------------+---------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+---------------------------------------+ +|:ref:`2021.1<2021.1>` | :ref:`2021.1.1.1<2021.1.1.1>` | :ref:`2021.1.1.11<2021.1.1.11>` | :ref:`2021.1.1.2<2021.1.1.2>` | :ref:`2021.1.1.3<2021.1.1.3>` | :ref:`2021.1.1.4<2021.1.1.4>` | :ref:`2021.1.1.6<2021.1.1.6>` | :ref:`2021.1.1_rdb_1<2021.1.1_rdb_1>` | ++---------------------------------+----------------------------------+---------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+---------------------------------------+ +| | :ref:`2021.1.2<2021.1.2>` | ++---------------------------------+----------------------------------+---------------------------------+----------------------------------+----------------------------------+----------------------------------+--------------------------------------------------------------------------+ +|:ref:`2021.2<2021.2>` | :ref:`2021.2.0.1<2021.2.0.1>` |:ref:`2021.2.0.3<2021.2.0.3>` | :ref:`2021.2.1<2021.2.1>` | :ref:`2021.2.1.14<2021.2.1.14>` | :ref:`2021.2.1.16<2021.2.1.16>` | :ref:`2021.2.1.17<2021.2.1.17>` | ++---------------------------------+----------------------------------+---------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+---------------------------------------+ +| |:ref:`2021.2.1.18<2021.2.1.18>` |:ref:`2021.2.1.19<2021.2.1.19>` | :ref:`2021.2.1.20<2021.2.1.20>` | :ref:`2021.2.1.21<2021.2.1.21>` | :ref:`2021.2.1.22<2021.2.1.22>` | :ref:`2021.2.1.23<2021.2.1.23>` | :ref:`2021.2.1.8<2021.2.1.8>` | ++---------------------------------+----------------------------------+---------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+---------------------------------------+ +| | :ref:`2021.2.1.18<2021.2.1.18>` | :ref:`2021.1.1<2021.1.1>` | :ref:`2021.1.1.1<2021.1.1.1>` | :ref:`2021.1.2<2021.1.2>` | ++---------------------------------+----------------------------------+---------------------------------+----------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+ +| :ref:`2020.3<2020.3>` | :ref:`2020.3.1<2020.3.1>` | :ref:`2020.3.2.1<2020.3.2.1>` | ++---------------------------------+----------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| :ref:`2020.2<2020.2>` | ++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| :ref:`2020.1<2020.1>` | ++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ .. toctree:: From bae359b04c2840434300804e2b38661379233f70 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 18 Jul 2022 13:56:07 +0300 Subject: [PATCH 117/316] Corrected patch order --- releases/index.rst | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/releases/index.rst b/releases/index.rst index 5e442a689..acb32e800 100644 --- a/releases/index.rst +++ b/releases/index.rst @@ -9,17 +9,17 @@ SQream releases notes are specific to each version of the application. Select yo | **Major Release** | **Minor Releases** | +---------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | :ref:`2022.1<2022.1>` | :ref:`2022.1.1<2022.1.1>` | -+---------------------------------+----------------------------------+---------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+---------------------------------------+ -|:ref:`2021.1<2021.1>` | :ref:`2021.1.1.1<2021.1.1.1>` | :ref:`2021.1.1.11<2021.1.1.11>` | :ref:`2021.1.1.2<2021.1.1.2>` | :ref:`2021.1.1.3<2021.1.1.3>` | :ref:`2021.1.1.4<2021.1.1.4>` | :ref:`2021.1.1.6<2021.1.1.6>` | :ref:`2021.1.1_rdb_1<2021.1.1_rdb_1>` | -+---------------------------------+----------------------------------+---------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+---------------------------------------+ -| | :ref:`2021.1.2<2021.1.2>` | -+---------------------------------+----------------------------------+---------------------------------+----------------------------------+----------------------------------+----------------------------------+--------------------------------------------------------------------------+ -|:ref:`2021.2<2021.2>` | :ref:`2021.2.0.1<2021.2.0.1>` |:ref:`2021.2.0.3<2021.2.0.3>` | :ref:`2021.2.1<2021.2.1>` | :ref:`2021.2.1.14<2021.2.1.14>` | :ref:`2021.2.1.16<2021.2.1.16>` | :ref:`2021.2.1.17<2021.2.1.17>` | -+---------------------------------+----------------------------------+---------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+---------------------------------------+ -| |:ref:`2021.2.1.18<2021.2.1.18>` |:ref:`2021.2.1.19<2021.2.1.19>` | :ref:`2021.2.1.20<2021.2.1.20>` | :ref:`2021.2.1.21<2021.2.1.21>` | :ref:`2021.2.1.22<2021.2.1.22>` | :ref:`2021.2.1.23<2021.2.1.23>` | :ref:`2021.2.1.8<2021.2.1.8>` | -+---------------------------------+----------------------------------+---------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+---------------------------------------+ -| | :ref:`2021.2.1.18<2021.2.1.18>` | :ref:`2021.1.1<2021.1.1>` | :ref:`2021.1.1.1<2021.1.1.1>` | :ref:`2021.1.2<2021.1.2>` | -+---------------------------------+----------------------------------+---------------------------------+----------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+ ++---------------------------------+----------------------------------+---------------------------------------+----------------------------------+----------------------------------+-------------------------------------------------------------------------------------------------------+ +| :ref:`2021.1<2021.1>` | :ref:`2021.1.1<2021.1.1>` | :ref:`2021.1.1_rdb_1<2021.1.1_rdb_1>` | :ref:`2021.1.1.11<2021.1.1.11>` | :ref:`2021.1.1.2<2021.1.1.2>` | :ref:`2021.1.1.3<2021.1.1.3>` | ++---------------------------------+----------------------------------+---------------------------------------+----------------------------------+----------------------------------+-------------------------------------------------------------------------------------------------------+ +| :ref:`2021.1.1.1<2021.1.1.1>` | :ref:`2021.1.1.4<2021.1.1.4>` | :ref:`2021.1.1.6<2021.1.1.6>` | :ref:`2021.1.1.7<2021.1.1.7>` | :ref:`2021.1.2<2021.1.2>` | ++---------------------------------+----------------------------------+---------------------------------------+----------------------------------+----------------------------------+----------------------------------+--------------------------------------------------------------------+ +| :ref:`2021.2<2021.2>` | :ref:`2021.2.0.1<2021.2.0.1>` |:ref:`2021.2.0.3<2021.2.0.3>` | :ref:`2021.2.1<2021.2.1>` | :ref:`2021.2.1.14<2021.2.1.14>` | :ref:`2021.2.1.16<2021.2.1.16>` | :ref:`2021.2.1.17<2021.2.1.17>` | ++---------------------------------+----------------------------------+---------------------------------------+----------------------------------+----------------------------------+----------------------------------+--------------------------------------------------------------------+ +| | :ref:`2021.2.1.18<2021.2.1.18>` |:ref:`2021.2.1.19<2021.2.1.19>` | :ref:`2021.2.1.20<2021.2.1.20>` | :ref:`2021.2.1.21<2021.2.1.21>` | :ref:`2021.2.1.22<2021.2.1.22>` | :ref:`2021.2.1.23<2021.2.1.23>` | ++---------------------------------+----------------------------------+---------------------------------------+----------------------------------+----------------------------------+----------------------------------+--------------------------------------------------------------------+ +| | :ref:`2021.1.1<2021.1.1>` | :ref:`2021.1.1.1<2021.1.1.1>` | :ref:`2021.2.1.8<2021.2.1.8>` | :ref:`2021.1.2<2021.1.2>` | ++---------------------------------+----------------------------------+---------------------------------------+----------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ | :ref:`2020.3<2020.3>` | :ref:`2020.3.1<2020.3.1>` | :ref:`2020.3.2.1<2020.3.2.1>` | +---------------------------------+----------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | :ref:`2020.2<2020.2>` | @@ -28,6 +28,7 @@ SQream releases notes are specific to each version of the application. Select yo +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + .. toctree:: :maxdepth: 2 :glob: From 3d355271ccd72d072a0ff399065fe1c754eb28f3 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 18 Jul 2022 14:11:49 +0300 Subject: [PATCH 118/316] Realignment --- releases/index.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/releases/index.rst b/releases/index.rst index acb32e800..19f447988 100644 --- a/releases/index.rst +++ b/releases/index.rst @@ -9,10 +9,10 @@ SQream releases notes are specific to each version of the application. Select yo | **Major Release** | **Minor Releases** | +---------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | :ref:`2022.1<2022.1>` | :ref:`2022.1.1<2022.1.1>` | -+---------------------------------+----------------------------------+---------------------------------------+----------------------------------+----------------------------------+-------------------------------------------------------------------------------------------------------+ -| :ref:`2021.1<2021.1>` | :ref:`2021.1.1<2021.1.1>` | :ref:`2021.1.1_rdb_1<2021.1.1_rdb_1>` | :ref:`2021.1.1.11<2021.1.1.11>` | :ref:`2021.1.1.2<2021.1.1.2>` | :ref:`2021.1.1.3<2021.1.1.3>` | -+---------------------------------+----------------------------------+---------------------------------------+----------------------------------+----------------------------------+-------------------------------------------------------------------------------------------------------+ -| :ref:`2021.1.1.1<2021.1.1.1>` | :ref:`2021.1.1.4<2021.1.1.4>` | :ref:`2021.1.1.6<2021.1.1.6>` | :ref:`2021.1.1.7<2021.1.1.7>` | :ref:`2021.1.2<2021.1.2>` | ++---------------------------------+----------------------------------+---------------------------------------+----------------------------------+----------------------------------+----------------------------------+--------------------------------------------------------------------+ +| :ref:`2021.1<2021.1>` | :ref:`2021.1.1<2021.1.1>` | :ref:`2021.1.1_rdb_1<2021.1.1_rdb_1>` | :ref:`2021.1.1.1<2021.1.1.1>` | :ref:`2021.1.1.11<2021.1.1.11>` | :ref:`2021.1.1.2<2021.1.1.2>` | :ref:`2021.1.1.3<2021.1.1.3>` | ++---------------------------------+----------------------------------+---------------------------------------+----------------------------------+----------------------------------+----------------------------------+--------------------------------------------------------------------+ +| | :ref:`2021.1.1.4<2021.1.1.4>` | :ref:`2021.1.1.6<2021.1.1.6>` | :ref:`2021.1.1.7<2021.1.1.7>` | :ref:`2021.1.2<2021.1.2>` | +---------------------------------+----------------------------------+---------------------------------------+----------------------------------+----------------------------------+----------------------------------+--------------------------------------------------------------------+ | :ref:`2021.2<2021.2>` | :ref:`2021.2.0.1<2021.2.0.1>` |:ref:`2021.2.0.3<2021.2.0.3>` | :ref:`2021.2.1<2021.2.1>` | :ref:`2021.2.1.14<2021.2.1.14>` | :ref:`2021.2.1.16<2021.2.1.16>` | :ref:`2021.2.1.17<2021.2.1.17>` | +---------------------------------+----------------------------------+---------------------------------------+----------------------------------+----------------------------------+----------------------------------+--------------------------------------------------------------------+ From 9695e6d138e6c3f5d517307beba45ec9d9eb6b1e Mon Sep 17 00:00:00 2001 From: YanivGerowitz <82020437+YanivGerowitz@users.noreply.github.com> Date: Tue, 19 Jul 2022 12:23:36 +0300 Subject: [PATCH 119/316] Add files via upload From abfd0bd98937971597d518df78ef719d5953724e Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 19 Jul 2022 12:27:49 +0300 Subject: [PATCH 120/316] Documented External Bugs for 2022.1 Reverted to original index table structure. Will reimplement new index table structure after filtering between external/internal bugs for 2021.1 and 2021.2. Need to filter and re-implement patch for 2022.1.1. All removed files saved in local folder: C:\Users\Yaniv\Desktop\Yaniv\Release Notes\2022.1\releases_new_structure_with_patches --- .../get_extents_file_list_for_chunk.rst | 22 +- .../get_metadata_chunk_key.rst | 4 +- releases/2020.3_index.rst | 17 +- releases/2021.1.1.1.rst | 32 --- releases/2021.1.1.rst | 71 ------ releases/2021.1_index.rst | 18 +- releases/2021.2.0.1.rst | 40 ---- releases/2021.2.1.1.rst | 28 --- releases/2021.2.1.22.rst | 26 --- releases/2021.2.1.23.rst | 26 --- releases/2021.2.1.24.rst | 57 ----- releases/2021.2_index.rst | 19 +- releases/2022.1.1.rst | 77 ------ releases/2022.1.rst | 221 +++--------------- releases/2022.1_index.rst | 20 -- releases/index.rst | 44 ++-- 16 files changed, 78 insertions(+), 644 deletions(-) delete mode 100644 releases/2021.1.1.1.rst delete mode 100644 releases/2021.1.1.rst delete mode 100644 releases/2021.2.0.1.rst delete mode 100644 releases/2021.2.1.1.rst delete mode 100644 releases/2021.2.1.22.rst delete mode 100644 releases/2021.2.1.23.rst delete mode 100644 releases/2021.2.1.24.rst delete mode 100644 releases/2022.1.1.rst delete mode 100644 releases/2022.1_index.rst diff --git a/reference/sql/sql_statements/utility_commands/get_extents_file_list_for_chunk.rst b/reference/sql/sql_statements/utility_commands/get_extents_file_list_for_chunk.rst index 3c05a48fe..968c0655a 100644 --- a/reference/sql/sql_statements/utility_commands/get_extents_file_list_for_chunk.rst +++ b/reference/sql/sql_statements/utility_commands/get_extents_file_list_for_chunk.rst @@ -53,8 +53,6 @@ Output ========== The following table describes the output generated from the ``GET_EXTENTS_FILE_FOR_CHUNK`` command: -Database name. table name, table id, column id, chunk id, file path - .. list-table:: :widths: 25 25 25 25 :header-rows: 1 @@ -81,31 +79,29 @@ Database name. table name, table id, column id, chunk id, file path * - ``column_id`` - The status of the chunk. - - **Comment** - *What is the type?* + - Numeric - ``1`` * - ``chunk_id`` - Describes the state of the chunk. - - **Comment** - *What is the type?* + - Numeric - ``chunk_state::`` * - ``file_path`` - Shows the path of the file. - Text - - **Comment** - *Provide example + - /home/sqream_testing_temp/sqreamdb/databases/master/tables The following is an example of the output generated from the ``GET_EXTENTS_FILE_FOR_CHUNK`` command: .. code-block:: postgres - master,public.t_1,0,0,3,/home/eyalw/sqream_testing_temp/sqreamdb/databases/master/tables/0/0/0-2 - master,public.t_1,0,1,3,/home/eyalw/sqream_testing_temp/sqreamdb/databases/master/tables/0/1/1-2 - master,public.t_1,0,2,3,/home/eyalw/sqream_testing_temp/sqreamdb/databases/master/tables/0/2/2-2 - master,public.t_1,0,3,3,/home/eyalw/sqream_testing_temp/sqreamdb/databases/master/tables/0/3/3-2 - master,public.t_1,0,4,3,/home/eyalw/sqream_testing_temp/sqreamdb/databases/master/tables/0/4/4-2 + master,public.t_1,0,0,3,/home/sqream_testing_temp/sqreamdb/databases/master/tables + master,public.t_1,0,1,3,/home/sqream_testing_temp/sqreamdb/databases/master/tables + master,public.t_1,0,2,3,/home/sqream_testing_temp/sqreamdb/databases/master/tables + master,public.t_1,0,3,3,/home/sqream_testing_temp/sqreamdb/databases/master/tables + master,public.t_1,0,4,3,/home/sqream_testing_temp/sqreamdb/databases/master/tables Permissions ============= -The ``GET_EXTENTS_FILE_FOR_CHUNK`` requires no special permissions. - -**Comment** - *Does it require any special permissions?* \ No newline at end of file +The ``GET_EXTENTS_FILE_FOR_CHUNK`` requires no special permissions. \ No newline at end of file diff --git a/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst b/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst index c43775de7..9c69d423f 100644 --- a/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst +++ b/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst @@ -148,6 +148,4 @@ The following is an example of the output generated from the ``GET_METADATA_CHUN Permissions ============= -The ``GET_METADATA_CHUNK_KEY`` requires no special permissions. - -**Comment** - *Does it require any special permissions?* \ No newline at end of file +The ``GET_METADATA_CHUNK_KEY`` requires no special permissions. \ No newline at end of file diff --git a/releases/2020.3_index.rst b/releases/2020.3_index.rst index 19bf3bd79..b13340b52 100644 --- a/releases/2020.3_index.rst +++ b/releases/2020.3_index.rst @@ -3,19 +3,16 @@ ************************** Release Notes 2020.3 ************************** -SQream releases notes are specific to each version of the application. Select your version from the table below to see the related release notes. +The 2020.3 Release Notes describe the following releases: -+---------------------------------+----------------------------------+------------------------------------------------------------------+ -| **Major Release** | **Minor Releases** | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+ -| :ref:`2020.3<2020.3>` | :ref:`2020.3.1<2020.3.1>` | :ref:`2020.3.2.1<2020.3.2.1>` | | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+ +.. contents:: + :local: + :depth: 1 .. toctree:: - :maxdepth: 2 + :maxdepth: 1 :glob: - :hidden: - 2020.3 + 2020.3.2.1 2020.3.1 - 2020.3.2.1 \ No newline at end of file + 2020.3 \ No newline at end of file diff --git a/releases/2021.1.1.1.rst b/releases/2021.1.1.1.rst deleted file mode 100644 index 2e562c858..000000000 --- a/releases/2021.1.1.1.rst +++ /dev/null @@ -1,32 +0,0 @@ -.. _2021.1.1.1: - -************************** -Release Notes 2021.1.1.1 -************************** -The 2021.1.1.1 release notes is a patch version released on 27/6/2022. - -The following table lists the issues that were resolved in Version 2021.1.1.1: - -.. list-table:: - :widths: 17 200 - :header-rows: 1 - - * - SQ No. - - Description - * - SQ-7045 - - Replace function doesn't support column value - * - SQ-7640 - - Some dates can't be recognized as a standard date format - * - SQ-7658 - - Can't perform "=" function between varchar(1) and text argument - * - SQ-7588 - - A thread that removes stuck open snapshots - -Version 2021.1.1.1 has no unresolved issues. - -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2021.1.1.1 \ No newline at end of file diff --git a/releases/2021.1.1.rst b/releases/2021.1.1.rst deleted file mode 100644 index 992b2f850..000000000 --- a/releases/2021.1.1.rst +++ /dev/null @@ -1,71 +0,0 @@ -.. _2021.1.1: - -************************** -Release Notes 2021.1.1 -************************** -The 2021.1.1 release notes were released on 7/27/2021 and describe the following: - -.. contents:: - :local: - :depth: 1 - -New Features -------------- -The 2021.1.1 Release Notes include the following new features: - -.. contents:: - :local: - :depth: 1 - -Complete Ranking Function Support -************ -SQream now supports the following new ranking functions: - -.. list-table:: - :widths: 1 23 76 - :header-rows: 1 - - * - Function - - Return Type - - Description - * - first_value - - Same type as value - - Returns the value in the first row of a window. - * - last_value - - Same type as value - - Returns the value in the last row of a window. - * - nth_value - - Same type as value - - Returns the value in a specified (``n``) row of a window. if the specified row does not exist, this function returns ``NULL``. - * - dense_rank - - bigint - - Returns the rank of the current row with no gaps. - * - percent_rank - - double - - Returns the relative rank of the current row. - * - cume_dist - - double - - Returns the cumulative distribution of rows. - * - ntile(buckets) - - integer - - Returns an integer ranging between ``1`` and the argument value, dividing the partitions as equally as possible. - -For more information, navigate to Windows Functions and scroll to the `Ranking Functions table `_. - - -Resolved Issues -------------- -The following list describes the resolved issues: - -* SQream did not support exporting and reading **Int64** columns as **bigint** in Parquet. This was fixed. -* The Decimal column was not supported when inserting data from Parquet files. This was fixed. -* Values in Parquet Numeric columns were not being converted correctly. This was fixed. -* Converting ``string`` data type to ``datetime`` was not working correctly. This was fixed. -* Casting ``datetime`` to ``text`` truncated the time. This was fixed. - -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2021.1.1 \ No newline at end of file diff --git a/releases/2021.1_index.rst b/releases/2021.1_index.rst index 0fa9d6ccf..64b06e1d1 100644 --- a/releases/2021.1_index.rst +++ b/releases/2021.1_index.rst @@ -3,20 +3,16 @@ ************************** Release Notes 2021.1 ************************** -SQream releases notes are specific to each version of the application. Select your version from the table below to see the related release notes. +The 2021.1 Release Notes describe the following releases: -+---------------------------------+----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Major Release** | **Minor Releases** | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------------+ -| :ref:`2021.1<2021.1>` | :ref:`2021.1.1<2021.1.1>` | :ref:`2021.1.1.1<2021.1.1.1>` | :ref:`2021.1.2<2021.1.2>` | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+------------------------------------------------------------------------------------------------------+ +.. contents:: + :local: + :depth: 1 .. toctree:: - :maxdepth: 2 + :maxdepth: 1 :glob: - :hidden: - 2021.1 + 2021.1.2 2021.1.1 - 2021.1.1.1 - 2021.1.2 \ No newline at end of file + 2021.1 \ No newline at end of file diff --git a/releases/2021.2.0.1.rst b/releases/2021.2.0.1.rst deleted file mode 100644 index 03edcad4e..000000000 --- a/releases/2021.2.0.1.rst +++ /dev/null @@ -1,40 +0,0 @@ -.. _2021.2.0.1: - -************************** -Release Notes 2021.2.0.1 -************************** -The 2021.2.0.1 release notes were released on x/x/xxxx and describe the following: - -The following table lists the issues that were resolved in Version 2021.2.0.1: - -.. list-table:: - :widths: 17 200 - :header-rows: 1 - - * - SQ No. - - Description - * - SQ-8345 - - Studio-How does a publicUser connect to a specified service? - * - SQ-8343 - - Running SQream from docker does not show configuration extended info - * - SQ-8294 - - Quote qualifier is not present in exported file thus file cannot be reloaded - * - SQ-8288 - - Support parameter TEXT casts - * - SQ-8272 - - `cleanup_chunk` creates garbage metadata, potentially leading to wrong results - * - SQ-8271 - - Saved query parameters of type text are not supported - * - SQ-8266 - - [LGE] Data loading issue depending to column order. // bad syntax (datetime type) - * - SQ-8266 - - [LGE] Data loading issue depending to column order. // bad syntax (datetime type) - -Version 2021.2.0.1 has no unresolved issues. - -.. toctree:: - :maxdepth: 3 - :glob: - :hidden: - - 2021.2.0.1 \ No newline at end of file diff --git a/releases/2021.2.1.1.rst b/releases/2021.2.1.1.rst deleted file mode 100644 index 65cf1b8a1..000000000 --- a/releases/2021.2.1.1.rst +++ /dev/null @@ -1,28 +0,0 @@ -.. _2021.2.1.1: - -****************************** -Release Notes 2021.2.1.1 -****************************** -The 2021.2.1.1 release notes is a patch version released on 9/12/2021. - -The following table lists the issues that were resolved in Version 2021.2.1.1: - -.. list-table:: - :widths: 17 200 - :header-rows: 1 - - * - SQ No. - - Description - * - SQ-9114 - - `cleanup_extents` on empty texts results in a missing file - * - SQ-8849 - - `Unclear "Map:at" error for invalid column mapping of Parquet files - -Version 2021.2.1.1 has no unresolved issues. - -.. toctree:: - :maxdepth: 3 - :glob: - :hidden: - - 2021.2.1.1 \ No newline at end of file diff --git a/releases/2021.2.1.22.rst b/releases/2021.2.1.22.rst deleted file mode 100644 index 62346a3c8..000000000 --- a/releases/2021.2.1.22.rst +++ /dev/null @@ -1,26 +0,0 @@ -.. _2021.2.1.22: - -****************************** -Release Notes 2021.2.1.22 -****************************** -The 2021.2.1.22 release notes is a patch version released on 13/6/2022. - -The following table lists the issues that were resolved in Version 2021.2.1.22: - -.. list-table:: - :widths: 17 200 - :header-rows: 1 - - * - SQ No. - - Description - * - SQ-10776 - - Out Of Memory invoked during copy from with multiple files. - -Version 2021.2.1.22 has no unresolved issues. - -.. toctree:: - :maxdepth: 4 - :glob: - :hidden: - - 2021.2.1.22 \ No newline at end of file diff --git a/releases/2021.2.1.23.rst b/releases/2021.2.1.23.rst deleted file mode 100644 index ca5e2dcbe..000000000 --- a/releases/2021.2.1.23.rst +++ /dev/null @@ -1,26 +0,0 @@ -.. _2021.2.1.23: - -****************************** -Release Notes 2021.2.1.23 -****************************** -The 2021.2.1.23 release notes is a patch version released on 27/6/2022. - -The following table lists the issues that were resolved in Version 2021.2.1.23: - -.. list-table:: - :widths: 17 200 - :header-rows: 1 - - * - SQ No. - - Description - * - SQ-10703 - - When the clause is specified, all existing permissions granted on source_table_name are granted on table_name as well. - -Version 2021.2.1.23 has no unresolved issues. - -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2021.2.1.23 \ No newline at end of file diff --git a/releases/2021.2.1.24.rst b/releases/2021.2.1.24.rst deleted file mode 100644 index cf4a2f391..000000000 --- a/releases/2021.2.1.24.rst +++ /dev/null @@ -1,57 +0,0 @@ -.. _2021.2.1.24: - -****************************** -Release Notes 2021.2.1.24 -****************************** -The 2021.2.1.24 release notes is a patch version released on xxxxxxxxxxxx. - -The following table lists the issues that were resolved in Version 2021.2.1.24.rst: - -+-------------+----------------------------------------------------------------------------------------------------------------------------------+ -| **SQ No.** | **Description** | -+=============+==================================================================================================================================+ -| SQ-9721 | pysqream - not finishing query | -+-------------+----------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10071 | error on exists subqueries with text and varchar equality condition | -+-------------+----------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10606 | [ACL] Queries getting stuck in the queue for a long time (Executing status) | -+-------------+----------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10691 | DB Schema identifier causes an error running some queries from joins suite - v2021.2.1_stable | -+-------------+----------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10843 | When getting "illegal memory access was encountered" error message worker does not crash, but fails every query afterwards. | -+-------------+----------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10879 | Performance | degradations in insert as select from ORC files | -+-------------+----------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10902 | test_copy_null_to_not_null[all_types-parquet] (from Generic Copy From) crashes sqreamd | -+-------------+----------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10918 | [SDC] WLM only assings jobs sequentially and it causes delay on user sqls when they are assigned to a worker running a huge job | -+-------------+----------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10955 | No metadata filters when filtering by nullable date using dateadd (LGU+) | -+-------------+----------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10963 | Extract File Reaper Mechanism To Separated Process | -+-------------+----------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10975 | Merging ACL's open snapshot functionality from V2021.1.1 to V2021.2.1.x | -+-------------+----------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10976 | Merging all V2021.1.X fixes/features to V2021.2&V2022.1.X | -+-------------+----------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11000 | DROP DATABASE fails to remove database path under sqreamdb and following creation commands is stuck | -+-------------+----------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11043 | correlated_subqueries_v1 test failed | -+-------------+----------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11055 | performance degradation - tpch10t - cases #1299, #1315, #1307 & #1297 | -+-------------+----------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11088 | specific worker compiling causes low performance | -+-------------+----------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11090 | SQream keeps the configuration flags where the query compiled and use it when the query is executed on a different worker | -+-------------+----------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11159 | Redesign the heartbeat timers, worker and metadata. | -+-------------+----------------------------------------------------------------------------------------------------------------------------------+ - -Version 2021.2.1.24 has no unresolved issues. - -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2021.2.1.24 \ No newline at end of file diff --git a/releases/2021.2_index.rst b/releases/2021.2_index.rst index 98a256bc2..77a22b0ae 100644 --- a/releases/2021.2_index.rst +++ b/releases/2021.2_index.rst @@ -3,22 +3,15 @@ ************************** Release Notes 2021.2 ************************** -SQream releases notes are specific to each version of the application. Select your version from the table below to see the related release notes. +The 2021.2 Release Notes describe the following releases: -+---------------------------------+----------------------------------+----------------------------------------------------------------------------------------------------+---------------------------------+---------------------------------+----------------------------------+ -| **Major Release** | **Minor Releases** | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+------------------------------------------------------------------------------------------------------+ -| :ref:`2021.2<2021.2>` | :ref:`2021.2.0.1<2021.2.0.1>` | :ref:`2021.2.1<2021.2.1>` | :ref:`2021.2.1.1<2021.2.1.1>` | :ref:`2021.2.1.22<2021.2.1.22>` | :ref:`2021.2.1.23<2021.2.1.23>` | -+---------------------------------+----------------------------------+--------------------------------+---------------------------------+---------------------------------+---------------------------------+---------------------------------+----------------------------------+ +.. contents:: + :local: + :depth: 1 .. toctree:: - :maxdepth: 2 + :maxdepth: 1 :glob: - :hidden: - 2021.2 - 2021.2.0.1 2021.2.1 - 2021.2.1.1 - 2021.2.1.22 - 2021.2.1.23 \ No newline at end of file + 2021.2 \ No newline at end of file diff --git a/releases/2022.1.1.rst b/releases/2022.1.1.rst deleted file mode 100644 index 081d608f2..000000000 --- a/releases/2022.1.1.rst +++ /dev/null @@ -1,77 +0,0 @@ -.. _2022.1.1: - -************************** -Release Notes 2022.1.1 -************************** -The 2022.1.1 release notes were released on x/x/xxxx and describe the following: - -The following table lists the issues that were resolved in Version 2022.1.1: - -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| **SQ No.** | **Description** | -+=============+==================================================================================================================================================+ -| SQ-6419 | Internal compiler error when casting numeric literal in aggregation function | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-9771 | The error returns different value when trying to insert date value without quotes. | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10100 | Implicit/Explicit cast from int/tinyint/bigint to bool is not working | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10741 | Got difference in execution time when ingesting data | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10772 | Internal Runtime Error when creating a text column with a limit characters size >= 1 and 30 zeros | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10790 | copy from with '*' (wildcard) from parquet is 3X slower than CSV | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10793 | Implement "Brute Force" Protection policy for the system login | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10816 | Data management on Big Table | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10838 | Repeat function throws an exception when entered a negative number | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10840 | UF - list all files related to chunk id, Get specific chunk key values | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10852 | Password Strength Check | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10863 | Performance | LGU | high SD in the duration of 'insert as select' query | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10873 | Inserting 100K bytes to a text column results in unclear error message | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10886 | Error in compilation process: : "Internal compiler error: | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10892 | Update || change error message when trying to run update on foreign table | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10899 | Cannot change the value of diskSpaceMinFreePercent - it is hard coded to 10% | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10919 | Automatic Foreign Table DDL Resolution | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10955 | No metadata filters when filtering by nullable date using dateadd (LGU+) | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10956 | Exception: "Could not read view.." - recompile and recreate doesn't help | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10963 | Extract File Reaper Mechanism To Separated Process | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10976 | Merging all V2021.1.X fixes/features to V2021.2&V2022.1.X | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10980 | sqream crashing when executing copy from avro (negative case copy file to unmatched column table) | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10988 | [SDC] stop_statement() doesn't work on jobs in queue | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11014 | Different float values between sqream and postgress | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11121 | Merging ACL's open snapshot functionality from V2021.1.1 to v2022.1.x code line | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11137 | CLONE - When getting "illegal memory access was encountered" error message worker does not crash, but fails every query afterwards. - AUTOMATIC | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11154 | After SQ-10980 fix, there is wrong error raised ("OVERFLOW exception") instead of "Tried inserting AVRO non-decimal" | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11158 | [ACL] Datediff doesn't work with specific dates - returns "Cast overflow" | -+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------+ - -Version 2022.1.1 has no unresolved issues. - -.. toctree:: - :maxdepth: 3 - :glob: - :hidden: - - 2022.1.1 \ No newline at end of file diff --git a/releases/2022.1.rst b/releases/2022.1.rst index 74e568fad..b6ffdf9ef 100644 --- a/releases/2022.1.rst +++ b/releases/2022.1.rst @@ -3,7 +3,7 @@ ************************** Release Notes 2022.1 ************************** -The 2022.1 release notes were released on x/xx/2022 and describe the following: +The 2022.1 release notes were released on 7/19/2022 and describe the following: .. contents:: :local: @@ -56,191 +56,35 @@ The following two new utility commands have been created: * `GET_METADATA_CHUNK_KEY `_ - returns specific metadata key values for user-specified chunks. +Known Issues +--------- +The following table lists the known issues for Version 2022.1: + ++-------------+-------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+===========================================================================================+ +| SQ-7732 | Reading numeric columns from an external Parquet file generated an error. | ++-------------+-------------------------------------------------------------------------------------------+ +| SQ-9889 | Running a query including Thai characters generated an internal runtime error. | ++-------------+-------------------------------------------------------------------------------------------+ +| SQ-10071 | error on exists subqueries with text and varchar equality condition | ++-------------+-------------------------------------------------------------------------------------------+ +| SQ-10191 | The ``ALTER DEFAULT SCHEMA`` command was not functioning correctly. | ++-------------+-------------------------------------------------------------------------------------------+ +| SQ-10629 | Inserting data into a table significantly slowed down running queries. | ++-------------+-------------------------------------------------------------------------------------------+ +| SQ-10659 | Using a comment generated a compile error. | ++-------------+-------------------------------------------------------------------------------------------+ + Resolved Issues --------- The following table lists the issues that were resolved in Version 2022.1: -**Comment** - *The items in the table below must be filtered according to external and internal bugs. We CANNOT expose internal bugs to external users.* - -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| **SQ No.** | **Description** | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-7490 | Native Avro file access via a dedicated FDW | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-7718 | Certify LTS Ubuntu versions (18.04 & 20.04) for production usage | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-7732 | Fail to read numeric columns from an external generated parquet file | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-8163 | Performance degradation - tpch1t_external_table_parquet - cases #6079 & #6105 | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-8182 | Encryption Function | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-8984 | Update statement MVP: literal assignment | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-9221 | [Mobicom] PBI - External Tables are not shown on the tables list. | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-9611 | Create a WIN-874 to UTF-8 conversion function | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-9634 | identifier not found | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-9644 | [ACL] Incomplete logs query causing Internal Runtime Error | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-9671 | Trying to read Thai UTF-8 csv file in TEXT column and it not shows Thai | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-9764 | No error when create a foreign table with difference in the column numbers in the table and the file | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-9790 | Encryption - MVP scope | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-9808 | Allowing to set deferredValueIOThresholdFactor flag not in developer Mode=true | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-9823 | [AIS] The user can't use literals when using sqream with Thai varchar | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-9889 | [AIS] Internal runtime Error receive | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-9952 | Removing temp files takes too long - timeout issue at LGU+ | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-9988 | Find a proper solution for data lost during copy from parquet - without reverting previous optimization | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-9990 | Merge v2021.2.1_stable into develop | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10005 | Go / No Go approvals | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10011 | Delete filter optimization chicken flag | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10055 | [SamsungDisplay] Slow loading of sqream after backup compacting | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10061 | compiler side - Implement MVP scope | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10071 | error on exists subqueries with text and varchar equality condition | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10111 | Parquet numeric - Sqream can't import parquet numeric columns from other sources | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10191 | [LGE] ALTER DEFAULT SCHEMA command has a problem. | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10216 | Performance degradation - tpch1t_1mchunk - case #1326 #1345 | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10242 | socket 11 error from "Create as Select~" | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10269 | cleanup_chunk error with text(X) column | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10314 | Unable to load avro file to sqream v1 + v2 from s3 | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10319 | Error on copy from avro file with numeric data | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10425 | Lot of time in copy from, external table parquet file | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10428 | [LGU] Can not execute cleanup_extents on table because there are mixed chunks | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10470 | count distinct on 0 rows doesn't return any value | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10478 | get_ddl disregards encrypted columns | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10479 | create a table with more than three encrypted column with no error | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10492 | Wrong values when select from table have encrypted column and regular column | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10494 | No “encrypted” label when read from table with encrypted column | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10496 | Not able to insert data to encrypted column after performing delete on the column | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10514 | No error when create table with encrypted column for the unsupported data types | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10515 | Run time error when decrypt 1 million rows | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10518 | create foreign table with encrypted column with no error | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10532 | Get Read time out error when try to read avro to wrong ddl (Frozen client) | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10534 | Wrong error message when copy null values from avro file to not null ddl (Overflow case instead null to not null) | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10551 | No error when add encrypt column to already existing table | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10585 | [V1] ORC Numeric reading - Overflow error | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10586 | SQream crashed when encrypt 1 billion rows | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10593 | Seg fault when inserting AVRO non-decimal value to Numeric type | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10594 | Some of configuration flags are displaced in default config | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10613 | Samsung test fail on branch v2022.1_stable | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10629 | Different join type between SELECT (Left) vs INSERT INTO SELECT (Left cross) | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10631 | Performance degradation - copies - copy_nvarchar40.sql - case #4556 | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10632 | Performance degradation - insert_as_select - insert_as_select_parquet_int.sql - case #4971 | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10655 | Performance degradation- some queries that perform COPY FROM - case #4624 | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10656 | Performance degradation - insert_as_select - #4971 & #4984 | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10659 | [SDC] Compile Error when using comment | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10665 | AWS V2 - Files are not deleted from S3 storage after DROP database and DROP table | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10667 | Log file not created when execute copy from avro | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10677 | Different results between subquery and physical table | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10692 | Internal Runtime Error when decrypt 1 million rows of text data type | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10695 | when ingest 100 million data into table with 3 encrypted column it took time more than expected | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10716 | Error on copy from avro (Expected auto cast) | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10734 | nvarchar_backward_comp1 failed in regression on branch v2022.1_stable | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10735 | numeric_upgrade_storage has failed in regression on v2022.1_stable | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10738 | Sqream worker on GPU id 1 consume also from GPU id 0 | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10745 | compiler_tests failed in regression on v2022.1_stable | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10776 | Out Of Memory invoked during copy from with multiple files | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10813 | Copy To - The statement doesn't working when I use with 'Avro' format for location='s3....' | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10823 | window_functions_part1 failed in regression in develop | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10855 | CLONE - UF - list all files related to chunk id, Get specific chunk key values | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10869 | Enable/Disable encryption by default | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10871 | Copy To - Getting an error when missing file_name in the end of the path at the location field(This happen only at Avro format) | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10877 | Avro not implemented on stable version v2022 s3 | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10885 | Filter on Delete - should be tested | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10889 | v2022.1_stable => Internal compiler error: Bad encryption type | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10895 | [AIS] behavior is not consistent when the user using Literals with Thai varchar WIN-874 or Thai text UTF-8 | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10902 | test_copy_null_to_not_null[all_types-parquet] (from Generic Copy From) crashes sqreamd | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10916 | [AIS] varcharEncoding": "WINDOWS-874" Flag should work NOT ONLY in Developer mode | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10938 | REGEXP_REPLACE is not supported in 2022 version | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10962 | Using Thai Literals on v2022 with Text type output shows bad results ONLY ON Clientcmd | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10987 | [AIS] The system not allowing to control the update permissions - Grant update permission | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10999 | File tracker error logs on Sqream with MD - insert & select queries | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11043 | correlated_subqueries_v1 test failed | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11063 | Migration of Varchar to Text - keep the size of Varchar after the migration to the text type. | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11101 | Show locks test failed in regression for v2022.1 | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11109 | User can't change his own password using the UI | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11168 | Migration script on 1B rows table and 8 columns output with Internal run time error. | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11170 | Create a tool for migrating a Varchar table to Text | -+------------+-------------------------------------------------------------------------------------------------------------------------------------+ ++-------------+-------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+===========================================================================================+ +| SQ-10111 | Reading numeric columns from an external Parquet file generated an error. | ++-------------+-------------------------------------------------------------------------------------------+ Operations and Configuration Changes -------- @@ -256,20 +100,9 @@ In SQream version 2022.1 the ``VARCHAR`` data type has been deprecated and repla If you are using an earlier version of SQream, see the `Using Legacy String Literals `_ configuration flag. -Known Issues and Limitations --------- -**Comment** - *TBD* - -The the list below describes the following known issues and limitations: - -* Text -* Text - End of Support ------- -**Comment** - *We need to know what to put here.* - -This section is not relevant to the 2022.1 release notes. +The End of Support section is not relevant to Version 2022.1. Upgrading to v2022.1 ------- diff --git a/releases/2022.1_index.rst b/releases/2022.1_index.rst deleted file mode 100644 index 6393d5511..000000000 --- a/releases/2022.1_index.rst +++ /dev/null @@ -1,20 +0,0 @@ -.. _2022.1_index: - -************************** -Release Notes 2022.1 -************************** -The 2022.1 Release Notes describe the following releases: - -+---------------------------------+----------------------------------+ -| **Major Release** | **Minor Releases** | -+---------------------------------+----------------------------------+ -| :ref:`2022.1<2022.1>` | :ref:`2022.1.1<2022.1.1>` | -+---------------------------------+----------------------------------+ - -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2022.1 - 2022.1.1 \ No newline at end of file diff --git a/releases/index.rst b/releases/index.rst index 19f447988..b1d065a9e 100644 --- a/releases/index.rst +++ b/releases/index.rst @@ -3,29 +3,27 @@ ********** Release Notes ********** -SQream releases notes are specific to each version of the application. Select your version from the table below to see the related release notes. -+---------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| **Major Release** | **Minor Releases** | -+---------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| :ref:`2022.1<2022.1>` | :ref:`2022.1.1<2022.1.1>` | -+---------------------------------+----------------------------------+---------------------------------------+----------------------------------+----------------------------------+----------------------------------+--------------------------------------------------------------------+ -| :ref:`2021.1<2021.1>` | :ref:`2021.1.1<2021.1.1>` | :ref:`2021.1.1_rdb_1<2021.1.1_rdb_1>` | :ref:`2021.1.1.1<2021.1.1.1>` | :ref:`2021.1.1.11<2021.1.1.11>` | :ref:`2021.1.1.2<2021.1.1.2>` | :ref:`2021.1.1.3<2021.1.1.3>` | -+---------------------------------+----------------------------------+---------------------------------------+----------------------------------+----------------------------------+----------------------------------+--------------------------------------------------------------------+ -| | :ref:`2021.1.1.4<2021.1.1.4>` | :ref:`2021.1.1.6<2021.1.1.6>` | :ref:`2021.1.1.7<2021.1.1.7>` | :ref:`2021.1.2<2021.1.2>` | -+---------------------------------+----------------------------------+---------------------------------------+----------------------------------+----------------------------------+----------------------------------+--------------------------------------------------------------------+ -| :ref:`2021.2<2021.2>` | :ref:`2021.2.0.1<2021.2.0.1>` |:ref:`2021.2.0.3<2021.2.0.3>` | :ref:`2021.2.1<2021.2.1>` | :ref:`2021.2.1.14<2021.2.1.14>` | :ref:`2021.2.1.16<2021.2.1.16>` | :ref:`2021.2.1.17<2021.2.1.17>` | -+---------------------------------+----------------------------------+---------------------------------------+----------------------------------+----------------------------------+----------------------------------+--------------------------------------------------------------------+ -| | :ref:`2021.2.1.18<2021.2.1.18>` |:ref:`2021.2.1.19<2021.2.1.19>` | :ref:`2021.2.1.20<2021.2.1.20>` | :ref:`2021.2.1.21<2021.2.1.21>` | :ref:`2021.2.1.22<2021.2.1.22>` | :ref:`2021.2.1.23<2021.2.1.23>` | -+---------------------------------+----------------------------------+---------------------------------------+----------------------------------+----------------------------------+----------------------------------+--------------------------------------------------------------------+ -| | :ref:`2021.1.1<2021.1.1>` | :ref:`2021.1.1.1<2021.1.1.1>` | :ref:`2021.2.1.8<2021.2.1.8>` | :ref:`2021.1.2<2021.1.2>` | -+---------------------------------+----------------------------------+---------------------------------------+----------------------------------+------------------------------------------------------------------------------------------------------------------------------------------+ -| :ref:`2020.3<2020.3>` | :ref:`2020.3.1<2020.3.1>` | :ref:`2020.3.2.1<2020.3.2.1>` | -+---------------------------------+----------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| :ref:`2020.2<2020.2>` | -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| :ref:`2020.1<2020.1>` | -+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + +.. list-table:: + :widths: auto + :header-rows: 1 + + + * - Version + - Release Date + * - :ref:`2022.1` + - July 19, 2022 + * - :ref:`2021.2` + - September 13, 2021 + * - :ref:`2021.1` + - June 13, 2021 + * - :ref:`2020.3` + - October 8, 2020 + * - :ref:`2020.2` + - July 22, 2020 + * - :ref:`2020.1` + - January 15, 2020 @@ -34,7 +32,7 @@ SQream releases notes are specific to each version of the application. Select yo :glob: :hidden: - 2022.1_index + 2022.1 2021.2_index 2021.1_index 2020.3_index From ce03a5ea5bb41dab92621fb5a335db6b0a4710b5 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 19 Jul 2022 14:02:36 +0300 Subject: [PATCH 121/316] Update get_metadata_chunk_key.rst --- .../utility_commands/get_metadata_chunk_key.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst b/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst index 9c69d423f..08eba8345 100644 --- a/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst +++ b/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst @@ -78,12 +78,12 @@ The following table describes the output generated from the ``GET_METADATA_CHUNK * - ``chunk_status`` - The status of the chunk. - - **Comment** - *What is the type?* + - Numeric - ``1`` * - ``chunk_aligned`` - Describes the state of the chunk. - - **Comment** - *What is the type?* + - Text - ``chunk_state::`` * - ``offset_in_file`` From 74a04f3e7196aae9457c44457b182980602d953a Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 19 Jul 2022 17:24:35 +0300 Subject: [PATCH 122/316] Implementing SQ-10818 on live branch (testing) https://sqream.atlassian.net/browse/SQ-10818 If works correctly, will implement on all other live branches. --- reference/catalog_reference.rst | 610 +----------------- .../catalog_reference_additonal_tables.rst | 120 ++++ .../catalog_reference_catalog_tables.rst | 455 +++++++++++++ reference/catalog_reference_examples.rst | 64 ++ reference/catalog_reference_overview.rst | 11 + .../catalog_reference_schema_information.rst | 62 ++ .../alter_default_permissions.rst | 76 ++- 7 files changed, 782 insertions(+), 616 deletions(-) create mode 100644 reference/catalog_reference_additonal_tables.rst create mode 100644 reference/catalog_reference_catalog_tables.rst create mode 100644 reference/catalog_reference_examples.rst create mode 100644 reference/catalog_reference_overview.rst create mode 100644 reference/catalog_reference_schema_information.rst diff --git a/reference/catalog_reference.rst b/reference/catalog_reference.rst index 8cfa8e832..8fc0593b8 100644 --- a/reference/catalog_reference.rst +++ b/reference/catalog_reference.rst @@ -1,606 +1,16 @@ .. _catalog_reference: ************************************* -Catalog reference +Catalog Reference Guide ************************************* +The **Catalog Reference Guide** describes the following: -SQream DB contains a schema called ``sqream_catalog`` that contains information about your database's objects - tables, columns, views, permissions, and more. +.. toctree:: + :maxdepth: 1 + :glob: -Some additional catalog tables are used primarily for internal introspection, which could change across SQream DB versions. - - -.. contents:: In this topic: - :local: - -Types of data exposed by ``sqream_catalog`` -============================================== - -.. list-table:: Database objects - :widths: auto - :header-rows: 1 - - * - Object - - Table - * - Clustering keys - - ``clustering_keys`` - * - Columns - - ``columns``, ``external_table_columns`` - * - Databases - - ``databases`` - * - Permissions - - ``table_permissions``, ``database_permissions``, ``schema_permissions``, ``permission_types``, ``udf_permissions`` - * - Roles - - ``roles``, ``roles_memeberships`` - * - Schemas - - ``schemas`` - * - Sequences - - ``identity_key`` - * - Tables - - ``tables``, ``external_tables`` - * - Views - - ``views`` - * - UDFs - - ``user_defined_functions`` - -The catalog contains a few more tables which contain storage details for internal use - -.. list-table:: Storage objects - :widths: auto - :header-rows: 1 - - * - Object - - Table - * - Extents - - ``extents`` - * - Chunks - - ``chunks`` - * - Delete predicates - - ``delete_predicates`` - -Tables in the catalog -======================== - -clustering_keys ------------------------ - -Explicit clustering keys for tables. - -When more than one clustering key is defined, each key is listed in a separate row. - - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Column - - Description - * - ``database_name`` - - Name of the database containing the table - * - ``table_id`` - - ID of the table containing the column - * - ``schema_name`` - - Name of the schema containing the table - * - ``table_name`` - - Name of the table containing the column - * - ``clustering_key`` - - Name of the column that is a clustering key for this table - -columns --------- - -Column objects for standard tables - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Column - - Description - * - ``database_name`` - - Name of the database containing the table - * - ``schema_name`` - - Name of the schema containing the table - * - ``table_id`` - - ID of the table containing the column - * - ``table_name`` - - Name of the table containing the column - * - ``column_id`` - - Ordinal of the column in the table (begins at 0) - * - ``column_name`` - - Name of the column - * - ``type_name`` - - :ref:`Data type ` of the column - * - ``column_size`` - - The maximum length in bytes. - * - ``has_default`` - - ``NULL`` if the column has no default value. ``1`` if the default is a fixed value, or ``2`` if the default is an :ref:`identity` - * - ``default_value`` - - :ref:`Default value` for the column - * - ``compression_strategy`` - - User-overridden compression strategy - * - ``created`` - - Timestamp when the column was created - * - ``altered`` - - Timestamp when the column was last altered - - -.. _external_tables_table: - -external_tables ----------------- - -``external_tables`` identifies external tables in the database. - -For ``TABLES`` see :ref:`tables ` - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Column - - Description - * - ``database_name`` - - Name of the database containing the table - * - ``table_id`` - - Database-unique ID for the table - * - ``schema_name`` - - Name of the schema containing the table - * - ``table_name`` - - Name of the table - * - ``format`` - - - Identifies the foreign data wrapper used. - - ``0`` for csv_fdw, ``1`` for parquet_fdw, ``2`` for orc_fdw. - - * - ``created`` - - Identifies the clause used to create the table - -external_table_columns ------------------------- - -Column objects for external tables - -databases ------------ - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Column - - Description - * - ``database_Id`` - - Unique ID of the database - * - ``database_name`` - - Name of the database - * - ``default_disk_chunk_size`` - - Internal use - * - ``default_process_chunk_size`` - - Internal use - * - ``rechunk_size`` - - Internal use - * - ``storage_subchunk_size`` - - Internal use - * - ``compression_chunk_size_threshold`` - - Internal use - -database_permissions ----------------------- - -``database_permissions`` identifies all permissions granted to databases. - -There is one row for each combination of role (grantee) and permission granted to a database. - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Column - - Description - * - ``database_name`` - - Name of the database the permission applies to - * - ``role_id`` - - ID of the role granted permissions (grantee) - * - ``permission_type`` - - Identifies the permission type - - -identity_key --------------- - - -permission_types ------------------- - -``permission_types`` Identifies the permission names that exist in the database. - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Column - - Description - * - ``permission_type_id`` - - ID of the permission type - * - ``name`` - - Name of the permission type - -roles ------- - -``roles`` identifies the roles in the database. - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Column - - Description - * - ``role_id`` - - Database-unique ID of the role - * - ``name`` - - Name of the role - * - ``superuser`` - - Identifies if this role is a superuser. ``1`` for superuser or ``0`` otherwise. - * - ``login`` - - Identifies if this role can be used to log in to SQream DB. ``1`` for yes or ``0`` otherwise. - * - ``has_password`` - - Identifies if this role has a password. ``1`` for yes or ``0`` otherwise. - * - ``can_create_function`` - - Identifies if this role can create UDFs. ``1`` for yes, ``0`` otherwise. - -roles_memberships -------------------- - -``roles_memberships`` identifies the role memberships in the database. - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Column - - Description - * - ``role_id`` - - Role ID - * - ``member_role_id`` - - ID of the parent role from which this role will inherit - * - ``inherit`` - - Identifies if permissions are inherited. ``1`` for yes or ``0`` otherwise. - -savedqueries ----------------- - -``savedqueries`` identifies the :ref:`saved_queries` in the database. - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Column - - Description - * - ``name`` - - Saved query name - * - ``num_parameters`` - - Number of parameters to be replaced at run-time - -schemas ----------- - -``schemas`` identifies all the database's schemas. - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Column - - Description - * - ``schema_id`` - - Unique ID of the schema - * - ``schema_name`` - - Name of the schema - * - ``schema_owner`` - - Name of the role who owns this schema - * - ``rechunker_ignore`` - - Internal use - - -schema_permissions --------------------- - -``schema_permissions`` identifies all permissions granted to schemas. - -There is one row for each combination of role (grantee) and permission granted to a schema. - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Column - - Description - * - ``database_name`` - - Name of the database containing the schema - * - ``schema_id`` - - ID of the schema the permission applies to - * - ``role_id`` - - ID of the role granted permissions (grantee) - * - ``permission_type`` - - Identifies the permission type - - -.. _tables_table: - -tables ----------- - -``tables`` identifies proper SQream tables in the database. - -For ``EXTERNAL TABLES`` see :ref:`external_tables ` - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Column - - Description - * - ``database_name`` - - Name of the database containing the table - * - ``table_id`` - - Database-unique ID for the table - * - ``schema_name`` - - Name of the schema containing the table - * - ``table_name`` - - Name of the table - * - ``row_count_valid`` - - Identifies if the ``row_count`` can be used - * - ``row_count`` - - Number of rows in the table - * - ``rechunker_ignore`` - - Internal use - - -table_permissions ------------------- - -``table_permissions`` identifies all permissions granted to tables. - -There is one row for each combination of role (grantee) and permission granted to a table. - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Column - - Description - * - ``database_name`` - - Name of the database containing the table - * - ``table_id`` - - ID of the table the permission applies to - * - ``role_id`` - - ID of the role granted permissions (grantee) - * - ``permission_type`` - - Identifies the permission type - - -udf_permissions ------------------- - -user_defined_functions -------------------------- - -``user_defined_functions`` identifies UDFs in the database. - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Column - - Description - * - ``database_name`` - - Name of the database containing the view - * - ``function_id`` - - Database-unique ID for the UDF - * - ``function_name`` - - Name of the UDF - -views -------- - -``views`` identifies views in the database. - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Column - - Description - * - ``view_id`` - - Database-unique ID for the view - * - ``view_schema`` - - Name of the schema containing the view - * - ``view_name`` - - Name of the view - * - ``view_data`` - - Internal use - * - ``view_query_text`` - - Identifies the ``AS`` clause used to create the view - - -Additional tables -====================== - -There are additional tables in the catalog that can be used for performance monitoring and inspection. - -The definition for these tables is provided below could change across SQream DB versions. - -extents ----------- - -``extents`` identifies storage extents. - -Each storage extents can contain several chunks. - -.. note:: This is an internal table designed for low-level performance troubleshooting. - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Column - - Description - * - ``database_name`` - - Name of the databse containing the extent - * - ``table_id`` - - ID of the table containing the extent - * - ``column_id`` - - ID of the column containing the extent - * - ``extent_id`` - - ID for the extent - * - ``size`` - - Extent size in megabytes - * - ``path`` - - Full path to the extent on the file system - -chunk_columns -------------------- - -``chunk_columns`` lists chunk information by column. - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Column - - Description - * - ``database_name`` - - Name of the databse containing the extent - * - ``table_id`` - - ID of the table containing the extent - * - ``column_id`` - - ID of the column containing the extent - * - ``chunk_id`` - - ID for the chunk - * - ``extent_id`` - - ID for the extent - * - ``compressed_size`` - - Actual chunk size in bytes - * - ``uncompressed_size`` - - Uncompressed chunk size in bytes - * - ``compression_type`` - - Actual compression scheme for this chunk - * - ``long_min`` - - Minimum numeric value in this chunk (if exists) - * - ``long_max`` - - Maximum numeric value in this chunk (if exists) - * - ``string_min`` - - Minimum text value in this chunk (if exists) - * - ``string_max`` - - Maximum text value in this chunk (if exists) - * - ``offset_in_file`` - - Internal use - -.. note:: This is an internal table designed for low-level performance troubleshooting. - -chunks -------- - -``chunks`` identifies storage chunks. - -.. note:: This is an internal table designed for low-level performance troubleshooting. - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Column - - Description - * - ``database_name`` - - Name of the databse containing the chunk - * - ``table_id`` - - ID of the table containing the chunk - * - ``column_id`` - - ID of the column containing the chunk - * - ``rows_num`` - - Amount of rows contained in the chunk - * - ``deletion_status`` - - When data is deleted from the table, it is first deleted logically. This value identifies how much data is deleted from the chunk. ``0`` for no data, ``1`` for some data, ``2`` to specify the entire chunk is deleted. - -delete_predicates -------------------- - -``delete_predicates`` identifies the existing delete predicates that have not been cleaned up. - -Each :ref:`DELETE ` command may result in several entries in this table. - -.. note:: This is an internal table designed for low-level performance troubleshooting. - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Column - - Description - * - ``database_name`` - - Name of the databse containing the predicate - * - ``table_id`` - - ID of the table containing the predicate - * - ``max_chunk_id`` - - Internal use. Placeholder marker for the highest ``chunk_id`` logged during the DELETE operation. - * - ``delete_predicate`` - - Identifies the DELETE predicate - - -Examples -=========== - -List all tables in the database ----------------------------------- - -.. code-block:: psql - - master=> SELECT * FROM sqream_catalog.tables; - database_name | table_id | schema_name | table_name | row_count_valid | row_count | rechunker_ignore - --------------+----------+-------------+----------------+-----------------+-----------+----------------- - master | 1 | public | nba | true | 457 | 0 - master | 12 | public | cool_dates | true | 5 | 0 - master | 13 | public | cool_numbers | true | 9 | 0 - master | 27 | public | jabberwocky | true | 8 | 0 - -List all schemas in the database ------------------------------------- - -.. code-block:: psql - - master=> SELECT * FROM sqream_catalog.schemas; - schema_id | schema_name | schema_owner | rechunker_ignore - ----------+---------------+--------------+----------------- - 0 | public | sqream | false - 1 | secret_schema | mjordan | false - - -List columns and their types for a specific table ---------------------------------------------------- - -.. code-block:: postgres - - SELECT column_name, type_name - FROM sqream_catalog.columns - WHERE table_name='cool_animals'; - -List delete predicates ------------------------- - -.. code-block:: postgres - - SELECT t.table_name, d.* FROM - sqream_catalog.delete_predicates AS d - INNER JOIN sqream_catalog.tables AS t - ON d.table_id=t.table_id; - - -List :ref:`saved_queries` ------------------------------ - -.. code-block:: postgres - - SELECT * FROM sqream_catalog.savedqueries; + catalog_reference_overview + catalog_reference_schema_information + catalog_reference_catalog_tables + catalog_reference_additonal_tables + catalog_reference_examples \ No newline at end of file diff --git a/reference/catalog_reference_additonal_tables.rst b/reference/catalog_reference_additonal_tables.rst new file mode 100644 index 000000000..7d34429d3 --- /dev/null +++ b/reference/catalog_reference_additonal_tables.rst @@ -0,0 +1,120 @@ +.. _catalog_reference_additonal_tables: + +************************************* +Additional Tables +************************************* +The Reference Catalog includes additional tables that can be used for performance monitoring and inspection. The definition for these tables described on this page may change across SQream versions. + +.. contents:: + :local: + :depth: 1 + +Extents +---------- +The ``extents`` storage object identifies storage extents, and each storage extents can contain several chunks. + +.. note:: This is an internal table designed for low-level performance troubleshooting. + +.. list-table:: + :widths: 20 180 + :header-rows: 1 + + * - Column + - Description + * - ``database_name`` + - Shows the name of the databse containing the extent. + * - ``table_id`` + - Shows the ID of the table containing the extent. + * - ``column_id`` + - Shows the ID of the column containing the extent. + * - ``extent_id`` + - Shows the ID for the extent. + * - ``size`` + - Shows the extent size in megabytes. + * - ``path`` + - Shows the full path to the extent on the file system. + +Chunk Columns +------------------- +The ``chunk_columns`` storage object lists chunk information by column. + +.. list-table:: + :widths: 20 180 + :header-rows: 1 + + * - Column + - Description + * - ``database_name`` + - Shows the name of the databse containing the extent. + * - ``table_id`` + - Shows the ID of the table containing the extent. + * - ``column_id`` + - Shows the ID of the column containing the extent. + * - ``chunk_id`` + - Shows the chunk ID. + * - ``extent_id`` + - Shows the extent ID. + * - ``compressed_size`` + - Shows the compressed chunk size in bytes. + * - ``uncompressed_size`` + - Shows the uncompressed chunk size in bytes. + * - ``compression_type`` + - Shows the chunk's actual compression scheme. + * - ``long_min`` + - Shows the minimum numeric value in the chunk (if one exists). + * - ``long_max`` + - Shows the maximum numeric value in the chunk (if one exists). + * - ``string_min`` + - Shows the minimum text value in the chunk (if one exists). + * - ``string_max`` + - Shows the maximum text value in the chunk (if one exists). + * - ``offset_in_file`` + - Reserved for internal use. + +.. note:: This is an internal table designed for low-level performance troubleshooting. + +Chunks +------- +The ``chunks`` storage object identifies storage chunks. + +.. list-table:: + :widths: 20 180 + :header-rows: 1 + + * - Column + - Description + * - ``database_name`` + - Shows the name of the databse containing the chunk. + * - ``table_id`` + - Shows the ID of the table containing the chunk. + * - ``column_id`` + - Shows the ID of the column containing the chunk. + * - ``rows_num`` + - Shows the amount of rows in the chunk. + * - ``deletion_status`` + - Determines what data to logically delete from the table first, and identifies how much data to delete from the chunk. The value ``0`` is ued for no data, ``1`` for some data, and ``2`` to delete the entire chunk. + +.. note:: This is an internal table designed for low-level performance troubleshooting. + +Delete Predicates +------------------- +The ``delete_predicates`` storage object identifies the existing delete predicates that have not been cleaned up. + +Each :ref:`DELETE ` command may result in several entries in this table. + +.. list-table:: + :widths: 20 180 + :header-rows: 1 + + * - Column + - Description + * - ``database_name`` + - Shows the name of the databse containing the predicate. + * - ``table_id`` + - Shows the ID of the table containing the predicate. + * - ``max_chunk_id`` + - Reserved for internal use, this is a placeholder marker for the highest ``chunk_id`` logged during the ``DELETE`` operation. + * - ``delete_predicate`` + - Identifies the DELETE predicate. + +.. note:: This is an internal table designed for low-level performance troubleshooting. \ No newline at end of file diff --git a/reference/catalog_reference_catalog_tables.rst b/reference/catalog_reference_catalog_tables.rst new file mode 100644 index 000000000..20c1bf342 --- /dev/null +++ b/reference/catalog_reference_catalog_tables.rst @@ -0,0 +1,455 @@ +.. _catalog_reference_catalog_tables: + +************************************* +Catalog Tables +************************************* +The ``sqream_catalog`` includes the following tables: + +.. contents:: + :local: + :depth: 1 + +.. _clustering_keys: + +Clustering Keys +---------------- +The ``clustering_keys`` data object is used for explicit clustering keys for tables. If you define more than one clustering key, each key is listed in a separate row, and is described in the following table: + +.. list-table:: + :widths: 20 180 + :header-rows: 1 + + * - Column + - Description + * - ``database_name`` + - Shows the name of the database containing the table. + * - ``table_id`` + - Shows the ID of the table containing the column. + * - ``schema_name`` + - Shows the name of the schema containing the table. + * - ``table_name`` + - Shows the name of the table containing the column. + * - ``clustering_key`` + - Shows the name of the column used as a clustering key for this table. + +.. _columns: + +Columns +---------------- +The **Columns** database object shows the following tables: + +.. contents:: + :local: + :depth: 1 + +Columns +*********** +The ``column`` data object is used with standard tables and is described in the following table: + +.. list-table:: + :widths: 20 150 + :header-rows: 1 + + * - Column + - Description + * - ``database_name`` + - Shows the name of the database containing the table. + * - ``schema_name`` + - Shows the name of the schema containing the table. + * - ``table_id`` + - Shows the ID of the table containing the column. + * - ``table_name`` + - Shows the name of the table containing the column. + * - ``column_id`` + - Shows the ordinal number of the column in the table (begins at **0**). + * - ``column_name`` + - Shows the column's name. + * - ``type_name`` + - Shows the column's data type. For more information see :ref:`Supported Data Types `. + * - ``column_size`` + - Shows the maximum length in bytes. + * - ``has_default`` + - Shows ``NULL`` if the column has no default value, ``1`` if the default is a fixed value, or ``2`` if the default is an identity. For more information, see :ref:`identity`. + * - ``default_value`` + - Shows the column's default value. For more information, see :ref:`Default Value Constraints`. + * - ``compression_strategy`` + - Shows the compression strategy that a user has overridden. + * - ``created`` + - Shows the timestamp displaying when the column was created. + * - ``altered`` + - Shows the timestamp displaying when the column was last altered. + +External Table Columns +*********** +The ``external_table_columns`` is used for viewing data from foreign tables. + +For more information on foreign tables, see :ref:`CREATE FOREIGN TABLE`. + +.. _databases: + +Databases +---------------- +The ``databases`` data object is used for displaying database information, and is described in the following table: + +.. list-table:: + :widths: 20 180 + :header-rows: 1 + + * - Column + - Description + * - ``database_Id`` + - Shows the database's unique ID. + * - ``database_name`` + - Shows the database's name. + * - ``default_disk_chunk_size`` + - Reserved for internal use. + * - ``default_process_chunk_size`` + - Reserved for internal use. + * - ``rechunk_size`` + - Reserved for internal use. + * - ``storage_subchunk_size`` + - Reserved for internal use. + * - ``compression_chunk_size_threshold`` + - Reserved for internal use. + +.. _permissions: + +Permissions +---------------- +The ``permissions`` data object is used for displaying permissions information, such as roles (also known as **grantees**), and is described in the following tables: + +.. contents:: + :local: + :depth: 1 + +Permission Types +*********** +The ``permission_types`` object identifies the permission names existing in the database. + +The following table describes the ``permission_types`` data object: + +.. list-table:: + :widths: 20 180 + :header-rows: 1 + + * - Column + - Description + * - ``permission_type_id`` + - Shows the permission type's ID. + * - ``name`` + - Shows the name of the permission type. + +Default Permissions +*********** +The commands included in the **Default Permissions** section describe how to check the following default permissions: + +.. contents:: + :local: + :depth: 1 + +Default Table Permissions +~~~~~~~~~~~~~~~~ +The ``sqream_catalog.table_default_permissions`` command shows the columns described below: + +.. list-table:: + :widths: 20 180 + :header-rows: 1 + + * - Column + - Description + * - ``database_name`` + - Shows the database that the default permission rule applies to. + * - ``schema_id`` + - Shows the schema that the rule applies to, or ``NULL`` if the ``ALTER`` statement does not specify a schema. + * - ``modifier_role_id`` + - Shows the role to apply the rule to. + * - ``getter_role_id`` + - Shows the role that the permission is granted to. + * - ``permission_type`` + - Shows the type of permission granted. + +Default Schema Permissions +~~~~~~~~~~~~~~~~ +The ``sqream_catalog.schema_default_permissions`` command shows the columns described below: + +.. list-table:: + :widths: 20 180 + :header-rows: 1 + + * - Column + - Description + * - ``database_name`` + - Shows the database that the default permission rule applies to. + * - ``modifier_role_id`` + - Shows the role to apply the rule to. + * - ``getter_role_id`` + - Shows the role that the permission is granted to. + * - ``permission_type`` + - Shows the type of permission granted. + +For an example of using the ``sqream_catalog.table_default_permissions`` command, see `Granting Default Table Permissions `_. + +Table Permissions +*********** +The ``table_permissions`` data object identifies all permissions granted to tables. Each role-permission combination displays one row. + +The following table describes the ``table_permissions`` data object: + +.. list-table:: + :widths: 20 180 + :header-rows: 1 + + * - Column + - Description + * - ``database_name`` + - Shows the name of the database containing the table. + * - ``table_id`` + - Shows the ID of the table the permission applies to. + * - ``role_id`` + - Shows the ID of the role granted permissions. + * - ``permission_type`` + - Identifies the permission type. + +Database Permissions +*********** +The ``database_permissions`` data object identifies all permissions granted to databases. Each role-permission combination displays one row. + +The following table describes the ``database_permissions`` data object: + +.. list-table:: + :widths: 20 180 + :header-rows: 1 + + * - Column + - Description + * - ``database_name`` + - Shows the name of the database the permission applies to + * - ``role_id`` + - Shows the ID of the role granted permissions. + * - ``permission_type`` + - Identifies the permission type. + +Schema Permissions +*********** +The ``schema_permissions`` data object identifies all permissions granted to schemas. Each role-permission combination displays one row. + +The following table describes the ``schema_permissions`` data object: + +.. list-table:: + :widths: 20 180 + :header-rows: 1 + + * - Column + - Description + * - ``database_name`` + - Shows the name of the database containing the schema. + * - ``schema_id`` + - Shows the ID of the schema the permission applies to. + * - ``role_id`` + - Shows the ID of the role granted permissions. + * - ``permission_type`` + - Identifies the permission type. + +UDF Permissions +*********** +**Comment** - *No content.* + +.. _queries: + +Queries +---------------- +The ``savedqueries`` data object identifies the saved_queries in the database, as shown in the following table: + +.. list-table:: + :widths: 20 180 + :header-rows: 1 + + * - Column + - Description + * - ``name`` + - Shows the saved query name. + * - ``num_parameters`` + - Shows the number of parameters to be replaced at run-time. + +For more information, see :ref:`saved_queries`. + +.. _roles: + +Roles +---------------- +The ``roles`` data object is used for displaying role information, and is described in the following tables: + +.. contents:: + :local: + :depth: 1 + +Roles +*********** +The ``roles`` data object identifies the roles in the database, as shown in the following table: + +.. list-table:: + :widths: 20 180 + :header-rows: 1 + + * - Column + - Description + * - ``role_id`` + - Shows the role's database-unique ID. + * - ``name`` + - Shows the role's name. + * - ``superuser`` + - Identifies whether the role is a superuser (``1`` - superuser, ``0`` - regular user). + * - ``login`` + - Identifies whether the role can be used to log in to SQream (``1`` - yes, ``0`` - no). + * - ``has_password`` + - Identifies whether the role has a password (``1`` - yes, ``0`` - no). + * - ``can_create_function`` + - Identifies whether role can create UDFs (``1`` - yes, ``0`` - no). + +Role Memberships +*********** +The ``roles_memberships`` data object identifies the role memberships in the database, as shown below: + +.. list-table:: + :widths: 20 180 + :header-rows: 1 + + * - Column + - Description + * - ``role_id`` + - Shows the role ID. + * - ``member_role_id`` + - Shows the ID of the parent role that this role inherits from. + * - ``inherit`` + - Identifies whether permissions are inherited (``1`` - yes, ``0`` - no). + +.. _schemas: + +Schemas +---------------- +The ``schemas`` data object identifies all the database's schemas, as shown below: + +.. list-table:: + :widths: 20 180 + :header-rows: 1 + + * - Column + - Description + * - ``schema_id`` + - Shows the schema's unique ID. + * - ``schema_name`` + - Shows the schema's name. + * - ``schema_owner`` + - Shows the name of the role that owns the schema. + * - ``rechunker_ignore`` + - Reserved for internal use. + +.. _sequences: + +Sequences +---------------- +The ``sequences`` data object is used for displaying identity key information, as shown below: + +Identity Key +*********** +**Comment** - *No content.* + +.. _tables: + +Tables +---------------- +The ``tables`` data object is used for displaying table information, and is described in the following tables: + +.. contents:: + :local: + :depth: 1 + +Tables +*********** +The ``tables`` data object identifies proper (**Comment** - *What does "proper" mean?*) SQream tables in the database, as shown in the following table: + +.. list-table:: + :widths: 20 180 + :header-rows: 1 + + * - Column + - Description + * - ``database_name`` + - Shows the name of the database containing the table. + * - ``table_id`` + - Shows the table's database-unique ID. + * - ``schema_name`` + - Shows the name of the schema containing the table. + * - ``table_name`` + - Shows the name of the table. + * - ``row_count_valid`` + - Identifies whether the ``row_count`` can be used. + * - ``row_count`` + - Shows the number of rows in the table. + * - ``rechunker_ignore`` + - Relevant for internal use. + +Foreign Tables +*********** +The ``external_tables`` data object identifies foreign tables in the database, as shown below: + +.. list-table:: + :widths: 20 200 + :header-rows: 1 + + * - Column + - Description + * - ``database_name`` + - Shows the name of the database containing the table. + * - ``table_id`` + - Shows the table's database-unique ID. + * - ``schema_name`` + - Shows the name of the schema containing the table. + * - ``table_name`` + - Shows the name of the table. + * - ``format`` + - Identifies the foreign data wrapper used. ``0`` for ``csv_fdw``, ``1`` for ``parquet_fdw``, ``2`` for ``orc_fdw``. + * - ``created`` + - Identifies the clause used to create the table. + +.. _views: + +Views +---------------- +The ``views`` data object is used for displaying views in the database, as shown below: + +.. list-table:: + :widths: 20 180 + :header-rows: 1 + + * - Column + - Description + * - ``view_id`` + - Shows the view's database-unique ID. + * - ``view_schema`` + - Shows the name of the schema containing the view. + * - ``view_name`` + - Shows the name of the view. + * - ``view_data`` + - Reserved for internal use. + * - ``view_query_text`` + - Identifies the ``AS`` clause used to create the view. + +.. _udfs: + +User Defined Functions +---------------- +The ``udf`` data object is used for displaying UDFs in the database, as shown below: + +.. list-table:: + :widths: 20 180 + :header-rows: 1 + + * - Column + - Description + * - ``database_name`` + - Shows the name of the database containing the view. + * - ``function_id`` + - Shows the UDF's database-unique ID. + * - ``function_name`` + - Shows the name of the UDF. \ No newline at end of file diff --git a/reference/catalog_reference_examples.rst b/reference/catalog_reference_examples.rst new file mode 100644 index 000000000..4531dfefc --- /dev/null +++ b/reference/catalog_reference_examples.rst @@ -0,0 +1,64 @@ +.. _catalog_reference_examples: + +************************************* +Examples +************************************* +The **Examples** page includes the following examples: + +.. contents:: + :local: + :depth: 1 + +Listing All Tables in a Database +---------------------------------- + +.. code-block:: psql + + master=> SELECT * FROM sqream_catalog.tables; + database_name | table_id | schema_name | table_name | row_count_valid | row_count | rechunker_ignore + --------------+----------+-------------+----------------+-----------------+-----------+----------------- + master | 1 | public | nba | true | 457 | 0 + master | 12 | public | cool_dates | true | 5 | 0 + master | 13 | public | cool_numbers | true | 9 | 0 + master | 27 | public | jabberwocky | true | 8 | 0 + +Listing All Schemas in a Database +------------------------------------ + +.. code-block:: psql + + master=> SELECT * FROM sqream_catalog.schemas; + schema_id | schema_name | schema_owner | rechunker_ignore + ----------+---------------+--------------+----------------- + 0 | public | sqream | false + 1 | secret_schema | mjordan | false + + +Listing Columns and Their Types for a Specific Table +--------------------------------------------------- + +.. code-block:: postgres + + SELECT column_name, type_name + FROM sqream_catalog.columns + WHERE table_name='cool_animals'; + +Listing Delete Predicates +------------------------ + +.. code-block:: postgres + + SELECT t.table_name, d.* FROM + sqream_catalog.delete_predicates AS d + INNER JOIN sqream_catalog.tables AS t + ON d.table_id=t.table_id; + + +Listing Saved Queries +----------------------------- + +.. code-block:: postgres + + SELECT * FROM sqream_catalog.savedqueries; + +For more information, see :ref:`saved_queries`. \ No newline at end of file diff --git a/reference/catalog_reference_overview.rst b/reference/catalog_reference_overview.rst new file mode 100644 index 000000000..b74663509 --- /dev/null +++ b/reference/catalog_reference_overview.rst @@ -0,0 +1,11 @@ +.. _catalog_reference_overview: + +************************************* +Overview +************************************* +The SQream database uses a schema called ``sqream_catalog`` that contains information about your database's objects, such tables, columns, views, and permissions. Some additional catalog tables are used primarily for internal analysis and which may be different across SQream versions. + +* :ref:`catalog_reference_schema_information` +* :ref:`catalog_reference_catalog_tables` +* :ref:`catalog_reference_additonal_tables` +* :ref:`catalog_reference_examples` \ No newline at end of file diff --git a/reference/catalog_reference_schema_information.rst b/reference/catalog_reference_schema_information.rst new file mode 100644 index 000000000..6cd43ab6a --- /dev/null +++ b/reference/catalog_reference_schema_information.rst @@ -0,0 +1,62 @@ +.. _catalog_reference_schema_information: + +************************************* +What Information Does the Schema Contain? +************************************* +The schema includes tables designated and relevant for both external and internal use: + +.. contents:: + :local: + :depth: 1 + +External Tables +----------------- +The following table shows the data objects contained in the ``sqream_catalog`` schema designated for external use: + +.. list-table:: Database Objects + :widths: 20 180 + :header-rows: 1 + + * - Database Object + - Table + * - :ref:`Clustering Keys` + - ``clustering_keys`` + * - :ref:`Columns` + - ``columns``, ``external_table_columns`` + * - :ref:`Databases` + - ``databases`` + * - :ref:`Permissions` + - ``table_permissions``, ``database_permissions``, ``schema_permissions``, ``permission_types``, ``udf_permissions``, ``sqream_catalog.table_default_permissions`` + * - :ref:`Queries` + - ``saved_queries`` + * - :ref:`Roles` + - ``roles``, ``roles_memeberships`` + * - :ref:`Schemas` + - ``schemas`` + * - :ref:`Sequences` + - ``identity_key`` + * - :ref:`Tables` + - ``tables``, ``external_tables`` + * - :ref:`Views` + - ``views`` + * - :ref:`User Defined Functions` + - ``user_defined_functions`` + +Internal Tables +----------------- +The following table shows the data objects contained in the ``sqream_catalog`` schema designated for internal use: + +.. list-table:: Storage Objects + :widths: 20 180 + :header-rows: 1 + + * - Database Object + - Table + * - Extents + - Shows ``extents``. + * - Chunk columns + - Shows ``chunks_columns``. + * - Chunks + - Shows ``chunks``. + * - Delete predicates + - Shows ``delete_predicates``. For more information, see :ref:`Deleting Data`. \ No newline at end of file diff --git a/reference/sql/sql_statements/access_control_commands/alter_default_permissions.rst b/reference/sql/sql_statements/access_control_commands/alter_default_permissions.rst index 220e05eb3..0ab200286 100644 --- a/reference/sql/sql_statements/access_control_commands/alter_default_permissions.rst +++ b/reference/sql/sql_statements/access_control_commands/alter_default_permissions.rst @@ -3,22 +3,27 @@ ***************************** ALTER DEFAULT PERMISSIONS ***************************** +The **ALTER DEFAULT PERMISSIONS** page describes the following: -``ALTER DEFAULT PERMISSIONS`` allows granting automatic permissions to future objects. +.. contents:: + :local: + :depth: 1 -By default, if one user creates a table, another user will not have ``SELECT`` permissions on it. -By modifying the target role's default permissions, a database administrator can ensure that -all objects created by that role will be accessible to others. +Overview +============= +The ``ALTER DEFAULT PERMISSIONS`` command lets you grant automatic permissions to future objects. + +By default, users do not have ``SELECT`` permissions on tables created by other users. Database administrators can grant access to other users by modifying the target role default permissions. -Learn more about the permission system in the :ref:`access control guide`. +For more information about access control, see :ref:`Access Control`. Permissions ============= - -To alter default permissions, the current role must have the ``SUPERUSER`` permission. +The ``SUPERUSER`` permission is required to alter default permissions. Syntax ========== +The following is the syntax for altering default permissions: .. code-block:: postgres @@ -55,32 +60,71 @@ Syntax :start-line: 127 :end-line: 180 - Examples ============ +This section includes the following examples: -Automatic permissions for newly created schemas +.. contents:: + :local: + :depth: 1 + +Granting Default Table Permissions ------------------------------------------------- +This example is based on the roles **r1** and **r2**, created as follows: -When role ``demo`` creates a new schema, roles u1,u2 will get USAGE and CREATE permissions in the new schema: +.. code-block:: postgres + + create role r1; + create role r2; + alter default permissions for r1 for tables grant select to r2; + +Once created, you can build and run the following query based on the above: .. code-block:: postgres - ALTER DEFAULT PERMISSIONS FOR demo FOR SCHEMAS GRANT USAGE, CREATE TO u1,u2; + select + tdp.database_name as "database_name", + ss.schema_name as "schema_name", + rs1.name as "table_creator", + rs2.name as "grant_to", + pts.name as "permission_type" + from sqream_catalog.table_default_permissions tdp + inner join sqream_catalog.roles rs1 on tdp.modifier_role_id = rs1.role_id + inner join sqream_catalog.roles rs2 on tdp.getter_role_id = rs2.role_id + left join sqream_catalog.schemas ss on tdp.schema_id = ss.schema_id + inner join sqream_catalog.permission_types pts on pts.permission_type_id=tdp.permission_type + ; + +The following is an example of the output generated from the above queries: ++-----------------------+----------------------+-------------------+--------------+------------------------------+ +| **database_name** | **schema_name** | **table_creator** | **grant_to** | **permission_type** | ++-----------------------+----------------------+-------------------+--------------+------------------------------+ +| master | NULL | public | public | select | ++-----------------------+----------------------+-------------------+--------------+------------------------------+ -Automatic permissions for newly created tables in a schema ----------------------------------------------------------------- +For more information about default permissions, see `Default Permissions `_. + +Granting Automatic Permissions for Newly Created Schemas +------------------------------------------------- +When the role ``demo`` creates a new schema, roles **u1,u2** are granted ``USAGE`` and ``CREATE`` permissions in the new schema, as shown below: -When role ``demo`` creates a new table in schema ``s1``, roles u1,u2 wil be granted with SELECT on it: +.. code-block:: postgres + + ALTER DEFAULT PERMISSIONS FOR demo FOR SCHEMAS GRANT USAGE, CREATE TO u1,u2; + +Granting Automatic Permissions for Newly Created Tables in a Schema +---------------------------------------------------------------- +When the role ``demo`` creates a new table in schema ``s1``, roles **u1,u2** are granted ``SELECT`` permissions, as shown below: .. code-block:: postgres ALTER DEFAULT PERMISSIONS FOR demo IN s1 FOR TABLES GRANT SELECT TO u1,u2; -Revoke (``DROP GRANT``) permissions for newly created tables +Revoking Permissions from Newly Created Tables --------------------------------------------------------------- +Revoking permissions refers to using the ``DROP GRANT`` command, as shown below: .. code-block:: postgres - ALTER DEFAULT PERMISSIONS FOR public FOR TABLES DROP GRANT SELECT,DDL,INSERT,DELETE TO public; + ALTER DEFAULT PERMISSIONS FOR public FOR TABLES DROP GRANT SELECT,DDL,INSERT,DELETE TO public; \ No newline at end of file From 3b13862d2959c862e65601fc522d089985a1e76d Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 19 Jul 2022 17:35:32 +0300 Subject: [PATCH 123/316] Fixed link syntax --- reference/catalog_reference_catalog_tables.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference/catalog_reference_catalog_tables.rst b/reference/catalog_reference_catalog_tables.rst index 20c1bf342..7ddb9c148 100644 --- a/reference/catalog_reference_catalog_tables.rst +++ b/reference/catalog_reference_catalog_tables.rst @@ -187,7 +187,7 @@ The ``sqream_catalog.schema_default_permissions`` command shows the columns desc * - ``permission_type`` - Shows the type of permission granted. -For an example of using the ``sqream_catalog.table_default_permissions`` command, see `Granting Default Table Permissions `_. +For an example of using the ``sqream_catalog.table_default_permissions`` command, see `Granting Default Table Permissions `_. Table Permissions *********** From c331ad331ec09b684e17b5ed0f285f0b8a1e9619 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 19 Jul 2022 17:41:44 +0300 Subject: [PATCH 124/316] Update grant.rst Capitalization --- reference/sql/sql_statements/access_control_commands/grant.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference/sql/sql_statements/access_control_commands/grant.rst b/reference/sql/sql_statements/access_control_commands/grant.rst index dfb48c212..ceac48f7a 100644 --- a/reference/sql/sql_statements/access_control_commands/grant.rst +++ b/reference/sql/sql_statements/access_control_commands/grant.rst @@ -126,7 +126,7 @@ Parameters .. include from here -Supported permissions +Supported Permissions ======================= .. list-table:: From 280f26dd224d9ae32ed62d02da641458be00a404 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 19 Jul 2022 18:18:00 +0300 Subject: [PATCH 125/316] Update get_metadata_chunk_key.rst --- .../get_metadata_chunk_key.rst | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst b/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst index 08eba8345..784a54246 100644 --- a/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst +++ b/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst @@ -107,34 +107,34 @@ The following table describes the output generated from the ``GET_METADATA_CHUNK - ``2`` * - ``min_long`` - - **Comment** - What is it? - - **Comment** - What is it? - - ``flat`` + - Shows the minimum value of the type. + - Long + - ``25`` * - ``max_long`` - - **Comment** - What is it? - - **Comment** - What is it? - - **Comment** - What is it? + - Shows the maximum value in the chunk of a number. + - Long + - ``12345`` * - ``min_string_max_string`` - - **Comment** - What is it? - - **Comment** - What is it? - - **Comment** - What is it? + - Shows the minimum value of the string type. + - String + - ``"abc"`` * - ``min_numeric`` - - **Comment** - What is it? - - **Comment** - What is it? - - **Comment** - What is it? + - Shows the minimum value of the numeric type in the chunk. + - Numeric + - ``12.22`` * - ``max_numeric`` - - **Comment** - What is it? - - **Comment** - What is it? - - **Comment** - What is it? + - Shows the maximum value of the numeric type in the chunk. + - Numeric + - ``555.22`` * - ``column_aligned`` - - **Comment** - What is it? - - **Comment** - What is it? - - **Comment** - What is it? + - Relevant to text columns, aligment in memory. + - Boolean + - ``Yes`` / ``No`` The following is an example of the output generated from the ``GET_METADATA_CHUNK_KEY`` command: From f348959e3c5789d19ff89a01986e8c8e3d2696e5 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 19 Jul 2022 18:26:00 +0300 Subject: [PATCH 126/316] Updated --- index.rst | 6 +----- releases/2022.1.rst | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/index.rst b/index.rst index db8e0fa2a..5c4582c19 100644 --- a/index.rst +++ b/index.rst @@ -4,8 +4,6 @@ SQream DB Documentation ************************* -The **v2022.1** branch is a private branch designed for internal use only until the release date. - .. only:: html .. tip:: @@ -51,7 +49,6 @@ SQream DB easily plugs in to third-party tools like :ref:`Tableau` - :ref:`connect_to_tableau` * - **Releases** - **Driver and Deployment** @@ -59,7 +56,7 @@ SQream DB easily plugs in to third-party tools like :ref:`Tableau` - :ref:`2021.2<2021.2>` + :ref:`2021.2<2021.2>` :ref:`2021.1<2021.1>` @@ -74,7 +71,6 @@ SQream DB easily plugs in to third-party tools like :ref:`Tableau` - :ref:`connect_to_tableau` - :ref:`troubleshooting` guide diff --git a/releases/2022.1.rst b/releases/2022.1.rst index b6ffdf9ef..8d881c92c 100644 --- a/releases/2022.1.rst +++ b/releases/2022.1.rst @@ -67,7 +67,7 @@ The following table lists the known issues for Version 2022.1: +-------------+-------------------------------------------------------------------------------------------+ | SQ-9889 | Running a query including Thai characters generated an internal runtime error. | +-------------+-------------------------------------------------------------------------------------------+ -| SQ-10071 | error on exists subqueries with text and varchar equality condition | +| SQ-10071 | Error on existing subqueries with TEXT and VARCHAR equality condition | +-------------+-------------------------------------------------------------------------------------------+ | SQ-10191 | The ``ALTER DEFAULT SCHEMA`` command was not functioning correctly. | +-------------+-------------------------------------------------------------------------------------------+ From 50e67c53984237eed802fe6b8ea9a884443c01f9 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 19 Jul 2022 18:45:40 +0300 Subject: [PATCH 127/316] Fixed table alignment. --- index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.rst b/index.rst index 5c4582c19..bc5c25c2c 100644 --- a/index.rst +++ b/index.rst @@ -56,7 +56,7 @@ SQream DB easily plugs in to third-party tools like :ref:`Tableau` - :ref:`2021.2<2021.2>` + :ref:`2021.2<2021.2>` :ref:`2021.1<2021.1>` From dd2de29193efb911a2bd87643930b8fe7250fdce Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 19 Jul 2022 23:39:00 +0300 Subject: [PATCH 128/316] Fixed link and table alignment --- data_ingestion/avro.rst | 2 +- .../installing_prometheus_using_binary_packages.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/data_ingestion/avro.rst b/data_ingestion/avro.rst index e943fe41c..753786376 100644 --- a/data_ingestion/avro.rst +++ b/data_ingestion/avro.rst @@ -161,7 +161,7 @@ The following table shows the supported **Complex** data types: +------------+-------------------------------------------------------+ | | SQream Type | -| +---------------+---------------+-----------+-----------+ +| +------------+----------------+-------------+-----------+ |Avro Type | Number | Date/Datetime | String | Boolean | +============+============+================+=============+===========+ | ``record`` | | | | | diff --git a/installation_guides/installing_prometheus_using_binary_packages.rst b/installation_guides/installing_prometheus_using_binary_packages.rst index a6104bdd0..5031ec181 100644 --- a/installation_guides/installing_prometheus_using_binary_packages.rst +++ b/installation_guides/installing_prometheus_using_binary_packages.rst @@ -102,7 +102,7 @@ You must install Prometheus before installing the Dashboard Data Collector. $ sudo chown -R prometheus:prometheus /etc/prometheus/consoles $ sudo chown -R prometheus:prometheus /etc/prometheus/console_libraries -For more information on installing the Dashboard Data Collector, see `Installing the Dashboard Data Collector `_. +For more information on installing the Dashboard Data Collector, see `Installing the Dashboard Data Collector `_. Back to :ref:`Installing Prometheus Using Binary Packages` @@ -238,4 +238,4 @@ From the **Query** tab you can query metrics, as shown below: * - .. image:: /_static/images/3c9c4e8b-49bd-44a8-9829-81d1772ed962.gif -Back to :ref:`Installing Prometheus Using Binary Packages` +Back to :ref:`Installing Prometheus Using Binary Packages` \ No newline at end of file From 77092d8367f34e4a87c37b131dd174774d4347ef Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Wed, 20 Jul 2022 14:46:07 +0300 Subject: [PATCH 129/316] Reinstituted Client Platforms (removed by accident) --- .../client_platforms/connect.sas | 27 ++ .../client_platforms/connect2.sas | 27 ++ .../client_platforms/connect3.sas | 17 + .../client_platforms/index.rst | 39 ++ .../client_platforms/informatica.rst | 173 +++++++ .../client_platforms/microstrategy.rst | 185 +++++++ .../client_platforms/odbc-sqream.tdc | 25 + .../client_platforms/pentaho.rst | 253 ++++++++++ connecting_to_sqream/client_platforms/php.rst | 76 +++ .../client_platforms/power_bi.rst | 143 ++++++ connecting_to_sqream/client_platforms/r.rst | 151 ++++++ .../client_platforms/sas_viya.rst | 185 +++++++ .../client_platforms/sql_workbench.rst | 135 ++++++ .../client_platforms/tableau.rst | 453 ++++++++++++++++++ .../client_platforms/talend.rst | 204 ++++++++ .../client_platforms/test.php | 16 + .../client_platforms/tibco_spotfire.rst | 387 +++++++++++++++ connecting_to_sqream/index.rst | 3 +- 18 files changed, 2498 insertions(+), 1 deletion(-) create mode 100644 connecting_to_sqream/client_platforms/connect.sas create mode 100644 connecting_to_sqream/client_platforms/connect2.sas create mode 100644 connecting_to_sqream/client_platforms/connect3.sas create mode 100644 connecting_to_sqream/client_platforms/index.rst create mode 100644 connecting_to_sqream/client_platforms/informatica.rst create mode 100644 connecting_to_sqream/client_platforms/microstrategy.rst create mode 100644 connecting_to_sqream/client_platforms/odbc-sqream.tdc create mode 100644 connecting_to_sqream/client_platforms/pentaho.rst create mode 100644 connecting_to_sqream/client_platforms/php.rst create mode 100644 connecting_to_sqream/client_platforms/power_bi.rst create mode 100644 connecting_to_sqream/client_platforms/r.rst create mode 100644 connecting_to_sqream/client_platforms/sas_viya.rst create mode 100644 connecting_to_sqream/client_platforms/sql_workbench.rst create mode 100644 connecting_to_sqream/client_platforms/tableau.rst create mode 100644 connecting_to_sqream/client_platforms/talend.rst create mode 100644 connecting_to_sqream/client_platforms/test.php create mode 100644 connecting_to_sqream/client_platforms/tibco_spotfire.rst diff --git a/connecting_to_sqream/client_platforms/connect.sas b/connecting_to_sqream/client_platforms/connect.sas new file mode 100644 index 000000000..10fcdb0a2 --- /dev/null +++ b/connecting_to_sqream/client_platforms/connect.sas @@ -0,0 +1,27 @@ +options sastrace='d,d,d,d' +sastraceloc=saslog +nostsuffix +msglevel=i +sql_ip_trace=(note,source) +DEBUG=DBMS_SELECT; + +options validvarname=any; + +libname sqlib jdbc driver="com.sqream.jdbc.SQDriver" + classpath="/opt/sqream/sqream-jdbc-4.0.0.jar" + URL="jdbc:Sqream://sqream-cluster.piedpiper.com:3108/raviga;cluster=true" + user="rhendricks" + password="Tr0ub4dor3" + schema="public" + PRESERVE_TAB_NAMES=YES + PRESERVE_COL_NAMES=YES; + +proc sql; + title 'Customers table'; + select * + from sqlib.customers; +quit; + +data sqlib.customers; + set sqlib.customers; +run; \ No newline at end of file diff --git a/connecting_to_sqream/client_platforms/connect2.sas b/connecting_to_sqream/client_platforms/connect2.sas new file mode 100644 index 000000000..10fcdb0a2 --- /dev/null +++ b/connecting_to_sqream/client_platforms/connect2.sas @@ -0,0 +1,27 @@ +options sastrace='d,d,d,d' +sastraceloc=saslog +nostsuffix +msglevel=i +sql_ip_trace=(note,source) +DEBUG=DBMS_SELECT; + +options validvarname=any; + +libname sqlib jdbc driver="com.sqream.jdbc.SQDriver" + classpath="/opt/sqream/sqream-jdbc-4.0.0.jar" + URL="jdbc:Sqream://sqream-cluster.piedpiper.com:3108/raviga;cluster=true" + user="rhendricks" + password="Tr0ub4dor3" + schema="public" + PRESERVE_TAB_NAMES=YES + PRESERVE_COL_NAMES=YES; + +proc sql; + title 'Customers table'; + select * + from sqlib.customers; +quit; + +data sqlib.customers; + set sqlib.customers; +run; \ No newline at end of file diff --git a/connecting_to_sqream/client_platforms/connect3.sas b/connecting_to_sqream/client_platforms/connect3.sas new file mode 100644 index 000000000..c1bf11dcf --- /dev/null +++ b/connecting_to_sqream/client_platforms/connect3.sas @@ -0,0 +1,17 @@ +options sastrace='d,d,d,d' +sastraceloc=saslog +nostsuffix +msglevel=i +sql_ip_trace=(note,source) +DEBUG=DBMS_SELECT; + +options validvarname=any; + +libname sqlib jdbc driver="com.sqream.jdbc.SQDriver" + classpath="/opt/sqream/sqream-jdbc-4.0.0.jar" + URL="jdbc:Sqream://sqream-cluster.piedpiper.com:3108/raviga;cluster=true" + user="rhendricks" + password="Tr0ub4dor3" + schema="public" + PRESERVE_TAB_NAMES=YES + PRESERVE_COL_NAMES=YES; \ No newline at end of file diff --git a/connecting_to_sqream/client_platforms/index.rst b/connecting_to_sqream/client_platforms/index.rst new file mode 100644 index 000000000..a5a3f5166 --- /dev/null +++ b/connecting_to_sqream/client_platforms/index.rst @@ -0,0 +1,39 @@ +.. _client_platforms: + +************************************ +Client Platforms +************************************ +These topics explain how to install and connect a variety of third party tools. + +Browse the articles below, in the sidebar, or use the search to find the information you need. + +Overview +========== + +SQream DB is designed to work with most common database tools and interfaces, allowing you direct access through a variety of drivers, connectors, tools, vizualisers, and utilities. + +The tools listed have been tested and approved for use with SQream DB. Most 3\ :sup:`rd` party tools that work through JDBC, ODBC, and Python should work. + +If you are looking for a tool that is not listed, SQream and our partners can help. Go to `SQream Support `_ or contact your SQream account manager for more information. + +.. toctree:: + :maxdepth: 4 + :caption: In this section: + :titlesonly: + + power_bi + tibco_spotfire + sas_viya + sql_workbench + tableau + pentaho + microstrategy + informatica + r + php + xxtalend + xxdiagnosing_common_connectivity_issues + +.. image:: /_static/images/connectivity_ecosystem.png + + diff --git a/connecting_to_sqream/client_platforms/informatica.rst b/connecting_to_sqream/client_platforms/informatica.rst new file mode 100644 index 000000000..6bc50b22a --- /dev/null +++ b/connecting_to_sqream/client_platforms/informatica.rst @@ -0,0 +1,173 @@ +.. _informatica: + +************************* +Connect to SQream Using Informatica Cloud Services +************************* + +Overview +========= +The **Connecting to SQream Using Informatica Cloud Services** page is quick start guide for connecting to SQream using Informatica cloud services. + +It describes the following: + +.. contents:: + :local: + +Establishing a Connection between SQream and Informatica +----------------- +The **Establishing a Connection between SQream and Informatica** page describes how to establish a connection between SQream and the Informatica data integration Cloud. + +**To establish a connection between SQream and the Informatica data integration Cloud:** + +1. Go to the `Informatica Cloud homepage `_. + + :: + +2. Do one of the following: + + 1. Log in using your credentials. + + :: + + 2. Log in using your SAML Identity Provider. + +3. From the **Services** window, select **Administrator** or click **Show all services** to show all services. + + + The SQream dashboard is displayed. + + + :: + + +4. In the menu on the left, click **Runtime Environments**. + + + The **Runtime Environments** panel is displayed. + + :: + +5. Click **Download Secure Agent**. + + :: + +6. When the **Download the Secure Agent** panel is displayed, do the following: + + 1. Select a platform (Windows 64 or Linux 64). + + :: + + + 2. Click **Copy** and save the token on your local hard drive. + + The token is used in combination with your user name to authorize the agent to access your account. + + +7. Click **Download**. + + The installation begins. + + :: + +8. When the **Informatica Cloud Secure Agent Setup** panel is displayed, click **Next**. + + + :: + + +9. Provide your **User Name** and **Install Token** and click **Register**. + + :: + + + +10. From the Runtime Environments panel, click **New Runtime Environment**. + + + The **New Secure Agent Group** window is displayed. + + :: + +11. On the New Secure Agent Group window, click **OK** to connect your Runtime Environment with the running agent. + + .. note:: If you do not download Secure Agent, you will not be able to connect your Runtime Environment with the running agent and continue establishing a connection between SQream and the Informatica data integration Cloud. + +Establishing a Connection In Your Environment +----------------- + +The **Establishing a Connection In Your Environment** describes the following: + +.. contents:: + :local: + +Establishing an ODBC DSN Connection In Your Environment +~~~~~~~~~~~~~ +After establishing a connection between SQream and Informatica you can establish an ODBC DSN connection in your environment. + +**To establish an ODBC connection in your environment:** + +1. Click **Add**. + + :: + +2. Click **Configure**. + + .. note:: Verify that **Use Server Picker** is selected. + +3. Click **Test**. + + :: + +4. Verify that the connection has tested successfully. + + :: + +5. Click **Save**. + + :: + +6. Click **Actions** > **Publish**. + +Establishing a JDBC Connection In Your Environment +~~~~~~~~~~~~~ +After establishing a connection between SQream and Informatica you can establish a JDBC connection in your environment. + +**To establish a JDBC connection in your environment:** + +1. Create a new DB connection by clicking **Connections** > **New Connection**. + + The **New Connection** window is displayed. + + :: + + +2. In the **JDBC_IC Connection Properties** section, in the **JDBC Connection URL** field, establish a JDBC connection by providing the correct connection string. + + For connection string examples, see `Connection Strings `_. + + :: + +3. Click **Test**. + + :: + +4. Verify that the connection has tested successfully. + + :: + +5. Click **Save**. + + :: + +6. Click **Actions** > **Publish**. + +Supported SQream Driver Versions +--------------- + +SQream supports the following SQream driver versions: + +* **JDBC** - Version 4.3.4 and above. + + :: + +* **ODBC** - Version 4.0.0 and above. diff --git a/connecting_to_sqream/client_platforms/microstrategy.rst b/connecting_to_sqream/client_platforms/microstrategy.rst new file mode 100644 index 000000000..6cad19be2 --- /dev/null +++ b/connecting_to_sqream/client_platforms/microstrategy.rst @@ -0,0 +1,185 @@ +.. _microstrategy: + + +************************* +Connect to SQream Using MicroStrategy +************************* + +.. _ms_top: + +Overview +--------------- +This document is a Quick Start Guide that describes how to install MicroStrategy and connect a datasource to the MicroStrategy dasbhoard for analysis. + + + +The **Connecting to SQream Using MicroStrategy** page describes the following: + + +.. contents:: + :local: + + + + + + +What is MicroStrategy? +================ +MicroStrategy is a Business Intelligence software offering a wide variety of data analytics capabilities. SQream uses the MicroStrategy connector for reading and loading data into SQream. + +MicroStrategy provides the following: + +* Data discovery +* Advanced analytics +* Data visualization +* Embedded BI +* Banded reports and statements + + +For more information about Microstrategy, see `MicroStrategy `_. + + + +:ref:`Back to Overview ` + + + + + +Connecting a Data Source +======================= + +1. Activate the **MicroStrategy Desktop** app. The app displays the Dossiers panel to the right. + + :: + +2. Download the most current version of the `SQream JDBC driver `_. + + :: + +3. Click **Dossiers** and **New Dossier**. The **Untitled Dossier** panel is displayed. + + :: + +4. Click **New Data**. + + :: + +5. From the **Data Sources** panel, select **Databases** to access data from tables. The **Select Import Options** panel is displayed. + + :: + +6. Select one of the following: + + * Build a Query + * Type a Query + * Select Tables + + :: + +7. Click **Next**. + + :: + +8. In the Data Source panel, do the following: + + 1. From the **Database** dropdown menu, select **Generic**. The **Host Name**, **Port Number**, and **Database Name** fields are removed from the panel. + + :: + + 2. In the **Version** dropdown menu, verify that **Generic DBMS** is selected. + + :: + + 3. Click **Show Connection String**. + + :: + + 4. Select the **Edit connection string** checkbox. + + :: + + 5. From the **Driver** dropdown menu, select a driver for one of the following connectors: + + * **JDBC** - The SQream driver is not integrated with MicroStrategy and does not appear in the dropdown menu. However, to proceed, you must select an item, and in the next step you must specify the path to the SQream driver that you installed on your machine. + * **ODBC** - SQreamDB ODBC + + :: + + 6. In the **Connection String** text box, type the relevant connection string and path to the JDBC jar file using the following syntax: + + .. code-block:: console + + $ jdbc:Sqream:///;user=;password=sqream;[; ...] + + The following example shows the correct syntax for the JDBC connector: + + .. code-block:: console + + jdbc;MSTR_JDBC_JAR_FOLDER=C:\path\to\jdbc\folder;DRIVER=;URL={jdbc:Sqream:///;user=;password=;[; ...];} + + The following example shows the correct syntax for the ODBC connector: + + .. code-block:: console + + odbc:Driver={SqreamODBCDriver};DSN={SQreamDB ODBC};Server=;Port=;Database=;User=;Password=;Cluster=; + + For more information about the available **connection parameters** and other examples, see `Connection Parameters `_. + + 7. In the **User** and **Password** fields, fill out your user name and password. + + :: + + 8. In the **Data Source Name** field, type **SQreamDB**. + + :: + + 9. Click **Save**. The SQreamDB that you picked in the Data Source panel is displayed. + + +9. In the **Namespace** menu, select a namespace. The tables files are displayed. + + :: + +10. Drag and drop the tables into the panel on the right in your required order. + + :: + +11. **Recommended** - Click **Prepare Data** to customize your data for analysis. + + :: + +12. Click **Finish**. + + :: + +13. From the **Data Access Mode** dialog box, select one of the following: + + + * Connect Live + * Import as an In-memory Dataset + +Your populated dashboard is displayed and is ready for data discovery and analytics. + + + + + + +.. _supported_sqream_drivers: + +:ref:`Back to Overview ` + +Supported SQream Drivers +================ + +The following list shows the supported SQream drivers and versions: + +* **JDBC** - Version 4.3.3 and higher. +* **ODBC** - Version 4.0.0. + + +.. _supported_tools_and_operating_systems: + +:ref:`Back to Overview ` diff --git a/connecting_to_sqream/client_platforms/odbc-sqream.tdc b/connecting_to_sqream/client_platforms/odbc-sqream.tdc new file mode 100644 index 000000000..36cd55e33 --- /dev/null +++ b/connecting_to_sqream/client_platforms/odbc-sqream.tdc @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/connecting_to_sqream/client_platforms/pentaho.rst b/connecting_to_sqream/client_platforms/pentaho.rst new file mode 100644 index 000000000..fa8146c41 --- /dev/null +++ b/connecting_to_sqream/client_platforms/pentaho.rst @@ -0,0 +1,253 @@ +.. _pentaho_data_integration: + +************************* +Connecting to SQream Using Pentaho Data Integration +************************* +.. _pentaho_top: + +Overview +========= +This document is a Quick Start Guide that describes how to install Pentaho, create a transformation, and define your output. + +The Connecting to SQream Using Pentaho page describes the following: + +* :ref:`Installing Pentaho ` +* :ref:`Installing and setting up the JDBC driver ` +* :ref:`Creating a transformation ` +* :ref:`Defining your output ` +* :ref:`Importing your data ` + +.. _install_pentaho: + +Installing Pentaho +~~~~~~~~~~~~~~~~~ +To install PDI, see the `Pentaho Community Edition (CE) Installation Guide `_. + +The **Pentaho Community Edition (CE) Installation Guide** describes how to do the following: + +* Downloading the PDI software. +* Installing the **JRE (Java Runtime Environment)** and **JDK (Java Development Kit)**. +* Setting up the JRE and JDK environment variables for PDI. + +:ref:`Back to Overview ` + +.. _install_set_up_jdbc_driver: + +Installing and Setting Up the JDBC Driver +~~~~~~~~~~~~~~~~~ +After installing Pentaho you must install and set up the JDBC driver. This section explains how to set up the JDBC driver using Pentaho. These instructions use Spoon, the graphical transformation and job designer associated with the PDI suite. + +You can install the driver by copying and pasting the SQream JDBC .jar file into your **/design-tools/data-integration/lib** directory. + +**NOTE:** Contact your SQream license account manager for the JDBC .jar file. + +:ref:`Back to Overview ` + +.. _create_transformation: + +Creating a Transformation +~~~~~~~~~~~~~~~~~~ +After installing Pentaho you can create a transformation. + +**To create a transformation:** + +1. Use the CLI to open the PDI client for your operating system (Windows): + + .. code-block:: console + + $ spoon.bat + +2. Open the spoon.bat file from its folder location. + +:: + +3. In the **View** tab, right-click **Transformations** and click **New**. + + A new transformation tab is created. + +4. In the **Design** tab, click **Input** to show its file contents. + +:: + +5. Drag and drop the **CSV file input** item to the new transformation tab that you created. + +:: + +6. Double-click **CSV file input**. The **CSV file input** panel is displayed. + +:: + +7. In the **Step name** field, type a name. + +:: + +8. To the right of the **Filename** field, click **Browse**. + +:: + +9. Select the file that you want to read from and click **OK**. + +:: + +10. In the CSV file input window, click **Get Fields**. + +:: + +11. In the **Sample data** window, enter the number of lines you want to sample and click **OK**. The default setting is **100**. + + The tool reads the file and suggests the field name and type. + +12. In the CSV file input window, click **Preview**. + +:: + +13. In the **Preview size** window, enter the number of rows you want to preview and click **OK**. The default setting is **1000**. + +:: + +14. Verify that the preview data is correct and click **Close**. + +:: + +15. Click **OK** in the **CSV file input** window. + +:ref:`Back to Overview ` + +.. _define_output: + +Defining Your Output +----------------- +After creating your transformation you must define your output. + +**To define your output:** + +1. In the **Design** tab, click **Output**. + + The Output folder is opened. + +2. Drag and drop **Table output** item to the Transformation window. + +:: + +3. Double-click **Table output** to open the **Table output** dialog box. + +:: + +4. From the **Table output** dialog box, type a **Step name** and click **New** to create a new connection. Your **steps** are the building blocks of a transformation, such as file input or a table output. + + The **Database Connection** window is displayed with the **General** tab selected by default. + +5. Enter or select the following information in the Database Connection window and click **Test**. + + The following table shows and describes the information that you need to fill out in the Database Connection window: + + .. list-table:: + :widths: 6 31 73 + :header-rows: 1 + + * - No. + - Element Name + - Description + * - 1 + - Connection name + - Enter a name that uniquely describes your connection, such as **sampledata**. + * - 2 + - Connection type + - Select **Generic database**. + * - 3 + - Access + - Select **Native (JDBC)**. + * - 4 + - Custom connection URL + - Insert **jdbc:Sqream:///;user=;password=;[; ...];**. The IP is a node in your SQream cluster and is the name or schema of the database you want to connect to. Verify that you have not used any leading or trailing spaces. + * - 5 + - Custom driver class name + - Insert **com.sqream.jdbc.SQDriver**. Verify that you have not used any leading or trailing spaces. + * - 6 + - Username + - Your SQreamdb username. If you leave this blank, you will be prompted to provide it when you connect. + * - 7 + - Password + - Your password. If you leave this blank, you will be prompted to provide it when you connect. + + The following message is displayed: + +.. image:: /_static/images/third_party_connectors/pentaho/connection_tested_successfully_2.png + +6. Click **OK** in the window above, in the Database Connection window, and Table Output window. + +:ref:`Back to Overview ` + +.. _import_data: + +Importing Data +----------------- +After defining your output you can begin importing your data. + +For more information about backing up users, permissions, or schedules, see `Backup and Restore Pentaho Repositories `_ + +**To import data:** + +1. Double-click the **Table output** connection that you just created. + +:: + +2. To the right of the **Target schema** field, click **Browse** and select a schema name. + +:: + +3. Click **OK**. The selected schema name is displayed in the **Target schema** field. + +:: + +4. Create a new hop connection between the **CSV file input** and **Table output** steps: + + 1. On the CSV file input step item, click the **new hop connection** icon. + + .. image:: /_static/images/third_party_connectors/pentaho/csv_file_input_options.png + + 2. Drag an arrow from the **CSV file input** step item to the **Table output** step item. + + .. image:: /_static/images/third_party_connectors/pentaho/csv_file_input_options_2.png + + 3. Release the mouse button. The following options are displayed. + + :: + + 4. Select **Main output of step**. + + .. image:: /_static/images/third_party_connectors/pentaho/main_output_of_step.png + +:: + +5. Double-click **Table output** to open the **Table output** dialog box. + +:: + +6. In the **Target table** field, define a target table name. + +:: + +7. Click **SQL** to open the **Simple SQL editor.** + +:: + +8. In the **Simple SQL editor**, click **Execute**. + + The system processes and displays the results of the SQL statements. + +9. Close all open dialog boxes. + +:: + +10. Click the play button to execute the transformation. + + .. image:: /_static/images/third_party_connectors/pentaho/execute_transformation.png + + The **Run Options** dialog box is displayed. + +11. Click **Run**. + + The **Execution Results** are displayed. + +:ref:`Back to Overview ` \ No newline at end of file diff --git a/connecting_to_sqream/client_platforms/php.rst b/connecting_to_sqream/client_platforms/php.rst new file mode 100644 index 000000000..2310fde6b --- /dev/null +++ b/connecting_to_sqream/client_platforms/php.rst @@ -0,0 +1,76 @@ +.. _php: + +***************************** +Connect to SQream Using PHP +***************************** + +Overview +========== +PHP is an open source scripting language that executes scripts on servers. The **Connect to PHP** page explains how to connect to a SQream cluster, and describes the following: + +.. contents:: + :local: + :depth: 1 + +Installing PHP +------------------- +**To install PHP:** + +1. Download the JDBC driver installer from the `SQream Drivers page `_. + + :: + +2. Create a DSN. + + :: + +3. Install the **uODBC** extension for your PHP installation. + + For more information, navigate to `PHP Documentation `_ and see the topic menu on the right side of the page. + +Configuring PHP +------------------- +You can configure PHP in one of the following ways: + +* When compiling, configure PHP to enable uODBC using ``./configure --with-pdo-odbc=unixODBC,/usr/local``. + + :: + +* Install ``php-odbc`` and ``php-pdo`` along with PHP using your distribution package manager. SQream recommends a minimum of version 7.1 for the best results. + +.. note:: PHP's string size limitations truncates fetched text, which you can override by doing one of the following: + + * Increasing the **php.ini** default setting, such as the *odbc.defaultlrl* to **10000**. + + :: + + * Setting the size limitation in your code before making your connection using **ini_set("odbc.defaultlrl", "10000");**. + + :: + + * Setting the size limitation in your code before fetchng your result using **odbc_longreadlen($result, "10000");**. + +Operating PHP +------------------- +After configuring PHP, you can test your connection. + +**To test your connection:** + +#. Create a test connection file using the correct parameters for your SQream installation, as shown below: + + .. literalinclude:: test.php + :language: php + :emphasize-lines: 4 + :linenos: + + For more information, download the sample :download:`PHP example connection file ` shown above. + + The following is an example of a valid DSN line: + + .. code:: php + + $dsn = "odbc:Driver={SqreamODBCDriver};Server=192.168.0.5;Port=5000;Database=master;User=rhendricks;Password=super_secret;Service=sqream"; + +#. Run the PHP file either directly with PHP (``php test.php``) or through a browser. + + For more information about supported DSN parameters, see :ref:`dsn_params`. \ No newline at end of file diff --git a/connecting_to_sqream/client_platforms/power_bi.rst b/connecting_to_sqream/client_platforms/power_bi.rst new file mode 100644 index 000000000..c088db851 --- /dev/null +++ b/connecting_to_sqream/client_platforms/power_bi.rst @@ -0,0 +1,143 @@ +.. _power_bi: + +************************* +Connect to SQream Using Power BI Desktop +************************* + +Overview +========= +**Power BI Desktop** lets you connect to SQream and use underlying data as with other data sources in Power BI Desktop. + +SQream integrates with Power BI Desktop to do the following: + +* Extract and transform your datasets into usable visual models in approximately one minute. + + :: + +* Use **DAX** functions **(Data Analysis Expressions)** to analyze your datasets. + + :: + +* Refresh datasets as needed or by using scheduled jobs. + +SQream uses Power BI for extracting data sets using the following methods: + +* **Direct query** - Direct queries lets you connect easily with no errors, and refreshes Power BI artifacts, such as graphs and reports, in a considerable amount of time in relation to the time taken for queries to run using the `SQream SQL CLI Reference guide `_. + + :: + +* **Import** - Lets you extract datasets from remote databases. + +The **Connect to SQream Using Power BI** page describes the following: + +.. contents:: + :local: + :depth: 1 + +Prerequisites +------------------- +To connect to SQream, the following must be installed: + +* **ODBC data source administrator** - 32 or 64, depending on your operating system. For Windows users, the ODBC data source administrator is embedded within the operating system. + +* **SQream driver** - The SQream application required for interacting with the ODBC according to the configuration specified in the ODBC administrator tool. + +Installing Power BI Desktop +------------------- +**To install Power BI Desktop:** + +1. Download `Power BI Desktop 64x `_. + + :: + +2. Download and configure your ODBC driver. + + For more information about configuring your ODBC driver, see `ODBC `_. + +3. Navigate to **Windows** > **Documents** and create a folder called **Power BI Desktop Custom Connectors**. + + :: + +4. In the **Power BI Desktop** folder, create a folder called **Custom Connectors**. + + +5. From the Client Drivers page, download the **PowerQuery.mez** file. + + :: + +5. Save the PowerQuery.mez file in the **Custom Connectors** folder you created in Step 3. + + :: + +6. Open the Power BI application. + + :: + +7. Navigate to **File** > **Options and Settings** > **Option** > **Security** > **Data Extensions**, and select **(Not Recommended) Allow any extension to load without validation or warning**. + + :: + +8. Restart the Power BI Desktop application. + + :: + +9. From the **Get Data** menu, select **SQream**. + + :: + +10. Click **Connect** and provide the information shown in the following table: + + .. list-table:: + :widths: 6 31 + :header-rows: 1 + + * - Element Name + - Description + * - Server + - Provide the network address to your database server. You can use a hostname or an IP address. + * - Port + - Provide the port that the database is responding to at the network address. + * - Database + - Provide the name of your database or the schema on your database server. + * - User + - Provide a SQreamdb username. + * - Passwords + - Provide a password for your user. + +11. Under **Data Connectivity mode**, select **DirectQuery mode**. + + :: + +12. Click **Connect**. + + :: + +13. Provide your user name and password and click **Connect**. + +Best Practices for Power BI +--------------- +SQream recommends using Power BI in the following ways for acquiring the best performance metrics: + +* Creating bar, pie, line, or plot charts when illustrating one or more columns. + + :: + +* Displaying trends and statuses using visual models. + + :: + +* Creating a unified view using **PowerQuery** to connect different data sources into a single dashboard. + +Supported SQream Driver Versions +--------------- +SQream supports the following SQream driver versions: + +* The **PowerQuery Connector** is an additional layer on top of the ODBC. + + :: + +* SQream Driver Installation (ODBC v4.1.1) - Contact your administrator for the link to download ODBC v4.1.1. + +Related Information +------------------- +For more information, see the `Glossary `_. \ No newline at end of file diff --git a/connecting_to_sqream/client_platforms/r.rst b/connecting_to_sqream/client_platforms/r.rst new file mode 100644 index 000000000..c84bf901b --- /dev/null +++ b/connecting_to_sqream/client_platforms/r.rst @@ -0,0 +1,151 @@ +.. _r: + +***************************** +Connect to SQream Using R +***************************** + +You can use R to interact with a SQream DB cluster. + +This tutorial is a guide that will show you how to connect R to SQream DB. + +.. contents:: In this topic: + :local: + +JDBC +========= + + +#. Get the :ref:`SQream DB JDBC driver`. + +#. + In R, install RJDBC + + .. code-block:: rconsole + + > install.packages("RJDBC") + Installing package into 'C:/Users/r/...' + (as 'lib' is unspecified) + + package 'RJDBC' successfully unpacked and MD5 sums checked + +#. + Import the RJDBC library + + .. code-block:: rconsole + + > library(RJDBC) + +#. + Set the classpath and initialize the JDBC driver which was previously installed. For example, on Windows: + + .. code-block:: rconsole + + > cp = c("C:\\Program Files\\SQream Technologies\\JDBC Driver\\2020.1-3.2.0\\sqream-jdbc-3.2.jar") + > .jinit(classpath=cp) + > drv <- JDBC("com.sqream.jdbc.SQDriver","C:\\Program Files\\SQream Technologies\\JDBC Driver\\2020.1-3.2.0\\sqream-jdbc-3.2.jar") +#. + Open a connection with a :ref:`JDBC connection string` and run your first statement + + .. code-block:: rconsole + + > con <- dbConnect(drv,"jdbc:Sqream://127.0.0.1:3108/master;user=rhendricks;password=Tr0ub4dor&3;cluster=true") + + > dbGetQuery(con,"select top 5 * from t") + xint xtinyint xsmallint xbigint + 1 1 82 5067 1 + 2 2 14 1756 2 + 3 3 91 22356 3 + 4 4 84 17232 4 + 5 5 13 14315 5 + +#. + Close the connection + + .. code-block:: rconsole + + > close(con) + +A full example +----------------- + +.. code-block:: rconsole + + > library(RJDBC) + > cp = c("C:\\Program Files\\SQream Technologies\\JDBC Driver\\2020.1-3.2.0\\sqream-jdbc-3.2.jar") + > .jinit(classpath=cp) + > drv <- JDBC("com.sqream.jdbc.SQDriver","C:\\Program Files\\SQream Technologies\\JDBC Driver\\2020.1-3.2.0\\sqream-jdbc-3.2.jar") + > con <- dbConnect(drv,"jdbc:Sqream://127.0.0.1:3108/master;user=rhendricks;password=Tr0ub4dor&3;cluster=true") + > dbGetQuery(con,"select top 5 * from t") + xint xtinyint xsmallint xbigint + 1 1 82 5067 1 + 2 2 14 1756 2 + 3 3 91 22356 3 + 4 4 84 17232 4 + 5 5 13 14315 5 + > close(con) + +ODBC +========= + +#. Install the :ref:`SQream DB ODBC driver` for your operating system, and create a DSN. + +#. + In R, install RODBC + + .. code-block:: rconsole + + > install.packages("RODBC") + Installing package into 'C:/Users/r/...' + (as 'lib' is unspecified) + + package 'RODBC' successfully unpacked and MD5 sums checked + +#. + Import the RODBC library + + .. code-block:: rconsole + + > library(RODBC) + +#. + Open a connection handle to an existing DSN (``my_cool_dsn`` in this example) + + .. code-block:: rconsole + + > ch <- odbcConnect("my_cool_dsn",believeNRows=F) + +#. + Run your first statement + + .. code-block:: rconsole + + > sqlQuery(ch,"select top 5 * from t") + xint xtinyint xsmallint xbigint + 1 1 82 5067 1 + 2 2 14 1756 2 + 3 3 91 22356 3 + 4 4 84 17232 4 + 5 5 13 14315 5 + +#. + Close the connection + + .. code-block:: rconsole + + > close(ch) + +A full example +----------------- + +.. code-block:: rconsole + + > library(RODBC) + > ch <- odbcConnect("my_cool_dsn",believeNRows=F) + > sqlQuery(ch,"select top 5 * from t") + xint xtinyint xsmallint xbigint + 1 1 82 5067 1 + 2 2 14 1756 2 + 3 3 91 22356 3 + 4 4 84 17232 4 + 5 5 13 14315 5 + > close(ch) diff --git a/connecting_to_sqream/client_platforms/sas_viya.rst b/connecting_to_sqream/client_platforms/sas_viya.rst new file mode 100644 index 000000000..83942ccfd --- /dev/null +++ b/connecting_to_sqream/client_platforms/sas_viya.rst @@ -0,0 +1,185 @@ +.. _connect_to_sas_viya: + +************************* +Connect to SQream Using SAS Viya +************************* + +Overview +========== +SAS Viya is a cloud-enabled analytics engine used for producing useful insights. The **Connect to SQream Using SAS Viya** page describes how to connect to SAS Viya, and describes the following: + +.. contents:: + :local: + :depth: 1 + +Installing SAS Viya +------------------- +The **Installing SAS Viya** section describes the following: + +.. contents:: + :local: + :depth: 1 + +Downloading SAS Viya +~~~~~~~~~~~~~~~~~~ +Integrating with SQream has been tested with SAS Viya v.03.05 and newer. + +To download SAS Viya, see `SAS Viya `_. + +Installing the JDBC Driver +~~~~~~~~~~~~~~~~~~ +The SQream JDBC driver is required for establishing a connection between SAS Viya and SQream. + +**To install the JDBC driver:** + +#. Download the `JDBC driver `_. + + :: + +#. Unzip the JDBC driver into a location on the SAS Viya server. + + SQream recommends creating the directory ``/opt/sqream`` on the SAS Viya server. + +Configuring SAS Viya +------------------- +After installing the JDBC driver, you must configure the JDBC driver from the SAS Studio so that it can be used with SQream Studio. + +**To configure the JDBC driver from the SAS Studio:** + +#. Sign in to the SAS Studio. + + :: + +#. From the **New** menu, click **SAS Program**. + + :: + +#. Configure the SQream JDBC connector by adding the following rows: + + .. literalinclude:: connect3.sas + :language: php + +For more information about writing a connection string, see **Connect to SQream DB with a JDBC Application** and navigate to `Connection String `_. + +Operating SAS Viya +-------------------- +The **Operating SAS Viya** section describes the following: + +.. contents:: + :local: + :depth: 1 + +Using SAS Viya Visual Analytics +~~~~~~~~~~~~~~~~~~ +This section describes how to use SAS Viya Visual Analytics. + +**To use SAS Viya Visual Analytics:** + +#. Log in to `SAS Viya Visual Analytics `_ using your credentials: + + :: + +2. Click **New Report**. + + :: + +3. Click **Data**. + + :: + +4. Click **Data Sources**. + + :: + +5. Click the **Connect** icon. + + :: + +6. From the **Type** menu, select **Database**. + + :: + +7. Provide the required information and select **Persist this connection beyond the current session**. + + :: + +8. Click **Advanced** and provide the required information. + + :: + +9. Add the following additional parameters by clicking **Add Parameters**: + +.. list-table:: + :widths: 10 90 + :header-rows: 1 + + * - Name + - Value + * - class + - com.sqream.jdbc.SQDriver + * - classPath + - ** + * - url + - \jdbc:Sqream://**:**/**;cluster=true + * - username + - + * - password + - + +10. Click **Test Connection**. + + :: + +11. If the connection is successful, click **Save**. + +If your connection is not successful, see :ref:`troubleshooting_sas_viya` below. + +.. _troubleshooting_sas_viya: + +Troubleshooting SAS Viya +------------------------- +The **Best Practices and Troubleshooting** section describes the following best practices and troubleshooting procedures when connecting to SQream using SAS Viya: + +.. contents:: + :local: + :depth: 1 + +Inserting Only Required Data +~~~~~~~~~~~~~~~~~~ +When using SAS Viya, SQream recommends using only data that you need, as described below: + +* Insert only the data sources you need into SAS Viya, excluding tables that don’t require analysis. + + :: + +* To increase query performance, add filters before analyzing. Every modification you make while analyzing data queries the SQream database, sometimes several times. Adding filters to the datasource before exploring limits the amount of data analyzed and increases query performance. + +Creating a Separate Service for SAS Viya +~~~~~~~~~~~~~~~~~~ +SQream recommends creating a separate service for SAS Viya with the DWLM. This reduces the impact that Tableau has on other applications and processes, such as ETL. In addition, this works in conjunction with the load balancer to ensure good performance. + +Locating the SQream JDBC Driver +~~~~~~~~~~~~~~~~~~ +In some cases, SAS Viya cannot locate the SQream JDBC driver, generating the following error message: + +.. code-block:: text + + java.lang.ClassNotFoundException: com.sqream.jdbc.SQDriver + +**To locate the SQream JDBC driver:** + +1. Verify that you have placed the JDBC driver in a directory that SAS Viya can access. + + :: + +2. Verify that the classpath in your SAS program is correct, and that SAS Viya can access the file that it references. + + :: + +3. Restart SAS Viya. + +For more troubleshooting assistance, see the `SQream Support Portal `_. + +Supporting TEXT +~~~~~~~~~~~~~~~~~~ +In SAS Viya versions lower than 4.0, casting ``TEXT`` to ``CHAR`` changes the size to 1,024, such as when creating a table including a ``TEXT`` column. This is resolved by casting ``TEXT`` into ``CHAR`` when using the JDBC driver. \ No newline at end of file diff --git a/connecting_to_sqream/client_platforms/sql_workbench.rst b/connecting_to_sqream/client_platforms/sql_workbench.rst new file mode 100644 index 000000000..16265ebd4 --- /dev/null +++ b/connecting_to_sqream/client_platforms/sql_workbench.rst @@ -0,0 +1,135 @@ +.. _connect_to_sql_workbench: + +***************************** +Connect to SQream Using SQL Workbench +***************************** + +You can use SQL Workbench to interact with a SQream DB cluster. SQL Workbench/J is a free SQL query tool, and is designed to run on any JRE-enabled environment. + +This tutorial is a guide that will show you how to connect SQL Workbench to SQream DB. + +.. contents:: In this topic: + :local: + +Installing SQL Workbench with the SQream DB installer (Windows only) +===================================================================== + +SQream DB's driver installer for Windows can install the Java prerequisites and SQL Workbench for you. + +#. Get the JDBC driver installer available for download from the `SQream Drivers page `_. The Windows installer takes care of the Java prerequisites and subsequent configuration. + +#. Install the driver by following the on-screen instructions in the easy-to-follow installer. + By default, the installer does not install SQL Workbench. Make sure to select the item! + + .. image:: /_static/images/jdbc_windows_installer_screen.png + +.. note:: The installer will install SQL Workbench in ``C:\Program Files\SQream Technologies\SQLWorkbench`` by default. You can change this path during the installation. + +#. Once finished, SQL Workbench is installed and contains the necessary configuration for connecting to SQream DB clusters. + +#. Start SQL Workbench from the Windows start menu. Be sure to select **SQL Workbench (64)** if you're on 64-bit Windows. + + .. image:: /_static/images/sql_workbench_launch.png + +You are now ready to create a profile for your cluster. Continue to :ref:`Creating a new connection profile `. + +Installing SQL Workbench manually (Linux, MacOS) +=================================================== + +Install Java Runtime +------------------------ + +Both SQL Workbench and the SQream DB JDBC driver require Java 1.8 or newer. You can install either Oracle Java or OpenJDK. + +**Oracle Java** + +Download and install Java 8 from Oracle for your platform - https://www.java.com/en/download/manual.jsp + +**OpenJDK** + +For Linux and BSD, see https://openjdk.java.net/install/ + +For Windows, SQream recommends Zulu 8 https://www.azul.com/downloads/zulu-community/?&version=java-8-lts&architecture=x86-64-bit&package=jdk + +Get the SQream DB JDBC driver +------------------------------- + +SQream DB's JDBC driver is provided as a zipped JAR file, available for download from the `SQream Drivers page `_. + +Download and extract the JAR file from the zip archive. + +Install SQL Workbench +----------------------- + +#. Download the latest stable release from https://www.sql-workbench.eu/downloads.html . The **Generic package for all systems** is recommended. + +#. Extract the downloaded ZIP archive into a directory of your choice. + +#. Start SQL workbench. If you are using 64 bit windows, run ``SQLWorkbench64.exe`` instead of ``SQLWOrkbench.exe``. + +Setting up the SQream DB JDBC driver profile +--------------------------------------------- + +#. Define a connection profile - :menuselection:`&File --> &Connect window (Alt+C)` + + .. image:: /_static/images/sql_workbench_connect_window1.png + +#. Open the drivers management window - :menuselection:`&Manage Drivers` + + .. image:: /_static/images/sql_workbench_manage_drivers.png + + + +#. Create the SQream DB driver profile + + .. image:: /_static/images/sql_workbench_create_driver.png + + #. Click on the Add new driver button ("New" icon) + + #. Name the driver as you see fit. We recommend calling it SQream DB , where is the version you have installed. + + #. + Add the JDBC drivers from the location where you extracted the SQream DB JDBC JAR. + + If you used the SQream installer, the file will be in ``C:\Program Files\SQream Technologies\JDBC Driver\`` + + #. Click the magnifying glass button to detect the classname automatically. Other details are purely optional + + #. Click OK to save and return to "new connection screen" + + +.. _new_connection_profile: + +Create a new connection profile for your cluster +===================================================== + + .. image:: /_static/images/sql_workbench_connection_profile.png + +#. Create new connection by clicking the New icon (top left) + +#. Give your connection a descriptive name + +#. Select the SQream Driver that was created in the previous screen + +#. Type in your connection string. To find out more about your connection string (URL), see the :ref:`Connection string documentation `. + +#. Text the connection details + +#. Click OK to save the connection profile and connect to SQream DB + +Suggested optional configuration +================================== + +If you installed SQL Workbench manually, you can set a customization to help SQL Workbench show information correctly in the DB Explorer panel. + +#. Locate your workbench.settings file + On Windows, typically: ``C:\Users\\.sqlworkbench\workbench.settings`` + On Linux, ``$HOME/.sqlworkbench`` + +#. Add the following line at the end of the file: + + .. code-block:: text + + workbench.db.sqreamdb.schema.retrieve.change.catalog=true + +#. Save the file and restart SQL Workbench diff --git a/connecting_to_sqream/client_platforms/tableau.rst b/connecting_to_sqream/client_platforms/tableau.rst new file mode 100644 index 000000000..ac67c8d55 --- /dev/null +++ b/connecting_to_sqream/client_platforms/tableau.rst @@ -0,0 +1,453 @@ +.. _connect_to_tableau: + +************************* +Connecting to SQream Using Tableau +************************* + +Overview +===================== +SQream's Tableau connector plugin, based on standard JDBC, enables storing and fast querying large volumes of data. + +The **Connecting to SQream Using Tableau** page is a Quick Start Guide that describes how install Tableau and the JDBC and ODBC drivers and connect to SQream using the JDBC and ODBC drivers for data analysis. It also describes using best practices and troubleshoot issues that may occur while installing Tableau. SQream supports both Tableau Desktop and Tableau Server on Windows, MacOS, and Linux distributions. + +For more information on SQream's integration with Tableau, see `Tableau's Extension Gallery `_. + +The Connecting to SQream Using Tableau page describes the following: + +.. contents:: + :local: + +Installing the JDBC Driver and Tableau Connector Plugin +------------------- +This section describes how to install the JDBC driver using the fully-integrated Tableau connector plugin (Tableau Connector, or **.taco** file). SQream has been tested with Tableau versions 9.2 and newer. + +**To connect to SQream using Tableau:** + +#. Install the Tableau Desktop application. + + For more information about installing the Tableau Desktop application, see the `Tableau products page `_ and click **Download Free Trial**. Note that Tableau offers a 14-day trial version. + + :: + +#. Do one of the following: + + * **For Windows** - See :ref:`Installing Tableau Using the Windows Installer `. + * **For MacOS or Linux** - See :ref:`Installing the JDBC Driver Manually `. + +.. note:: For Tableau **2019.4 versions and later**, SQream recommends installing the JDBC driver instead of the previously recommended ODBC driver. + +.. _tableau_windows_installer: + +Installing the JDBC Driver Using the Windows Installer +~~~~~~~~~~~~~~~~~~ +If you are using Windows, after installing the Tableau Desktop application you can install the JDBC driver using the Windows installer. The Windows installer is an installation wizard that guides you through the JDBC driver installation steps. When the driver is installed, you can connect to SQream. + +**To install Tableau using the Windows installer**: + +#. Close Tableau Desktop. + + :: + +#. Download the most current version of the `SQream JDBC driver `_. + + :: + +#. Do the following: + + #. Start the installer. + #. Verify that the **Tableau Desktop connector** item is selected. + #. Follow the installation steps. + + :: + +You can now restart Tableau Desktop or Server to begin using the SQream driver by :ref:`connecting to SQream `. + +.. _tableau_jdbc_installer: + +Installing the JDBC Driver Manually +~~~~~~~~~~~~~ +If you are using MacOS, Linux, or the Tableau server, after installing the Tableau Desktop application you can install the JDBC driver manually. When the driver is installed, you can connect to SQream. + +**To install the JDBC driver manually:** + +1. Download the JDBC installer and SQream Tableau connector (.taco) file from the :ref:`from the client drivers page`. + + :: + +#. Install the JDBC driver by unzipping the JDBC driver into a Tableau driver directory. + + Based on the installation method that you used, your Tableau driver directory is located in one of the following places: + + * **Tableau Desktop on Windows:** *C:\\Program Files\\Tableau\\Drivers* + * **Tableau Desktop on MacOS:** *~/Library/Tableau/Drivers* + * **Tableau on Linux**: */opt/tableau/tableau_driver/jdbc* + +.. note:: If the driver includes only a single .jar file, copy it to *C:\\Program Files\\Tableau/Drivers*. If the driver includes multiple files, create a subfolder *A* in *C:\\Program Files\\Tableau/Drivers* and copy all files to folder *A*. + +Note the following when installing the JDBC driver: + +* You must have read permissions on the .jar file. +* Tableau requires a JDBC 4.0 or later driver. +* Tableau requires a Type 4 JDBC driver. +* The latest 64-bit version of Java 8 is installed. + +3. Install the **SQreamDB.taco** file by moving the SQreamDB.taco file into the Tableau connectors directory. + + Based on the installation method that you used, your Tableau driver directory is located in one of the following places: + + * **Tableau Desktop on Windows:** *C:\\Users\\\\My Tableau Repository\\Connectors* + * **Tableau Desktop on Mac:** *~/My Tableau Repository/Connectors* + + :: + +4. *Optional* - If you are using the Tableau Server, do the following: + + 1. Create a directory for Tableau connectors and give it a descriptive name, such as *C:\\tableau_connectors*. + + This directory needs to exist on all Tableau servers. + + :: + + 2. Copy the SQreamDB.taco file into the new directory. + + :: + + 3. Set the **native_api.connect_plugins_path** option to ``tsm`` as shown in the following example: + + .. code-block:: console + + $ tsm configuration set -k native_api.connect_plugins_path -v C:/tableau_connectors + + If a configuration error is displayed, add ``--force-keys`` to the end of the command as shown in the following example: + + .. code-block:: console + + $ tsm configuration set -k native_api.connect_plugins_path -v C:/tableau_connectors--force-keys + + 4. To apply the pending configuration changes, run the following command: + + .. code-block:: console + + $ tsm pending-changes apply + + .. warning:: This restarts the server. + +You can now restart Tableau Desktop or Server to begin using the SQream driver by :ref:`connecting to SQream ` as described in the section below. + +.. _tableau_connect_to_sqream: + + +Installing the ODBC Driver for Tableau Versions 2019.3 and Earlier +-------------- + + +This section describes the installation method for Tableau version 2019.3 or earlier and describes the following: + +.. contents:: + :local: + +.. note:: SQream recommends installing the JDBC driver to provide improved connectivity. + +Automatically Reconfiguring the ODBC Driver After Initial Installation +~~~~~~~~~~~~~~~~~~ +If you've already installed the SQream ODBC driver and installed Tableau, SQream recommends reinstalling the ODBC driver with the **.TDC Tableau Settings for SQream DB** configuration shown in the image below: + +.. image:: /_static/images/odbc_windows_installer_tableau.png + +SQream recommends this configuration because Tableau creates temporary tables and runs several discovery queries that may impact performance. The ODBC driver installer avoids this by automatically reconfiguring Tableau. + +For more information about reinstalling the ODBC driver installer, see :ref:`Install and Configure ODBC on Windows `. + +If you want to manually reconfigure the ODBC driver, see :ref:`Manually Reconfiguring the ODBC Driver After Initial Installation ` below. + +.. _manually_reconfigure_odbc_driver: + +Manually Reconfiguring the ODBC Driver After Initial Installation +~~~~~~~~~~~~~~~~~~ +The file **Tableau Datasource Customization (TDC)** file lets you use Tableau make full use of SQream DB's features and capabilities. + +**To manually reconfigure the ODBC driver after initial installation:** + +1. Do one of the following: + + 1. Download the :download:`odbc-sqream.tdc ` file to your machine and open it in a text editor. + + :: + + 2. Copy the text below into a text editor: + + .. literalinclude:: odbc-sqream.tdc + :language: xml + :caption: SQream ODBC TDC File + :emphasize-lines: 2 + +#. Check which version of Tableau you are using. + + :: + +#. In the text of the file shown above, in the highlighted line, replace the version number with the **major** version of Tableau that you are using. + + For example, if you are using Tableau vesion **2019.2.1**, replace it with **2019.2**. + + :: + +#. Do one of the following: + + * If you are using **Tableau Desktop** - save the TDC file to *C:\\Users\\\\Documents\\My Tableau Repository\\Datasources*, where ```` is the Windows username that you have installed Tableau under. + + :: + + * If you are using the **Tableau Server** - save the TDC file to *C:\\ProgramData\\Tableau\\Tableau Server\\data\\tabsvc\\vizqlserver\\Datasources*. + +Configuring the ODBC Connection +~~~~~~~~~~~~ +The ODBC connection uses a DSN when connecting to ODBC data sources, and each DSN represents one SQream database. + +**To configure the ODBC connection:** + +1. Create an ODBC DSN. + + :: + +#. Open the Windows menu by pressing the Windows button (:kbd:`⊞ Win`) or clicking the **Windows** menu button. + + :: + +#. Type **ODBC** and select **ODBC Data Sources (64-bit)**. + + During installation, the installer created a sample user DSN named **SQreamDB**. + + :: + +#. *Optional* - Do one or both of the following: + + * Modify the DSN name. + + :: + + * Create a new DSN name by clicking **Add** and selecting **SQream ODBC Driver**. + +.. image:: /_static/images/odbc_windows_dsns.png + + +5. Click **Finish**. + + :: + +6. Enter your connection parameters. + + The following table describes the connection parameters: + + .. list-table:: + :widths: 15 38 38 + :header-rows: 1 + + * - Item + - Description + - Example + * - Data Source Name + - The Data Source Name. SQream recommends using a descriptive and easily recognizable name for referencing your DSN. Once set, the Data Source Name cannot be changed. + - + * - Description + - The description of your DSN. This field is optional. + - + * - User + - The username of a role to use for establishing the connection. + - ``rhendricks`` + * - Password + - The password of the selected role. + - ``Tr0ub4dor`` + * - Database + - The database name to connect to. For example, ``master`` + - ``master`` + * - Service + - The :ref:`service queue` to use. + - For example, ``etl``. For the default service ``sqream``, leave blank. + * - Server + - The hostname of the SQream worker. + - ``127.0.0.1`` or ``sqream.mynetwork.co`` + * - Port + - The TCP port of the SQream worker. + - ``5000`` or ``3108`` + * - User Server Picker + - Uses the load balancer when establishing a connection. Use only if exists, and check port. + - + * - SSL + - Uses SSL when establishing a connection. + - + * - Logging Options + - Lets you modify your logging options when tracking the ODBC connection for connection issues. + - + +.. tip:: Test the connection by clicking **Test** before saving your DSN. + +7. Save the DSN by clicking **OK.** + +Connecting Tableau to SQream +~~~~~~~~~~~~ +**To connect Tableau to SQream:** + +1. Start Tableau Desktop. + + :: + +#. In the **Connect** menu, in the **To a server** sub-menu, click **More Servers** and select **Other Databases (ODBC)**. + + The **Other Databases (ODBC)** window is displayed. + + :: + +#. In the Other Databases (ODBC) window, select the DSN that you created in :ref:`Setting Up SQream Tables as Data Sources `. + + Tableau may display the **Sqream ODBC Driver Connection Dialog** window and prompt you to provide your username and password. + +#. Provide your username and password and click **OK**. + +.. _tableau_connect_to_sqream_db: + + +Connecting to SQream +--------------------- +After installing the JDBC driver you can connect to SQream. + +**To connect to SQream:** + +#. Start Tableau Desktop. + + :: + +#. In the **Connect** menu, in the **To a Server** sub-menu, click **More...**. + + More connection options are displayed. + + :: + +#. Select **SQream DB by SQream Technologies**. + + The **New Connection** dialog box is displayed. + + :: + +#. In the New Connection dialog box, fill in the fields and click **Sign In**. + + The following table describes the fields: + + .. list-table:: + :widths: 15 38 38 + :header-rows: 1 + + * - Item + - Description + - Example + * - Server + - Defines the server of the SQream worker. + - ``127.0.0.1`` or ``sqream.mynetwork.co`` + * - Port + - Defines the TCP port of the SQream worker. + - ``3108`` when using a load balancer, or ``5100`` when connecting directly to a worker with SSL. + * - Database + - Defines the database to establish a connection with. + - ``master`` + * - Cluster + - Enables (``true``) or disables (``false``) the load balancer. After enabling or disabling the load balance, verify the connection. + - + * - Username + - Specifies the username of a role to use when connecting. + - ``rhendricks`` + * - Password + - Specifies the password of the selected role. + - ``Tr0ub4dor&3`` + * - Require SSL (recommended) + - Sets SSL as a requirement for establishing this connection. + - + +The connection is established and the data source page is displayed. + +.. tip:: + Tableau automatically assigns your connection a default name based on the DSN and table. SQream recommends giving the connection a more descriptive name. + +.. _set_up_sqream_tables_as_data_sources: + +Setting Up SQream Tables as Data Sources +---------------- +After connecting to SQream you must set up the SQream tables as data sources. + +**To set up SQream tables as data sources:** + +1. From the **Table** menu, select the desired database and schema. + + SQream's default schema is **public**. + + :: + +#. Drag the desired tables into the main area (labeled **Drag tables here**). + + This area is also used for specifying joins and data source filters. + + :: + +#. Open a new sheet to analyze data. + +.. tip:: + For more information about configuring data sources, joining, filtering, see Tableau's `Set Up Data Sources `_ tutorials. + +Tableau Best Practices and Troubleshooting +--------------- +This section describes the following best practices and troubleshooting procedures when connecting to SQream using Tableau: + +.. contents:: + :local: + +Inserting Only Required Data +~~~~~~~~~~~~~~~~~~ +When using Tableau, SQream recommends using only data that you need, as described below: + +* Insert only the data sources you need into Tableau, excluding tables that don't require analysis. + + :: + +* To increase query performance, add filters before analyzing. Every modification you make while analyzing data queries the SQream database, sometimes several times. Adding filters to the datasource before exploring limits the amount of data analyze and increases query performance. + +Using Tableau's Table Query Syntax +~~~~~~~~~~~~~~~~~~~ +Dragging your desired tables into the main area in Tableau builds queries based on its own syntax. This helps ensure increased performance, while using views or custom SQL may degrade performance. In addition, SQream recommends using the :ref:`create_view` to create pre-optimized views, which your datasources point to. + +Creating a Separate Service for Tableau +~~~~~~~~~~~~~~~~~~~ +SQream recommends creating a separate service for Tableau with the DWLM. This reduces the impact that Tableau has on other applications and processes, such as ETL. In addition, this works in conjunction with the load balancer to ensure good performance. + +Troubleshooting Workbook Performance Before Deploying to the Tableau Server +~~~~~~~~~~~~~~~~~~~ +Tableau has a built-in `performance recorder `_ that shows how time is being spent. If you're seeing slow performance, this could be the result of a misconfiguration such as setting concurrency too low. + +Use the Tableau Performance Recorder for viewing the performance of queries run by Tableau. You can use this information to identify queries that can be optimized by using views. + +Troubleshooting Error Codes +~~~~~~~~~~~~~~~~~~~ +Tableau may be unable to locate the SQream JDBC driver. The following message is displayed when Tableau cannot locate the driver: + +.. code-block:: console + + Error Code: 37CE01A3, No suitable driver installed or the URL is incorrect + +**To troubleshoot error codes:** + +If Tableau cannot locate the SQream JDBC driver, do the following: + + 1. Verify that the JDBC driver is located in the correct directory: + + * **Tableau Desktop on Windows:** *C:\Program Files\Tableau\Drivers* + * **Tableau Desktop on MacOS:** *~/Library/Tableau/Drivers* + * **Tableau on Linux**: */opt/tableau/tableau_driver/jdbc* + + 2. Find the file path for the JDBC driver and add it to the Java classpath: + + * **For Linux** - ``export CLASSPATH=;$CLASSPATH`` + + :: + + * **For Windows** - add an environment variable for the classpath: + + .. image:: /_static/images/Third_Party_Connectors/tableau/envrionment_variable_for_classpath.png + +If you experience issues after restarting Tableau, see the `SQream support portal `_. \ No newline at end of file diff --git a/connecting_to_sqream/client_platforms/talend.rst b/connecting_to_sqream/client_platforms/talend.rst new file mode 100644 index 000000000..2a4d2658a --- /dev/null +++ b/connecting_to_sqream/client_platforms/talend.rst @@ -0,0 +1,204 @@ +.. _talend: + +************************* +Connecting to SQream Using Talend +************************* + +.. _top: + +Overview +================= + +This page describes how to use Talend to interact with a SQream DB cluster. The Talend connector is used for reading data from a SQream DB cluster and loading data into SQream DB. + +In addition, this page provides a viability report on Talend's comptability with SQream DB for stakeholders. + +It includes the following: + +* :ref:`A Quick Start guide ` +* :ref:`Information about supported SQream drivers ` +* :ref:`Supported data sources ` and :ref:`tool and operating system versions ` +* :ref:`A description of known issues ` +* :ref:`Related links ` + + +About Talend +================= +Talend is an open-source data integration platform. It provides various software and services for Big Data integration and management, enterprise application integration, data quality and cloud storage. + +For more information about Talend, see `Talend `_. + + +.. _quickstart_guide: + +Quick Start Guide +======================= + +Creating a New Metadata JDBC DB Connection +------------- +**To create a new metadata JDBC DB connection:** + +1. In the **Repository** panel, nagivate to **Metadata** and right-click **Db connections**. + +.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_1.png + +2. Select **Create connection**. + +.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_2.png + +3. In the **Name** field, type a name. + +.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_3.png + +The name cannot contain spaces. + +4. In the **Purpose** field, type a purpose and click **Next**. You cannot go to the next step until you define both a Name and a Purpose. + +.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_4.png + +5. In the **DB Type** field, select **JDBC**. + +.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_5.png + +6. In the **JDBC URL** field, type the relevant connection string. + + For connection string examples, see `Connection Strings `_. + +.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_6.png + +7. In the **Drivers** field, click the **Add** button. + + The **"newLine** entry is added. + +.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_7.png + +8. One the **"newLine** entry, click the ellipsis. + +.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_8.png + +The **Module** window is displayed. + +9. From the Module window, select **Artifact repository(local m2/nexus)** and select **Install a new module**. + +.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_9.png + +10. Click the ellipsis. + +.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_9.5.png + +Your hard drive is displayed. + +11. Navigate to a **JDBC jar file** (such as **sqream-jdbc-4.4.0.jar**)and click **Open**. + +.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_10.png + +12. Click **Detect the module install status**. + +.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_11.5.png + +13. Click **OK**. + +The JDBC that you selected is displayed in the **Driver** field. + +.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_12.png + +14. Click **Select class name**. + +.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_13.png + +15. Click **Test connection**. + +.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_14.png + +If a driver class is not found (for example, you didn't select a JDBC jar file), the following error message is displayed: + +.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_15.png + +After creating a new metadata JDBC DB connection, you can do the following: + + * Use your new metadata connection. + * Drag it to the **job** screen. + * Build Talend components. + +For more information on loading data from JSON files to the Talend Open Studio, see `How to Load Data from JSON Files in Talend `_. + +:ref:`Back to top ` + +.. _supported_sqream_drivers: + +Supported SQream Drivers +================ + +The following list shows the supported SQream drivers and versions: + +* **JDBC** - Version 4.3.3 and higher. +* **ODBC** - Version 4.0.0. This version requires a Bridge to connect. For more information on the required Bridge, see `Connecting Talend on Windows to an ODBC Database `_. + +:ref:`Back to top ` + + +.. _supported_data_sources: + +Supported Data Sources +============================ +Talend Cloud connectors let you create reusable connections with a wide variety of systems and environments, such as those shown below. This lets you access and read records of a range of diverse data. + +* **Connections:** Connections are environments or systems for storing datasets, including databases, file systems, distributed systems and platforms. Because these systems are reusable, you only need to establish connectivity with them once. + +* **Datasets:** Datasets include database tables, file names, topics (Kafka), queues (JMS) and file paths (HDFS). For more information on the complete list of connectors and datasets that Talend supports, see `Introducing Talend Connectors `_. + +:ref:`Back to top ` + + +.. _supported_tools_os_sys_versions: + +Supported Tool and Operating System Versions +====================== +Talend was tested using the following: + +* Talend version 7.4.1M6 +* Windows 10 +* SQream version 2021.1 +* JDBC version + + + + +:ref:`Back to top ` + + +.. _known_issues: + +Known Issues +=========================== +The the list below describes the following known issues as of 6/1/2021: + +* Schemas not displayed for tables with identical names. + +:ref:`Back to top ` + + +.. _related_links: + +Related Links +=============== +The following is a list of links relevant to the Talend connector: + +* `Talend Home page `_ +* `Talend Community page `_ +* `Talend BugTracker `_ + + +Download Links +================== +The following is a list of download links relevant to the Talend connector: + +* `Talend Open Studio for Big Data `_ +* `Latest version of SQream JDBC `_ + +:ref:`Back to top ` + + + +.. contents:: In this topic: + :local: diff --git a/connecting_to_sqream/client_platforms/test.php b/connecting_to_sqream/client_platforms/test.php new file mode 100644 index 000000000..88ec88338 --- /dev/null +++ b/connecting_to_sqream/client_platforms/test.php @@ -0,0 +1,16 @@ + diff --git a/connecting_to_sqream/client_platforms/tibco_spotfire.rst b/connecting_to_sqream/client_platforms/tibco_spotfire.rst new file mode 100644 index 000000000..4c032ba84 --- /dev/null +++ b/connecting_to_sqream/client_platforms/tibco_spotfire.rst @@ -0,0 +1,387 @@ +.. _tibco_spotfire: + + +************************* +Connecting to SQream Using TIBCO Spotfire +************************* +Overview +========= +The **TIBCO Spotfire** software is an analytics solution that enables visualizing and exploring data through dashboards and advanced analytics. + +This document is a Quick Start Guide that describes the following: + +.. contents:: + :local: + :depth: 1 + +Establishing a Connection between TIBCO Spotfire and SQream +----------------- +TIBCO Spotfire supports the following versions: + +* **JDBC driver** - Version 4.5.2 +* **ODBC driver** - Version 4.1.1 + +SQream supports TIBCO Spotfire version 7.12.0. + +The **Establishing a JDBC Connection between TIBCO Spotfire and SQream** section describes the following: + +.. contents:: + :local: + :depth: 1 + +Creating a JDBC Connection +~~~~~~~~~~~ +For TIBCO Spotfire to recognize SQream, you must add the correct JDBC jar file to Spotfire's loaded binary folder. The following is an example of a path to the Spotfire loaded binaries folder: ``C:\tibco\tss\7.12.0\tomcat\bin``. + +For the complete TIBCO Spotfire documentation, see `TIBCO Spotfire® JDBC Data Access Connectivity Details `_. + +Creating an ODBC Connection +~~~~~~~~~~~ +**To create an ODBC connection** + +1. Install and configure ODBC on Windows. + + For more information, see :ref:`Install and Configure ODBC on Windows`. + +#. Launch the TIBCO Spotfire application. + + :: + +#. From the **File** menu click **Add Data Tables**. + + The **Add Database Tables** window is displayed. + +#. Click **Add** and select **Database**. + + The **Open Database** window is displayed. + +#. In the **Data source type** area, select **ODBC SQream** (Odbc Data Provider) and click **Configure**. + + The **Configure Data Source and Connection** window is displayed. + +#. Select **System or user data source** and from the drop-down menu select the DSN of your data source (SQreamDB). + + :: + +#. Provide your database username and password and click **OK**. + + :: + +#. In the **Open Database** window, click **OK**. + + The **Specify Tables and Columns** window is displayed. + +#. In the **Specify Tables and Columns** window, select the checkboxes corresponding to the tables and columns that you want to include in your SQL statement. + + :: + +#. In the **Data source name** field, set your data source name and click **OK**. + + Your data source is displayed in the **Data tables** area. + +#. In the **Add Data Tables** dialog, click **OK** to load the data from your ODBC data source into Spotfire. + +.. note:: Verify that you have checked the SQL statement. + +Creating the SQream Data Source Template +~~~~~~~~~~~ +After creating a connection, you can create your SQream data source template. + +**To create your SQream data source template:** + +1. Log in to the TIBCO Spotfire Server Configuration Tool. + + :: + +#. From the **Configuration** tab, in the **Configuration Start** menu, click **Data Source Templates**. + + The **Data Source Templates** list is displayed. + +#. From the Data Source Templates list do one of the following: + + * Override an existing template: + + 1. In the template text field, select an existing template. + + :: + + 2. Copy and paste your data source template text. + + :: + + * Create a new template: + + 1. Click **New**. + + The **Add Data Source Template** window is displayed. + + .. _creating_sqream_data_source_template: + + 2. In the **Name** field, define your template name. + + :: + + 3. In the **Data Source Template** text field, copy and paste your data source template text. + + The following is an example of a data source template: + + .. code-block:: console + + + SQream + com.sqream.jdbc.SQDriver + jdbc:Sqream://<host>:<port>/database;user=sqream;password=sqream;cluster=true + true + true + false + TABLE,EXTERNAL_TABLE + + + Bool + Integer + + + VARCHAR(2048) + String + + + INT + Integer + + + BIGINT + LongInteger + + + Real + Real + + + Decimal + Float + + + Numeric + Float + + + Date + DATE + + + DateTime + DateTime + + + + + +4. Click **Save configuration**. + + :: + +5. Close and restart your Spotfire server. + +Creating a Data Source +~~~~~~~~~~~ +After creating the SQream data source template, you can create a data source. + +**To create a data source:** + +1. Launch the TIBCO Spotfire application. + + :: + +#. From the **Tools** menu, select **Information Designer**. + + The **Information Designer** window is displayed. + + :: + +#. From the **New** menu, click **Data Source**. + + The **Data Source** tab is displayed. + + :: + +#. Provide the following information: + + * **Name** - define a unique name. + + :: + + * **Type** - use the same type template name you used while configuring your template. See **Step 3** in :ref:`Creating the SQream Data Source Template`. + + :: + + * **Connection URL** - use the standard JDBC connection string, ``:/database``. + + :: + + * **No. of connections** - define a number between **1** and **100**. SQream recommends setting your number of connections to **100**. + + :: + + * **Username and Password** - define your SQream username and password. + +Creating an Information Link +~~~~~~~~~~~ +After creating a data source, you can create an information link. + +**To create an information link**: + +1. From the **Tools** menu, select **Information Designer**. + + The **Information Designer** window is displayed. + + :: + +#. From the **New** menu, click **Information Link**. + + The **Information link** tab is displayed. + +#. From the **Elements** tab, select a column type and click **Add**. + + The column type is added to the **Elements** region as a filter. + + Note the following: + + * You can select procedures from the Elements region. + + :: + + * You can remove an element by selecting an element and clicking **Remove**. + + .. tip:: If the Elements menu is not displayed, you can display it by clicking the **Elements** tab. You can simultaneously select multiple elements by pressing **Ctrl** and making additional selections, and select a range of elements by holding **Shift** and clicking two elements. + +#. If the elements you select originate from more than one data source table, specify a **Join path**. + +5. *Optional* - In the **Description** region, type the description of the information link. + + :: + +#. *Optional* - To filter your data, expand the **Filters** section and do the following: + + 1. From the **Information Link** region, select the element you added in Step 3 above. + + :: + + 2. Click **Add**. + + The **Add Column** window is displayed. + + 3. From the drop-down list, select a column to add a hard filter to and click **OK**. + + The selected column is added to the Filters list. + + 4. Repeat steps 2 and 3 to add filters to additional columns. + + :: + + 5. For each column, from the **Filter Type** drop-down list, select **range** or **values**. + + .. note:: Filtering by range means entering the upper and lower limits of the desired range. Filtering by values means entering the exact values that you want to include in the returned data, separated by semicolon. + + 6. In the **Values** field type the desired values separated with semicolons, or set the upper and lower limits in the **Min Value** and **Max Value** fields. Alternatively, you can type ``?param_name`` in the Values field to use a parameter as the filter for the selected column, where ``param_name`` is the name used to identify the parameter. + + .. note:: Because limits are inclusive, setting the lower limit to **1000** includes the value **1000** in the data table. + + .. note:: When setting upper and lower limits on **String** type columns, ``A`` precedes ``AA``, and a lone letter precedes words beginning with that latter. For example, ``S** precedes **Smith**, indicating that the name ``Smith`` will not be present when you select names from ``D`` to ``S``. The order of characters is standard ASCII. + + For more information on adding filters, see `Adding Hard Filters `_. + +7. *Optional* - To add runtime filtering prompts, expand the **Prompts** section and do the following: + + 1. Click **Add**. + + The **Add Column** window is displayed. + + #. From the **Select column** list, select a column to add a prompt to and click **OK**. + + The selected column is added to the Prompts list. + + #. Repeat **Step 1** to add prompts to additional columns. + + :: + + #. Do the following for each column: + + * Make a selection from the **Prompt Type** drop-down list. + * Select or clear **Mandatory**. + * *Optional* - Set your **Max Selections**. + + For more information on adding prompts, see `Adding Prompts `_. + +8. *Optional* - Expand the **Conditioning** section and specify one of the following conditions: + + * None + * Distinct + * Pivot + + Note that you can edit the Pivot conditioning by selecting **Pivot** and clicking **Edit**. + +9. *Optional* - Expand the **Parameters** section and define your parameters. + + :: + +10. *Optional* - Expand the **Properties** section and define your properties. + + :: + +11. *Optional* - Expand the **Caching** section and enable or disable whether your information link can be cached. + + :: + +12. Click **Save**. + + The **Save As** window is displayed. + +13. In the tree, select where you want to save the information link. + + :: + +14. In the **Name** field, type a name and description for the information link. + + :: + + +15. Click **Save**. + + The new information link is added to the library and can be accessed by other users. + +.. tip:: You can test the information link directly by clicking **Open Data**. You can also view and edit the SQL belonging to the information link by clicking **SQL**. + +For more information on the Information Link attributes, see `Information Link Tab `_. + +Troubleshooting +------------- +The **Troubleshooting** section describes the following scenarios: + +.. contents:: + :local: + :depth: 1 + +The JDBC Driver does not Support Boolean, Decimal, or Numeric Types +~~~~~~~~~~~ +When attempting to load data, the the Boolean, Decimal, or Numeric column types are not supported and generate the following error: + +.. code-block:: console + + Failed to execute query: Unsupported JDBC data type in query result: Bool (HRESULT: 80131500) + +The error above is resolved by casting the columns as follows: + +* ``Bool`` columns to ``INT``. +* ``Decimal`` and ``Numeric`` columns to ``REAL``. + +For more information, see the following: + +* **Resolving this error** - `Details on Change Data Types `_. + +* **Supported data types** - :ref:`Data Types`. + +Information Services do not Support Live Queries +~~~~~~~~~~~ +TIBCO Spotfire data connectors support live queries, but no APIs currently exist for creating custom data connectors. This is resolved by creating a customized SQream adapter using TIBCO's **Data Virtualization (TDV)** or the **Spotfire Advanced Services (ADS)**. These can be used from the built-in TDV connector to enable live queries. + +This resolution applies to JDBC and ODBC drivers. \ No newline at end of file diff --git a/connecting_to_sqream/index.rst b/connecting_to_sqream/index.rst index a790f085d..ecb9e4715 100644 --- a/connecting_to_sqream/index.rst +++ b/connecting_to_sqream/index.rst @@ -1,4 +1,4 @@ -.. _third_party_tools: +.. _connecting_to_sqream: ************************* Connecting to SQream @@ -12,6 +12,7 @@ This section provides information about the following third party tools: :glob: :titlesonly: + client_platforms/index client_drivers/index If you need a tool that SQream does not support, contact SQream Support or your SQream account manager for more information. \ No newline at end of file From e46f40bc2d874b9de4a13f7aea69f2a197db2663 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Wed, 20 Jul 2022 15:02:18 +0300 Subject: [PATCH 130/316] Fixed links (changed to 2022.1) --- .../client_platforms/informatica.rst | 2 +- .../client_platforms/microstrategy.rst | 2 +- connecting_to_sqream/client_platforms/php.rst | 2 +- connecting_to_sqream/client_platforms/power_bi.rst | 6 +++--- connecting_to_sqream/client_platforms/sas_viya.rst | 4 ++-- .../client_platforms/sql_workbench.rst | 14 ++++++++------ connecting_to_sqream/client_platforms/tableau.rst | 2 +- connecting_to_sqream/client_platforms/talend.rst | 2 +- 8 files changed, 18 insertions(+), 16 deletions(-) diff --git a/connecting_to_sqream/client_platforms/informatica.rst b/connecting_to_sqream/client_platforms/informatica.rst index 6bc50b22a..ec39a0129 100644 --- a/connecting_to_sqream/client_platforms/informatica.rst +++ b/connecting_to_sqream/client_platforms/informatica.rst @@ -143,7 +143,7 @@ After establishing a connection between SQream and Informatica you can establish 2. In the **JDBC_IC Connection Properties** section, in the **JDBC Connection URL** field, establish a JDBC connection by providing the correct connection string. - For connection string examples, see `Connection Strings `_. + For connection string examples, see `Connection Strings `_. :: diff --git a/connecting_to_sqream/client_platforms/microstrategy.rst b/connecting_to_sqream/client_platforms/microstrategy.rst index 6cad19be2..370312a0d 100644 --- a/connecting_to_sqream/client_platforms/microstrategy.rst +++ b/connecting_to_sqream/client_platforms/microstrategy.rst @@ -54,7 +54,7 @@ Connecting a Data Source :: -2. Download the most current version of the `SQream JDBC driver `_. +2. Download the most current version of the `SQream JDBC driver `_. :: diff --git a/connecting_to_sqream/client_platforms/php.rst b/connecting_to_sqream/client_platforms/php.rst index 2310fde6b..ebb2c796f 100644 --- a/connecting_to_sqream/client_platforms/php.rst +++ b/connecting_to_sqream/client_platforms/php.rst @@ -16,7 +16,7 @@ Installing PHP ------------------- **To install PHP:** -1. Download the JDBC driver installer from the `SQream Drivers page `_. +1. Download the JDBC driver installer from the `SQream Drivers page `_. :: diff --git a/connecting_to_sqream/client_platforms/power_bi.rst b/connecting_to_sqream/client_platforms/power_bi.rst index c088db851..1cdf7c81b 100644 --- a/connecting_to_sqream/client_platforms/power_bi.rst +++ b/connecting_to_sqream/client_platforms/power_bi.rst @@ -22,7 +22,7 @@ SQream integrates with Power BI Desktop to do the following: SQream uses Power BI for extracting data sets using the following methods: -* **Direct query** - Direct queries lets you connect easily with no errors, and refreshes Power BI artifacts, such as graphs and reports, in a considerable amount of time in relation to the time taken for queries to run using the `SQream SQL CLI Reference guide `_. +* **Direct query** - Direct queries lets you connect easily with no errors, and refreshes Power BI artifacts, such as graphs and reports, in a considerable amount of time in relation to the time taken for queries to run using the `SQream SQL CLI Reference guide `_. :: @@ -52,7 +52,7 @@ Installing Power BI Desktop 2. Download and configure your ODBC driver. - For more information about configuring your ODBC driver, see `ODBC `_. + For more information about configuring your ODBC driver, see `ODBC `_. 3. Navigate to **Windows** > **Documents** and create a folder called **Power BI Desktop Custom Connectors**. @@ -140,4 +140,4 @@ SQream supports the following SQream driver versions: Related Information ------------------- -For more information, see the `Glossary `_. \ No newline at end of file +For more information, see the `Glossary `_. \ No newline at end of file diff --git a/connecting_to_sqream/client_platforms/sas_viya.rst b/connecting_to_sqream/client_platforms/sas_viya.rst index 83942ccfd..ef4a338a4 100644 --- a/connecting_to_sqream/client_platforms/sas_viya.rst +++ b/connecting_to_sqream/client_platforms/sas_viya.rst @@ -32,7 +32,7 @@ The SQream JDBC driver is required for establishing a connection between SAS Viy **To install the JDBC driver:** -#. Download the `JDBC driver `_. +#. Download the `JDBC driver `_. :: @@ -59,7 +59,7 @@ After installing the JDBC driver, you must configure the JDBC driver from the SA .. literalinclude:: connect3.sas :language: php -For more information about writing a connection string, see **Connect to SQream DB with a JDBC Application** and navigate to `Connection String `_. +For more information about writing a connection string, see **Connect to SQream DB with a JDBC Application** and navigate to `Connection String `_. Operating SAS Viya -------------------- diff --git a/connecting_to_sqream/client_platforms/sql_workbench.rst b/connecting_to_sqream/client_platforms/sql_workbench.rst index 16265ebd4..a5f7e8871 100644 --- a/connecting_to_sqream/client_platforms/sql_workbench.rst +++ b/connecting_to_sqream/client_platforms/sql_workbench.rst @@ -11,8 +11,9 @@ This tutorial is a guide that will show you how to connect SQL Workbench to SQre .. contents:: In this topic: :local: -Installing SQL Workbench with the SQream DB installer (Windows only) +Installing SQL Workbench with the SQream Installer ===================================================================== +This section applies to Windows only. SQream DB's driver installer for Windows can install the Java prerequisites and SQL Workbench for you. @@ -33,8 +34,9 @@ SQream DB's driver installer for Windows can install the Java prerequisites and You are now ready to create a profile for your cluster. Continue to :ref:`Creating a new connection profile `. -Installing SQL Workbench manually (Linux, MacOS) +Installing SQL Workbench Manually =================================================== +This section applies to Linux and MacOS only. Install Java Runtime ------------------------ @@ -51,7 +53,7 @@ For Linux and BSD, see https://openjdk.java.net/install/ For Windows, SQream recommends Zulu 8 https://www.azul.com/downloads/zulu-community/?&version=java-8-lts&architecture=x86-64-bit&package=jdk -Get the SQream DB JDBC driver +Get the SQream DB JDBC Driver ------------------------------- SQream DB's JDBC driver is provided as a zipped JAR file, available for download from the `SQream Drivers page `_. @@ -67,7 +69,7 @@ Install SQL Workbench #. Start SQL workbench. If you are using 64 bit windows, run ``SQLWorkbench64.exe`` instead of ``SQLWOrkbench.exe``. -Setting up the SQream DB JDBC driver profile +Setting up the SQream DB JDBC Driver Profile --------------------------------------------- #. Define a connection profile - :menuselection:`&File --> &Connect window (Alt+C)` @@ -100,7 +102,7 @@ Setting up the SQream DB JDBC driver profile .. _new_connection_profile: -Create a new connection profile for your cluster +Create a New Connection Profile for Your Cluster ===================================================== .. image:: /_static/images/sql_workbench_connection_profile.png @@ -117,7 +119,7 @@ Create a new connection profile for your cluster #. Click OK to save the connection profile and connect to SQream DB -Suggested optional configuration +Suggested Optional Configuration ================================== If you installed SQL Workbench manually, you can set a customization to help SQL Workbench show information correctly in the DB Explorer panel. diff --git a/connecting_to_sqream/client_platforms/tableau.rst b/connecting_to_sqream/client_platforms/tableau.rst index ac67c8d55..3c08ebe83 100644 --- a/connecting_to_sqream/client_platforms/tableau.rst +++ b/connecting_to_sqream/client_platforms/tableau.rst @@ -48,7 +48,7 @@ If you are using Windows, after installing the Tableau Desktop application you c :: -#. Download the most current version of the `SQream JDBC driver `_. +#. Download the most current version of the `SQream JDBC driver `_. :: diff --git a/connecting_to_sqream/client_platforms/talend.rst b/connecting_to_sqream/client_platforms/talend.rst index 2a4d2658a..fc16441b9 100644 --- a/connecting_to_sqream/client_platforms/talend.rst +++ b/connecting_to_sqream/client_platforms/talend.rst @@ -194,7 +194,7 @@ Download Links The following is a list of download links relevant to the Talend connector: * `Talend Open Studio for Big Data `_ -* `Latest version of SQream JDBC `_ +* `Latest version of SQream JDBC `_ :ref:`Back to top ` From c3c7b867b6b326af44b2fe48254527707473b3d9 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 21 Jul 2022 11:52:03 +0300 Subject: [PATCH 131/316] Updated Talend with Yotam --- .../client_platforms/talend.rst | 183 +++++------------- 1 file changed, 51 insertions(+), 132 deletions(-) diff --git a/connecting_to_sqream/client_platforms/talend.rst b/connecting_to_sqream/client_platforms/talend.rst index fc16441b9..1aefe8917 100644 --- a/connecting_to_sqream/client_platforms/talend.rst +++ b/connecting_to_sqream/client_platforms/talend.rst @@ -4,201 +4,120 @@ Connecting to SQream Using Talend ************************* -.. _top: - Overview -================= - -This page describes how to use Talend to interact with a SQream DB cluster. The Talend connector is used for reading data from a SQream DB cluster and loading data into SQream DB. - -In addition, this page provides a viability report on Talend's comptability with SQream DB for stakeholders. - -It includes the following: - -* :ref:`A Quick Start guide ` -* :ref:`Information about supported SQream drivers ` -* :ref:`Supported data sources ` and :ref:`tool and operating system versions ` -* :ref:`A description of known issues ` -* :ref:`Related links ` - - -About Talend -================= -Talend is an open-source data integration platform. It provides various software and services for Big Data integration and management, enterprise application integration, data quality and cloud storage. +================= +This page describes how to use Talend to interact with a SQream cluster. The Talend connector is used for reading data from a SQream cluster and loading data into SQream. In addition, this page provides a viability report on Talend's comptability with SQream for stakeholders. -For more information about Talend, see `Talend `_. +The **Connecting to SQream Using Talend** describes the following: - -.. _quickstart_guide: - -Quick Start Guide -======================= +.. contents:: + :local: + :depth: 1 Creating a New Metadata JDBC DB Connection -------------- +---------------- **To create a new metadata JDBC DB connection:** 1. In the **Repository** panel, nagivate to **Metadata** and right-click **Db connections**. -.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_1.png - + :: + 2. Select **Create connection**. -.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_2.png - + :: + 3. In the **Name** field, type a name. -.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_3.png + :: -The name cannot contain spaces. + Note that the name cannot contain spaces. -4. In the **Purpose** field, type a purpose and click **Next**. You cannot go to the next step until you define both a Name and a Purpose. +4. In the **Purpose** field, type a purpose and click **Next**. -.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_4.png + Note that you cannot continue to the next step until you define both a Name and a Purpose. + + :: 5. In the **DB Type** field, select **JDBC**. -.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_5.png + :: 6. In the **JDBC URL** field, type the relevant connection string. - For connection string examples, see `Connection Strings `_. + For connection string examples, see `Connection Strings `_. -.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_6.png - 7. In the **Drivers** field, click the **Add** button. - The **"newLine** entry is added. - -.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_7.png - -8. One the **"newLine** entry, click the ellipsis. + The **"newLine"** entry is added. -.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_8.png +8. One the **"newLine'** entry, click the ellipsis. -The **Module** window is displayed. + The **Module** window is displayed. 9. From the Module window, select **Artifact repository(local m2/nexus)** and select **Install a new module**. -.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_9.png + :: 10. Click the ellipsis. -.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_9.5.png + Your hard drive is displayed. -Your hard drive is displayed. +11. Navigate to a **JDBC jar file** (such as **sqream-jdbc-4.5.3.jar**)and click **Open**. -11. Navigate to a **JDBC jar file** (such as **sqream-jdbc-4.4.0.jar**)and click **Open**. - -.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_10.png + :: 12. Click **Detect the module install status**. -.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_11.5.png + :: 13. Click **OK**. -The JDBC that you selected is displayed in the **Driver** field. - -.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_12.png + The JDBC that you selected is displayed in the **Driver** field. 14. Click **Select class name**. -.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_13.png + :: 15. Click **Test connection**. -.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_14.png - -If a driver class is not found (for example, you didn't select a JDBC jar file), the following error message is displayed: + If a driver class is not found (for example, you didn't select a JDBC jar file), the following error message is displayed: -.. image:: /_static/images/Third_Party_Connectors/Creating_a_New_Metadata_JDBC_DB_Connection_15.png + After creating a new metadata JDBC DB connection, you can do the following: -After creating a new metadata JDBC DB connection, you can do the following: - - * Use your new metadata connection. - * Drag it to the **job** screen. - * Build Talend components. + * Use your new metadata connection. + + :: + + * Drag it to the **job** screen. + + :: + + * Build Talend components. -For more information on loading data from JSON files to the Talend Open Studio, see `How to Load Data from JSON Files in Talend `_. - -:ref:`Back to top ` + For more information on loading data from JSON files to the Talend Open Studio, see `How to Load Data from JSON Files in Talend `_. -.. _supported_sqream_drivers: - Supported SQream Drivers -================ - +---------------- The following list shows the supported SQream drivers and versions: * **JDBC** - Version 4.3.3 and higher. -* **ODBC** - Version 4.0.0. This version requires a Bridge to connect. For more information on the required Bridge, see `Connecting Talend on Windows to an ODBC Database `_. -:ref:`Back to top ` - - -.. _supported_data_sources: + :: + +* **ODBC** - Version 4.0.0. This version requires a Bridge to connect. For more information on the required Bridge, see `Connecting Talend on Windows to an ODBC Database `_. Supported Data Sources -============================ +---------------- Talend Cloud connectors let you create reusable connections with a wide variety of systems and environments, such as those shown below. This lets you access and read records of a range of diverse data. * **Connections:** Connections are environments or systems for storing datasets, including databases, file systems, distributed systems and platforms. Because these systems are reusable, you only need to establish connectivity with them once. -* **Datasets:** Datasets include database tables, file names, topics (Kafka), queues (JMS) and file paths (HDFS). For more information on the complete list of connectors and datasets that Talend supports, see `Introducing Talend Connectors `_. - -:ref:`Back to top ` - - -.. _supported_tools_os_sys_versions: - -Supported Tool and Operating System Versions -====================== -Talend was tested using the following: - -* Talend version 7.4.1M6 -* Windows 10 -* SQream version 2021.1 -* JDBC version - - - - -:ref:`Back to top ` - + :: -.. _known_issues: +* **Datasets:** Datasets include database tables, file names, topics (Kafka), queues (JMS) and file paths (HDFS). For more information on the complete list of connectors and datasets that Talend supports, see `Introducing Talend Connectors `_. Known Issues -=========================== -The the list below describes the following known issues as of 6/1/2021: - -* Schemas not displayed for tables with identical names. - -:ref:`Back to top ` - - -.. _related_links: - -Related Links -=============== -The following is a list of links relevant to the Talend connector: +---------------- +As of 6/1/2021 schemas were not displayed for tables with identical names. -* `Talend Home page `_ -* `Talend Community page `_ -* `Talend BugTracker `_ - - -Download Links -================== -The following is a list of download links relevant to the Talend connector: - -* `Talend Open Studio for Big Data `_ -* `Latest version of SQream JDBC `_ - -:ref:`Back to top ` - - - -.. contents:: In this topic: - :local: +If you experience issues using Talend, see the `SQream support portal `_. \ No newline at end of file From da777d3fdaff938683c7ed3b58d34853eda2132c Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 21 Jul 2022 11:54:47 +0300 Subject: [PATCH 132/316] Updated with Yotam --- connecting_to_sqream/client_platforms/talend.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connecting_to_sqream/client_platforms/talend.rst b/connecting_to_sqream/client_platforms/talend.rst index 1aefe8917..7f11092fb 100644 --- a/connecting_to_sqream/client_platforms/talend.rst +++ b/connecting_to_sqream/client_platforms/talend.rst @@ -44,7 +44,7 @@ Creating a New Metadata JDBC DB Connection 6. In the **JDBC URL** field, type the relevant connection string. - For connection string examples, see `Connection Strings `_. + For connection string examples, see `Connection Strings `_. 7. In the **Drivers** field, click the **Add** button. From e61fc4053407a30e2ef361c66e48247bd98ac766 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 21 Jul 2022 11:59:29 +0300 Subject: [PATCH 133/316] Added Talend to index --- connecting_to_sqream/client_platforms/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connecting_to_sqream/client_platforms/index.rst b/connecting_to_sqream/client_platforms/index.rst index a5a3f5166..19f929067 100644 --- a/connecting_to_sqream/client_platforms/index.rst +++ b/connecting_to_sqream/client_platforms/index.rst @@ -31,7 +31,7 @@ If you are looking for a tool that is not listed, SQream and our partners can he informatica r php - xxtalend + talend xxdiagnosing_common_connectivity_issues .. image:: /_static/images/connectivity_ecosystem.png From 0f1264ea356b718d39b318fb4a23a303917b41ab Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 21 Jul 2022 12:16:38 +0300 Subject: [PATCH 134/316] Alphabetized --- connecting_to_sqream/client_platforms/index.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/connecting_to_sqream/client_platforms/index.rst b/connecting_to_sqream/client_platforms/index.rst index 19f929067..a38f1f1f5 100644 --- a/connecting_to_sqream/client_platforms/index.rst +++ b/connecting_to_sqream/client_platforms/index.rst @@ -21,17 +21,17 @@ If you are looking for a tool that is not listed, SQream and our partners can he :caption: In this section: :titlesonly: + informatica + microstrategy + pentaho + php power_bi - tibco_spotfire + r sas_viya sql_workbench tableau - pentaho - microstrategy - informatica - r - php talend + tibco_spotfire xxdiagnosing_common_connectivity_issues .. image:: /_static/images/connectivity_ecosystem.png From 3366ab3ecd7753351d9d754e7db193ad057582aa Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 21 Jul 2022 12:48:57 +0300 Subject: [PATCH 135/316] Update tableau.rst --- .../client_platforms/tableau.rst | 310 +++--------------- 1 file changed, 40 insertions(+), 270 deletions(-) diff --git a/connecting_to_sqream/client_platforms/tableau.rst b/connecting_to_sqream/client_platforms/tableau.rst index 3c08ebe83..01f90bbb4 100644 --- a/connecting_to_sqream/client_platforms/tableau.rst +++ b/connecting_to_sqream/client_platforms/tableau.rst @@ -1,4 +1,4 @@ -.. _connect_to_tableau: +.. _tableau: ************************* Connecting to SQream Using Tableau @@ -8,7 +8,7 @@ Overview ===================== SQream's Tableau connector plugin, based on standard JDBC, enables storing and fast querying large volumes of data. -The **Connecting to SQream Using Tableau** page is a Quick Start Guide that describes how install Tableau and the JDBC and ODBC drivers and connect to SQream using the JDBC and ODBC drivers for data analysis. It also describes using best practices and troubleshoot issues that may occur while installing Tableau. SQream supports both Tableau Desktop and Tableau Server on Windows, MacOS, and Linux distributions. +The **Connecting to SQream Using Tableau** page is a Quick Start Guide that describes how install Tableau and the JDBC driver and connect to SQream for data analysis. It also describes using best practices and troubleshoot issues that may occur while installing Tableau. SQream supports both Tableau Desktop and Tableau Server on Windows, MacOS, and Linux distributions. For more information on SQream's integration with Tableau, see `Tableau's Extension Gallery `_. @@ -16,295 +16,75 @@ The Connecting to SQream Using Tableau page describes the following: .. contents:: :local: + :depth: 1 Installing the JDBC Driver and Tableau Connector Plugin ------------------- This section describes how to install the JDBC driver using the fully-integrated Tableau connector plugin (Tableau Connector, or **.taco** file). SQream has been tested with Tableau versions 9.2 and newer. -**To connect to SQream using Tableau:** - -#. Install the Tableau Desktop application. - - For more information about installing the Tableau Desktop application, see the `Tableau products page `_ and click **Download Free Trial**. Note that Tableau offers a 14-day trial version. - - :: +You can connect to SQream using Tableau by doing one of the following: -#. Do one of the following: - - * **For Windows** - See :ref:`Installing Tableau Using the Windows Installer `. * **For MacOS or Linux** - See :ref:`Installing the JDBC Driver Manually `. -.. note:: For Tableau **2019.4 versions and later**, SQream recommends installing the JDBC driver instead of the previously recommended ODBC driver. - -.. _tableau_windows_installer: - -Installing the JDBC Driver Using the Windows Installer -~~~~~~~~~~~~~~~~~~ -If you are using Windows, after installing the Tableau Desktop application you can install the JDBC driver using the Windows installer. The Windows installer is an installation wizard that guides you through the JDBC driver installation steps. When the driver is installed, you can connect to SQream. - -**To install Tableau using the Windows installer**: - -#. Close Tableau Desktop. - - :: - -#. Download the most current version of the `SQream JDBC driver `_. - - :: - -#. Do the following: - - #. Start the installer. - #. Verify that the **Tableau Desktop connector** item is selected. - #. Follow the installation steps. - - :: - -You can now restart Tableau Desktop or Server to begin using the SQream driver by :ref:`connecting to SQream `. - -.. _tableau_jdbc_installer: + :: -Installing the JDBC Driver Manually + * **For Windows** - See :ref:`Installing Tableau Using the Windows Installer `. + +Installing the JDBC Driver ~~~~~~~~~~~~~ If you are using MacOS, Linux, or the Tableau server, after installing the Tableau Desktop application you can install the JDBC driver manually. When the driver is installed, you can connect to SQream. -**To install the JDBC driver manually:** +**To install the JDBC driver:** 1. Download the JDBC installer and SQream Tableau connector (.taco) file from the :ref:`from the client drivers page`. :: -#. Install the JDBC driver by unzipping the JDBC driver into a Tableau driver directory. - - Based on the installation method that you used, your Tableau driver directory is located in one of the following places: +2. Based on your operating system, your Tableau driver directory is located in one of the following places: - * **Tableau Desktop on Windows:** *C:\\Program Files\\Tableau\\Drivers* * **Tableau Desktop on MacOS:** *~/Library/Tableau/Drivers* - * **Tableau on Linux**: */opt/tableau/tableau_driver/jdbc* - -.. note:: If the driver includes only a single .jar file, copy it to *C:\\Program Files\\Tableau/Drivers*. If the driver includes multiple files, create a subfolder *A* in *C:\\Program Files\\Tableau/Drivers* and copy all files to folder *A*. - -Note the following when installing the JDBC driver: - -* You must have read permissions on the .jar file. -* Tableau requires a JDBC 4.0 or later driver. -* Tableau requires a Type 4 JDBC driver. -* The latest 64-bit version of Java 8 is installed. - -3. Install the **SQreamDB.taco** file by moving the SQreamDB.taco file into the Tableau connectors directory. - - Based on the installation method that you used, your Tableau driver directory is located in one of the following places: - - * **Tableau Desktop on Windows:** *C:\\Users\\\\My Tableau Repository\\Connectors* - * **Tableau Desktop on Mac:** *~/My Tableau Repository/Connectors* :: -4. *Optional* - If you are using the Tableau Server, do the following: - - 1. Create a directory for Tableau connectors and give it a descriptive name, such as *C:\\tableau_connectors*. - - This directory needs to exist on all Tableau servers. - - :: - - 2. Copy the SQreamDB.taco file into the new directory. - - :: - - 3. Set the **native_api.connect_plugins_path** option to ``tsm`` as shown in the following example: - - .. code-block:: console - - $ tsm configuration set -k native_api.connect_plugins_path -v C:/tableau_connectors + * **Tableau Desktop on Windows:** *C:\\Program Files\\Tableau\\Drivers* - If a configuration error is displayed, add ``--force-keys`` to the end of the command as shown in the following example: - - .. code-block:: console + :: - $ tsm configuration set -k native_api.connect_plugins_path -v C:/tableau_connectors--force-keys - - 4. To apply the pending configuration changes, run the following command: - - .. code-block:: console - - $ tsm pending-changes apply - - .. warning:: This restarts the server. - -You can now restart Tableau Desktop or Server to begin using the SQream driver by :ref:`connecting to SQream ` as described in the section below. - -.. _tableau_connect_to_sqream: - - -Installing the ODBC Driver for Tableau Versions 2019.3 and Earlier --------------- - - -This section describes the installation method for Tableau version 2019.3 or earlier and describes the following: - -.. contents:: - :local: - -.. note:: SQream recommends installing the JDBC driver to provide improved connectivity. - -Automatically Reconfiguring the ODBC Driver After Initial Installation -~~~~~~~~~~~~~~~~~~ -If you've already installed the SQream ODBC driver and installed Tableau, SQream recommends reinstalling the ODBC driver with the **.TDC Tableau Settings for SQream DB** configuration shown in the image below: - -.. image:: /_static/images/odbc_windows_installer_tableau.png - -SQream recommends this configuration because Tableau creates temporary tables and runs several discovery queries that may impact performance. The ODBC driver installer avoids this by automatically reconfiguring Tableau. - -For more information about reinstalling the ODBC driver installer, see :ref:`Install and Configure ODBC on Windows `. - -If you want to manually reconfigure the ODBC driver, see :ref:`Manually Reconfiguring the ODBC Driver After Initial Installation ` below. - -.. _manually_reconfigure_odbc_driver: - -Manually Reconfiguring the ODBC Driver After Initial Installation -~~~~~~~~~~~~~~~~~~ -The file **Tableau Datasource Customization (TDC)** file lets you use Tableau make full use of SQream DB's features and capabilities. - -**To manually reconfigure the ODBC driver after initial installation:** - -1. Do one of the following: + * **Tableau on Linux**: */opt/tableau/tableau_driver/jdbc* + + Note the following when installing the JDBC driver: - 1. Download the :download:`odbc-sqream.tdc ` file to your machine and open it in a text editor. + * You must have read permissions on the .jar file. - :: + :: + + * Tableau requires a JDBC 4.0 or later driver. - 2. Copy the text below into a text editor: + :: + + * Tableau requires a Type 4 JDBC driver. - .. literalinclude:: odbc-sqream.tdc - :language: xml - :caption: SQream ODBC TDC File - :emphasize-lines: 2 - -#. Check which version of Tableau you are using. - - :: - -#. In the text of the file shown above, in the highlighted line, replace the version number with the **major** version of Tableau that you are using. - - For example, if you are using Tableau vesion **2019.2.1**, replace it with **2019.2**. - - :: - -#. Do one of the following: - - * If you are using **Tableau Desktop** - save the TDC file to *C:\\Users\\\\Documents\\My Tableau Repository\\Datasources*, where ```` is the Windows username that you have installed Tableau under. - - :: - - * If you are using the **Tableau Server** - save the TDC file to *C:\\ProgramData\\Tableau\\Tableau Server\\data\\tabsvc\\vizqlserver\\Datasources*. - -Configuring the ODBC Connection -~~~~~~~~~~~~ -The ODBC connection uses a DSN when connecting to ODBC data sources, and each DSN represents one SQream database. - -**To configure the ODBC connection:** - -1. Create an ODBC DSN. - - :: - -#. Open the Windows menu by pressing the Windows button (:kbd:`⊞ Win`) or clicking the **Windows** menu button. - - :: - -#. Type **ODBC** and select **ODBC Data Sources (64-bit)**. + :: + + * The latest 64-bit version of Java 8 is installed. - During installation, the installer created a sample user DSN named **SQreamDB**. - - :: +3. Install the **SQreamDB.taco** file by moving the SQreamDB.taco file into the Tableau connectors directory. -#. *Optional* - Do one or both of the following: + Based on the installation method that you used, your Tableau driver directory is located in one of the following places: - * Modify the DSN name. + * **Tableau Desktop on Windows:** *C:\\Users\\\\My Tableau Repository\\Connectors* :: - - * Create a new DSN name by clicking **Add** and selecting **SQream ODBC Driver**. - -.. image:: /_static/images/odbc_windows_dsns.png - -5. Click **Finish**. + * **Tableau Desktop on MacOS:** *~/My Tableau Repository/Connectors* - :: +You can now restart Tableau Desktop or Server to begin using the SQream driver by connecting to SQream as described in the section below. -6. Enter your connection parameters. - - The following table describes the connection parameters: - - .. list-table:: - :widths: 15 38 38 - :header-rows: 1 - - * - Item - - Description - - Example - * - Data Source Name - - The Data Source Name. SQream recommends using a descriptive and easily recognizable name for referencing your DSN. Once set, the Data Source Name cannot be changed. - - - * - Description - - The description of your DSN. This field is optional. - - - * - User - - The username of a role to use for establishing the connection. - - ``rhendricks`` - * - Password - - The password of the selected role. - - ``Tr0ub4dor`` - * - Database - - The database name to connect to. For example, ``master`` - - ``master`` - * - Service - - The :ref:`service queue` to use. - - For example, ``etl``. For the default service ``sqream``, leave blank. - * - Server - - The hostname of the SQream worker. - - ``127.0.0.1`` or ``sqream.mynetwork.co`` - * - Port - - The TCP port of the SQream worker. - - ``5000`` or ``3108`` - * - User Server Picker - - Uses the load balancer when establishing a connection. Use only if exists, and check port. - - - * - SSL - - Uses SSL when establishing a connection. - - - * - Logging Options - - Lets you modify your logging options when tracking the ODBC connection for connection issues. - - - -.. tip:: Test the connection by clicking **Test** before saving your DSN. - -7. Save the DSN by clicking **OK.** - -Connecting Tableau to SQream -~~~~~~~~~~~~ -**To connect Tableau to SQream:** - -1. Start Tableau Desktop. - - :: - -#. In the **Connect** menu, in the **To a server** sub-menu, click **More Servers** and select **Other Databases (ODBC)**. - - The **Other Databases (ODBC)** window is displayed. - - :: - -#. In the Other Databases (ODBC) window, select the DSN that you created in :ref:`Setting Up SQream Tables as Data Sources `. - - Tableau may display the **Sqream ODBC Driver Connection Dialog** window and prompt you to provide your username and password. +.. _tableau_windows_installer: -#. Provide your username and password and click **OK**. - -.. _tableau_connect_to_sqream_db: +.. _tableau_jdbc_installer: +.. _tableau_connect_to_sqream: Connecting to SQream --------------------- @@ -362,10 +142,7 @@ After installing the JDBC driver you can connect to SQream. - The connection is established and the data source page is displayed. - -.. tip:: - Tableau automatically assigns your connection a default name based on the DSN and table. SQream recommends giving the connection a more descriptive name. - + .. _set_up_sqream_tables_as_data_sources: Setting Up SQream Tables as Data Sources @@ -388,9 +165,6 @@ After connecting to SQream you must set up the SQream tables as data sources. #. Open a new sheet to analyze data. -.. tip:: - For more information about configuring data sources, joining, filtering, see Tableau's `Set Up Data Sources `_ tutorials. - Tableau Best Practices and Troubleshooting --------------- This section describes the following best practices and troubleshooting procedures when connecting to SQream using Tableau: @@ -398,16 +172,6 @@ This section describes the following best practices and troubleshooting procedur .. contents:: :local: -Inserting Only Required Data -~~~~~~~~~~~~~~~~~~ -When using Tableau, SQream recommends using only data that you need, as described below: - -* Insert only the data sources you need into Tableau, excluding tables that don't require analysis. - - :: - -* To increase query performance, add filters before analyzing. Every modification you make while analyzing data queries the SQream database, sometimes several times. Adding filters to the datasource before exploring limits the amount of data analyze and increases query performance. - Using Tableau's Table Query Syntax ~~~~~~~~~~~~~~~~~~~ Dragging your desired tables into the main area in Tableau builds queries based on its own syntax. This helps ensure increased performance, while using views or custom SQL may degrade performance. In addition, SQream recommends using the :ref:`create_view` to create pre-optimized views, which your datasources point to. @@ -437,7 +201,13 @@ If Tableau cannot locate the SQream JDBC driver, do the following: 1. Verify that the JDBC driver is located in the correct directory: * **Tableau Desktop on Windows:** *C:\Program Files\Tableau\Drivers* + + :: + * **Tableau Desktop on MacOS:** *~/Library/Tableau/Drivers* + + :: + * **Tableau on Linux**: */opt/tableau/tableau_driver/jdbc* 2. Find the file path for the JDBC driver and add it to the Java classpath: From 4e6bd961b99742efbde41793580af6fa442b1200 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 21 Jul 2022 12:55:04 +0300 Subject: [PATCH 136/316] Update tableau.rst --- connecting_to_sqream/client_platforms/tableau.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connecting_to_sqream/client_platforms/tableau.rst b/connecting_to_sqream/client_platforms/tableau.rst index 01f90bbb4..ad29a7d15 100644 --- a/connecting_to_sqream/client_platforms/tableau.rst +++ b/connecting_to_sqream/client_platforms/tableau.rst @@ -6,7 +6,7 @@ Connecting to SQream Using Tableau Overview ===================== -SQream's Tableau connector plugin, based on standard JDBC, enables storing and fast querying large volumes of data. +SQream's Tableau connector plugin, based on standard JDBC, enables storing and fast querying large volumes of data. The **Connecting to SQream Using Tableau** page is a Quick Start Guide that describes how install Tableau and the JDBC driver and connect to SQream for data analysis. It also describes using best practices and troubleshoot issues that may occur while installing Tableau. SQream supports both Tableau Desktop and Tableau Server on Windows, MacOS, and Linux distributions. From a58d0028e203acd4eea8ad0f1517a236ed28e8bd Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 21 Jul 2022 13:02:27 +0300 Subject: [PATCH 137/316] Update tableau.rst --- connecting_to_sqream/client_platforms/tableau.rst | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/connecting_to_sqream/client_platforms/tableau.rst b/connecting_to_sqream/client_platforms/tableau.rst index ad29a7d15..1d2ca17b6 100644 --- a/connecting_to_sqream/client_platforms/tableau.rst +++ b/connecting_to_sqream/client_platforms/tableau.rst @@ -24,14 +24,12 @@ This section describes how to install the JDBC driver using the fully-integrated You can connect to SQream using Tableau by doing one of the following: - * **For MacOS or Linux** - See :ref:`Installing the JDBC Driver Manually `. + * **For MacOS or Linux** - See :ref:`Installing the JDBC Driver `. - :: - - * **For Windows** - See :ref:`Installing Tableau Using the Windows Installer `. +.. _tableau_jdbc_installer: Installing the JDBC Driver -~~~~~~~~~~~~~ +------------------- If you are using MacOS, Linux, or the Tableau server, after installing the Tableau Desktop application you can install the JDBC driver manually. When the driver is installed, you can connect to SQream. **To install the JDBC driver:** @@ -80,12 +78,6 @@ If you are using MacOS, Linux, or the Tableau server, after installing the Table You can now restart Tableau Desktop or Server to begin using the SQream driver by connecting to SQream as described in the section below. -.. _tableau_windows_installer: - -.. _tableau_jdbc_installer: - -.. _tableau_connect_to_sqream: - Connecting to SQream --------------------- After installing the JDBC driver you can connect to SQream. From bfefafacce2957e7c8924f2ae5a84ba93626b722 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 21 Jul 2022 13:31:53 +0300 Subject: [PATCH 138/316] Reinstated missing files --- .../installing_and_launching_sqream.rst | 3 +- installation_guides/installing_monit.rst | 315 ++++++++++++++++++ .../installing_sqream_with_binary.rst | 277 +++++++++++++++ 3 files changed, 594 insertions(+), 1 deletion(-) create mode 100644 installation_guides/installing_monit.rst create mode 100644 installation_guides/installing_sqream_with_binary.rst diff --git a/installation_guides/installing_and_launching_sqream.rst b/installation_guides/installing_and_launching_sqream.rst index 6ff465758..6a41ba52b 100644 --- a/installation_guides/installing_and_launching_sqream.rst +++ b/installation_guides/installing_and_launching_sqream.rst @@ -13,4 +13,5 @@ The **Installing and Launching SQream** page includes the following installation installing_sqream_with_binary running_sqream_in_a_docker_container installing_sqream_with_kubernetes - installing_monit \ No newline at end of file + installing_monit + launching_sqream_with_monit \ No newline at end of file diff --git a/installation_guides/installing_monit.rst b/installation_guides/installing_monit.rst new file mode 100644 index 000000000..ab49164f6 --- /dev/null +++ b/installation_guides/installing_monit.rst @@ -0,0 +1,315 @@ +.. _installing_monit: + +********************************************* +Installing Monit +********************************************* + +Getting Started +============================== + +Before installing SQream with Monit, verify that you have followed the required :ref:`recommended pre-installation configurations `. + +The procedures in the **Installing Monit** guide must be performed on each SQream cluster node. + +.. _back_to_top: + +Overview +============================== + + +Monit is a free open source supervision utility for managing and monitoring Unix and Linux. Monit lets you view system status directly from the command line or from a native HTTP web server. Monit can be used to conduct automatic maintenance and repair, such as executing meaningful causal actions in error situations. + +SQream uses Monit as a watchdog utility, but you can use any other utility that provides the same or similar functionality. + +The **Installing Monit** procedures describes how to install, configure, and start Monit. + +You can install Monit in one of the following ways: + +* :ref:`Installing Monit on CentOS ` +* :ref:`Installing Monit on CentOS offline ` +* :ref:`Installing Monit on Ubuntu ` +* :ref:`Installing Monit on Ubuntu offline ` + + + + + + + +.. _installing-monit-on-centos: + +Installing Monit on CentOS: +------------------------------------ + + + +**To install Monit on CentOS:** + +1. Install Monit as a superuser on CentOS: + + .. code-block:: console + + $ sudo yum install monit + + +.. _installing-monit-on-centos-offline: + + + +Installing Monit on CentOS Offline: +------------------------------------ + + +Installing Monit on CentOS offline can be done in either of the following ways: + +* :ref:`Building Monit from Source Code ` +* :ref:`Building Monit from Pre-Built Binaries ` + + + + +.. _building_monit_from_source_code: + +Building Monit from Source Code +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + + +**To build Monit from source code:** + +1. Copy the Monit package for the current version: + + .. code-block:: console + + $ tar zxvf monit-.tar.gz + + The value ``x.y.z`` denotes the version numbers. + +2. Navigate to the directory where you want to store the package: + + .. code-block:: console + + $ cd monit-x.y.z + +3. Configure the files in the package: + + .. code-block:: console + + $ ./configure (use ./configure --help to view available options) + +4. Build and install the package: + + .. code-block:: console + + $ make && make install + +The following are the default storage directories: + +* The Monit package: **/usr/local/bin/** +* The **monit.1 man-file**: **/usr/local/man/man1/** + +5. **Optional** - To change the above default location(s), use the **--prefix** option to ./configure. + +.. + _**Comment - I took this line directly from the external online documentation. Is the "prefix option" referrin gto the "--help" in Step 3? URL: https://mmonit.com/wiki/Monit/Installation** + +6. **Optional** - Create an RPM package for CentOS directly from the source code: + + .. code-block:: console + + $ rpmbuild -tb monit-x.y.z.tar.gz + +.. + _**Comment - Is this an optional or mandatory step?** + + + + +.. _building_monit_from_pre_built_binaries: + +Building Monit from Pre-Built Binaries +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**To build Monit from pre-built binaries:** + +1. Copy the Monit package for the current version: + + .. code-block:: console + + $ tar zxvf monit-x.y.z-linux-x64.tar.gz + + The value ``x.y.z`` denotes the version numbers. + +2. Navigate to the directory where you want to store the package: + + .. code-block:: console$ cd monit-x.y.z + +3. Copy the **bin/monit** and **/usr/local/bin/** directories: + + .. code-block:: console + + $ cp bin/monit /usr/local/bin/ + +4. Copy the **conf/monitrc** and **/etc/** directories: + + .. code-block:: console + + $ cp conf/monitrc /etc/ + +.. + _**Comment - please review this procedure.** + +For examples of pre-built Monit binarties, see :ref:`Download Precompiled Binaries`. + +:ref:`Back to top ` + + + +.. _installing-monit-on-ubuntu: + + + +Installing Monit on Ubuntu: +------------------------------------ + + +**To install Monit on Ubuntu:** + +1. Install Monit as a superuser on Ubuntu: + + .. code-block:: console + + $ sudo apt-get install monit + +:ref:`Back to top ` + + + +.. _installing-monit-on-ubuntu-offline: + + +Installing Monit on Ubuntu Offline: +------------------------------------- + + +You can install Monit on Ubuntu when you do not have an internet connection. + +**To install Monit on Ubuntu offline:** + +1. Compress the required file: + + .. code-block:: console + + $ tar zxvf monit--linux-x64.tar.gz + + **NOTICE:** ** denotes the version number. + +2. Navigate to the directory where you want to save the file: + + .. code-block:: console + + $ cd monit-x.y.z + +3. Copy the **bin/monit** directory into the **/usr/local/bin/** directory: + + .. code-block:: console + + $ cp bin/monit /usr/local/bin/ + +4. Copy the **conf/monitrc** directory into the **/etc/** directory: + + .. code-block:: console + + $ cp conf/monitrc /etc/ + +:ref:`Back to top ` + + +Configuring Monit +==================================== + +When the installation is complete, you can configure Monit. You configure Monit by modifying the Monit configuration file, called **monitrc**. This file contains blocks for each service that you want to monitor. + +The following is an example of a service block: + + .. code-block:: console + + $ #SQREAM1-START + $ check process sqream1 with pidfile /var/run/sqream1.pid + $ start program = "/usr/bin/systemctl start sqream1" + $ stop program = "/usr/bin/systemctl stop sqream1" + $ #SQREAM1-END + +For example, if you have 16 services, you can configure this block by copying the entire block 15 times and modifying all service names as required, as shown below: + + .. code-block:: console + + $ #SQREAM2-START + $ check process sqream2 with pidfile /var/run/sqream2.pid + $ start program = "/usr/bin/systemctl start sqream2" + $ stop program = "/usr/bin/systemctl stop sqream2" + $ #SQREAM2-END + +For servers that don't run the **metadataserver** and **serverpicker** commands, you can use the block example above, but comment out the related commands, as shown below: + + .. code-block:: console + + $ #METADATASERVER-START + $ #check process metadataserver with pidfile /var/run/metadataserver.pid + $ #start program = "/usr/bin/systemctl start metadataserver" + $ #stop program = "/usr/bin/systemctl stop metadataserver" + $ #METADATASERVER-END + +**To configure Monit:** + +1. Copy the required block for each required service. +2. Modify all service names in the block. +3. Copy the configured **monitrc** file to the **/etc/monit.d/** directory: + + .. code-block:: console + + $ cp monitrc /etc/monit.d/ + +4. Set file permissions to **600** (full read and write access): + + .. code-block:: console + + $ sudo chmod 600 /etc/monit.d/monitrc + +5. Reload the system to activate the current configurations: + + .. code-block:: console + + $ sudo systemctl daemon-reload + +6. **Optional** - Navigate to the **/etc/sqream** directory and create a symbolic link to the **monitrc** file: + + .. code-block:: console + + $ cd /etc/sqream + $ sudo ln -s /etc/monit.d/monitrc monitrc + +Starting Monit +==================================== + +After configuring Monit, you can start it. + +**To start Monit:** + +1. Start Monit as a super user: + + .. code-block:: console + + $ sudo systemctl start monit + +2. View Monit's service status: + + .. code-block:: console + + $ sudo systemctl status monit + +3. If Monit is functioning correctly, enable the Monit service to start on boot: + + .. code-block:: console + + $ sudo systemctl enable monit diff --git a/installation_guides/installing_sqream_with_binary.rst b/installation_guides/installing_sqream_with_binary.rst new file mode 100644 index 000000000..7a3c7fff8 --- /dev/null +++ b/installation_guides/installing_sqream_with_binary.rst @@ -0,0 +1,277 @@ +.. _installing_sqream_with_binary: + +********************************************* +Installing SQream Using Binary Packages +********************************************* +This procedure describes how to install SQream using Binary packages and must be done on all servers. + +**To install SQream using Binary packages:** + +1. Copy the SQream package to the **/home/sqream** directory for the current version: + + .. code-block:: console + + $ tar -xf sqream-db-v<2020.2>.tar.gz + +2. Append the version number to the name of the SQream folder. The version number in the following example is **v2020.2**: + + .. code-block:: console + + $ mv sqream sqream-db-v<2020.2> + +3. Move the new version of the SQream folder to the **/usr/local/** directory: + + .. code-block:: console + + $ sudo mv sqream-db-v<2020.2> /usr/local/ + +4. Change the ownership of the folder to **sqream folder**: + + .. code-block:: console + + $ sudo chown -R sqream:sqream /usr/local/sqream-db-v<2020.2> + +5. Navigate to the **/usr/local/** directory and create a symbolic link to SQream: + + .. code-block:: console + + $ cd /usr/local + $ sudo ln -s sqream-db-v<2020.2> sqream + +6. Verify that the symbolic link that you created points to the folder that you created: + + .. code-block:: console + + $ ls -l + +7. Verify that the symbolic link that you created points to the folder that you created: + + .. code-block:: console + + $ sqream -> sqream-db-v<2020.2> + +8. Create the SQream configuration file destination folders and set their ownership to **sqream**: + + .. code-block:: console + + $ sudo mkdir /etc/sqream + $ sudo chown -R sqream:sqream /etc/sqream + +9. Create the SQream service log destination folders and set their ownership to **sqream**: + + .. code-block:: console + + $ sudo mkdir /var/log/sqream + $ sudo chown -R sqream:sqream /var/log/sqream + +10. Navigate to the **/usr/local/** directory and copy the SQream configuration files from them: + + .. code-block:: console + + $ cd /usr/local/sqream/etc/ + $ cp * /etc/sqream + +The configuration files are **service configuration files**, and the JSON files are **SQream configuration files**, for a total of four files. The number of SQream configuration files and JSON files must be identical. + +.. note:: Verify that the JSON files have been configured correctly and that all required flags have been set to the correct values. + +In each JSON file, the following parameters **must be updated**: + +* instanceId +* machineIP +* metadataServerIp +* spoolMemoryGB +* limitQueryMemoryGB +* gpu +* port +* ssl_port + +Note the following: + +* The value of the **metadataServerIp** parameter must point to the IP that the metadata is running on. +* The value of the **machineIP** parameter must point to the IP of your local machine. + +It would be same on server running metadataserver and different on other server nodes. + +11. **Optional** - To run additional SQream services, copy the required configuration files and create additional JSON files: + + .. code-block:: console + + $ cp sqream2_config.json sqream3_config.json + $ vim sqream3_config.json + +.. note:: A unique **instanceID** must be used in each JSON file. IN the example above, the instanceID **sqream_2** is changed to **sqream_3**. + +12. **Optional** - If you created additional services in **Step 11**, verify that you have also created their additional configuration files: + + .. code-block:: console + + $ cp sqream2-service.conf sqream3-service.conf + $ vim sqream3-service.conf + +13. For each SQream service configuration file, do the following: + + 1. Change the **SERVICE_NAME=sqream2** value to **SERVICE_NAME=sqream3**. + + 2. Change **LOGFILE=/var/log/sqream/sqream2.log** to **LOGFILE=/var/log/sqream/sqream3.log**. + +.. note:: If you are running SQream on more than one server, you must configure the ``serverpicker`` and ``metadatserver`` services to start on only one of the servers. If **metadataserver** is running on the first server, the ``metadataServerIP`` value in the second server's /etc/sqream/sqream1_config.json file must point to the IP of the server on which the ``metadataserver`` service is running. + +14. Set up **servicepicker**: + + 1. Do the following: + + .. code-block:: console + + $ vim /etc/sqream/server_picker.conf + + 2. Change the IP **127.0.0.1** to the IP of the server that the **metadataserver** service is running on. + + 3. Change the **CLUSTER** to the value of the cluster path. + +15. Set up your service files: + + .. code-block:: console + + $ cd /usr/local/sqream/service/ + $ cp sqream2.service sqream3.service + $ vim sqream3.service + +16. Increment each **EnvironmentFile=/etc/sqream/sqream2-service.conf** configuration file for each SQream service file, as shown below: + + .. code-block:: console + + $ EnvironmentFile=/etc/sqream/sqream<3>-service.conf + +17. Copy and register your service files into systemd: + + .. code-block:: console + + $ sudo cp metadataserver.service /usr/lib/systemd/system/ + $ sudo cp serverpicker.service /usr/lib/systemd/system/ + $ sudo cp sqream*.service /usr/lib/systemd/system/ + +18. Verify that your service files have been copied into systemd: + + .. code-block:: console + + $ ls -l /usr/lib/systemd/system/sqream* + $ ls -l /usr/lib/systemd/system/metadataserver.service + $ ls -l /usr/lib/systemd/system/serverpicker.service + $ sudo systemctl daemon-reload + +19. Copy the license into the **/etc/license** directory: + + .. code-block:: console + + $ cp license.enc /etc/sqream/ + + +If you have an HDFS environment, see :ref:`Configuring an HDFS Environment for the User sqream `. + + + + + + +Upgrading SQream Version +------------------------- +Upgrading your SQream version requires stopping all running services while you manually upgrade SQream. + +**To upgrade your version of SQream:** + +1. Stop all actively running SQream services. + +.. note:: All SQream services must remain stopped while the upgrade is in process. Ensuring that SQream services remain stopped depends on the tool being used. + +For an example of stopping actively running SQream services, see :ref:`Launching SQream with Monit `. + +2. Verify that SQream has stopped listening on ports **500X**, **510X**, and **310X**: + + .. code-block:: console + + $ sudo netstat -nltp #to make sure sqream stopped listening on 500X, 510X and 310X ports. + +3. Replace the old version ``sqream-db-v2020.2``, with the new version ``sqream-db-v2021.1``: + + .. code-block:: console + + $ cd /home/sqream + $ mkdir tempfolder + $ mv sqream-db-v2021.1.tar.gz tempfolder/ + $ tar -xf sqream-db-v2021.1.tar.gz + $ sudo mv sqream /usr/local/sqream-db-v2021.1 + $ cd /usr/local + $ sudo chown -R sqream:sqream sqream-db-v2021.1 + +4. Remove the symbolic link: + + .. code-block:: console + + $ sudo rm sqream + +5. Create a new symbolic link named "sqream" pointing to the new version: + + .. code-block:: console + + $ sudo ln -s sqream-db-v2021.1 sqream + +6. Verify that the symbolic SQream link points to the real folder: + + .. code-block:: console + + $ ls -l + + The following is an example of the correct output: + + .. code-block:: console + + $ sqream -> sqream-db-v2021.1 + +7. **Optional-** (for major versions) Upgrade your version of SQream storage cluster, as shown in the following example: + + .. code-block:: console + + $ cat /etc/sqream/sqream1_config.json |grep cluster + $ ./upgrade_storage + + The following is an example of the correct output: + + .. code-block:: console + + get_leveldb_version path{} + current storage version 23 + upgrade_v24 + upgrade_storage to 24 + upgrade_storage to 24 - Done + upgrade_v25 + upgrade_storage to 25 + upgrade_storage to 25 - Done + upgrade_v26 + upgrade_storage to 26 + upgrade_storage to 26 - Done + validate_leveldb + ... + upgrade_v37 + upgrade_storage to 37 + upgrade_storage to 37 - Done + validate_leveldb + storage has been upgraded successfully to version 37 + +8. Verify that the latest version has been installed: + + .. code-block:: console + + $ ./sqream sql --username sqream --password sqream --host localhost --databasename master -c "SELECT SHOW_VERSION();" + + The following is an example of the correct output: + + .. code-block:: console + + v2021.1 + 1 row + time: 0.050603s + +For more information, see the `upgrade_storage `_ command line program. + +For more information about installing Studio on a stand-alone server, see `Installing Studio on a Stand-Alone Server `_. \ No newline at end of file From 3c89d556f405dc12e25a1d9d6ab3eaa04da749ac Mon Sep 17 00:00:00 2001 From: YanivGerowitz <82020437+YanivGerowitz@users.noreply.github.com> Date: Thu, 21 Jul 2022 13:52:14 +0300 Subject: [PATCH 139/316] Added Upgrade Storage link --- releases/2022.1.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/releases/2022.1.rst b/releases/2022.1.rst index 8d881c92c..f02676c34 100644 --- a/releases/2022.1.rst +++ b/releases/2022.1.rst @@ -138,11 +138,11 @@ Upgrading to v2022.1 $ ./upgrade_storage - .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in **Step 7** of the Upgrading SQream Version procedure. + .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version `_ procedure. .. toctree:: :maxdepth: 2 :glob: :hidden: - 2022.1 \ No newline at end of file + 2022.1 From bce4e2dc23534b6dddb56308896231c449067c0c Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 21 Jul 2022 14:14:04 +0300 Subject: [PATCH 140/316] Added SAP BO --- .../client_platforms/index.rst | 1 + .../client_platforms/sap_businessobjects.rst | 60 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 connecting_to_sqream/client_platforms/sap_businessobjects.rst diff --git a/connecting_to_sqream/client_platforms/index.rst b/connecting_to_sqream/client_platforms/index.rst index a38f1f1f5..be5f4af16 100644 --- a/connecting_to_sqream/client_platforms/index.rst +++ b/connecting_to_sqream/client_platforms/index.rst @@ -27,6 +27,7 @@ If you are looking for a tool that is not listed, SQream and our partners can he php power_bi r + sap_businessobjects sas_viya sql_workbench tableau diff --git a/connecting_to_sqream/client_platforms/sap_businessobjects.rst b/connecting_to_sqream/client_platforms/sap_businessobjects.rst new file mode 100644 index 000000000..4c740b034 --- /dev/null +++ b/connecting_to_sqream/client_platforms/sap_businessobjects.rst @@ -0,0 +1,60 @@ +.. _sap_businessobjects: + +************************* +Connecting to SQream Using SAP BusinessObjects +************************* +The **Connecting to SQream Using SAP BusinessObjects** guide includes the following sections: + +.. contents:: + :local: + :depth: 1 + +Overview +========== +The **Connecting to SQream Using SAP BusinessObjects** guide describes the best practices for configuring a connection between SQream and the SAP BusinessObjects BI platform. SAP BO's multi-tier architecture includes both client and server components, and this guide describes integrating SQream with SAP BO's object client tools using a generic JDBC connector. The instructions in this guide are relevant to both the **Universe Design Tool (UDT)** and the **Information Design Tool (IDT)**. This document only covers how to establish a connection using the generic out-of-the-box JDBC connectors, and does not cover related business object products, such as the **Business Objects Data Integrator**. + +The **Define a new connection** window below shows the generic JDBC driver, which you can use to establish a new connection to a database. + +.. image:: /_static/images/SAP_BO_2.png + +SAP BO also lets you customize the interface to include a SQream data source. + +Establising a New Connection Using a Generic JDCB Connector +========== +This section shows an example of using a generic JDBC connector to establish a new connection. + +**To establish a new connection using a generic JDBC connector:** + +1. In the fields, provide a user name, password, database URL, and JDBC class. + + The following is the correct format for the database URL: + + .. code-block:: console + +
jdbc:Sqream://:3108/
+	  
+   SQream recommends quickly testing your connection to SQream by selecting the Generic JDBC data source in the **Define a new connection** window. When you connect using a generic JDBC data source you do not need to modify your configuration files, but are limited to the out-of-the-box settings defined in the default **jdbc.prm** file.
+   
+   .. note:: Modifying the jdbc.prm file for the generic driver impacts all other databases using the same driver.
+
+For more information, see `Connection String Examples `_.
+
+2. (Optonal)If you are using the generic JDBC driver specific to SQream, modify the jdbc.sbo file to include the SQream JDBC driver location by adding the following lines under the Database section of the file:
+
+   .. code-block:: console
+
+      Database Active="Yes" Name="SQream JDBC data source">
+      
+      
+      C:\Program Files\SQream Technologies\JDBC Driver\2021.2.0-4.5.3\sqream-jdbc-4.5.3.jar
+      
+      
+      
+      com.sqream.jdbc.SQDriver
+
+      
+      
+
+3. Restart the BusinessObjects server.
+
+   When the connection is established, **SQream** is listed as a driver selection.
\ No newline at end of file

From 980753a69c3792e854316368614f1dfe370de159 Mon Sep 17 00:00:00 2001
From: Yaniv Gerowitz 
Date: Thu, 21 Jul 2022 14:16:55 +0300
Subject: [PATCH 141/316] Added images

---
 _static/images/SAP_BO.png   | Bin 0 -> 112881 bytes
 _static/images/SAP_BO_2.png | Bin 0 -> 25160 bytes
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 _static/images/SAP_BO.png
 create mode 100644 _static/images/SAP_BO_2.png

diff --git a/_static/images/SAP_BO.png b/_static/images/SAP_BO.png
new file mode 100644
index 0000000000000000000000000000000000000000..413ce7d0e4731668b9320ab6a6139177329c1af6
GIT binary patch
literal 112881
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

pLD2D_$vWC+{e~$c+6bxRmwn z#FdQsrS(f2X2C4+Io+TB$W06`%&QpX;L|p<58)Lzs%>4MB-ikY=;@hysp>d2cP-&P zqGVLf6tpmxMO5`HJit3R&!oRHQcdEUew~4~?_M5yfS-)O0Wpo^36z zqjRBdqVex~F8qy~e*VX90w28*6UzT;H(fDm;5Mf6n^u6E#H})SpVB-h<0@~HB4wVe zV3Q+<$v!7W+;>FdFc(HtE8wFe3R?ELs@55MkIJ%2JMCvP<5LS_mcV{^0^DS9=%OLU ztMZBh`I`&s-!g0PDEZoxYR_CYJi~2n=-!})Z#XL#@&m7fh+0EsQBd;hretll@ zw176Vn5lPctEgtcK@Q`~if-(()~a@aKXS^mh@0s;B#LPGU6FM+b;%E(0Dp!nbFXh>=w9sJcTe zDuT+6U!NAza|n?$A`7Vz-6PxGBD)CT?QWC~a!SuZE-emeD?MD4uo~XPDbCy}>6_zH zXL-)3=W_a-@8BMp8t@iB-@jsd(5WsOUJS2Ctl> zfP!;Ab;Sr9fBK?sOwM3j?vRdE@p;2BSp$d8D@CStNNTt!8W1DWnon^lOQ_>ybzDxeD~BXdE1DO0B#aexoX>E` z7u1Yom-n;qsHz#ci6~%rBn)LV96W=vwM>a_{+W`h_OhCe8fKmbw!V^THj279j8lk| znoUSTsjQ~0kh}@6q#h|O(>o;X5EGwoM3%EpjJ~CJaotQ!+eTz^^Jxy{il)Vy)@61c zEge%5pSW@F*qxk`zKi^tikgnPCZ4k^FNguDQp#qc@`jqm&fy7V<_a^+aRWf z?yHU6SMw`J#pEshBML)eichnMS~~@b%bShOJ;*Qb;}g@Q}+R!!=7E|Qp9vK;5;un&Bo?Rq9wInnuljs+NvGp{ya^)6O@FY>vvTLmDeJJq- zoZK>#bGIkw?m$nC6qqC`qq~0lr=h8ULjKpw>NIQq_&K5@yIT3K7kOFlvb*)V|nx5E37k#;O<{s-l(9WXOHug zlG7NUS&L21HL-FktZ1^vdP&ObJbJP9Yi@eqO~3iJ?r%5MUNWTen>TYCl?s^U$vWii zI<594hwcSg{AqDV0liRBBg)68v_y5nzdNtbD&qLTewp*aZtPOt``HaIDR}N@wYZ`f zct*(nlT(VvdCd-R8e_a_xMY03y`aq{<8thhji74aS0|Ov3D_IB)oZylF)N1czhW<_ z9dPur={M&LP2Fp?U8;nP629Rw;n(tI5w`p0lp3#+|KW>P(k5X?xIuQhmla&OWISYz zVoz{ei|PbiQow!AB*`La{w=ejltCb~D3(u^%r4{1CJh1#+|RDaDrp7n-0~jBFPp1d z$FWLU^Qt+^ng(1}bTM`-vh}NXiRe7QX(p~8=AGEXA??I0X3MMW&adJjXA*Wn$VS6D z?mWMxoI#+t2JwqyQYz*_9OCAxm_S(re_6v&aFeE8rnOIv2c^p=p+``ID4_19Wfvu) z?q=zheu2-_z&`GZjIE*x=@6R|zmkK2BZW=W1j)VB!I>jm)kwTK&l8eSES^Y;?RKrs{q&3}TwA~`pTh3llm)0gI8hAk0Ow-KQ)-~=B zlenc*l(ah53>#u>7kH9QM$^mXeriAefOpi>i6jLpIq(`>y9zj3{V2dHQ8|`KPg5mbb80D;!iq7;g$8E0 z_|)RS@Z?ZR`s~u(rS(V69g|Ef0)b(vAVF7RSXF(`)!Q%JeL`J40+P}SrRBAt;_4Zg znOl*PRRV5G&MYytA}Fex-hI5ae&adl=}+ABPws{P|H@4@myK(9&FgrK%LPnJrEDsW ziTeF;#dZH>mmj&^FR8_gndBVh_f)YfIxFgNS4i-d=eX1E2h zS{I*lQPGQ2&P&`d#@4^x#;?OMq+38MLenwNIkHpABudFD!Gc(NQQqT{f|s&o5iC_E4o;^XRBc%gHn3D zDNV8lfxZbHDi%?)20=XXuG%*7l$^1kn`-f}u_Y9=ItU#0d9)+N+|5E2z%GBk0c zu)Ny_2NMKk6}FDf+>TBzPcLYmS$RA(brT4R%E>Kl_YO=NpSv|Nf7>T8v7>(>HK)eS zJCfiTTHP=(y?A$F?eXCFCdSSi?;c9<3@@qbTHJWFwDD+oay=k4$<-^w4(DA`+1fX} z5S@^_uy&V{kn2f~#1ed?6Y_68*aEe!Y(j2&{`PyizuokQZmPOsT6x8!g5RuK(6mO# zxJKBhj$f~uPp3*yzm`v@LeipM+^kaCvP|4GM@T!8LN63t8xkR zB2nXFX-tiRO}&g|m4a=RqJ51lrdrjZS>CEr22(6=U7}!Hu7s^qu&-6cH^|$SE7%sv zTj!}dlxaEFYT#=%UFy`GtK@77R2)iFv1K~&5?`r;Em6ajXcEeey&E*~6?(3rA{FZ2Y?nTMh7!*8YQ5e*Lxqz2-hGR=%yafo-;dEmr;w_Q5TdzV&9r8pn_h`@lA*ux^YG z6+@!h1~lO#x^SVL*1pZwC1ZC-eb6aovGw zLokhZT(<|M1KLB<$H?*hVVRTuNrQe#{lV!YvQb@xnp4&1HK9Eq`20|?9u4l z$%w4+sGO zDeW;i1Brzr@%h79RdbZAK4?rT98WKwNiCgDDw@nFUra8VOD&$ys$9vbT1_sTNy?u} z$Q{oto6jtp%POBQq^@U`!vvElg%d^fYx%WHh16vrvwXU&Wxc3=DW`h6v}vWJVKJk0 zG^>29qGh?deXXE&ISmBzkn4ZWL{ZHp~KH|o09${J@Yn-{2EYi)x!n))_7Ms9YF z-YTh|Y#X}XH+i>XXtTO$vY}(4fBaV0(ABP?&B4jr@Uo?6xxIf4x`#tkckA2do4S|! z#%_+z-tQj1IyiZ!Z|nw4KfU}ErthD)F*tc+V*cLn)J>4rTdn+Q`(# z33jjKe>>O@TIq^(=TEgJ-kD?~6g zVpi3{7Ns%{H3G)D>}rWpb~O?Kw+u#X6|NE~MKbtj{rg0OQ+^iyU?gAG8hbAw-YZhxXWq_BvCB9YTBXQ3LqMejI2h zdc-+=kPtCUh!}B+9Px;ma7BMZH|!caK%n$^#`O~u2J{I9gvd^E%9vODpjZ5Wcft@U zafF;S>Yp+}P8=g8jQA#x`zDS1pg*Y_@l74|PoD_PnDS4Z@Jk-|Pn`@*n+isMr!pR% zGZ&CL7M3*~oIW0wH5ryY5t%m`o;@CsJ4MN#56hg6%$Y|Y4bPp6Er7~6C2t}+e6wahoET>m2XH>4F zlrCgdtz}lNrh<>ER`TlB(Xj{W)^ciA3L7@Fsupvq7YiHK3hGw@sBe!qP(WRUvao)& ztaY=XeyOBs4JdCzM?@)WSu1QWcJa})cw(!hhuY(MrQ7f&p#ZQxjVV|Xkz}s_}o3(U;~e)79UP6p)C^&59U^% zF04PFUU~%W(@PI#&}X0?E~A5=yxjhs3b3;I3{uk4#>4G?+%mB7Wc|j=)y-#ryXl|1 ziN~xQ{YNxSN(Id-g-j|%AV3*co|29iwyYMisuZ@V;>VN;*;ETzSBu(G0TJ6;VVgPu z%UW^!W)T~zur*cOzD3NgMa;HY3fn4XLzQ%Bkis@eJ2pu=)I&wmp+g$mE#uItL+mrixpPEGet z4Yzi6*ET(G^qwW|{{DK;bx>UebO6T9_@UHabLMx;J{VwWDV-8`UA&$G#d+-~OA zDQ1?f=3HkHIB4SAXX-y_7BFb)KVV88vg$=n-#_>@@ zE^))oaeeq05ZQox+?Z$lxJUe$nRkPsdyP-Zj7QvDl?(ki~gxo!I`rmSu+73sodG%ENGk$ z%UX=gT?xsU3(sDN$Xy7_o{7qzqiJh4x?nCUcQ&?gF{WSb>Cp7!!O4e1lb|H1+#i`ie^oa; zeIHacP8+-l{YA^{gUQ9mz|_){vAKuSOHXH)pH0Kdg@>~%Pp20jEv&zQ`tthA#kJ>i zOW>v#^Q#XQR_{ZGnp?RK!3wmsdiBLB`VVKK4~757yNO9Ugk3G0MYV`Uqw>5)`FX99 z^IApBTE#5rKT%i4u3e6zQ-%UoqQR+G#-&%zrC)wg9~~X#l0n5~uo8_cMitz~l>iTf zCX=emCY9Xg)x4&a=s!hgQYvO%eo-TJ*GY`1S-yx_o`hAgh()2aeYL1%g)Fu~*rHOz zvPuTLW8WxY*C1k5D`8hJhijL1XpyjKka1{|b8M1vXb`uqk;OL3J2lDUT4k^uGT2U8 zhh_zAgQ`=5u3L+&Wzok>me8TocWY2{tm06jXc8K=+*(zfo77yIHClt~#=lj| zrG!^I%ptt}2p?A1FcudDS*ac4*JVcTvH;$GsPHs+f$8jv>On>0#{8zLu-`zB8W zq|JKAkNKz0cqfhdB#)ERrl3Mjo$^ng^+_5BACXfg12gCR)20H_r-CwPf-G=e7F2+vx9pyKmI@-K_1p3KUH@hb8ccMN5Ro&|tz0)&sziaGH5BjURJKf`V z`==jtL!O$v*Ee;4Xy#G>#C_U0bN7d59u0t%W*?2tJ{q2R0B#zbygN>F6NqVY;ql}G zI_@RprkQ1Qu#`zq(()5pbb1WwX@2#|{OV%}P)q9&m!8cnqd)gu+;}p#`e5bSv*pdF zD_5T_Z9G9A3cpIrP1jIp&o`mJ^?hrl_uNF&6Icm#6Nu?OH{E~m>H&?14}U^=^wXn9 zKRtd7div?flb^SF`t+A=o;~~J#j{^tKL7bGuU`E8>gCTrz5E5l^b3gT)h}Bhrk}t{ zZ{76E&+tFZNx%Gpwr*{`{MAk8Bttk=GuTuM*flCIs8?LjEW4mp%&c9+qE*DET?%62 zKq=+WE#c5D=F}s|Cq`2w6KS~Rkkc9N5U+dTPvAEH9-PXA!Sn|WLkDbFYlsuj)Zls zjD3TkX&IMR7LP%p60TL&u3o^Xh~KaPG$ilPAZ%L7YfvQb*r9;ylyhiOb!wEeE*3RN z;#Lm+;Gl|z0FXd$zg>>3NwS80p^Ry!oK>MRwo=QrQ5jb)XI*6C(=211E@GUhY+r5a z(WUeLXgFpXxs}=ax7zr&YdNBmnRrp5k7gOrZWY*N7dD{jQmuk3GxBb9 zj2f^F>C_>VYB=QB`PCD`+pK--t%JJMoGM{5Z1|w1Uz;Vl*^p4-9yRC{J7Pm_*29-s zcsIJoj=9B7n0YtryH+}dG?5d!zdEC$=a_;Isc{Of@=xxz_AavU$n%VDBPaH{M6`NF z_h39LN%6zJ$zy)06U4+}-_!{bIq;J}|e>%LJ2+Ek;CO8wK(^N?2 zWN6kD5SBe1obatesZod&k86qP>DvatDd zapURICh%nWDi{g{eT?AO=fcqeQm);2f%1Dd-FbQA&WpF9>9=nB>HdS44<5V#9zJ{t zJbLsB05Ls&^6JUc*F1gp(>BkZ{ruwDPjAHZ)2kP+`RV1)Xkr3h{;~yndiC>bF>Skv z<|-Pfx3;!kym)p0wVTdJg|VyBa+7BDIrXY@S{3KC%Fb(-UeGRO(XL?CsbbTvV$-Q) z(=BJygAN^Z>nb?(DmnG5IQ5}7R|Q-&tbPMJ=Gq~6%v-E zoGLM2Fk3N8kv~6cET$i?XqCe(<$vIc>-U#j&q+s!n-?-k_#WiO9prJktQIa|ntEEq z<0wDjxS)%eQKE=J!cji_aeik>lVowD#AAF;hk0H24RRD68x*nCDvlMbvc4zz9S?Du zeRNcjTakEx-9*ZOa#onYF6YOg7-a0zC}Nm+M%YEeKJ%QY!v!%XR&gI~Y|#&#daTko zW7leHpB7DQD)QMCX`^@zySxixgbU&Xc4;3yeCcr>EUT1#aRT(0Mwfqcm$ZytX5 zlEEnf467uLSJm6tHDA*{omJA6Q^r$BE5yRP$|j(}IjTnuo5v#7%0zv~ z3{rd_Bs+KaVmow3EFCj6#CbxDquWk*>{JOOQ>N*Xm{5l{nIh22j$3vOOj*ZCKvT z@;2zoU8`sVu2yzjgPvV=$2Fj)^Ey!1bpxPw-+TkO=_Wb`X78=0K9uIZTP=OJf!6-p ztpm5)2JZmvLwDPU?zExYZXZVJ7`X##S8j&J>=Me{@{_sc$MY*s7FVBcgAOdW z_G|%-PAJP8&zI5Bc+ruYpilRvTlZpv#?@;tuU&tIa`QFUZ~X+^xc&2u+fe>=>ki88 zyFUYW?)?JXy}xzu{xA0*{PLzxheG?!3UuhU{;W^;{MpvaH@t!l9q@eXrx#m4zufwT z#?~tu+ZKY5gcdYK{b6o8B^|-4mW$qR(yV3DsA1BoI-^~2R;T=&cEtsq8fKk37L-~R zy=oS{DpuWUfK9K4UB8xHzlOuG7T`3hdkdFw-9;0WOQzJzrnS7LH9SV;!sb=NW+gIK zrC(gIImSznHBJ5cya|(#i>z7NhsX6fk*kpsgVb&AW^u8#E=TUY)FKqqM z5y@kh48Axmf11x!NW<&MMLlK_D*+WZ5p}O0nAO;&2$$3%lpHIxT&nnVBELANBV!VA zMV|2GDfv@Zj1RDAE0{)pbX0*~BjCU#jIwSI!OgO`DBB<^T*_udpiKln{63il&T?%clpgXqx+InR{~yYAfp#4xba{ zmo`1lDlMhy$SZ3hs)n^ArYabb%?L^R&&!)Q#|x=AaY~q9k+o8{3bY}nv5AKWYA9VVlPnS9wlr|NdKD|vy#taae zF&&nPLK}nt9V2C%$Q+cY+&O@fHxESTFT~`}$K=n&70d(ig$vsx6oHbKl8S)Eq~gWo zlEswLrEOBnmeb0C?V$*kY2$@21DTb}Sye09RVz8w=zzSrzm6BaMjM%Tqky{khK<7d zjiQFlZHgPO0<=Ld(E)k4DQme_-g>>F?M7wW^~$zuRqfY->W&*gP3KLZt_yhAO*iYi zZ`JqQYUsV)*n7LF_jYqHi0KZ{+J6^l8@LCw58iJdyw^Si-0c`f=^VKSbdBEc9=+f5 z8g$&tzVZ7&|HOlV39u4+j|mu_dNe%saAf+?Hls6-fw7s#<11D=(H;UoNe_TwHsxxc*{k{l)UeOJH^L)#}EpHDL4Q z#?@CFo3E~3{Ry~s?dR*)f4K(S`1#sRlMTpnW^=68hgC+;2K1 z6T+gNc|pD4f>tGyW(AXW*%_UZv%1CSbV@GhRIun&)2L$6t6# z`tdO(148}}oMx=Dp5L$<>*EW)XV&|HO@~L>>kOZhpjzo89S7MAugJLuBzH55 zSY8k||MIldMOk}MO`lWT=K8pFm#{|nsJ1VeG!!l40y9SbANJk?FplI*8_t*9U2=E1 z@4o*i$>l;D+)Z{j%S_(&GJ~0!nVBuimTbu^w3wNhHIjyBG^EjJBn@>Bi&^tO)ioN+ zT4%HCtna)Ry?#`#uCA)C?ymQl_pPq3UVkio?cwBq{?&V1PoxINH9heBk{93K`lAQl z-*!6XbVSV$ANu&Uxd(pn_^jiX@(u;2|NM_1yzt)opFZ^N+;x7he6sbERVRP_%-jWA zfn%52cLUy^L%N(ucoN4a|lV*P=uzngr{pMBGOwTGg@wBYAK?!TBEbI z6frriF*(}U+*XRXJY78Zgf6k5EwKQhE{QC935IH)WH%Ah>2`LL3COGjyq`13u7)>f z&V|ubZSsE0;HKSV;noXh$jZDtgkHe8D{ZuvaUZ7xxaBUXPX~t%rjs2;6HqG#>~#{y z#D@&*JQ;aZ=L1=Xx7i5@6fS|nDO9>d3Ief;EO#m4mI()>>MlU0cFQ%sZy6A9b`yb0 z*QW+r`!sC?oZUngaw3cHwhy$m59m7v+d2keI?>^$cH3AoCB4(tf`< z`N1X04=ql4WO2r$i?bhHoI}E;S&uHwc#Om2%QBu=o(Vj;A`5tGWi|&yGM`?R^~~yQ z;Mp}f&#%dPaaHP!H7PSzCBCyM^}+W}|KRcUzn!t`fme4uFk}0VA6xPGdq@8D!DX*3 zy!6zk0grs(|Hub^|NP*RnaeLeKhOX1kB|NO)$Koca^=g50w4YG$Wx!5cy9LT2jANB z%a=DjJNx9Tivu2cZ~uQjweFc&L34NIEIp9-!t8VZ@$ll$HeP@J!~OsMyN@4uVa@NJ zTeEn3)c1e!(aHm9uPzAumj@R;@!|1xCrj^pVaM-Y+xhOA&?i1P`}&fwf4YC}ha19H zA1z;bxa`v{H@^GJk2jpI_|=PhAOGOwlKsi|&sh8PhdY1p;H>$Z!*}=EWU3yXI|{OS=`NKySJp0N1Up&3| zd@O&%(fA)d`0>oS2OoZI_1eSH@2xmBf7_L3KHB-x?1S6=GiR+2UVk|LffrY-IS}>A zCwpG{Xvc#uFI%$h(t&`?hhALz=?cG}KJ-a&bi=u@njih{!)?dY_Xd`qjcGn}LwYhy z5D?q!e?xjITzD=9+$234B@Kv{2FA!J&d16rF2oU#nFI;VK3q&x0Nm=A%FD@s;!2A0 zDuLp9sxl-+8Jeo12uo9kr)z+Sbah0!>PCh-DpNxdou!G%R>$P1fY@9$5SOQ+h|g~U z67yS<3cN@z)TR`98Ol4}#38lRJJ>X7yor8i1?bGI?8vI>%q9!VkrfDlyjoLUtueoj zprGCa6xEx#=}wkn9+~u1++ZqcFqbr%$-*gQ?G#Hn-(11BRPrrV+~Q5uLKdhISqa2s zVL3ACNn)*+T6t2oL1yJ(qiB-b_{}y!vrVY510p401H>vjAW=IgWEv+2hrETLS?g4^ zx)iN$GL4{>fP4dr!-P)lmW2ItlEqVY_qK;Ti#)?on>Mi8yq==X76Y9RltN z-54-DG*0m+p3`v{=O~H8g#C1j-E{V`c{lzzH}R1LnGem+d}v|XLyM9hUYz{LMJbOi z%6NQH_T!6kA6u03_>!#0mt;P^B;$!C8BZ?Fd}co zd&~dLHAxS=b?U#K*$F)LS>KX`oeN1KyZ9jic9zkPN8!|$AU@Xa%yZqB&x#T}n+iC=!OV&&ng1$#1o^30Z1 zM=L(vl>WfXBM-fOHIyM@$qj^iK_1d2sxKyK$XIv^!R1uVWzKH8mP)^6prIh&SxMId;ps4-S|T!9A~UrV zH?mrza5I+KeH6X;AS?My8*P^6U` zf%FO!kWmR3Gr&+)hOAr0!pS zK1^Z#lVjnZ=cX?jZyFdFAN-2k7Lrw*yfd2?lLvNBEy;X(X%_GdStdN|+2z?jJhvj}`IWf< zH}Nv>xs|yut}S?eRnClcc~32je|~ZNTkA94*^vJ3ri|woM$BB5_~yE_hd#dg$Y-Ii zuFiOWOX1ArDbIWs@zf`wAFR)vwXNj!Whqa89Qxv%sL!?(%-L4-^8DzR=S3khZ%4_D z1u-u#h@Z8)?!C=rpKLFmv%BJhjae_u4Si{T=-aE}-d~$EYirJ|t$FXRNt?g7eEz=5 zx7MbAwzFu#-qPiVD&Afd``VJo_t$2uI$HnXhQ!7D3s)SfTXvvk(Y~V3wq~q2T!Zuv z)}_3@EaJ0m$(zpBe6l%t`Qh@7e*Be3>erqSEI(L}HZ0szw(LOp<}McAgi`+n)9DhNQ*&^7aG^b_CYX-;wg!#+WUq%XSA; zuiT%r@4RqNfN0hJ;w>ktHykcG93ZpCKj*|1(aCF)b%zS( zZ%N*8yzF>r^P#KawMPqgo~zjzP<<*wzIxH6lbHAboKx@fj~_W7^eZw$G2Qa05lXq zi7h~Ik~TP5dohLJQflj^RNq)QncPG{W;SK$xZ&_tG8Uepi^y!F;KsslexJ@a79LH; z!U^IE^zjp8;R!_@iN&1>g`J5-#-w7?1dPe0#*{J>MQXVjNUN{_>6J`+B|=kXl_`sk zg>%TQWq`aoz&jRRSkD4QJS#y1z!o=JOPUBu`2=MG8#jT#Rw1xg2)H=}B3qT1Jg2K6 z-++Q!=Y(@tCncztIRWoLxXjro_kEns&4*j3^y1d%bZ*I{@6%0sPS>N*^>H9moG8?7 z{eVV40JO9ZXgj>nb;6;$>C=(1aP9+8bU1v{df~%>i5W4oqh^*mbhkXGn>@eibKLa# z^_zS?-Jjs5!STVN+i=t92*ID{CWMo@>38o1JTg1_v3Y5KoSXH~+{}j;Wc+bq+9L~7 z9$lFF*n-T*7vw&^Aph}&`Hz#2tYkk)koDA(?5CIHJWVDylB?m9@4_+1?xh^>xB0Cx;KX6TSI8=HlM0_kxYB)E{&LJ^eQ5}cw9PSsu{+yt~-;Xvj$ft%6^ zH-%&na9_}D4a?Mpb2FQOh^)5A96$%$$ZflkOTwr;g6Mn#^0bc5z%10q7jg7d)R{!g zCF4!gsl<>{Vn{7D0%>KYv~prJadwlLnogPI^O@vP9rv`3KBu$f)msQR)!*c%LLLD} zOkR{U5s+0eiS@*m3#=6c;3ga4CXu}gMiYHP$33K*%uQrwlhildop>av%)FkrbVT$$dVP%x~%gH0|6spgQ`so&BvGba3d51AyM-MZ1}^ zo5=j8A;8EGm{?#KAxBJuj1AmGj3zR(3B*LgAv?IqG3;=TI6+J2?2 zjvNUm=xKb+GmbJoZhHU1qjTdQUy$|CoUDiD<@|9`_Cxc*O=*uVNPmnheVO<8g2Kla z6+X5&5A;MP5G=}hYH=>`^pd=1mgYaZEdSZ%Kpybi^8DvkkY&POSXl@>PoCD5KC`;) z*)?U)ttowBZOKb(i(g(__{ut<2$-?HXvT)(85>GwY%F_qQ^l(r%VusWeq&P+@Froa z;(AeR~_i;&--{yt}RBz3rt0Agmqb@9wO8XJ^HGyUN}tABHOWXiwqC96s4w z^2wgkPxh97vajOP{gt2YulV#}#b*b~XCEk=bD(7I!Q#0GOXeLcpMR)){^6qehl>{+ zu3T`WYQd4Rg~!Sk9<5je<~mlf=y=7V6IHx)=0B=JeZ^L6 zZfh`aYfuyS0Vu)tApXu^!LEzKT^9wrF9H1Bm-%~uD}ucgSA~183ie(T?7dE~FNEMg zsNi6j;7}+ZI2_7962?CoCO8%*JRUCMAU+W(KM~msoV-DBDhk|00AeD5a~G}fk5!zF zQ%=UYcoh(kpbkvb0OylhI3S|AkkS&A(gJP@PHVjgq_%*bE`y%Zv{wl?>457Qy6c&` zkStwjrY%ts4z~9IvMB`CvHT1!lwf_)srbszFAIQ|E_^4ZuEk1 z6Gu#?e5O>umI+wGO+qsLk|QR{O-BZJ}`J#h@x z!&y&27nyk32Dh$9sqaw%?LF#_9(8+1$3C+6opv7q3Ig#}M6%6npQ?vsmh zpW^WJ;@oElH|0G`>1kR1bHMWa=a(0}u!3;YiyU59S@gon;ulvHzqG38mDNQv))c+E zrtr136IfR`b6wHQ^~E#Sm%P5AbmoSVnVW#(nVU;q-(2#>mQvu&EoE;c9wmztK^ei#h>ji0cPzkpG96OKO zAwgP^A+5MG9Vj8lC^2M|5@ePcvw(7Ab_GFBr75?HAg|h-Ut<9ZYMBD^gpPd3x2TRO zs%47nSfHeyEv{!vybtM^(gwDy(Ml#aaT6~oywB+b_8OrBs1-WuL|)X3oji#PXpj;# z5;&V=F22kqkh=x)E@3l3ClGW|h?U)96*rB*JGrTwe*KAl2?|hX$zYRG*GDno%>jKa z?fn2;xmNCDnUlS_$vz!7xrsP*B;>xf!kJF6n1;>d3Ee2ejxg*n3s^_2))AX+6tLSy z9e|y{=@@f43EZx64x?Ref^N8VU1L2H>t6Ozz@eM)=>`bK$yhkS*zn*uFan2;12-=m z?ivTM5CyTAusuXDj&PWZ^o@}S> zq&_|;^NG1RkI&5oLp{DA=ZOV5PcF=TY5~F13v-`dl=}=Aio>%@@+h8Ln*aQ={1=wz zgP~qrp8wLayqAIHc{5hzzq&I2wUzlZR}}!Sug>@3jWq=nGr?9HOJ-~;d6mP=%`l_N zUf;}t1W$ZX6-1QwWDnI zj*8hks%Gz~p1reX)~@Q=yQ^mJuAH@}lH;jbVD|pHIR|*a+=KPNyhDuyhk5f4^A;Rw zTzHfZEIP_xdQ`Cd2!Hv}h84$nE05Q%I#ILgWEHR)I90v+WX;-B_3KVGu0JK%a7wh{ z6j_R3;qzA4@4skeqRdV=>dZCjibPvRA6?m8tq<>VEkI6o95*3A7BT0PTRPbwH)_LZchh=*YAtI6y=Vyt3%j^Yi^*S$gS(g%@5}bnfLPXJ1}&`jsVq zGZvqFb;+G-$^13$HFe|Jw2kGgnXqA$)yh5XBp-ym)hU&|7PQ-&z~|_S%c@ ztPOs5&4u??pMP)7g%8#SeYg$?{%C#hhwFns-gt2W!Jllp=)-4QFMm1##DQ7c21){>viw7HC*y2b-nr1+fUumvi0r_Ktn-mT_Jtb+ zK~dSkQ8__3vV(7AUyRDR7?ph~8pt7t$+;4jcR4QaN?iVxc!H}51sw9PB^ChJfuw?v zwIqT=B#>4Tl~ERzQ5v058k1QTn^hj0RS}m>fXGC=GCrp= z0m!XN%&khws|Hf?Z$WB)b$VewYVNFI+O(sxWlT};`kVr`_kX>4v1C-U}mIL*9 z6%@SuN}vH@VO0Y~QFUWcbwhD=LrF~|P+HqWP|pX-c!F}Cu%ba!$)Tzd5F@N^64f+` zYdO^MIS3>KLP0mop`=kHZ4}Fz0Evt*kqM-7KqzY#$`oG66(XQnDOM0j6iO+e zRLTfcauuLPsAy?vZqWdW7L8J?QMPDQS^~AMMWfSFwCGy2ZC!GL9u01amb($FGMTzaDY?dgSqt$YY@q$HKyo zhlZaBi=a3Oghx&SHp5Rv01>Anfk?l|h%;fK{$U~h;UQMTG@>5y~OtVsz-msL)G3M2B9E0Ya{jF#KY4bZ~U+#pu}Jn3&+0=%ASB z;Mkbp*w~A)2^V9NyogJ@7#DvrF7|R<^tHGf*JC3?;-Y}i_#2_|QDO1X03yD4SVDAo zB0*SUTu5T_^~BWcNy*oflCCEuh9oD3q{N4$#DyjU@uA5HVabVMDM{feDd8z;Kv-&W zSXxq8DhDnSo|+VqnjDdy${`I1Pfw+YOizl*h>6R%L6Aui6`vUm#AT2$J~IYLxQV#< z?BuxY6b`9Ce2y0hxoMM;$RQ~=B{4TKF*iObFCi&EAvr(Zivn*vB|jlGKRz`-F13In zKBX`rr7$s-q9`G)*oQ=l^b#Ne$S4I8GfI;tkPKv&CTEqUWRoxn$Og)jb2#Kyq~unl z=9J$AHuEY|^DAzmpfYU&hyy7FRjEKBP@M)80X69Wmja{|)uaN&wLn@)-DIQ#rFH3L zb?N1G8C;lNUY}N8pI*VE$f#(@C~wFt=VewjWL5IADiIQ7QdDuMoIGkt0|=xPxfDWKu1K0A zl4f(r5y_B}2Z-cAzPQO!Te zP^B(HWD3-pBDJPa-2xO)Xh^(Jt-T2ihn7}~0TU)EOEp^(K z`c`d&uC=LE+sH+DUT%_W>RSzJMVm&hYi-u+l$|Y#_GX1%qSQ;3ZOzIyrBbg}=v9h# z1%cj&W@WqLc0hWws)GX}ZE`@Zm#YYxReA*hvZ44*$d!7TN-tBl%T#SLWafYfAoZe+ zLZX=pnYvA;(Mti9Ucv!Y$+?y*NaIO}L&%h5mss5<=1NHk^d#P*mjN1*4shu=E0?Nu zGL;uNIyn|OoHv`a1)&a*a6o2>TJHspg~r@$zxQ;=+2I`NWkE#KCTh_OCLkn0N}EWd z6JZzG3+O~z4v1)ULJr=&e->(;NR9Ajif}So2n3UWng!lNv zlhH~*vsL?`qiCzqVeh22-3~PzeEDyw$6Hlfbz56?Yip%WSJg&PISEzBpw-s2w&D=H zHeI8x6~xrg*4E(Vre3?S$EI*wTb!)UY1O$M8kfDf%OUHw%erjMT{flLrgqy@PJ1)p zBAbAM!2YMu?6%7ZY|UI|0vBqqseN$R)eeLtj&vmlg~O&qiruEMlkgTe>>8(C?X;_0 z9GrF~2OJ9rlDZud!08Y>5!z)=yWHVucGwjY+0b$s+2xQrk?v49>`DR>Z?@Z&91x*# zmEEo&aht+!Yj)bCE()v6Wy9$!TvnwIUF5pqG-Ym^#BCG106Pvr;IK;_HYwK_(jKl2 zXph2WS90wK)J})S;ZRKiIn4>QcwuXCPQZm5L9VULdwDsy9Dfo{htlQHIvqNvqt!_w zT3V;m-r}-rIUs`D?E?-0XgN&TH3e$!EYxV*x6*qw*Rsz>eG?SDmYBF)?$-RyP zDdM!^h~E6ZoE*@MiIz+{sNJft*;H1$%8JknrOk#!boI}H(*>JVW3#p(5g`L5E$wStn$Y<7tq%0d*@+Zd-q<>e+jBVddI#w4*ArDmhVViH-*Le?w* z7?Y4Oi5QcZF^eoFp~WmP8wFMd*#xXb#F&LhM~GcqL}W7Xt&D_brYR_E;lP-YE;V$b zpv+_xF&3G{EH&exW*kw>SR|;{WE5H~Qj!8#BxbXi!WXxoW(qWt0EZS>%zTTvX#$7~ z%mhNSFEd(brrG!w3rU{<;=WB^90#JCBt${R3!IVfq`Y9w0In6iTzrJwvFJe&M|&FS zaT%u3Y_7*9V`;Loe3Pl($_f~U&sZ8+28leDX+VTS6Y{W(z+&R#xK>ugS`cYuNlxUc zzZE>@7Box++sLp88!Rl3fbqhcp9ShC!B@|1_ud8;E6-vj^>d&_rr_2hlk1-VX%BKv zJvA;fT5g?a{A7^hP5{mD0&!$+^n&3qaqgsrsEXmSYy)7n)Uz}X*;~s2Eorjg%Hx8w zJe!T*+0kTW6c%&|lgP?6n~dm(H@hY6ITN=Vos+_s!ok9IW`fV{n%tLYoFqb7pb=9b zCOSCL>n7)CNVUHDy}HJ!@a^weqLZfeqdhi+5Eh-1^Ed53-SZ#Nx z%|DxS3(n=_2TUN4!}&=F$SLs4DLD04gVQ+$XL1VsCjpzd0swaTQN5p94+iXzjo5%V_v62s5-y)sZ$4vqY!*{y*b@fqOw|;!` z#HurAR-QSt;@r9Qey7*?pILv_e}n&-b^d48p7C1^AdZx?{+rJDZS?m;xZ(6EWLtag z+`2PoR{Nb<>vv||H2wtE`}u9~^V@hUkg~z=%tivg4W~|XdCqJ+eR}jLV@ANi5zfJxDD>rOJl*z}UU^q-kyr+RPT)RDPPNOW zu{%_5x5nXA04_HfiFY_vPG^hVu5miGZg;E0p|U#^P8SCU89|=}Yyv6*r_$+EaA=+Y z@*_{nUn_1Id4!BQI(gJ4!mgek4RoxlTWxp9;l^VxEGa}lUf6pZE9skL zH-UU{%IGxQCgCRH$pSXJkk^p3YQ+Z%S%u54U@cA?Xs6S%!$oA~u4)S)rNOrxG%l<;BEv1Mhew8C>KHSpFn<$L#)UaQkz|?LeQT zBc61u6MdLv{=In^ou3N$yDbakn*3+XV&P=rJ{o9mlHMpN)7xyj)a*VM+XSpIIawA5s1 zvNB?`QD|dj9UVMjmdxOoL|Yd}5RI0Lcw(d&A8TEIk%MPW8ck%3{6M`SjU z6qv3mP41d?GfPY3hKEcn3YvK)Q=@NO;%)->_qL#9^m$Cl_O)Y5^ZpxfhukFY>uuk= zXZ6x0?;k$2VgJ5WB_#?!)F4k3IE6vU4eOs&$= z*aHVv967S)$l=vz&TMUMt;JsC0jc4~3Oxp96d8J)aN;Ka?tK&RMch@@10-z)di*%m8v$#nR&poPd z`aHO?t!V%}3scX9oI_1-0YeyyVTDFhqt!<2db3&3*QZ6dw3zA40PMwG6CsWi^kH>N z{>s&_mK4X13|r6}S*yTg<_xQw_xdgYUERk!|Ks>ZannG*@v~1~JLkV&$S-MZC}`2} zB;vA&@Uvj6J-b(ghMek$e{PaW#3jx03Wr18*(ubhYYYYv%Qp9P>(;LMB+_yRs^TCDVBt+Vm9$V=eqdlewY21NrGeX#>cuorM1eb-H(ei@@hbtbMBGy)1Nw z3OrxNA~l=Hw4I(F9exOPZ6zXUoKPAel0_mSmZo-e);QfFO>4%gwJ(*GQEnnnmPskN z&v*TL3P6;^j$_dIDabGM#JPM~a5O3)gDMQ1S)4wMN^aMLq5UNRH3XFt1?1Ea)j})D z_{`^Welc*Vadt){egjAiq%mmN?YW+G;5*Qt-T%_X z;~Up6Si1OwIkR7fNt}~?<9xt@fOGqm%{4jMQQNjImdh%;yY#(1owGiBH96_(;DBj# zgq=O>wZw!gGHJ#6zylHC=Z+lSq-d@zEWA-r5bks~gO%v$6&;iMTubg{;Ntq8)A_im zv7s@3`LfqE>LP_AQz(k>>Jn&M3hHZP?I0jyja-s06{qT23QUHoW?7a-RnRQWZr7Dt zjJ3L!La8`~-xyO}6>2iqXj%%J1WB^yY_o-@R24Px)46WP9h8hf$??liU{Y`qIxO{9 z0$g?S%D5|vy0n0(`%YeXBThD$lsJ*xKE;pv^pvsT{WuK z_|@y5D=Uj08Z=QlLs@b?NzGGk_ty*DNFAr}Uxb}QuJ=k?ecGK{XW$v7}X3u)#*paRAahJQhIzIg1rBf$&f}7T_ zows+-n)=#Y7*;#BF9%ia+q>r2(JkPhHXYyPZ0+wefSclCgS)%h5uZ2r&5ZQ$;-ZAd z9{qWEnE#c_C-&@K&f{g&)up&x3J?=zR{G%Yb1k`-fr~qpo9xb}dS3LhWv^&kigddC zCVmuat(MEv#G+)UtwG37XyipTHAM63BD9*Ein41UBb6dsEJ$im=Lni&TD4it@`Re2 zt4ejcKpd}W%@s+L@gv{Zl-SUi$oX`zuyCh+3JFRANpVv^Ndx{$K(9ZpgRj$jcX88t z0jbd-1lQmyb-7!tRtbFMwvK|5ioo>jqmBG1hl}s-lG_{tRZIG+wJ(>I#i7HatkEdI z#bhkn| z7)B%CY9%vH&D=yqIy8*%mNt9|pa^QP*<`dV9bD#iO+6x)ct_j>lV|SiHxC}zP*{-A z*idM}*o4l)Ag&RZe3PYxP;^O`Z+wYzQT1&Z! zQU+UrdpNDTB{lw!_}JfrluQ)&SD!|RZ(_HD2P@nl6du@+Lp}9iYp}D zS`Dg_h~s(nAzkh&vpKJxcSR_UY!XFw_cdr*GwT{68u>9QO|I1r=aI+pAk|57cPESp zZ2EkhzXFhJP6wXoz#j$Y<8Vq#6qWnY?&?xmS-Hiew6QH}b)`_4<8Y|(3u-nhY*wXO zQ?P3F%(BwN(GjcFDueOPy~DuW)|)r_>j!#1{UxT|{ub|v-qxwOJvWi5Ih?UWIBt?h zHu+dz1{@`kcQyd}loK=!CH-78{tPC3>M8ZyGS_+nb7Z?qa&pw?|kROwg9`@-cFMGyqy!xD%U;2GpTYYx*Z(d%=h(m1U) zv$FCEhzYx@tFKEW@l8$PthKmJpI%dUNhFOHNn;OAWq#$T~& zMll%+XR*okKrzGI{dZQtEU;Dx6_N+s)JWkPPfrAWi5h?uTsONNP>PI^amEgSlu4$_ zR{(f~GdT&l7z}*7y%`}*`AR@NC`-&wix?s0DJ0%G?a^B-a;HO+oOI>D z{?(^WZUs)B*wQSo$jiO4X7wi{!)5`$VCm9#ii@Ljb3@!+O8j~dbCkTtBr$zsxCyo% zr3P-(%M|2BTJ3yZL;TVuuW3{zc6%ek)bMz*?d@e&Yc0$ug)&ttOOVME6w2gQT~=dL zq}5twG?wxO(XF~{nLJ)1jc(*$uW!88s?U-t5`>Z%z9>rDmLrtJDbyLPz1G6k5PBjE zHTfwOjxO?zx%{=m0#%1kL59Pz>2|jeZZbDnZH)$VDPyZ*to01bHyD~+?q*GE&Z@Pq z6c@(~4VpnooRXvXUFRm+?TL-U5el?-lEpy=<39(&8lMNc97=U|!bl{K%c-eC)4wX{ z(P=%@Xu5-XXmMH(fO_x?@%3_((C&~G7vB(x^W1I~E+0q~Y|_BXDlLt-+ms+0lTpHN zDu|8_jE)L~an!)euC7jXI@Ppim`#$btkB5FGZ7JfVo@Q>$`y)=lHypmOVip~UtAQ! z+2I&EPqEKFLpZc)7_|66|pP~ zc!9~>U^4U6nj*O(x4pBn(^#$3m$O!M&<1U5nVI3WwU;(4Gi8dj*0usDQcG)ztU0H( zt;}rUA#OB*k2n&X`h3cF(Qvc>nn5lCb!T9V7>s0^5`3ke9*xZ=vDrmtrq=4HwmEBT z4ss)GcA3j9Q){!lV0NYO7W5Brh1KPy-roG{VsXt>9d~5~y_}b~qFWsp*8ouL|%{M@J)g z4aI4NNB|x|;l4pQ<@7n=3f~DgLEreSRbaJ=$W%9T6U&OgRxlSG4jhuq%!Dxo4uVz1 zkcb?Y0|W`6eU!Y>KBrUZa)H`7gM!;jBX+wSzZ)PX?so%LD4Bm~wMo#QKG%|a6O@nW zxDOWxQ*b}pPN%%KHfj0Nch$-&8!NVuHBZQDDh$)y(J8UoR2H_`U=%UvJ?KUzvC%AL zScTCfHJagZh^!8&3GBnd7Q;`s91b$epv&U-M}*$VEi7|8c<;TBv;HbUSetP7#DvTS zs|^fQ-_cnsk!H)Ab0xAgg*ru{PL{}0#ga^=vZPs&-zbP$w&Hn?n=H^4ZtMou$4#=k zOMrqyaYF`LisnH4(Q+6V!vutK^h~%oj%-7ajQl>UPpy^n~$qL0oIjRwBeS z@t!ck$!)lYfp$`rpxi|LJJO-?6J1l2xN6mV+Lmg%m=u|9Os;_3Xv8JLEypjLh%Cfm z0X4&ol~@>DH<{T&ey$l-Vl?s1sEUkm6Z4a@4nGfWKmpTSK}KHy(^% zKG;p=<*`?<9z1(?Ye3+R;ETHgFKiAtzv*1SmJ1hl1qSZEaA9}w#U1k(yii@0Ix=kG z#-ya&2*%9{?-I}}jOHd2D>AcUgNe`DWDch?KmW#CuRVUjfA8tz>;2DcIeu!}$x}Pd zo!aJqY}0APPi{MXa);lkors(`xyA47j+3Xh_@CZ!_VkWphu1&$=ug&e_{`O#v#<(= zfj!mgbZA^o4Qwk|h)$Qn;gZ9=AQ7j+?x62-a<69+D4h-zX?Ax>GctpMF6`~;)`3%C zaJb!Cr&Hr{EA0+qdpg~6w9^KY&DqRBfl6Sz(Hb1E;~eTPx7y``+Y}rWw5O{}V{pZUf8$-ZvS=bVbLyx{Ro(v+;2k;^Twj z#B|{FRKzlHCxtdg zZP3L{M~|-S?$YCz64qRoTW_%_7^}!)Z7^Hw7+aGWMOeAnDk5Mc_)R6lI2H**7NHbd zEzLGoYPa()UfOu{$f};6R?e8^RyUh^5$>3qIM=zyOb_B zT{8f`PIN7SY1~D)TrF-_3nC6|601RFvx20iEFgOmaGAT@t#)qRWSdpl*@6BkV~8dD zXS?NJ1cvLI`%Mr5+^O-z%~0&Wr* zOid<|A~u>uM&GkJlfYsUSXr2F)fa*{967SKr@I~Lu(`V3?M5S7$TzbMW|n7S8d1=~ z$~w(WMpj_5hzv#nag0DrI4@EUSq|4~tqUUctnTe;BU9eVdqSUAVO-%mwVS-tCAj68 z5TUcTO%u)+Of~o~unx#usSMeq>63?$XbQEz$fi|HCt^%c8!@c@mvNKP)aY_I+iYTo zLk6P>#ALHetybwRD>P5zFU6Ggyl(>h0=S%H?G*5i&8kA&%EH~?mahLCY&MnKrA0Qg zNyb>{O-5^@6)-j42+pOjj)@*O^+koM~dL)#roOgPVMIliSs1HaEl6 z!V!%Y9@vc(G)p>6jV7yru}RFZKgduF=!sh?+bAXrOj~P%f;JpEyt=2SjaAiXy7}n@~$p5tO_U{F)u6v6C>o-B}c(Zt$n&Vy6D z+$6GDVN|x8jK~Z(kQiU6#|S26ltws7&~Z{BfRn=IY5+aKXkslKHwAAza(E4~zsON; zIsFOTDK~K=VKP{2C=ZJXhL88L8Y}APs0SHYZAfnbJrUChE#ux-L}<55+S_Z9PPEia zmgxeJ2XX8*nHtIJf`qLma}%Yfsco3RH;J2IF-au3W#v)%`JuVFA=x?Cb81I^`~ZZ6M#du+&*CwPcbSezeRDR)*i*qXsuET`+rOXuxRi0iUjh`g9X^lcJ}q z(`b+rUSl~hVxy@UglKiBtPX|Mu4JubA}gon4OSN1BxD)B)m9T6yy?i{bv@mkFbTP- zf1g+IJLD#qc~ZtAbvZR|cMF~9>2j%1m)$N03mObfPFFLrfXMQ4+*^X&`#~USx)d*Y zBH)z6uK_@3G!Z@^VR7#}y#QKF+}#OK!kXL+%1Y4rZwxot9n!|8^zA!lA3wgv&ugHu)XrwMdP29b;AI=SSTC!2g>)@8$jhoz=|mvP-+W6oi!+ zfziY#b5m@}_71U9$!lmRsjn}ot1W73D%GfA9&+=3OysLYzVW7`M<>RcY>F;-2V+sg zJ~Eh_V1HTd%^e+brHWtQP*}&yudC1J3re)wdX^E}tOB#C9u6IRLyntZH?8aKHZT@B z$ADiSH@RIc1qCsY5&ls(&P7D{H8$pymnGKMWt5b}fTZY?IDmUa@a7vmpdJ`mPG@sz zX>>%y2_Q1^B%hx}9#?U1%yBLr8Biyzbj$N^A3aTOhEM0eG28?vx1k|*-u#!cvai(E zCRJ4>)YK$ZRsiXhrIU$o8dR)0bfikgcpF-O$n8(`7W9RE${z zSj-CUS98i;{u)8Xn^=>SjJsQ8tWj(;i+j5XH!Yd>$>?xTr%hWZt~`;NRO9Tb?7$DZ zfoD=T7^OmkSlB5RnG`Bl`;N2w8?_B)V!TKS@~_{2|3A%{Kcj!3oi&Rbtfb40Qy_!9 z7c*OW)plm;RH8L9&b{(U2w`&qy}_y zGDlh_lhu`$=B8)HXJsd3WW;4;MAuYjwd)&fR*}Wrz`#Z!+*BQWal>7*o5cP7o$J@l zS+?|plP9(vJ+i5+EV-~CHaaR`$M!|JIT6kBa=T55vvP22VB^?UtK8*M(+KD`J^kvg zor|7+>K8|kuB)s}B2&w(&2%O!;@~5eCC}7hlr=Txq@`Wy?QI2rbIeP!2ZL&_S+@KS->lCbIxBn@=Mq;+9tu|>vLFoMt z{PUazuMG?tSc}+Um2`KhxVN2g7I3&=5-QWvVno9FcD=T&q);vs>9oyxIf-?(xmH#I zeIyUp2sc&T!cErZE?2vuQ*L3TW=3QoZvUKfugx4G{kTDvJbax zUg&>jcYmM3&?&C0NNH-yx7*e2dO=-XR-3NLW>c9>(zdpy;-a`GpS-VGUfHH=M0YV6 zCCGsM=mDLbLba+I^wieYkd$=sqmQ10|0opZag+DC_gA=SnH=#`o&Uyglfxmct4mtG z{0*hDgnrr&7A2R5+=*#?P569A|Fig$*Wb)d%IofKnUr`3^?xPMSyas?@?@}?a#LTo zIxgzm(mC&YMtckvMX{jdVqQkJN_C^8SZTA@Ds?g0C8|zF(Qb*$DX*5c?)AGMP^m07 z@}pi*5dORS|9STOnf=2?)Ni-JZc@TKVOg2MAZA&O(Wt(BIlyA>)azQ$2Lu!s7MKkB zw3L|a%ow|^1=>fsiLnxH^7(X>o6II9!^%5NO{`63G)pgEK4UR==-b-WDs79ZwNu}b zospcGe#7ljbDy3Svt%&3Cio&aZgp=D84Ldt*OT0lJK-j>M#`Kwj~w2dn-e1uRoHD> zf4@CJ=MQh(Fn`sGPe1)+MthqmKJF4sDi~Ic4f%-)mzOPlzgb>|-y;0@;KxcTDSPeJ zKhhs1n^l#Xa_#uBEys>-%FVfvpBH`l)VAIp{m~=quU(YY<*3X~&CSy@rS=dc-m$MawHS@Jc zE#_v}hbm?5+iyL+Ztd)i8|HoX>8t6fA#2xs8Xp(Db<4ubmyf*u`XgFxZGBz3UeDvs z#P`GXzsYX;O1ddh7R;hD7?mN{gY-I$psC@=p#$Ne*P3O* z)Z{2|irdw8D>tn>dKA7`8`^2J$>5ZAcEX_(GdB2iVuMM1{rWjwtGcnFk>4b$t*&q4 zHKruSW~Ik;yIQS`i~$vrq4&w$#GUUgr%!RG+|<|CF?Y@z@ZFjk3uF@5O`7-Ld*1K# zt_|zwtyuPPQ9)usUi?E3{vdP02g{CP9S$1FYFt+x^rK=he= zJn3uLy@_dV`fmqA>FLXX6v6esJz$kvt>W%()vf81@9)g1%bqQXR{Lv1mO{{%Nl-7aXQ++-0LEsd;QVl<0mW3Onna+}R;Hg}qgom!0|J~p(h zB(ZL6peMIW%d5|R;raVnrrB;&$z|nlzx8Bh zMp$l6WMIJF%8HbY8|EH8vf=RI^)b#l?=t*l@YH|cQEY&MD8)k2;Ou%b>A&&-ml zgu?Q?{FKbBxa5=@si`rkDN%X3@hWAF)6r})G(lMru`oM36y^-e z$_)nLj_r%DUO5Ir;nnAWq~x-yz;g%S+#NZzskkWN!ukCdFCHA|Z|`VtGMmIshe{|c zSh?~8Zb=%YUf&oVe)`Dawa1TbNJt3E%m~@DdpUgC4eRIB)n=aY+fh^$8x?g{t*+*# zCj74)Z$h4Fe2tiV{l5%|CfpYP{bS*bMQAk(Sn>f>F|NS0fM;bS(*RLa`)w9u@~NO)~h zX|YI{=X5HKMi2^&Ns(U9tFKR|GofrYd3$?9dis^Lw95tqU#qQc;N@CbRb6eCl~qV3 zWg=lwWo0rb?0>J_G>xwpq-TEx{K@5I$oex@wz<2j^=9Jj=i_{BU@Ux_x!z`}BQNN~ z7~$S9b@%FS#9Uf5f8OxWu)$_174fzQUx}*|W>hz&mQi7YQ`?eFCyGDXYN~r1FY2~cCq3vx13?gvV~?#qlL`p78*=K)~c|u3ad?H zwvcsHSgRb3FV4MxoK^0PX~AXr(OXLw{X)JTyE^T1>h8iLqR{ifDE82IG<29s&8($ z8f---H@UQM*{rP0ZUb=&Sw_k*IAIv85{4B!oG9LCHaEb`BX*`s)8*FSH_F0DoG!J& zC~~>fCbJmi?QkmX4h6%KcXPZSxg~%NdCUAJ@?H;tm;-GpZ9mDtl@*y7xbbA~UB#s1 za>PW&HOR25-65)}ja$9u?Pf)x!%61E<8lELIj8Y;fnNVFiz&Bn638y})$Se*d1sY- za}}Gn=J}d|_A?e9!|+TNj+@ADu*luh8Wj_?bjfE!!)^nk5o?-)W3Gp$#zv(?$D~9@ zrbI=j#l)mVL?(sZNQsS3Pre>|L)ES_FwGWLTwEIUyZisYS+i#jkFfBnY>d=R-r}I+ zO#*{aV7DteI`K0pH=E^Tx|31LvI?>&n2D}SNoGV_EKRJHcRpzIvEysIx>``sZf_>s zWG0iVjpjy!slo1$p&kn(GvX>)#hv6MNn8)Nkp9m=1;~{8Mu(&6LeSjL(EYSD5@{#5cIel_J@Mtfii{@W^SH6(+OF2zmm!u=N(E zmSyU=8Tukvo8)JT(1*~3kVd9LV1fa8E4c4*-=rQRBO!x`T-(6+1YCdR_DT$l6hOp8 zR<5}#z=6;h?z&CBGCT`YZ?!kp)yJ(^Ia8r5wA#oU*u-ukWBFXpY5Y%s{>V+~R6ba& zLNhDq?o%7gjfi)eU?89)k%dI=7DzvDG_#Ec3y*t&R$#OUd-`(fD(t*pGut>sp;BDw~qBfqt{ zq})rgHvx-@d~~`Iu&@nAbDiBOJbz*9;Ui0X`;=sX6v7zj|5Rms_zK*_5zQ^2`F-j) ziJQp5aM$VakPSv@J$?sJ%4Cs)n2cann3UvI?>eNjWw$dmHHjYD z3z)$GJtE}=IPENP+WA&<6TlL}CNFlAUIi}qa@pO&q!!-7O-`2(+_Z4fODc6S%L-wx z!`?)QJ35Vf5M`w99W@8pvc^byKruzaJb-fH8+>JL1>_3+^p{r#C^xoVaWRMusHA=)nG<`ZrVNv33lBM z6E=~V;~+~TYk_arNY-Jn@L7ORQlrh>Kw%}GBiVbiRd*4DB0qP12sb%gg4(*+lc!ee z+A8f1SdrYj&|aTzN+r{{Cjh<0uSj=~3g!S^R|7gWCC}FkuETI<v;$S*>EDkv}ld zek1bC@@4OJb!pYADy5=Aqpnga%Qc!xwWhSCwOFIgS7~z9EqRClh|suBUtCah>486d zZ{C8Z2Zt4Arqu}2Z2U^k3NjGK%+y?}}s*P|6SeC40&obn@0UXHEcie&m5_p0(o8scdgGY~S z;O2$@sr9hFGB-^CR6;N*kc1U3m}5cqeww` zl)O^AXZNyS{QMth&3a{M$OtXN>8MmiyoUI?`dA(>o&fQ>*v7_0L~a9KLS0>aV`D0h zmvZXlx?{)Ibh*_mBZW_=QdaQlGwNzndG$aFkC$9mo6y)uA`?jRq5+jB*3~Bn1nH>i z#0fNeWmmV#YLmbdoO1dc$aVH{)0BN*0H`|58EV%MTA7NQ_6~BA{AP;;7L$>4=nRaU zaFcgbNNO=RGbSZ~2v`H$WMmsSSDy|r-4;_uorFd*%p`?_JsD>5T4po(dOd39V1heo zK`2LiCMfJK0OxL!GbWrD!pT=dY%zf-CB5CPE{ED_Q#q`vE~n0AYjN7JIgS4rI5=>x zPfdl>LEiPHuLP6P8SdrViAQyxyYF8k$oPhovB*tEDa$BLMtQfpy`(7lx4-$}%vYa$ z_UYfh@Z5vXKl}TaUwRm9_55>xcG27oU3)A@KY&kNfc4(~lwL!TW!;e$DcM zUYEma(yE15E*2oJnO&Vod3o%r`M59|Bbi9CV#(8{%5uXoZY@-+x+tZ zySv?58`IpTZMbsjDEVB1-}ZC<+s~fadd`2#nbRBm&us8Nx7PpMYX5Vqrr>PAnloot z0o!(b7t0 zc#sT`-+iMAz`5hRZeb)1g%~SBG3Xef^r>mCGl>LjA8^ zIS~?a`s$VAp&_TPT|E(U{ZwekX+*AGJ#qcoNo-Oe@$%(k5#eX^^I~jPHPE7|&CL!; zO9{%(ypof36=81nwXBTG0OGerer`xc+C^l}Outf7mE7f2k^z!85z{$KHU8| z5EZ^HH&OncasxmF)Fmd%baK=~84Bt*1spMvY)y=Jl!us3AO-T!fs8aYfqlquwMk+% z%B{v`)+A%ekW-VHtpgC@>i<$8^u(Y-@(L1h)F(!rI8L0}es0&@9(6*i=w9>Otp-a=!o5hUMC^`tW|Dfq%Mb&L|B>KD!(0MPP@!z6}cS9AYm;c6v2-x zV-lehYY{u`a)%ASwIY{O=CFxuR-w%%Ca{ZacHtzzN)p-aa4JFi^pli0DV!sI20qXA ze}Kd zq~hX8LEit$J{GKJh6#@!MKaD{wUD1ia1ABv zsem7V-b)^K^I4STMskVyZz84%)ZYpXC4C;sg$#|1?>QKmeh4&8fZHU@OBkQD-y|mA zue@V!!pU=2hn&B`z+vffX>*_503KMM4J^4N=u_!7Aee+wqU(kA_K)Z!7L~K^R-3~S+`b880un7TjE?`M3nM`1}%S|Q`XEDj(DgOx{ z`4(>SSt2*N32aU5Slm1t;!Q>q&tR-;(^qtKR_gU-ZThnI_HuoDxvs4gaf6|{qoV?w z`u4K+jxvL>vZJ%SOm>OI4HAZ7?hrUeTR$}O=K%}F+yb}>FL@5eiN@r(fhoMH-UeVD}X);u`>xwNn zqQ0!Nqe|CS*=cNO>!@w-tnFy8H0Vp2juKOQaYsj)zO&-)p}m8md=khtnZV@q&*z-R ze>e15kNydK@ewEO>ZsIrRDEewPV~Aj4|<^xLD{PIc4#YsUSHMOS)*@< z){~B{?!EwEh3*Im-yRyVJtTbFWLyv13WP=OxE6|VXGr*t>tWl&BX@^}?1+rm6&AMT zdgz9*$SvVFwuOdm3lG~F8MZU@+Lnm0t>NL@FJIkqEqwpA$dlJ2jz@&=jtJcn8?`Gc zV*8EoZBgOdBg3{uNA8LW-w_qD(~IyOH?WB?Vs~ih?i)7_hKKHsjof$R`nK5cT~Q&s zVj~aSh&UJ?e(-w8zKDnek)gZdBX-4H+YohqLl~MGvE%LmC(dE&_4yo-;Y;S6#$7`M zI>T4O_9?gfE&zv^a!|l`+$np%YJ0YaL~Q+PApH~S4D1RC+Z__NX9BxJ!*?V7df2wG z$nBw#Td#(02nk1i7{+TK+NeCDjDUiZ2jN;YRli=x8-ks zvH3ecN8)D0>E^e8vFY2t+Wf8i)_><0tN-CQYyajai~jbfi@*PyHQ)L9%5UGd_FKPP z|9^hH{%?M>?(crJ;@dx-^P`7XDLOrj)#J4G+)Z?In38x~AY0cozESv+clIyGm+l)j z_g8_-X>)!RAU}>m&$`!X?eoFG_ShM+3v6I#9X8h1rq#9SH2OAadz+wL5AY|@1Q?Ct z`ns%DD?iq@@cMc?4V_Z*(Hb&w3{>M|rJF4D=efy5zAgu!uE}cWC#9U(zGI%pGcZ0j zIzB$^@eGZ7`aPcBaZe9IU~C-W(D>M}XMB8o)C2GvMHUm=-`hVnIyN@u8OQEnkICq$ zt!|WvC8J}gVQ6T4c!*T$dHwx;|Ma7ezklEI@7}licdwrLf4|@QH$PqRyEoWUkuffP)Z+n0 zy1K00-4>Ti=XSNY-5L&R4l1C#TO*MaE?M$MOG|ZcFL`0uVj+(mZ)ZCFId0-6bRa_B zLWbRBa|q%SPHx*i+vDj1lMIi#S-Y;?AT=^_i%ns)NIT7vc7tSi)H&|y1LKU3j|`6t zH#Rj64E7BS_70B@jCw|g$H#gHhFGghB5Q8s*N=F5M?5|Kp56hEr)S(V^TUIG|APApqZ`}v|%;ksWuz2|TLYr*$_wc;P|TlU?bF8lkfk0=|BA%bhi52KU?;XzghM7 zKb`kaKmF{tkFBt{$yLO4ylX)9xM9=yUksv$cMVhe&leo)&UzY1<*N#g1w({l@^ME- zMxnSvqvO!`erUbj)!}sO>G#SBlaQ|>k;x5a^6qq#%`U3vB`se3szy`RKcHo~@8*7) zcUC5IlNWRX*u=bvCWlj;oN{*ij``!nL>lNFG}Jd{saqQK?GlBuPSaA?(ppu^OLMyP z9?u{y0j#9{{s94BFwoa$F`I1;yWQ=w*lh}pTB%kFg@Q(20~mMQGcYvXhf{QqdtUqa z_}~4^<+L`*D|NQu$ezox5e!uc3k8S$#BOCwacPqa4(|P~$yX8N5 zY$NdZKb!LpznK3|zg+tBCwBhVAGdt#U*0=@wSNEk(trNt?Em=vitqkx;otpi;lDn( z;-^n-`u7J`eD^;;y6^EN9Zqs}C*7*Mfm?rErt!ZGQ*QUyjxT?#$vM9y?m$qA9uBNT zh-n;d5my_Wqp|Uk@o~64Q2Bm`qtoGNGm!=PvMfH`r`4t5s?=Hp20$t&3m2 z{B4byCfwwaO<`OlqrYC+smq>`Ugz|{nl$&{rh^` z`v+BgL7K_j41OJl`!?zs8XRqE6^O=7Xf8~LM^YP99_2}~N{q&>tM{>8EEZKOx==J$Q|M0U< zfA++hWqXp>9?AUU8@vARFF&0*``nge#TyTm{^E&s+s~$)j3}P7`Rb~J>HqQIivM_U z`I6l+i+9C-xFX`8e>wlhkId=lCgeXY(=si0BpfACx&m1t0;VEc_{AS|IgL(xo5?6< z7{J9xbE-tI2D&C#mU8yU7< zz>iIe&&kWk&dSJ6%`M0*N{o$FsHDA~z8;U~)sIho>z_WDz4H3WOI5#qY}xv~N!yNO z{r!Kul~dKX`9RjE%dVciE_&?co%j85c~GSETnPVsgy{88PxxP{pR@ehs;%jtEWWn= zSW;G%>C@#G_xhDD-IB0uTWn~G{CIFlTo&`m;>-W?^S9VuYBx>Gv`ot#$W3k=1#wz!y}{7Tu&v#_M!Tz3tFNzX z$m#2K>f7`!+E&J9E3c`JOHL>($xly9Nl(noNXk02|3Gej){tiy+%)6EeBcO*BtiTp>bC;T@?xvAT2b~`(4R!wb9_8YG~|99W{)_1=BtzZ7)|6RIxoP0Fb zC9kbbUb5&TwL;L}Ycd+hBHi5kH=lRw?v$H6o`I3k-tN8*v8>c=Y2`Oozy0Qm6=mt2 z9elC4*kn=-4A=(-?E^!0SC_G>y0Ev$tyZZtE!t+4Dmgv9LC8-`j*pFwx*B}Fx~%R- zctl!8>ab_D&*ORN-Gje)XoLUNri1>4JC3FwK35bN+VK2ayV6V8=il7*@ArKWk)mF` zBkF3b^!1OAyglngL2dVjJ+a}*(jWci!{0x(@rAdJ96eur;B4-s!<=2BFW&YP{ z_xmTk^xnozd*feuXaCQC{}J0oJmzVcmT9>oxyemrW85<~N{6CGJmUlK>0FLBmrI?J za&g(xkCrd}Xz9{-mM?$%(4kdEW24h8tgDY-w(R{Dbz^^jhrz%n?+kvGvGA$*95>Ay z9qS(V^!E)K%PNz5dQDwjoiQ=z-EK{Hx2Co>-OB2~pkrj{eyD$-uehkl%Ca5p?fUk1 zfmj@NZgDF(9}Kc(@o2?+_6mM zrg87qh-a+d?KF0GwOef>mAY7^tY~SeQL2iyt))s;VTYm0;pWxWM=o9ZhFVqC-`{F7 zljS|X%=%4VjhjZt`$oqdwY*$)OH*5$P@}1CZLQI0DtWxz?k)=&I!;EM$NGCm%1UcX zi_2g)X+| zyzk$)_&Y!P?BSV*pLq8~TJ6ZXqlKTYkN(4}`~Lptvw!mV##tK@=4?v-Xm!l@f4S)X zm-l|QG2x@NN&j;H+K1mf_{cklzxBgezkcq}^B-US?oSrHz2xd=>u*5e zv8>%aJr+JK({jgh3pY*3m}eZ;#Q=P|E_a)SZL~R>oUZ2X9yM95#U*feODt@itGm9T zDSE}qx76y&zCMlF(!hGxmg7(1oIB?x(8$<$|Cp!CYS$W!%~qRAuO~0>kr$mA)$m|9 znHexXIyUAR8}W4L92I3XLV=*9w78(CFeEHIAn?Mq>(}Dr;;&u~3GfeEFmLghvjO0X z0gva6_ji2n-#+;6k5~WQ&$fN%zczmFzAfMS;fnA4Wc98f&A&gq>;L?C*|+|4*>``j z4k_RI(aP`qWc{~)jQECc|JVAz{rQ$}|77$3`LA`~`T6p1|9sj1`N`V9`RUeg{cy|Q z|9tm%e!Ss3KU(v5|F!=A{9y5qAKjpLd*B&Q%d||(9m!2@BL8vW*w`rHCeNUi)oWXL z&B`35Ivci9v!YPllHaV%Y*u8eTXHqJjPj~0D_6bQ(o)&mr!txASX-l+eC6b8<0dlR zG&(jo=IJB0&iKICXphaR9UZZfIho@$veLBl ztnl!tq@*NXeSKa|L2PuwmCGS*`c86Y9?wU!_x#{zAO7gKOMddux_|%e(w{uM=7$d~ z`H%Y-K0IURkN&Xm2M^5u@k5J$^oK?NasPtWJ% z?Xv&){n8&kyx<29&imKjE&S1gYkqM5x*r0+Tk(V6F8S$0tN!)APw#(r@w87jEz|NB z$SvG7HZ~5BS3tP&rsBf%;Go0jFKiDA-X0vhKQM4l@WtK17k6H`uoEd4f;R?V+&X8@ zj8<)9U!UG!0I`6BZp%D(&P{`(qa$Nv!WH<^Gcq`AF?Ea%^?1exJ!3chNr@mFEQ79D(MTjh`8mz}#-9ROS{3%pix;d)8HmF%lgSzTzO_bN}zv`ouam7ClI;fM(` zHaao@ZYs=A4G%pR9qmsL6%-wHF*+(RIvObf(a~q4V@^dzo?N)#{ni#~Uys>nkg<%y zLKfo&6HTF=JLIMXV`Ff?;Ik3Wj!gd^9`0;!@r?F*#(OYpX?=x$TQ;U8uIiZKI-X0=21`Yn8!Wj>EX(vp1xu7Ud-Sq!7w+W zby}unTJA`0auY{PToUCb&!EMmwOh5^B6bp%QL&7MWt+(-p;$Q*-CZ)FD0|(Sxh-m8 zPq)ErlCw;+k$i6N>*S`Pkx_VUePiP=jz-2uhfRjo(P5Xz(>*rg_Kd-3LX*k6Hlw4X zb#?V7lW}Oce|V&y*nVTMvphDNqpq&Dv9SRsHp+3+$QYT)H3lne6eT?(kt8W8B{?}o zBoYx?CNB!ZQbT>He2m2Dq*O8ijFcE1$6jI(4PnFM86NW(EjC_b6GucN@Ic8dbz;z= zj%k-}TBhZW1qyWwH*uN>5TDNJFm!iy*laSJP0D>bL1VKubDJb|cS#x=lUFSNNUdz@ z>j5{(7>mqk1j&4T+(Z~)ba33`)_02Z?ahV`jat=cGRoT98{6B3LxXP6C{6;wK>rxO zNixts(BI!PFwi|VIy^iu-t8K)Ssl&I@_Js)IJjkuP!a;r4|l2_fl%y!_RJaoGiT48 zJr{6JCYOzZl>o3a;Y65hWD^m(IWi7o$a{srN;vk=*m!Gudr@f-wnnf;tR*C)U4-T6 zHJ+AfnU=3EH@S&!!Cru^z*!f4T`rT;(Mp$lGn>WarC;tXUoLELxEpKgqL(arORcKy z?{6pTos-E;w`HC?<)-m*5Yy1$sG*`ZLD$Cb?38tOiaI(Q^zD^(^(l6{9vnj0Y0T5p z8l&r}z)~r;BBx2<49~|iJ?PjcuL?#{u`;3nuj=gQ|?Wn+DVdW}?z02O(p@k2J zuvslPF-G!+AF-V1MV*#unU*^c!b{{2n#$=db!&)sGSb`aHai_!3)5&JpX?@|e&FIf z3)?{F5Y*O3ELl2Jqp2Dg(305$49{q;1Gh}!oIBdqf5Fa0R+V50z zbF;D2k{F*77izTTE6_9mX`Yd{x*||d~k$* zd}Rvf{6*X}I@UWl+R-4$((9X3lH!sRV$)NiWU@k;JfC3{?k;0@58K_#n3(3ehWy?> zC(D}J^%@&%Zmbn1M5h+z7iMRtXJjR&W+Vh(xhN2e#<^i4GKfAteEQ^(Gk(W$wm}yH zS1w;skXty^Kl<6nb2o3;zJ1HCmCM&8C8Rw5=;Ik_Y3ZpcM-LrMip`w+$>Ob>wl0`I z=kk@nb?cV~U-B;~%v!f@ZE(<)^MTiLvPvT(;_B-fV3ffjq}O;_re#{by4>U@j+IEv zJBPqC=(KlsyE{ND1Y}K1#l&Y+$WlvoXHz{dVa4(fH0p-F-gc8o#Ih1%TYZjm{!(rl z9yJLi1@h*az`)}tPwYD%c(|f6p;=jCwW_UFy~AN~I+>2n=9=2Vp6)K4woRvPH5<*9 z;j^dD;G9Jw>7s>;0s{jFhK7Ij zo8R8JaU(S3`u1(x6B80Yc>lw$u5PQB(yJZ ztJ$=9)0#EwN=vKY%Gqtswl+O?EvIE#rsa<1CO44{uRcL}2{+lT?Ok4OB46#EG(P|- ze7mcmju*Xb**j_#S(Ddf1YwE3%y)gi5;u|Oh5Z92zA(S1SKnz6Yg_pponog;C6Sdd zta^CZJv=lpG|=DMYpY{GMB_*Ze z9Jw)ZoZ)Ejxu8RPjy22ML=yGe@4Opu{#@5U&pRK#TTxw7TVD|w85SKKy?Dto6j8Ud zel~kf@WqRpH*c=4u1-r!D=I2lym)aXC+pX*KX~w9WMrgLsVpcc;Pd&oiX$U9#I#Jy zwA`5xULt?qO(NrD5SQa7TSu3xom*@d)B%10D6tT3a=7d28X}f2e@mmT@9#C5j8Zc9 zl6ZfgC!fE-Zt{4B`ua`PHR+61VRy9H?X9d;ZF8uqYSPRWHAi0Kqr=0)Lp>$MIeMMW zVr1HNMukj$BO*#7kt8IfMG};)s2%!buzIm@a*}Mr~EHn zy|!iB#^|_+fzke$#Mm?benCOO`S~T~WwnP7oq{#g(P`YeZJXp$hL`{VxYbESK~z{Q z4hjl7ckbMU3l~Hp(V;_!q*5uE=){Q=b#-5^8FZ($#Gm9~&U;9~&DU>aD6QDk;iS$YoNoT&-x$Ov}y9 zD#*&rjgE@Gcqu3^KWod@b&HqGCG(uP=lf(dd~94Mmu6(ASJhYO4Qh=}Is#X=%bA&# zo0(DA?H=!Pj>#mtkzvo^;80UjBN#^}lVxUR*3{IX5^$f}?Y7x$;4Ey`*VkucWGEC0 zYB6!sF{Wi&rsdA$Ugsv5MX)}4U2eV8+2(ZW+uEc~SBJyV>UOt}kN1p?f}2S5$47@4 zb4O!CjabAlDJsg&%n7{~?(Y|H?P^GTeB70*!GY)f7A>9~5_TCC!py=+1H&UDqvOM5 zt|s}8%Me+On7ri-((;UO)4In-Q8PmF-#A&W7*S#kfqlqqFphwz&`s_!=gm06X_=O3 zxg#NpP5!)_MD87KTHqNU;$~NpuRo2Axjmk4lc{BNw2QnzHxBfX$8BgWIRnz@zFt?C z+oo2@MM8d6c~xq1dVXHMOfIRcF3!kGNKB5h*-hZ4(Gi$Vq{JxP!IA#akzVe}-PrgD zc!)3-F|A-Mc}B*@2gb>APhh}7(irlXfXo5&aTBE~kR3v>5_kDXIzk$`t3r63fyZ(p}Oi-5r7`-CfcpC89p({{24>uXwrVI&;m;H)hTh ziHw4%qZtmR4&P@#%F>#;g#8}HMUgjL&}18{C1qx-ZS$OCrA@wK{)uswacTu^o3s>P z$C|up)Hc61;uMESn+OMF*PgY6g`fuiKpT@EB_HIn$`j~Nu!X=Ww>MM-3cAFL}reNy|V(_`*bPRq|%G|9X{Tk=++vE z1^x9mH)r&MVH3@Og$kr`1e1=R;aA+j`k<_=tb!Q65E;xj_Dy4z+Eow!J$hVuFDysq zt8{sd+E9+o_4R`C2wy#2?tS?v`k2J5C@wC(va%9S_tNWZrFkNqm)X$G?Zx$jLJy>2 z*|E{)d#TW@C8Nsg*VFdRf`l-z6Sk9tsthO_LjB{-M?AqWXLqXZRFw^Rk^myp9Uwe) zNj+(1-m~4)mydN1s#-aY;m(vY26X!Qlu)eawWNNG8rcmhf`$k+bI|1i!>g%<#q*9c zUS4l#ek~i&C8&in6)O!nqy6an%P+Wp#z7e5*|xvy_B)4s!?F??LHzxxMBFBQ)N*87 zVT}1Da=T&sw5vKSh8$@GB&2GH8wU@RmDFl0}BhLsd_UrEX{5e@os*i1-bSy{ABN6|T)bCRPTJSGklP<6_KITfcOV2WJ zG^?vGT{gO|uidpeUAJKwfZ^G&Y_?FciC)XL*+4@qw&F*A5Piggt>74;18!$uz>jaa z=rlzKGc%f6NVz?kDp$B5O6nH7C`J>0cI4Z^|7Iz?ymp3YsK<~3W(pZTutJD+0|x|b zM#z-3Ae`w$1dw{aj$w0oPrf2iYmIB59jaqKTZO1~!S?Aa={^r({DCS4h&ebR=X zt+17T%^ZQKp{1(d@9O%-bDmEH5u#rk0Dw zx_wxsTZh?PXz)qX_vTQ;3caFGxCzURJ|RLPve?{~{t%CxDT5+)6!;q+K3i_YGQ!4D zpr4D9xO~o7{`7FQyA)Ol7u#o(gF}-3hoR*1zvO#={4W%LVy7mOCkeYttxJC>a}SjW z&t5ZYN?lTBaqs;kibhA@8{3$|`*>6ezlIV5KR-~J{no0i-t8&59)J%I%4p83AgQMRLc^u^kC%zb#vtJ-E4;_`)#RmSQX>Xup zH6f*(D_-Fq6uGu$^k4xuWB=LLhr)@qULabX_enXuD6j-d7>|_T?RnVQ=>E`8{rmpH z#l=NYW?Xd)lN_pxm>{$_Y_Pys;(qli2za4Tp$9ixzNeQd>s`JcuC9Eax7k-)oMczi zxD7FnK}o|yLj_!CpeIGOi)6C*0*nBOEm{$C4_tj zvV{8=w%;TfSpbEtwETC>OovPNf+G0t+)S3!Ypr>Yw{(+(#p{A@u*7d-a!QPx)68k_ zfE9${M))}0et#aDagV49opP-?or0^XYRXoRy)Xtc+K$9>vWk$QJVu zeE~lURaj1vM%WRBq#tXD10mV}7FY>N4hlu@&sb@7VaSS}4NYiqUKe*I!4ssVyTQRF zGGW=7+k$~+rl*685xH*QIej=BA-r`c%5j=|P-@rywtcbv%kQmx2k6S&ra3$|`PMgz zZWwz7XBB5lQ`($4z+dK#OK(@*=*(`*-TjO1fR3~lCS%3n%gB(+BpV+`PlSJQn19c( zrmm}W;!X8v$IxtRhvCnj7Z=mXh|TNIW+cmIrE#u3o1z>-1csOk5K^)sR5FYx>61RF z>w+{%VPRptoEiJ{yYAoTo%PUyr772?x68}Rqw#bh$4EJ;zYmsHm~RVUr$~O;;2NFh z$8wW=Rvumgkyb%t+*0S zxQd=0hYOkrV7e^@8964RuhBz8a;~#Lu{HZ`)a^%RpMdo2 z!ajm>P;&8^n8{XXak?@rfg*}!kH%!_UYBg?5kw3gc_Q@zuOlidszpNvGYIA(3L#FS z%A?M5J6jQ&!@D5HE7GZI`109NQ*3P8o<&to8y_FvubX~@maF*ZkMGY#QCSO{ z$M9Bh@J9-#1ND6QiW8N7_OT2x!lQJmJ{{0lvo>MHMos>AgW2VN{x4BV4y(%M=(yMH ztjujJOTgG7XSG5P?@3w0RQBi@rdxz7h35Ub<#>KHx8O9_s7{W*8L2!_SV)S?p|`=g z{UAXQ(a_gXS+hN49;YTU*e8?yIBi@Av-%eDMBX^^qTB?9 zatb&qoXWsnDhi9b?}Nxhe?Uv$#FO!6HTH6^>mF^30&B(lIDl{Ia4z&jiAo?&IgqAo zR}ywd$1Vnfg3RgL+ttyL-))5dia6QD+>X1J&8_k8lhoJaUXEhnGymz>-bicc_sV!_ zv;(QY(ux|hg7^rM)_w$#!02zgCB?)d%$EJ z6fo?_4yE#0Z?Jv)RPjS4ERxhz-{2X{Ae#KY_T~WGA%1jTGO7-Kypbzl=mXFsFg6w(e6wrI7sKD7JA;1}yjUtf%FNh=)D8jm-iSQOOZo12@ZGp~rj zV9#+jKC6z74oBhDK9nrQCD4vnCy;CT-wI$Y!@KJ02(5F~o@uhzO^*|e^1M;-oTZq- z8+*Nb6Y1#zL@Eu_;a~~F$65)-doB^izr#{=-$L_n-HDy~^$kA!c5*#uGlE^%Y0eLm z|GMTGPplz|m>n|Mp6VZi=_iM^1+AU*7w|e6mKjtv>Qzrpj?c_opPsH&f2B>-diU<` z^70U@4~e$zQUAwbJ%ws_8J3^FIUGY#XVlI_9A%qVU0sbpAaE&oNJ&W%eu?EeRlLR> z!2h0q9^c0)$kH6SwSMaQCslV>@{gUwlZmOR+nna%$Dp3y;>m$fib|sxdoY ziQKvw0U$A&$%?m~a@TT_Gc4+bAtiZ>rh?x)6_vHPvGU{Nm75!tk6(7YNN~Zz1ji*@ z(nq@h5;7yFlu?(w)slD?92|UO{_lE!;{J4*go46*t1tNJ$zMyLvmwVXQ%tQyi0&BIhLVWdBy%o>iU zK4g#13Mec*qukn92@w+nub|CFS*ym*D}B@CR9971S5iWg)YjHn)LOI`VIjPWav>qpHB&}=Yy5^AZAvNA4{sN6d?%Gpp+CbVD_`RM3q zGb=`Z00rX{6_sn52Dm4FH@8C#P#~Pb&%T zD6DV9BQjy&U~kVwj%#0fM^KU1nEfsH<>LDKpSx9;x8E%E@AlJ86|9D%$zFP$M#jej zO|gg)*3NDz}n4%q06*fxVee%KAGIz*(z3cRY}Rv=H|cC<;F`|^Uube zUfhC$P1V(o|Nj1oAfQ7gVK6}657?B{bupH?V3O3(!V=_nfh2pMEFE(0CmNBc6|NJxjr3@s(BITm1d~)b{pYe7Q{q#=5%d-rl^2*d-`|GP$;>uuJd* zn%8WmfQ_G@UmsBlTA%3_h1}L`jcM;+AX2y3^aR;)31IqQf9cRMLU9KG2#8;YsKW06 z_$BZE_vsf02M2qz<1#;`=@y-y6JJFl(ilK-YwaFCK3sH1NC?<`lT)s&tR$e9$Vf}W zM3bK^$4Q;Nn-XRE?`bpEey$A(;n!qRx;(<1(MG@`(@(MrA8UVus4@zjM*Wa&QeNCuiTAf)D`ZytA^}N>ogs4|56w`+$zvV;tSv zbCM&~%6=}tE$C%cPJ{NiZV!ZqhaVr?YYB;pwwVuN(jJZ_F^ldrewU&lCr?XB2_?<2 zWC*w+;tW2)`az&W_Wse9*^P7@0d5cj3=s*~WtnS1Qtkg$OLJCU5vrbyY+I$DgU&Om zpR=V#RmUO)8QLbK+wdzVx}_BnqM24(z)>!+3(-A(D`i8CEkz=Wnwnz2sTB_oP~#~y z=;h?(;058^tBYCxzB}VHEN@2J@I7r9g~;R;6hPa|%s?3uSOm1vOtgaVFMWM|SwaqQ z5Jv^D4dBI#lHlFl`s_TvV-8Xkb@f+4eF2NID{SByFuHip!Hy#(ub*sU?!LJq7cw6t~7 z)6&vYwNpsbOIgYW$~?r^>CSRBD@bFd+p#MNg12{n{J=sYm=*H-lPHkib1JH;ic4H~ zNAUS5s%iELF-}fS%%vF#aiZmzN)U2p9>LE3)*Lkm+pO$tbIpFzB40E#v_ys?&5Cb% zk}>v;jg4^%y8!i`C{qXrVPQpthMMsbs2VD%K^DVkFaXNE{XUePr7T5cpT03$X_j52 zP?b3-kShnIl(RF-Xnif_jszK?BHq&PzB6#ItAK9}B=T0fnx{9mMm^)=;fjlj0`|G6 zs;R|AM|1Gjg&xfvw(={oUW%c(-cMD++6y$XrJ zI}lQtNCl>y=R*GrG`}OsZ>n+yA2+Vp0wUb^zDtyaOp#=q&N8mV8$je(~VxF`bG|LhNGZAX*b3$ z_xpP$du;jY_rpK4#~2E!vw{+rRJ$*a`bfuwf6+b**u;@)G9!E!q*=<7DiP=L_lX~2hz-uciuOy|$9tD@_ z|3b8B5(;5q%E^grOR%+l+_UjlDvWC4%!<$X=>6+X4Umv5k4)!*DdEGyLcivgR z{Wl9NZ^8LB!y6ULAKTD6iV?=TLA@UFarhN!5q62e+=x&3?XK)uUXt4P#0`OW+fv=j zBF9HG^opW_3L}G~5d|aca&O$`A*O_tYG9-?}DStV3HtZLn-vfG6LG_6Dzf88>c{Kp)pvC0N#dNW&sFdYC1uZ&xMz^Hyeh%CB@Mg_>{)!k;_jXplq%)=WV=D{|8ly?t(~ch)mUKaT*#J;9;WI z&hg#5ziP_m$6)$MmRt%&C(Aasb!kZ}rJ=g?fQ{&(L~a8MK@)Y+cJQ zWaFb?)DwL5;#%#pe9(GgVnXu6-RaS6SqKuzPPA1HF6>JoRbp;StYnAfue{C08ZId* zL2x93Wq`*5?mR&L2e5bpWHHYiHFXMK1`LbEY z1Xy7o+nYisGBRLl{*Nfc{n5V1=ZYzpZ=XbKUigYzEYy~TX)GbJ1)nH%X}=0YWEu!S zBWBM;+#|uTJbvzz)&FiJy39S=)Gb?!!ssYwpQ`hKs<;KPwIp~N6wNp%Ln~7H+$_3zxF8b96Awk;P#p_Or_p?=(FP|VddiQQ%z+RtC~%8`Y`>^ zUj}}VgMUb=DXNim&F)hz#=NbYzh;Xhw4{}q@vb0b;co^?dFcuhL>P_GU3lCg+IacJ1T_6K1F|7n zF{GOZ|Is{TH_y;!YRotbCJHZPo?&&YDWo^X@e#1HDcG7ztHhBKl(p4Lx&68pnajG~ zFsYelH>0E)g#KI{SJkTP%~2N-7FRheDH8AhDlEP>dG4G#$lWM5411lX_ML_qH}0cQ z=E(LwQB3*b?$H*-+4J_RQPi^t%Y)^Pl~F6P`%jop^&Bp(HeZ#<_dcaWb`{Ht=~n$jz`Bk#8Sfm`CnLqtTxcTigkystWqE(Av7B~L8aIB?MU@yai^@L5O zkafVHF*Ymxw!pX85rd`{B5rG;riW3#R822);&Voq#^AD+&YRMmZ#d@cQ)*V;6~C^S zzcN_O!hBq3mK_`n36Tx?6FNNBT7suK{QD$1|7t1Cw_|Z>7;w~{e{a8WNxpWXPZ-&~ z>b^j}!~3!Sj$8jTB?TBK=xF8>0M!mnY;6w#Ui&{e%Vo0%=nh*q1Aha@xmaf!F+2L> z=l#Vd;Xj9yg&Me7n_a#4mSK&4Bjymu2A_k^1OPQ~LXbqWSw9-P0O$(nL3i}ZA)es^ zA>qA$A5RJ}=brxlzQDr53MrJvVSo4!QM}+H-Lq#R#~--7bQSdjM3BJ8qcR7FFN@?; zN`hq8{Q>F{SD**5{1maC2^JweDNdNJ*e$s{6VW#!YoY=2knI*g8)?Ea*&B(YNs2Eu zsL|PzbE@AeDlXR8>kCE)QWro`6riqEOw|I7#I-hHE!lpBI9WmwY$aTq+h6eb3i~6P zp^PuJlsn*OGH^|{RXX!Gkh_|5fm1m1;Vn2~aPh}%z_y3@%yq+bU?EHI?2_l>Ttj0Z zDyq%*q0z9zo7*?Mp{Wrgh}Y&*bbvT98gMmCArn*1AaBJ_ z1r%1SpkP*W?cm?8OnkW;0r$pj5w?2(yz7VG80LvWsC{Ee1TiBJWSGyf9b@iZ-7Q%H zupUElI}7ej2%`}Oj+bno+_C`I;7<@mPg&+u0q>ho7ipkEEQJiNFRlF-;fx% zg->u{Ju0{c?J4j{bHo)|GsqgzXf_Qc68=_}ABdA}0Z2PjKfAiR#>SLf-RSj&fDqDDj}L*ItmuTs;smGrXlO0 zm_*Kx16OS45)$aQs#lUBGt)0dmuxRC>jS>XCCRL_hryBjI|u&aVk zQ&!-as>({~*JC(Np=jwTDSb-)wGR(Id;?-?eX1TmzG2iL@&FfsSua$rnW7YjR@x`1 zKI-YupMD~xh+fPES*Esv&!36q5a3g&R*VFYPRGy}&?yQ?KQp2!N3@_ip}%4x;tCNS zlq!lt4e66Z2BRzEkkb-tkjr6O;@hAG;kVGYVWtr|;W6=HP74n;;QmmGIK~3fJ0%50 zgrlt!AZ*|5l+;HJ7NXj6e_HvU!uhd13Mq&EEcP}%)yf!8Jn+{};RMCK`WAw4v6hxV zw9|4qxwR?lxIa+Rfjk=zEe2cg#&`CJcZ;p*eBu96vNOIg*ix$_#mn-&;fLIw#>$$; zlxLC0eDld=K5Omq3GuG8{heFIwqdBh%n7TM^UkNg+ST~9Gv2l8|M)kh>9H(u%+|cE z3E4o&eNTw5M?+(8F4G4_I?H}64CGVk<8}2tJ~`1(Q&mzzF_(E(*uayHD@^3Y7&2|^ zXlq+uQ$t5f3wnu=>eJaG(h8$4Kbqd$On4)W&u8C9bXf)`JEfx~it=Qq_996bMd$7N zIl#EZSOm@KnVN!U;e&pBC`!nxGwqFEF|)~>e3z>hA$kpnt@QYau&}R}V~JQ%P*FN%Xk{3sm^nACTK9G=in%6!VlL@uS;`%!HLN zA6II~Gnd)lo!>o`^5)3)1@Kw>1N#&a8F&hr29pi3=HrLLw9Bmy^K>Zhm3H@#poX87Ppk$F#xJ@Z;^LAVvJ_t~@$Y;h9}pRi zLp97Ee0KgR<+KFyxA=_n>RDiIMex<9Sx2dW(&K2kEGaR<8dTVGKssR}jDt>71jBd1 z*;4%`e&7;jwXpM|_cO+V7@db~(JE>(piDcQ$yiT=1&XrH#2u23qnETpx}hV0qq8Tv z;Cn$CYRNr{kuFS$q);d%&Kl-S+7DmdrT@`AIqc-TH^(AnaP zRe4=%_EahFpKmx~2@U2=fnx$v;ADO;K1t)t-L1h};_&NSe$UvsiJDot>N4l=mw5^=R!E!M#;wlB3c(Oln0n>STWs zj3gKpj+>nAWREe+rkol>^R%D8qFj!GKL#C1txb4lOeMuXqeQqp_g zzBk15;|}S5M-a*P5f#`|d5nn%|Y;5@G@**fN1JMg?g;OnFlgqlb=@C=w(kzKh zI;p(!4p33kP2gk=)ZMhXqy{DkgIM3Hvj zW~Zz}`c3kux+9@o6eh)oLM^cXcx_!%Ql0jROqSTJuR0N4-rd(-OqTM zvi5j#=BxjwIS?cB!ky85+Og>pOX3TIipt_*YYJ3e%Bp-X=3f0#NECb)gkZA{1W zA!fGJLdD`a^SjKt-0a8#893QYHLrhu{Ljt;MW`-+iQsq!{+|Hje?cFD=vWsUx}u62 z7e08`{QlQQzc%v<+mJ^;|)2s}W!^n$=xtcRNhGV&Ho6G0F z;>~|un;-r<2cN&~87p7m)NZx<;;KSM;4=ITaOJGM+^rg0r$PIR+VKpTH&1q9&GbZ^ zHI}KA>x5UC>tt{9@=RJ%I;fyn?TD3gim-Ant0i8oy~~s*JsrSZ6cj&x{16cq20+2( zdxm&*2o{SM(FWkbf!CIoZ#kCN)ztw#MSXpuiy|^>bT{dX6<{ly>gR!D?gIj|t)78_ zJ$YTJtgK_|8&*#^n0ad3eVS|?_uRc5s>BM(0E@{H51qR`AE8^2!yaURUT^KV47MUK z;e2gIWoRBAsjOFuxxJwuuMtb1&1b_G)+hL(FT+jiO(;yR!KKgP{cfwRWx)_!3gYuduXg zy*@SOe&%5~BkuT>Bpm#@u(RE8x{CiW4h8vPC#eJQ7ol-EZ}#B(6Dh_KFhsDnpm6m8 zYaQ1PCbPXymrz4tN*4gc2e5=;tFxrvjjf_0mSA>P7Mp5TQ^4;#Zo?K7Z?lq?7IOPl zka3%9zpdZ^^*8`2djF%>fw})tSaRnedGqVnuZ6Q!kHu$5AYN1fMU`#bAhm@OVn?cg zwnSy0bP~Y|2(kp*0=H|zFr}UV_eJ#dE>S5t8({_;)r(1?JY)7DPwMNANt5(#^CiJU znbeW9!`7_TvjySq7KN&cIlHP6w0sv{7r(uL?bFt=sKcOi&GoG-yWtv@9QG>+GvMnk zijhjTYpAT&5yBuH=lDqtehj#&MKjpOcxfOWC;m~VxT>m3U9BfG!)O0=*#iS3>|XQy z_V$YqHTMh^fjjLh&muVce}*^~IWaLYKtKSjfC^^-nsndlL)|m#YX(S_!`nwd@$3Ef z=YsvUx_UmpHO@+{LGv+S!(#8Zzk2%h6W~M~U3Z3}I=wFxw)ZE}gWo0k3;_!ly~wqdeM)Rg%}i!b)4>CdyX44l`y0)8HxJ&)2=j#f6zGTe8^ zfPkJ0IXqyX6acImg5W(B*tU5k-87IYSn~a`Ry9Zi4T0jWt)qk1g(AMbzJ7aqOTwli zP3Gk>$gqXsgZdT<{Z{y$LBC=3tUlx%4|A~AxYNMEfL}lWcuh(Dg}8^NT|Pv1q_HR~ ziJLM#0Bix=B*1_89EKhq0#i8ShXiS?Ls1&Bfs{AeOM?6lV<)QOb%rPJtJZ4+8!IN? zoj_1XkC|8ToYL z?HgAsvsB69m6b<87mkgsE-BeNIM7L-J-a1zW3TN%L8b;6cImGGm1(Dkw3p{$3^MRb0Uc_h(C02eXLKsEe>$ z`UpXxi93E5M1O)bV#k34qM?wHa&0txoL@uPS`MCZPTd**v9|f*tp?yuk0r+Qi}A0 zeX_Nlfct?k`C(mJyaaM&Z8lbQ8B8d7?-f0wVDDE=-kQT7QlRKUC^q~1 z`$~1d3-khHZ!?@qg#K7ay+X*>tXL=t)Qp^$W}4iWq#$ln8)Zv23qb#+fEH(FsG$*@ z%FHjsMe`qpaJtlhflF>>Wkne`0??1B8BlbUWqwnN1mFcLg@XT7n3G_JNJN^*u+GGz zHn+^43C)_Wof8s?n-hnjWg|U15sUnX3!PZEcc{6uH8hv{lJwbwc0V5_oLj5f>fu#d z6)DGnv=2yEA2=!ijHb)3rBJN@NmE2f=u=6_WlWkV{?WT7E^dmhaI1Zf|Ln2GBOkR>U55ik3odqTE)Mnn9e`SJP z%@R#w(4-4~XB8l~!oGA>&y3Hkw4}vXRvuSZ)0U`tUzCjP(9)A{~KL-b+mb^l+R3E_I557_f_P#$^0A%CBk5I4} z1&y3x$*cMnhs9bX60J$Tv<0vRBPM`Bk!c~np%uV>%nV-w5}&m zgbd+sKCFL?3Dfi=|9d(XrjHM!2vwqc6DjI!TZ!#yyvk-to=2&5*|+F;xl_+XNl^j| zD;VJN>C^p#sM4hJXK=({*V>e-^Np@_FW%j6XDK%~UsF=%92S#TR$sms4>57Eb-Cy( z!V^WywgnZjy|K2i*Z~B!dMk9-0-TsO0Kyt~cw#4lRD$D8>aZLOL6b?6GB&QRkW7L% z1=wSjLQt@d{Zy#X76DEJc}M`1pt9imy~zH-!DmA0TENjvDT9OAXgjmHNjM46zQE9O zwa7H><0&`r**S|FbS4$0_yGng;ecW90BmQl8ZY{o(B|y2wvIub|L#HVOAc@6P1P=cR!Q#0X0qpv@!^<$guFWp z!eVm``}J6;r1hW92U<-%7=58Q4f0Ved~O~KKf=qc%cHrl8i*hipNSmXb6j34%JN{D zr&ooJ2QVtUcr=H+<2_)>IB>J&+$>{Q%i{42n$=ySP@@4cpejSR=I!@Qc*%Ktl28_$ zwwp~d6o&@gVVJ_d%Ae;SLZSmvBbp*o#zj=Vx4}K?MxS4tT$}^Gilo+-rgYNu`9)yM zk1%?6V&moR10GWs#tT{m6dj{zOLi`??~zL&p3kZvw5qM9gc-Z~YbY^fuHb8PGEvWq zT;(?S3Q{kVCRuYy)FsJE-T?jeV=|XU37b`gj%L~$76%}kg@jTe+fhr~iL-d_kFX+C zA-2EA9JV8sVTp+Ro*_Qs%kp_ibg9*`NL_ys1tUpfZUq#HSXBfAnxyH}Md5_n6f95} z#R|3uPu~fCnV(<(g}3M1fVY|k_mZ=>!B?Hmb@RsQ7*!OKNRg-#XbPI%}S_tmg~QDn?8NRy-Z+{AEX_=rFCc|q%` z-hVGK;Pvz%R&gF`FRj zf@Dh^#+2ZvCUb6;>FUB}m98q}<70Gy9SBg;x)JI*%sF)$j@z_qahG#v>F3^NmRc_s z$g*uLoygC~^?^c*C?+uG>?hAwz29nT0!_k^o7tW%->%}?460lK(=iH&bQT$^E~h#4 z=r0x6!t*&ABN0~E#vS<{(#M~P*D2z%p;e)^1`MNJY{;8yXb>ri!lBH}y9+gjz<8RQ zDD9GU?uYHxKW})hcpUvC=qpTlQb5?=Z7+GOV2rqH;pr6a%i)pR6@#uL%y?#I*Uc{c}`O9+}vAE?QDbDN-ZJ18utP$=15P)QWW z<7zR(R4JKF{^44qC5>Mi^XnAX#G8(F5_C7&<~R?CL3D*F4$@NDi1>?*ZtweA$<@{i zuIJo}>FijuF$HqfOi!Xl%ZzNNMLEo~XI|(!dIw6FuJzFLi3H%wUO+z$6v?x-_Qtk0 zO8i&YL4qyg9V8f7N_-nmZ8VqAAD|ZZKtzT9BcG9ett2gNA1pW#{2a`v@ zM(Qg9PO0nc(lLjTW*e#0t_xFT=UUuHZoTZ8OnlWp}gcWv#96g@pwH=8%jO z>J%(ymiD=|H6g$9y?E|e9x#|BMyj#2ybK6J4Kd{k;+Cze8n~w1J7H@8=^woZC~h2Y zO99dCGM$5h+aPoRm@DZiC_rHaumpmpZn4vPB8}|1j`Z1h>T@8G%X>(Zxw9jb9UPu( zmW797vZzi@P6BNuFkm2zg4DqLi?aUs_?Y+Myd9WZw9=Cv%*&(K6LsA}LEzCN;TWR@ zglNey1{`QC#yFJc2gPrT6ZdvK{JY>rN?uKgF=*p*Z2$4C--b2J<26vMMv54?frjcY z+dsbgAzjV9Q`gqt=m#+r3Bs)@1Xy^JHNKMF+Bc;s1+TUkpk~AuA93T$s~Q(5j2{2M zFMgx`nfp8LmRr%=+x^?r{@e)<^QPY%L2){ZbP|Ph1&Ew{R4?7K6%rQKov`0?$3RpR z7oR-5cr-zo0`L{n7;uBUPM7-gu~DiELf_Kwi2`L8qZF9gQ7E29aY)3c6LSY?$Ew=0 z2fQS45FG1EY2EO{oeC!|*Z@X&upMFUO+d2}9gVZK_@CeA_PDB!i4cjxjKDtRV>|fq zLp@)L4vcgs)zQ^uUR?ojPF>*b^N@ZNj2nXct*?K9-E{s}@>Nh$3sGPSv`@9o?Q*L> zIhi;XgMY<>f&dWhej*zh8j@Z)bOrwL+amQFTDm`5jW8czG^_(%umm&fDS_K%%DlJhnTdl+%mny&!yaI#_7Qw;m8mUstRD+&hT`H&(-zy z{&NBbapYi&=h3x(V~-xNX};w3M*vCW2R_=#F%P_-uha%4%KuDJu2w)NmM!cATM%$s z5!|E8_rLxEz%&hH;=w92l@8PlBVrD{Q?FDtSDY+KBJjya?KKK0=-=;6RLQ>h|G-U* zC<=*=YdMl&(?C8#dd~q0T?e8wfnIVv45a|*VEbMO{`#5!4-XH`ugL0Kj@VcRf(-$q z#G(f@JCIcI{mP1gXYe@+kFT#UT)|K@_LdF)es?6UJ|``0M5G%17HBdOPgtKl17>3A zj%XAjl8QiS!DW}IOGD?_>Kq>|fa>m-$oC>JXX&Q=;&BEal-DtmlJ|E&vQy;WBSr6n z=Z@lHZJuU1r{RiwjZX8R^Zd~q+sB37X0YRo_L}jmkBiZiIP;;w@lgi!`=h18Q?F2| z3pT;YAsq*E2=h%T>88?DK5XfQldWxAOA8N=^Y60!zV5AAb;&q+a_CkJZx0G>ER9G! zh1^BgPXe5v`_4^sT&TwVI2XIb=7L=jXdWcx6s_YZDB<XS^~J+$arOe736XLc)Xt0E ze^O<}2#pdkKHO^5odO&_&!-2sho|h#CrtF$Dk^emx&{U~aC8G1nX*|_SD=RA1?Zup zppKFAni#!(`!PEk7oori##JdGBNi_)gDbRzwMYm;p3Gf<;A}V?jZr1+-WX!0u1qxc z_AyvBG%QnjWa7ALDXOc|HJRB+eJN^2Lr;6{*VTji-F1otPcMl|yVS9==VxnywcpgA zPmKYvpuhR&tWOCmbCdmy0_2R2a3fK|y>~wXrEWdA)DwSy&40!48dV&G$tcxu+&_T- z1!E_N`SPrFQ{hrQgRii@p6}T+tP0Q;HU#mB%7O+O)`jhZ8Y^uWuRSEZ)7#lebC;wy z33TXQKwc9&lqSgpBmIFPO|Qh1!oB19Dg?bCXaQLA(EoxIZL2mPiLN0H*uErb z5!E42xCH{hJWsXk_7Z?Y3C*w|nXFdRgsTm#{2dEdU(LuIu8Yk2;E8tg)y zEAjkrmA_L}e|o3SJEBWx(!GpLFC}VXp+hX1xGUZfjUv#@`icMl)DSDH$4wTnha(jiO_ZUn64hp|;g?{ZzZe z`*!^(t!z%%Slj;j(1dTHT%91qJK#e|U~$d9=JYQc&f32*ns-LB2mi(;uJV6=`}2C% zpN*0aErq=RdDG^CK-jl+meEvzkZ%j&&>DnL33_Bu3Fa6FB+%O0x+n&PnP3jZ#1=`+ zA_pb?OfW#BjY1KxNnk)J!-Qw&9Kf^Y|vrH3_r@Ku_MTO`0y9s}E+~s@u7kzkcbHViiMQLfH zj5lH8a|kUpB^BvC;Z$6j|97?`0vTL1PHYk@hz6F-iaY2t^?M4LYV;j<9fbn->Y~sp zJq5;-dTOh9UkIo+?CaywXKEK#)s|QoyFkO&{pyhs--%8r7+U_i(~%0TCAr6n3QgBM z#<;@Nv0ctS%y?sjUBQxwjj-Sw(cq!9qP*%UEbz9q%IKLvqW}pP%3HC!cQKNF0zeWx-Wa?T zH)pkD;Ed$<63bwIUmpXj0HFyor)E;J>f@tTvY>|jhdq?S93xI~CNvq-mH8uSVEFDS zQq`|)TBx%|R6@pqIld&_E+~Wjwr~mJIXgj<^thf> zrf{X_0v$|3N`!+^^0_oi!9nQ9W(B;Ia~KhEGWlYnN*64YH(024Av;OpuZ)5D2Doyx zG>Ec=_Whij=zEL3WRT7Qr!z+IsylajeV;wp?lqM{8((Fp;T8G*n%w8U{Y3qbQP%7p zVx%mII|p3#Xcuoj?-5_%e3*mCwG8}4K&A0nQW5nr+!AH)21p>f!~Z+j@9Oy31?Un) zE>R((#9HIO1Dq+iZ-yX8xLGo$WED355BT;9Hs|NxzlH;PzxUp)pT>lO3LBn8sH!U_{xt149Kk_4!1f$L$(zykQVVEA zTbi1r4_1IKFAUbNZHpE>3eL=SWppV9vDxXa{NHo$mPM%Eq~s`8IUJr(oM^whs}lH4 zn#t+pR@b#;b>2r!5F^!Lq()JisE7~3nq2?&JNrDA=G6aLdH%xNJDA5ooxr!hEe)6nJgF{Z@cR*9+(`A08gMKinTg*NrjuLDERQm}VeNP#zmp!!bNsXu{~n zyu5gKXI2jB!}IflS6>JJ0>l)mI(xpTTaiNX_Ly#k7H{tpKk41YX3+5*$6TIN05#5( z;vnADEon$UpYxiiaB^azS+hYQrqzq=N#3qYv^Q{!ePCv=*z`{3;kM5&P8kZ|E|feJ z=|qiApR1jm9NIg5%`^~Xk8=2shJ=lnjWVNju3Z1Nc!=$hnO3vxjlTT{-8`7_!d&w7 zN?O&dh?aKQ&5h2qDtZZX-uiI)pN*}8iof4R1_XMqy?f~dzb2;ttzkZ)SiF1sH-27? zjrmpP9||ZmB2|Lvu_yQBo^ZlomyDd}FiyL)LA zM39sa5NVL^PKgJlS-O!9>GU1HzjI#x=dgP-_ssRVYJk-+EzRSlo}ONMdb)W3wMQ7E zP*x>yS-it=K)^|~=A$UP;U$17e)KbL?CR<&D|_#XsiTW!()H4%loQ#3Kn0Pk$mTC0|&G=4U zfC1i-n%;D^Z+!VNM}=*;x!E+WO$OKu=c9p+;F%#qziGs*@o6Gzp2lKV_O{be=!ucc zCWq>6T*v%h_rSk@nYV0l0Vn_!1ubA$Y=+HDfw|h}c*#Id4{i6exUY+x9FhmuHzlPY4P03ae=e8& zheQ5aygC@9^W>pn&NPB%8j&thSmOLY{$0v`j0qtb4J3s;t>&=lcixFU2+Q?`oDMR< z!NH;Ti>uYd@-qN_&3!kCvt9$fDg=pvfq|iKP_#`pc6Pb9sH4&~CL15vrH6NRY;G{9 zA0AIab8~a?9)VUw2W~v!Ny=@vq;0MOODJnX9Y2eujU2=8fU=gjY`?!>EA(lTcJ})d z--`pE-1f4LI{3PVc#ci^j8$FMOQc39ez}mm$7#YI7Ptm^~d&Hpz<>&pwMeda^Khiz?t5MCMj@4tsJ*AUO+B~f&+ zi?;*1;a>#GdmPM?y5Ei8odP^0Ia!E7#0=&9m)!0bWsqWLkLy5d?V%inBn>COkn;mn zKg1t`brBVhdW9g}O%QShkwQZfoR)=H(V5*ZpM;>TLWEglu8;*;AQ2&#5rNsF`NkQ+nR{)Y_?W;A&uwXy_Y>yR7|snjQr9OV%f$7c8)B%Ms#UtcrK| zD?{%1iT?s{K|wG76oA1EVhz(!(t)7S2A#^t%J!N){YeMA1JXPE-`#P2F?ftsJ-yC- z(Kry?5}*j5)#BO{Y!Z+mE(4V`5*c%MFplFQPM&nuy0WrTRaI5rGoPdyLt`M0l@9%- z%x$y#CWK4r$G=PMI|c>*0>dU1IXOf~W_8aCR2swul~Q54J#%54Givo>&7_Nw zB|GW7=c2>Ll-^=gOnA8c6*}k#>P)HwE*;PzB3=XlPX-4@Qrv6xF$X9r^X#&gx3AM2 z3T54=bLZrK{<7tD;eAPbH8P5Z=7jLKTWMUJ+6{MN5d|Df?F^Rk_J8Uwo*`ay=>0b8 zm=9G`zwzE)7VLqM#z{g^adCO@eCp1zihgAnu%fdfRU`3Y2(*BR9H>QmNAv<1MsLJ7 z>Cly`@}i^g()5Nt_WyCDs)po;fcgq#AE2qLso_G=!*GIn`2IO|fi(2+3Bm%AF%8&b z;^-V_90{|~uafC@@%9!BKy!mo0w3ccT~E)#h!vm2ztYRY%8FrH?y>xsy7kA_AP<;egLa8 zxCi!C(A9JHtT=d#7WFb$l+tYPwLf6Zx`b>ha1*>x6yIzNr>-LeH27(J7yKd_`0Om+ z3rS`)j0h`}dOmnyzM=!InkyONXAp7rGxslY`w2?fM`RR9+1>p;KOdiigTqh~ z4+VBKurUiDq~%j<>*>W1($Te68&;10;KE19`3h=g7(&A&`IrS1F#;5IquNoUCOz5U zh(t*~uiM-pKf9TR^lcb8!&N&iu`u;7=8u%vA~e?i!$O_lZmfRCl^4&<6E2Xrs)s`H zZ!Ij+y_v|R6zbW7g%15bpFi}88l9?~)Xm_$bn$KKD@DICxmXtKWp3q#p~i=Oya`7# zboBLcp8e7q-n`2=MLYLGwvjuZ+@R2`>eE*^CyVhmxp^=Hj@FgejLrRljPuL1wf^LU$QQejYlzoB=IYn=R6dUcc-q>6Dvy45_QeV$)ts4E&BAi>&xMQ0F}(eNt`0m zHBw#g6r{7}h@s+o@4`Tps;;e*&y>^LbE&~_-|K;F#$VdjCyJ7Sg!MRRIeiyNsSqKd z50}03Sb$43>J0J^2xv`N>!w7;u+W$E+Qlbi+GoKZcWC(a^87!bj{ajbfQULZrKP8L zJwRr5D%X|G8wGuB>=dqw@exir`tO5Agw(>f*h@uLt5oMG%Gudmn|ycdF0E4q)3-+m zThI97RW}@(U+n5l?^Li$-dFX^>V=o7W4DCr7~fwXF8{6L@b=`fd$l4!?uGOIK=0x; zwB$ZK`GtC?=WkqTWCa){ND#ruzsbT=hpkuud{>Hvm;>p@TK}I64!^ssBfYP7x4er|OuT<2K;n8VXgI z>15=Jy{vFN`EUP#8|P-vU=3B_pJ&DUDPGJsB#15hR?Ujjp#jT7R= z!`a8sc5pCT0Hfy~2Rr*BVALlIRkVBc(ch#$4Kf3+i`u(@DY<)nT#TBzPTsnveCfg-Ns-5n z<<|n6ivQ;?1{fR-mmO2-*C!M|p0YS>wRr4`y5?`gtg9)>FpL0J5ErZyuPg2=ZI78Vu=h&Vre!Bnc${d?8a_2J{k)h5^6zIACEkhg6I&1t!! zo;&{x5MRxcZdL+M8X5sOY`p|NCxC>JBJ=6f0^?o&J^Ocn(t0%)g&5*$BG;;{<#~KK zTpV(J@hJ+6Z_1S=MW>SHR=0d)kH^5-Fi!R859PqQ7p1|h&3t8g#140O#Hf?W$tBqX z*X3zw)z4*eY=^zs7keKAF1~%CjYW3aICwQ=_s@pru{{EUK8MR~O#tw}`xW}|BlN!< zalPWH4nQf})KNG<$T-fbi>3}P4bP%Xp;Lg-46^{K0DllnN&fT+YCf9AsZ<37fg~}6 z`|4RaBdFG4fL44+$VGBLbL5}c;7w#)thlnaB3LYZaA)z~Gk9)~r)0HojS8#k(YZ6vT)S*_R_$+7z14K z-Xw@BRHIDxtbzBmth~I29E8?i=mzPQlfYvdmm(LzC@zHu@Ua#h&r4$LyZ6e;t@oJI z3z=*N%8Is~3Pw7*Nz+q5R)4-a-o%T?{@A@1%T7MtKzjH~>`XX#8%<`6T4yG!VOV|n zNUY{}qOP{2{Waea>4c0Q{F0VEx5?Qi(B3z5dg#)oHq^5hqB+7coj%oSxFewnhbBP}9 zYWCKz@nglgV>%cazlX^nL0=U(yNLy&qD{;74JHx%9*Px~K7kjqiwM}WLFm zEbGK9vRyam9`2P&ZoRcZMZ2(Klg7|0@x1fc89#N~4N=J>>?1m{7-h=dfsQsvlj5^O zg7u*^DRNK>=&ez8r@$Uj3CTV!|)#^CMdgl6b)|peP{UH zch+>j^5v!$3F>1sK^Kw140K$Wnwk&wjoFSqdCPEsA z!lzt~6};=lQ^$v;0j*s;f?KfusPY8qb8K6y}RAS@&Wj_mK| z2VXzi<(!p_sq0cVtrV_@=X3}Ko~$MED&<}kw!fS8B@bQqQzU>W&b*O zo!DR`rosN)o2Ik}LK?9_q_Oc6xkJ;JXC2~mqpV?T`x^j|W<6YOC(*_a;T5_EV1gj{ zPTd5OAIbUuojoMpAmz(IkH7;yrRARR7!&XQt$+UfgO-K{J_=gJyX6vQ{K1d3AFW2tFD2?1cW1zUgmF|uJ-}s_a`bIlxsddz8i60I+5;R z=cQ%>H;gcP3{`!6L;6^AEd1w!=+)g(#<&zZ6)-lgbVI;iucDf7fW;ar1}8qnn__H{ zFPzg^z)UWjw{zh&$c*1<&5Rb8`17{)+5;KdlRn66=Q_S>mfXR0|8OF4F?OaNpq%T{ zd>;DZT#N6-ul9W5Qv(Il=r)LX zR_7r(`M-RYad*G^H$eas6SN~*zLK7to}2sO10&u&0ID_^thc92wKOw;jH)4LmYD0m zL(v@8Nl8fwad3<1VFHJNpkS&d>QBb?aDt1d#&+l{wis+&8xXD4#0?%|iNvltUTTTp zN|gU9itf@69#Y0XxZr|^=Wjhjfh6Zp_*JFyt=)7-K(MWzy1lyVz#5EZmxTNZ4+k3u z?WR ztDA6VU1Z6QHtg8F~2uMcUv<_&+2({;jakdZpdJI|>-vPw(QUNJ#J;~ z6h>ngw*XevuS`L#hN1Q~a?*Fe$kg0u`|BAoA`JKp08z=;t)-(wf{%aPLjfb8!~5yF z+)7dejdYz0=c6MW1JY!e#p(W9PsC|mX(>iYz3e#XyA2Esw1g8Exc7m{>!jG0Y~cjdJHWh zAM=|Gx66GU2x%I0D64v@PM?D|^nsTSV;ssujz2sk2pSb&kUKDDAYsyFB(c+9hn47`TpcA#;ZlT^jpySJZ z_;zGuB%qWSCi-e|zaY5)pefN!#Di5-t@LUI?YX>M!2~)Z56UC(@sQ^N8aNCIZN+aB z2gXN-=NGA&l9txHVC32n#R%hC3AsNS92_JU8rU`Zn)_UcUJ~*9e(R#Ls?Oxhfgbm= zvYIj%i_(!6af7dQ%aU@smTO&UHtzBoj8TcZUR!6ovb_C%E^m8kZSAG{efgjEzn|Uz z{H+)9b)cGF zkucJG6~vlruyP@o&d$!==+cDM(2*2YmKc;gq*JV3;Gc+HLp!Ep>fz!+q`;}=fl|L^ ztLTDKuprgh#kOMXAIOXKfak_98!(b4fEj#G>KU@!LwA3OfD7l)gRV!)6(rTxLb z%MAl_{BU;{*7N|OgAg=~qy4nVkY?HnfU$X@q5m8n4#UOAH|ewerVU&Xk&D2AuaTFG zUqBwLb;oK!^n@ftqG#-dBakreh#K?+o1vX<^eVbw!$ghYSZCf)_m&Zcl<+y4$ZX_> zFR;p-5bBMJ|2dReTDe|j*P267{Eu-%jF09;00sioL8CO0(N~%j>6>&cVnm`Aou%yC z2y23B4A#k`#U_HqAw~!$FmyqgGo10Fp&aqX(i+T0P{H{ zF7EyNYNg2X@t%O>uD4|1u~7Y^D<~D|0F&A>p5HuE%%y2p7MLpU;Vfe?CfZVDM;<4_ zt1FfFPT>#>RnR2$eoFl*U-)Do?3nd2s%rN6lbH4DiCA0$+M~-8R*s0W2({^%qPWyo z0s~Y^M%@}0#BjPlN$==JVet>>$QdQ&t2%Y2Yg-BLzD zL4lET+(9BClv}Uju|Slw0~F<1$qiMGV;yu$@^SA%D8l%%d(8J@Jf!h>(AoL6_@rMS zV@VsBn&M{2vAbZ=SiLX z*;ejm#vex`NJv4;XYZ&WY=h9)$@+*;#|FI;*OQS}LPEd!XQ}i9kl}eumD;nPH1%ZzE*ny<;Orv|gk4(H!awqwD4% zh7$GjQFoIvh6C0nSOgM0D}&)cU!Yqb2fiA;xr1hqEbP_!A;MjfMY5l&HP0?3rv5_; zjb=Bp0xFWsZ}eq9R+neeSiEk8JXhww6N^k)+h(+a6-_LleanHI_Ffa>qb+l7Y)ZJxS8*`1EQ}?BjYT8m9T2NSP|S5y@&1 zW3ym%b=^LGdVB*u`UY(4hOc8}_{&78Qr?(@Go+Dj<$rpbxxzoN=n_>l7kroWeeV_V zt>WpZ6!P=0i(Q&hgw&K*2>B(MTuSssw{oA6t-XrxVpLx5mH|vD@H$D z1grLMoQ@CWnFT=*cs4I@6Pf8s*AM!KC~q_gkJJB)L5O8cn_@tpw$FGjNS9te%Cz)q zGNyZ$!B-~H;DZW7IUTwQThd5Ps?S8?J@6Gx*WkY@NR*6Jx`%s^uqfyHGFjyOleGw# z33sUezcQ+vqyS-hlIf+Z=)O@HHHTm;?2%C<`bL`G<6u2IYo^9msW=Ol{7|Q5?_B%~ z0d1Tj6_4O~4{3uBE}larX@l+}=-!=~iE;+=o1B~+sC=JfiDZfq$WCm0L%n4@`aFu) zR;R>*W~gLHU-W{WM?6TkDXv_y&8W`b$Pq~^^LL!H|(``5Wo11+8 zypzHglzc!`feS^LlV2z1zb&PtqH=U}q<16gRs?Z&Wmo{V#5i(@x0e?ny9?f9<^Ol5 zv>Ff?I8WKyC&Wi!8HQC@sf{ZGj0Z&b@q~@TMz6!@Gv0lGvfpC77a##U6;f}1A2QMu z@i&7T$fHQjYvX5>xbe~yMq7$X2|?rZPQ9_+FK2ly(^vGR(+3|h^|E?r)X)$s^Y?!k z;@N9K97R*Sn!K;CS+P+q0|V~?gaoA_!Qem#$_}VRFP<7Uf2VJ~p&yl)l7ei#)(dcq z&wE={0H_Q^fol&G4g&sDD)`PTG*s#WAQ&JlYaoL1Vrxd+7$oN=r}^-mZka*EW0da5 z6$9Y%kc(YPT|;{GsI0gClrpSLZt;!4oin{JMWaPs1FEWP^DnPp6UiFWf?PDLcz%L# zCj*^&v5}nm<`kb-XuQga23LfUdWTm@Gt5t>#0}%3#t!ic-8xBH9xugr@6#=8cDCGi z1Zlh&DIB?9F0^bDTzvazLX#7a(*xxJVFiHo?maeU_-%iYkfeWGQaL(0&~g;`6Vl?^ zEgb(1=`r@eK)N4?O89W4V{!BBC8*CfFfgE?pa7+HYrpE>04dciq8At{zKHw&Jh%*b zy8Uf$Zx0%qAJPMN=?+tsw`u?0C<-8yApHEMz6nUm=hjL;p0~sJOl0hhCy!86ZO+D-5Db(kzO651PvkUMaIifWJA z5y0I&R7iW8QGMAg@GO1g=1`fr5D zDQ6e#Suscnv9b?xzVgxiFTOz-44lo0x7 z_=U*GRI$3E?!V?ZqNCNW)oqWChd-m^=KIIT%-63xF76Jh_ywS^Ma+AV(Yu>L-y*b9 z&)7ISIXOayUIVE?M@OgH6ZF*pF14Yd0f7j?c9(!9x))?s4LL{!(By5TjR_0LAED@; z9&emvF+%tV4kfFMPR{KlT()6&tb}yKBD)RPejiLfF8tOC=y;T@a&YUm;~lQFX;E0N zn3+Aen1C_f81*r`cGWVa2uER_;RVU-_#vyy4hbP5W+^D3a_Z8o4Ik9uVlUW>Z;_LG zv@VgZ!W`X(v~+d9P91Dv>R9VI`?$zB818)7T2vjY6p9($q;YFrVzRb&s8ryfMv{A? zA1rcqUj(ezwoer!8;R1P_!NFWI@RLQ5L!4*YAm}5HT zj*ic7K`)tUL#<|&b5mwuL#9mwWy?SYds|gkQ9&DZ-wJ(6kcH}t@4~OSlB+B#-MhBV z-Z7-)(eXeV%m<1Z;a)>u;+a!tis}|F409$e1T#26_vA>3d}yw*=3B$hS$cllg69{X zu_QVkNz0dy-S$2d{a4}CF~LKfr{};B=-_0JEIZ)*5o{T>f70hn195T?2&Nq_0S-pj zkY1?=tTM22R2ep4vI~9_`e(Gx@5X25EZy?B1y1&1=P=cOR-Kn$#Jt(uiu3ZIKu~_j zZ~=v7TZ4lN5Nen`7~H{pas~+b760Ef0+ zkWl%8%~8{0Kt&o?y4F#3>3@TgF{&<2-Ub|%YPK;7T7ieVr2b|frs(y`_u~fxQd=!J zPH*qv#4Y-AbU5P;Ze8NN=J*Up2S3R1$mf%P{q_hvd{(u5R3nznOb^fD%36#N{9Mrd zO~3FhJMsQxEgM8@q$8eP@6+9ua>2w`?Xs*aBiGdyM;^+g==HUpjfbdnXCJCruOY|8 zX-HPkZuj=Tsw{E@G8i}PTTf39ASh(fbcQ~{EHvbBqu#s^{?~G9R3bw!D(e5iFKilw zM!>Z%VAJ;VZw5rj+QdYGqB$v+T*dPE!+5@&{&5FzSd3RyRQxl2e31wQEu+;~PO|J8 z9IhZXn!&=e_jjC2g#d1qWWr3VKCXIsUO6=huF?A+}9C#K2@X0+zX?NwckjZY(~j-b6gAJ=kx71Y;`Bd~K@ z3BXcqzxeOe=Ka-M3-~!qUyW3;6`Gs)!hvvp#!kQbMm6a5ZlWjKAK0wqBEO z9cT=-!1#bS2P79ze1PC0`FNoP$nEduv_koKk!;-DidV={pm7?|UmOS3*eM=Nl-@V4 zp8wlr##x9%t}z0K zm=r$yxCFJ+C{xB^rl@AZ^z6hCx@Bx9f`8j3h7)5bfN>}n22=71MkjdhrAT~AsO|>! z%Q*h@O zWdhs2yF)FX@!^ho`fkf>RAr{3+?nK5w@|(NZ7Cry{Y_YObpLx1uZqVSr? zuOK^p70fX%u;-yPqV{PSSaPhpqL;7L&uVC8t1J9oe+cIMDx|FTl@LU_k*txwqHttU z?UA1`{V$#;ZQ#47SS&$EQN_dAEinDo=Em3D6a)3#-RD#LzqR>JesW#vbbIn}agkB+ zH1hRzb#%PHJtrf1yx4(&6zgfEwi0Hb0PQneKZyqrhxiW{M~38XT9`H<*VPRQDIb;5 zU1KZ3!No1$OxN&SiCzrXUy~Im{_!^&BOs&2p<6gMtQzGt1+wbhi~oHiX6~Asm}2&- zJ@TyTJa)GBq*QmoBU1~T!PNK*EPMMGBqM}SEd$YN`ygN6&wUe>GqV)&f^6RNa|ToP zz{V0xQ~esvX>v}VwYJ)aJrZG(~zG@7&S7 zzytvQWln*s_A^YD4{IrNkeUmhg4lU4L{;W3T&{Z2BqvA0BuAo>^Jq-95(Q-d=Ti03 z`(obBifc%D9K{5ucm*T%Iala#hF*W7J5CYk z8=?QC-20qs77GKFk>lTX$n$l0_&oi0dpENZdJyfbm##|g)I{K=LoXK4-&eofk9q!j z_yg$Cbe(c$b{%U{$6$lo%Tlc$*H^j=&fP_*dGB>&1efQ!nVmoMXjI7$GW}srE(MoD zN{ptdGCPIK#me3BVZ!HDR|)bQ*OjDEJ!h{3Xav=A8%#!3hq!az5Rv=)zC>Wo8^A!r?+XIKehxMbkS6BJDU zE_|NmD`Tvpj0ePY&3I&bQx+T9zp-$Fz?1?J^sFrfIU`4v^XI&7?o3Q~-f-N3EVOqqP43eZuR5Bp9wxQ%me8LF zI{*nG-Edig2TD>^aWRh60wJx)8VU~8vJAGiMu{LmhyRn$wY5`na&QtUaS-rDnl_T~ z-dEMtfKppTqq}5X>F1j3<@|_Ck@#HL>6T<6n0gNv(zNRzrCBh(NONe}lQYTGuLM>< z2Mh3)Ac~OJIdPIGE=Br5PW<_#gdF3uEFJ5n%Y%AVUB}|DT_IN$AAfY*v~7GfB2}sD z(RXYROiMG#<=s5GYJ3Y#R$Gj>rqQ+0tY*C7o%QNw{-97aH%A`tZR3eljp5iz&~?Mc zjX=~rM1wBUuyDL?9>_D~dOx_4@V%nj{cm+udxcV=cC#^8hzOEV)m-`90Z@p+$bzyf zn}i;b;uB^K@GgMFfbV@v&n^wfUwSE&aKaT2QS?l;Vt!#^VF?Kde)fWj3gnoo!iHfh zp<1ThI+Ri^CryM;R*ezMU{17EkHs3yL#xIZxL_fdV2eW`s(!s!J)Am18CSRrLYGxz zqd!}18oYLKyv2f3C$zN;1A_1Bo5U7IC0rVGrz$k(D6nz%nx<91K?h%tQxE4d*e>T^=d>^j(FnC&9-&nH;!Z3wIIyd zUA$1c_;?j^#SN6tZI&oc^Re#np@Z=(rz-!=Y3>$hk&@id7ssjU^BZttW;N&)mI-~% zd{ZQpOn^S~eNK26hc738(y6qxqLtVGPkD!gj%1Z#fy<-=)y3T%3!LCV2mVcW6nikB z)wHm1df3J>?HCL121uBVUpI`FC3J#=8$iI5CMQ**Bel?)l~kn*qKWC8J_XM6bszEF z%IC~TbQp_YzI-1XyxXVz{6?461-JW#=cUD2%v1hNWCVyDM$0-od)wFqn3&*Ta*`(Z znMdHh*}E`|nZhOSrRTR$FTV26?nyGQ`oSx(JK?C4I5qY5>1>v&L9mw6V5Si3xA1o} zVcV;UK;M&Q6WlOWgtq1VbN_gS4z*&6E4&_NWoRfA;!le!)-Ak6)ySK0_A843<)(po zhm7J~S0ufSCW;>+-a49uPuApKV%C_dk~QQts>FElmoLf_dgO0Nbd6L~vEdiWuC9fn ztaBw)dqOPE0*B~NY)*)lf+e%sdtOR;`y6S5?0UXqxqs<(okO}7h4VOB+qS8+1B3UG z(1iDJj*#Ta-j``d)MTXvB4#BD50|}Pe%7{m;4<#*jRKP zQ6q$SWL-5d;;|86k6}ID2YRk?i{X8mW@b~9lO}fk&R%O%g3l#B~o>Mn} z@scmsxxDhG6^o>HR1Yz2G%Xej5Rv5HT*<$AJaSfL^>yud+_@==UWjhpXHVyLS**41 zX&1Fs%Ml6OdCswU^F=K9Yi+I5{2!(>47B&}&&_|2%&6=-`uV{^C?a2Mr1XmnO4&Xm z`hqW0-%JFLFi`>n+?#>9EbIoQ9Iw0mMPEXnL*thMc2v~$M$RTU zs-GkJ*t(~_4kV|RDGZHO-iigs%sJ9LqrUKOcS$eo?Cd?}vG-<6HB4~!^nC0HZ1Ozk zb6xIq=e|_)Q4_N&9u+&h_7CP-g#|*#gE#tG5b}~FB>XNk7(9;zu+{4uzFV3^2`DD>~3fIoF z{YFlzcTFx8m8DA^{Kp%&{N=h_=eN6}>(-;BJu$x|v;4rc))DB7n1TCjDJv@-1>A+Z z-X@1`N@_v9nadtn{fRDGx{a&ab^M6x;s*8QGd$VhgG*6VG#b;Yv#ZK;BcWfbq{5CT zPyUO(|IOEUuKYAP_c_e&05+qXw&J5D2_UC@X4eb(s;w)Y(_yF@F+BYsa-#IEjB&?t zU795#-?TExzG29s)}c&`#;0YpwBA6xy4p*uZTb7kABUAy$ltLbv>%H?IjG1Wrv1{B>maF4eP&S7=A*h0CH5gVPA z&GY3B&z26=9j_90w%U9x%`YferXM?7N~w)GN9zplf=%UARb{%`_e_;7oK@+4MwR*R zw#WAD=f+=dA8&_0w6RoFvF{(3RaUY}b8{6J)$*ay2nwd*-o!Hv*z+VLQ0}W}Z2Q!OH7Vc(yEChB64@NwlEvJD`~oMX@xQyrwRvW+gr`g+M4cD>$@KC zHW*1j@Z)C1UNw=E14+fVZo&{M@(L|Wc5gW6a>&v}IFSll;jFWB^9 z;7FIKxzFaf-bn0d{P{L+aYx_gzK5t7b)ye?P38hek*-sZi|t2M_(jV$6df*4Pn>%V)*N6y?&RRz5|ESN@=-CNa(-#Y>k4}6;!CUC%|#v=IE#zswG?b)Sv~;Y z_r9L5q>=ncEzw)FJQ-FwHH#9KO(3>~7fsiGcSUYv#2_NDUo~2(%l}ipZf5B@x$L(w zA1wG%v?U*DQ|1_F0eO_B1K9ZBPBrxrsztg51pLJ~XWN%U%g0}0YJN;%`G|;xJ(s4< z!)z?zL3>DrzY-QEh`Z{Cu#(RlP+qhuM0_Eajg0qj3l?z9x-hIq6vhb7FQ`%!v!PqF z6m(!el>XhxA!21v93`2$Tc1c3AI)44mObHcKo5y7t?bk+koh|IEkd%vAu?WeNFxGf zQdxvM!fc7;9wjf(TUB%y%Q1PwCJH5R>-RAx)6p{fEMl)WLw7&-K}}=9^b|JjQ{x$4y%MR%oy^>`wSwRvS4B% z&6VfO9q=f`nrbXR3#YFSOiN)_2zN04o`4Vp#6E+_qNmQY>fn7@WD*QSOoG7rQ9d$d zCe0DJGRGdjiUWtE0CB4Z3@RX0HZ#MaNMXJ`)F?$Boh$NbeH9}mHe&eK%jnN483mai zhn?6y6%d0Bq~B+Ft;!Bj1t zVg2exOob`lmGS6Jrj^+ZVv#WloOq&tAukg#LyEzSikI~xWFs?O){BOqoO!4ZRiJ*( zjCB4~dMe$mF>6=$p$N4>A-a(1u?D6{8J0n)q9cV)TFeVNB z@u&5*LRp%}tB;v#*9N_;LuN=>8k80aksAL^jo`LXpT4!#mTw^LL$pTE_^KZnJVYlz zVOE{6nWDULPakO-DT~gnU(~DA9vg{m@&Og!GEz#L$xV@TlFa#Y={q}lv4GZtWr%7` zhncu8+1p{fsJ<5&p;fQwt9H6;YxFrTp7l7r_`hc}5iecDL%1CgdmC#US$u^%ugb0r5boXva67(%5V?51+%y~Zf$Z;?{bUxnK^kZ_Uv`xo7mm1o5 z#{LHZ@!~R|S+RCSqkLAIBHm3ORfuvgM6>gSW4tK{O$u6NjboEUrxxft+C0+J#&%t z{O3xMULPj(KgJ`SIY~nSVTuLAa4!%GV+ojvb%dkSCp98y`11~3`IAKNcv;$t{3xBZ z!U7zRK6x||1D%&hdKk(iF$f`EJ$KOAXLH))iJ}-4W+NU?;QTB& z-NS*boy1Brh^WD6+iYg{DHE>DH~r0Ul8h#5l8cv`5N6k{>TX4j-e1EYd=VYc*(;AG z^I$iQL4?B^jOE*JB>CzZja==*Ez&>fS1~ry`q|faJPcEIyl<&#oy=vV-QYHU@%g#g zF+4OM$ba0hi%=WC)O#nVqdCReuL&jo#9E|qu4kFtO+c5DkGqR>xb|NxA!(9h9zFm# zg>Q8zKR_5|neHOK7WG&h*Jrd=o3g`? z!48GN5+T7}VdHPht(o~d9#En-n(@b>WZMu*g4P)!BleMDVj4k2y24t*B7IuKOpT}E znCQ8(NP=#I)|RkfIWv5XuNvBU^Z~XJ3Pi!@c*{wa8qm6+#$D=hBWoUp_$Zj1&H(Bj zk8Co2u140n(U1V92VGF_^Co%?IfUy&exIJL2$2Qy^w%PCG2vAs1PYsPdMMV!i?FJE zN=by#BtLbs_@np5X#6DKB$uLJRm^qm&M3LAd0neim;`?nW%1RqK6Q-K-eA6XYEr#; zN&NF??EEi6Wbae za@9&ooI!NK=X_h_ZDGv2xJCb^*-RuZ9qe-*?{P-)2Q@>r3e&u=)4Y60-pNfvs^Cod z>T)o=AZ+{=Gg~1w~VHYd^Y~3C?42Mlwzrvon3Xh9~i^4<9{# zt)!xD%pJoUy#Ds+v|V$>N!1rs7L2d&C$X2Q?)ap(PONJm!do1Um(+!w4ci^Y{(A^N znEQmg-0Tm2L-2!Y3r!AFfMwhYykbUp|AQ*!8gcj(yhOq5&X8%Xd%8m5M4_xQW%+2I zmBgb!S<6zOKnKY|H7zZqFn&b-ihhze{_8Ug!@$6v{h3@9;1?jRc#DuliH#oE&*mf8 zkT@ZZe5``@W?GmvLsgNjPGPgrvX1Y*aH17R`4TVp$^9JZwQ-*diPgi=|Y@ z-b%qUnGhek_DnOD&CAeMpo#L0bE=NLGfn;`{<=EcXmMn6ifA71_x&1|C9NvsQ)b9dhZBJe!)ZeZ+FB{eT?q6 zA-PcU?^0LRn@S~huZ=;w4@IV>(pHVqwDvg)X!`aRjEQ5jK10wJ*=W->h!qUofu3=P zUVOR3_UF-^U2mKlhHA6#jXh68FH^lmFbpvoVvL`M>c^yoC}QY!XCwW|ShHY4Fc3{( zv@6@^eAb?tMW5)+5K{oS4Q=5rRgee$#X1BoToQDj(`DM;zPfopW*6JJAN{azZKh`0 z5^$GjHdj?~l&qIknd6{}6!I*E%>fHbz*MzE`5hA|{u*~07arbDWhUy%LPSIR?{`k< zSw_qALEfiMKq_E#)v%?;b6rnH%_w)|^WDy_6pk|giStDYsq&L)enIYq5+PJj+Glk< zPJw@`3ZZGzJDZ412Tz#&9#}hqpP>b{Yvo3?XTi4=Nj+rZ8Ir1x8?l4th`(^ zH_PAOxfjJ%fQFRtY}w;tXlF3mIJriG`{b^sz-X@G%k9JY-_bl*LCQtqN5T8+O3~`j zqZJ8u@dZ%NiRF7@U|{G&WVNVyBib@I9#Fd7V_|FsdP%b zEs%ZvVQldQ9?iUf=WL)>aYt%SV1sg+i|>Vvl_{!OyVu(E=bQjbN9FyN%@>!*FMFF$RVKgh#v!+)X|k;lxgD7)sIv(znH2~=T~}%Fo_AkNcb;#(8JehsKNEk}WOL+1{a)(t zr5P5ct6J6>?jf~UJMZnRW?UtXKhdXBK}TDJtZc4XA8Ub_M#-~28ljS4j=(pa1>ma6p+Rft;+kf{zuO|S(klfr@V@UEXzta z@Uh`rj!N1a25rpo-`f3HTMsa{?&Pte>V-ReOZ_EtYXOmpOrE`gs5q%kk4vc9ig#V% z{aDkNA6+--Hvt*2(z5)eJQTs76CU$NZc zFFfm-@$unnE!*SNua)McAi_~v4#MSUI{yCqXtW7NH6A+)-k$ec4P7_ep$07;J7uZ- zQjb;-`H^F}!FSPpD|(!x0eb_hi~rvI zt#3%z*0t{bJ!X{l@_wnR(aAu}e?$s&E$~?G{FtlCRaTQcpWkXy%U*id*?6L#Ad_Ep zE#-&N=^spqE$VXrXKwWdYut8Zy6NxJzE8D1*wdsTWNN~(qhN_X)$;HEnMOouAtW%*SD3W8OGe7z0LyH~Wj7=HgTw=B#QV~c-Ruk1FmLcF)lmhdaZ8PrD!<3F1OjIjhlh(#3XOx-qgKBa znsj<>pU&3>>VD6z3An7tr_YJ*)L6<%^}d`eym4Mk)77&LzM7}wu z4}RHWvzwP?KXVrECloisWgM-o@4zLP)#iQSuagIDZA>NnJ?1VQe@NY5jAacMv$OO6 z{*@(Q`}2qI$rq#gU49-^$)^UX8Esp%2WGDt&mZr7S8ucC%2B^@nMpeTNZ7u;eeJb3 zG7hqKAi6%XKU0^^ndP%TeSBDPz} zjoi7yzOoA)am8xKOAVIt?h`b-xuOk$flD4+id4cJ@K);@-Kp^Sy{&gNFeYF1mKu7@wN80Qs}^wix&>;-LnQ*V6}9+oQlhr642M+fVQ?K8~B29FFgON?5wMIZlC$v^S{hUzuetb3CpKX?F1@a zy14)BnO#$-zUlKRwVDR4MtUeR5~N}r<9{*(YO47T;i$}A!X^o{?lax2Y((-;HxoiO znHz82I<#)x?2%z-V9*;J_67akkzvn>-!r4v2^)?d+on*|DwTET&hAzz>#{Nv4;)yF@}8c`^t6jFUOi;9c6WA^qSd~A zt1~k$A+wWJrNa|&QQ=Lr%Fep7XZMQu`1Q?A1sGBCjpOKg*Usfv5)-g{{Mgnrr+3}B zaV$6I+T}|J+FFY&md=~WCt&UP@ohcb6&Qud*j`nc3Vk?DE`Cw&5 zs@v6{eB)Sg(M`Rs*sdl=y6O$%@wPM_NG;Ri1`9KAT6u(@Z?mwWfF zsI5t_u1-r#JYX@m(bL+|QzYuwEXFbZ=P+YaG%%q`!X~NiKI_FJW}5J`X=+VXS$R@^ z{#B1l=d|fv4!y@|a5=OthsJ4FT1?$`Td!JGXV5pPRA^4AmS_kg4fMVt{8nolu-r2l zTU5$gy56B}grMk0M@?Y52%>A$sO#~QZZx(il{Kh^HJi0Vp{N!wfurV-b@WcS7W9Qy zW^)@Xpb(m9g+j3#zG_5nN zD5}YtreWW{m8(}z&(6N=aCE}~92142N-nS9JDd0xFuk}LJv<3w9OLho31PX*1?wTKmmnZ4w;){ixMbEwcIbOu?19t;bBI`xzyCtHd{NlMWMw4 zY{l{%ILJ4J(~a_BY{G1aag2W;%yTjnR*%9ae)1OZB;GwxV>H#H#B6TDZ$1_jSlXD3 zZTR&@UVsuL7yQCAOnULCny{e7st_{uib9Ph^b{C&#lsxpLc4g%j2;K0RU~?ZXY^>U zQVC2X8T!%#YihL&4WSG>{fcrdGf@j!sj8$=@xyoGnYd6Z@u;2E+JY(-JupnYz&Jgz zL60BPQ?jTM4%5SH=oHq(qaLKs7D#~}j>YjJ`|uf>*wS!J4GKkt$ppxt$MMA94aCE= zVnh(wLmr4qRYk)W*YEg=Jd(xmxglwWpQ?k*ZlDBAGCyZ0o{1p^dT=*1OdJ;I(5Q7a zc6*z}(hPxz21YsClng?qDmpLsPj`%C{C%(lNe=+ieQeU|YaYQmEX@RtU~&^Q&<`)R z_kXt`<0o1q0^)%(ieY+2A00yog^;nHpL#_k69kBda-qpv4nM6wYygg$LWV51e9P+#gQ)`uy`u*?>yFA>#X>~dQM2y7WIm{E(8@GeC- z38EKlVTa>fz$NK~dKd4jGh2|FA?2*1Ve+H@;spu90T`(k&ngpqh&KliC^KxqEO3?( zP1r;sdLdajNzKLK;<3Oixvj556F#0Ofo6EH_gxJ&*I>098Wdq1bvFiU_0=(s@jr_( z94e6_CMpxFax(P%VRnKs4$?fESohAZ#Bp zVjH`F55@>6b7YdHI`lwUNME#NI|LcRIAqkaeK-J_%c)AVg}@4^B~)UY(seo_0% z0EY{?r$`|&3d%s~4O5|)VbNfzU-kq8QvP7VZoMR zE@VL@n}Bj`*=-b}IW-YOh+@iT;h4TU#xedUFl9dvLXyNGY(llf;>mS{F`xkvLX#CG z*rnfL@%+6ACnO8>N)r)Xp*0bO2gNO>I65PyhyLl^02DB!BVq$V!ZI}x55!Y;Aao=S zMVdemC{qMRu6jf*1u%!MKoBlu9Tuo69PlKB^B1WvhCFgcWJy%Qc^2|JUOh!LXXmL_ zto67M+tK!62ib?XpB~Nt(NIg>5t@kO0DUnWw7riw*iu7bio6o9SVCW9Uvz|8$n1s$ zOws{i|JesVTqH1ji}x{z52(@^;gces;trjrDCUzM;~4*QSS$s^#EZCwtJ5`vu!;Aj zI=213FXS>j4BFs!fIB&wQD?rO&s52Ss4f@(ga*aV> zJr<*UG)ql>ZX9)R9>Gx!zaxG`kKr@RP^Aa|JWpASzX#USo1Z ztIO1y5~aFWsV-4#%2etyg|bwosz9m~!lw4tw5G;8&5d_kno=NuAz*h*Zfb+ANa<8ubc74O$ z?w)+TA&gD(-t6A)Ol(Q$$^grIvQRP>XZ3Vv_jKok8S-e(>gmb6&!Hwi6Mk^)kHg>T z@#%p-89hDeVTSw_z4yjA#{WFd>gmnu?9S-IMD5M#>dEQu$yKUKP3G{kz9wTe*kY~) zn@u%fmPfOhxXx^@4>RO3nKdQ-pA|=r{c$*|`M1m5MNOEcP9=`g2S=XqI*Vx(qwp(r zzAcXK>v0&fSDL`141(|5468*cJc7seXOx<$K7ymF9?2nt--$QgBpC6~~=pG-RN8A5){eK+azKQ*B z&g5YXn_@hgF*Bn0@oT>ej_U5w%uNtc%#wxCu^pxJ`26U$>;`xD==gsakGB8q`XA-q zm>zyZ`%lDC&A}*)VN;C9V44{ZPT$9`{Vq7F$4B#+{zw-7`QCmjJ$}3Xe-|D`a+Li? z^Qd)Yc-0xhrXM5Y+&>XVHGeciKYI2&p~6=(^q+{Mx_dN3e{?TV3KB~$eJjj1Bm3g+ zqSPLf+1hBEk>ycM9+RUCN;ad^zBZ4x{|Js@(@%<@?A(uP{%D4N!-HR5iLwyUJE?)c zMi-LtZ=EG)zOt7mb^9xM%pSjXFW;U2->#pd`71q-WGFxQ{ARd$44b}B<{t_Tz2hnL z)?IqL6RJWdX>8W(>5UQmY_>{;wuB?nbK2PQ&kpa3_cW0;?u%dWgc7ZI=bzN6c%Kwn z)rgrPu<1TL375pT*>X0aPOBm7##h!W8SwPGV-<`NjB*Mx}Ska2Mwgjd{_-wQ@>SPi{X z>>(UwTw-#S#{#qDwm4{H?f%&phX~ziLupQgS&1KJpN@$nu>X)@8LeRI{)80eF>Lxi znNF~H-?`P+YA`mK%#BuC3$|uUli=nt*=lX$uPWGV?JQUaMeL#@R8b*%H`H6KFx6x>V~bX8VI~WquFXv*bCb>1*4CO|RFvefcSFHq zfzEy3A{m{c2|9vtbb(HJmkbJqw{VqZb`@Jmz!rmIhRmau#?IR@nRRdkFvW%aW{0Dr ztu42>_!`0nXo6Y<2E!bLCq4c!2=`!wePCD75eqDfeo00l9|s&djGYbwS!ja5<#tCK zjt>O%$mfU~KER?JCkuzsYHe+6%P%Ut#t0>bAaG6m*r?SqVWf%A?ARP-Jj{I1;IK3h zbb-?igLGu9G?CC8hlmG4+X((j`!FjVF&6lsm6s>i)ujRf=?#kln;5)e*z|oeV-seZ z)7dFN0h5Db$zs9z!|9}wQH(R%%BTe9vun3^U>ac;0=B4SY(lNcgz_dd0i!v#Y?(_S z1TGOmsCNvU$8D9x}7R$W<8kh%Ngsm2>Z`fGxL$ zW0=HJbJj;8w%q(-ER4{Sgku%4WHdD#Jh)=*+RuFhy&4UD0|E!16b!T|e!}D5pb=jT z#K0i{r`T;tL251poMm1gg@(Y)a-=4oln2KZ{T3|@1Y3k|e8S50>!-@k0*#u)Dr&? zK?p?!heQViyMpFgn&E^K+?B*@AvA7fP z3OjTt7@Htt(T$}ycJCjP(M$j#IT_;cRKWoRc2Mestx}1jegCf|)P=4_p{O7jlCFi{ zHygSn|1b{KiWMlq5S<9wij|+9KC{K?!f@zIB2+6piDA?C$&5|B0_O?JvB9(XVT@X6 zVovkw9TOU%Xt#Hyrk-B2X4+^!An^T2LkFW0#vlMys;2o2O52Lm`Zygrk%l z5Lm+wAUrUc7@MjL#%fNT4jfp%bLYZfP{;7cW=Asz8x*8ygjaj^EMwo=+VYPaS{tTM&Ar04+z=Lc2#92HmMKNTF5?c4 z2}&Sii+)>M^Y-swfrdDVLXF3ct%OY&DKQTOE9*mtR&Clm%j4Pxf~~smU0K`GF?%kEs|OKa;5l=Fgl?@e8COG{o_VVbk}?j7^bw6HnjB zDL$HcCLx~rbLtE(SYd74IQxSSp1poOe$}d}2M(-sI=i5Z*$>!)K@J9oqZ7Msch9wJ z2PaK>2?EqOTA;%r#Jy15(wsviV>MT))mMN`X8ht+9X$Buu3d}#eib)-7_&ianc-)1 zbIyPNzy9}~I~OD80yvHz|2rNpoCG5{C9K3Qgbf>JwYTSE2I~#A^8V5)*)5|HW^0fQ zX|(W)pF|zS;;3@iP%sz}-m-)7$TeoTJ?(@|BJ<*(Xz&vre{n5F-?Vzw^qo7GUc9*X z*s;xfb}#SgDL0$>5;*<+5o{J0yv-IYX6dM+97mo<2m6qr>~eKiRo#8%m0xiaVV~fV zqdnsI)B6VS+h8=IN_Ob*D&$QrcV`G1#9!zjU>A@?*o3@k^z;3ZOua-73S5sY*lcdA zs=D{ut2i&s4tsY^P5LXZ{2D-JGB-M$?RrB!5CoadYvX@iU31s%?m~`+0Wvajj{u+t z&P4?C1A6??My>cC-k6ritA zR2@FN?#h+@nB~YmhKJOvS5IHHYFaR8xOidj#~;7sam&@Jy5t+jt|T6+ugkUDdfVGd z5--PJzjj!usJ(VIVba8L!^3K1TRlA`h$6BtlJ>BBl7JuWO0Zg8X)*&QD)t{lzOZO; zP>l&4_Euu{lN##j&tdcf2sJDdtk%xfmcsw~U;pdV|bhs)$cmym8Y^U@>PR`1KYCpPYZv<8LrD>GX}y|LxzaWcM7-Zs1f_ z_GPWEsj)Hla^k`3*N%jn%lTTc| zdbqJEzo8-L#TS18gE|1B9)}lQh_QsO`h^As1{?#MkiY_GH*K1Y9~B%2eoFznCk{BW zOQ4=On{4NyEDZ`Q&YiZwHFj`HnrQV9TBk+tro#Fji82v<-&zsSiaTOri-;e{qV46%jN}d zzx9{I%LiAlo*92|gTvmZRyD0#Gk5jMxtlgDt*E@fFF1F0-}!TUCry00 zxHx&oj>UjEbc)|Svl%g8DSqEDdwABOQ^qE&=HOnf!Bl!6e*TW_OZ-DdjasA_(bvww zVqVfk5OD#86q=2Oj{4fX*Ixbe>eX}i?c3PVA$$3iKiO=Gd-oFOFPO4s&HQD{W|ows zeKBWJTYDuG4#sbJ;f3FC-n_(OL4wev(>C6{duro`FUm@9)2b@eVRSzCu16F5NOUL6Me=V@d)TA>sy!7%fs;city z7A~BMA#d2QC^PfwtFJw+)i)VTEm{M8K%24;_@-?p4h;$e!Fb^wa>mN|gr%D{ec^WX zajk%08Zw;6j{z_XQzG2(F`1gO` zQ&z2-^W~Sbi;Gh~{&@V+V>@4a?XPihE7q)?d+x$MoxWLTXw+a)M*feo9A@Dvr?i;) zGLspJUipfZAD=n9(e3WUkq7S6q|(t}31iswee&1CCafKjlaDN3Jh8bc2W=6zIGxC1 zfKB6Hd+N;TUCWnEJ$@|C?NZd$<}P14{mW%DpZ>$Y9zVM4qYqzgZY-{rWoKqwIe%{7 zbI<Rzi-~Mbll5N*VN>nJhcZ=y>!{<35T}y_cz|UeZH(bWBmAM zKL7mv6)V1Y_0>P0J-7djxBjBmHo&Y#SFh%k5q#4Ej+;cM>?+1mOJ5?P9B>KpCbz3s zlz&^;#1@(w8*+h7JGZYqux}%N)t>$9FNcSXbLLL?$3OnIa@7~`{KUzMJTZQF{s z-uhc_UtMbIr8nRDE7C?_E8t0`#tIY$;d7+r5CfG2HlduBbzy9paOUi$7&iT|`0HVl z-QJavabe|(&+~GxIvqVYkxFH)e^|F>^-Q1=AnEd@_z54sG7>N?UpD>7;kcx0CtrB} zw{crnyz%<8UXRx6(Ezh9T|DsjSAM^9=klbaBUTFljxIeSXQ(sYy3ZY>QiV z^VaFovXo!`>i?WE^L=@L?aQzHp|LUFWNOo>>&&J$IC=c|=55>Nx3?EqEUgdr8_9H( zM5KKu*rYcgM`(KHxqq#1%yGKNnMMvgx05I6bm%sj-&d>~OQfY8(*?%#FQ7o{DCI$u- z#-@rDD<+*ev&HT1ieb|ah{wVv%ri-0^f{&}DAJJj^t5xEH_a_5xNb7F>UGV71L}3_ zzWDg#aW|7s#%)`+al?F%TQzUa#G^;zl5d_ znfB64zc!iLZH}IQyz}fYfBj#41M2k~=5E=#=+^C12M(^y&bhjH$){JYCM;bx<@kxX z)oW&*JHN+j?NF(z;ojM^+qZ3-*VR=d0F>Q}>^kyrp*#|siVr5tzmHAiBs8Hj8k@f2 z_ye2NnmXXf+<6}!KDz1Z^~0C1#K#}nkbLvRjG6Bx-#m5b@Rqm#@f;R+8#gTq25slg zANYLQJMjq{H*H#U^X8d-`_^aYBrjb${m|h!<;_vSnAzO;AWh8JG^-K|?^;}bT`UpUcdZUbJE|MYi595g<{QAdw5 zCO{Hl6aBTc%4Dvkyy*dKYQ!%YeuOZV7&d*MJPMomhebN0qt7lF3iT!m)^tf=1mJ1F8H*p^j>k%?e**CY}z<4 zH|J_z?zQ;%wLYIBCnxdrsW|*hY3Y_iY|(|l7txp4VkT9I2$8U9K?F7-{@F3O$_+(0 zkv@d*)e~KV$=KS|l(%i$BCW0wv7M89Wy7Yq24hQ8OWvM+D>iSLfB5Le&aTqUTjy)_ zjn{7+K6`#wU47QEU2cO_Z5Fh)ta)6B^$4`7xRQ*w@)vxMj;+{Qlu50p}|&Zi(64 z(b$x~|G+wo>%hT{9UYY?PVPE(e8(?;^6a2tA#%Y5x@^)ks?d^pY zObfadu%*9W*4UU+SDV$+Twu5Lh#%hO)|SHh`mE;WJe3L^b=1{m)Y9ei7Nt_w-CfF) z081pyY|IIo-*kTp_lsT3cx)wX!tAfRk4?jo*cA4b(j@^*#MMSqol-@&CedG%=r*7F z&dw60s@iO6K?2ezuYhc^wsv$D%Bt^mb(feet-XC^N|g-d{fa8+w09J!HPr| zEyrR(awjvH_{TYt*=I0hI!a?;(h7L$ATJJkUmvp0rq;H?#>TwP&T@;T%V=zGXvnLn z%~mSw4ThHPo-z#%4zdPgg9be^tP?ghh~o)tVh50wU@YbFhZa2?n`$0{O+1RIu}Dni zbV%{rW2i@F3Tt4Ms-~-}1V369OM7EuZc|f!dwZ$X+HEp*T)A@SlTTjj>8+B<(#)1N zpgjDiKQhvv;lwm};OH^)GGC@Q(4e%siU@4l7RDybL#WZbiec0D$&bV)>Fn|ej%X_wP=`hxah9M(4&r4OB>D(KnKxoHn*W) zY?Vs7hZdURZb=GV>1Y%4@gxT**P!*OsqEp{M1k#ec02@|#u!VOsTK=xI{UgBlbIgq zrBg#^fquQfuy3<xqKI2vM7BcH4!=}<3m<;a=!c8GLyw?ED2lBC@I*4rEs<}FpFWO2 zKvk$jug8>aU~JmCbLr5a4oL^*P=u4=c`2B`a1XP>PxMQ-Yh&Q_$VlilLv#=@9kDBJ zuoQ2}(4ZlF25KX{YJvdYFiak@9Gu_`L#)9T_t_2X&ec?8HE5L=0faKNvQ7}v8kxV}G zp(dB;=Y*7LAOwH#kbY6XNRD`F(b?4F2cuD-36$xii=2ojz!)cp?}Nn{@q?iwoTW*! zYW3t3CpLS%J>tw(t2Gq{V=YqS7&iU$ScKdIyO`oQ%~oqGegnl%AAVh%5XNGz)3gXP z{ho)J{*WxrZWM>(Hi|>a__2!Q$c7RN3zBi_i=ZdeBh5~F6O+kOc`#w&o;_b8Z{kc! zxEIykgEk-V|3UrlfN|)=J;#I{*b+9GOAj4cykWx^ZkJNTJpYDMDu-QUI!|)^AM`(Z zyiq*n(dJ_k)mAz+%+R4cD5OI@!X*r(+H9>l7{6%Swz)1Bf|MJU4XJ=o`$~vEub0IhHVrJHvy!;E{txt zQ`xyE1w#Oj*;cY3jFWr;F42}cMftg$oXeS+=L$>CY})eKhV`?Xn+nP2>_`v6Qoj;Q zRg(YT5r^z&Wl^Vj`Iq24j%Rkx>D+>2o3>0|zwQfCZ8R_u$+B~IMfC8o|AhnC+|!_(V5k2CT!a_&+Y0JOD&Nh5^~k5)%1&^ zR92RiC#R*s2)jBa^FT00iKU@|9~@e=pO5yRYtcNaFU%jdPsVd{&tNRMd1vzS&ds0y z?x|Coy`B!0s>EojwA!j`>yj%gug9?IpU0Rt*y0Bb%)3}Ym`shewP}0zF2^t7?mdg+ z;^yt%y=cdd`8#*c-!TR+5ZgIBc71W5u}eJnAq?f&J9fg!$XI&)c(S@%HWTdEw4o zbN3ybvv}!0jvw3Ru=mroA+d~ADl3d89RH>#JpOz%B9B-ki=!8HkiQ0_iye!JsV~^1 zu6OQS5Vw8y{)6+DEr0Lm(e-v)mqtUtDpptxz$Pp+vBD}SNW`e)w$mwlB!`b!B-7|n z6*<5s91-b9c75M6{0|lGAp1BkyLQjry?fr`MIR*JIN-21n9WsYb9q}EekYD}cW1@0 z>7U4>@+Mkw7#dnyax*i}XJwts%e#c%mYm%4_}!)-N&LJJLy#Ch?B{ZF#m~-t#_ppT zI;RCkwqh0vk-bof(4@XDB99O*LE(H(c4B^hVrqJPLDA{l+{B#hYq`0XkT(gx9H~Po5__AMe=$272lHZPCbAFwR-Y*>K9!kuw5B@KZ0uIkdq@bIwBkjP zI0a95{K0&b!W^v=QFWgqkNH8EfI9`tH7M;$kbqsAEJ+gGx5G)CJGTPEY7X`GvTHY@W~S7(mR zR%^9ZHZ@-_DLvWRdP}1zj$zaH$^xyBnL8XEW_pQjz17xiu{N2_4HiqI#o9m&;XCIh z!Te6uCX2P6_<<6*(PT7;C+V#+yR(-5{Acd8(hFy)Dy;c1X8WW2dK`{y8_5r|(`2U? zKT<7X6(uHft;Jqtu~wT+9U3*g3Qni1R%@zow1G`(`Xs?OJpK>!gqdrjnmmHhX&v=T zN4QPw(%&xmkF9n`i^)=r5g855dR>cnu^(L)P^mDS1^|;vU4=oRN2~R5I(?YuVV@uO z2#n^3TegyKEdMi~a^LSQcjbi;rN+yuLA0*I}kVrH7cRDg{S&M1MQeYUw?hMsuakP==^L zY#^|uKi@nChy2%JN&6%$HGGiSX5=UY(@{lQO7|!rp}-;4Xe)Kb5{<6ZXlPT&5e%&w ztxTaThYtO%joxJTWXC_sJ)O2zr>z^s^N9chQ_2AHhu3*KYeu0FumwI z6EckkKYb|SKg3oEj=Wn0fk#&v9?3LWAM7GZK`^}@K-_#B$xx;q`E3N;oc``hk*pUl zKQojOQ*1O*v>2oMdNdPi=#eUFADct1q~Y@sh_o3sI>JhLrB;jk5@@|sX|$9Bn{?V{ zrJ~V9uWhKpnvU zjPXB<#r&WM)K+WMRXV<-AJc;F=!s%6pR`Y$cRYk2_^pdz^j;-c>InVf#}m6e=PLC2 zO2mVfF2q8gt0c3JV0IpJ9gGNnOct$p?DvlVILde=R~z)TIGB7?wVFzUp;D`@(9;tt z2oL;v%S_0a*z+ep{-Zp65KM^yUUhnnV3JW1)g+1|+oE^TUFdXhrx+C0{-Y^paJWi73@^YRaMcHiphyTAIobtM6lzP7zBEhqOtXV3M1<(>S(gN@CJ8f{KV>FLVK@bxB>u{y>vj&Y2?J2o1? zw1U&?kkVE<9Ze`~YP{XrcEjZ^@9w?b+;YuoD^(~m8yb_;nxYUk#VAHGiqQ{?{?mW@ Z{{yVFQ$#+Xs)hgn002ovPDHLkV1g9&3}^rV literal 0 HcmV?d00001 diff --git a/_static/images/SAP_BO_2.png b/_static/images/SAP_BO_2.png new file mode 100644 index 0000000000000000000000000000000000000000..91bc53d1a98462d50718f5cada0b2149d55b04bb GIT binary patch literal 25160 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 }(bbAR8C%mz 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 Date: Thu, 21 Jul 2022 15:02:28 +0300 Subject: [PATCH 142/316] Moved Hardware Guide to Getting Started --- {operational_guides => getting_started}/hardware_guide.rst | 0 getting_started/index.rst | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) rename {operational_guides => getting_started}/hardware_guide.rst (100%) diff --git a/operational_guides/hardware_guide.rst b/getting_started/hardware_guide.rst similarity index 100% rename from operational_guides/hardware_guide.rst rename to getting_started/hardware_guide.rst diff --git a/getting_started/index.rst b/getting_started/index.rst index e799d047a..87b98870d 100644 --- a/getting_started/index.rst +++ b/getting_started/index.rst @@ -12,4 +12,5 @@ The **Getting Started** page describes the following things you need to start us preparing_your_machine_to_install_sqream installing_sqream executing_statements_in_sqream - performing_basic_sqream_operations \ No newline at end of file + performing_basic_sqream_operations + hardware_guide \ No newline at end of file From f7cb29376a22d163b8ff7427e7777234795b19fe Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 24 Jul 2022 17:07:39 +0300 Subject: [PATCH 143/316] TPD-233 --- operational_guides/access_control.rst | 81 ++++++++----------- .../alter_default_permissions.rst | 3 +- .../access_control_commands/grant.rst | 43 +++++----- 3 files changed, 61 insertions(+), 66 deletions(-) diff --git a/operational_guides/access_control.rst b/operational_guides/access_control.rst index 7f92f8eaf..ffe687213 100644 --- a/operational_guides/access_control.rst +++ b/operational_guides/access_control.rst @@ -4,61 +4,42 @@ Access Control ************** -.. contents:: In this topic: +.. contents:: :local: + :depth: 1 Overview ========== +Access control provides authentication and authorization in SQream DB. SQream DB manages authentication and authorization using a role-based access control system (RBAC), like ANSI SQL and other SQL products. -Access control provides authentication and authorization in SQream DB. +SQream DB has a default permissions system which is inspired by Postgres, but with more power. In most cases, this allows an administrator to set things up so that every object gets permissions set automatically. In SQream DB, users log in from any worker which verifies their roles and permissions from the metadata server. Each statement issues commands as the currently logged in role. -SQream DB manages authentication and authorization using a role-based access control system (RBAC), like ANSI SQL and other SQL products. +Roles are defined at the cluster level, meaning they are valid for all databases in the cluster. To bootstrap SQream DB, a new install will always have one ``SUPERUSER`` role, typically named ``sqream``. To create more roles, you should first connect as this role. -SQream DB has a default permissions system which is inspired by Postgres, but with more power. In most cases, this allows an administrator to set things up so that every object gets permissions set automatically. +The following: -In SQream DB, users log in from any worker which verifies their roles and permissions from the metadata server. Each statement issues commands as the currently logged in role. +* **Role** - a role can be a user, a group, or both. Roles can own database objects (e.g. tables), and can assign permissions on those objects to other roles. Roles can be members of other roles, meaning a user role can inherit permissions from its parent role. -Roles are defined at the cluster level, meaning they are valid for all databases in the cluster. + :: -To bootstrap SQream DB, a new install will always have one ``SUPERUSER`` role, typically named ``sqream``. To create more roles, you should first connect as this role. +* **Authentication** - verifying the identity of the role. User roles have usernames (:term:`role names`) and passwords. + :: -Terminology -================ +* **Authorization** - checking the role has permissions to do a particular thing. The :ref:`grant` command is used for this. -Roles ----------- - -:term:`Role` : a role can be a user, a group, or both. - -Roles can own database objects (e.g. tables), and can assign permissions on those objects to other roles. - -Roles can be members of other roles, meaning a user role can inherit permissions from its parent role. - -Authentication --------------------- - -:term:`Authentication` : verifying the identity of the role. User roles have usernames (:term:`role names`) and passwords. - - -Authorization ----------------- - -:term:`Authorization` : checking the role has permissions to do a particular thing. The :ref:`grant` command is used for this. - - -Roles +Managing Roles ===== +Roles are used for both users and groups. Roles are global across all databases in the SQream DB cluster. To use a ``ROLE`` as a user, it should have a password, the login permission, and connect permissions to the relevant databases. -Roles are used for both users and groups. +The Roles section describes the following role-related operations: -Roles are global across all databases in the SQream DB cluster. - -To use a ``ROLE`` as a user, it should have a password, the login permission, and connect permissions to the relevant databases. +.. contents:: + :local: + :depth: 1 -Creating new roles (users) +Creating New Roles (Users) ------------------------------ - A user role can log in to the database, so it should have ``LOGIN`` permissions, as well as a password. For example: @@ -81,7 +62,7 @@ Examples: A database role may have a number of permissions that define what tasks it can perform. These are assigned using the :ref:`grant` command. -Dropping a user +Dropping Users --------------- .. code-block:: postgres @@ -94,7 +75,7 @@ Examples: DROP ROLE admin_role ; -Altering a user name +Altering a User Name ------------------------ Renaming a user's role: @@ -111,7 +92,7 @@ Examples: .. _change_password: -Changing user passwords +Changing User Passwords -------------------------- To change a user role's password, grant the user a new password. @@ -122,7 +103,7 @@ To change a user role's password, grant the user a new password. .. note:: Granting a new password overrides any previous password. Changing the password while the role has an active running statement does not affect that statement, but will affect subsequent statements. -Public Role +Altering Public Role Permissions ----------- There is a public role which always exists. Each role is granted to the ``PUBLIC`` role (i.e. is a member of the public group), and this cannot be revoked. You can alter the permissions granted to the public role. @@ -130,7 +111,7 @@ There is a public role which always exists. Each role is granted to the ``PUBLIC The ``PUBLIC`` role has ``USAGE`` and ``CREATE`` permissions on ``PUBLIC`` schema by default, therefore, new users can create, :ref:`insert`, :ref:`delete`, and :ref:`select` from objects in the ``PUBLIC`` schema. -Role membership (groups) +Altering Role Membership (Groups) ------------------------- Many database administrators find it useful to group user roles together. By grouping users, permissions can be granted to, or revoked from a group with one command. In SQream DB, this is done by creating a group role, granting permissions to it, and then assigning users to that group role. @@ -174,6 +155,7 @@ Removing users and permissions can be done with the ``REVOKE`` command: Permissions =========== +The following table displays the access control permissions: .. list-table:: :widths: auto @@ -226,6 +208,10 @@ Permissions * - table - ``INSERT`` - :ref:`insert` into the table + + * - table + - ``UPDATE`` + - :ref:`update` the value of certain columns in existing rows without creating a table * - table - ``DELETE`` @@ -254,7 +240,7 @@ Permissions GRANT ----- -:ref:`grant` gives permissions to a role. +:ref:`grant` gives permissions to a role, shown in the following syntax example: .. code-block:: postgres @@ -296,8 +282,8 @@ GRANT GRANT [, ...] TO WITH ADMIN OPTION - -``GRANT`` examples: + +The following are some ``GRANT`` examples: .. code-block:: postgres @@ -324,7 +310,7 @@ GRANT REVOKE ------ -:ref:`revoke` removes permissions from a role. +:ref:`revoke` removes permissions from a role, shown in the following syntax example: .. code-block:: postgres @@ -372,7 +358,7 @@ Examples: REVOKE CREATE FUNCTION FROM admin; -Default permissions +Default Permissions ------------------- The default permissions system (See :ref:`alter_default_permissions`) @@ -403,6 +389,7 @@ schema statement is run. | USAGE | SELECT | INSERT + | UPDATE | DELETE | DDL | EXECUTE diff --git a/reference/sql/sql_statements/access_control_commands/alter_default_permissions.rst b/reference/sql/sql_statements/access_control_commands/alter_default_permissions.rst index 0ab200286..a49e53f88 100644 --- a/reference/sql/sql_statements/access_control_commands/alter_default_permissions.rst +++ b/reference/sql/sql_statements/access_control_commands/alter_default_permissions.rst @@ -43,6 +43,7 @@ The following is the syntax for altering default permissions: | USAGE | SELECT | INSERT + | UPDATE | DELETE | DDL | EXECUTE @@ -103,7 +104,7 @@ The following is an example of the output generated from the above queries: | master | NULL | public | public | select | +-----------------------+----------------------+-------------------+--------------+------------------------------+ -For more information about default permissions, see `Default Permissions `_. +For more information about default permissions, see `Default Permissions `_. Granting Automatic Permissions for Newly Created Schemas ------------------------------------------------- diff --git a/reference/sql/sql_statements/access_control_commands/grant.rst b/reference/sql/sql_statements/access_control_commands/grant.rst index ceac48f7a..d86522900 100644 --- a/reference/sql/sql_statements/access_control_commands/grant.rst +++ b/reference/sql/sql_statements/access_control_commands/grant.rst @@ -15,13 +15,9 @@ Learn more about the permission system in the :ref:`access control guide Date: Sun, 24 Jul 2022 17:24:04 +0300 Subject: [PATCH 144/316] Removed HW Guide from Index --- operational_guides/index.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/operational_guides/index.rst b/operational_guides/index.rst index aca578e8b..9deb0835c 100644 --- a/operational_guides/index.rst +++ b/operational_guides/index.rst @@ -24,4 +24,3 @@ This section summarizes the following operational guides: seeing_system_objects_as_ddl configuration optimization_best_practices - hardware_guide From 37f40386591f873b287020ec0c6864a5acd0164f Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 26 Jul 2022 10:25:02 +0300 Subject: [PATCH 145/316] Removed internal items. --- reference/sql/sql_statements/index.rst | 4 - .../get_extents_file_list_for_chunk.rst | 107 ------------- .../get_metadata_chunk_key.rst | 151 ------------------ releases/2022.1.rst | 11 -- 4 files changed, 273 deletions(-) delete mode 100644 reference/sql/sql_statements/utility_commands/get_extents_file_list_for_chunk.rst delete mode 100644 reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst diff --git a/reference/sql/sql_statements/index.rst b/reference/sql/sql_statements/index.rst index 1a075f69e..d2b92b152 100644 --- a/reference/sql/sql_statements/index.rst +++ b/reference/sql/sql_statements/index.rst @@ -108,10 +108,6 @@ The following table shows the Utility commands: - Usage * - :ref:`EXPLAIN` - Returns a static query plan, which can be used to debug query plans - * - :ref:`GET_EXTENTS_FILE_FOR_CHUNK` - - Points to all files that contain data related to a specific chunk |icon-new_2022.1| - * - :ref:`GET_METADATA_CHUNK_KEY` - - Returns a list of metadata key values for the chunks that you specify |icon-New_Dark_Gray| * - :ref:`SELECT GET_LICENSE_INFO` - View a user's license information * - :ref:`SELECT GET_DDL` diff --git a/reference/sql/sql_statements/utility_commands/get_extents_file_list_for_chunk.rst b/reference/sql/sql_statements/utility_commands/get_extents_file_list_for_chunk.rst deleted file mode 100644 index 968c0655a..000000000 --- a/reference/sql/sql_statements/utility_commands/get_extents_file_list_for_chunk.rst +++ /dev/null @@ -1,107 +0,0 @@ -.. _get_extents_file_list_for_chunk: - -******************** -GET_EXTENTS_FILE_FOR_CHUNK -******************** -The ``GET_EXTENTS_FILE_FOR_CHUNK`` |icon-new_2022.1| command points to all files that contain data related to a specific chunk. This command is used for debugging purposes. - -.. |icon-new_2022.1| image:: /_static/images/new_2022.1.png - :align: middle - :width: 110 - -This reference page includes the following information: - -.. contents:: - :local: - :depth: 1 - -Syntax -========== -The following is the syntax for the ``GET_EXTENTS_FILE_FOR_CHUNK`` command: - -.. code-block:: postgres - - select get_extents_file_list_for_chunk(database_name, " - "table_id, chunk_id);" - -Parameters -============ -The following table shows the ``GET_EXTENTS_FILE_FOR_CHUNK`` parameters: - -.. list-table:: - :widths: 10 100 - :header-rows: 1 - - * - Parameter - - Description - * - ``database_name`` - - The name of the database where the chunk is located. - * - ``table_id`` - - The ID of the table where the chunk is located. - * - ``chunk_id`` - - The ID of the chunk. - -Example -=========== -The following is an example of the ``GET_EXTENTS_FILE_FOR_CHUNK`` command: - -.. code-block:: postgres - - master=> select get_extents_file_list_for_chunk('master', 0, 3); - -Output -========== -The following table describes the output generated from the ``GET_EXTENTS_FILE_FOR_CHUNK`` command: - -.. list-table:: - :widths: 25 25 25 25 - :header-rows: 1 - - * - Parameter - - Description - - Type - - Example - - * - ``database_name`` - - The name of the database where the chunk is located. - - Text - - ``master`` - - * - ``table_name`` - - The ID of the table where the chunk is located. - - Numeric - - ``0`` - - * - ``table_id`` - - The ID of the column. - - Numeric - - ``0`` - - * - ``column_id`` - - The status of the chunk. - - Numeric - - ``1`` - - * - ``chunk_id`` - - Describes the state of the chunk. - - Numeric - - ``chunk_state::`` - - * - ``file_path`` - - Shows the path of the file. - - Text - - /home/sqream_testing_temp/sqreamdb/databases/master/tables - -The following is an example of the output generated from the ``GET_EXTENTS_FILE_FOR_CHUNK`` command: - -.. code-block:: postgres - - master,public.t_1,0,0,3,/home/sqream_testing_temp/sqreamdb/databases/master/tables - master,public.t_1,0,1,3,/home/sqream_testing_temp/sqreamdb/databases/master/tables - master,public.t_1,0,2,3,/home/sqream_testing_temp/sqreamdb/databases/master/tables - master,public.t_1,0,3,3,/home/sqream_testing_temp/sqreamdb/databases/master/tables - master,public.t_1,0,4,3,/home/sqream_testing_temp/sqreamdb/databases/master/tables - -Permissions -============= -The ``GET_EXTENTS_FILE_FOR_CHUNK`` requires no special permissions. \ No newline at end of file diff --git a/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst b/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst deleted file mode 100644 index 784a54246..000000000 --- a/reference/sql/sql_statements/utility_commands/get_metadata_chunk_key.rst +++ /dev/null @@ -1,151 +0,0 @@ -.. _get_metadata_chunk_key: - -******************** -GET_METADATA_CHUNK_KEY -******************** -The ``GET_METADATA_CHUNK_KEY`` |icon-new_2022.1| command returns specific metadata key values for user-specified chunks. - -.. |icon-new_2022.1| image:: /_static/images/new_2022.1.png - :align: middle - :width: 110 - -This reference page includes the following information: - -.. contents:: - :local: - :depth: 1 - -Syntax -========== -The following is the syntax for the ``GET_METADATA_CHUNK_KEY`` command: - -.. code-block:: postgres - - get_metadata_chunk_key(database_name, table_id, chunk_id); - -Parameters -============ -The following table shows the ``GET_METADATA_CHUNK_KEY`` parameters: - -.. list-table:: - :widths: 10 100 - :header-rows: 1 - - * - Parameter - - Description - * - ``database_name`` - - The name of the database where the chunk is located. - * - ``table_id`` - - The ID of the table where the chunk is located. - * - ``chunk_id`` - - The ID of the chunk. - -Example -=========== -The following is an example of the ``GET_METADATA_CHUNK_KEY`` command: - -.. code-block:: postgres - - master=> select get_metadata_chunk_key('master', 0, 1); - -Output -========== -The following table describes the output generated from the ``GET_METADATA_CHUNK_KEY`` command: - -.. list-table:: - :widths: 25 25 25 25 - :header-rows: 1 - - * - Parameter - - Description - - Type - - Example - - * - ``database_name`` - - The name of the database where the chunk is located. - - Text - - ``master`` - - * - ``table_id`` - - The ID of the table where the chunk is located. - - Numeric - - ``0`` - - * - ``column_id`` - - The ID of the column. - - Numeric - - ``0`` - - * - ``chunk_status`` - - The status of the chunk. - - Numeric - - ``1`` - - * - ``chunk_aligned`` - - Describes the state of the chunk. - - Text - - ``chunk_state::`` - - * - ``offset_in_file`` - - Shows the file's offset setting. - - Numeric - - ``-1`` - - * - ``compressed_size`` - - Shows the file's compressed size. - - Numeric - - ``0`` - - * - ``uncompressed_size`` - - Shows the file's uncompressed size. - - Numeric - - ``2`` - - * - ``compression_type`` - - Shows the file's compression type. - - Numeric - - ``2`` - - * - ``min_long`` - - Shows the minimum value of the type. - - Long - - ``25`` - - * - ``max_long`` - - Shows the maximum value in the chunk of a number. - - Long - - ``12345`` - - * - ``min_string_max_string`` - - Shows the minimum value of the string type. - - String - - ``"abc"`` - - * - ``min_numeric`` - - Shows the minimum value of the numeric type in the chunk. - - Numeric - - ``12.22`` - - * - ``max_numeric`` - - Shows the maximum value of the numeric type in the chunk. - - Numeric - - ``555.22`` - - * - ``column_aligned`` - - Relevant to text columns, aligment in memory. - - Boolean - - ``Yes`` / ``No`` - -The following is an example of the output generated from the ``GET_METADATA_CHUNK_KEY`` command: - -.. code-block:: postgres - - master,0,0,1,chunk_state::clean,1,0,2,2,flat,0,0,,,0x7f722ffb7c60,0x7f722ffb7c70,1 - master,0,1,1,chunk_state::clean,1,0,8,8,flat,1,2,,,0x7f722ffb7c60,0x7f722ffb7c70,1 - master,0,2,1,chunk_state::clean,1,0,2,2,flat,0,0,,,0x7f722ffb7c60,0x7f722ffb7c70,1 - master,0,3,1,chunk_state::clean,1,0,8,8,flat,3,3,,,0x7f722ffb7c60,0x7f722ffb7c70,1 - master,0,4,1,chunk_state::clean,1,0,16,16,flat,0,0,abc,dfg,0x7f722ffb7c60,0x7f722ffb7c70,1 - -Permissions -============= -The ``GET_METADATA_CHUNK_KEY`` requires no special permissions. \ No newline at end of file diff --git a/releases/2022.1.rst b/releases/2022.1.rst index f02676c34..3c5ae24e6 100644 --- a/releases/2022.1.rst +++ b/releases/2022.1.rst @@ -16,7 +16,6 @@ The 2022.1 Release Notes describes the following: * Enhanced security features. * New data manipulation command. * Additional data ingestion format. -* New utility commands. New Features ---------- @@ -46,16 +45,6 @@ SQream now supports ingesting data from Avro files. For more information, see `Inserting Data from Avro `_. -New Utility Commands -************ -The following two new utility commands have been created: - -* `GET EXTENTS FILE FOR CHUNK `_ - points to all files that contain data related to a specific chunk. This command is used for debugging purposes. - - :: - -* `GET_METADATA_CHUNK_KEY `_ - returns specific metadata key values for user-specified chunks. - Known Issues --------- The following table lists the known issues for Version 2022.1: From ab2544bca967738da725b715b8fd76f937e397ca Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 26 Jul 2022 14:38:05 +0300 Subject: [PATCH 146/316] Corrected the links. --- configuration_guides/admin_cluster_flags.rst | 2 +- configuration_guides/admin_regular_flags.rst | 48 +++++++++---------- configuration_guides/admin_worker_flags.rst | 8 ++-- .../generic_regular_flags.rst | 26 +++++----- configuration_guides/generic_worker_flags.rst | 2 +- 5 files changed, 43 insertions(+), 43 deletions(-) diff --git a/configuration_guides/admin_cluster_flags.rst b/configuration_guides/admin_cluster_flags.rst index 3c74819d6..f17cee34a 100644 --- a/configuration_guides/admin_cluster_flags.rst +++ b/configuration_guides/admin_cluster_flags.rst @@ -6,4 +6,4 @@ Cluster Administration Flags The **Cluster Administration Flags** page describes **Cluster** modification type flags, which can be modified by administrators on a session and cluster basis using the ``ALTER SYSTEM SET`` command: -* `Persisting Your Cache Directory `_ \ No newline at end of file +* `Persisting Your Cache Directory `_ \ No newline at end of file diff --git a/configuration_guides/admin_regular_flags.rst b/configuration_guides/admin_regular_flags.rst index 5300310b6..064fc4b1a 100644 --- a/configuration_guides/admin_regular_flags.rst +++ b/configuration_guides/admin_regular_flags.rst @@ -5,27 +5,27 @@ Regular Administration Flags ************************* The **Regular Administration Flags** page describes **Regular** modification type flags, which can be modified by administrators on a session and cluster basis using the ``ALTER SYSTEM SET`` command: -* `Setting Bin Size `_ -* `Setting CUDA Memory `_ -* `Limiting Runtime to Utility Functions `_ -* `Enabling High Bin Control Granularity `_ -* `Reducing CPU Hashtable Sizes `_ -* `Setting Chunk Size for Copying from CPU to GPU `_ -* `Indicating GPU Synchronicity `_ -* `Enabling Modification of R&D Flags `_ -* `Checking for Post-Production CUDA Errors `_ -* `Enabling Modification of clientLogger_debug File `_ -* `Activating the NVidia Profiler Markers `_ -* `Appending String at End of Log Lines `_ -* `Monitoring and Printing Pinned Allocation Reports `_ -* `Increasing Chunk Size to Reduce Query Speed `_ -* `Adding Rechunker before Expensing Chunk Producer `_ -* `Setting the Buffer Size `_ -* `Setting Memory Used to Abort Server `_ -* `Splitting Large Reads for Concurrent Execution `_ -* `Setting Worker Amount to Handle Concurrent Reads `_ -* `Setting Implicit Casts in ORC Files `_ -* `Setting Timeout Limit for Locking Objects before Executing Statements `_ -* `Interpreting Decimal Literals as Double Instead of Numeric `_ -* `Interpreting VARCHAR as TEXT `_ -* `VARCHAR Identifiers `_ +* `Setting Bin Size `_ +* `Setting CUDA Memory `_ +* `Limiting Runtime to Utility Functions `_ +* `Enabling High Bin Control Granularity `_ +* `Reducing CPU Hashtable Sizes `_ +* `Setting Chunk Size for Copying from CPU to GPU `_ +* `Indicating GPU Synchronicity `_ +* `Enabling Modification of R&D Flags `_ +* `Checking for Post-Production CUDA Errors `_ +* `Enabling Modification of clientLogger_debug File `_ +* `Activating the NVidia Profiler Markers `_ +* `Appending String at End of Log Lines `_ +* `Monitoring and Printing Pinned Allocation Reports `_ +* `Increasing Chunk Size to Reduce Query Speed `_ +* `Adding Rechunker before Expensing Chunk Producer `_ +* `Setting the Buffer Size `_ +* `Setting Memory Used to Abort Server `_ +* `Splitting Large Reads for Concurrent Execution `_ +* `Setting Worker Amount to Handle Concurrent Reads `_ +* `Setting Implicit Casts in ORC Files `_ +* `Setting Timeout Limit for Locking Objects before Executing Statements `_ +* `Interpreting Decimal Literals as Double Instead of Numeric `_ +* `Interpreting VARCHAR as TEXT `_ +* `VARCHAR Identifiers `_ diff --git a/configuration_guides/admin_worker_flags.rst b/configuration_guides/admin_worker_flags.rst index 2be570695..cd1a527d5 100644 --- a/configuration_guides/admin_worker_flags.rst +++ b/configuration_guides/admin_worker_flags.rst @@ -5,7 +5,7 @@ Worker Administration Flags ************************* The **Worker Administration Flags** page describes **Worker** modification type flags, which can be modified by administrators on a session and cluster basis using the ``ALTER SYSTEM SET`` command: -* `Setting Total Device Memory Usage in SQream Instance `_ -* `Enabling Manually Setting Reported IP `_ -* `Setting Port Used for Metadata Server Connection `_ -* `Assigning Local Network IP `_ \ No newline at end of file +* `Setting Total Device Memory Usage in SQream Instance `_ +* `Enabling Manually Setting Reported IP `_ +* `Setting Port Used for Metadata Server Connection `_ +* `Assigning Local Network IP `_ \ No newline at end of file diff --git a/configuration_guides/generic_regular_flags.rst b/configuration_guides/generic_regular_flags.rst index f8235ae07..83afa9e8f 100644 --- a/configuration_guides/generic_regular_flags.rst +++ b/configuration_guides/generic_regular_flags.rst @@ -6,16 +6,16 @@ Regular Generic Flags The **Regular Generic Flags** page describes **Regular** modification type flags, which can be modified by standard users on a session basis: -* `Flipping Join Order to Force Equijoins `_ -* `Determining Client Level `_ -* `Setting CPU to Compress Defined Columns `_ -* `Setting Query Memory Processing Limit `_ -* `Setting the Spool Memory `_ -* `Setting Cache Partitions `_ -* `Setting Cache Flushing `_ -* `Setting InMemory Spool Memory `_ -* `Setting Disk Spool Memory `_ -* `Setting Spool Saved File Directory Location `_ -* `Setting Data Stored Persistently on Cache `_ -* `Setting Persistent Spool Saved File Directory Location `_ -* `Setting Session Tag Name `_ \ No newline at end of file +* `Flipping Join Order to Force Equijoins `_ +* `Determining Client Level `_ +* `Setting CPU to Compress Defined Columns `_ +* `Setting Query Memory Processing Limit `_ +* `Setting the Spool Memory `_ +* `Setting Cache Partitions `_ +* `Setting Cache Flushing `_ +* `Setting InMemory Spool Memory `_ +* `Setting Disk Spool Memory `_ +* `Setting Spool Saved File Directory Location `_ +* `Setting Data Stored Persistently on Cache `_ +* `Setting Persistent Spool Saved File Directory Location `_ +* `Setting Session Tag Name `_ \ No newline at end of file diff --git a/configuration_guides/generic_worker_flags.rst b/configuration_guides/generic_worker_flags.rst index 97cee4ecf..59fb9ac7a 100644 --- a/configuration_guides/generic_worker_flags.rst +++ b/configuration_guides/generic_worker_flags.rst @@ -5,4 +5,4 @@ Worker Generic Flags ************************* The Worker Generic Flags** page describes **Worker** modification type flags, which can be modified by standard users on a session basis: - * `Persisting Your Cache Directory `_ \ No newline at end of file + * `Persisting Your Cache Directory `_ \ No newline at end of file From 5956468d1b8c57b9724f109fc4aecd658ee18772 Mon Sep 17 00:00:00 2001 From: YanivGerowitz <82020437+YanivGerowitz@users.noreply.github.com> Date: Tue, 26 Jul 2022 17:13:50 +0300 Subject: [PATCH 147/316] Update data_encryption_syntax.rst --- feature_guides/data_encryption_syntax.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/feature_guides/data_encryption_syntax.rst b/feature_guides/data_encryption_syntax.rst index a7cb3e68d..3370698cf 100644 --- a/feature_guides/data_encryption_syntax.rst +++ b/feature_guides/data_encryption_syntax.rst @@ -22,4 +22,6 @@ The following is an example of encrypting a new table: last_name TEXT(128), salary INT(6) ENCRYPT); -.. note:: Users without permissions cannot view the entire table as long as at least one column is encrypted. The (unique) encryption/decryption key is relevant only at the system level and is not held by users. \ No newline at end of file +.. note:: Users without permissions cannot view the entire table as long as at least one column is encrypted. The (unique) encryption/decryption key is relevant only at the system level and is not held by users. + +Note that the master key is hard-coded in the system and cannot be changed. From 027a982ceddb086857411d6f3d51ad073f020e76 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 10:59:03 +0300 Subject: [PATCH 148/316] Released 2021.2.1.24 --- feature_guides/index.rst | 1 + feature_guides/query_healer.rst | 34 +++++++++++++++ releases/2021.2.1.24.rst | 77 +++++++++++++++++++++++++++++++++ releases/2021.2_index.rst | 1 + 4 files changed, 113 insertions(+) create mode 100644 feature_guides/query_healer.rst create mode 100644 releases/2021.2.1.24.rst diff --git a/feature_guides/index.rst b/feature_guides/index.rst index 2ca100a0f..6011d5e0b 100644 --- a/feature_guides/index.rst +++ b/feature_guides/index.rst @@ -11,6 +11,7 @@ This section describes the following features: :maxdepth: 1 :titlesonly: + query_healer key_evaluation data_encryption compression diff --git a/feature_guides/query_healer.rst b/feature_guides/query_healer.rst new file mode 100644 index 000000000..7a2e0bc8d --- /dev/null +++ b/feature_guides/query_healer.rst @@ -0,0 +1,34 @@ +.. _query_healer: + +*********************** +Query Healer +*********************** +The **Query Healer** page describes the following: + +.. contents:: + :local: + :depth: 1 + +Overview +---------- +The **Query Healer** periodically examines the progress of running statements, creating a log entry for all statements exceeding the ``healerMaxInactivityHours`` flag setting. The default setting of the ``healerMaxInactivityHours`` is five hours. + +Configuring the Healer +------------------ +The following flags are required to configure the Query Healer: + + * **isHealerOn** - Enables the Query Healer. + + :: + + * **healerMaxInactivityHours** - Defines the threshold for creating a log recording a slow statement. The log includes information about the log memory, CPU and GPU. + +The ``healerMaxInactivityHours`` log frequency is calculated as 5% of the flag setting. For example, setting ``healerMaxInactivityHours`` to five hours (the default setting) triggers an examination every 15 minutes. + +For more information, see the following Administration Worker flags: + + * :ref:`is_healer_on` + + :: + + * :ref:`healerMaxInactivityHours \ No newline at end of file diff --git a/releases/2021.2.1.24.rst b/releases/2021.2.1.24.rst new file mode 100644 index 000000000..7d8a1fd28 --- /dev/null +++ b/releases/2021.2.1.24.rst @@ -0,0 +1,77 @@ +.. _2021.2.1.24: + +************************** +Release Notes 2021.2.1.24 +************************** +The 2021.2.1.24 release notes were released on xx/xx/2022 and describe the following: + +.. contents:: + :local: + :depth: 1 + +Version Content +---------- +The 2021.2.1.24 Release Notes includes a query maintenance feature. + +New Features +---------- +The 2021.2.1.24 Release Notes include the following new features: + +.. contents:: + :local: + :depth: 1 + +Query Healer +************ +The new **Query Healer** feature periodically examines the progress of running statements, and is used for query maintenance. + +For more information, see :ref:`query_healer`. + +Known Issues +--------- +The following table lists the known issues for Version 2021.2.1.24: + ++-------------+------------------------------------------------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+====================================================================================================================================+ +| SQ-10071 | An error occurred on existing subqueries with ``TEXT`` and ``VARCHAR`` equality conditions. | ++-------------+------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10606 | Queries were getting stuck in the queue for a prolonged time. | ++-------------+------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10691 | The DB schema identifier was causing an error when running queries from joins suite. | ++-------------+------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10902 | Inserting a null value into non-null column was causing SQream to crash. | ++-------------+------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10918 | The Workload Manager was only assigning jobs sequentially, delaying user SQLs assigned to workers running very large jobs. | ++-------------+------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10955 | Metadata filters were not being applied when users filtered by nullable dates using ``dateadd`` | ++-------------+------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11088 | Specific workers caused low performance during compilation. | ++-------------+------------------------------------------------------------------------------------------------------------------------------------+ + +Resolved Issues +--------- +The Resolved Issues section is not relevant for Version 2021.2.1.24. + +Operations and Configuration Changes +-------- +No relevant operations and configuration changes were made. + +Naming Changes +------- +No relevant naming changes were made. + +Deprecated Features +------- +Version 2021.2.1.24 includes no deprecated features. + +End of Support +------- +The End of Support section is not relevant to Version 2021.2.1.24. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2021.2.1.24 diff --git a/releases/2021.2_index.rst b/releases/2021.2_index.rst index 77a22b0ae..9bee5fd66 100644 --- a/releases/2021.2_index.rst +++ b/releases/2021.2_index.rst @@ -13,5 +13,6 @@ The 2021.2 Release Notes describe the following releases: :maxdepth: 1 :glob: + 2021.2.1.24 2021.2.1 2021.2 \ No newline at end of file From 30f98c94e945de893f18b2a60f8dfbe7c9a9db4c Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 11:02:26 +0300 Subject: [PATCH 149/316] Fixed release date --- releases/2021.2.1.24.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releases/2021.2.1.24.rst b/releases/2021.2.1.24.rst index 7d8a1fd28..125092f0e 100644 --- a/releases/2021.2.1.24.rst +++ b/releases/2021.2.1.24.rst @@ -3,7 +3,7 @@ ************************** Release Notes 2021.2.1.24 ************************** -The 2021.2.1.24 release notes were released on xx/xx/2022 and describe the following: +The 2021.2.1.24 release notes were released on 7/28/2022 and describe the following: .. contents:: :local: From 284c11bbd151ff9d63d9797bf103197a538467b1 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 11:15:54 +0300 Subject: [PATCH 150/316] Added missing flags --- configuration_guides/admin_worker_flags.rst | 10 ++++++---- .../healer_max_inactivity_hours.rst | 14 ++++++++++++++ configuration_guides/is_healer_on.rst | 14 ++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 configuration_guides/healer_max_inactivity_hours.rst create mode 100644 configuration_guides/is_healer_on.rst diff --git a/configuration_guides/admin_worker_flags.rst b/configuration_guides/admin_worker_flags.rst index cd1a527d5..a3ca2710a 100644 --- a/configuration_guides/admin_worker_flags.rst +++ b/configuration_guides/admin_worker_flags.rst @@ -5,7 +5,9 @@ Worker Administration Flags ************************* The **Worker Administration Flags** page describes **Worker** modification type flags, which can be modified by administrators on a session and cluster basis using the ``ALTER SYSTEM SET`` command: -* `Setting Total Device Memory Usage in SQream Instance `_ -* `Enabling Manually Setting Reported IP `_ -* `Setting Port Used for Metadata Server Connection `_ -* `Assigning Local Network IP `_ \ No newline at end of file +* `Setting Total Device Memory Usage in SQream Instance `_ +* `Enabling Manually Setting Reported IP `_ +* `Setting Port Used for Metadata Server Connection `_ +* `Assigning Local Network IP `_ +* `Assigning Local Network IP `_ +* `Assigning Local Network IP `_ \ No newline at end of file diff --git a/configuration_guides/healer_max_inactivity_hours.rst b/configuration_guides/healer_max_inactivity_hours.rst new file mode 100644 index 000000000..730bd16ef --- /dev/null +++ b/configuration_guides/healer_max_inactivity_hours.rst @@ -0,0 +1,14 @@ +.. _healer_max_inactivity_hours + +************************* +Query Healer +************************* +The ``healerMaxInactivityHours`` flag is used for defining the threshold for creating a log recording a slow statement. The log includes information about the log memory, CPU and GPU. + +The following describes the ``healerMaxInactivityHours`` flag: + +* **Data type** - size_t +* **Default value** - ``5`` +* **Allowed values** - 1-4000000000 + +For related flags, see :ref:`is_healer_on`. \ No newline at end of file diff --git a/configuration_guides/is_healer_on.rst b/configuration_guides/is_healer_on.rst new file mode 100644 index 000000000..8b90654ec --- /dev/null +++ b/configuration_guides/is_healer_on.rst @@ -0,0 +1,14 @@ +.. _is_healer_on: + +************************* +Enabling the Query Healer +************************* +The ``is_healer_on`` flag enables the Query Healer, which periodically examines the progress of running statements and logs statements exceeding the ``healerMaxInactivityHours`` flag setting. + +The following describes the ``is_healer_on`` flag: + +* **Data type** - boolean +* **Default value** - ``true`` +* **Allowed values** - ``true``, ``false`` + +For related flags, see :ref:`healer_max_inactivity_hours`. \ No newline at end of file From a7a03e2341991417303d52844440b1f0a50cee5b Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 11:18:30 +0300 Subject: [PATCH 151/316] Update healer_max_inactivity_hours.rst --- configuration_guides/healer_max_inactivity_hours.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configuration_guides/healer_max_inactivity_hours.rst b/configuration_guides/healer_max_inactivity_hours.rst index 730bd16ef..d05d46014 100644 --- a/configuration_guides/healer_max_inactivity_hours.rst +++ b/configuration_guides/healer_max_inactivity_hours.rst @@ -1,4 +1,4 @@ -.. _healer_max_inactivity_hours +.. _healer_max_inactivity_hours: ************************* Query Healer From 1d47c5e558e3b57126a3f7d83010026d48af290a Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 11:20:55 +0300 Subject: [PATCH 152/316] REmoved key evaluation --- feature_guides/index.rst | 1 - feature_guides/key_evaluation.rst | 13 ---- .../key_evaluation_operational_modes.rst | 70 ------------------- feature_guides/key_evaluation_overview.rst | 16 ----- 4 files changed, 100 deletions(-) delete mode 100644 feature_guides/key_evaluation.rst delete mode 100644 feature_guides/key_evaluation_operational_modes.rst delete mode 100644 feature_guides/key_evaluation_overview.rst diff --git a/feature_guides/index.rst b/feature_guides/index.rst index 6011d5e0b..d70ceb705 100644 --- a/feature_guides/index.rst +++ b/feature_guides/index.rst @@ -12,7 +12,6 @@ This section describes the following features: :titlesonly: query_healer - key_evaluation data_encryption compression python_functions diff --git a/feature_guides/key_evaluation.rst b/feature_guides/key_evaluation.rst deleted file mode 100644 index e016e68c7..000000000 --- a/feature_guides/key_evaluation.rst +++ /dev/null @@ -1,13 +0,0 @@ -.. _key_evaluation: - -************************** -Key Evaluation -************************** -The **Key Evaluation** section describes the following: - -.. toctree:: - :maxdepth: 4 - :titlesonly: - - key_evaluation_overview - key_evaluation_operational_modes \ No newline at end of file diff --git a/feature_guides/key_evaluation_operational_modes.rst b/feature_guides/key_evaluation_operational_modes.rst deleted file mode 100644 index feb4fd9c1..000000000 --- a/feature_guides/key_evaluation_operational_modes.rst +++ /dev/null @@ -1,70 +0,0 @@ -.. _key_evaluation_operational_modes: - -************************** -Operational Modes -************************** -Key Evaluation can be used to do one of the following: - -**Comment** - *Do users initiate one of these modes, or do they occur in the background on their own? The answer to this question determines whether key evaluation belongs in Feature Guides or Operational Guides.* - -.. contents:: - :local: - :depth: 1 - -View All Problematic Chunk Keys ----------- -You can use the **View** mode to find all problematic keys in the database for all databases and/or tables. - -The following shows the View command options: - -.. code-block:: - - $ select  keys_evaluate ('view'); - -.. code-block:: - - $ select  keys_evaluate ('view', 'master'); - -.. code-block:: - - $ select  keys_evaluate ('view', 'master', 'public.tbl'); - -Find and Clean Problematic Keys from Storage ----------- -You can use the **Clean Storage** mode to find all problematic keys located in the Storage for all databases. - -The following shows the Clean Storage command: - -.. code-block:: - - $ select  keys_evaluate ('clean_storage'); - -.. note:: This mode backs up the levelDB to the **backup** folder in the cluster before finding and cleaning problematic keys from your storage. - -Find and Clean Problematic Keys from a Database ----------- -You can use the **Clean Database** mode to find and clean all problematic keys located for a specific database and/or table. - -The following shows the Clean Database command options: - -.. code-block:: - - $ select keys_evaluate ('clean_database','master'); - -.. code-block:: - - $ select keys_evaluate ('clean_database','master', 'public.tbl'); - -.. note:: This mode backs up the levelDB to the **backup** folder in the cluster before finding and cleaning problematic keys from your database. - -Clean Specifically Defined Chunk Keys ----------- -**Comment** - *Currently not supported. Remove until further notice?* - -You can use the **Clean Chunk Key** mode to clean a specific problematic chunk key. **Comment** - *Note: data_diag vs keys_evaluate.* - -The following shows the Clean Chunk Key command options: - -.. code-block:: - - $ select data_diag (12, ''); \ No newline at end of file diff --git a/feature_guides/key_evaluation_overview.rst b/feature_guides/key_evaluation_overview.rst deleted file mode 100644 index 3d3aabf8a..000000000 --- a/feature_guides/key_evaluation_overview.rst +++ /dev/null @@ -1,16 +0,0 @@ -.. _key_evaluation_overview: - -************************** -Overview -************************** -The **Key Evaluation** feature resolves conflicts caused by ingesting and deleting data at the same time. Although this rarely occurs, it causes the leveldb to restore keys pointing to deleted data. In turn, this causes SQream metadata to search for deleted files. - -An indication that this conflict has occurred is SQream's inability to retrieve deleted data pointers, generating the type of error shown below: - -.. code-block:: console - - Internal Runtime Error *** Error opening [errno 2 No such file or directory] file name /mnt/disk1/sqream_cluster/databases/******/tables/289/17/17-391270 - -In addition, key evaluation prevents the database from creating phantom keys, which are duplicate chunk keys generated when data is ingested. Under normal circumstances ingesting data creates incrementing chunk keys. - -**Comment** - *Please confirm the reason I provided based on my understanding of the source doc.* \ No newline at end of file From 100d27230010fef969978571cb048dd43d78c091 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 11:26:58 +0300 Subject: [PATCH 153/316] Fixed link --- feature_guides/query_healer.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature_guides/query_healer.rst b/feature_guides/query_healer.rst index 7a2e0bc8d..4d9b9e998 100644 --- a/feature_guides/query_healer.rst +++ b/feature_guides/query_healer.rst @@ -31,4 +31,4 @@ For more information, see the following Administration Worker flags: :: - * :ref:`healerMaxInactivityHours \ No newline at end of file + * :ref:`healer_max_inactivity_hours \ No newline at end of file From 34ec04726ada8871613cdf4090e073615232b5f0 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 11:41:16 +0300 Subject: [PATCH 154/316] Update query_healer.rst --- feature_guides/query_healer.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature_guides/query_healer.rst b/feature_guides/query_healer.rst index 4d9b9e998..4b7120db2 100644 --- a/feature_guides/query_healer.rst +++ b/feature_guides/query_healer.rst @@ -31,4 +31,4 @@ For more information, see the following Administration Worker flags: :: - * :ref:`healer_max_inactivity_hours \ No newline at end of file + * :ref:`healer_max_inactivity_hours` \ No newline at end of file From f4220cf1d4f71be492061949de2e17effa457d6d Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 11:48:46 +0300 Subject: [PATCH 155/316] Update admin_worker_flags.rst --- configuration_guides/admin_worker_flags.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configuration_guides/admin_worker_flags.rst b/configuration_guides/admin_worker_flags.rst index a3ca2710a..35edaf4ff 100644 --- a/configuration_guides/admin_worker_flags.rst +++ b/configuration_guides/admin_worker_flags.rst @@ -9,5 +9,5 @@ The **Worker Administration Flags** page describes **Worker** modification type * `Enabling Manually Setting Reported IP `_ * `Setting Port Used for Metadata Server Connection `_ * `Assigning Local Network IP `_ -* `Assigning Local Network IP `_ -* `Assigning Local Network IP `_ \ No newline at end of file +* `Enabling the Query Healer `_ +* `Configuring the Query Healer `_ \ No newline at end of file From b3c547958ab046c4e819f759ee4cda988bad5239 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 11:59:10 +0300 Subject: [PATCH 156/316] Update healer_max_inactivity_hours.rst --- configuration_guides/healer_max_inactivity_hours.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configuration_guides/healer_max_inactivity_hours.rst b/configuration_guides/healer_max_inactivity_hours.rst index d05d46014..56ddb78fc 100644 --- a/configuration_guides/healer_max_inactivity_hours.rst +++ b/configuration_guides/healer_max_inactivity_hours.rst @@ -1,7 +1,7 @@ .. _healer_max_inactivity_hours: ************************* -Query Healer +Configuring the Query Healer ************************* The ``healerMaxInactivityHours`` flag is used for defining the threshold for creating a log recording a slow statement. The log includes information about the log memory, CPU and GPU. From e2dbe63ebe42fb20aad7e4cdb2e826f4e3856f42 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 12:02:16 +0300 Subject: [PATCH 157/316] Update admin_worker_flags.rst --- configuration_guides/admin_worker_flags.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configuration_guides/admin_worker_flags.rst b/configuration_guides/admin_worker_flags.rst index 35edaf4ff..def1e8dac 100644 --- a/configuration_guides/admin_worker_flags.rst +++ b/configuration_guides/admin_worker_flags.rst @@ -9,5 +9,5 @@ The **Worker Administration Flags** page describes **Worker** modification type * `Enabling Manually Setting Reported IP `_ * `Setting Port Used for Metadata Server Connection `_ * `Assigning Local Network IP `_ -* `Enabling the Query Healer `_ +* `Enabling the Query Healer `_ * `Configuring the Query Healer `_ \ No newline at end of file From 55c2ae428cc8d95f40e0588bf01a55b54a1f3a36 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 12:08:47 +0300 Subject: [PATCH 158/316] Update admin_worker_flags.rst --- configuration_guides/admin_worker_flags.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/configuration_guides/admin_worker_flags.rst b/configuration_guides/admin_worker_flags.rst index def1e8dac..5725fc507 100644 --- a/configuration_guides/admin_worker_flags.rst +++ b/configuration_guides/admin_worker_flags.rst @@ -5,9 +5,9 @@ Worker Administration Flags ************************* The **Worker Administration Flags** page describes **Worker** modification type flags, which can be modified by administrators on a session and cluster basis using the ``ALTER SYSTEM SET`` command: -* `Setting Total Device Memory Usage in SQream Instance `_ -* `Enabling Manually Setting Reported IP `_ -* `Setting Port Used for Metadata Server Connection `_ +* `Setting Total Device Memory Usage in SQream Instance `_ +* `Enabling Manually Setting Reported IP `_ +* `Setting Port Used for Metadata Server Connection `_ * `Assigning Local Network IP `_ * `Enabling the Query Healer `_ -* `Configuring the Query Healer `_ \ No newline at end of file +* `Configuring the Query Healer `_ \ No newline at end of file From 207472f01f0713446f202e6146dc80d551c70c67 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 12:15:37 +0300 Subject: [PATCH 159/316] Added log example --- feature_guides/query_healer.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/feature_guides/query_healer.rst b/feature_guides/query_healer.rst index 4b7120db2..07e2dc0e4 100644 --- a/feature_guides/query_healer.rst +++ b/feature_guides/query_healer.rst @@ -13,6 +13,12 @@ Overview ---------- The **Query Healer** periodically examines the progress of running statements, creating a log entry for all statements exceeding the ``healerMaxInactivityHours`` flag setting. The default setting of the ``healerMaxInactivityHours`` is five hours. +The following is an example of a log record for a query stuck in the query detection phase for more than five hours: + + .. code-block:: console + + 2022/05/19::20:01:25|ERROR|Healer|(0x7f07147fc700)|Stuck query found. Statement ID: 72, Last chunk producer updated: 1 WriteTable, Started on: Thu May 19 14:01:25 2022, Last updated: Thu May 19 15:01:25 2022, Stuck time: 5 hours, Max allowed stuck query time: 5 hours + Configuring the Healer ------------------ The following flags are required to configure the Query Healer: From c5f344027a90af81ffaf7e8ecea154a7f6cb08b8 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 12:47:04 +0300 Subject: [PATCH 160/316] Update query_healer.rst --- feature_guides/query_healer.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/feature_guides/query_healer.rst b/feature_guides/query_healer.rst index 07e2dc0e4..cb50549b8 100644 --- a/feature_guides/query_healer.rst +++ b/feature_guides/query_healer.rst @@ -15,9 +15,9 @@ The **Query Healer** periodically examines the progress of running statements, c The following is an example of a log record for a query stuck in the query detection phase for more than five hours: - .. code-block:: console +.. code-block:: console - 2022/05/19::20:01:25|ERROR|Healer|(0x7f07147fc700)|Stuck query found. Statement ID: 72, Last chunk producer updated: 1 WriteTable, Started on: Thu May 19 14:01:25 2022, Last updated: Thu May 19 15:01:25 2022, Stuck time: 5 hours, Max allowed stuck query time: 5 hours + 2022/05/19::20:01:25|ERROR|Healer|(0x7f07147fc700)|Stuck query found. Statement ID: 72, Last chunk producer updated: 1 WriteTable, Started on: Thu May 19 14:01:25 2022, Last updated: Thu May 19 15:01:25 2022, Stuck time: 5 hours, Max allowed stuck query time: 5 hours Configuring the Healer ------------------ From 664e4fe191aab8deafce010b68399c944655791b Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 14:06:46 +0300 Subject: [PATCH 161/316] Created and Published 2022.1.1 Including all related documentation updates. --- configuration_guides/admin_worker_flags.rst | 5 +- configuration_guides/login_max_retries.rst | 11 + operational_guides/access_control.rst | 587 +----------------- .../access_control_departmental_example.rst | 185 ++++++ .../access_control_managing_roles.rst | 124 ++++ .../access_control_overview.rst | 20 + .../access_control_password_policy.rst | 42 ++ .../access_control_permissions.rst | 218 +++++++ releases/2022.1.1.rst | 115 ++++ releases/2022.1_index.rst | 17 + 10 files changed, 744 insertions(+), 580 deletions(-) create mode 100644 configuration_guides/login_max_retries.rst create mode 100644 operational_guides/access_control_departmental_example.rst create mode 100644 operational_guides/access_control_managing_roles.rst create mode 100644 operational_guides/access_control_overview.rst create mode 100644 operational_guides/access_control_password_policy.rst create mode 100644 operational_guides/access_control_permissions.rst create mode 100644 releases/2022.1.1.rst create mode 100644 releases/2022.1_index.rst diff --git a/configuration_guides/admin_worker_flags.rst b/configuration_guides/admin_worker_flags.rst index 5725fc507..453c66af8 100644 --- a/configuration_guides/admin_worker_flags.rst +++ b/configuration_guides/admin_worker_flags.rst @@ -8,6 +8,7 @@ The **Worker Administration Flags** page describes **Worker** modification type * `Setting Total Device Memory Usage in SQream Instance `_ * `Enabling Manually Setting Reported IP `_ * `Setting Port Used for Metadata Server Connection `_ -* `Assigning Local Network IP `_ +* `Assigning Local Network IP `_ * `Enabling the Query Healer `_ -* `Configuring the Query Healer `_ \ No newline at end of file +* `Configuring the Query Healer `_ +* `Adjusting Permitted Log-in Attempts `_ \ No newline at end of file diff --git a/configuration_guides/login_max_retries.rst b/configuration_guides/login_max_retries.rst new file mode 100644 index 000000000..bf3ae6d40 --- /dev/null +++ b/configuration_guides/login_max_retries.rst @@ -0,0 +1,11 @@ +.. _login_max_retries: + +************************* +Adjusting Permitted Log-in Attempts +************************* +The ``loginMaxRetries`` flag sets the permitted log-in attempts. + +The following describes the ``loginMaxRetries`` flag: + +* **Data type** - size_t +* **Default value** - ``5`` \ No newline at end of file diff --git a/operational_guides/access_control.rst b/operational_guides/access_control.rst index ffe687213..bd25d0d99 100644 --- a/operational_guides/access_control.rst +++ b/operational_guides/access_control.rst @@ -4,581 +4,12 @@ Access Control ************** -.. contents:: - :local: - :depth: 1 - -Overview -========== -Access control provides authentication and authorization in SQream DB. SQream DB manages authentication and authorization using a role-based access control system (RBAC), like ANSI SQL and other SQL products. - -SQream DB has a default permissions system which is inspired by Postgres, but with more power. In most cases, this allows an administrator to set things up so that every object gets permissions set automatically. In SQream DB, users log in from any worker which verifies their roles and permissions from the metadata server. Each statement issues commands as the currently logged in role. - -Roles are defined at the cluster level, meaning they are valid for all databases in the cluster. To bootstrap SQream DB, a new install will always have one ``SUPERUSER`` role, typically named ``sqream``. To create more roles, you should first connect as this role. - -The following: - -* **Role** - a role can be a user, a group, or both. Roles can own database objects (e.g. tables), and can assign permissions on those objects to other roles. Roles can be members of other roles, meaning a user role can inherit permissions from its parent role. - - :: - -* **Authentication** - verifying the identity of the role. User roles have usernames (:term:`role names`) and passwords. - - :: - -* **Authorization** - checking the role has permissions to do a particular thing. The :ref:`grant` command is used for this. - -Managing Roles -===== -Roles are used for both users and groups. Roles are global across all databases in the SQream DB cluster. To use a ``ROLE`` as a user, it should have a password, the login permission, and connect permissions to the relevant databases. - -The Roles section describes the following role-related operations: - -.. contents:: - :local: - :depth: 1 - -Creating New Roles (Users) ------------------------------- -A user role can log in to the database, so it should have ``LOGIN`` permissions, as well as a password. - -For example: - -.. code-block:: postgres - - CREATE ROLE role_name ; - GRANT LOGIN to role_name ; - GRANT PASSWORD 'new_password' to role_name ; - GRANT CONNECT ON DATABASE database_name to role_name ; - -Examples: - -.. code-block:: postgres - - CREATE ROLE new_role_name ; - GRANT LOGIN TO new_role_name; - GRANT PASSWORD 'my_password' TO new_role_name; - GRANT CONNECT ON DATABASE master TO new_role_name; - -A database role may have a number of permissions that define what tasks it can perform. These are assigned using the :ref:`grant` command. - -Dropping Users ---------------- - -.. code-block:: postgres - - DROP ROLE role_name ; - -Examples: - -.. code-block:: postgres - - DROP ROLE admin_role ; - -Altering a User Name ------------------------- - -Renaming a user's role: - -.. code-block:: postgres - - ALTER ROLE role_name RENAME TO new_role_name ; - -Examples: - -.. code-block:: postgres - - ALTER ROLE admin_role RENAME TO copy_role ; - -.. _change_password: - -Changing User Passwords --------------------------- - -To change a user role's password, grant the user a new password. - -.. code-block:: postgres - - GRANT PASSWORD 'new_password' TO rhendricks; - -.. note:: Granting a new password overrides any previous password. Changing the password while the role has an active running statement does not affect that statement, but will affect subsequent statements. - -Altering Public Role Permissions ------------ - -There is a public role which always exists. Each role is granted to the ``PUBLIC`` role (i.e. is a member of the public group), and this cannot be revoked. You can alter the permissions granted to the public role. - -The ``PUBLIC`` role has ``USAGE`` and ``CREATE`` permissions on ``PUBLIC`` schema by default, therefore, new users can create, :ref:`insert`, :ref:`delete`, and :ref:`select` from objects in the ``PUBLIC`` schema. - - -Altering Role Membership (Groups) -------------------------- - -Many database administrators find it useful to group user roles together. By grouping users, permissions can be granted to, or revoked from a group with one command. In SQream DB, this is done by creating a group role, granting permissions to it, and then assigning users to that group role. - -To use a role purely as a group, omit granting it ``LOGIN`` and ``PASSWORD`` permissions. - -The ``CONNECT`` permission can be given directly to user roles, and/or to the groups they are part of. - -.. code-block:: postgres - - CREATE ROLE my_group; - -Once the group role exists, you can add user roles (members) using the ``GRANT`` command. For example: - -.. code-block:: postgres - - -- Add my_user to this group - GRANT my_group TO my_user; - - -To manage object permissions like databases and tables, you would then grant permissions to the group-level role (see :ref:`the permissions table` below. - -All member roles then inherit the permissions from the group. For example: - -.. code-block:: postgres - - -- Grant all group users connect permissions - GRANT CONNECT ON DATABASE a_database TO my_group; - - -- Grant all permissions on tables in public schema - GRANT ALL ON all tables IN schema public TO my_group; - -Removing users and permissions can be done with the ``REVOKE`` command: - -.. code-block:: postgres - - -- remove my_other_user from this group - REVOKE my_group FROM my_other_user; - -.. _permissions_table: - -Permissions -=========== -The following table displays the access control permissions: - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Object/layer - - Permission - - Description - - * - all databases - - ``LOGIN`` - - use role to log into the system (the role also needs connect permission on the database it is connecting to) - - * - all databases - - ``PASSWORD`` - - the password used for logging into the system - - * - all databases - - ``SUPERUSER`` - - no permission restrictions on any activity - - * - database - - ``SUPERUSER`` - - no permission restrictions on any activity within that database (this does not include modifying roles or permissions) - - * - database - - ``CONNECT`` - - connect to the database - - * - database - - ``CREATE`` - - create schemas in the database - - * - database - - ``CREATE FUNCTION`` - - create and drop functions - - * - schema - - ``USAGE`` - - allows additional permissions within the schema - - * - schema - - ``CREATE`` - - create tables in the schema - - * - table - - ``SELECT`` - - :ref:`select` from the table - - * - table - - ``INSERT`` - - :ref:`insert` into the table - - * - table - - ``UPDATE`` - - :ref:`update` the value of certain columns in existing rows without creating a table - - * - table - - ``DELETE`` - - :ref:`delete` and :ref:`truncate` on the table - - * - table - - ``DDL`` - - drop and alter on the table - - * - table - - ``ALL`` - - all the table permissions - - * - function - - ``EXECUTE`` - - use the function - - * - function - - ``DDL`` - - drop and alter on the function - - * - function - - ``ALL`` - - all function permissions - -GRANT ------ - -:ref:`grant` gives permissions to a role, shown in the following syntax example: - -.. code-block:: postgres - - -- Grant permissions at the instance/ storage cluster level: - GRANT - - { SUPERUSER - | LOGIN - | PASSWORD '' - } - TO [, ...] - - -- Grant permissions at the database level: - GRANT {{CREATE | CONNECT| DDL | SUPERUSER | CREATE FUNCTION} [, ...] | ALL [PERMISSIONS]} - - ON DATABASE [, ...] - TO [, ...] - - -- Grant permissions at the schema level: - GRANT {{ CREATE | DDL | USAGE | SUPERUSER } [, ...] | ALL [ - PERMISSIONS ]} - ON SCHEMA [, ...] - TO [, ...] - - -- Grant permissions at the object level: - GRANT {{SELECT | INSERT | DELETE | DDL } [, ...] | ALL [PERMISSIONS]} - ON { TABLE [, ...] | ALL TABLES IN SCHEMA [, ...]} - TO [, ...] - - -- Grant execute function permission: - GRANT {ALL | EXECUTE | DDL} ON FUNCTION function_name - TO role; - - -- Allows role2 to use permissions granted to role1 - GRANT [, ...] - TO - - -- Also allows the role2 to grant role1 to other roles: - GRANT [, ...] - TO - WITH ADMIN OPTION - -The following are some ``GRANT`` examples: - -.. code-block:: postgres - - GRANT LOGIN,superuser TO admin; - - GRANT CREATE FUNCTION ON database master TO admin; - - GRANT SELECT ON TABLE admin.table1 TO userA; - - GRANT EXECUTE ON FUNCTION my_function TO userA; - - GRANT ALL ON FUNCTION my_function TO userA; - - GRANT DDL ON admin.main_table TO userB; - - GRANT ALL ON all tables IN schema public TO userB; - - GRANT admin TO userC; - - GRANT superuser ON schema demo TO userA - - GRANT admin_role TO userB; - -REVOKE ------- - -:ref:`revoke` removes permissions from a role, shown in the following syntax example: - -.. code-block:: postgres - - -- Revoke permissions at the instance/ storage cluster level: - REVOKE - { SUPERUSER - | LOGIN - | PASSWORD - } - FROM [, ...] - - -- Revoke permissions at the database level: - REVOKE {{CREATE | CONNECT | DDL | SUPERUSER | CREATE FUNCTION}[, ...] |ALL [PERMISSIONS]} - ON DATABASE [, ...] - FROM [, ...] - - -- Revoke permissions at the schema level: - REVOKE { { CREATE | DDL | USAGE | SUPERUSER } [, ...] | ALL [PERMISSIONS]} - ON SCHEMA [, ...] - FROM [, ...] - - -- Revoke permissions at the object level: - REVOKE { { SELECT | INSERT | DELETE | DDL } [, ...] | ALL } - ON { [ TABLE ] [, ...] | ALL TABLES IN SCHEMA - - [, ...] } - FROM [, ...] - - -- Removes access to permissions in role1 by role 2 - REVOKE [, ...] FROM [, ...] WITH ADMIN OPTION - - -- Removes permissions to grant role1 to additional roles from role2 - REVOKE [, ...] FROM [, ...] WITH ADMIN OPTION - - -Examples: - -.. code-block:: postgres - - REVOKE superuser on schema demo from userA; - - REVOKE delete on admin.table1 from userB; - - REVOKE login from role_test; - - REVOKE CREATE FUNCTION FROM admin; - -Default Permissions -------------------- - -The default permissions system (See :ref:`alter_default_permissions`) -can be used to automatically grant permissions to newly -created objects (See the departmental example below for one way it can be used). - -A default permissions rule looks for a schema being created, or a -table (possibly by schema), and is table to grant any permission to -that object to any role. This happens when the create table or create -schema statement is run. - - -.. code-block:: postgres - - - ALTER DEFAULT PERMISSIONS FOR target_role_name - [IN schema_name, ...] - FOR { TABLES | SCHEMAS } - { grant_clause | DROP grant_clause} - TO ROLE { role_name | public }; - - grant_clause ::= - GRANT - { CREATE FUNCTION - | SUPERUSER - | CONNECT - | CREATE - | USAGE - | SELECT - | INSERT - | UPDATE - | DELETE - | DDL - | EXECUTE - | ALL - } - - -Departmental Example -======================= - -You work in a company with several departments. - -The example below shows you how to manage permissions in a database shared by multiple departments, where each department has different roles for the tables by schema. It walks you through how to set the permissions up for existing objects and how to set up default permissions rules to cover newly created objects. - -The concept is that you set up roles for each new schema with the correct permissions, then the existing users can use these roles. - -A superuser must do new setup for each new schema which is a limitation, but superuser permissions are not needed at any other time, and neither are explicit grant statements or object ownership changes. - -In the example, the database is called ``my_database``, and the new or existing schema being set up to be managed in this way is called ``my_schema``. - -.. figure:: /_static/images/access_control_department_example.png - :scale: 60 % - - Our departmental example has four user group roles and seven users roles - -There will be a group for this schema for each of the following: - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Group - - Activities - - * - database designers - - create, alter and drop tables - - * - updaters - - insert and delete data - - * - readers - - read data - - * - security officers - - add and remove users from these groups - -Setting up the department permissions ------------------------------------------- - -As a superuser, you connect to the system and run the following: - -.. code-block:: postgres - - -- create the groups - - CREATE ROLE my_schema_security_officers; - CREATE ROLE my_schema_database_designers; - CREATE ROLE my_schema_updaters; - CREATE ROLE my_schema_readers; - - -- grant permissions for each role - -- we grant permissions for existing objects here too, - -- so you don't have to start with an empty schema - - -- security officers - - GRANT connect ON DATABASE my_database TO my_schema_security_officers; - GRANT usage ON SCHEMA my_schema TO my_schema_security_officers; - - GRANT my_schema_database_designers TO my_schema_security_officers WITH ADMIN OPTION; - GRANT my_schema_updaters TO my_schema_security_officers WITH ADMIN OPTION; - GRANT my_schema_readers TO my_schema_security_officers WITH ADMIN OPTION; - - -- database designers - - GRANT connect ON DATABASE my_database TO my_schema_database_designers; - GRANT usage ON SCHEMA my_schema TO my_schema_database_designers; - - GRANT create,ddl ON SCHEMA my_schema TO my_schema_database_designers; - - -- updaters - - GRANT connect ON DATABASE my_database TO my_schema_updaters; - GRANT usage ON SCHEMA my_schema TO my_schema_updaters; - - GRANT SELECT,INSERT,DELETE ON ALL TABLES IN SCHEMA my_schema TO my_schema_updaters; - - -- readers - - GRANT connect ON DATABASE my_database TO my_schema_readers; - GRANT usage ON SCHEMA my_schema TO my_schema_readers; - - GRANT SELECT ON ALL TABLES IN SCHEMA my_schema TO my_schema_readers; - GRANT EXECUTE ON ALL FUNCTIONS TO my_schema_readers; - - - -- create the default permissions for new objects - - ALTER DEFAULT PERMISSIONS FOR my_schema_database_designers IN my_schema - FOR TABLES GRANT SELECT,INSERT,DELETE TO my_schema_updaters; - - -- For every table created by my_schema_database_designers, give access to my_schema_readers: - - ALTER DEFAULT PERMISSIONS FOR my_schema_database_designers IN my_schema - FOR TABLES GRANT SELECT TO my_schema_readers; - -.. note:: - * This process needs to be repeated by a user with ``SUPERUSER`` permissions each time a new schema is brought into this permissions management approach. - - * - By default, any new object created will not be accessible by our new ``my_schema_readers`` group. - Running a ``GRANT SELECT ...`` only affects objects that already exist in the schema or database. - - If you're getting a ``Missing the following permissions: SELECT on table 'database.public.tablename'`` error, make sure that - you've altered the default permissions with the ``ALTER DEFAULT PERMISSIONS`` statement. - -Creating new users in the departments ------------------------------------------ - -After the group roles have been created, you can now create user roles for each of your users. - -.. code-block:: postgres - - -- create the new database designer users - - CREATE ROLE ecodd; - GRANT LOGIN TO ecodd; - GRANT PASSWORD 'ecodds_secret_password' TO ecodd; - GRANT CONNECT ON DATABASE my_database TO ecodd; - GRANT my_schema_database_designers TO ecodd; - - CREATE ROLE ebachmann; - GRANT LOGIN TO ebachmann; - GRANT PASSWORD 'another_secret_password' TO ebachmann; - GRANT CONNECT ON DATABASE my_database TO ebachmann; - GRANT my_database_designers TO ebachmann; - - -- If a user already exists, we can assign that user directly to the group - - GRANT my_schema_updaters TO rhendricks; - - -- Create users in the readers group - - CREATE ROLE jbarker; - GRANT LOGIN TO jbarker; - GRANT PASSWORD 'action_jack' TO jbarker; - GRANT CONNECT ON DATABASE my_database TO jbarker; - GRANT my_schema_readers TO jbarker; - - CREATE ROLE lbream; - GRANT LOGIN TO lbream; - GRANT PASSWORD 'artichoke123' TO lbream; - GRANT CONNECT ON DATABASE my_database TO lbream; - GRANT my_schema_readers TO lbream; - - CREATE ROLE pgregory; - GRANT LOGIN TO pgregory; - GRANT PASSWORD 'c1ca6a' TO pgregory; - GRANT CONNECT ON DATABASE my_database TO pgregory; - GRANT my_schema_readers TO pgregory; - - -- Create users in the security officers group - - CREATE ROLE hoover; - GRANT LOGIN TO hoover; - GRANT PASSWORD 'mintchip' TO hoover; - GRANT CONNECT ON DATABASE my_database TO hoover; - GRANT my_schema_security_officers TO hoover; - - -.. todo: - create some example users - show that they have the right permission - try out the with admin option. we can't really do a security officer because - only superusers can create users and logins. see what can be done - need 1-2 users in each group, for at least 2 schemas/departments - this example will be very big just to show what this setup can do ... - example: a security officer for a department which will only have - read only access to a schema can only get that with admin option - access granted to them - -After this setup: - -* Database designers will be able to run any ddl on objects in the schema and create new objects, including ones created by other database designers -* Updaters will be able to insert and delete to existing and new tables -* Readers will be able to read from existing and new tables - -All this will happen without having to run any more ``GRANT`` statements. - -Any security officer will be able to add and remove users from these -groups. Creating and dropping login users themselves must be done by a -superuser. +.. toctree:: + :maxdepth: 1 + :titlesonly: + + access_control_overview + access_control_managing_roles + access_control_permissions + access_control_password_policy + access_control_departmental_example \ No newline at end of file diff --git a/operational_guides/access_control_departmental_example.rst b/operational_guides/access_control_departmental_example.rst new file mode 100644 index 000000000..0a6b55e54 --- /dev/null +++ b/operational_guides/access_control_departmental_example.rst @@ -0,0 +1,185 @@ +.. _access_control_departmental_example: + +************** +Departmental Example +************** + +You work in a company with several departments. + +The example below shows you how to manage permissions in a database shared by multiple departments, where each department has different roles for the tables by schema. It walks you through how to set the permissions up for existing objects and how to set up default permissions rules to cover newly created objects. + +The concept is that you set up roles for each new schema with the correct permissions, then the existing users can use these roles. + +A superuser must do new setup for each new schema which is a limitation, but superuser permissions are not needed at any other time, and neither are explicit grant statements or object ownership changes. + +In the example, the database is called ``my_database``, and the new or existing schema being set up to be managed in this way is called ``my_schema``. + +Our departmental example has four user group roles and seven users roles + +There will be a group for this schema for each of the following: + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Group + - Activities + + * - database designers + - create, alter and drop tables + + * - updaters + - insert and delete data + + * - readers + - read data + + * - security officers + - add and remove users from these groups + +Setting up the department permissions +------------------------------------------ + +As a superuser, you connect to the system and run the following: + +.. code-block:: postgres + + -- create the groups + + CREATE ROLE my_schema_security_officers; + CREATE ROLE my_schema_database_designers; + CREATE ROLE my_schema_updaters; + CREATE ROLE my_schema_readers; + + -- grant permissions for each role + -- we grant permissions for existing objects here too, + -- so you don't have to start with an empty schema + + -- security officers + + GRANT connect ON DATABASE my_database TO my_schema_security_officers; + GRANT usage ON SCHEMA my_schema TO my_schema_security_officers; + + GRANT my_schema_database_designers TO my_schema_security_officers WITH ADMIN OPTION; + GRANT my_schema_updaters TO my_schema_security_officers WITH ADMIN OPTION; + GRANT my_schema_readers TO my_schema_security_officers WITH ADMIN OPTION; + + -- database designers + + GRANT connect ON DATABASE my_database TO my_schema_database_designers; + GRANT usage ON SCHEMA my_schema TO my_schema_database_designers; + + GRANT create,ddl ON SCHEMA my_schema TO my_schema_database_designers; + + -- updaters + + GRANT connect ON DATABASE my_database TO my_schema_updaters; + GRANT usage ON SCHEMA my_schema TO my_schema_updaters; + + GRANT SELECT,INSERT,DELETE ON ALL TABLES IN SCHEMA my_schema TO my_schema_updaters; + + -- readers + + GRANT connect ON DATABASE my_database TO my_schema_readers; + GRANT usage ON SCHEMA my_schema TO my_schema_readers; + + GRANT SELECT ON ALL TABLES IN SCHEMA my_schema TO my_schema_readers; + GRANT EXECUTE ON ALL FUNCTIONS TO my_schema_readers; + + + -- create the default permissions for new objects + + ALTER DEFAULT PERMISSIONS FOR my_schema_database_designers IN my_schema + FOR TABLES GRANT SELECT,INSERT,DELETE TO my_schema_updaters; + + -- For every table created by my_schema_database_designers, give access to my_schema_readers: + + ALTER DEFAULT PERMISSIONS FOR my_schema_database_designers IN my_schema + FOR TABLES GRANT SELECT TO my_schema_readers; + +.. note:: + * This process needs to be repeated by a user with ``SUPERUSER`` permissions each time a new schema is brought into this permissions management approach. + + * + By default, any new object created will not be accessible by our new ``my_schema_readers`` group. + Running a ``GRANT SELECT ...`` only affects objects that already exist in the schema or database. + + If you're getting a ``Missing the following permissions: SELECT on table 'database.public.tablename'`` error, make sure that + you've altered the default permissions with the ``ALTER DEFAULT PERMISSIONS`` statement. + +Creating new users in the departments +----------------------------------------- + +After the group roles have been created, you can now create user roles for each of your users. + +.. code-block:: postgres + + -- create the new database designer users + + CREATE ROLE ecodd; + GRANT LOGIN TO ecodd; + GRANT PASSWORD 'ecodds_secret_password' TO ecodd; + GRANT CONNECT ON DATABASE my_database TO ecodd; + GRANT my_schema_database_designers TO ecodd; + + CREATE ROLE ebachmann; + GRANT LOGIN TO ebachmann; + GRANT PASSWORD 'another_secret_password' TO ebachmann; + GRANT CONNECT ON DATABASE my_database TO ebachmann; + GRANT my_database_designers TO ebachmann; + + -- If a user already exists, we can assign that user directly to the group + + GRANT my_schema_updaters TO rhendricks; + + -- Create users in the readers group + + CREATE ROLE jbarker; + GRANT LOGIN TO jbarker; + GRANT PASSWORD 'action_jack' TO jbarker; + GRANT CONNECT ON DATABASE my_database TO jbarker; + GRANT my_schema_readers TO jbarker; + + CREATE ROLE lbream; + GRANT LOGIN TO lbream; + GRANT PASSWORD 'artichoke123' TO lbream; + GRANT CONNECT ON DATABASE my_database TO lbream; + GRANT my_schema_readers TO lbream; + + CREATE ROLE pgregory; + GRANT LOGIN TO pgregory; + GRANT PASSWORD 'c1ca6a' TO pgregory; + GRANT CONNECT ON DATABASE my_database TO pgregory; + GRANT my_schema_readers TO pgregory; + + -- Create users in the security officers group + + CREATE ROLE hoover; + GRANT LOGIN TO hoover; + GRANT PASSWORD 'mintchip' TO hoover; + GRANT CONNECT ON DATABASE my_database TO hoover; + GRANT my_schema_security_officers TO hoover; + + +.. todo: + create some example users + show that they have the right permission + try out the with admin option. we can't really do a security officer because + only superusers can create users and logins. see what can be done + need 1-2 users in each group, for at least 2 schemas/departments + this example will be very big just to show what this setup can do ... + example: a security officer for a department which will only have + read only access to a schema can only get that with admin option + access granted to them + +After this setup: + +* Database designers will be able to run any ddl on objects in the schema and create new objects, including ones created by other database designers +* Updaters will be able to insert and delete to existing and new tables +* Readers will be able to read from existing and new tables + +All this will happen without having to run any more ``GRANT`` statements. + +Any security officer will be able to add and remove users from these +groups. Creating and dropping login users themselves must be done by a +superuser. \ No newline at end of file diff --git a/operational_guides/access_control_managing_roles.rst b/operational_guides/access_control_managing_roles.rst new file mode 100644 index 000000000..373b9a212 --- /dev/null +++ b/operational_guides/access_control_managing_roles.rst @@ -0,0 +1,124 @@ +.. _access_control_managing_roles: + +************** +Managing Roles +************** +Roles are used for both users and groups, and are global across all databases in the SQream cluster. For a ``ROLE`` to be used as a user, it requires a password and log-in and connect permissionss to the relevant databases. + +The Managing Roles section describes the following role-related operations: + +.. contents:: + :local: + :depth: 1 + +Creating New Roles (Users) +------------------------------ +A user role logging in to the database requires ``LOGIN`` permissions and as a password. + +The following is the syntax for creating a new role: + +.. code-block:: postgres + + CREATE ROLE ; + GRANT LOGIN to ; + GRANT PASSWORD <'new_password'> to ; + GRANT CONNECT ON DATABASE to ; + +The following is an example of creating a new role: + +.. code-block:: postgres + + CREATE ROLE new_role_name ; + GRANT LOGIN TO new_role_name; + GRANT PASSWORD 'my_password' to new_role_name; + GRANT CONNECT ON DATABASE master to new_role_name; + +A database role may have a number of permissions that define what tasks it can perform, which are assigned using the :ref:`grant` command. + +Dropping a User +------------------------------ +The following is the syntax for dropping a user: + +.. code-block:: postgres + + DROP ROLE ; + +The following is an example of dropping a user: + +.. code-block:: postgres + + DROP ROLE admin_role ; + +Altering a User Name +------------------------------ +The following is the syntax for altering a user name: + +.. code-block:: postgres + + ALTER ROLE RENAME TO ; + +The following is an example of altering a user name: + +.. code-block:: postgres + + ALTER ROLE admin_role RENAME TO copy_role ; + +Changing a User Password +------------------------------ +You can change a user role's password by granting the user a new password. + +The following is an example of changing a user password: + +.. code-block:: postgres + + GRANT PASSWORD <'new_password'> TO rhendricks; + +.. note:: Granting a new password overrides any previous password. Changing the password while the role has an active running statement does not affect that statement, but will affect subsequent statements. + +Altering Public Role Permissions +------------------------------ + +There is a public role which always exists. Each role is granted to the ``PUBLIC`` role (i.e. is a member of the public group), and this cannot be revoked. You can alter the permissions granted to the public role. + +The ``PUBLIC`` role has ``USAGE`` and ``CREATE`` permissions on ``PUBLIC`` schema by default, therefore, new users can create, :ref:`insert`, :ref:`delete`, and :ref:`select` from objects in the ``PUBLIC`` schema. + + +Altering Role Membership (Groups) +------------------------------ + +Many database administrators find it useful to group user roles together. By grouping users, permissions can be granted to, or revoked from a group with one command. In SQream DB, this is done by creating a group role, granting permissions to it, and then assigning users to that group role. + +To use a role purely as a group, omit granting it ``LOGIN`` and ``PASSWORD`` permissions. + +The ``CONNECT`` permission can be given directly to user roles, and/or to the groups they are part of. + +.. code-block:: postgres + + CREATE ROLE my_group; + +Once the group role exists, you can add user roles (members) using the ``GRANT`` command. For example: + +.. code-block:: postgres + + -- Add my_user to this group + GRANT my_group TO my_user; + + +To manage object permissions like databases and tables, you would then grant permissions to the group-level role (see :ref:`the permissions table` below. + +All member roles then inherit the permissions from the group. For example: + +.. code-block:: postgres + + -- Grant all group users connect permissions + GRANT CONNECT ON DATABASE a_database TO my_group; + + -- Grant all permissions on tables in public schema + GRANT ALL ON all tables IN schema public TO my_group; + +Removing users and permissions can be done with the ``REVOKE`` command: + +.. code-block:: postgres + + -- remove my_other_user from this group + REVOKE my_group FROM my_other_user; \ No newline at end of file diff --git a/operational_guides/access_control_overview.rst b/operational_guides/access_control_overview.rst new file mode 100644 index 000000000..080797fec --- /dev/null +++ b/operational_guides/access_control_overview.rst @@ -0,0 +1,20 @@ +.. _access_control_overview: + +************** +Overview +************** +Access control refers to SQream's authentication and authorization operations, managed using a **Role-Based Access Control (RBAC)** system, such as ANSI SQL or other SQL products. SQream's default permissions system is similar to Postgres, but is more powerful. SQream's method lets administrators prepare the system to automatically provide objects with their required permissions. + +SQream users can log in from any worker, which verify their roles and permissions from the metadata server. Each statement issues commands as the role that you're currently logged into. Roles are defined at the cluster level, and are valid for all databases in the cluster. To bootstrap SQream, new installations require one ``SUPERUSER`` role, typically named ``sqream``. You can only create new roles by connecting as this role. + +Access control refers to the following basic concepts: + + * **Role** - A role can be a user, a group, or both. Roles can own database objects (such as tables) and can assign permissions on those objects to other roles. Roles can be members of other roles, meaning a user role can inherit permissions from its parent role. + + :: + + * **Authentication** - Verifies the identity of the role. User roles have usernames (or **role names**) and passwords. + + :: + + * **Authorization** - Checks that a role has permissions to perform a particular operation, such as the :ref:`grant` command. \ No newline at end of file diff --git a/operational_guides/access_control_password_policy.rst b/operational_guides/access_control_password_policy.rst new file mode 100644 index 000000000..10a4f697f --- /dev/null +++ b/operational_guides/access_control_password_policy.rst @@ -0,0 +1,42 @@ +.. _access_control_password_policy: + +************** +Password Policy +************** +As part of our compliance with GDPR standards SQream relies on a strong password policy when accessing the CLI or Studio, with the following requirements: + +* At least eight characters long. + + :: + +* Mandatory upper and lowercase letters. + + :: + +* At least one numeric character. + + :: + +* May not include a username. + + :: + +* Must include at least one special character, such as **?**, **!**, **$**, etc. + +You can create a password through the Studio graphic interface or through the CLI, as in the following example command: + +.. code-block:: console + + CREATE ROLE user_a ; + GRANT LOGIN to user_a ; + GRANT PASSWORD 'BBAu47?fqPL' to user_a ; + +Creating a password that does not comply with the above requirements generates an error message with a request to modify it. + +Unsuccessfully attempting to log in three times displays the following message: + +.. code-block:: console + + The user is locked. please contact your system administrator to reset the password and regain access functionality. + +For more information, see :ref:`login_max_retries`. diff --git a/operational_guides/access_control_permissions.rst b/operational_guides/access_control_permissions.rst new file mode 100644 index 000000000..5afc23009 --- /dev/null +++ b/operational_guides/access_control_permissions.rst @@ -0,0 +1,218 @@ +.. _access_control_permissions: + +************** +Permissions +************** + +The following table displays the access control permissions: + ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| **Permission** | **Description** | ++====================+=========================================================================================================================+ +| **Object/Layer: All Databases** | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| ``LOGIN`` | use role to log into the system (the role also needs connect permission on the database it is connecting to) | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| ``PASSWORD`` | the password used for logging into the system | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| ``SUPERUSER`` | no permission restrictions on any activity | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| **Object/Layer: Database** | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| ``SUPERUSER`` | no permission restrictions on any activity within that database (this does not include modifying roles or permissions) | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| ``CONNECT`` | connect to the database | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| ``CREATE`` | create schemas in the database | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| ``CREATE FUNCTION``| create and drop functions | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| **Object/Layer: Schema** | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| ``USAGE`` | allows additional permissions within the schema | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| ``CREATE`` | create tables in the schema | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| **Object/Layer: Table** | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| ``SELECT`` | :ref:`select` from the table | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| ``INSERT`` | :ref:`insert` into the table | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| ``UPDATE`` | UPDATE the value of certain columns in existing rows without creating a table | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| ``DELETE`` | :ref:`delete` and :ref:`truncate` on the table | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| ``DDL`` | drop and alter on the table | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| ``ALL`` | all the table permissions | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| **Object/Layer: Function** | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| ``EXECUTE`` | use the function | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| ``DDL`` | drop and alter on the function | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ +| ``ALL`` | all function permissions | ++--------------------+-------------------------------------------------------------------------------------------------------------------------+ + + + + +GRANT +----- + +:ref:`grant` gives permissions to a role. + +.. code-block:: postgres + + -- Grant permissions at the instance/ storage cluster level: + GRANT + + { SUPERUSER + | LOGIN + | PASSWORD '' + } + TO [, ...] + + -- Grant permissions at the database level: + GRANT {{CREATE | CONNECT| DDL | SUPERUSER | CREATE FUNCTION} [, ...] | ALL [PERMISSIONS]} + + ON DATABASE [, ...] + TO [, ...] + + -- Grant permissions at the schema level: + GRANT {{ CREATE | DDL | USAGE | SUPERUSER } [, ...] | ALL [ + PERMISSIONS ]} + ON SCHEMA [, ...] + TO [, ...] + + -- Grant permissions at the object level: + GRANT {{SELECT | INSERT | DELETE | DDL } [, ...] | ALL [PERMISSIONS]} + ON { TABLE [, ...] | ALL TABLES IN SCHEMA [, ...]} + TO [, ...] + + -- Grant execute function permission: + GRANT {ALL | EXECUTE | DDL} ON FUNCTION function_name + TO role; + + -- Allows role2 to use permissions granted to role1 + GRANT [, ...] + TO + + -- Also allows the role2 to grant role1 to other roles: + GRANT [, ...] + TO + WITH ADMIN OPTION + +``GRANT`` examples: + +.. code-block:: postgres + + GRANT LOGIN,superuser TO admin; + + GRANT CREATE FUNCTION ON database master TO admin; + + GRANT SELECT ON TABLE admin.table1 TO userA; + + GRANT EXECUTE ON FUNCTION my_function TO userA; + + GRANT ALL ON FUNCTION my_function TO userA; + + GRANT DDL ON admin.main_table TO userB; + + GRANT ALL ON all tables IN schema public TO userB; + + GRANT admin TO userC; + + GRANT superuser ON schema demo TO userA + + GRANT admin_role TO userB; + +REVOKE +------ + +:ref:`revoke` removes permissions from a role. + +.. code-block:: postgres + + -- Revoke permissions at the instance/ storage cluster level: + REVOKE + { SUPERUSER + | LOGIN + | PASSWORD + } + FROM [, ...] + + -- Revoke permissions at the database level: + REVOKE {{CREATE | CONNECT | DDL | SUPERUSER | CREATE FUNCTION}[, ...] |ALL [PERMISSIONS]} + ON DATABASE [, ...] + FROM [, ...] + + -- Revoke permissions at the schema level: + REVOKE { { CREATE | DDL | USAGE | SUPERUSER } [, ...] | ALL [PERMISSIONS]} + ON SCHEMA [, ...] + FROM [, ...] + + -- Revoke permissions at the object level: + REVOKE { { SELECT | INSERT | DELETE | DDL } [, ...] | ALL } + ON { [ TABLE ] [, ...] | ALL TABLES IN SCHEMA + + [, ...] } + FROM [, ...] + + -- Removes access to permissions in role1 by role 2 + REVOKE [, ...] FROM [, ...] WITH ADMIN OPTION + + -- Removes permissions to grant role1 to additional roles from role2 + REVOKE [, ...] FROM [, ...] WITH ADMIN OPTION + + +Examples: + +.. code-block:: postgres + + REVOKE superuser on schema demo from userA; + + REVOKE delete on admin.table1 from userB; + + REVOKE login from role_test; + + REVOKE CREATE FUNCTION FROM admin; + +Default permissions +------------------- + +The default permissions system (See :ref:`alter_default_permissions`) +can be used to automatically grant permissions to newly +created objects (See the departmental example below for one way it can be used). + +A default permissions rule looks for a schema being created, or a +table (possibly by schema), and is table to grant any permission to +that object to any role. This happens when the create table or create +schema statement is run. + + +.. code-block:: postgres + + + ALTER DEFAULT PERMISSIONS FOR target_role_name + [IN schema_name, ...] + FOR { TABLES | SCHEMAS } + { grant_clause | DROP grant_clause} + TO ROLE { role_name | public }; + + grant_clause ::= + GRANT + { CREATE FUNCTION + | SUPERUSER + | CONNECT + | CREATE + | USAGE + | SELECT + | INSERT + | DELETE + | DDL + | EXECUTE + | ALL + } \ No newline at end of file diff --git a/releases/2022.1.1.rst b/releases/2022.1.1.rst new file mode 100644 index 000000000..8e90524ef --- /dev/null +++ b/releases/2022.1.1.rst @@ -0,0 +1,115 @@ +.. _2022.1.1: + +************************** +Release Notes 2022.1.1 +************************** +The 2022.1.1 patch release notes were released on 7/28/2022 and describe the following: + +.. contents:: + :local: + :depth: 1 + +Version Content +---------- +The **Version Content** section is not relevant to the 2022.1.1 patch release notes. + +New Features +---------- +The 2022.1 Release Notes include the following new features: + +.. contents:: + :local: + :depth: 1 + +Automatically Identifying Schemas when Mapping Foreign Tables +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +SQream can now automatically identify the corresponding schema, avoiding complex error-prone DDL operations, saving you the time and effort required to build your schema manually. This is especially useful for particular file formats, such as Parquet, which include a built-in schema declaration. In addition, this feature improves user experience by letting you quickly load foreign tables without specifying hundred of columns. + +For more information, see :ref:`automatic_schema_identification`. + +Password Policy +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +SQream has implemented a strong password policy required when accessing the CLI or Studio. + +For more information, see :ref:`access_control_password_policy`. + +Resolved Issues +--------- +The following table lists the issues that were resolved in the 2022.1.1 patch release: + ++-------------+-----------------------------------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+=======================================================================================================================+ +| SQ-6419 | An internal compiler error occurred when casting a numeric literal in an aggregation function. | ++-------------+-----------------------------------------------------------------------------------------------------------------------+ +| SQ-10873 | Inserting 100K bytes into a ``TEXT`` column resulted in an unclear error message. | ++-------------+-----------------------------------------------------------------------------------------------------------------------+ +| SQ-10886 | An internal compiler error occurred during the compilation process. | ++-------------+-----------------------------------------------------------------------------------------------------------------------+ +| SQ-10892 | The error message displayed when ``UPDATE`` is run on a foreign table was corrected. | ++-------------+-----------------------------------------------------------------------------------------------------------------------+ +| SQ-10955 | Unneeded reads occured when filtering by date. | ++-------------+-----------------------------------------------------------------------------------------------------------------------+ + +Known Issues +--------- +The **Known Issues** section is not relevant to Version 2022.1.1. + +Operations and Configuration Changes +-------- +The **Operations and Configuration Changes** section is not relevant to the 2022.1.1 patch release notes. + +Naming Changes +------- +The **Naming Changes** section is not relevant to the 2022.1.1 patch release notes. + +Deprecated Features +------- +The **Deprecated Features** section is not relevant to the 2022.1.1 patch release. + +End of Support +------- +The **End of Support** section is not relevant to the 2022.1.1 patch release. + +Upgrading to v2022.1.1 +------- +1. Generate a back-up of the metadata by running the following command: + + .. code-block:: console + + $ select backup_metadata('out_path'); + + .. tip:: SQream recommends storing the generated back-up locally in case needed. + + SQream runs the Garbage Collector and creates a clean backup tarball package. + +2. Shut down all SQream services. + + :: + +3. Extract the recently created back-up file. + + :: + +4. Replace your current metadata with the metadata you stored in the back-up file. + + :: + +5. Navigate to the new SQream package bin folder. + + :: + +6. Run the following command: + + .. code-block:: console + + $ ./upgrade_storage + + .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in **Step 7** of the Upgrading SQream Version procedure. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2022.1.1 \ No newline at end of file diff --git a/releases/2022.1_index.rst b/releases/2022.1_index.rst new file mode 100644 index 000000000..628b372aa --- /dev/null +++ b/releases/2022.1_index.rst @@ -0,0 +1,17 @@ +.. _2022.1_index: + +************************** +Release Notes 2022.1 +************************** +The 2022.1 Release Notes describe the following releases: + +.. contents:: + :local: + :depth: 1 + +.. toctree:: + :maxdepth: 1 + :glob: + + 2022.1.1 + 2022.1 \ No newline at end of file From 16eab5d2b00fbdb1ffe8b66329bca9efaa64650b Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 14:18:06 +0300 Subject: [PATCH 162/316] Added 2022.1_index to main RN index --- releases/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releases/index.rst b/releases/index.rst index b1d065a9e..84024586e 100644 --- a/releases/index.rst +++ b/releases/index.rst @@ -32,7 +32,7 @@ Release Notes :glob: :hidden: - 2022.1 + 2022.1_index 2021.2_index 2021.1_index 2020.3_index From 7d1d837fe0616a5dbc24cbb4c9eb12e3853a45b6 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 14:24:05 +0300 Subject: [PATCH 163/316] Added Auto Schema Identification --- .../automatic_schema_identification.rst | 46 +++++++++++++++++++ feature_guides/index.rst | 1 + 2 files changed, 47 insertions(+) create mode 100644 feature_guides/automatic_schema_identification.rst diff --git a/feature_guides/automatic_schema_identification.rst b/feature_guides/automatic_schema_identification.rst new file mode 100644 index 000000000..e2089143e --- /dev/null +++ b/feature_guides/automatic_schema_identification.rst @@ -0,0 +1,46 @@ +.. _automatic_schema_identification: + +*********************** +Automatic Schema Identification +*********************** +The **Automatic Schema Identification** page describes the following: + +.. contents:: + :local: + :depth: 1 + +Overview +---------- +SQream must be able to access a schema when reading and mapping external files to a foreign table. To facilitate this, you must specify the correct schema in the statement that creates the foreign table, which must also include the correct list of columns. To avoid human error related to this complex process SQream can now automatically identify the corresponding schema, saving you the time and effort required to build your schema manually. This is especially useful for particular file formats, such as Parquet, which include a built-in schema declaration. + +Usage Notes +---------- +The automatic schema identification feature supports Parquet, ORC, and Avro files, while using it with CSV files generates an error. You can activate this feature when you create a foreign table by omitting the column list, described in the **Syntax** section below. + +Using this feature the path you specify in the ``LOCATION`` option must point to at least one existing file. If no files exist for the schema to read, an error will be generated. You can specify the schema manually even in the event of the error above. + +.. note:: When using this feature, SQream assumes that all files in the path use the same schema. + +Syntax +---------- +The following is the syntax for using the automatic schema identification feature: + +.. code-block:: console + + CREATE FOREIGN TABLE table_name + [FOREIGN DATA] WRAPPER fdw_name + [OPTIONS (...)]; + +Example +---------- +The following is an example of using the automatic schema identification feature: + +.. code-block:: console + + create foreign table parquet_table + wrapper parquet_fdw + options (location = '/tmp/file.parquet'); + +Permissions +---------- +The Automatic Schema Identification feature requires **Read** permissions. \ No newline at end of file diff --git a/feature_guides/index.rst b/feature_guides/index.rst index d70ceb705..d1a0c7fc3 100644 --- a/feature_guides/index.rst +++ b/feature_guides/index.rst @@ -12,6 +12,7 @@ This section describes the following features: :titlesonly: query_healer + automatic_schema_identification data_encryption compression python_functions From aa11873d48cbaecb9eeaa41e4a39a14d089f3bff Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 15:23:25 +0300 Subject: [PATCH 164/316] Updated --- .../automatic_schema_identification.rst | 46 ------------------- feature_guides/index.rst | 1 - releases/2022.1.1.rst | 6 --- 3 files changed, 53 deletions(-) delete mode 100644 feature_guides/automatic_schema_identification.rst diff --git a/feature_guides/automatic_schema_identification.rst b/feature_guides/automatic_schema_identification.rst deleted file mode 100644 index e2089143e..000000000 --- a/feature_guides/automatic_schema_identification.rst +++ /dev/null @@ -1,46 +0,0 @@ -.. _automatic_schema_identification: - -*********************** -Automatic Schema Identification -*********************** -The **Automatic Schema Identification** page describes the following: - -.. contents:: - :local: - :depth: 1 - -Overview ----------- -SQream must be able to access a schema when reading and mapping external files to a foreign table. To facilitate this, you must specify the correct schema in the statement that creates the foreign table, which must also include the correct list of columns. To avoid human error related to this complex process SQream can now automatically identify the corresponding schema, saving you the time and effort required to build your schema manually. This is especially useful for particular file formats, such as Parquet, which include a built-in schema declaration. - -Usage Notes ----------- -The automatic schema identification feature supports Parquet, ORC, and Avro files, while using it with CSV files generates an error. You can activate this feature when you create a foreign table by omitting the column list, described in the **Syntax** section below. - -Using this feature the path you specify in the ``LOCATION`` option must point to at least one existing file. If no files exist for the schema to read, an error will be generated. You can specify the schema manually even in the event of the error above. - -.. note:: When using this feature, SQream assumes that all files in the path use the same schema. - -Syntax ----------- -The following is the syntax for using the automatic schema identification feature: - -.. code-block:: console - - CREATE FOREIGN TABLE table_name - [FOREIGN DATA] WRAPPER fdw_name - [OPTIONS (...)]; - -Example ----------- -The following is an example of using the automatic schema identification feature: - -.. code-block:: console - - create foreign table parquet_table - wrapper parquet_fdw - options (location = '/tmp/file.parquet'); - -Permissions ----------- -The Automatic Schema Identification feature requires **Read** permissions. \ No newline at end of file diff --git a/feature_guides/index.rst b/feature_guides/index.rst index d1a0c7fc3..d70ceb705 100644 --- a/feature_guides/index.rst +++ b/feature_guides/index.rst @@ -12,7 +12,6 @@ This section describes the following features: :titlesonly: query_healer - automatic_schema_identification data_encryption compression python_functions diff --git a/releases/2022.1.1.rst b/releases/2022.1.1.rst index 8e90524ef..08843f380 100644 --- a/releases/2022.1.1.rst +++ b/releases/2022.1.1.rst @@ -21,12 +21,6 @@ The 2022.1 Release Notes include the following new features: :local: :depth: 1 -Automatically Identifying Schemas when Mapping Foreign Tables -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -SQream can now automatically identify the corresponding schema, avoiding complex error-prone DDL operations, saving you the time and effort required to build your schema manually. This is especially useful for particular file formats, such as Parquet, which include a built-in schema declaration. In addition, this feature improves user experience by letting you quickly load foreign tables without specifying hundred of columns. - -For more information, see :ref:`automatic_schema_identification`. - Password Policy ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SQream has implemented a strong password policy required when accessing the CLI or Studio. From 4b0631f94889c9c1ef7c30c274ebacb372b8d131 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 15:34:57 +0300 Subject: [PATCH 165/316] REverted --- releases/2022.1.1.rst | 109 -------------------------------------- releases/2022.1_index.rst | 1 - releases/index.rst | 2 +- 3 files changed, 1 insertion(+), 111 deletions(-) delete mode 100644 releases/2022.1.1.rst diff --git a/releases/2022.1.1.rst b/releases/2022.1.1.rst deleted file mode 100644 index 08843f380..000000000 --- a/releases/2022.1.1.rst +++ /dev/null @@ -1,109 +0,0 @@ -.. _2022.1.1: - -************************** -Release Notes 2022.1.1 -************************** -The 2022.1.1 patch release notes were released on 7/28/2022 and describe the following: - -.. contents:: - :local: - :depth: 1 - -Version Content ----------- -The **Version Content** section is not relevant to the 2022.1.1 patch release notes. - -New Features ----------- -The 2022.1 Release Notes include the following new features: - -.. contents:: - :local: - :depth: 1 - -Password Policy -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -SQream has implemented a strong password policy required when accessing the CLI or Studio. - -For more information, see :ref:`access_control_password_policy`. - -Resolved Issues ---------- -The following table lists the issues that were resolved in the 2022.1.1 patch release: - -+-------------+-----------------------------------------------------------------------------------------------------------------------+ -| **SQ No.** | **Description** | -+=============+=======================================================================================================================+ -| SQ-6419 | An internal compiler error occurred when casting a numeric literal in an aggregation function. | -+-------------+-----------------------------------------------------------------------------------------------------------------------+ -| SQ-10873 | Inserting 100K bytes into a ``TEXT`` column resulted in an unclear error message. | -+-------------+-----------------------------------------------------------------------------------------------------------------------+ -| SQ-10886 | An internal compiler error occurred during the compilation process. | -+-------------+-----------------------------------------------------------------------------------------------------------------------+ -| SQ-10892 | The error message displayed when ``UPDATE`` is run on a foreign table was corrected. | -+-------------+-----------------------------------------------------------------------------------------------------------------------+ -| SQ-10955 | Unneeded reads occured when filtering by date. | -+-------------+-----------------------------------------------------------------------------------------------------------------------+ - -Known Issues ---------- -The **Known Issues** section is not relevant to Version 2022.1.1. - -Operations and Configuration Changes --------- -The **Operations and Configuration Changes** section is not relevant to the 2022.1.1 patch release notes. - -Naming Changes -------- -The **Naming Changes** section is not relevant to the 2022.1.1 patch release notes. - -Deprecated Features -------- -The **Deprecated Features** section is not relevant to the 2022.1.1 patch release. - -End of Support -------- -The **End of Support** section is not relevant to the 2022.1.1 patch release. - -Upgrading to v2022.1.1 -------- -1. Generate a back-up of the metadata by running the following command: - - .. code-block:: console - - $ select backup_metadata('out_path'); - - .. tip:: SQream recommends storing the generated back-up locally in case needed. - - SQream runs the Garbage Collector and creates a clean backup tarball package. - -2. Shut down all SQream services. - - :: - -3. Extract the recently created back-up file. - - :: - -4. Replace your current metadata with the metadata you stored in the back-up file. - - :: - -5. Navigate to the new SQream package bin folder. - - :: - -6. Run the following command: - - .. code-block:: console - - $ ./upgrade_storage - - .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in **Step 7** of the Upgrading SQream Version procedure. - -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2022.1.1 \ No newline at end of file diff --git a/releases/2022.1_index.rst b/releases/2022.1_index.rst index 628b372aa..9c7b2b211 100644 --- a/releases/2022.1_index.rst +++ b/releases/2022.1_index.rst @@ -13,5 +13,4 @@ The 2022.1 Release Notes describe the following releases: :maxdepth: 1 :glob: - 2022.1.1 2022.1 \ No newline at end of file diff --git a/releases/index.rst b/releases/index.rst index 84024586e..b1d065a9e 100644 --- a/releases/index.rst +++ b/releases/index.rst @@ -32,7 +32,7 @@ Release Notes :glob: :hidden: - 2022.1_index + 2022.1 2021.2_index 2021.1_index 2020.3_index From ab5f5c6a3f3bf913e9f19cce2a6c6387e403e2d1 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 15:58:22 +0300 Subject: [PATCH 166/316] Updated --- releases/2022.1_index.rst | 1 + releases/index.rst | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/releases/2022.1_index.rst b/releases/2022.1_index.rst index 9c7b2b211..628b372aa 100644 --- a/releases/2022.1_index.rst +++ b/releases/2022.1_index.rst @@ -13,4 +13,5 @@ The 2022.1 Release Notes describe the following releases: :maxdepth: 1 :glob: + 2022.1.1 2022.1 \ No newline at end of file diff --git a/releases/index.rst b/releases/index.rst index b1d065a9e..84024586e 100644 --- a/releases/index.rst +++ b/releases/index.rst @@ -32,7 +32,7 @@ Release Notes :glob: :hidden: - 2022.1 + 2022.1_index 2021.2_index 2021.1_index 2020.3_index From 98028f90d4a7d65a6df75d0a0bbcf3633c17df57 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 16:09:45 +0300 Subject: [PATCH 167/316] Create 2022.1.1.rst --- releases/2022.1.1.rst | 109 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 releases/2022.1.1.rst diff --git a/releases/2022.1.1.rst b/releases/2022.1.1.rst new file mode 100644 index 000000000..08843f380 --- /dev/null +++ b/releases/2022.1.1.rst @@ -0,0 +1,109 @@ +.. _2022.1.1: + +************************** +Release Notes 2022.1.1 +************************** +The 2022.1.1 patch release notes were released on 7/28/2022 and describe the following: + +.. contents:: + :local: + :depth: 1 + +Version Content +---------- +The **Version Content** section is not relevant to the 2022.1.1 patch release notes. + +New Features +---------- +The 2022.1 Release Notes include the following new features: + +.. contents:: + :local: + :depth: 1 + +Password Policy +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +SQream has implemented a strong password policy required when accessing the CLI or Studio. + +For more information, see :ref:`access_control_password_policy`. + +Resolved Issues +--------- +The following table lists the issues that were resolved in the 2022.1.1 patch release: + ++-------------+-----------------------------------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+=======================================================================================================================+ +| SQ-6419 | An internal compiler error occurred when casting a numeric literal in an aggregation function. | ++-------------+-----------------------------------------------------------------------------------------------------------------------+ +| SQ-10873 | Inserting 100K bytes into a ``TEXT`` column resulted in an unclear error message. | ++-------------+-----------------------------------------------------------------------------------------------------------------------+ +| SQ-10886 | An internal compiler error occurred during the compilation process. | ++-------------+-----------------------------------------------------------------------------------------------------------------------+ +| SQ-10892 | The error message displayed when ``UPDATE`` is run on a foreign table was corrected. | ++-------------+-----------------------------------------------------------------------------------------------------------------------+ +| SQ-10955 | Unneeded reads occured when filtering by date. | ++-------------+-----------------------------------------------------------------------------------------------------------------------+ + +Known Issues +--------- +The **Known Issues** section is not relevant to Version 2022.1.1. + +Operations and Configuration Changes +-------- +The **Operations and Configuration Changes** section is not relevant to the 2022.1.1 patch release notes. + +Naming Changes +------- +The **Naming Changes** section is not relevant to the 2022.1.1 patch release notes. + +Deprecated Features +------- +The **Deprecated Features** section is not relevant to the 2022.1.1 patch release. + +End of Support +------- +The **End of Support** section is not relevant to the 2022.1.1 patch release. + +Upgrading to v2022.1.1 +------- +1. Generate a back-up of the metadata by running the following command: + + .. code-block:: console + + $ select backup_metadata('out_path'); + + .. tip:: SQream recommends storing the generated back-up locally in case needed. + + SQream runs the Garbage Collector and creates a clean backup tarball package. + +2. Shut down all SQream services. + + :: + +3. Extract the recently created back-up file. + + :: + +4. Replace your current metadata with the metadata you stored in the back-up file. + + :: + +5. Navigate to the new SQream package bin folder. + + :: + +6. Run the following command: + + .. code-block:: console + + $ ./upgrade_storage + + .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in **Step 7** of the Upgrading SQream Version procedure. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2022.1.1 \ No newline at end of file From 41d91c9eb25c7627eae74b8c26abbbbc95e61970 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 18:18:51 +0300 Subject: [PATCH 168/316] Updated --- releases/2022.1.rst | 137 -------------------------------------- releases/2022.1_index.rst | 1 - releases/index.rst | 2 +- 3 files changed, 1 insertion(+), 139 deletions(-) delete mode 100644 releases/2022.1.rst diff --git a/releases/2022.1.rst b/releases/2022.1.rst deleted file mode 100644 index 3c5ae24e6..000000000 --- a/releases/2022.1.rst +++ /dev/null @@ -1,137 +0,0 @@ -.. _2022.1: - -************************** -Release Notes 2022.1 -************************** -The 2022.1 release notes were released on 7/19/2022 and describe the following: - -.. contents:: - :local: - :depth: 1 - -Version Content ----------- -The 2022.1 Release Notes describes the following: - -* Enhanced security features. -* New data manipulation command. -* Additional data ingestion format. - -New Features ----------- -The 2022.1 Release Notes include the following new features: - -.. contents:: - :local: - :depth: 1 - -Data Encryption -************ -SQream now supports data encryption mechanisms in accordance with **General Data Protection Regulation (GDPR)** standards. - -Using the data encryption feature may lead to a maximum of a 10% increase in performance degradation. - -For more information, see `Data Encryption `_. - -Update Feature -************ -SQream now supports the DML **Update** feature, which is used for modifying the value of certain columns in existing rows. - -For more information, see `UPDATE `_. - -Avro Ingestion -************ -SQream now supports ingesting data from Avro files. - -For more information, see `Inserting Data from Avro `_. - -Known Issues ---------- -The following table lists the known issues for Version 2022.1: - -+-------------+-------------------------------------------------------------------------------------------+ -| **SQ No.** | **Description** | -+=============+===========================================================================================+ -| SQ-7732 | Reading numeric columns from an external Parquet file generated an error. | -+-------------+-------------------------------------------------------------------------------------------+ -| SQ-9889 | Running a query including Thai characters generated an internal runtime error. | -+-------------+-------------------------------------------------------------------------------------------+ -| SQ-10071 | Error on existing subqueries with TEXT and VARCHAR equality condition | -+-------------+-------------------------------------------------------------------------------------------+ -| SQ-10191 | The ``ALTER DEFAULT SCHEMA`` command was not functioning correctly. | -+-------------+-------------------------------------------------------------------------------------------+ -| SQ-10629 | Inserting data into a table significantly slowed down running queries. | -+-------------+-------------------------------------------------------------------------------------------+ -| SQ-10659 | Using a comment generated a compile error. | -+-------------+-------------------------------------------------------------------------------------------+ - -Resolved Issues ---------- -The following table lists the issues that were resolved in Version 2022.1: - -+-------------+-------------------------------------------------------------------------------------------+ -| **SQ No.** | **Description** | -+=============+===========================================================================================+ -| SQ-10111 | Reading numeric columns from an external Parquet file generated an error. | -+-------------+-------------------------------------------------------------------------------------------+ - -Operations and Configuration Changes --------- -No relevant operations and configuration changes were made. - -Naming Changes -------- -No relevant naming changes were made. - -Deprecated Features -------- -In SQream version 2022.1 the ``VARCHAR`` data type has been deprecated and replaced with ``TEXT``. SQream will maintain ``VARCHAR`` in all previous versions until completing the migration to ``TEXT``, at which point it will be deprecated in all earlier versions. SQream also provides an automated and secure tool to facilitate and simplify migration from ``VARCHAR`` to ``TEXT``. - -If you are using an earlier version of SQream, see the `Using Legacy String Literals `_ configuration flag. - -End of Support -------- -The End of Support section is not relevant to Version 2022.1. - -Upgrading to v2022.1 -------- -1. Generate a back-up of the metadata by running the following command: - - .. code-block:: console - - $ select backup_metadata('out_path'); - - .. tip:: SQream recommends storing the generated back-up locally in case needed. - - SQream runs the Garbage Collector and creates a clean backup tarball package. - -2. Shut down all SQream services. - - :: - -3. Extract the recently created back-up file. - - :: - -4. Replace your current metadata with the metadata you stored in the back-up file. - - :: - -5. Navigate to the new SQream package bin folder. - - :: - -6. Run the following command: - - .. code-block:: console - - $ ./upgrade_storage - - .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version `_ procedure. - -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2022.1 diff --git a/releases/2022.1_index.rst b/releases/2022.1_index.rst index 628b372aa..9c7b2b211 100644 --- a/releases/2022.1_index.rst +++ b/releases/2022.1_index.rst @@ -13,5 +13,4 @@ The 2022.1 Release Notes describe the following releases: :maxdepth: 1 :glob: - 2022.1.1 2022.1 \ No newline at end of file diff --git a/releases/index.rst b/releases/index.rst index 84024586e..b1d065a9e 100644 --- a/releases/index.rst +++ b/releases/index.rst @@ -32,7 +32,7 @@ Release Notes :glob: :hidden: - 2022.1_index + 2022.1 2021.2_index 2021.1_index 2020.3_index From e30d16380d31cc4ae9184406691e9d43881b3143 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 18:30:29 +0300 Subject: [PATCH 169/316] Update index.rst --- releases/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releases/index.rst b/releases/index.rst index b1d065a9e..84024586e 100644 --- a/releases/index.rst +++ b/releases/index.rst @@ -32,7 +32,7 @@ Release Notes :glob: :hidden: - 2022.1 + 2022.1_index 2021.2_index 2021.1_index 2020.3_index From 0ba6ce89dd90cee3feedab870658b8a89dae46d4 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 18:32:24 +0300 Subject: [PATCH 170/316] Update index.rst --- releases/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releases/index.rst b/releases/index.rst index 84024586e..b1d065a9e 100644 --- a/releases/index.rst +++ b/releases/index.rst @@ -32,7 +32,7 @@ Release Notes :glob: :hidden: - 2022.1_index + 2022.1 2021.2_index 2021.1_index 2020.3_index From 534c19e397a4ee85e1b50b6d7e3da3e4b9355a33 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 18:33:06 +0300 Subject: [PATCH 171/316] Update index.rst --- releases/index.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/releases/index.rst b/releases/index.rst index b1d065a9e..b3cfb3900 100644 --- a/releases/index.rst +++ b/releases/index.rst @@ -12,8 +12,6 @@ Release Notes * - Version - Release Date - * - :ref:`2022.1` - - July 19, 2022 * - :ref:`2021.2` - September 13, 2021 * - :ref:`2021.1` @@ -32,7 +30,6 @@ Release Notes :glob: :hidden: - 2022.1 2021.2_index 2021.1_index 2020.3_index From 3f84a22424552289d179fd5024d945d23f2617b3 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 18:36:17 +0300 Subject: [PATCH 172/316] Update index.rst --- releases/index.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/releases/index.rst b/releases/index.rst index b3cfb3900..b1d065a9e 100644 --- a/releases/index.rst +++ b/releases/index.rst @@ -12,6 +12,8 @@ Release Notes * - Version - Release Date + * - :ref:`2022.1` + - July 19, 2022 * - :ref:`2021.2` - September 13, 2021 * - :ref:`2021.1` @@ -30,6 +32,7 @@ Release Notes :glob: :hidden: + 2022.1 2021.2_index 2021.1_index 2020.3_index From b649c40d4ea124d95ded76c3c151142c161e424a Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 28 Jul 2022 18:40:49 +0300 Subject: [PATCH 173/316] Create 2022.1.rst --- releases/2022.1.rst | 137 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 releases/2022.1.rst diff --git a/releases/2022.1.rst b/releases/2022.1.rst new file mode 100644 index 000000000..cdd6d98c5 --- /dev/null +++ b/releases/2022.1.rst @@ -0,0 +1,137 @@ +.. _2022.1: + +************************** +Release Notes 2022.1 +************************** +The 2022.1 release notes were released on 7/19/2022 and describe the following: + +.. contents:: + :local: + :depth: 1 + +Version Content +---------- +The 2022.1 Release Notes describes the following: + +* Enhanced security features. +* New data manipulation command. +* Additional data ingestion format. + +New Features +---------- +The 2022.1 Release Notes include the following new features: + +.. contents:: + :local: + :depth: 1 + +Data Encryption +************ +SQream now supports data encryption mechanisms in accordance with **General Data Protection Regulation (GDPR)** standards. + +Using the data encryption feature may lead to a maximum of a 10% increase in performance degradation. + +For more information, see `Data Encryption `_. + +Update Feature +************ +SQream now supports the DML **Update** feature, which is used for modifying the value of certain columns in existing rows. + +For more information, see `UPDATE `_. + +Avro Ingestion +************ +SQream now supports ingesting data from Avro files. + +For more information, see `Inserting Data from Avro `_. + +Known Issues +--------- +The following table lists the known issues for Version 2022.1: + ++-------------+-------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+===========================================================================================+ +| SQ-7732 | Reading numeric columns from an external Parquet file generated an error. | ++-------------+-------------------------------------------------------------------------------------------+ +| SQ-9889 | Running a query including Thai characters generated an internal runtime error. | ++-------------+-------------------------------------------------------------------------------------------+ +| SQ-10071 | Error on existing subqueries with TEXT and VARCHAR equality condition | ++-------------+-------------------------------------------------------------------------------------------+ +| SQ-10191 | The ``ALTER DEFAULT SCHEMA`` command was not functioning correctly. | ++-------------+-------------------------------------------------------------------------------------------+ +| SQ-10629 | Inserting data into a table significantly slowed down running queries. | ++-------------+-------------------------------------------------------------------------------------------+ +| SQ-10659 | Using a comment generated a compile error. | ++-------------+-------------------------------------------------------------------------------------------+ + +Resolved Issues +--------- +The following table lists the issues that were resolved in Version 2022.1: + ++-------------+-------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+===========================================================================================+ +| SQ-10111 | Reading numeric columns from an external Parquet file generated an error. | ++-------------+-------------------------------------------------------------------------------------------+ + +Operations and Configuration Changes +-------- +No relevant operations and configuration changes were made. + +Naming Changes +------- +No relevant naming changes were made. + +Deprecated Features +------- +In SQream version 2022.1 the ``VARCHAR`` data type has been deprecated and replaced with ``TEXT``. SQream will maintain ``VARCHAR`` in all previous versions until completing the migration to ``TEXT``, at which point it will be deprecated in all earlier versions. SQream also provides an automated and secure tool to facilitate and simplify migration from ``VARCHAR`` to ``TEXT``. + +If you are using an earlier version of SQream, see the `Using Legacy String Literals `_ configuration flag. + +End of Support +------- +The End of Support section is not relevant to Version 2022.1. + +Upgrading to v2022.1 +------- +1. Generate a back-up of the metadata by running the following command: + + .. code-block:: console + + $ select backup_metadata('out_path'); + + .. tip:: SQream recommends storing the generated back-up locally in case needed. + + SQream runs the Garbage Collector and creates a clean backup tarball package. + +2. Shut down all SQream services. + + :: + +3. Extract the recently created back-up file. + + :: + +4. Replace your current metadata with the metadata you stored in the back-up file. + + :: + +5. Navigate to the new SQream package bin folder. + + :: + +6. Run the following command: + + .. code-block:: console + + $ ./upgrade_storage + + .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version `_ procedure. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2022.1 From 174f17de04347f32e5a8e6007e67be838b4580ff Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 31 Jul 2022 10:12:57 +0300 Subject: [PATCH 174/316] Removed Healer Toggle (2022.1.1) --- configuration_guides/admin_worker_flags.rst | 1 - .../healer_max_inactivity_hours.rst | 4 +- configuration_guides/is_healer_on.rst | 14 --- feature_guides/query_healer.rst | 18 +-- releases/2022.1.1.rst | 109 ------------------ 5 files changed, 3 insertions(+), 143 deletions(-) delete mode 100644 configuration_guides/is_healer_on.rst delete mode 100644 releases/2022.1.1.rst diff --git a/configuration_guides/admin_worker_flags.rst b/configuration_guides/admin_worker_flags.rst index 453c66af8..6b7a74b9e 100644 --- a/configuration_guides/admin_worker_flags.rst +++ b/configuration_guides/admin_worker_flags.rst @@ -9,6 +9,5 @@ The **Worker Administration Flags** page describes **Worker** modification type * `Enabling Manually Setting Reported IP `_ * `Setting Port Used for Metadata Server Connection `_ * `Assigning Local Network IP `_ -* `Enabling the Query Healer `_ * `Configuring the Query Healer `_ * `Adjusting Permitted Log-in Attempts `_ \ No newline at end of file diff --git a/configuration_guides/healer_max_inactivity_hours.rst b/configuration_guides/healer_max_inactivity_hours.rst index 56ddb78fc..1ff8ddaa6 100644 --- a/configuration_guides/healer_max_inactivity_hours.rst +++ b/configuration_guides/healer_max_inactivity_hours.rst @@ -9,6 +9,4 @@ The following describes the ``healerMaxInactivityHours`` flag: * **Data type** - size_t * **Default value** - ``5`` -* **Allowed values** - 1-4000000000 - -For related flags, see :ref:`is_healer_on`. \ No newline at end of file +* **Allowed values** - 1-4000000000 \ No newline at end of file diff --git a/configuration_guides/is_healer_on.rst b/configuration_guides/is_healer_on.rst deleted file mode 100644 index 8b90654ec..000000000 --- a/configuration_guides/is_healer_on.rst +++ /dev/null @@ -1,14 +0,0 @@ -.. _is_healer_on: - -************************* -Enabling the Query Healer -************************* -The ``is_healer_on`` flag enables the Query Healer, which periodically examines the progress of running statements and logs statements exceeding the ``healerMaxInactivityHours`` flag setting. - -The following describes the ``is_healer_on`` flag: - -* **Data type** - boolean -* **Default value** - ``true`` -* **Allowed values** - ``true``, ``false`` - -For related flags, see :ref:`healer_max_inactivity_hours`. \ No newline at end of file diff --git a/feature_guides/query_healer.rst b/feature_guides/query_healer.rst index cb50549b8..380b1558f 100644 --- a/feature_guides/query_healer.rst +++ b/feature_guides/query_healer.rst @@ -21,20 +21,6 @@ The following is an example of a log record for a query stuck in the query detec Configuring the Healer ------------------ -The following flags are required to configure the Query Healer: +The **healerMaxInactivityHours** is required define the threshold for creating a log recording a slow statement. The log includes information about the log memory, CPU and GPU. The ``healerMaxInactivityHours`` log frequency is calculated as 5% of the flag setting. For example, setting ``healerMaxInactivityHours`` to five hours (the default setting) triggers an examination every 15 minutes. - * **isHealerOn** - Enables the Query Healer. - - :: - - * **healerMaxInactivityHours** - Defines the threshold for creating a log recording a slow statement. The log includes information about the log memory, CPU and GPU. - -The ``healerMaxInactivityHours`` log frequency is calculated as 5% of the flag setting. For example, setting ``healerMaxInactivityHours`` to five hours (the default setting) triggers an examination every 15 minutes. - -For more information, see the following Administration Worker flags: - - * :ref:`is_healer_on` - - :: - - * :ref:`healer_max_inactivity_hours` \ No newline at end of file +For more information, see :ref:`healer_max_inactivity_hours`. \ No newline at end of file diff --git a/releases/2022.1.1.rst b/releases/2022.1.1.rst deleted file mode 100644 index 08843f380..000000000 --- a/releases/2022.1.1.rst +++ /dev/null @@ -1,109 +0,0 @@ -.. _2022.1.1: - -************************** -Release Notes 2022.1.1 -************************** -The 2022.1.1 patch release notes were released on 7/28/2022 and describe the following: - -.. contents:: - :local: - :depth: 1 - -Version Content ----------- -The **Version Content** section is not relevant to the 2022.1.1 patch release notes. - -New Features ----------- -The 2022.1 Release Notes include the following new features: - -.. contents:: - :local: - :depth: 1 - -Password Policy -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -SQream has implemented a strong password policy required when accessing the CLI or Studio. - -For more information, see :ref:`access_control_password_policy`. - -Resolved Issues ---------- -The following table lists the issues that were resolved in the 2022.1.1 patch release: - -+-------------+-----------------------------------------------------------------------------------------------------------------------+ -| **SQ No.** | **Description** | -+=============+=======================================================================================================================+ -| SQ-6419 | An internal compiler error occurred when casting a numeric literal in an aggregation function. | -+-------------+-----------------------------------------------------------------------------------------------------------------------+ -| SQ-10873 | Inserting 100K bytes into a ``TEXT`` column resulted in an unclear error message. | -+-------------+-----------------------------------------------------------------------------------------------------------------------+ -| SQ-10886 | An internal compiler error occurred during the compilation process. | -+-------------+-----------------------------------------------------------------------------------------------------------------------+ -| SQ-10892 | The error message displayed when ``UPDATE`` is run on a foreign table was corrected. | -+-------------+-----------------------------------------------------------------------------------------------------------------------+ -| SQ-10955 | Unneeded reads occured when filtering by date. | -+-------------+-----------------------------------------------------------------------------------------------------------------------+ - -Known Issues ---------- -The **Known Issues** section is not relevant to Version 2022.1.1. - -Operations and Configuration Changes --------- -The **Operations and Configuration Changes** section is not relevant to the 2022.1.1 patch release notes. - -Naming Changes -------- -The **Naming Changes** section is not relevant to the 2022.1.1 patch release notes. - -Deprecated Features -------- -The **Deprecated Features** section is not relevant to the 2022.1.1 patch release. - -End of Support -------- -The **End of Support** section is not relevant to the 2022.1.1 patch release. - -Upgrading to v2022.1.1 -------- -1. Generate a back-up of the metadata by running the following command: - - .. code-block:: console - - $ select backup_metadata('out_path'); - - .. tip:: SQream recommends storing the generated back-up locally in case needed. - - SQream runs the Garbage Collector and creates a clean backup tarball package. - -2. Shut down all SQream services. - - :: - -3. Extract the recently created back-up file. - - :: - -4. Replace your current metadata with the metadata you stored in the back-up file. - - :: - -5. Navigate to the new SQream package bin folder. - - :: - -6. Run the following command: - - .. code-block:: console - - $ ./upgrade_storage - - .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in **Step 7** of the Upgrading SQream Version procedure. - -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2022.1.1 \ No newline at end of file From 5b4e90d3f75caea97e4036fd38c3a93c2350ef52 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 31 Jul 2022 10:23:34 +0300 Subject: [PATCH 175/316] Removed reference to Healer configuration --- configuration_guides/admin_worker_flags.rst | 1 - configuration_guides/healer_max_inactivity_hours.rst | 12 ------------ feature_guides/query_healer.rst | 4 +--- 3 files changed, 1 insertion(+), 16 deletions(-) delete mode 100644 configuration_guides/healer_max_inactivity_hours.rst diff --git a/configuration_guides/admin_worker_flags.rst b/configuration_guides/admin_worker_flags.rst index 6b7a74b9e..6be021d70 100644 --- a/configuration_guides/admin_worker_flags.rst +++ b/configuration_guides/admin_worker_flags.rst @@ -9,5 +9,4 @@ The **Worker Administration Flags** page describes **Worker** modification type * `Enabling Manually Setting Reported IP `_ * `Setting Port Used for Metadata Server Connection `_ * `Assigning Local Network IP `_ -* `Configuring the Query Healer `_ * `Adjusting Permitted Log-in Attempts `_ \ No newline at end of file diff --git a/configuration_guides/healer_max_inactivity_hours.rst b/configuration_guides/healer_max_inactivity_hours.rst deleted file mode 100644 index 1ff8ddaa6..000000000 --- a/configuration_guides/healer_max_inactivity_hours.rst +++ /dev/null @@ -1,12 +0,0 @@ -.. _healer_max_inactivity_hours: - -************************* -Configuring the Query Healer -************************* -The ``healerMaxInactivityHours`` flag is used for defining the threshold for creating a log recording a slow statement. The log includes information about the log memory, CPU and GPU. - -The following describes the ``healerMaxInactivityHours`` flag: - -* **Data type** - size_t -* **Default value** - ``5`` -* **Allowed values** - 1-4000000000 \ No newline at end of file diff --git a/feature_guides/query_healer.rst b/feature_guides/query_healer.rst index 380b1558f..667a91ed8 100644 --- a/feature_guides/query_healer.rst +++ b/feature_guides/query_healer.rst @@ -21,6 +21,4 @@ The following is an example of a log record for a query stuck in the query detec Configuring the Healer ------------------ -The **healerMaxInactivityHours** is required define the threshold for creating a log recording a slow statement. The log includes information about the log memory, CPU and GPU. The ``healerMaxInactivityHours`` log frequency is calculated as 5% of the flag setting. For example, setting ``healerMaxInactivityHours`` to five hours (the default setting) triggers an examination every 15 minutes. - -For more information, see :ref:`healer_max_inactivity_hours`. \ No newline at end of file +The **healerMaxInactivityHours** is required define the threshold for creating a log recording a slow statement. The log includes information about the log memory, CPU and GPU. The ``healerMaxInactivityHours`` log frequency is calculated as 5% of the flag setting. For example, setting ``healerMaxInactivityHours`` to five hours (the default setting) triggers an examination every 15 minutes. \ No newline at end of file From 9de62ba18c3006361b0c3433828fd767ff5a51e1 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 31 Jul 2022 10:35:01 +0300 Subject: [PATCH 176/316] Update 2021.2.1.24.rst --- releases/2021.2.1.24.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releases/2021.2.1.24.rst b/releases/2021.2.1.24.rst index 125092f0e..fe21d40c0 100644 --- a/releases/2021.2.1.24.rst +++ b/releases/2021.2.1.24.rst @@ -25,7 +25,7 @@ Query Healer ************ The new **Query Healer** feature periodically examines the progress of running statements, and is used for query maintenance. -For more information, see :ref:`query_healer`. +For more information, see `Query Healer `_. Known Issues --------- From 93000b924307a192a334e7cdbec8b458e8604e5e Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 31 Jul 2022 13:27:15 +0300 Subject: [PATCH 177/316] Testing links --- releases/2021.1.2.rst | 6 +- releases/2021.2.1.24.rst | 2 +- releases/2021.2.1.rst | 4 +- releases/2021.2.rst | 4 +- releases/2022.1.rst | 10 +- sqream_studio_5.4.3/Version_5.3.3.txt | 898 ++++++++++++++++++++++++++ 6 files changed, 911 insertions(+), 13 deletions(-) create mode 100644 sqream_studio_5.4.3/Version_5.3.3.txt diff --git a/releases/2021.1.2.rst b/releases/2021.1.2.rst index 448b047df..5ccd878d8 100644 --- a/releases/2021.1.2.rst +++ b/releases/2021.1.2.rst @@ -40,17 +40,17 @@ String Literals Containing ASCII Characters Interepreted as TEXT ************ SQream now interprets all string literals, including those containing ASCII characters, as ``text``. -For more information, see `String Types `_. +For more information, see `String Types `_. Decimal Literals Interpreted as Numeric Columns ************ SQream now interprets literals containing decimal points as ``numeric`` instead of as ``double``. -For more information, see `Data Types `_. +For more information, see `Data Types `_. Roles Area Added to Studio Version 5.3.3 **************** -The **Roles** area has been added to `Studio version 5.3.3 `_. From the Roles area users can create and assign roles and manage user permissions. +The **Roles** area has been added to `Studio version 5.3.3 `_. From the Roles area users can create and assign roles and manage user permissions. Resolved Issues ------------- diff --git a/releases/2021.2.1.24.rst b/releases/2021.2.1.24.rst index fe21d40c0..f92cfda00 100644 --- a/releases/2021.2.1.24.rst +++ b/releases/2021.2.1.24.rst @@ -25,7 +25,7 @@ Query Healer ************ The new **Query Healer** feature periodically examines the progress of running statements, and is used for query maintenance. -For more information, see `Query Healer `_. +For more information, see `Query Healer `_. Known Issues --------- diff --git a/releases/2021.2.1.rst b/releases/2021.2.1.rst index 3afba3093..c7e1dbada 100644 --- a/releases/2021.2.1.rst +++ b/releases/2021.2.1.rst @@ -21,7 +21,7 @@ CREATE TABLE ************ SQream now supports duplicating the column structure of an existing table using the ``LIKE`` clause. -For more information, see `Duplicating the Column Structure of an Existing Table `_. +For more information, see `Duplicating the Column Structure of an Existing Table `_. PERCENTILE FUNCTIONS ************ @@ -41,7 +41,7 @@ Delete Optimization ************ The ``DELETE`` statement can now delete values that contain multi-table conditions. -For more information, see `Deleting Values that Contain Multi-Table Conditions `_. +For more information, see `Deleting Values that Contain Multi-Table Conditions `_. For more information, see :ref:`regexp_replace`. diff --git a/releases/2021.2.rst b/releases/2021.2.rst index 1bd6c6223..cce1675dc 100644 --- a/releases/2021.2.rst +++ b/releases/2021.2.rst @@ -33,8 +33,8 @@ SQream now uses a new configuration system based on centralized configuration ac For more information, see the following: -* `Configuration `_ - describes how to configure your instance of SQream from a centralized location. -* `SQream Studio 5.4.2 `_ - configure your instance of SQream from Studio. +* `Configuration `_ - describes how to configure your instance of SQream from a centralized location. +* `SQream Studio 5.4.2 `_ - configure your instance of SQream from Studio. Qualifying Schemas Without Providing an Alias ************ diff --git a/releases/2022.1.rst b/releases/2022.1.rst index cdd6d98c5..085108a43 100644 --- a/releases/2022.1.rst +++ b/releases/2022.1.rst @@ -37,13 +37,13 @@ Update Feature ************ SQream now supports the DML **Update** feature, which is used for modifying the value of certain columns in existing rows. -For more information, see `UPDATE `_. +For more information, see `UPDATE `_. Avro Ingestion ************ SQream now supports ingesting data from Avro files. -For more information, see `Inserting Data from Avro `_. +For more information, see `Inserting Data from Avro `_. Known Issues --------- @@ -87,7 +87,7 @@ Deprecated Features ------- In SQream version 2022.1 the ``VARCHAR`` data type has been deprecated and replaced with ``TEXT``. SQream will maintain ``VARCHAR`` in all previous versions until completing the migration to ``TEXT``, at which point it will be deprecated in all earlier versions. SQream also provides an automated and secure tool to facilitate and simplify migration from ``VARCHAR`` to ``TEXT``. -If you are using an earlier version of SQream, see the `Using Legacy String Literals `_ configuration flag. +If you are using an earlier version of SQream, see the `Using Legacy String Literals `_ configuration flag. End of Support ------- @@ -127,11 +127,11 @@ Upgrading to v2022.1 $ ./upgrade_storage - .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version `_ procedure. + .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version `_ procedure. .. toctree:: :maxdepth: 2 :glob: :hidden: - 2022.1 + 2022.1 \ No newline at end of file diff --git a/sqream_studio_5.4.3/Version_5.3.3.txt b/sqream_studio_5.4.3/Version_5.3.3.txt new file mode 100644 index 000000000..458302aad --- /dev/null +++ b/sqream_studio_5.4.3/Version_5.3.3.txt @@ -0,0 +1,898 @@ +.. _acceleration_studio_version_5.3.3: + +**************************** +SQream Acceleration Studio 5.3.3 +**************************** + +The SQream Studio is a web-based client for use with SQream DB. The Studio provides users with all functionality available from the command line in an intuitive and easy-to-use format. This includes running statements, managing roles and permissions, and managing SQream DB clusters. + + +.. contents:: This page describes the following: + :depth: 3 + +Getting Started +================== + +.. _setting_up_and_starting_studio: + + +Setting Up and Starting Studio +---------------- + +Studio is included with all `dockerized installations of SQream DB `_. When starting Studio, it listens on the local machine on port 8080. + + + + + + + +Logging In to Studio +--------------- +**To log in to SQream Studio:** + +1. Open a browser to the host on **port 8080**. + + For example, if your machine IP address is ``192.168.0.100``, insert the IP address into the browser as shown below: + + .. code-block:: console + + $ http://192.168.0.100:8080 + +2. Fill in your SQream DB login credentials. These are the same credentials used for `SQream CLI Reference `_ or JDBC. + + When you sign in, the License Warning is displayed. + +Navigating Studio's Main Features +------------- +When you log in, you are automatically taken to the **Editor** screen. The Studio's main functions are displayed in the **Navigation** pane on the left side of the screen. + +From here you can navigate between the main areas of the Studio: + +.. list-table:: + :widths: 10 90 + :header-rows: 1 + + * - Element + - Description + * - :ref:`Dashboard` + - Only users with **superuser** permissions have access to the Dashboard. + * - :ref:`Editor` + - All users have access to the Editor and to databases that they have permissions for. + * - :ref:`Logs` + - Only users with the **superuser** permissions have access to the logs. + * - :ref:`Roles` + - Lets you create users and manage user permissions. + +By clicking the user icon, you can also use it for logging out and viewing the following: + +* User information +* Connection type +* SQream version +* SQream Studio version +* Data size limitations +* Log out + + + +.. _back_to_dashboard: + +.. _studio_dashboard: + +Monitoring Workers and Services from the Dashboard +============================== +The **Dashboard** is used for the following: + +* Monitoring cluster storage and system health. +* Viewing, monitoring, and adding defined service queues. +* Viewing and managing worker status and add workers. + +You can only access the Dashboard if you signed in with a ``SUPERUSER`` role. + +The following is a brief description of the Dashboard panels: + +.. list-table:: + :widths: 10 25 65 + :header-rows: 1 + + * - No. + - Element + - Description + * - 1 + - :ref:`Data Storage panel` + - Used to monitor cluster storage. + * - 2 + - :ref:`Services panel` + - Used for viewing and monitoring the defined `service queues `_. + * - 3 + - :ref:`Workers panel` + - Monitors system health and shows each Sqreamd worker running in the cluster. + * - 4 + - :ref:`License information` + - Shows the remaining amount of days left on your license. + + +.. _data_storage_panel: + +Displaying System Disk Usage from the Data Storage Panel +----------------------- +The **Data Storage** area displays your system's total disk usage (percentage) and data storage (donut graph). + +Your data storage is shows as the following four components: + +* **Data** – Storage occupied by databases in SQream DB. +* **Free** – Free storage space. +* **Deleted** – Storage that is temporarily occupied, but has not been reclaimed. For more information, see `Deleting Data `_. The **deleted** value is estimated and may not be accurate. +* **Other** – Storage used by other applications. On a dedicated SQream DB cluster this should be near zero. + +.. _administration_storage_database: + +You can show more information by clicking the expand arrow on the Data Storage panel. + +.. image:: /_static/images/studio_dashboard_expand_data_storage_5.3.0.png + +The expanded Data Storage panel can be used to drill down into each database's storage footprint, and displays a breakdown of how much storage each database in the cluster uses. + +The database information is displayed in a table and shows the following: + +* **Database name** - the name of the database. +* **Raw Size** – the estimated size of (uncompressed) raw data in the database. +* **Storage Size** – the physical size of the compressed data. +* **Ratio** – the effective compression ratio +* **Deleted Data** – Storage that is temporarily occupied, but has not been reclaimed. + +Below the table, an interactive line graph displays the database storage trends. By default, the line graph displays the total storage for all databases. You can show a particular database's graph by clicking it in the table. You can also change the line graph's timespan by selecting one from the timespan dropdown menu. + +.. image:: /_static/images/studio_dashboard_expand_data_storage_3_5.3.0.png + +:ref:`Back to Dashboard` + +.. _services_panel: + +Subscribing to Workers from the Services Panel +-------------------------- +Services are used to categorize and associate (also known as **subscribing**) workers to particular services. The **Service** panel is used for viewing, monitoring, and adding defined `service queues `_. + +.. image:: /_static/images/studio_dashboard_services_panel_5.3.0.png + +The Dashboard includes the four panes shown below: + +.. image:: /_static/images/studio_dashboard_service_queue_5.3.0.png + +The following is a brief description of each pane: + +.. list-table:: + :widths: 10 90 + :header-rows: 1 + + * - No. + - Description + * - 1 + - Adds a worker to the selected service. + * - 2 + - Shows the service name. + * - 3 + - Shows a trend graph of queued statements loaded over time. + * - 4 + - Adds a service. + * - 5 + - Shows the currently processed queries belonging to the service/total queries for that service in the system (including queued queries). + +Adding A Service +^^^^^^^^^^^^^^^^^^^^^ +You can add a service by clicking **+ Add** and defining the service name. + +.. note:: If you do not associate a worker with the new service, it will not be created. + +You can manage workers from the **Workers** panel. For more information on managing workers, see :ref:`Workers`. + +:ref:`Back to Dashboard` + +.. _workers_panel: + +Managing Workers from the Workers Panel +------------ +From the **Workers** panel you can do the following: + +* :ref:`View workers ` +* :ref:`Add a worker to a service` +* :ref:`View a worker's active query information` +* :ref:`View a worker's execution plan` + +.. _view_workers: + +Viewing Workers +^^^^^^^^ +The **Worker** panel shows each worker (``sqreamd``) running in the cluster. Each worker has a status bar that represents the status over time. The status bar is divided into 20 equal segments, showing the most dominant activity in that segment. + +From the **Scale** dropdown menu you can set the time scale of the displayed information +You can hover over segments in the status bar to see the date and time corresponding to each activity type: + +* **Idle** – the worker is idle and available for statements. +* **Compiling** – the worker is compiling a statement and is preparing for execution. +* **Executing** – the worker is executing a statement after compilation. +* **Stopped** – the worker was stopped (either deliberately or due to an error). +* **Waiting** – the worker was waiting on an object locked by another worker. + +.. _add_worker_to_service: + +Adding A Worker to A Service +^^^^^^^^^^^^^^^^^^^^^ +You can add a worker to a service by clicking the **add** button. + +.. image:: /_static/images/studio_dashboard_add_worker_to_service_5.3.0.png + +Clicking the **add** button shows the selected service's workers. You can add the selected worker to the service by clicking **Add Worker**. Adding a worker to a service does not break associations already made between that worker and other services. + + +.. _view_worker_query_information: + +Viewing A Worker's Active Query Information +^^^^^^^^^^^^^^^^^^^^^ +You can view a worker's active query information by clicking **Queries**, which displays them in the selected service. + + +Each statement shows the **query ID**, **status**, **service queue**, **elapsed time**, **execution time**, and **estimated completion status**. In addition, each statement can be stopped or expanded to show its execution plan and progress. For more information on viewing a statement's execution plan and progress, see :ref:`Viewing a Worker's Execution Plan ` below. + +Viewing A Worker's Host Utilization +^^^^^^^^^^^^^^^^^^^^^ + +While viewing a worker's query information, clicking the **down arrow** expands to show the host resource utilization. + +.. image:: /_static/images/studio_dashboard_show_cpu_gpu_graph_5.3.0.png + +The graphs show the resource utilization trends over time, and the **CPU memory** and **utilization** and the **GPU utilization** values on the right. You can hover over the graph to see more information about the activity at any point on the graph. + +Error notifications related to statements are displayed as shown in the figure below, and you can hover over them for more information about the error. + +.. image:: /_static/images/studio_dashboard_notification_error_5.3.0.png + +.. _view_worker_execution_plan: + +Viewing a Worker's Execution Plan +^^^^^^^^^^^^^^^^^^^^^ + +Clicking the ellipsis in a service shows the following additional options: + +* **Stop Query** - stops the query. +* **Show Execution Plan** - shows the execution plan as a table. The columns in the **Show Execution Plan** table can be sorted. + +For more information on the current query plan, see `SHOW_NODE_INFO `_. For more information on checking active sessions across the cluster, see `SHOW_SERVER_STATUS `_. + +.. include:: /reference/sql/sql_statements/monitoring_commands/show_server_status.rst + :start-line: 67 + :end-line: 84 + +Managing Worker Status +^^^^^^^^^^^^^^^^^^^^^ + +In some cases you may want to stop or restart workers for maintenance purposes. Each Worker line has a :kbd:`⋮` menu used for stopping, starting, or restarting workers. + +.. image:: /_static/images/stop_restart_worker.png + +Starting or restarting workers terminates all queries related to that worker. When you stop a worker, its background turns gray. + + + + +.. |icon-user| image:: /_static/images/studio_icon_user.png + :align: middle + +.. |icon-dots| image:: /_static/images/studio_icon_dots.png + :align: middle + +.. |icon-editor| image:: /_static/images/studio_icon_editor.png + :align: middle + +.. |icon-copy| image:: /_static/images/studio_icon_copy.png + :align: middle + +.. |icon-select| image:: /_static/images/studio_icon_select.png + :align: middle + +.. |icon-dots| image:: /_static/images/studio_icon_dots.png + :align: middle + +.. |icon-filter| image:: /_static/images/studio_icon_filter.png + :align: middle + +.. |icon-ddl-edit| image:: /_static/images/studio_icon_ddl_edit.png + :align: middle + +.. |icon-run-optimizer| image:: /_static/images/studio_icon_run_optimizer.png + :align: middle + +.. |icon-generate-create-statement| image:: /_static/images/studio_icon_generate_create_statement.png + :align: middle + +.. |icon-plus| image:: /_static/images/studio_icon_plus.png + :align: middle + +.. |icon-close| image:: /_static/images/studio_icon_close.png + :align: middle + +.. |icon-left| image:: /_static/images/studio_icon_left.png + :align: middle + +.. |icon-right| image:: /_static/images/studio_icon_right.png + :align: middle + +.. |icon-format-sql| image:: /_static/images/studio_icon_format.png + :align: middle + +.. |icon-download-query| image:: /_static/images/studio_icon_download_query.png + :align: middle + +.. |icon-open-query| image:: /_static/images/studio_icon_open_query.png + :align: middle + +.. |icon-execute| image:: /_static/images/studio_icon_execute.png + :align: middle + +.. |icon-stop| image:: /_static/images/studio_icon_stop.png + :align: middle + +.. |icon-dashboard| image:: /_static/images/studio_icon_dashboard.png + :align: middle + +.. |icon-expand| image:: /_static/images/studio_icon_expand.png + :align: middle + +.. |icon-scale| image:: /_static/images/studio_icon_scale.png + :align: middle + +.. |icon-expand-down| image:: /_static/images/studio_icon_expand_down.png + :align: middle + +.. |icon-add| image:: /_static/images/studio_icon_add.png + :align: middle + +.. |icon-add-worker| image:: /_static/images/studio_icon_add_worker.png + :align: middle + +.. |keep-tabs| image:: /_static/images/studio_keep_tabs.png + :align: middle + +:ref:`Back to Dashboard` + + + +.. _license_information: + +License Information +---------------------- +The license information is a counter showing the amount of time in days remaining on the license. + +:ref:`Back to Dashboard` + + +.. _studio_editor: + +.. _editor_top: + +Executing Statements and Running Queries from the Editor +================= +The **Editor** is used for the following: + +* Selecting an active database and executing queries. +* Performing statement-related operations and showing metadata. +* Executing pre-defined queries. +* Writing queries and statements and viewing query results. + +The following is a brief description of the Editor panels: + + +.. list-table:: + :widths: 10 34 56 + :header-rows: 1 + + * - No. + - Element + - Description + * - 1 + - :ref:`Toolbar` + - Used to select the active database you want to work on, limit the number of rows, save query, etc. + * - 2 + - :ref:`Database Tree and System Queries panel` + - Shows a heirarchy tree of databases, views, tables, and columns + * - 3 + - :ref:`Statement panel` + - Used for writing queries and statements + * - 4 + - :ref:`Results panel` + - Shows query results and execution information. + + +.. _studio_editor_db_tree: + +.. _top: + +.. _studio_editor_toolbar: + +Executing Statements from the Toolbar +------------- + +The following figure shows the **Toolbar** pane: + +.. image:: /_static/images/studio_editor_toolbar_5.3.0.png + +You can access the following from the Toolbar pane: + +* **Database dropdown list** - select a database that you want to run statements on. + +* **Service dropdown list** - select a service that you want to run statements on. The options in the service dropdown menu depend on the database you select from the **Database** dropdown list. + +* **Execute** - lets you set which statements to execute. The **Execute** button toggles between **Execute** and **Stop**, and can be used to stop an active statement before it completes: + + * **Statements** - executes the statement at the location of the cursor. + * **Selected** - executes only the highlighted text. This mode should be used when executing subqueries or sections of large queries (as long as they are valid SQLs). + * **All** - executes all statements in a selected tab. + +For more information on stopping active statements, see the :ref:`STOP_STATEMENT` command. + +* **Format SQL** - Lets you reformat and reindent statements. + +* **Download query** - Lets you download query text to your computer. + +* **Open query** - Lets you upload query text from your computer. + +* **Max Rows** - By default, the Editor fetches only the first 10,000 rows. You can modify this number by selecting an option from the **Max Rows** dropdown list. Note that setting a higher number may slow down your browser if the result is very large. This number is limited to 100,000 results. To see a higher number, you can save the results in a file or a table using the :ref:`create_table_as` command. + +:ref:`Back to Editor` + +Performing Statement-Related Operations from the Database Tree +--------------- +From the Database Tree you can perform statement-related operations and show metadata (such as a number indicating the amount of rows in the table). + +The following figure shows the **Database Tree** and **System Queries** panel, with the Database Tree tab selected. + +.. image:: /_static/images/studio_database_tree_system_queries_panel_5053.png + +The following figure shows the database object functions in the **calcs** table object. + +.. image:: /_static/images/studio_database_object_operations_5030.png + +The database object functions are used to perform the following: + + + * The **SELECT** statement - copies the selected table's **columns** into the Statement panel as ``SELECT`` parameters. + * The **copy** feature |icon-copy| - copies the selected table's **name** into the Statement panel. + * The **additional operations** |icon-dots| - displays the following additional options: + + + + + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Function + - Description + * - Insert statement + - Generates an `INSERT `_ statement for the selected table in the editing area. + * - Delete statement + - Generates a `DELETE `_ statement for the selected table in the editing area. + * - Create Table As statement + - Generates a `CREATE TABLE AS `_ statement for the selected table in the editing area. + * - Rename statement + - Generates an `RENAME TABLE AS `_ statement for renaming the selected table in the editing area. + * - Adding column statement + - Generates an `ADD COLUMN `_ statement for adding columns to the selected table in the editing area. + * - Truncate table statement + - Generates a `TRUNCATE_IF_EXISTS `_ statement for the selected table in the editing area. + * - Drop table statement + - Generates a ``DROP`` statement for the selected object in the editing area. + * - Table DDL + - Generates a DDL statement for the selected object in the editing area. To get the entire database DDL, click the |icon-ddl-edit| icon next to the database name in the tree root. See also `Seeing System Objects as DDL `_. + * - DDL Optimizer + - The `DDL Optimizer `_ lets you analyze database tables and recommends possible optimizations. + + + + + +Optimizing Database Tables Using the DDL Optimizer +^^^^^^^^^^^^^^^^^^^^^ +The **DDL Optimizer** tab analyzes database tables and recommends possible optimizations according to SQream's best practices. + +As described in the previous table, you can access the DDL Optimizer by clicking the **additional options icon** and selecting **DDL Optimizer**. + +The following table describes the DDL Optimizer screen: + +.. list-table:: + :widths: 15 75 + :header-rows: 1 + + * - Element + - Description + * - Column area + - Shows the column **names** and **column types** from the selected table. You can scroll down or to the right/left for long column lists. + * - Optimization area + - Shows the number of rows to sample as the basis for running an optimization, the default setting (1,000,000) when running an optimization (this is also the overhead threshold used when analyzing ``VARCHAR`` fields), and the default percent buffer to add to ``VARCHAR`` lengths (10%). Attempts to determine field nullability. + * - Run Optimizer + - Starts the optimization process. + +Clicking **Run Optimizer** adds a tab to the Statement panel showing the optimized results of the selected object. The figure below shows the **calcs Optimized** tab for the optimized **calcs** table. + +For more information, see `Optimization and Best Practices `_. + +:ref:`Back to top` + +Executing Pre-Defined Queries from the System Queries Panel +--------------- +The **System Queries** panel lets you execute pre-defined queries and includes the following system query types: + +* **Catalog queries** - used for analyzing table compression rates, users and permissions, etc. +* **Admin queries** - queries related to available (describe the functionality in a general way). Queries useful for SQream database management: + + + + + +Clicking an item pastes the query into the Statement pane, and you can undo a previous operation by pressing **Ctrl + Z**. + + +.. _studio_editor_statement_area: + +Writing Statements and Queries from the Statement Panel +---------------- +The multi-tabbed statement area is used for writing queries and statements, and is used in tandem with the toolbar. When writing and executing statements, you must first select a database from the **Database** dropdown menu in the toolbar. When you execute a statement, it passes through a series of statuses until completing. Knowing the status helps you with statement maintenance, and the statuses are shown in the **Results panel**. + +The following table shows the statement statuses: + +.. list-table:: + :widths: 45 160 + :header-rows: 1 + + * - Status + - Description + * - Pending + - The statement is pending. + * - In queue + - The statement is waiting for execution. + * - Initializing + - The statement has entered execution checks. + * - Executing + - The statement is executing. + * - Statement stopped + - The statement has been stopped. + +You can add and name new tabs for each statement that you need to execute, and Studio preserves your created tabs when you switch between databases. You can add new tabs by clicking |icon-plus| , which creates a new tab to the right with a default name of SQL and an increasing number. This helps you keep track of your statements. + +.. image:: /_static/images/statement_pane_adding_statement_5.3.0.png + +You can also rename the default tab name by double-clicking it and typing a new name and write multiple statements in tandem in the same tab by separating them with semicolons (``;``).If too many tabs to fit into the Statement Pane are open at the same time, the tab arrows are displayed. You can scroll through the tabs by clicking |icon-left| or |icon-right|, and close tabs by clicking |icon-close|. You can also close all tabs at once by clicking **Close all** located to the right of the tabs. + +.. tip:: If this is your first time using SQream, see `First steps with SQream DB `_. + + +.. Keyboard shortcuts +.. ^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. :kbd:`Ctrl` +: kbd:`Enter` - Execute all queries in the statement area, or just the highlighted part of the query. + +.. :kbd:`Ctrl` + :kbd:`Space` - Auto-complete the current keyword + +.. :kbd:`Ctrl` + :kbd:`↑` - Switch to next tab. + +.. :kbd:`Ctrl` + :kbd:`↓` - Switch to previous tab + +.. _studio_editor_results: + +:ref:`Back to Editor` + + +Viewing Statement and Query Results from the Results Panel +------------------------------------ +The results pane shows statment and query results. By default, only the first 10,000 results are returned, although you can modify this from the :ref:`studio_editor_toolbar`, as described above. + +.. image:: /_static/images/studio_editor_results_5053.png + +By default, executing several statements together opens a separate results tab for each statement. Executing statements together executes them serially, and any failed statement cancels all subsequent executions. + +The following is a brief description of the elements on the Results panel views: + +.. list-table:: + :widths: 45 160 + :header-rows: 1 + + * - Element + - Description + * - :ref:`Results view` + - Lets you view search query results. + * - :ref:`Execution Details view` + - Lets you view execution details, such as statement ID, number of rows, and averge number of rows in chunk. + * - :ref:`SQL view` + - Lets you see the SQL view. + * - :ref:`Save results to clipboard` + - Lets you save your search results to the clipboard to paste into another text editor. + * - :ref:`Save results to local file` + - Lets you save your search query results to a local file. + +.. _results_view: + + + +Searching Query Results in the Results View +^^^^^^^^^^^^ +The **Results view** lets you view search query results. + +From this view you can also do the following: + +* View the amount of time (in seconds) taken for a query to finish executing. +* Switch and scroll between tabs. +* Close all tabs at once. +* Enable keeping tabs by selecting **Keep tabs**. +* Sort column results. + +In the Results view you can also run parallel statements, as described in **Running Parallel Statements** below. + +.. _running_parallel_statements: + +Running Parallel Statements +^^^^^^^^^^^^ +While Studio's default functionality is to open a new tab for each executed statement, Studio supports running parallel statements in one statement tab. Running parallel statements requires using macros and is useful for advanced users. + +The following shows the syntax for running parallel statements: + +.. code-block:: console + + $ @@ parallel + $ $$ + $ select 1; + $ select 2; + $ select 3; + $ $$ + +The following figure shows the parallel statement syntax in the Editor: + +.. image:: /_static/images/running_parallel_statements.png + +.. _execution_details_view: + +Execution Details View +^^^^^^^^^^^^ +The **Execution Details** view lets you view a query’s execution plan for monitoring purposes. Most importantly, the Execution Details view highlights rows based on how long they ran relative to the entire query. + +This can be seen in the **timeSum** column as follows: + +* **Rows highlighted red** - longest runtime +* **Rows highlighted orange** - medium runtime +* **Rows highlighted yellow** - shortest runtime + +.. image:: /_static/images/execution_details_view_3.png + + + +.. _sql_view: + +Viewing Wrapped Strings in the SQL View +^^^^^^^^^^^^ +The SQL View panel allows you to more easily view certain queries, such as a long string that appears on one line. The SQL View makes it easier to see by wrapping it so that you can see the entire string at once. It also reformats and organizes query syntax entered in the Statement panel for more easily locating particular segments of your queries. The SQL View is identical to the **Format SQL** feature in the Toolbar, allowing you to retain your originally constructed query while viewing a more intuititively structured snapshot of it. + +The following figure shows the SQL view: + +.. image:: /_static/images/sql_view_5.0.3.png + +.. _save_results_to_clipboard: + +Saving Results to the Clipboard +^^^^^^^^^^^^ +The **Save results to clipboard** function lets you save your results to the clipboard to paste into another text editor or into Excel for further analysis. + + +.. _save_results_to_local_file: + +Saving Results to a Local File +^^^^^^^^^^^^ +The **Save results to local file** functions lets you save your search query results to a local file. Clicking **Save results to local file** downloads the contents of the Results panel to an Excel sheet. You can then use copy and paste this content into other editors as needed. + +Analyzing Results +---------------------------- + +When results are produced, a **Generate CREATE statement** button is displayed. Clicking this button creates a new tab with an optimized :ref:`create_table` statement, and an :ref:`insert` statement to copy the data to the new table. + +.. _logs: + +.. _logs_top: + +:ref:`Back to Editor` + +Viewing Logs +============ +The **Logs** screen is used for viewing logs and includes the following elements: + +.. list-table:: + :widths: 15 75 + :header-rows: 1 + + * - Element + - Description + * - :ref:`Filter area` + - Lets you filter the data shown in the table. + * - :ref:`Query tab` + - Shows basic query information logs, such as query number and the time the query was run. + * - :ref:`Session tab` + - Shows basic session information logs, such as session ID and user name. + * - :ref:`System tab` + - Shows all system logs. + * - :ref:`Log lines tab` + - Shows the total amount of log lines. + + +.. _filter: + +Filtering Table Data +------------- +From the Logs tab, from the **FILTERS** area you can also apply the **TIMESPAN**, **ONLY ERRORS**, and additional filters (**Add**). The **Timespan** filter lets you select a timespan. The **Only Errors** toggle button lets you show all queries, or only queries that generated errors. The **Add** button lets you add additional filters to the data shown in the table. The **Filter** button applies the selected filter(s). + + +Some filters require you to type text to define the filter. + +.. image:: /_static/images/logs_filters_5.3.0.png + +Other filters require you to select an item from a dropdown menu: + +* INFO +* WARNING +* ERROR +* FATAL +* SYSTEM + +You can also export a record of all of your currently filtered logs in Excel format by clicking **Download** located above the Filter area. + +.. _queries: + +:ref:`Back to Viewing Logs` + + +Viewing Query Logs +---------- +The **QUERIES** log area shows basic query information, such as query number and the time the query was run. The number next to the title indicates the amount of queries that have been run. + +From the Queries area you can see and sort by the following: + +* Query ID +* Start time +* Query +* Compilation duration +* Execution duration +* Total duration +* Details (execution details, error details, successful query details) + +In the Queries table, you can click on the **Statement ID** and **Query** items to set them as your filters. In the **Details** column you can also access additional details by clicking one of the **Details** options for a more detailed explanation of the query. + +:ref:`Back to Viewing Logs` + +.. _sessions: + +Viewing Session Logs +---------- +The **SESSIONS** tab shows the sessions log table and is used for viewing activity that has occurred during your sessions. The number at the top indicates the amount of sessions that have occurred. + +From here you can see and sort by the following: + +* Timestamp +* Connection ID +* Username +* Client IP +* Login (Success or Failed) +* Duration (of session) +* Configuration Changes + +In the Sessions table, you can click on the **Timestamp**, **Connection ID**, and **Username** items to set them as your filters. + +:ref:`Back to Viewing Logs` + +.. _system: + +Viewing System Logs +---------- +The **SYSTEM** tab shows the system log table and is used for viewing all system logs. The number at the top indicates the amount of sessions that have occurred. Because system logs occur less frequently than queries and sessions, you may need to increase the filter timespan for the table to display any system logs. + +From here you can see and sort by the following: + +* Timestamp +* Log type +* Message + +In the Systems table, you can click on the **Timestamp** and **Log type** items to set them as your filters. In the **Message** column, you can also click on an item to show more information about the message. + +:ref:`Back to Viewing Logs` + +.. _log_lines: + +Viewing All Log Lines +---------- +The **LOG LINES** tab is used for viewing the total amount of log lines in a table. From here users can view a more granular breakdown of log information collected by Studio. The other tabs (QUERIES, SESSIONS, and SYSTEM) show a filtered form of the raw log lines. For example, the QUERIES tab shows an aggregation of several log lines. + +From here you can see and sort by the following: + +* Timestamp +* Message level +* Worker hostname +* Worker port +* Connection ID +* Database name +* User name +* Statement ID + +In the **LOG LINES** table, you can click on any of the items to set them as your filters. + +:ref:`Back to Viewing Logs` + +:ref:`Back to Editor` + +.. _roles: + +Creating, Assigning, and Managing Roles and Permissions +============ +Overview +--------------- +In the **Roles** area you can create and assign roles and manage user permissions. + +The **Type** column displays one of the following assigned role types: + +.. list-table:: + :widths: 15 75 + :header-rows: 1 + + * - Role Type + - Description + * - Groups + - Roles with no users. + * - Enabled users + - Users with log-in permissions and a password. + * - Disabled users + - Users with log-in permissions and with a disabled password. An admin may disable a user's password permissions to temporary disable access to the system. + +.. note:: If you disable a password, when you enable it you have to create a new one. + + +Viewing Information About a Role +-------------------- +Clicking a role in the roles table displays the following information: + + * **Parent Roles** - displays the parent roles of the selected role. Roles inherit all roles assigned to the parent. + * **Members** - displays all members that the role has been assigned to. The arrow indicates the roles that the role has inherited. Hovering over a member displays the roles that the role is inherited from. + * **Permissions** - displays the role's permissions. The arrow indicates the permissions that the role has inherited. Hovering over a permission displays the roles that the permission is inherited from. + +Creating a New Role +-------------------- +You can create a new role by clicking **New Role**. + +.. image:: /_static/images/role_button.png + +An admin creates a **user** by granting login permissions and a password to a role. Each role is defined by a set of permissions. An admin can also group several roles together to form a **group** to manage them simultaneously. For example, permissions can be granted to or revoked on a group level. + +Clicking **New Role** lets you do the following: + + * Add and assign a role name (required) + * Enable or disable log-in permissions for the role. + * Set a password. + * Assign or delete parent roles. + * Add or delete permissions. + * Grant the selected user with superuser permissions. + +From the New Role panel you view directly and indirectly (or inherited) granted permissions. Disabled permissions have no connect permissions for the referenced database and are displayed in gray text. You can add or remove permissions from the **Add permissions** field. From the New Role panel you can also search and scroll through the permissions. In the **Search** field you can use the **and** operator to search for strings that fulfill multiple criteria. + +When adding a new role, you must select the **Enable login for this role** and **Has password** check boxes. + +Editing a Role +-------------------- +Once you've created a role, clicking the **Edit Role** button lets you do the following: + + * Edit the role name. + * Enable or disable log-in permissions. + * Set a password. + * Assign or delete parent roles. + * Assign a role **administrator** permissions. + * Add or delete permissions. + * Grant the selected user with superuser permissions. + +From the Edit Role panel you view directly and indirectly (or inherited) granted permissions. Disabled permissions have no connect permissions for the referenced database and are displayed in gray text. You can add or remove permissions from the **Add permissions** field. From the Edit Role panel you can also search and scroll through the permissions. In the **Search** field you can use the **and** operator to search for strings that fulfill multiple criteria. + +Deleting a Role +----------------- +Clicking the **delete** icon displays a confirmation message with the amount of users and groups that will be impacted by deleting the role. From d002f318c28dd2ace824bd21d26618768cfe4044 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 31 Jul 2022 15:54:01 +0300 Subject: [PATCH 178/316] Removed password policy --- operational_guides/access_control.rst | 1 - .../access_control_password_policy.rst | 42 ------------------- 2 files changed, 43 deletions(-) delete mode 100644 operational_guides/access_control_password_policy.rst diff --git a/operational_guides/access_control.rst b/operational_guides/access_control.rst index bd25d0d99..88a14d71b 100644 --- a/operational_guides/access_control.rst +++ b/operational_guides/access_control.rst @@ -11,5 +11,4 @@ Access Control access_control_overview access_control_managing_roles access_control_permissions - access_control_password_policy access_control_departmental_example \ No newline at end of file diff --git a/operational_guides/access_control_password_policy.rst b/operational_guides/access_control_password_policy.rst deleted file mode 100644 index 10a4f697f..000000000 --- a/operational_guides/access_control_password_policy.rst +++ /dev/null @@ -1,42 +0,0 @@ -.. _access_control_password_policy: - -************** -Password Policy -************** -As part of our compliance with GDPR standards SQream relies on a strong password policy when accessing the CLI or Studio, with the following requirements: - -* At least eight characters long. - - :: - -* Mandatory upper and lowercase letters. - - :: - -* At least one numeric character. - - :: - -* May not include a username. - - :: - -* Must include at least one special character, such as **?**, **!**, **$**, etc. - -You can create a password through the Studio graphic interface or through the CLI, as in the following example command: - -.. code-block:: console - - CREATE ROLE user_a ; - GRANT LOGIN to user_a ; - GRANT PASSWORD 'BBAu47?fqPL' to user_a ; - -Creating a password that does not comply with the above requirements generates an error message with a request to modify it. - -Unsuccessfully attempting to log in three times displays the following message: - -.. code-block:: console - - The user is locked. please contact your system administrator to reset the password and regain access functionality. - -For more information, see :ref:`login_max_retries`. From 0dcf869e40e8545f6e745ae29cd29298f41f2629 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 31 Jul 2022 17:40:00 +0300 Subject: [PATCH 179/316] Links --- releases/2020.3.rst | 14 +++++--------- releases/2021.1.2.rst | 4 ++-- releases/2021.1.rst | 14 +++++++------- releases/2021.2.1.24.rst | 12 ++++++------ releases/2021.2.1.rst | 8 ++++---- 5 files changed, 24 insertions(+), 28 deletions(-) diff --git a/releases/2020.3.rst b/releases/2020.3.rst index b51a9955d..eb8ca8f62 100644 --- a/releases/2020.3.rst +++ b/releases/2020.3.rst @@ -26,9 +26,12 @@ The following list describes the new features: * ``TEXT`` is ramping up with new features (previously only available with VARCHARs): - * :ref:`substring`, :ref:`lower`, :ref:`ltrim`, :ref:`charindex`, :ref:`replace`, etc. + * `SUBSTRING `_ + * `LTRIM `_ + * `CHARINDEX `_ + * `REPLACE `_ - * Binary operators - :ref:`concat`, :ref:`like`, etc. + * Binary operators - `CONCAT `_ , `REPLACE `_ , etc. * Casts to and from ``TEXT`` @@ -100,10 +103,3 @@ Upgrading to v2020.3 Versions are available for IBM POWER9, RedHat (CentOS) 7, Ubuntu 18.04, and other OSs via Docker. Contact your account manager to get the latest release of SQream. - -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2020.3 diff --git a/releases/2021.1.2.rst b/releases/2021.1.2.rst index 5ccd878d8..e163c987d 100644 --- a/releases/2021.1.2.rst +++ b/releases/2021.1.2.rst @@ -48,9 +48,9 @@ SQream now interprets literals containing decimal points as ``numeric`` instead For more information, see `Data Types `_. -Roles Area Added to Studio Version 5.3.3 +Roles Area Added to Studio Version 5.4.3 **************** -The **Roles** area has been added to `Studio version 5.3.3 `_. From the Roles area users can create and assign roles and manage user permissions. +The **Roles** area has been added to `Studio version 5.3.3 `_. From the Roles area users can create and assign roles and manage user permissions. Resolved Issues ------------- diff --git a/releases/2021.1.rst b/releases/2021.1.rst index 15824d5d5..389655262 100644 --- a/releases/2021.1.rst +++ b/releases/2021.1.rst @@ -40,7 +40,7 @@ SQream now supports Numeric Data types for the following operations: * All aggregation types (not including Window functions). * Scalar functions (not including some trigonometric and logarithmic functions). -For more information, see `Numeric Data Types `_. +For more information, see `Numeric Data Types `_. Text Data Type ************ @@ -54,14 +54,14 @@ SQream now supports TEXT data types in all operations, which is default string d * Support text columns in queries with multiple distinct aggregates. * Text literal support for all functions. -For more information, see `String Types `_. +For more information, see `String Types `_. Supports Scalar Subqueries ************ SQream now supports running initial scalar subqueries. -For more information, see `Subqueries `_. +For more information, see `Subqueries `_. Literal Arguments ************ @@ -72,7 +72,7 @@ Simple Scalar SQL UDFs ************ SQream now supports simple scalar SQL UDF's. -For more information, see `Simple Scalar SQL UDF’s `_. +For more information, see `Simple Scalar SQL UDF’s `_. Logging Enhancements ************ @@ -91,7 +91,7 @@ Improved Presented License Information ************ SQream now displays information related to data size limitations, expiration date, type of license shown by the new UF. The **Utility Function (UF)** name is ``get_license_info()``. -For more information, see `GET_LICENSE_INFO `_. +For more information, see `GET_LICENSE_INFO `_. @@ -171,7 +171,7 @@ Operations and Configuration Changes Recommended SQream Configuration on Cloud ************ -For more information about AWS, see `Amazon S3 `_. +For more information about AWS, see `Amazon S3 `_. @@ -183,7 +183,7 @@ SQream now has a new ``runtimeGlobalFlags`` flag called ``WriteToFileThreads``. This flag configures the number of threads in the **WriteToFile** function. The default value is ``16``. -For more information about the ``runtimeGlobalFlags`` flag, see the **Runtime Global Flags** table in `Configuration `_. +For more information about the ``runtimeGlobalFlags`` flag, see the **Runtime Global Flags** table in `Configuration `_. diff --git a/releases/2021.2.1.24.rst b/releases/2021.2.1.24.rst index f92cfda00..1d5407d89 100644 --- a/releases/2021.2.1.24.rst +++ b/releases/2021.2.1.24.rst @@ -15,7 +15,7 @@ The 2021.2.1.24 Release Notes includes a query maintenance feature. New Features ---------- -The 2021.2.1.24 Release Notes include the following new features: +The 2021.2.1.24 Release Notes include the following new features: .. contents:: :local: @@ -25,7 +25,7 @@ Query Healer ************ The new **Query Healer** feature periodically examines the progress of running statements, and is used for query maintenance. -For more information, see `Query Healer `_. +For more information, see `Query Healer `_. Known Issues --------- @@ -53,9 +53,9 @@ Resolved Issues --------- The Resolved Issues section is not relevant for Version 2021.2.1.24. -Operations and Configuration Changes --------- -No relevant operations and configuration changes were made. +Operational and Configuration Changes +------- +No relevant operational or configuration changes were made. Naming Changes ------- @@ -74,4 +74,4 @@ The End of Support section is not relevant to Version 2021.2.1.24. :glob: :hidden: - 2021.2.1.24 + 2021.2.1.24 \ No newline at end of file diff --git a/releases/2021.2.1.rst b/releases/2021.2.1.rst index c7e1dbada..c476bd2d5 100644 --- a/releases/2021.2.1.rst +++ b/releases/2021.2.1.rst @@ -21,7 +21,7 @@ CREATE TABLE ************ SQream now supports duplicating the column structure of an existing table using the ``LIKE`` clause. -For more information, see `Duplicating the Column Structure of an Existing Table `_. +For more information, see `Duplicating the Column Structure of an Existing Table `_. PERCENTILE FUNCTIONS ************ @@ -35,15 +35,15 @@ REGEX REPLACE ************ SQream now supports the ``REGEXP_REPLACE`` function for finding and replacing text column substrings. -For more information, see :ref:`regexp_replace`. +For more information, see `REGEX_REPLACE `_. Delete Optimization ************ The ``DELETE`` statement can now delete values that contain multi-table conditions. -For more information, see `Deleting Values that Contain Multi-Table Conditions `_. +For more information, see `Deleting Values that Contain Multi-Table Conditions `_. -For more information, see :ref:`regexp_replace`. +For more information, see `REGEX_REPLACE `_. Performance Enhancements ------ From 4c79df05607c298193c873538bc82c089cb4726b Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 31 Jul 2022 18:35:05 +0300 Subject: [PATCH 180/316] Links --- releases/2021.2.1.rst | 10 +++++----- releases/2021.2.rst | 8 ++------ 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/releases/2021.2.1.rst b/releases/2021.2.1.rst index c476bd2d5..2988d98f6 100644 --- a/releases/2021.2.1.rst +++ b/releases/2021.2.1.rst @@ -27,15 +27,15 @@ PERCENTILE FUNCTIONS ************ SQream now supports the following aggregation functions: -* :ref:`percentile_cont` -* :ref:`percentile_disc` -* :ref:`mode` +* `PERCENTILE_CONT `_ +* `PERCENTILE_DISC `_ +* `MODE `_ REGEX REPLACE ************ SQream now supports the ``REGEXP_REPLACE`` function for finding and replacing text column substrings. -For more information, see `REGEX_REPLACE `_. +For more information, see `REGEX_REPLACE `_. Delete Optimization ************ @@ -43,7 +43,7 @@ The ``DELETE`` statement can now delete values that contain multi-table conditio For more information, see `Deleting Values that Contain Multi-Table Conditions `_. -For more information, see `REGEX_REPLACE `_. +For more information, see `REGEX_REPLACE `_. Performance Enhancements ------ diff --git a/releases/2021.2.rst b/releases/2021.2.rst index cce1675dc..a46762f01 100644 --- a/releases/2021.2.rst +++ b/releases/2021.2.rst @@ -34,17 +34,13 @@ SQream now uses a new configuration system based on centralized configuration ac For more information, see the following: * `Configuration `_ - describes how to configure your instance of SQream from a centralized location. -* `SQream Studio 5.4.2 `_ - configure your instance of SQream from Studio. +* `SQream Studio 5.4.3 `_ - configure your instance of SQream from Studio. Qualifying Schemas Without Providing an Alias ************ When running queries, SQream now supports qualifying schemas without providing an alias. -For more information, see :ref:`create_schema`. - - - - +For more information, see `SQream Studio 5.4.3 `_. Double-Quotations Supported When Importing and Exporting CSVs ************ From 82abd5b5a6d0243f88e149a1f30d00483dd15990 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 31 Jul 2022 18:46:32 +0300 Subject: [PATCH 181/316] Links --- releases/2021.1.2.rst | 2 +- releases/2021.2.1.rst | 10 +++++----- releases/2021.2.rst | 15 ++++++++------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/releases/2021.1.2.rst b/releases/2021.1.2.rst index e163c987d..8945a0261 100644 --- a/releases/2021.1.2.rst +++ b/releases/2021.1.2.rst @@ -50,7 +50,7 @@ For more information, see `Data Types `_. From the Roles area users can create and assign roles and manage user permissions. +The **Roles** area has been added to `Studio version 5.4.3 `_. From the Roles area users can create and assign roles and manage user permissions. Resolved Issues ------------- diff --git a/releases/2021.2.1.rst b/releases/2021.2.1.rst index 2988d98f6..e1a01a147 100644 --- a/releases/2021.2.1.rst +++ b/releases/2021.2.1.rst @@ -27,15 +27,15 @@ PERCENTILE FUNCTIONS ************ SQream now supports the following aggregation functions: -* `PERCENTILE_CONT `_ -* `PERCENTILE_DISC `_ -* `MODE `_ +* `PERCENTILE_CONT `_ +* `PERCENTILE_DISC `_ +* `MODE `_ REGEX REPLACE ************ SQream now supports the ``REGEXP_REPLACE`` function for finding and replacing text column substrings. -For more information, see `REGEX_REPLACE `_. +For more information, see `REGEX_REPLACE `_. Delete Optimization ************ @@ -43,7 +43,7 @@ The ``DELETE`` statement can now delete values that contain multi-table conditio For more information, see `Deleting Values that Contain Multi-Table Conditions `_. -For more information, see `REGEX_REPLACE `_. +For more information, see `REGEX_REPLACE `_. Performance Enhancements ------ diff --git a/releases/2021.2.rst b/releases/2021.2.rst index a46762f01..800b8c863 100644 --- a/releases/2021.2.rst +++ b/releases/2021.2.rst @@ -34,13 +34,13 @@ SQream now uses a new configuration system based on centralized configuration ac For more information, see the following: * `Configuration `_ - describes how to configure your instance of SQream from a centralized location. -* `SQream Studio 5.4.3 `_ - configure your instance of SQream from Studio. +* `SQream Studio 5.4.3 `_ - configure your instance of SQream from Studio. Qualifying Schemas Without Providing an Alias ************ When running queries, SQream now supports qualifying schemas without providing an alias. -For more information, see `SQream Studio 5.4.3 `_. +For more information, see `SQream Studio 5.4.3 `_. Double-Quotations Supported When Importing and Exporting CSVs ************ @@ -48,9 +48,10 @@ When importing and exporting CSVs, SQream now supports using quotation character For more information, see the following: -* :ref:`copy_from` +* `COPY_FROM `_ + +* `COPY_TO `_ -* :ref:`copy_to` Note the following: @@ -128,7 +129,7 @@ NVARCHAR Data Type Renamed TEXT The ``NVARCHAR`` data type has been renamed ``TEXT``. -For more information on the ``TEXT`` data type, see `String (TEXT) `_ +For more information on the ``TEXT`` data type, see `String (TEXT) `_ End of Support ------ @@ -159,13 +160,13 @@ For more information on upgrading your SQream version, see `Upgrading SQream Ver Upgrading Your Client Drivers ************ -For more information on the client drivers for version 2021.2, see `Client Drivers for 2021.2 `_. +For more information on the client drivers for version 2021.2, see `Client Drivers for 2021.2 `_. Configuring Your Instance of SQream ************ A new configuration method is used starting with Version 2021.2. -For more information about configuring your instance of SQream, see :ref:`configuration`. +For more information about configuring your instance of SQream, see `Client Drivers for 2021.2 `_. .. toctree:: :maxdepth: 2 From f72cf319f80d4b3a2aa1b03000eeeac4e25c0ce7 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 31 Jul 2022 19:12:27 +0300 Subject: [PATCH 182/316] Fixed link --- releases/2021.1.2.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releases/2021.1.2.rst b/releases/2021.1.2.rst index 8945a0261..750420260 100644 --- a/releases/2021.1.2.rst +++ b/releases/2021.1.2.rst @@ -40,7 +40,7 @@ String Literals Containing ASCII Characters Interepreted as TEXT ************ SQream now interprets all string literals, including those containing ASCII characters, as ``text``. -For more information, see `String Types `_. +For more information, see `String Types `_. Decimal Literals Interpreted as Numeric Columns ************ From c6cb8164225ddfd101bd43aa787965bf9e72ee54 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 1 Aug 2022 12:09:01 +0300 Subject: [PATCH 183/316] Corrected driver links --- connecting_to_sqream/client_drivers/index.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/connecting_to_sqream/client_drivers/index.rst b/connecting_to_sqream/client_drivers/index.rst index 79d1fd176..b230faaef 100644 --- a/connecting_to_sqream/client_drivers/index.rst +++ b/connecting_to_sqream/client_drivers/index.rst @@ -18,14 +18,14 @@ The following are applicable to all operating systems: * **JDBC** - recommended installation via ``mvn``: * `JDBC .jar file `_ - sqream-jdbc-4.5.3 (.jar) - * `JDBC driver `_ + * `JDBC driver `_ .. _tableau_connector: * **Tableau**: * `Tableau connector `_ - SQream (.taco) - * `Tableau manual installation `_ + * `Tableau manual installation `_ .. _powerbi_connector: @@ -33,7 +33,7 @@ The following are applicable to all operating systems: * **Power BI**: * `Power BI PowerQuery connector `_ - SQream (.mez) - * `Power BI manual installation `_ + * `Power BI manual installation `_ Windows @@ -53,12 +53,12 @@ Linux The following are applicable to Linux: * `SQream SQL (x86_64) `_ - sqream-sql-v2020.1.1_stable.x86_64.tar.gz -* `Sqream SQL CLI Reference `_ - Interactive command-line SQL client for Intel-based machines +* `Sqream SQL CLI Reference `_ - Interactive command-line SQL client for Intel-based machines :: * `SQream SQL*(IBM POWER9) `_ - sqream-sql-v2020.1.1_stable.ppc64le.tar.gz -* `Sqream SQL CLI Reference `_ - Interactive command-line SQL client for IBM POWER9-based machines +* `Sqream SQL CLI Reference `_ - Interactive command-line SQL client for IBM POWER9-based machines :: From edcf3ce813e7ce9b41a52782397006848cf93f3e Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 1 Aug 2022 13:35:35 +0300 Subject: [PATCH 184/316] corrected links --- releases/2021.2.rst | 5 ++++- releases/2022.1.rst | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/releases/2021.2.rst b/releases/2021.2.rst index 800b8c863..c4174a3aa 100644 --- a/releases/2021.2.rst +++ b/releases/2021.2.rst @@ -89,7 +89,10 @@ Note the following: For more information, see the following statements: -* :ref:`copy_from` +* `COPY_FROM `_ + +* `CREATE_FOREIGN_TABLE `_ + * :ref:`create_foreign_table` diff --git a/releases/2022.1.rst b/releases/2022.1.rst index 085108a43..3d1517371 100644 --- a/releases/2022.1.rst +++ b/releases/2022.1.rst @@ -31,7 +31,7 @@ SQream now supports data encryption mechanisms in accordance with **General Data Using the data encryption feature may lead to a maximum of a 10% increase in performance degradation. -For more information, see `Data Encryption `_. +For more information, see `Data Encryption `_. Update Feature ************ From 2f95101378fdcf6f73f57e738f699a96ef8759dd Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 1 Aug 2022 19:03:59 +0300 Subject: [PATCH 185/316] Added External Storage Platforms --- .../hdfs.rst | 0 external_storage_platforms/index.rst | 25 +++++++++++++++++++ .../s3.rst | 0 index.rst | 1 + operational_guides/external_data.rst | 25 ------------------- operational_guides/index.rst | 1 - 6 files changed, 26 insertions(+), 26 deletions(-) rename {operational_guides => external_storage_platforms}/hdfs.rst (100%) create mode 100644 external_storage_platforms/index.rst rename {operational_guides => external_storage_platforms}/s3.rst (100%) delete mode 100644 operational_guides/external_data.rst diff --git a/operational_guides/hdfs.rst b/external_storage_platforms/hdfs.rst similarity index 100% rename from operational_guides/hdfs.rst rename to external_storage_platforms/hdfs.rst diff --git a/external_storage_platforms/index.rst b/external_storage_platforms/index.rst new file mode 100644 index 000000000..92c35ee63 --- /dev/null +++ b/external_storage_platforms/index.rst @@ -0,0 +1,25 @@ +.. _external_storage_platforms: + +*********************** +External Storage Platforms +*********************** +SQream supports the following external storage platforms: + +.. toctree:: + :maxdepth: 1 + :titlesonly: + + s3 + hdfs + +For more information, see the following: + +* :ref:`foreign_tables` + + :: + +* :ref:`copy_from` + + :: + +* :ref:`copy_to` diff --git a/operational_guides/s3.rst b/external_storage_platforms/s3.rst similarity index 100% rename from operational_guides/s3.rst rename to external_storage_platforms/s3.rst diff --git a/index.rst b/index.rst index bc5c25c2c..0f418c2fb 100644 --- a/index.rst +++ b/index.rst @@ -100,6 +100,7 @@ If you're looking for an older version of the documentation, versions 1.10 throu installation_guides/index data_ingestion/index connecting_to_sqream/index + external_storage_platforms/index loading_and_unloading_data/index feature_guides/index operational_guides/index diff --git a/operational_guides/external_data.rst b/operational_guides/external_data.rst deleted file mode 100644 index 8bf51f108..000000000 --- a/operational_guides/external_data.rst +++ /dev/null @@ -1,25 +0,0 @@ -.. _external_data: - -********************************** -Working with External Data -********************************** -SQream supports the following external data sources: - -.. toctree:: - :maxdepth: 1 - :titlesonly: - - s3 - hdfs - -For more information, see the following: - -* :ref:`external_tables` - - :: - -* :ref:`copy_from` - - :: - -* :ref:`copy_to` \ No newline at end of file diff --git a/operational_guides/index.rst b/operational_guides/index.rst index 9deb0835c..25e2cdff2 100644 --- a/operational_guides/index.rst +++ b/operational_guides/index.rst @@ -14,7 +14,6 @@ This section summarizes the following operational guides: access_control creating_or_cloning_a_storage_cluster - external_data foreign_tables delete_guide exporting_data From 637d7f74b1c40e4624bced96b28af440c7f1bff5 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 2 Aug 2022 11:10:27 +0300 Subject: [PATCH 186/316] Fixed links. --- releases/2021.2.rst | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/releases/2021.2.rst b/releases/2021.2.rst index c4174a3aa..2140dc6be 100644 --- a/releases/2021.2.rst +++ b/releases/2021.2.rst @@ -91,10 +91,7 @@ For more information, see the following statements: * `COPY_FROM `_ -* `CREATE_FOREIGN_TABLE `_ - - -* :ref:`create_foreign_table` +* `CREATE_FOREIGN_TABLE `_ Performance Enhancements ------ @@ -159,7 +156,7 @@ When upgrading from a SQream version earlier than 2021.2 you must upgrade your s $ cat /etc/sqream/sqream1_config.json |grep cluster $ ./upgrade_storage -For more information on upgrading your SQream version, see `Upgrading SQream Version `_. +For more information on upgrading your SQream version, see `Upgrading SQream Version `_. Upgrading Your Client Drivers ************ From b65ab1f10b30ddfa0ab646a9704da87ddd4cabe0 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 2 Aug 2022 12:17:56 +0300 Subject: [PATCH 187/316] Reinstated Healer configuration flags Removed login max retries flag (it's for 2022.1.1). --- configuration_guides/admin_worker_flags.rst | 3 ++- .../healer_max_inactivity_hours.rst | 14 ++++++++++++++ configuration_guides/is_healer_on.rst | 14 ++++++++++++++ feature_guides/query_healer.rst | 12 +++++++++++- 4 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 configuration_guides/healer_max_inactivity_hours.rst create mode 100644 configuration_guides/is_healer_on.rst diff --git a/configuration_guides/admin_worker_flags.rst b/configuration_guides/admin_worker_flags.rst index 6be021d70..d58dad687 100644 --- a/configuration_guides/admin_worker_flags.rst +++ b/configuration_guides/admin_worker_flags.rst @@ -9,4 +9,5 @@ The **Worker Administration Flags** page describes **Worker** modification type * `Enabling Manually Setting Reported IP `_ * `Setting Port Used for Metadata Server Connection `_ * `Assigning Local Network IP `_ -* `Adjusting Permitted Log-in Attempts `_ \ No newline at end of file +* `Enabling the Query Healer `_ +* `Configuring the Query Healer `_ \ No newline at end of file diff --git a/configuration_guides/healer_max_inactivity_hours.rst b/configuration_guides/healer_max_inactivity_hours.rst new file mode 100644 index 000000000..d05d46014 --- /dev/null +++ b/configuration_guides/healer_max_inactivity_hours.rst @@ -0,0 +1,14 @@ +.. _healer_max_inactivity_hours: + +************************* +Query Healer +************************* +The ``healerMaxInactivityHours`` flag is used for defining the threshold for creating a log recording a slow statement. The log includes information about the log memory, CPU and GPU. + +The following describes the ``healerMaxInactivityHours`` flag: + +* **Data type** - size_t +* **Default value** - ``5`` +* **Allowed values** - 1-4000000000 + +For related flags, see :ref:`is_healer_on`. \ No newline at end of file diff --git a/configuration_guides/is_healer_on.rst b/configuration_guides/is_healer_on.rst new file mode 100644 index 000000000..8b90654ec --- /dev/null +++ b/configuration_guides/is_healer_on.rst @@ -0,0 +1,14 @@ +.. _is_healer_on: + +************************* +Enabling the Query Healer +************************* +The ``is_healer_on`` flag enables the Query Healer, which periodically examines the progress of running statements and logs statements exceeding the ``healerMaxInactivityHours`` flag setting. + +The following describes the ``is_healer_on`` flag: + +* **Data type** - boolean +* **Default value** - ``true`` +* **Allowed values** - ``true``, ``false`` + +For related flags, see :ref:`healer_max_inactivity_hours`. \ No newline at end of file diff --git a/feature_guides/query_healer.rst b/feature_guides/query_healer.rst index 667a91ed8..8f0b56d08 100644 --- a/feature_guides/query_healer.rst +++ b/feature_guides/query_healer.rst @@ -19,6 +19,16 @@ The following is an example of a log record for a query stuck in the query detec 2022/05/19::20:01:25|ERROR|Healer|(0x7f07147fc700)|Stuck query found. Statement ID: 72, Last chunk producer updated: 1 WriteTable, Started on: Thu May 19 14:01:25 2022, Last updated: Thu May 19 15:01:25 2022, Stuck time: 5 hours, Max allowed stuck query time: 5 hours +The ``healerMaxInactivityHours`` log frequency is calculated as 5% of the flag setting. When set to to five hours (the default setting), the Query Healer triggers an examination every 15 minutes. + Configuring the Healer ------------------ -The **healerMaxInactivityHours** is required define the threshold for creating a log recording a slow statement. The log includes information about the log memory, CPU and GPU. The ``healerMaxInactivityHours`` log frequency is calculated as 5% of the flag setting. For example, setting ``healerMaxInactivityHours`` to five hours (the default setting) triggers an examination every 15 minutes. \ No newline at end of file +The following **Administration Worker** flags are required to configure the Query Healer: + + * :ref:`is_healer_on` - Enables the Query Healer. + + :: + + * :ref:`healer_max_inactivity_hours` - Defines the threshold for creating a log recording a slow statement. The log includes information about the log memory, CPU and GPU. + +The ``healerMaxInactivityHours`` log frequency is calculated as 5% of the flag setting. For example, setting ``healerMaxInactivityHours`` to five hours (the default setting) triggers an examination every 15 minutes. \ No newline at end of file From 307fba9a817b840cbc901500db43da96f6fe4897 Mon Sep 17 00:00:00 2001 From: YanivGerowitz <82020437+YanivGerowitz@users.noreply.github.com> Date: Tue, 2 Aug 2022 15:24:32 +0300 Subject: [PATCH 188/316] Update data_encryption_syntax.rst --- feature_guides/data_encryption_syntax.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/feature_guides/data_encryption_syntax.rst b/feature_guides/data_encryption_syntax.rst index 3370698cf..65f03ab5e 100644 --- a/feature_guides/data_encryption_syntax.rst +++ b/feature_guides/data_encryption_syntax.rst @@ -23,5 +23,3 @@ The following is an example of encrypting a new table: salary INT(6) ENCRYPT); .. note:: Users without permissions cannot view the entire table as long as at least one column is encrypted. The (unique) encryption/decryption key is relevant only at the system level and is not held by users. - -Note that the master key is hard-coded in the system and cannot be changed. From ed492d74ac4aa33abbe63b6b38ead278fe7e34fc Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 2 Aug 2022 16:34:18 +0300 Subject: [PATCH 189/316] Created and populated 2022.1.1 - NOT PUBLISHED --- _static/images/new_2022.1.1.png | Bin 0 -> 3259 bytes _static/images/new_dark_gray_2022.1.1.png | Bin 0 -> 2867 bytes _static/images/new_gray_2022.1.1.png | Bin 0 -> 3842 bytes configuration_guides/admin_worker_flags.rst | 19 ++- configuration_guides/login_max_retries.rst | 7 +- feature_guides/compression.rst | 8 + operational_guides/access_control.rst | 1 + .../access_control_password_policy.rst | 63 ++++++++ .../sql_statements/dml_commands/update.rst | 149 +++++++++++++++++- releases/2022.1.1.rst | 136 ++++++++++++++++ releases/2022.1_index.rst | 1 + releases/index.rst | 2 +- 12 files changed, 373 insertions(+), 13 deletions(-) create mode 100644 _static/images/new_2022.1.1.png create mode 100644 _static/images/new_dark_gray_2022.1.1.png create mode 100644 _static/images/new_gray_2022.1.1.png create mode 100644 operational_guides/access_control_password_policy.rst create mode 100644 releases/2022.1.1.rst diff --git a/_static/images/new_2022.1.1.png b/_static/images/new_2022.1.1.png new file mode 100644 index 0000000000000000000000000000000000000000..2ffb80039be7a7a4ac7605f8271045e4d0138185 GIT binary patch literal 3259 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 Ef=gpok^lez literal 0 HcmV?d00001 diff --git a/configuration_guides/admin_worker_flags.rst b/configuration_guides/admin_worker_flags.rst index d58dad687..edbc71465 100644 --- a/configuration_guides/admin_worker_flags.rst +++ b/configuration_guides/admin_worker_flags.rst @@ -3,11 +3,18 @@ ************************* Worker Administration Flags ************************* + +.. |icon-new_gray_2022.1.1| image:: /_static/images/new_gray_2022.1.1.png + :align: middle + :width: 110 + + The **Worker Administration Flags** page describes **Worker** modification type flags, which can be modified by administrators on a session and cluster basis using the ``ALTER SYSTEM SET`` command: -* `Setting Total Device Memory Usage in SQream Instance `_ -* `Enabling Manually Setting Reported IP `_ -* `Setting Port Used for Metadata Server Connection `_ -* `Assigning Local Network IP `_ -* `Enabling the Query Healer `_ -* `Configuring the Query Healer `_ \ No newline at end of file +* `Setting Total Device Memory Usage in SQream Instance `_ +* `Enabling Manually Setting Reported IP `_ +* `Setting Port Used for Metadata Server Connection `_ +* `Assigning Local Network IP `_ +* `Enabling the Query Healer `_ +* `Configuring the Query Healer `_ +* `Adjusting the Permitted Log-In Attempts `_ |icon-new_gray_2022.1.1| \ No newline at end of file diff --git a/configuration_guides/login_max_retries.rst b/configuration_guides/login_max_retries.rst index bf3ae6d40..af236c9c3 100644 --- a/configuration_guides/login_max_retries.rst +++ b/configuration_guides/login_max_retries.rst @@ -3,7 +3,12 @@ ************************* Adjusting Permitted Log-in Attempts ************************* -The ``loginMaxRetries`` flag sets the permitted log-in attempts. + +.. |icon-new_2022.1.1| image:: /_static/images/new_2022.1.1.png + :align: middle + :width: 110 + +The ``loginMaxRetries`` flag |icon-new_2022.1.1| sets the permitted log-in attempts. The following describes the ``loginMaxRetries`` flag: diff --git a/feature_guides/compression.rst b/feature_guides/compression.rst index 96c051ff4..ce5e922b6 100644 --- a/feature_guides/compression.rst +++ b/feature_guides/compression.rst @@ -4,6 +4,10 @@ Compression *********************** +.. |icon-new_dark_gray_2022.1.1.png| image:: /_static/images/new_dark_gray_2022.1.1.png + :align: middle + :width: 110 + SQream DB uses compression and encoding techniques to optimize query performance and save on disk space. Encoding @@ -89,6 +93,10 @@ Compression strategies - Integer types - Optimized RLE + Delta type for built-in :ref:`identity columns`. - GPU + * - ``zlib`` |icon-new_dark_gray_2022.1.1.png| + - All types + - The **basic_zlib_compressor** and **basic_zlib_decompressor** compress and decompress data in the **ZLIB** format, using **DualUseFilters** for input and output. In general, compression filters are for output, and decompression filters for input. + - CPU .. _specifying_compressions: diff --git a/operational_guides/access_control.rst b/operational_guides/access_control.rst index 88a14d71b..d5d32394e 100644 --- a/operational_guides/access_control.rst +++ b/operational_guides/access_control.rst @@ -11,4 +11,5 @@ Access Control access_control_overview access_control_managing_roles access_control_permissions + access_control_password_policy access_control_departmental_example \ No newline at end of file diff --git a/operational_guides/access_control_password_policy.rst b/operational_guides/access_control_password_policy.rst new file mode 100644 index 000000000..0a17f833e --- /dev/null +++ b/operational_guides/access_control_password_policy.rst @@ -0,0 +1,63 @@ +.. _access_control_password_policy: + +************** +Password Policy (New!) +************** + +.. |icon-new_gray_2022.1.1| image:: /_static/images/new_gray_2022.1.1.png + :align: middle + :width: 110 + +As part of our compliance with GDPR standards |icon-new_gray_2022.1.1| SQream relies on a strong password policy when accessing the CLI or Studio, with the following requirements: + +* At least eight characters long. + + :: + +* Mandatory upper and lowercase letters. + + :: + +* At least one numeric character. + + :: + +* May not include a username. + + :: + +* Must include at least one special character, such as **?**, **!**, **$**, etc. + +You can create a password through the Studio graphic interface or through the CLI, as in the following example command: + +.. code-block:: console + + CREATE ROLE user_a ; + GRANT LOGIN to user_a ; + GRANT PASSWORD 'BBAu47?fqPL' to user_a ; + +Creating a password that does not comply with the above requirements generates the following error message: + +.. code-block:: console + + The password you attempt to create does not comply with SQream security requirements. Please follow the requirements below: + + * At least 8 characters long. + + * Must include both upper and lower case letters. + + * Must include at least one numeric character. + + * Must not include your username. + + * Must include at least one “special” character (?, !, $, etc.). + +.. note:: When a new user created in Studio, a message is displayed to help you determine what the constraints are. + +Unsuccessfully attempting to log in three times displays the following message: + +.. code-block:: console + + The user is locked. please contact your system administrator to reset the password and regain access functionality. + +For more information, see :ref:`login_max_retries`. \ No newline at end of file diff --git a/reference/sql/sql_statements/dml_commands/update.rst b/reference/sql/sql_statements/dml_commands/update.rst index d0f545017..b804d6c37 100644 --- a/reference/sql/sql_statements/dml_commands/update.rst +++ b/reference/sql/sql_statements/dml_commands/update.rst @@ -3,9 +3,9 @@ ********************** UPDATE ********************** -The **UPDATE** statement page |icon-new_2022.1| describes the following: +The **UPDATE** statement page describes the following: -.. |icon-new_2022.1| image:: /_static/images/new_2022.1.png +.. |icon-new_2022.1.1| image:: /_static/images/new_2022.1.1.png :align: middle :width: 110 @@ -35,6 +35,7 @@ The following is the correct syntax for the ``UPDATE`` command: UPDATE target_table_name [[AS] alias1] SET column_name = expression [,...] + [FROM additional_table_name [[AS] alias2][,...]] [WHERE condition] The following is the correct syntax for triggering a clean-up: @@ -60,10 +61,14 @@ The following table describes the ``UPDATE`` parameters: * - ``column_name`` - Specifies the column containing the data to be updated. * - ``additional_table_name`` - - Additional tables used in the WHERE condition for performing complex joins. + - Specifies the column containing the data to be updated. + * - ``FROM`` |icon-new_2022.1.1| + - For making complex joins, specifies additional tables to be used in the WHERE condition. ``FROM`` is similar to the ``FROM`` clause in a ``DELETE`` statement. * - ``condition`` - Specifies the condition for updating the data. +.. note:: A single table can appear **both** as a ``DELETE`` target *and* as a ``FROM`` table. This can be useful for deleting data based on self-join conditions. A ``SET`` clause can contain columns from tables specified in a ``FROM`` clause. For example, using the join ``WHERE`` condition updates rows in the target tables with the values of one of the matching rows. + .. note:: Similar to a ``DELETE`` statement, an ``UPDATE`` statement may leave some uncleaned data behind, which requires a clean-up operation. Examples @@ -74,6 +79,30 @@ The **Examples** section includes the following examples: :local: :depth: 1 +Updating an Entire Table +----------------- +The Examples section shows how to modify the value of certain columns in existing rows without creating a table. The examples are based on the following tables: + +.. image:: /_static/images/delete_optimization.png + +The following methods for updating an entire table generate the same output, and result with the ``bands`` record set to ``NULL``: + +.. code-block:: postgres + + UPDATE bands SET records_sold = 0; + +.. code-block:: postgres + + UPDATE bands SET records_sold = 0 WHERE true; + +.. code-block:: postgres + + UPDATE bands SET records_sold = 0 USING countries; + +.. code-block:: postgres + + UPDATE bands SET records_sold = 0 USING countries WHERE 1=1; + Performing Simple Updates ----------------- The following is an example of performing a simple update: @@ -81,9 +110,102 @@ The following is an example of performing a simple update: .. code-block:: postgres UPDATE bands SET records_sold = records_sold + 1 WHERE name LIKE 'The %'; + +Updating Tables that Contain Multi-Table Conditions +----------------- +The following shows an example of updating tables that contain multi-table conditions: -Triggering a Clean-Up +.. code-block:: postgres + + UPDATE bands + SET records_sold = records_sold + 1 + WHERE EXISTS ( + SELECT 1 FROM countries + WHERE countries.id=bands.country_id + AND country.name = 'Sweden' + ); + +Updating Tables that Contain Multi-Table Conditions using the FROM Clause +----------------- +The following shows an example of updating tables that contain multi-table conditions using the ``FROM`` clause: + +.. code-block:: postgres + + UPDATE bands + SET records_sold = records_sold + + CASE + WHEN c.name = 'Israel' THEN 2 + ELSE 1 + END + FROM countries c + +You can also write the statement above using the FROM clause: + +.. code-block:: psql + + UPDATE bands + SET records_sold = records_sold + 1 + FROM countries + WHERE countries.id=bands.country_id AND country.name = 'Sweden'; + +Updating Tables that Contain Multi-Table Expressions +----------------- +The following shows an example of updating tables that contain multi-table expressions: + +.. code-block:: postgres + + UPDATE bands + SET records_sold = records_sold + + CASE + WHEN c.name = 'Israel' THEN 2 + ELSE 1 + END + FROM countries c + +Identifying and Cleaning Up Tables --------------------------------------- +The following section shows examples of each phase required for cleaning up tables: + +* :ref:`Listing tables that require clean-up` +* :ref:`Identifying clean-up predicates` +* :ref:`Triggering a clean-up` + +.. _listing_tables_that_require_cleanup: + +Listing Tables that Require Clean-Up +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The following shows an example of listing tables that require clean-up: + +.. code-block:: psql + + farm=> SELECT t.table_name FROM sqream_catalog.delete_predicates dp + JOIN sqream_catalog.tables t + ON dp.table_id = t.table_id + GROUP BY 1; + cool_animals + + 1 row + +.. _identifying_cleanup_predicates: + +Identifying Clean-Up Predicates +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The following shows an example of listing the clean-up predicates: + +.. code-block:: psql + + farm=> SELECT delete_predicate FROM sqream_catalog.delete_predicates dp + JOIN sqream_catalog.tables t + ON dp.table_id = t.table_id + WHERE t.table_name = 'cool_animals'; + weight > 1000 + + 1 row + +.. _triggering_a_cleanup: + +Triggering a Clean-Up +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The following section shows an example of triggering a clean-up: .. code-block:: psql @@ -98,10 +220,27 @@ The following is an example of the output generated from the above: * **column_id** - 1 * **extent_ID** - 0 +Security and Access Control +============= +Executing an ``UPDATE`` statement requires the following: + +* Both ``UPDATE`` and ``SELECT`` permissions on the target table. + + :: + +* The ``SELECT`` permission for each additional table referenced in the the statement (either in the ``FROM`` clause or in a ``WHERE`` subquery expression). + +For more information, navigate to the **Access Control** page and see `Permissions `_. + +file:///C:/Users/Yaniv/sqream_docs/_build/html/operational_guides/access_control_permissions.html + Locking and Concurrency ============= Executing the ``UPDATE`` statement obtains an exclusive ``UPDATE`` lock on the target table. Permissions ============= -Executing an ``UPDATE`` statement requires both ``UPDATE`` and ``SELECT`` permissions on the target table. \ No newline at end of file +Executing an ``UPDATE`` statement requires the following permissions: + +* Both ``UPDATE`` and ``SELECT`` permissions on the target table. +* The ``SELECT`` permission for each additional table you reference in the statement (in ither the ``FROM`` clause or ``WHERE`` subquery section). \ No newline at end of file diff --git a/releases/2022.1.1.rst b/releases/2022.1.1.rst new file mode 100644 index 000000000..15fcd8c42 --- /dev/null +++ b/releases/2022.1.1.rst @@ -0,0 +1,136 @@ +.. _2022.1.1: + +************************** +Release Notes 2022.1.1 +************************** +The 2022.1.1 release notes were released on 7/19/2022 and describe the following: + +.. contents:: + :local: + :depth: 1 + +Version Content +---------- +The 2022.1.1 Release Notes describes the following: + +* Enhanced security features. +* New data manipulation command. +* Additional data ingestion format. + +New Features +---------- +The 2022.1.1 Release Notes include the following new features: + +.. contents:: + :local: + :depth: 1 + +Update Feature +************ +SQream now supports the DML **Update** feature, which is used for modifying the value of certain columns in existing rows. + +For more information, see `UPDATE `_. + +file:///C:/Users/Yaniv/sqream_docs/_build/html/reference/sql/sql_statements/dml_commands/update.html?highlight=update + +Password Policy +************ +In compliance with GDPR standards, SQream now requires a strong password policy when accessing the CLI or Studio. + +For more information, see `Password Policy `_. + +file:///C:/Users/Yaniv/sqream_docs/_build/html/operational_guides/access_control_password_policy.html?highlight=password%20policy + +Compression +************ + +SQream now supports the **zlib** compression format. + +For more information, see `Compression `_. + +file:///C:/Users/Yaniv/sqream_docs/_build/html/feature_guides/compression.html#compression-strategies + +Known Issues +--------- +The following table lists the known issues for Version 2022.1.1: + ++-------------+------------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+================================================================================================+ +| SQ-6419 | An internal compiler error occurred when casting Numeric literals in an aggregation function. | ++-------------+------------------------------------------------------------------------------------------------+ + +Resolved Issues +--------- +The following table lists the issues that were resolved in Version 2022.1.1: + ++-------------+----------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+========================================================================================+ +| SQ-10873 | Inserting 100K bytes into a text column resulted in an unclear error message. | ++-------------+----------------------------------------------------------------------------------------+ +| SQ-10955 | No metadata filters were applied when filtering by a nullable date using ``dateadd``. | ++-------------+----------------------------------------------------------------------------------------+ + +Operations and Configuration Changes +-------- +The ``login_max_retries`` configuration flag is required for adjusting the permitted log-in attempts. + +For more information, see `Adjusting the Permitted Log-In Attempts `_. + +https://docs.sqream.com/en/latest/configuration_guides/login_max_retries.html + +Naming Changes +------- +No relevant naming changes were made. + +Deprecated Features +------- +No features were deprecated for Version 2022.1.1. + +End of Support +------- +The End of Support section is not relevant to Version 2022.1.1. + +Upgrading to v2022.1.1 +------- +1. Generate a back-up of the metadata by running the following command: + + .. code-block:: console + + $ select backup_metadata('out_path'); + + .. tip:: SQream recommends storing the generated back-up locally in case needed. + + SQream runs the Garbage Collector and creates a clean backup tarball package. + +2. Shut down all SQream services. + + :: + +3. Extract the recently created back-up file. + + :: + +4. Replace your current metadata with the metadata you stored in the back-up file. + + :: + +5. Navigate to the new SQream package bin folder. + + :: + +6. Run the following command: + + .. code-block:: console + + $ ./upgrade_storage + + .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version `_ procedure. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2022.1.1.1 \ No newline at end of file diff --git a/releases/2022.1_index.rst b/releases/2022.1_index.rst index 9c7b2b211..628b372aa 100644 --- a/releases/2022.1_index.rst +++ b/releases/2022.1_index.rst @@ -13,4 +13,5 @@ The 2022.1 Release Notes describe the following releases: :maxdepth: 1 :glob: + 2022.1.1 2022.1 \ No newline at end of file diff --git a/releases/index.rst b/releases/index.rst index b1d065a9e..84024586e 100644 --- a/releases/index.rst +++ b/releases/index.rst @@ -32,7 +32,7 @@ Release Notes :glob: :hidden: - 2022.1 + 2022.1_index 2021.2_index 2021.1_index 2020.3_index From 3239b338af16ae2262dc98ece1b5626d567a84fc Mon Sep 17 00:00:00 2001 From: YanivGerowitz <82020437+YanivGerowitz@users.noreply.github.com> Date: Tue, 2 Aug 2022 17:08:37 +0300 Subject: [PATCH 190/316] Update data_encryption_syntax.rst --- feature_guides/data_encryption_syntax.rst | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/feature_guides/data_encryption_syntax.rst b/feature_guides/data_encryption_syntax.rst index 65f03ab5e..0eec64bc7 100644 --- a/feature_guides/data_encryption_syntax.rst +++ b/feature_guides/data_encryption_syntax.rst @@ -7,19 +7,20 @@ The following is the syntax for encrypting a new table: .. code-block:: console - CREATE TABLE ( - <(maximum string length)>, - - last_name <(maximum string length)>, - salary (<(maximum string length)>) ENCRYPT); + CREATE TABLE

( + NOT NULL ENCRYPT, + ENCRYPT, + , + ENCRYPT); The following is an example of encrypting a new table: .. code-block:: console CREATE TABLE client_name ( - first_name TEXT(128), - last_name TEXT(128), - salary INT(6) ENCRYPT); + id BIGINT NOT NULL ENCRYPT, + first_name TEXT ENCRYPT, + last_name TEXT, + salary INT ENCRYPT); .. note:: Users without permissions cannot view the entire table as long as at least one column is encrypted. The (unique) encryption/decryption key is relevant only at the system level and is not held by users. From 14d029d853ac26bda98622b282d649a22c17a89e Mon Sep 17 00:00:00 2001 From: YanivGerowitz <82020437+YanivGerowitz@users.noreply.github.com> Date: Tue, 2 Aug 2022 18:13:08 +0300 Subject: [PATCH 191/316] Update data_encryption_syntax.rst --- feature_guides/data_encryption_syntax.rst | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/feature_guides/data_encryption_syntax.rst b/feature_guides/data_encryption_syntax.rst index 0eec64bc7..bba431aec 100644 --- a/feature_guides/data_encryption_syntax.rst +++ b/feature_guides/data_encryption_syntax.rst @@ -23,4 +23,12 @@ The following is an example of encrypting a new table: last_name TEXT, salary INT ENCRYPT); -.. note:: Users without permissions cannot view the entire table as long as at least one column is encrypted. The (unique) encryption/decryption key is relevant only at the system level and is not held by users. +.. note:: Because encryption is not associated with any role, users with **Read** or **Insert** permissions can read tables containing encrypted data. + +.. warning:: Your performance degradation increases in correlation with the amount of added columns. + +You cannot encrypt more than three columns. Attempting to encrypt more than three columns displays the following error message: + +.. code-block:: console + + Error preparing statement: Cannot create a table with more than three encrypted columns. From c020e61055c97b51fabb9aa5f62436a31593ae95 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 2 Aug 2022 19:11:31 +0300 Subject: [PATCH 192/316] Added Avro --- data_ingestion/index.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data_ingestion/index.rst b/data_ingestion/index.rst index fae7824c7..c11d47faa 100644 --- a/data_ingestion/index.rst +++ b/data_ingestion/index.rst @@ -14,5 +14,6 @@ The **Data Ingestion Sources** provides information about the following: csv parquet orc + oracle -For information about database tools and interfaces that SQream supports, see `Third Party Tools `_. \ No newline at end of file +For information about database tools and interfaces that SQream supports, see `Third Party Tools `_. \ No newline at end of file From 53070e875581b3fbf71c51432e28a558ae48798c Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Wed, 3 Aug 2022 16:14:36 +0300 Subject: [PATCH 193/316] Added Table (Jenny's request) --- .../access_control_password_policy.rst | 2 +- .../sql_statements/dml_commands/update.rst | 121 +----------------- releases/2022.1.1.rst | 19 +-- releases/2022.1_index.rst | 54 +++++++- 4 files changed, 57 insertions(+), 139 deletions(-) diff --git a/operational_guides/access_control_password_policy.rst b/operational_guides/access_control_password_policy.rst index 0a17f833e..6d9d989f2 100644 --- a/operational_guides/access_control_password_policy.rst +++ b/operational_guides/access_control_password_policy.rst @@ -1,7 +1,7 @@ .. _access_control_password_policy: ************** -Password Policy (New!) +Password Security Compliance (New!) ************** .. |icon-new_gray_2022.1.1| image:: /_static/images/new_gray_2022.1.1.png diff --git a/reference/sql/sql_statements/dml_commands/update.rst b/reference/sql/sql_statements/dml_commands/update.rst index b804d6c37..7c1b8c8b8 100644 --- a/reference/sql/sql_statements/dml_commands/update.rst +++ b/reference/sql/sql_statements/dml_commands/update.rst @@ -78,31 +78,7 @@ The **Examples** section includes the following examples: .. contents:: :local: :depth: 1 - -Updating an Entire Table ------------------ -The Examples section shows how to modify the value of certain columns in existing rows without creating a table. The examples are based on the following tables: - -.. image:: /_static/images/delete_optimization.png - -The following methods for updating an entire table generate the same output, and result with the ``bands`` record set to ``NULL``: - -.. code-block:: postgres - - UPDATE bands SET records_sold = 0; - -.. code-block:: postgres - - UPDATE bands SET records_sold = 0 WHERE true; - -.. code-block:: postgres - - UPDATE bands SET records_sold = 0 USING countries; - -.. code-block:: postgres - - UPDATE bands SET records_sold = 0 USING countries WHERE 1=1; - + Performing Simple Updates ----------------- The following is an example of performing a simple update: @@ -125,87 +101,8 @@ The following shows an example of updating tables that contain multi-table condi AND country.name = 'Sweden' ); -Updating Tables that Contain Multi-Table Conditions using the FROM Clause ------------------ -The following shows an example of updating tables that contain multi-table conditions using the ``FROM`` clause: - -.. code-block:: postgres - - UPDATE bands - SET records_sold = records_sold + - CASE - WHEN c.name = 'Israel' THEN 2 - ELSE 1 - END - FROM countries c - -You can also write the statement above using the FROM clause: - -.. code-block:: psql - - UPDATE bands - SET records_sold = records_sold + 1 - FROM countries - WHERE countries.id=bands.country_id AND country.name = 'Sweden'; - -Updating Tables that Contain Multi-Table Expressions ------------------ -The following shows an example of updating tables that contain multi-table expressions: - -.. code-block:: postgres - - UPDATE bands - SET records_sold = records_sold + - CASE - WHEN c.name = 'Israel' THEN 2 - ELSE 1 - END - FROM countries c - -Identifying and Cleaning Up Tables ---------------------------------------- -The following section shows examples of each phase required for cleaning up tables: - -* :ref:`Listing tables that require clean-up` -* :ref:`Identifying clean-up predicates` -* :ref:`Triggering a clean-up` - -.. _listing_tables_that_require_cleanup: - -Listing Tables that Require Clean-Up -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The following shows an example of listing tables that require clean-up: - -.. code-block:: psql - - farm=> SELECT t.table_name FROM sqream_catalog.delete_predicates dp - JOIN sqream_catalog.tables t - ON dp.table_id = t.table_id - GROUP BY 1; - cool_animals - - 1 row - -.. _identifying_cleanup_predicates: - -Identifying Clean-Up Predicates -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The following shows an example of listing the clean-up predicates: - -.. code-block:: psql - - farm=> SELECT delete_predicate FROM sqream_catalog.delete_predicates dp - JOIN sqream_catalog.tables t - ON dp.table_id = t.table_id - WHERE t.table_name = 'cool_animals'; - weight > 1000 - - 1 row - -.. _triggering_a_cleanup: - Triggering a Clean-Up -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +----------------- The following section shows an example of triggering a clean-up: .. code-block:: psql @@ -220,20 +117,6 @@ The following is an example of the output generated from the above: * **column_id** - 1 * **extent_ID** - 0 -Security and Access Control -============= -Executing an ``UPDATE`` statement requires the following: - -* Both ``UPDATE`` and ``SELECT`` permissions on the target table. - - :: - -* The ``SELECT`` permission for each additional table referenced in the the statement (either in the ``FROM`` clause or in a ``WHERE`` subquery expression). - -For more information, navigate to the **Access Control** page and see `Permissions `_. - -file:///C:/Users/Yaniv/sqream_docs/_build/html/operational_guides/access_control_permissions.html - Locking and Concurrency ============= Executing the ``UPDATE`` statement obtains an exclusive ``UPDATE`` lock on the target table. diff --git a/releases/2022.1.1.rst b/releases/2022.1.1.rst index 15fcd8c42..517c11042 100644 --- a/releases/2022.1.1.rst +++ b/releases/2022.1.1.rst @@ -27,29 +27,22 @@ The 2022.1.1 Release Notes include the following new features: Update Feature ************ -SQream now supports the DML **Update** feature, which is used for modifying the value of certain columns in existing rows. +The DML ``UPDATE`` statement has been enhanced to support running subqueries in the ``WHERE`` condition. For more information, see `UPDATE `_. -file:///C:/Users/Yaniv/sqream_docs/_build/html/reference/sql/sql_statements/dml_commands/update.html?highlight=update - -Password Policy +Password Security Compliance ************ In compliance with GDPR standards, SQream now requires a strong password policy when accessing the CLI or Studio. -For more information, see `Password Policy `_. - -file:///C:/Users/Yaniv/sqream_docs/_build/html/operational_guides/access_control_password_policy.html?highlight=password%20policy +For more information, see :ref:`access_control_password_policy`. Compression ************ - SQream now supports the **zlib** compression format. For more information, see `Compression `_. -file:///C:/Users/Yaniv/sqream_docs/_build/html/feature_guides/compression.html#compression-strategies - Known Issues --------- The following table lists the known issues for Version 2022.1.1: @@ -69,7 +62,7 @@ The following table lists the issues that were resolved in Version 2022.1.1: +=============+========================================================================================+ | SQ-10873 | Inserting 100K bytes into a text column resulted in an unclear error message. | +-------------+----------------------------------------------------------------------------------------+ -| SQ-10955 | No metadata filters were applied when filtering by a nullable date using ``dateadd``. | +| SQ-10892 | An unclear message was displayed when users ran ``UPDATE`` on foreign tables. | +-------------+----------------------------------------------------------------------------------------+ Operations and Configuration Changes @@ -78,8 +71,6 @@ The ``login_max_retries`` configuration flag is required for adjusting the permi For more information, see `Adjusting the Permitted Log-In Attempts `_. -https://docs.sqream.com/en/latest/configuration_guides/login_max_retries.html - Naming Changes ------- No relevant naming changes were made. @@ -133,4 +124,4 @@ Upgrading to v2022.1.1 :glob: :hidden: - 2022.1.1.1 \ No newline at end of file + 2022.1.1 \ No newline at end of file diff --git a/releases/2022.1_index.rst b/releases/2022.1_index.rst index 628b372aa..76d9e0e7c 100644 --- a/releases/2022.1_index.rst +++ b/releases/2022.1_index.rst @@ -5,13 +5,57 @@ Release Notes 2022.1 ************************** The 2022.1 Release Notes describe the following releases: -.. contents:: - :local: - :depth: 1 - .. toctree:: :maxdepth: 1 :glob: 2022.1.1 - 2022.1 \ No newline at end of file + 2022.1 + +You can also use the following tables for a summary of the new features in Version 2022.1 according to month: + +.. contents:: + :local: + :depth: 1 + +August 2022 +================== +The following enhancements were introduced in :ref:`August 2022 (2022.1.1) <2022.1.1>`: + +.. list-table:: + :widths: 20 20 60 + :header-rows: 1 + + * - Topic + - Feature + - Description + * - **Reference Guides** + - :ref:`update` + - The DML ``UPDATE`` statement has been enhanced to support running subqueries in the ``WHERE`` condition. + * - **Feature Guides** + - :ref:`compression` + - SQream supports compressing and decompressing data in and from the **ZLIB** format. + * - **Operational Guides** + - :ref:`Password Security Compliance` + - Integrated password security compliance measures when logging in to the CLI or Studio. + +July 2022 +================== +The following enhancements were introduced in :ref:`July 2022 (2022.1) <2022.1>`: + +.. list-table:: + :widths: 20 20 60 + :header-rows: 1 + + * - Topic + - Feature + - Description + * - **Feature Guides** + - :ref:`data_encryption` + - SQream has integrated data encryption mechanisms in accordance with General Data Protection Regulation (GDPR) standards. + * - **Data Ingestion** + - :ref:`avro` + - SSQream now supports ingesting data from Avro files. + * - **Reference Guides** + - :ref:`update` + - Supports modifying the value of certain columns in existing rows. \ No newline at end of file From c718d0ad427faced59301553fcf3c46a3c41692c Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Wed, 3 Aug 2022 16:37:13 +0300 Subject: [PATCH 194/316] Modified tables --- .../sql/sql_statements/dml_commands/update.rst | 2 +- releases/2022.1_index.rst | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/reference/sql/sql_statements/dml_commands/update.rst b/reference/sql/sql_statements/dml_commands/update.rst index 7c1b8c8b8..6cc33f516 100644 --- a/reference/sql/sql_statements/dml_commands/update.rst +++ b/reference/sql/sql_statements/dml_commands/update.rst @@ -89,7 +89,7 @@ The following is an example of performing a simple update: Updating Tables that Contain Multi-Table Conditions ----------------- -The following shows an example of updating tables that contain multi-table conditions: +The following shows an example of updating tables that contain multi-table conditions |icon-new_2022.1.1|: .. code-block:: postgres diff --git a/releases/2022.1_index.rst b/releases/2022.1_index.rst index 76d9e0e7c..16a7d80ef 100644 --- a/releases/2022.1_index.rst +++ b/releases/2022.1_index.rst @@ -23,21 +23,21 @@ August 2022 The following enhancements were introduced in :ref:`August 2022 (2022.1.1) <2022.1.1>`: .. list-table:: - :widths: 20 20 60 + :widths: 24 25 60 :header-rows: 1 * - Topic - Feature - Description - * - **Reference Guides** - - :ref:`update` - - The DML ``UPDATE`` statement has been enhanced to support running subqueries in the ``WHERE`` condition. * - **Feature Guides** - :ref:`compression` - SQream supports compressing and decompressing data in and from the **ZLIB** format. * - **Operational Guides** - :ref:`Password Security Compliance` - Integrated password security compliance measures when logging in to the CLI or Studio. + * - **Reference Guides** + - :ref:`update` + - The DML ``UPDATE`` statement has been enhanced to support running subqueries in the ``WHERE`` condition. July 2022 ================== @@ -50,12 +50,12 @@ The following enhancements were introduced in :ref:`July 2022 (2022.1) <2022.1>` * - Topic - Feature - Description + * - **Data Ingestion** + - :ref:`avro` + - SQream now supports ingesting data from Avro files. * - **Feature Guides** - :ref:`data_encryption` - SQream has integrated data encryption mechanisms in accordance with General Data Protection Regulation (GDPR) standards. - * - **Data Ingestion** - - :ref:`avro` - - SSQream now supports ingesting data from Avro files. * - **Reference Guides** - - :ref:`update` - - Supports modifying the value of certain columns in existing rows. \ No newline at end of file + - `UPDATE `_ + - The DML ``UPDATE`` statement has been introduced to support modifying the value of certain columns in existing rows. \ No newline at end of file From 08682c571b81bdd8c80b90869a4d79f7770fbcb6 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 4 Aug 2022 11:27:08 +0300 Subject: [PATCH 195/316] Updated menu --- feature_guides/data_encryption.rst | 3 ++- .../data_encryption_permissions.rst | 6 +++++ feature_guides/data_encryption_syntax.rst | 2 -- .../access_control_password_policy.rst | 24 +++++++++++++------ 4 files changed, 25 insertions(+), 10 deletions(-) create mode 100644 feature_guides/data_encryption_permissions.rst diff --git a/feature_guides/data_encryption.rst b/feature_guides/data_encryption.rst index dbc6152ed..19aabb8e3 100644 --- a/feature_guides/data_encryption.rst +++ b/feature_guides/data_encryption.rst @@ -16,4 +16,5 @@ The **Data Encryption** page |icon-new_2022.1| describes the following: data_encryption_overview data_encryption_methods data_encryption_types - data_encryption_syntax \ No newline at end of file + data_encryption_syntax + data_encryption_permissions \ No newline at end of file diff --git a/feature_guides/data_encryption_permissions.rst b/feature_guides/data_encryption_permissions.rst new file mode 100644 index 000000000..ba51f2501 --- /dev/null +++ b/feature_guides/data_encryption_permissions.rst @@ -0,0 +1,6 @@ +.. _data_encryption_permissions: + +*********************** +Permissions +*********************** +Because the Data Encryption feature does not require a role, users with **Read** and **Insert** permissions can read tables containing encrypted data. \ No newline at end of file diff --git a/feature_guides/data_encryption_syntax.rst b/feature_guides/data_encryption_syntax.rst index bba431aec..56934378e 100644 --- a/feature_guides/data_encryption_syntax.rst +++ b/feature_guides/data_encryption_syntax.rst @@ -25,8 +25,6 @@ The following is an example of encrypting a new table: .. note:: Because encryption is not associated with any role, users with **Read** or **Insert** permissions can read tables containing encrypted data. -.. warning:: Your performance degradation increases in correlation with the amount of added columns. - You cannot encrypt more than three columns. Attempting to encrypt more than three columns displays the following error message: .. code-block:: console diff --git a/operational_guides/access_control_password_policy.rst b/operational_guides/access_control_password_policy.rst index 6d9d989f2..fc845ebc4 100644 --- a/operational_guides/access_control_password_policy.rst +++ b/operational_guides/access_control_password_policy.rst @@ -8,27 +8,37 @@ Password Security Compliance (New!) :align: middle :width: 110 -As part of our compliance with GDPR standards |icon-new_gray_2022.1.1| SQream relies on a strong password policy when accessing the CLI or Studio, with the following requirements: +As part of our compliance with GDPR standards |icon-new_gray_2022.1.1| SQream relies on a strong password policy when accessing the CLI or Studio. + +The following requirements apply when creating a password: * At least eight characters long. :: -* Mandatory upper and lowercase letters. +* At least one numeric character. :: -* At least one numeric character. +* Should not include a username. :: -* May not include a username. +* Must include at least one special character, such as **?**, **!**, **$**, etc. :: -* Must include at least one special character, such as **?**, **!**, **$**, etc. +* Mandatory upper and lowercase letters. + +The following is the syntax for creating a password: + +.. code-block:: console + + CREATE ROLE ; + GRANT LOGIN ; + GRANT PASSWORD <'password'> to ; -You can create a password through the Studio graphic interface or through the CLI, as in the following example command: +The following is an example of creating a password: .. code-block:: console @@ -52,7 +62,7 @@ Creating a password that does not comply with the above requirements generates t * Must include at least one “special” character (?, !, $, etc.). -.. note:: When a new user created in Studio, a message is displayed to help you determine what the constraints are. +.. note:: When a new user is created in Studio, a message is displayed to help you determine what the constraints are. Unsuccessfully attempting to log in three times displays the following message: From abc2245f25a0219ad6186d052b436001a5c798a6 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 4 Aug 2022 13:58:14 +0300 Subject: [PATCH 196/316] Changed 5.4.3 to 5.4.6 --- index.rst | 2 +- reference/sql/sql_statements/index.rst | 2 + .../utility_commands/shutdown_server.rst | 115 ++ sqream_studio_5.4.3/Version_5.3.3.txt | 898 ---------------- .../configuring_your_instance_of_sqream.rst | 44 +- ...ing_and_managing_roles_and_permissions.rst | 196 ++-- ...ts_and_running_queries_from_the_editor.rst | 984 +++++++++--------- .../getting_started.rst | 126 +-- .../index.rst | 36 +- ...orkers_and_services_from_the_dashboard.rst | 530 +++++----- .../viewing_logs.rst | 244 ++--- 11 files changed, 1200 insertions(+), 1977 deletions(-) create mode 100644 reference/sql/sql_statements/utility_commands/shutdown_server.rst delete mode 100644 sqream_studio_5.4.3/Version_5.3.3.txt rename {sqream_studio_5.4.3 => sqream_studio_5.4.6}/configuring_your_instance_of_sqream.rst (98%) rename {sqream_studio_5.4.3 => sqream_studio_5.4.6}/creating_assigning_and_managing_roles_and_permissions.rst (95%) rename {sqream_studio_5.4.3 => sqream_studio_5.4.6}/executing_statements_and_running_queries_from_the_editor.rst (92%) rename {sqream_studio_5.4.3 => sqream_studio_5.4.6}/getting_started.rst (92%) rename {sqream_studio_5.4.3 => sqream_studio_5.4.6}/index.rst (88%) rename {sqream_studio_5.4.3 => sqream_studio_5.4.6}/monitoring_workers_and_services_from_the_dashboard.rst (90%) rename {sqream_studio_5.4.3 => sqream_studio_5.4.6}/viewing_logs.rst (85%) diff --git a/index.rst b/index.rst index 0f418c2fb..23e2288c0 100644 --- a/index.rst +++ b/index.rst @@ -104,7 +104,7 @@ If you're looking for an older version of the documentation, versions 1.10 throu loading_and_unloading_data/index feature_guides/index operational_guides/index - sqream_studio_5.4.3/index + sqream_studio_5.4.6/index architecture/index configuration_guides/index reference/index diff --git a/reference/sql/sql_statements/index.rst b/reference/sql/sql_statements/index.rst index d2b92b152..5cac43122 100644 --- a/reference/sql/sql_statements/index.rst +++ b/reference/sql/sql_statements/index.rst @@ -130,6 +130,8 @@ The following table shows the Utility commands: - Returns a list of active sessions across the cluster * - :ref:`SHOW VERSION` - Returns the system version for SQream DB + * - :ref:`SHUTDOWN SERVER` + - Performs a graceful server shutdown * - :ref:`STOP STATEMENT` - Stops or aborts an active statement diff --git a/reference/sql/sql_statements/utility_commands/shutdown_server.rst b/reference/sql/sql_statements/utility_commands/shutdown_server.rst new file mode 100644 index 000000000..ac0c4dc96 --- /dev/null +++ b/reference/sql/sql_statements/utility_commands/shutdown_server.rst @@ -0,0 +1,115 @@ +.. _shutdown_server: + +******************** +SHUTDOWN SERVER +******************** +**Comment** - When finished, add command to Utility Commands > shutdown_server. + +The **SHUTDOWN_SERVER** guide describes the following: + +.. contents:: + :local: + :depth: 1 + +Overview +=============== +SQream's current method for stopping the SQream server is running the ``shutdown_server ()`` utility command. Because this command abruptly shuts down the server while executing operations, it has been modified to perform a graceful shutdown, giving you more control over the following: + +* Preventing new queries from connecting to the server. + + :: + +* The amount of time to wait before shutting down the server. + + :: + +* Configurations related to shutting down the server. + +How Does it Work? +======================== +Running the ``SHUTDOWN_SERVER`` command does the following: + +* Prevents new queries from entering the server by doing the following: + + * Setting the SQream server to unavailable in the metadata server. **Comment** - *Is "unavailable" the official server setting?* + + :: + + * Unsubscribing the server from its service. + +* Preventing new connections from being made to the server - attempting to establish a connection with the server after initiating a graceful shutdown displays the "Server is shutting down, no new connections are possible at the moment" messsge. + + :: + +* Waiting for the statement queue to be cleared - the graceful shutdown waits for queries that have been compiled on the server to be cleared from the statement queue. During this time - start executing on other available servers. + +**Comment** - *The last bullet requires clarification.* + +Syntax +========== +The following is the syntax for using the ``SHUTDOWN_SERVER`` command: + +.. code-block:: postgres + + select shutdown_server([is_graceful, [timeout]]); + +**Comment** - *Is the below syntax correct?* + +.. code-block:: postgres + + select shutdown_server([true/false, [timeout]]); + +**Comment** - *Can you set the timeout as a flag in Studio, or only in the CLI?* + +Returns +========== +Running the ``shutdown_server`` command returns no output. + +Parameters +============ +The following table shows the ``shutdown_server`` parameters: + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + - Example + - Default + * - ``is_graceful`` + - Determines the method used to shut down the server. + - Selecting ``false`` shuts down the server while queries are running. Selecting ``true`` uses the graceful shutdown method. + - **Comment** - Is the default ``true`` or ``false``? + * - ``timeout`` + - Sets the maximum amount of minutes for the graceful shutdown method to run before the server is shut down using the standard method. + - ``30`` + - Five minutes. + +.. note:: Setting ``is_graceful`` to ``false`` and defining the ``timeout`` value shuts the server down mid-query after the defined time. + +It is possible to pass as the second argument the timeout in minutes after which a forceful shutdown will run, regardless of the progression of the graceful shutdown. + +**Comment** - *How can the above be true given the following, "Note that running forced shutdown with a timeout, i.e. select shutdown_server(false, 30) will return an error message; forced shutdown has no timeout timer"?* + +Note that you set the timeout value using the ``defaultGracefulShutdownTimeoutMinutes`` flag in Studio. + +For more information, see :ref:`graceful_shutdown`. + +**Comment** - *I have not yet created the ``graceful_shutdown`` configuration flag. I need to know what category it belongs in before doing so.* + +Like shutdown_server() graceful shutdown will stop any query currently running on the server. + +**Comment** - *The above makes it seem like it's a separate command, but that's not the case.* + +Relationship to Healer & Use Case +============================ +**Comment** - *Cannot document this section until I know what the Healer actually does.* + +Currently the Healer will not trigger a graceful shutdown upon detection of a stuck query. It will however log detection of such a query, prompting the user to run a graceful shutdown of the server, possibly saving existing queued queries. + +Permissions +============= +Using the ``shutdown_server`` command requires no special permissions. + +**Comment** - *Confirm.* \ No newline at end of file diff --git a/sqream_studio_5.4.3/Version_5.3.3.txt b/sqream_studio_5.4.3/Version_5.3.3.txt deleted file mode 100644 index 458302aad..000000000 --- a/sqream_studio_5.4.3/Version_5.3.3.txt +++ /dev/null @@ -1,898 +0,0 @@ -.. _acceleration_studio_version_5.3.3: - -**************************** -SQream Acceleration Studio 5.3.3 -**************************** - -The SQream Studio is a web-based client for use with SQream DB. The Studio provides users with all functionality available from the command line in an intuitive and easy-to-use format. This includes running statements, managing roles and permissions, and managing SQream DB clusters. - - -.. contents:: This page describes the following: - :depth: 3 - -Getting Started -================== - -.. _setting_up_and_starting_studio: - - -Setting Up and Starting Studio ----------------- - -Studio is included with all `dockerized installations of SQream DB `_. When starting Studio, it listens on the local machine on port 8080. - - - - - - - -Logging In to Studio ---------------- -**To log in to SQream Studio:** - -1. Open a browser to the host on **port 8080**. - - For example, if your machine IP address is ``192.168.0.100``, insert the IP address into the browser as shown below: - - .. code-block:: console - - $ http://192.168.0.100:8080 - -2. Fill in your SQream DB login credentials. These are the same credentials used for `SQream CLI Reference `_ or JDBC. - - When you sign in, the License Warning is displayed. - -Navigating Studio's Main Features -------------- -When you log in, you are automatically taken to the **Editor** screen. The Studio's main functions are displayed in the **Navigation** pane on the left side of the screen. - -From here you can navigate between the main areas of the Studio: - -.. list-table:: - :widths: 10 90 - :header-rows: 1 - - * - Element - - Description - * - :ref:`Dashboard` - - Only users with **superuser** permissions have access to the Dashboard. - * - :ref:`Editor` - - All users have access to the Editor and to databases that they have permissions for. - * - :ref:`Logs` - - Only users with the **superuser** permissions have access to the logs. - * - :ref:`Roles` - - Lets you create users and manage user permissions. - -By clicking the user icon, you can also use it for logging out and viewing the following: - -* User information -* Connection type -* SQream version -* SQream Studio version -* Data size limitations -* Log out - - - -.. _back_to_dashboard: - -.. _studio_dashboard: - -Monitoring Workers and Services from the Dashboard -============================== -The **Dashboard** is used for the following: - -* Monitoring cluster storage and system health. -* Viewing, monitoring, and adding defined service queues. -* Viewing and managing worker status and add workers. - -You can only access the Dashboard if you signed in with a ``SUPERUSER`` role. - -The following is a brief description of the Dashboard panels: - -.. list-table:: - :widths: 10 25 65 - :header-rows: 1 - - * - No. - - Element - - Description - * - 1 - - :ref:`Data Storage panel` - - Used to monitor cluster storage. - * - 2 - - :ref:`Services panel` - - Used for viewing and monitoring the defined `service queues `_. - * - 3 - - :ref:`Workers panel` - - Monitors system health and shows each Sqreamd worker running in the cluster. - * - 4 - - :ref:`License information` - - Shows the remaining amount of days left on your license. - - -.. _data_storage_panel: - -Displaying System Disk Usage from the Data Storage Panel ------------------------ -The **Data Storage** area displays your system's total disk usage (percentage) and data storage (donut graph). - -Your data storage is shows as the following four components: - -* **Data** – Storage occupied by databases in SQream DB. -* **Free** – Free storage space. -* **Deleted** – Storage that is temporarily occupied, but has not been reclaimed. For more information, see `Deleting Data `_. The **deleted** value is estimated and may not be accurate. -* **Other** – Storage used by other applications. On a dedicated SQream DB cluster this should be near zero. - -.. _administration_storage_database: - -You can show more information by clicking the expand arrow on the Data Storage panel. - -.. image:: /_static/images/studio_dashboard_expand_data_storage_5.3.0.png - -The expanded Data Storage panel can be used to drill down into each database's storage footprint, and displays a breakdown of how much storage each database in the cluster uses. - -The database information is displayed in a table and shows the following: - -* **Database name** - the name of the database. -* **Raw Size** – the estimated size of (uncompressed) raw data in the database. -* **Storage Size** – the physical size of the compressed data. -* **Ratio** – the effective compression ratio -* **Deleted Data** – Storage that is temporarily occupied, but has not been reclaimed. - -Below the table, an interactive line graph displays the database storage trends. By default, the line graph displays the total storage for all databases. You can show a particular database's graph by clicking it in the table. You can also change the line graph's timespan by selecting one from the timespan dropdown menu. - -.. image:: /_static/images/studio_dashboard_expand_data_storage_3_5.3.0.png - -:ref:`Back to Dashboard` - -.. _services_panel: - -Subscribing to Workers from the Services Panel --------------------------- -Services are used to categorize and associate (also known as **subscribing**) workers to particular services. The **Service** panel is used for viewing, monitoring, and adding defined `service queues `_. - -.. image:: /_static/images/studio_dashboard_services_panel_5.3.0.png - -The Dashboard includes the four panes shown below: - -.. image:: /_static/images/studio_dashboard_service_queue_5.3.0.png - -The following is a brief description of each pane: - -.. list-table:: - :widths: 10 90 - :header-rows: 1 - - * - No. - - Description - * - 1 - - Adds a worker to the selected service. - * - 2 - - Shows the service name. - * - 3 - - Shows a trend graph of queued statements loaded over time. - * - 4 - - Adds a service. - * - 5 - - Shows the currently processed queries belonging to the service/total queries for that service in the system (including queued queries). - -Adding A Service -^^^^^^^^^^^^^^^^^^^^^ -You can add a service by clicking **+ Add** and defining the service name. - -.. note:: If you do not associate a worker with the new service, it will not be created. - -You can manage workers from the **Workers** panel. For more information on managing workers, see :ref:`Workers`. - -:ref:`Back to Dashboard` - -.. _workers_panel: - -Managing Workers from the Workers Panel ------------- -From the **Workers** panel you can do the following: - -* :ref:`View workers ` -* :ref:`Add a worker to a service` -* :ref:`View a worker's active query information` -* :ref:`View a worker's execution plan` - -.. _view_workers: - -Viewing Workers -^^^^^^^^ -The **Worker** panel shows each worker (``sqreamd``) running in the cluster. Each worker has a status bar that represents the status over time. The status bar is divided into 20 equal segments, showing the most dominant activity in that segment. - -From the **Scale** dropdown menu you can set the time scale of the displayed information -You can hover over segments in the status bar to see the date and time corresponding to each activity type: - -* **Idle** – the worker is idle and available for statements. -* **Compiling** – the worker is compiling a statement and is preparing for execution. -* **Executing** – the worker is executing a statement after compilation. -* **Stopped** – the worker was stopped (either deliberately or due to an error). -* **Waiting** – the worker was waiting on an object locked by another worker. - -.. _add_worker_to_service: - -Adding A Worker to A Service -^^^^^^^^^^^^^^^^^^^^^ -You can add a worker to a service by clicking the **add** button. - -.. image:: /_static/images/studio_dashboard_add_worker_to_service_5.3.0.png - -Clicking the **add** button shows the selected service's workers. You can add the selected worker to the service by clicking **Add Worker**. Adding a worker to a service does not break associations already made between that worker and other services. - - -.. _view_worker_query_information: - -Viewing A Worker's Active Query Information -^^^^^^^^^^^^^^^^^^^^^ -You can view a worker's active query information by clicking **Queries**, which displays them in the selected service. - - -Each statement shows the **query ID**, **status**, **service queue**, **elapsed time**, **execution time**, and **estimated completion status**. In addition, each statement can be stopped or expanded to show its execution plan and progress. For more information on viewing a statement's execution plan and progress, see :ref:`Viewing a Worker's Execution Plan ` below. - -Viewing A Worker's Host Utilization -^^^^^^^^^^^^^^^^^^^^^ - -While viewing a worker's query information, clicking the **down arrow** expands to show the host resource utilization. - -.. image:: /_static/images/studio_dashboard_show_cpu_gpu_graph_5.3.0.png - -The graphs show the resource utilization trends over time, and the **CPU memory** and **utilization** and the **GPU utilization** values on the right. You can hover over the graph to see more information about the activity at any point on the graph. - -Error notifications related to statements are displayed as shown in the figure below, and you can hover over them for more information about the error. - -.. image:: /_static/images/studio_dashboard_notification_error_5.3.0.png - -.. _view_worker_execution_plan: - -Viewing a Worker's Execution Plan -^^^^^^^^^^^^^^^^^^^^^ - -Clicking the ellipsis in a service shows the following additional options: - -* **Stop Query** - stops the query. -* **Show Execution Plan** - shows the execution plan as a table. The columns in the **Show Execution Plan** table can be sorted. - -For more information on the current query plan, see `SHOW_NODE_INFO `_. For more information on checking active sessions across the cluster, see `SHOW_SERVER_STATUS `_. - -.. include:: /reference/sql/sql_statements/monitoring_commands/show_server_status.rst - :start-line: 67 - :end-line: 84 - -Managing Worker Status -^^^^^^^^^^^^^^^^^^^^^ - -In some cases you may want to stop or restart workers for maintenance purposes. Each Worker line has a :kbd:`⋮` menu used for stopping, starting, or restarting workers. - -.. image:: /_static/images/stop_restart_worker.png - -Starting or restarting workers terminates all queries related to that worker. When you stop a worker, its background turns gray. - - - - -.. |icon-user| image:: /_static/images/studio_icon_user.png - :align: middle - -.. |icon-dots| image:: /_static/images/studio_icon_dots.png - :align: middle - -.. |icon-editor| image:: /_static/images/studio_icon_editor.png - :align: middle - -.. |icon-copy| image:: /_static/images/studio_icon_copy.png - :align: middle - -.. |icon-select| image:: /_static/images/studio_icon_select.png - :align: middle - -.. |icon-dots| image:: /_static/images/studio_icon_dots.png - :align: middle - -.. |icon-filter| image:: /_static/images/studio_icon_filter.png - :align: middle - -.. |icon-ddl-edit| image:: /_static/images/studio_icon_ddl_edit.png - :align: middle - -.. |icon-run-optimizer| image:: /_static/images/studio_icon_run_optimizer.png - :align: middle - -.. |icon-generate-create-statement| image:: /_static/images/studio_icon_generate_create_statement.png - :align: middle - -.. |icon-plus| image:: /_static/images/studio_icon_plus.png - :align: middle - -.. |icon-close| image:: /_static/images/studio_icon_close.png - :align: middle - -.. |icon-left| image:: /_static/images/studio_icon_left.png - :align: middle - -.. |icon-right| image:: /_static/images/studio_icon_right.png - :align: middle - -.. |icon-format-sql| image:: /_static/images/studio_icon_format.png - :align: middle - -.. |icon-download-query| image:: /_static/images/studio_icon_download_query.png - :align: middle - -.. |icon-open-query| image:: /_static/images/studio_icon_open_query.png - :align: middle - -.. |icon-execute| image:: /_static/images/studio_icon_execute.png - :align: middle - -.. |icon-stop| image:: /_static/images/studio_icon_stop.png - :align: middle - -.. |icon-dashboard| image:: /_static/images/studio_icon_dashboard.png - :align: middle - -.. |icon-expand| image:: /_static/images/studio_icon_expand.png - :align: middle - -.. |icon-scale| image:: /_static/images/studio_icon_scale.png - :align: middle - -.. |icon-expand-down| image:: /_static/images/studio_icon_expand_down.png - :align: middle - -.. |icon-add| image:: /_static/images/studio_icon_add.png - :align: middle - -.. |icon-add-worker| image:: /_static/images/studio_icon_add_worker.png - :align: middle - -.. |keep-tabs| image:: /_static/images/studio_keep_tabs.png - :align: middle - -:ref:`Back to Dashboard` - - - -.. _license_information: - -License Information ----------------------- -The license information is a counter showing the amount of time in days remaining on the license. - -:ref:`Back to Dashboard` - - -.. _studio_editor: - -.. _editor_top: - -Executing Statements and Running Queries from the Editor -================= -The **Editor** is used for the following: - -* Selecting an active database and executing queries. -* Performing statement-related operations and showing metadata. -* Executing pre-defined queries. -* Writing queries and statements and viewing query results. - -The following is a brief description of the Editor panels: - - -.. list-table:: - :widths: 10 34 56 - :header-rows: 1 - - * - No. - - Element - - Description - * - 1 - - :ref:`Toolbar` - - Used to select the active database you want to work on, limit the number of rows, save query, etc. - * - 2 - - :ref:`Database Tree and System Queries panel` - - Shows a heirarchy tree of databases, views, tables, and columns - * - 3 - - :ref:`Statement panel` - - Used for writing queries and statements - * - 4 - - :ref:`Results panel` - - Shows query results and execution information. - - -.. _studio_editor_db_tree: - -.. _top: - -.. _studio_editor_toolbar: - -Executing Statements from the Toolbar -------------- - -The following figure shows the **Toolbar** pane: - -.. image:: /_static/images/studio_editor_toolbar_5.3.0.png - -You can access the following from the Toolbar pane: - -* **Database dropdown list** - select a database that you want to run statements on. - -* **Service dropdown list** - select a service that you want to run statements on. The options in the service dropdown menu depend on the database you select from the **Database** dropdown list. - -* **Execute** - lets you set which statements to execute. The **Execute** button toggles between **Execute** and **Stop**, and can be used to stop an active statement before it completes: - - * **Statements** - executes the statement at the location of the cursor. - * **Selected** - executes only the highlighted text. This mode should be used when executing subqueries or sections of large queries (as long as they are valid SQLs). - * **All** - executes all statements in a selected tab. - -For more information on stopping active statements, see the :ref:`STOP_STATEMENT` command. - -* **Format SQL** - Lets you reformat and reindent statements. - -* **Download query** - Lets you download query text to your computer. - -* **Open query** - Lets you upload query text from your computer. - -* **Max Rows** - By default, the Editor fetches only the first 10,000 rows. You can modify this number by selecting an option from the **Max Rows** dropdown list. Note that setting a higher number may slow down your browser if the result is very large. This number is limited to 100,000 results. To see a higher number, you can save the results in a file or a table using the :ref:`create_table_as` command. - -:ref:`Back to Editor` - -Performing Statement-Related Operations from the Database Tree ---------------- -From the Database Tree you can perform statement-related operations and show metadata (such as a number indicating the amount of rows in the table). - -The following figure shows the **Database Tree** and **System Queries** panel, with the Database Tree tab selected. - -.. image:: /_static/images/studio_database_tree_system_queries_panel_5053.png - -The following figure shows the database object functions in the **calcs** table object. - -.. image:: /_static/images/studio_database_object_operations_5030.png - -The database object functions are used to perform the following: - - - * The **SELECT** statement - copies the selected table's **columns** into the Statement panel as ``SELECT`` parameters. - * The **copy** feature |icon-copy| - copies the selected table's **name** into the Statement panel. - * The **additional operations** |icon-dots| - displays the following additional options: - - - - - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Function - - Description - * - Insert statement - - Generates an `INSERT `_ statement for the selected table in the editing area. - * - Delete statement - - Generates a `DELETE `_ statement for the selected table in the editing area. - * - Create Table As statement - - Generates a `CREATE TABLE AS `_ statement for the selected table in the editing area. - * - Rename statement - - Generates an `RENAME TABLE AS `_ statement for renaming the selected table in the editing area. - * - Adding column statement - - Generates an `ADD COLUMN `_ statement for adding columns to the selected table in the editing area. - * - Truncate table statement - - Generates a `TRUNCATE_IF_EXISTS `_ statement for the selected table in the editing area. - * - Drop table statement - - Generates a ``DROP`` statement for the selected object in the editing area. - * - Table DDL - - Generates a DDL statement for the selected object in the editing area. To get the entire database DDL, click the |icon-ddl-edit| icon next to the database name in the tree root. See also `Seeing System Objects as DDL `_. - * - DDL Optimizer - - The `DDL Optimizer `_ lets you analyze database tables and recommends possible optimizations. - - - - - -Optimizing Database Tables Using the DDL Optimizer -^^^^^^^^^^^^^^^^^^^^^ -The **DDL Optimizer** tab analyzes database tables and recommends possible optimizations according to SQream's best practices. - -As described in the previous table, you can access the DDL Optimizer by clicking the **additional options icon** and selecting **DDL Optimizer**. - -The following table describes the DDL Optimizer screen: - -.. list-table:: - :widths: 15 75 - :header-rows: 1 - - * - Element - - Description - * - Column area - - Shows the column **names** and **column types** from the selected table. You can scroll down or to the right/left for long column lists. - * - Optimization area - - Shows the number of rows to sample as the basis for running an optimization, the default setting (1,000,000) when running an optimization (this is also the overhead threshold used when analyzing ``VARCHAR`` fields), and the default percent buffer to add to ``VARCHAR`` lengths (10%). Attempts to determine field nullability. - * - Run Optimizer - - Starts the optimization process. - -Clicking **Run Optimizer** adds a tab to the Statement panel showing the optimized results of the selected object. The figure below shows the **calcs Optimized** tab for the optimized **calcs** table. - -For more information, see `Optimization and Best Practices `_. - -:ref:`Back to top` - -Executing Pre-Defined Queries from the System Queries Panel ---------------- -The **System Queries** panel lets you execute pre-defined queries and includes the following system query types: - -* **Catalog queries** - used for analyzing table compression rates, users and permissions, etc. -* **Admin queries** - queries related to available (describe the functionality in a general way). Queries useful for SQream database management: - - - - - -Clicking an item pastes the query into the Statement pane, and you can undo a previous operation by pressing **Ctrl + Z**. - - -.. _studio_editor_statement_area: - -Writing Statements and Queries from the Statement Panel ----------------- -The multi-tabbed statement area is used for writing queries and statements, and is used in tandem with the toolbar. When writing and executing statements, you must first select a database from the **Database** dropdown menu in the toolbar. When you execute a statement, it passes through a series of statuses until completing. Knowing the status helps you with statement maintenance, and the statuses are shown in the **Results panel**. - -The following table shows the statement statuses: - -.. list-table:: - :widths: 45 160 - :header-rows: 1 - - * - Status - - Description - * - Pending - - The statement is pending. - * - In queue - - The statement is waiting for execution. - * - Initializing - - The statement has entered execution checks. - * - Executing - - The statement is executing. - * - Statement stopped - - The statement has been stopped. - -You can add and name new tabs for each statement that you need to execute, and Studio preserves your created tabs when you switch between databases. You can add new tabs by clicking |icon-plus| , which creates a new tab to the right with a default name of SQL and an increasing number. This helps you keep track of your statements. - -.. image:: /_static/images/statement_pane_adding_statement_5.3.0.png - -You can also rename the default tab name by double-clicking it and typing a new name and write multiple statements in tandem in the same tab by separating them with semicolons (``;``).If too many tabs to fit into the Statement Pane are open at the same time, the tab arrows are displayed. You can scroll through the tabs by clicking |icon-left| or |icon-right|, and close tabs by clicking |icon-close|. You can also close all tabs at once by clicking **Close all** located to the right of the tabs. - -.. tip:: If this is your first time using SQream, see `First steps with SQream DB `_. - - -.. Keyboard shortcuts -.. ^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. :kbd:`Ctrl` +: kbd:`Enter` - Execute all queries in the statement area, or just the highlighted part of the query. - -.. :kbd:`Ctrl` + :kbd:`Space` - Auto-complete the current keyword - -.. :kbd:`Ctrl` + :kbd:`↑` - Switch to next tab. - -.. :kbd:`Ctrl` + :kbd:`↓` - Switch to previous tab - -.. _studio_editor_results: - -:ref:`Back to Editor` - - -Viewing Statement and Query Results from the Results Panel ------------------------------------- -The results pane shows statment and query results. By default, only the first 10,000 results are returned, although you can modify this from the :ref:`studio_editor_toolbar`, as described above. - -.. image:: /_static/images/studio_editor_results_5053.png - -By default, executing several statements together opens a separate results tab for each statement. Executing statements together executes them serially, and any failed statement cancels all subsequent executions. - -The following is a brief description of the elements on the Results panel views: - -.. list-table:: - :widths: 45 160 - :header-rows: 1 - - * - Element - - Description - * - :ref:`Results view` - - Lets you view search query results. - * - :ref:`Execution Details view` - - Lets you view execution details, such as statement ID, number of rows, and averge number of rows in chunk. - * - :ref:`SQL view` - - Lets you see the SQL view. - * - :ref:`Save results to clipboard` - - Lets you save your search results to the clipboard to paste into another text editor. - * - :ref:`Save results to local file` - - Lets you save your search query results to a local file. - -.. _results_view: - - - -Searching Query Results in the Results View -^^^^^^^^^^^^ -The **Results view** lets you view search query results. - -From this view you can also do the following: - -* View the amount of time (in seconds) taken for a query to finish executing. -* Switch and scroll between tabs. -* Close all tabs at once. -* Enable keeping tabs by selecting **Keep tabs**. -* Sort column results. - -In the Results view you can also run parallel statements, as described in **Running Parallel Statements** below. - -.. _running_parallel_statements: - -Running Parallel Statements -^^^^^^^^^^^^ -While Studio's default functionality is to open a new tab for each executed statement, Studio supports running parallel statements in one statement tab. Running parallel statements requires using macros and is useful for advanced users. - -The following shows the syntax for running parallel statements: - -.. code-block:: console - - $ @@ parallel - $ $$ - $ select 1; - $ select 2; - $ select 3; - $ $$ - -The following figure shows the parallel statement syntax in the Editor: - -.. image:: /_static/images/running_parallel_statements.png - -.. _execution_details_view: - -Execution Details View -^^^^^^^^^^^^ -The **Execution Details** view lets you view a query’s execution plan for monitoring purposes. Most importantly, the Execution Details view highlights rows based on how long they ran relative to the entire query. - -This can be seen in the **timeSum** column as follows: - -* **Rows highlighted red** - longest runtime -* **Rows highlighted orange** - medium runtime -* **Rows highlighted yellow** - shortest runtime - -.. image:: /_static/images/execution_details_view_3.png - - - -.. _sql_view: - -Viewing Wrapped Strings in the SQL View -^^^^^^^^^^^^ -The SQL View panel allows you to more easily view certain queries, such as a long string that appears on one line. The SQL View makes it easier to see by wrapping it so that you can see the entire string at once. It also reformats and organizes query syntax entered in the Statement panel for more easily locating particular segments of your queries. The SQL View is identical to the **Format SQL** feature in the Toolbar, allowing you to retain your originally constructed query while viewing a more intuititively structured snapshot of it. - -The following figure shows the SQL view: - -.. image:: /_static/images/sql_view_5.0.3.png - -.. _save_results_to_clipboard: - -Saving Results to the Clipboard -^^^^^^^^^^^^ -The **Save results to clipboard** function lets you save your results to the clipboard to paste into another text editor or into Excel for further analysis. - - -.. _save_results_to_local_file: - -Saving Results to a Local File -^^^^^^^^^^^^ -The **Save results to local file** functions lets you save your search query results to a local file. Clicking **Save results to local file** downloads the contents of the Results panel to an Excel sheet. You can then use copy and paste this content into other editors as needed. - -Analyzing Results ----------------------------- - -When results are produced, a **Generate CREATE statement** button is displayed. Clicking this button creates a new tab with an optimized :ref:`create_table` statement, and an :ref:`insert` statement to copy the data to the new table. - -.. _logs: - -.. _logs_top: - -:ref:`Back to Editor` - -Viewing Logs -============ -The **Logs** screen is used for viewing logs and includes the following elements: - -.. list-table:: - :widths: 15 75 - :header-rows: 1 - - * - Element - - Description - * - :ref:`Filter area` - - Lets you filter the data shown in the table. - * - :ref:`Query tab` - - Shows basic query information logs, such as query number and the time the query was run. - * - :ref:`Session tab` - - Shows basic session information logs, such as session ID and user name. - * - :ref:`System tab` - - Shows all system logs. - * - :ref:`Log lines tab` - - Shows the total amount of log lines. - - -.. _filter: - -Filtering Table Data -------------- -From the Logs tab, from the **FILTERS** area you can also apply the **TIMESPAN**, **ONLY ERRORS**, and additional filters (**Add**). The **Timespan** filter lets you select a timespan. The **Only Errors** toggle button lets you show all queries, or only queries that generated errors. The **Add** button lets you add additional filters to the data shown in the table. The **Filter** button applies the selected filter(s). - - -Some filters require you to type text to define the filter. - -.. image:: /_static/images/logs_filters_5.3.0.png - -Other filters require you to select an item from a dropdown menu: - -* INFO -* WARNING -* ERROR -* FATAL -* SYSTEM - -You can also export a record of all of your currently filtered logs in Excel format by clicking **Download** located above the Filter area. - -.. _queries: - -:ref:`Back to Viewing Logs` - - -Viewing Query Logs ----------- -The **QUERIES** log area shows basic query information, such as query number and the time the query was run. The number next to the title indicates the amount of queries that have been run. - -From the Queries area you can see and sort by the following: - -* Query ID -* Start time -* Query -* Compilation duration -* Execution duration -* Total duration -* Details (execution details, error details, successful query details) - -In the Queries table, you can click on the **Statement ID** and **Query** items to set them as your filters. In the **Details** column you can also access additional details by clicking one of the **Details** options for a more detailed explanation of the query. - -:ref:`Back to Viewing Logs` - -.. _sessions: - -Viewing Session Logs ----------- -The **SESSIONS** tab shows the sessions log table and is used for viewing activity that has occurred during your sessions. The number at the top indicates the amount of sessions that have occurred. - -From here you can see and sort by the following: - -* Timestamp -* Connection ID -* Username -* Client IP -* Login (Success or Failed) -* Duration (of session) -* Configuration Changes - -In the Sessions table, you can click on the **Timestamp**, **Connection ID**, and **Username** items to set them as your filters. - -:ref:`Back to Viewing Logs` - -.. _system: - -Viewing System Logs ----------- -The **SYSTEM** tab shows the system log table and is used for viewing all system logs. The number at the top indicates the amount of sessions that have occurred. Because system logs occur less frequently than queries and sessions, you may need to increase the filter timespan for the table to display any system logs. - -From here you can see and sort by the following: - -* Timestamp -* Log type -* Message - -In the Systems table, you can click on the **Timestamp** and **Log type** items to set them as your filters. In the **Message** column, you can also click on an item to show more information about the message. - -:ref:`Back to Viewing Logs` - -.. _log_lines: - -Viewing All Log Lines ----------- -The **LOG LINES** tab is used for viewing the total amount of log lines in a table. From here users can view a more granular breakdown of log information collected by Studio. The other tabs (QUERIES, SESSIONS, and SYSTEM) show a filtered form of the raw log lines. For example, the QUERIES tab shows an aggregation of several log lines. - -From here you can see and sort by the following: - -* Timestamp -* Message level -* Worker hostname -* Worker port -* Connection ID -* Database name -* User name -* Statement ID - -In the **LOG LINES** table, you can click on any of the items to set them as your filters. - -:ref:`Back to Viewing Logs` - -:ref:`Back to Editor` - -.. _roles: - -Creating, Assigning, and Managing Roles and Permissions -============ -Overview ---------------- -In the **Roles** area you can create and assign roles and manage user permissions. - -The **Type** column displays one of the following assigned role types: - -.. list-table:: - :widths: 15 75 - :header-rows: 1 - - * - Role Type - - Description - * - Groups - - Roles with no users. - * - Enabled users - - Users with log-in permissions and a password. - * - Disabled users - - Users with log-in permissions and with a disabled password. An admin may disable a user's password permissions to temporary disable access to the system. - -.. note:: If you disable a password, when you enable it you have to create a new one. - - -Viewing Information About a Role --------------------- -Clicking a role in the roles table displays the following information: - - * **Parent Roles** - displays the parent roles of the selected role. Roles inherit all roles assigned to the parent. - * **Members** - displays all members that the role has been assigned to. The arrow indicates the roles that the role has inherited. Hovering over a member displays the roles that the role is inherited from. - * **Permissions** - displays the role's permissions. The arrow indicates the permissions that the role has inherited. Hovering over a permission displays the roles that the permission is inherited from. - -Creating a New Role --------------------- -You can create a new role by clicking **New Role**. - -.. image:: /_static/images/role_button.png - -An admin creates a **user** by granting login permissions and a password to a role. Each role is defined by a set of permissions. An admin can also group several roles together to form a **group** to manage them simultaneously. For example, permissions can be granted to or revoked on a group level. - -Clicking **New Role** lets you do the following: - - * Add and assign a role name (required) - * Enable or disable log-in permissions for the role. - * Set a password. - * Assign or delete parent roles. - * Add or delete permissions. - * Grant the selected user with superuser permissions. - -From the New Role panel you view directly and indirectly (or inherited) granted permissions. Disabled permissions have no connect permissions for the referenced database and are displayed in gray text. You can add or remove permissions from the **Add permissions** field. From the New Role panel you can also search and scroll through the permissions. In the **Search** field you can use the **and** operator to search for strings that fulfill multiple criteria. - -When adding a new role, you must select the **Enable login for this role** and **Has password** check boxes. - -Editing a Role --------------------- -Once you've created a role, clicking the **Edit Role** button lets you do the following: - - * Edit the role name. - * Enable or disable log-in permissions. - * Set a password. - * Assign or delete parent roles. - * Assign a role **administrator** permissions. - * Add or delete permissions. - * Grant the selected user with superuser permissions. - -From the Edit Role panel you view directly and indirectly (or inherited) granted permissions. Disabled permissions have no connect permissions for the referenced database and are displayed in gray text. You can add or remove permissions from the **Add permissions** field. From the Edit Role panel you can also search and scroll through the permissions. In the **Search** field you can use the **and** operator to search for strings that fulfill multiple criteria. - -Deleting a Role ------------------ -Clicking the **delete** icon displays a confirmation message with the amount of users and groups that will be impacted by deleting the role. diff --git a/sqream_studio_5.4.3/configuring_your_instance_of_sqream.rst b/sqream_studio_5.4.6/configuring_your_instance_of_sqream.rst similarity index 98% rename from sqream_studio_5.4.3/configuring_your_instance_of_sqream.rst rename to sqream_studio_5.4.6/configuring_your_instance_of_sqream.rst index e5f4b11e5..2b334cbfa 100644 --- a/sqream_studio_5.4.3/configuring_your_instance_of_sqream.rst +++ b/sqream_studio_5.4.6/configuring_your_instance_of_sqream.rst @@ -1,23 +1,23 @@ -.. _configuring_your_instance_of_sqream: - -**************************** -Configuring Your Instance of SQream -**************************** -The **Configuration** section lets you edit parameters from one centralized location. While you can edit these parameters from the **worker configuration file (config.json)** or from your CLI, you can also modify them in Studio in an easy-to-use format. - -Configuring your instance of SQream in Studio is session-based, which enables you to edit parameters per session on your own device. -Because session-based configurations are not persistent and are deleted when your session ends, you can edit your required parameters while avoiding conflicts between parameters edited on different devices at different points in time. - -Editing Your Parameters -------------------------------- -When configuring your instance of SQream in Studio you can edit parameters for the **Generic** and **Admin** parameters only. - -Studio includes two types of parameters: toggle switches, such as **flipJoinOrder**, and text fields, such as **logSysLevel**. After editing a parameter, you can reset each one to its previous value or to its default value individually, or revert all parameters to their default setting simultaneously. Note that you must click **Save** to save your configurations. - -You can hover over the **information** icon located on each parameter to read a short description of its behavior. - -Exporting and Importing Configuration Files -------------------------- -You can also export and import your configuration settings into a .json file. This allows you to easily edit your parameters and to share this file with other users if required. - +.. _configuring_your_instance_of_sqream: + +**************************** +Configuring Your Instance of SQream +**************************** +The **Configuration** section lets you edit parameters from one centralized location. While you can edit these parameters from the **worker configuration file (config.json)** or from your CLI, you can also modify them in Studio in an easy-to-use format. + +Configuring your instance of SQream in Studio is session-based, which enables you to edit parameters per session on your own device. +Because session-based configurations are not persistent and are deleted when your session ends, you can edit your required parameters while avoiding conflicts between parameters edited on different devices at different points in time. + +Editing Your Parameters +------------------------------- +When configuring your instance of SQream in Studio you can edit parameters for the **Generic** and **Admin** parameters only. + +Studio includes two types of parameters: toggle switches, such as **flipJoinOrder**, and text fields, such as **logSysLevel**. After editing a parameter, you can reset each one to its previous value or to its default value individually, or revert all parameters to their default setting simultaneously. Note that you must click **Save** to save your configurations. + +You can hover over the **information** icon located on each parameter to read a short description of its behavior. + +Exporting and Importing Configuration Files +------------------------- +You can also export and import your configuration settings into a .json file. This allows you to easily edit your parameters and to share this file with other users if required. + For more information about configuring your instance of SQream, see `Configuration Guides `_. \ No newline at end of file diff --git a/sqream_studio_5.4.3/creating_assigning_and_managing_roles_and_permissions.rst b/sqream_studio_5.4.6/creating_assigning_and_managing_roles_and_permissions.rst similarity index 95% rename from sqream_studio_5.4.3/creating_assigning_and_managing_roles_and_permissions.rst rename to sqream_studio_5.4.6/creating_assigning_and_managing_roles_and_permissions.rst index 325563761..b87b6f2cf 100644 --- a/sqream_studio_5.4.3/creating_assigning_and_managing_roles_and_permissions.rst +++ b/sqream_studio_5.4.6/creating_assigning_and_managing_roles_and_permissions.rst @@ -1,98 +1,98 @@ -.. _creating_assigning_and_managing_roles_and_permissions: - -.. _roles_5.4.3: - -**************************** -Creating, Assigning, and Managing Roles and Permissions -**************************** -The **Creating, Assigning, and Managing Roles and Permissions** describes the following: - -.. contents:: - :local: - :depth: 1 - -Overview ---------------- -In the **Roles** area you can create and assign roles and manage user permissions. - -The **Type** column displays one of the following assigned role types: - -.. list-table:: - :widths: 15 75 - :header-rows: 1 - - * - Role Type - - Description - * - Groups - - Roles with no users. - * - Enabled users - - Users with log-in permissions and a password. - * - Disabled users - - Users with log-in permissions and with a disabled password. An admin may disable a user's password permissions to temporary disable access to the system. - -.. note:: If you disable a password, when you enable it you have to create a new one. - -:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` - - -Viewing Information About a Role --------------------- -Clicking a role in the roles table displays the following information: - - * **Parent Roles** - displays the parent roles of the selected role. Roles inherit all roles assigned to the parent. - - :: - - * **Members** - displays all members that the role has been assigned to. The arrow indicates the roles that the role has inherited. Hovering over a member displays the roles that the role is inherited from. - - :: - - * **Permissions** - displays the role's permissions. The arrow indicates the permissions that the role has inherited. Hovering over a permission displays the roles that the permission is inherited from. - -:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` - - -Creating a New Role --------------------- -You can create a new role by clicking **New Role**. - - - -An admin creates a **user** by granting login permissions and a password to a role. Each role is defined by a set of permissions. An admin can also group several roles together to form a **group** to manage them simultaneously. For example, permissions can be granted to or revoked on a group level. - -Clicking **New Role** lets you do the following: - - * Add and assign a role name (required) - * Enable or disable log-in permissions for the role. - * Set a password. - * Assign or delete parent roles. - * Add or delete permissions. - * Grant the selected user with superuser permissions. - -From the New Role panel you view directly and indirectly (or inherited) granted permissions. Disabled permissions have no connect permissions for the referenced database and are displayed in gray text. You can add or remove permissions from the **Add permissions** field. From the New Role panel you can also search and scroll through the permissions. In the **Search** field you can use the **and** operator to search for strings that fulfill multiple criteria. - -When adding a new role, you must select the **Enable login for this role** and **Has password** check boxes. - -:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` - -Editing a Role --------------------- -Once you've created a role, clicking the **Edit Role** button lets you do the following: - - * Edit the role name. - * Enable or disable log-in permissions. - * Set a password. - * Assign or delete parent roles. - * Assign a role **administrator** permissions. - * Add or delete permissions. - * Grant the selected user with superuser permissions. - -From the Edit Role panel you view directly and indirectly (or inherited) granted permissions. Disabled permissions have no connect permissions for the referenced database and are displayed in gray text. You can add or remove permissions from the **Add permissions** field. From the Edit Role panel you can also search and scroll through the permissions. In the **Search** field you can use the **and** operator to search for strings that fulfill multiple criteria. - -:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` - -Deleting a Role ------------------ -Clicking the **delete** icon displays a confirmation message with the amount of users and groups that will be impacted by deleting the role. - -:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` \ No newline at end of file +.. _creating_assigning_and_managing_roles_and_permissions: + +.. _roles_5.4.6: + +**************************** +Creating, Assigning, and Managing Roles and Permissions +**************************** +The **Creating, Assigning, and Managing Roles and Permissions** describes the following: + +.. contents:: + :local: + :depth: 1 + +Overview +--------------- +In the **Roles** area you can create and assign roles and manage user permissions. + +The **Type** column displays one of the following assigned role types: + +.. list-table:: + :widths: 15 75 + :header-rows: 1 + + * - Role Type + - Description + * - Groups + - Roles with no users. + * - Enabled users + - Users with log-in permissions and a password. + * - Disabled users + - Users with log-in permissions and with a disabled password. An admin may disable a user's password permissions to temporary disable access to the system. + +.. note:: If you disable a password, when you enable it you have to create a new one. + +:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` + + +Viewing Information About a Role +-------------------- +Clicking a role in the roles table displays the following information: + + * **Parent Roles** - displays the parent roles of the selected role. Roles inherit all roles assigned to the parent. + + :: + + * **Members** - displays all members that the role has been assigned to. The arrow indicates the roles that the role has inherited. Hovering over a member displays the roles that the role is inherited from. + + :: + + * **Permissions** - displays the role's permissions. The arrow indicates the permissions that the role has inherited. Hovering over a permission displays the roles that the permission is inherited from. + +:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` + + +Creating a New Role +-------------------- +You can create a new role by clicking **New Role**. + + + +An admin creates a **user** by granting login permissions and a password to a role. Each role is defined by a set of permissions. An admin can also group several roles together to form a **group** to manage them simultaneously. For example, permissions can be granted to or revoked on a group level. + +Clicking **New Role** lets you do the following: + + * Add and assign a role name (required) + * Enable or disable log-in permissions for the role. + * Set a password. + * Assign or delete parent roles. + * Add or delete permissions. + * Grant the selected user with superuser permissions. + +From the New Role panel you view directly and indirectly (or inherited) granted permissions. Disabled permissions have no connect permissions for the referenced database and are displayed in gray text. You can add or remove permissions from the **Add permissions** field. From the New Role panel you can also search and scroll through the permissions. In the **Search** field you can use the **and** operator to search for strings that fulfill multiple criteria. + +When adding a new role, you must select the **Enable login for this role** and **Has password** check boxes. + +:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` + +Editing a Role +-------------------- +Once you've created a role, clicking the **Edit Role** button lets you do the following: + + * Edit the role name. + * Enable or disable log-in permissions. + * Set a password. + * Assign or delete parent roles. + * Assign a role **administrator** permissions. + * Add or delete permissions. + * Grant the selected user with superuser permissions. + +From the Edit Role panel you view directly and indirectly (or inherited) granted permissions. Disabled permissions have no connect permissions for the referenced database and are displayed in gray text. You can add or remove permissions from the **Add permissions** field. From the Edit Role panel you can also search and scroll through the permissions. In the **Search** field you can use the **and** operator to search for strings that fulfill multiple criteria. + +:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` + +Deleting a Role +----------------- +Clicking the **delete** icon displays a confirmation message with the amount of users and groups that will be impacted by deleting the role. + +:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` \ No newline at end of file diff --git a/sqream_studio_5.4.3/executing_statements_and_running_queries_from_the_editor.rst b/sqream_studio_5.4.6/executing_statements_and_running_queries_from_the_editor.rst similarity index 92% rename from sqream_studio_5.4.3/executing_statements_and_running_queries_from_the_editor.rst rename to sqream_studio_5.4.6/executing_statements_and_running_queries_from_the_editor.rst index e1b6765eb..9640665da 100644 --- a/sqream_studio_5.4.3/executing_statements_and_running_queries_from_the_editor.rst +++ b/sqream_studio_5.4.6/executing_statements_and_running_queries_from_the_editor.rst @@ -1,492 +1,492 @@ -.. _executing_statements_and_running_queries_from_the_editor: - -.. _editor_top_5.4.3: - -**************************** -Executing Statements and Running Queries from the Editor -**************************** -The **Editor** is used for the following: - -* Selecting an active database and executing queries. -* Performing statement-related operations and showing metadata. -* Executing pre-defined queries. -* Writing queries and statements and viewing query results. - -The following is a brief description of the Editor panels: - - -.. list-table:: - :widths: 10 34 56 - :header-rows: 1 - - * - No. - - Element - - Description - * - 1 - - :ref:`Toolbar` - - Used to select the active database you want to work on, limit the number of rows, save query, etc. - * - 2 - - :ref:`Database Tree and System Queries panel` - - Shows a hierarchy tree of databases, views, tables, and columns - * - 3 - - :ref:`Statement panel` - - Used for writing queries and statements - * - 4 - - :ref:`Results panel` - - Shows query results and execution information. - - - -.. _top_5.4.3: - -.. _studio_5.4.3_editor_toolbar: - -Executing Statements from the Toolbar -================ -You can access the following from the Toolbar pane: - -* **Database dropdown list** - select a database that you want to run statements on. - - :: - -* **Service dropdown list** - select a service that you want to run statements on. The options in the service dropdown menu depend on the database you select from the **Database** dropdown list. - - :: - -* **Execute** - lets you set which statements to execute. The **Execute** button toggles between **Execute** and **Stop**, and can be used to stop an active statement before it completes: - - * **Statements** - executes the statement at the location of the cursor. - * **Selected** - executes only the highlighted text. This mode should be used when executing subqueries or sections of large queries (as long as they are valid SQLs). - * **All** - executes all statements in a selected tab. - -* **Format SQL** - Lets you reformat and reindent statements. - - :: - -* **Download query** - Lets you download query text to your computer. - - :: - -* **Open query** - Lets you upload query text from your computer. - - :: - -* **Max Rows** - By default, the Editor fetches only the first 10,000 rows. You can modify this number by selecting an option from the **Max Rows** dropdown list. Note that setting a higher number may slow down your browser if the result is very large. This number is limited to 100,000 results. To see a higher number, you can save the results in a file or a table using the :ref:`create_table_as` command. - - -For more information on stopping active statements, see the :ref:`STOP_STATEMENT` command. - -:ref:`Back to Executing Statements and Running Queries from the Editor` - - -.. _studio_5.4.3_editor_db_tree: - -Performing Statement-Related Operations from the Database Tree -================ -From the Database Tree you can perform statement-related operations and show metadata (such as a number indicating the amount of rows in the table). - - - - - -The database object functions are used to perform the following: - -* The **SELECT** statement - copies the selected table's **columns** into the Statement panel as ``SELECT`` parameters. - - :: - -* The **copy** feature |icon-copy| - copies the selected table's **name** into the Statement panel. - - :: - -* The **additional operations** |icon-dots| - displays the following additional options: - - -.. |icon-user| image:: /_static/images/studio_icon_user.png - :align: middle - -.. |icon-dots| image:: /_static/images/studio_icon_dots.png - :align: middle - -.. |icon-editor| image:: /_static/images/studio_icon_editor.png - :align: middle - -.. |icon-copy| image:: /_static/images/studio_icon_copy.png - :align: middle - -.. |icon-select| image:: /_static/images/studio_icon_select.png - :align: middle - -.. |icon-dots| image:: /_static/images/studio_icon_dots.png - :align: middle - -.. |icon-filter| image:: /_static/images/studio_icon_filter.png - :align: middle - -.. |icon-ddl-edit| image:: /_static/images/studio_icon_ddl_edit.png - :align: middle - -.. |icon-run-optimizer| image:: /_static/images/studio_icon_run_optimizer.png - :align: middle - -.. |icon-generate-create-statement| image:: /_static/images/studio_icon_generate_create_statement.png - :align: middle - -.. |icon-plus| image:: /_static/images/studio_icon_plus.png - :align: middle - -.. |icon-close| image:: /_static/images/studio_icon_close.png - :align: middle - -.. |icon-left| image:: /_static/images/studio_icon_left.png - :align: middle - -.. |icon-right| image:: /_static/images/studio_icon_right.png - :align: middle - -.. |icon-format-sql| image:: /_static/images/studio_icon_format.png - :align: middle - -.. |icon-download-query| image:: /_static/images/studio_icon_download_query.png - :align: middle - -.. |icon-open-query| image:: /_static/images/studio_icon_open_query.png - :align: middle - -.. |icon-execute| image:: /_static/images/studio_icon_execute.png - :align: middle - -.. |icon-stop| image:: /_static/images/studio_icon_stop.png - :align: middle - -.. |icon-dashboard| image:: /_static/images/studio_icon_dashboard.png - :align: middle - -.. |icon-expand| image:: /_static/images/studio_icon_expand.png - :align: middle - -.. |icon-scale| image:: /_static/images/studio_icon_scale.png - :align: middle - -.. |icon-expand-down| image:: /_static/images/studio_icon_expand_down.png - :align: middle - -.. |icon-add| image:: /_static/images/studio_icon_add.png - :align: middle - -.. |icon-add-worker| image:: /_static/images/studio_icon_add_worker.png - :align: middle - -.. |keep-tabs| image:: /_static/images/studio_keep_tabs.png - :align: middle - - -.. list-table:: - :widths: 30 70 - :header-rows: 1 - - * - Function - - Description - * - Insert statement - - Generates an `INSERT `_ statement for the selected table in the editing area. - * - Delete statement - - Generates a `DELETE `_ statement for the selected table in the editing area. - * - Create Table As statement - - Generates a `CREATE TABLE AS `_ statement for the selected table in the editing area. - * - Rename statement - - Generates an `RENAME TABLE AS `_ statement for renaming the selected table in the editing area. - * - Adding column statement - - Generates an `ADD COLUMN `_ statement for adding columns to the selected table in the editing area. - * - Truncate table statement - - Generates a `TRUNCATE_IF_EXISTS `_ statement for the selected table in the editing area. - * - Drop table statement - - Generates a ``DROP`` statement for the selected object in the editing area. - * - Table DDL - - Generates a DDL statement for the selected object in the editing area. To get the entire database DDL, click the |icon-ddl-edit| icon next to the database name in the tree root. See `Seeing System Objects as DDL `_. - * - DDL Optimizer - - The `DDL Optimizer `_ lets you analyze database tables and recommends possible optimizations. - -Optimizing Database Tables Using the DDL Optimizer ------------------------ -The **DDL Optimizer** tab analyzes database tables and recommends possible optimizations according to SQream's best practices. - -As described in the previous table, you can access the DDL Optimizer by clicking the **additional options icon** and selecting **DDL Optimizer**. - -The following table describes the DDL Optimizer screen: - -.. list-table:: - :widths: 15 75 - :header-rows: 1 - - * - Element - - Description - * - Column area - - Shows the column **names** and **column types** from the selected table. You can scroll down or to the right/left for long column lists. - * - Optimization area - - Shows the number of rows to sample as the basis for running an optimization, the default setting (1,000,000) when running an optimization (this is also the overhead threshold used when analyzing ``TEXT`` fields), and the default percent buffer to add to ``TEXT`` lengths (10%). Attempts to determine field nullability. - * - Run Optimizer - - Starts the optimization process. - -Clicking **Run Optimizer** adds a tab to the Statement panel showing the optimized results of the selected object. - -For more information, see `Optimization and Best Practices `_. - -Executing Pre-Defined Queries from the System Queries Panel ---------------- -The **System Queries** panel lets you execute predefined queries and includes the following system query types: - -* **Catalog queries** - Used for analyzing table compression rates, users and permissions, etc. - - :: - -* **Admin queries** - Queries useful for SQream database management. - -Clicking an item pastes the query into the Statement pane, and you can undo a previous operation by pressing **Ctrl + Z**. - -.. _studio_5.4.3_editor_statement_area: - -Writing Statements and Queries from the Statement Panel -============== -The multi-tabbed statement area is used for writing queries and statements, and is used in tandem with the toolbar. When writing and executing statements, you must first select a database from the **Database** dropdown menu in the toolbar. When you execute a statement, it passes through a series of statuses until completed. Knowing the status helps you with statement maintenance, and the statuses are shown in the **Results panel**. - -The auto-complete feature assists you when writing statements by suggesting statement options. - -The following table shows the statement statuses: - -.. list-table:: - :widths: 45 160 - :header-rows: 1 - - * - Status - - Description - * - Pending - - The statement is pending. - * - In queue - - The statement is waiting for execution. - * - Initializing - - The statement has entered execution checks. - * - Executing - - The statement is executing. - * - Statement stopped - - The statement has been stopped. - -You can add and name new tabs for each statement that you need to execute, and Studio preserves your created tabs when you switch between databases. You can add new tabs by clicking |icon-plus| , which creates a new tab to the right with a default name of SQL and an increasing number. This helps you keep track of your statements. - -You can also rename the default tab name by double-clicking it and typing a new name and write multiple statements in tandem in the same tab by separating them with semicolons (``;``).If too many tabs to fit into the Statement Pane are open at the same time, the tab arrows are displayed. You can scroll through the tabs by clicking |icon-left| or |icon-right|, and close tabs by clicking |icon-close|. You can also close all tabs at once by clicking **Close all** located to the right of the tabs. - -.. tip:: If this is your first time using SQream, see `Getting Started `_. - - -.. Keyboard shortcuts -.. ^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. :kbd:`Ctrl` +: kbd:`Enter` - Execute all queries in the statement area, or just the highlighted part of the query. - -.. :kbd:`Ctrl` + :kbd:`Space` - Auto-complete the current keyword - -.. :kbd:`Ctrl` + :kbd:`↑` - Switch to next tab. - -.. :kbd:`Ctrl` + :kbd:`↓` - Switch to previous tab - -.. _studio_editor_results_5.4.3: - -:ref:`Back to Executing Statements and Running Queries from the Editor` - -.. _studio_5.4.3_editor_results: - -.. _results_panel_5.4.3: - -Viewing Statement and Query Results from the Results Panel -============== -The results panel shows statement and query results. By default, only the first 10,000 results are returned, although you can modify this from the :ref:`studio_editor_toolbar`, as described above. By default, executing several statements together opens a separate results tab for each statement. Executing statements together executes them serially, and any failed statement cancels all subsequent executions. - -.. image:: /_static/images/results_panel.png - -The following is a brief description of the Results panel views highlighted in the figure above: - -.. list-table:: - :widths: 45 160 - :header-rows: 1 - - * - Element - - Description - * - :ref:`Results view` - - Lets you view search query results. - * - :ref:`Execution Details view` - - Lets you analyze your query for troubleshooting and optimization purposes. - * - :ref:`SQL view` - - Lets you see the SQL view. - - -.. _results_view_5.4.3: - -:ref:`Back to Executing Statements and Running Queries from the Editor` - -Searching Query Results in the Results View ----------------- -The **Results view** lets you view search query results. - -From this view you can also do the following: - -* View the amount of time (in seconds) taken for a query to finish executing. -* Switch and scroll between tabs. -* Close all tabs at once. -* Enable keeping tabs by selecting **Keep tabs**. -* Sort column results. - -Saving Results to the Clipboard -^^^^^^^^^^^^ -The **Save results to clipboard** function lets you save your results to the clipboard to paste into another text editor or into Excel for further analysis. - -.. _save_results_to_local_file_5.4.3: - -Saving Results to a Local File -^^^^^^^^^^^^ -The **Save results to local file** functions lets you save your search query results to a local file. Clicking **Save results to local file** downloads the contents of the Results panel to an Excel sheet. You can then use copy and paste this content into other editors as needed. - -In the Results view you can also run parallel statements, as described in **Running Parallel Statements** below. - -.. _running_parallel_statements_5.4.3: - -Running Parallel Statements -^^^^^^^^^^^^ -While Studio's default functionality is to open a new tab for each executed statement, Studio supports running parallel statements in one statement tab. Running parallel statements requires using macros and is useful for advanced users. - -The following shows the syntax for running parallel statements: - -.. code-block:: console - - $ @@ parallel - $ $$ - $ select 1; - $ select 2; - $ select 3; - $ $$ - - -:ref:`Back to Viewing Statement and Query Results from the Results Panel` - -.. _execution_details_view_5.4.3: - -.. _execution_tree_5.4.3: - -Execution Details View --------------- -The **Execution Details View** section describes the following: - -.. contents:: - :local: - :depth: 1 - -Overview -^^^^^^^^^^^^ -Clicking **Execution Details View** displays the **Execution Tree**, which is a chronological tree of processes that occurred to execute your queries. The purpose of the Execution Tree is to analyze all aspects of your query for troubleshooting and optimization purposes, such as resolving queries with an exceptionally long runtime. - -.. note:: The **Execution Details View** button is enabled only when a query takes longer than five seconds. - -From this screen you can scroll in, out, and around the execution tree with the mouse to analyze all aspects of your query. You can navigate around the execution tree by dragging or by using the mini-map in the bottom right corner. - -.. image:: /_static/images/execution_tree_1.png - -You can also search for query data by pressing **Ctrl+F** or clicking the search icon |icon-search| in the search field in the top right corner and typing text. - -.. image:: /_static/images/search_field.png - -Pressing **Enter** takes you directly to the next result matching your search criteria, and pressing **Shift + Enter** takes you directly to the previous result. You can also search next and previous results using the up and down arrows. - -.. |icon-search| image:: /_static/images/studio_icon_search.png - :align: middle - -The nodes are color-coded based on the following: - -* **Slow nodes** - red -* **In progress nodes** - yellow -* **Completed nodes** - green -* **Pending nodes** - white -* **Currently selected node** - blue -* **Search result node** - purple (in the mini-map) - -The execution tree displays the same information as shown in the plain view in tree format. - -The Execution Tree tracks each phase of your query in real time as a vertical tree of nodes. Each node refers to an operation that occurred on the GPU or CPU. When a phase is completed, the next branch begins to its right until the entire query is complete. Joins are displayed as two parallel branches merged together in a node called **Join**, as shown in the figure above. The nodes are connected by a line indicating the number of rows passed from one node to the next. The width of the line indicates the amount of rows on a logarithmic scale. - -Each node displays a number displaying its **node ID**, its **type**, **table name** (if relevant), **status**, and **runtime**. The nodes are color-coded for easy identification. Green nodes indicate **completed nodes**, yellow indicates **nodes in progress**, and red indicates **slowest nodes**, typically joins, as shown below: - -.. image:: /_static/images/nodes.png - -Viewing Query Statistics -^^^^^^^^^^^^ -The following statistical information is displayed in the top left corner, as shown in the figure above: - -* **Query Statistics**: - - * **Elapsed** - the total time taken for the query to complete. - * **Result rows** - the amount of rows fetched. - * **Running nodes completion** - * **Total query completion** - the amount of the total execution tree that was executed (nodes marked green). - -* **Slowest Nodes** information is displayed in the top right corner in red text. Clicking the slowest node centers automatically on that node in the execution tree. - -You can also view the following **Node Statistics** in the top right corner for each individual node by clicking a node: - -.. list-table:: - :widths: 45 160 - :header-rows: 1 - - * - Element - - Description - * - Node type - - Shows the node type. - * - Status - - Shows the execution status. - * - Time - - The total time taken to execute. - * - Rows - - Shows the number of produced rows passed to the next node. - * - Chunks - - Shows number of produced chunks. - * - Average rows per chunk - - Shows the number of average rows per chunk. - * - Table (for **ReadTable** and joins only) - - Shows the table name. - * - Write (for joins only) - - Shows the total date size written to the disk. - * - Read (for **ReadTable** and joins only) - - Shows the total data size read from the disk. - -Note that you can scroll the Node Statistics table. You can also download the execution plan table in .csv format by clicking the download arrow |icon-download| in the upper-right corner. - -.. |icon-download| image:: /_static/images/studio_icon_download.png - :align: middle - -Using the Plain View -^^^^^^^^^^^^ -You can use the **Plain View** instead of viewing the execution tree by clicking **Plain View** |icon-plain| in the top right corner. The plain view displays the same information as shown in the execution tree in table format. - -.. |icon-plain| image:: /_static/images/studio_icon_plain.png - :align: middle - - - - -The plain view lets you view a query’s execution plan for monitoring purposes and highlights rows based on how long they ran relative to the entire query. - -This can be seen in the **timeSum** column as follows: - -* **Rows highlighted red** - longest runtime -* **Rows highlighted orange** - medium runtime -* **Rows highlighted yellow** - shortest runtime - -:ref:`Back to Viewing Statement and Query Results from the Results Panel` - -.. _sql_view_5.4.3: - -Viewing Wrapped Strings in the SQL View ------------------- -The SQL View panel allows you to more easily view certain queries, such as a long string that appears on one line. The SQL View makes it easier to see by wrapping it so that you can see the entire string at once. It also reformats and organizes query syntax entered in the Statement panel for more easily locating particular segments of your queries. The SQL View is identical to the **Format SQL** feature in the Toolbar, allowing you to retain your originally constructed query while viewing a more intuitively structured snapshot of it. - -.. _save_results_to_clipboard_5.4.3: - -:ref:`Back to Viewing Statement and Query Results from the Results Panel` - -:ref:`Back to Executing Statements and Running Queries from the Editor` +.. _executing_statements_and_running_queries_from_the_editor: + +.. _editor_top_5.4.6: + +**************************** +Executing Statements and Running Queries from the Editor +**************************** +The **Editor** is used for the following: + +* Selecting an active database and executing queries. +* Performing statement-related operations and showing metadata. +* Executing pre-defined queries. +* Writing queries and statements and viewing query results. + +The following is a brief description of the Editor panels: + + +.. list-table:: + :widths: 10 34 56 + :header-rows: 1 + + * - No. + - Element + - Description + * - 1 + - :ref:`Toolbar` + - Used to select the active database you want to work on, limit the number of rows, save query, etc. + * - 2 + - :ref:`Database Tree and System Queries panel` + - Shows a hierarchy tree of databases, views, tables, and columns + * - 3 + - :ref:`Statement panel` + - Used for writing queries and statements + * - 4 + - :ref:`Results panel` + - Shows query results and execution information. + + + +.. _top_5.4.6: + +.. _studio_5.4.6_editor_toolbar: + +Executing Statements from the Toolbar +================ +You can access the following from the Toolbar pane: + +* **Database dropdown list** - select a database that you want to run statements on. + + :: + +* **Service dropdown list** - select a service that you want to run statements on. The options in the service dropdown menu depend on the database you select from the **Database** dropdown list. + + :: + +* **Execute** - lets you set which statements to execute. The **Execute** button toggles between **Execute** and **Stop**, and can be used to stop an active statement before it completes: + + * **Statements** - executes the statement at the location of the cursor. + * **Selected** - executes only the highlighted text. This mode should be used when executing subqueries or sections of large queries (as long as they are valid SQLs). + * **All** - executes all statements in a selected tab. + +* **Format SQL** - Lets you reformat and reindent statements. + + :: + +* **Download query** - Lets you download query text to your computer. + + :: + +* **Open query** - Lets you upload query text from your computer. + + :: + +* **Max Rows** - By default, the Editor fetches only the first 10,000 rows. You can modify this number by selecting an option from the **Max Rows** dropdown list. Note that setting a higher number may slow down your browser if the result is very large. This number is limited to 100,000 results. To see a higher number, you can save the results in a file or a table using the :ref:`create_table_as` command. + + +For more information on stopping active statements, see the :ref:`STOP_STATEMENT` command. + +:ref:`Back to Executing Statements and Running Queries from the Editor` + + +.. _studio_5.4.6_editor_db_tree: + +Performing Statement-Related Operations from the Database Tree +================ +From the Database Tree you can perform statement-related operations and show metadata (such as a number indicating the amount of rows in the table). + + + + + +The database object functions are used to perform the following: + +* The **SELECT** statement - copies the selected table's **columns** into the Statement panel as ``SELECT`` parameters. + + :: + +* The **copy** feature |icon-copy| - copies the selected table's **name** into the Statement panel. + + :: + +* The **additional operations** |icon-dots| - displays the following additional options: + + +.. |icon-user| image:: /_static/images/studio_icon_user.png + :align: middle + +.. |icon-dots| image:: /_static/images/studio_icon_dots.png + :align: middle + +.. |icon-editor| image:: /_static/images/studio_icon_editor.png + :align: middle + +.. |icon-copy| image:: /_static/images/studio_icon_copy.png + :align: middle + +.. |icon-select| image:: /_static/images/studio_icon_select.png + :align: middle + +.. |icon-dots| image:: /_static/images/studio_icon_dots.png + :align: middle + +.. |icon-filter| image:: /_static/images/studio_icon_filter.png + :align: middle + +.. |icon-ddl-edit| image:: /_static/images/studio_icon_ddl_edit.png + :align: middle + +.. |icon-run-optimizer| image:: /_static/images/studio_icon_run_optimizer.png + :align: middle + +.. |icon-generate-create-statement| image:: /_static/images/studio_icon_generate_create_statement.png + :align: middle + +.. |icon-plus| image:: /_static/images/studio_icon_plus.png + :align: middle + +.. |icon-close| image:: /_static/images/studio_icon_close.png + :align: middle + +.. |icon-left| image:: /_static/images/studio_icon_left.png + :align: middle + +.. |icon-right| image:: /_static/images/studio_icon_right.png + :align: middle + +.. |icon-format-sql| image:: /_static/images/studio_icon_format.png + :align: middle + +.. |icon-download-query| image:: /_static/images/studio_icon_download_query.png + :align: middle + +.. |icon-open-query| image:: /_static/images/studio_icon_open_query.png + :align: middle + +.. |icon-execute| image:: /_static/images/studio_icon_execute.png + :align: middle + +.. |icon-stop| image:: /_static/images/studio_icon_stop.png + :align: middle + +.. |icon-dashboard| image:: /_static/images/studio_icon_dashboard.png + :align: middle + +.. |icon-expand| image:: /_static/images/studio_icon_expand.png + :align: middle + +.. |icon-scale| image:: /_static/images/studio_icon_scale.png + :align: middle + +.. |icon-expand-down| image:: /_static/images/studio_icon_expand_down.png + :align: middle + +.. |icon-add| image:: /_static/images/studio_icon_add.png + :align: middle + +.. |icon-add-worker| image:: /_static/images/studio_icon_add_worker.png + :align: middle + +.. |keep-tabs| image:: /_static/images/studio_keep_tabs.png + :align: middle + + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + + * - Function + - Description + * - Insert statement + - Generates an `INSERT `_ statement for the selected table in the editing area. + * - Delete statement + - Generates a `DELETE `_ statement for the selected table in the editing area. + * - Create Table As statement + - Generates a `CREATE TABLE AS `_ statement for the selected table in the editing area. + * - Rename statement + - Generates an `RENAME TABLE AS `_ statement for renaming the selected table in the editing area. + * - Adding column statement + - Generates an `ADD COLUMN `_ statement for adding columns to the selected table in the editing area. + * - Truncate table statement + - Generates a `TRUNCATE_IF_EXISTS `_ statement for the selected table in the editing area. + * - Drop table statement + - Generates a ``DROP`` statement for the selected object in the editing area. + * - Table DDL + - Generates a DDL statement for the selected object in the editing area. To get the entire database DDL, click the |icon-ddl-edit| icon next to the database name in the tree root. See `Seeing System Objects as DDL `_. + * - DDL Optimizer + - The `DDL Optimizer `_ lets you analyze database tables and recommends possible optimizations. + +Optimizing Database Tables Using the DDL Optimizer +----------------------- +The **DDL Optimizer** tab analyzes database tables and recommends possible optimizations according to SQream's best practices. + +As described in the previous table, you can access the DDL Optimizer by clicking the **additional options icon** and selecting **DDL Optimizer**. + +The following table describes the DDL Optimizer screen: + +.. list-table:: + :widths: 15 75 + :header-rows: 1 + + * - Element + - Description + * - Column area + - Shows the column **names** and **column types** from the selected table. You can scroll down or to the right/left for long column lists. + * - Optimization area + - Shows the number of rows to sample as the basis for running an optimization, the default setting (1,000,000) when running an optimization (this is also the overhead threshold used when analyzing ``TEXT`` fields), and the default percent buffer to add to ``TEXT`` lengths (10%). Attempts to determine field nullability. + * - Run Optimizer + - Starts the optimization process. + +Clicking **Run Optimizer** adds a tab to the Statement panel showing the optimized results of the selected object. + +For more information, see `Optimization and Best Practices `_. + +Executing Pre-Defined Queries from the System Queries Panel +--------------- +The **System Queries** panel lets you execute predefined queries and includes the following system query types: + +* **Catalog queries** - Used for analyzing table compression rates, users and permissions, etc. + + :: + +* **Admin queries** - Queries useful for SQream database management. + +Clicking an item pastes the query into the Statement pane, and you can undo a previous operation by pressing **Ctrl + Z**. + +.. _studio_5.4.6_editor_statement_area: + +Writing Statements and Queries from the Statement Panel +============== +The multi-tabbed statement area is used for writing queries and statements, and is used in tandem with the toolbar. When writing and executing statements, you must first select a database from the **Database** dropdown menu in the toolbar. When you execute a statement, it passes through a series of statuses until completed. Knowing the status helps you with statement maintenance, and the statuses are shown in the **Results panel**. + +The auto-complete feature assists you when writing statements by suggesting statement options. + +The following table shows the statement statuses: + +.. list-table:: + :widths: 45 160 + :header-rows: 1 + + * - Status + - Description + * - Pending + - The statement is pending. + * - In queue + - The statement is waiting for execution. + * - Initializing + - The statement has entered execution checks. + * - Executing + - The statement is executing. + * - Statement stopped + - The statement has been stopped. + +You can add and name new tabs for each statement that you need to execute, and Studio preserves your created tabs when you switch between databases. You can add new tabs by clicking |icon-plus| , which creates a new tab to the right with a default name of SQL and an increasing number. This helps you keep track of your statements. + +You can also rename the default tab name by double-clicking it and typing a new name and write multiple statements in tandem in the same tab by separating them with semicolons (``;``).If too many tabs to fit into the Statement Pane are open at the same time, the tab arrows are displayed. You can scroll through the tabs by clicking |icon-left| or |icon-right|, and close tabs by clicking |icon-close|. You can also close all tabs at once by clicking **Close all** located to the right of the tabs. + +.. tip:: If this is your first time using SQream, see `Getting Started `_. + + +.. Keyboard shortcuts +.. ^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. :kbd:`Ctrl` +: kbd:`Enter` - Execute all queries in the statement area, or just the highlighted part of the query. + +.. :kbd:`Ctrl` + :kbd:`Space` - Auto-complete the current keyword + +.. :kbd:`Ctrl` + :kbd:`↑` - Switch to next tab. + +.. :kbd:`Ctrl` + :kbd:`↓` - Switch to previous tab + +.. _studio_editor_results_5.4.6: + +:ref:`Back to Executing Statements and Running Queries from the Editor` + +.. _studio_5.4.6_editor_results: + +.. _results_panel_5.4.6: + +Viewing Statement and Query Results from the Results Panel +============== +The results panel shows statement and query results. By default, only the first 10,000 results are returned, although you can modify this from the :ref:`studio_editor_toolbar`, as described above. By default, executing several statements together opens a separate results tab for each statement. Executing statements together executes them serially, and any failed statement cancels all subsequent executions. + +.. image:: /_static/images/results_panel.png + +The following is a brief description of the Results panel views highlighted in the figure above: + +.. list-table:: + :widths: 45 160 + :header-rows: 1 + + * - Element + - Description + * - :ref:`Results view` + - Lets you view search query results. + * - :ref:`Execution Details view` + - Lets you analyze your query for troubleshooting and optimization purposes. + * - :ref:`SQL view` + - Lets you see the SQL view. + + +.. _results_view_5.4.6: + +:ref:`Back to Executing Statements and Running Queries from the Editor` + +Searching Query Results in the Results View +---------------- +The **Results view** lets you view search query results. + +From this view you can also do the following: + +* View the amount of time (in seconds) taken for a query to finish executing. +* Switch and scroll between tabs. +* Close all tabs at once. +* Enable keeping tabs by selecting **Keep tabs**. +* Sort column results. + +Saving Results to the Clipboard +^^^^^^^^^^^^ +The **Save results to clipboard** function lets you save your results to the clipboard to paste into another text editor or into Excel for further analysis. + +.. _save_results_to_local_file_5.4.6: + +Saving Results to a Local File +^^^^^^^^^^^^ +The **Save results to local file** functions lets you save your search query results to a local file. Clicking **Save results to local file** downloads the contents of the Results panel to an Excel sheet. You can then use copy and paste this content into other editors as needed. + +In the Results view you can also run parallel statements, as described in **Running Parallel Statements** below. + +.. _running_parallel_statements_5.4.6: + +Running Parallel Statements +^^^^^^^^^^^^ +While Studio's default functionality is to open a new tab for each executed statement, Studio supports running parallel statements in one statement tab. Running parallel statements requires using macros and is useful for advanced users. + +The following shows the syntax for running parallel statements: + +.. code-block:: console + + $ @@ parallel + $ $$ + $ select 1; + $ select 2; + $ select 3; + $ $$ + + +:ref:`Back to Viewing Statement and Query Results from the Results Panel` + +.. _execution_details_view_5.4.6: + +.. _execution_tree_5.4.6: + +Execution Details View +-------------- +The **Execution Details View** section describes the following: + +.. contents:: + :local: + :depth: 1 + +Overview +^^^^^^^^^^^^ +Clicking **Execution Details View** displays the **Execution Tree**, which is a chronological tree of processes that occurred to execute your queries. The purpose of the Execution Tree is to analyze all aspects of your query for troubleshooting and optimization purposes, such as resolving queries with an exceptionally long runtime. + +.. note:: The **Execution Details View** button is enabled only when a query takes longer than five seconds. + +From this screen you can scroll in, out, and around the execution tree with the mouse to analyze all aspects of your query. You can navigate around the execution tree by dragging or by using the mini-map in the bottom right corner. + +.. image:: /_static/images/execution_tree_1.png + +You can also search for query data by pressing **Ctrl+F** or clicking the search icon |icon-search| in the search field in the top right corner and typing text. + +.. image:: /_static/images/search_field.png + +Pressing **Enter** takes you directly to the next result matching your search criteria, and pressing **Shift + Enter** takes you directly to the previous result. You can also search next and previous results using the up and down arrows. + +.. |icon-search| image:: /_static/images/studio_icon_search.png + :align: middle + +The nodes are color-coded based on the following: + +* **Slow nodes** - red +* **In progress nodes** - yellow +* **Completed nodes** - green +* **Pending nodes** - white +* **Currently selected node** - blue +* **Search result node** - purple (in the mini-map) + +The execution tree displays the same information as shown in the plain view in tree format. + +The Execution Tree tracks each phase of your query in real time as a vertical tree of nodes. Each node refers to an operation that occurred on the GPU or CPU. When a phase is completed, the next branch begins to its right until the entire query is complete. Joins are displayed as two parallel branches merged together in a node called **Join**, as shown in the figure above. The nodes are connected by a line indicating the number of rows passed from one node to the next. The width of the line indicates the amount of rows on a logarithmic scale. + +Each node displays a number displaying its **node ID**, its **type**, **table name** (if relevant), **status**, and **runtime**. The nodes are color-coded for easy identification. Green nodes indicate **completed nodes**, yellow indicates **nodes in progress**, and red indicates **slowest nodes**, typically joins, as shown below: + +.. image:: /_static/images/nodes.png + +Viewing Query Statistics +^^^^^^^^^^^^ +The following statistical information is displayed in the top left corner, as shown in the figure above: + +* **Query Statistics**: + + * **Elapsed** - the total time taken for the query to complete. + * **Result rows** - the amount of rows fetched. + * **Running nodes completion** + * **Total query completion** - the amount of the total execution tree that was executed (nodes marked green). + +* **Slowest Nodes** information is displayed in the top right corner in red text. Clicking the slowest node centers automatically on that node in the execution tree. + +You can also view the following **Node Statistics** in the top right corner for each individual node by clicking a node: + +.. list-table:: + :widths: 45 160 + :header-rows: 1 + + * - Element + - Description + * - Node type + - Shows the node type. + * - Status + - Shows the execution status. + * - Time + - The total time taken to execute. + * - Rows + - Shows the number of produced rows passed to the next node. + * - Chunks + - Shows number of produced chunks. + * - Average rows per chunk + - Shows the number of average rows per chunk. + * - Table (for **ReadTable** and joins only) + - Shows the table name. + * - Write (for joins only) + - Shows the total date size written to the disk. + * - Read (for **ReadTable** and joins only) + - Shows the total data size read from the disk. + +Note that you can scroll the Node Statistics table. You can also download the execution plan table in .csv format by clicking the download arrow |icon-download| in the upper-right corner. + +.. |icon-download| image:: /_static/images/studio_icon_download.png + :align: middle + +Using the Plain View +^^^^^^^^^^^^ +You can use the **Plain View** instead of viewing the execution tree by clicking **Plain View** |icon-plain| in the top right corner. The plain view displays the same information as shown in the execution tree in table format. + +.. |icon-plain| image:: /_static/images/studio_icon_plain.png + :align: middle + + + + +The plain view lets you view a query’s execution plan for monitoring purposes and highlights rows based on how long they ran relative to the entire query. + +This can be seen in the **timeSum** column as follows: + +* **Rows highlighted red** - longest runtime +* **Rows highlighted orange** - medium runtime +* **Rows highlighted yellow** - shortest runtime + +:ref:`Back to Viewing Statement and Query Results from the Results Panel` + +.. _sql_view_5.4.6: + +Viewing Wrapped Strings in the SQL View +------------------ +The SQL View panel allows you to more easily view certain queries, such as a long string that appears on one line. The SQL View makes it easier to see by wrapping it so that you can see the entire string at once. It also reformats and organizes query syntax entered in the Statement panel for more easily locating particular segments of your queries. The SQL View is identical to the **Format SQL** feature in the Toolbar, allowing you to retain your originally constructed query while viewing a more intuitively structured snapshot of it. + +.. _save_results_to_clipboard_5.4.6: + +:ref:`Back to Viewing Statement and Query Results from the Results Panel` + +:ref:`Back to Executing Statements and Running Queries from the Editor` diff --git a/sqream_studio_5.4.3/getting_started.rst b/sqream_studio_5.4.6/getting_started.rst similarity index 92% rename from sqream_studio_5.4.3/getting_started.rst rename to sqream_studio_5.4.6/getting_started.rst index 3b9644cdc..6b328ae67 100644 --- a/sqream_studio_5.4.3/getting_started.rst +++ b/sqream_studio_5.4.6/getting_started.rst @@ -1,61 +1,65 @@ -.. _getting_started: - -**************************** -Getting Started with SQream Acceleration Studio 5.4.3 -**************************** -Setting Up and Starting Studio ----------------- -Studio is included with all `dockerized installations of SQream DB `_. When starting Studio, it listens on the local machine on port 8080. - -Logging In to Studio ---------------- -**To log in to SQream Studio:** - -1. Open a browser to the host on **port 8080**. - - For example, if your machine IP address is ``192.168.0.100``, insert the IP address into the browser as shown below: - - .. code-block:: console - - $ http://192.168.0.100:8080 - -2. Fill in your SQream DB login credentials. These are the same credentials used for :ref:`sqream sql` or JDBC. - - When you sign in, the License Warning is displayed. - -Navigating Studio's Main Features -------------- -When you log in, you are automatically taken to the **Editor** screen. The Studio's main functions are displayed in the **Navigation** pane on the left side of the screen. - -From here you can navigate between the main areas of the Studio: - -.. list-table:: - :widths: 10 90 - :header-rows: 1 - - * - Element - - Description - * - :ref:`Dashboard` - - Lets you monitor system health and manage queues and workers. - * - :ref:`Editor` - - Lets you select databases, perform statement operations, and write and execute queries. - * - :ref:`Logs` - - Lets you view usage logs. - * - :ref:`Roles` - - Lets you create users and manage user permissions. - * - :ref:`Configuration` - - Lets you configure your instance of SQream. - -By clicking the user icon, you can also use it for logging out and viewing the following: - -* User information -* Connection type -* SQream version -* SQream Studio version -* License expiration date -* License storage capacity -* Log out - -.. _back_to_dashboard_5.4.3: - -.. _studio_dashboard_5.4.3: +.. _getting_started: + +**************************** +Getting Started with SQream Acceleration Studio 5.4.6 +**************************** +Setting Up and Starting Studio +---------------- + +:ref:`installing-sqream-db-docker` + + +Studio is included with all `dockerized installations of SQream DB `_. When starting Studio, it listens on the local machine on port 8080. + +Logging In to Studio +--------------- +**To log in to SQream Studio:** + +1. Open a browser to the host on **port 8080**. + + For example, if your machine IP address is ``192.168.0.100``, insert the IP address into the browser as shown below: + + .. code-block:: console + + $ http://192.168.0.100:8080 + +2. Fill in your SQream DB login credentials. These are the same credentials used for :ref:`sqream sql` or JDBC. + + When you sign in, the License Warning is displayed. + +Navigating Studio's Main Features +------------- +When you log in, you are automatically taken to the **Editor** screen. The Studio's main functions are displayed in the **Navigation** pane on the left side of the screen. + +From here you can navigate between the main areas of the Studio: + +.. list-table:: + :widths: 10 90 + :header-rows: 1 + + * - Element + - Description + * - :ref:`Dashboard` + - Lets you monitor system health and manage queues and workers. + * - :ref:`Editor` + - Lets you select databases, perform statement operations, and write and execute queries. + * - :ref:`Logs` + - Lets you view usage logs. + * - :ref:`Roles` + - Lets you create users and manage user permissions. + * - :ref:`Configuration` + - Lets you configure your instance of SQream. + +By clicking the user icon, you can also use it for logging out and viewing the following: + +* User information +* Connection type +* SQream version +* SQream Studio version +* License expiration date +* License storage capacity +* Log out + +.. _back_to_dashboard_5.4.6: + +.. _studio_dashboard_5.4.6: diff --git a/sqream_studio_5.4.3/index.rst b/sqream_studio_5.4.6/index.rst similarity index 88% rename from sqream_studio_5.4.3/index.rst rename to sqream_studio_5.4.6/index.rst index ac607b121..83fd6d224 100644 --- a/sqream_studio_5.4.3/index.rst +++ b/sqream_studio_5.4.6/index.rst @@ -1,19 +1,19 @@ -.. _sqream_studio_5.4.3: - -********************************** -SQream Acceleration Studio 5.4.3 -********************************** -The SQream Acceleration Studio is a web-based client for use with SQream. Studio provides users with all functionality available from the command line in an intuitive and easy-to-use format. This includes running statements, managing roles and permissions, and managing SQream clusters. - -This section describes how to use the SQream Accleration Studio version 5.4.3: - -.. toctree:: - :maxdepth: 1 - :glob: - - getting_started - monitoring_workers_and_services_from_the_dashboard - executing_statements_and_running_queries_from_the_editor - viewing_logs - creating_assigning_and_managing_roles_and_permissions +.. _sqream_studio_5.4.6: + +********************************** +SQream Acceleration Studio 5.4.6 +********************************** +The SQream Acceleration Studio is a web-based client for use with SQream. Studio provides users with all functionality available from the command line in an intuitive and easy-to-use format. This includes running statements, managing roles and permissions, and managing SQream clusters. + +This section describes how to use the SQream Accleration Studio version 5.4.6: + +.. toctree:: + :maxdepth: 1 + :glob: + + getting_started + executing_statements_and_running_queries_from_the_editor + monitoring_workers_and_services_from_the_dashboard + viewing_logs + creating_assigning_and_managing_roles_and_permissions configuring_your_instance_of_sqream \ No newline at end of file diff --git a/sqream_studio_5.4.3/monitoring_workers_and_services_from_the_dashboard.rst b/sqream_studio_5.4.6/monitoring_workers_and_services_from_the_dashboard.rst similarity index 90% rename from sqream_studio_5.4.3/monitoring_workers_and_services_from_the_dashboard.rst rename to sqream_studio_5.4.6/monitoring_workers_and_services_from_the_dashboard.rst index e30962f37..00ec30eda 100644 --- a/sqream_studio_5.4.3/monitoring_workers_and_services_from_the_dashboard.rst +++ b/sqream_studio_5.4.6/monitoring_workers_and_services_from_the_dashboard.rst @@ -1,265 +1,265 @@ -.. _monitoring_workers_and_services_from_the_dashboard: - -.. _back_to_dashboard_5.4.3: - -**************************** -Monitoring Workers and Services from the Dashboard -**************************** -The **Dashboard** is used for the following: - -* Monitoring system health. -* Viewing, monitoring, and adding defined service queues. -* Viewing and managing worker status and add workers. - -The following is an image of the Dashboard: - -.. image:: /_static/images/dashboard.png - -You can only access the Dashboard if you signed in with a ``SUPERUSER`` role. - -The following is a brief description of the Dashboard panels: - -.. list-table:: - :widths: 10 25 65 - :header-rows: 1 - - * - No. - - Element - - Description - * - 1 - - :ref:`Services panel` - - Used for viewing and monitoring the defined service queues. - * - 2 - - :ref:`Workers panel` - - Monitors system health and shows each Sqreamd worker running in the cluster. - * - 3 - - :ref:`License information` - - Shows the remaining amount of days left on your license. - - -.. _data_storage_panel_5.4.3: - - - -:ref:`Back to Monitoring Workers and Services from the Dashboard` - -.. _services_panel_5.4.3: - -Subscribing to Workers from the Services Panel --------------------------- -Services are used to categorize and associate (also known as **subscribing**) workers to particular services. The **Service** panel is used for viewing, monitoring, and adding defined `service queues `_. - - - -The following is a brief description of each pane: - -.. list-table:: - :widths: 10 90 - :header-rows: 1 - - * - No. - - Description - * - 1 - - Adds a worker to the selected service. - * - 2 - - Shows the service name. - * - 3 - - Shows a trend graph of queued statements loaded over time. - * - 4 - - Adds a service. - * - 5 - - Shows the currently processed queries belonging to the service/total queries for that service in the system (including queued queries). - -Adding A Service -^^^^^^^^^^^^^^^^^^^^^ -You can add a service by clicking **+ Add** and defining the service name. - -.. note:: If you do not associate a worker with the new service, it will not be created. - -You can manage workers from the **Workers** panel. For more information about managing workers, see the following: - -* :ref:`Managing Workers from the Workers Panel` -* `Workers `_ - -:ref:`Back to Monitoring Workers and Services from the Dashboard` - -.. _workers_panel_5.4.3: - -Managing Workers from the Workers Panel ------------- -From the **Workers** panel you can do the following: - -* :ref:`View workers ` -* :ref:`Add a worker to a service` -* :ref:`View a worker's active query information` -* :ref:`View a worker's execution plan` - -.. _view_workers_5.4.3: - -Viewing Workers -^^^^^^^^ -The **Worker** panel shows each worker (``sqreamd``) running in the cluster. Each worker has a status bar that represents the status over time. The status bar is divided into 20 equal segments, showing the most dominant activity in that segment. - -From the **Scale** dropdown menu you can set the time scale of the displayed information -You can hover over segments in the status bar to see the date and time corresponding to each activity type: - -* **Idle** – the worker is idle and available for statements. -* **Compiling** – the worker is compiling a statement and is preparing for execution. -* **Executing** – the worker is executing a statement after compilation. -* **Stopped** – the worker was stopped (either deliberately or due to an error). -* **Waiting** – the worker was waiting on an object locked by another worker. - -.. _add_worker_to_service_5.4.3: - -Adding A Worker to A Service -^^^^^^^^^^^^^^^^^^^^^ -You can add a worker to a service by clicking the **add** button. - - - -Clicking the **add** button shows the selected service's workers. You can add the selected worker to the service by clicking **Add Worker**. Adding a worker to a service does not break associations already made between that worker and other services. - - -.. _view_worker_query_information_5.4.3: - -Viewing A Worker's Active Query Information -^^^^^^^^^^^^^^^^^^^^^ -You can view a worker's active query information by clicking **Queries**, which displays them in the selected service. - - -Each statement shows the **query ID**, **status**, **service queue**, **elapsed time**, **execution time**, and **estimated completion status**. In addition, each statement can be stopped or expanded to show its execution plan and progress. For more information on viewing a statement's execution plan and progress, see :ref:`Viewing a Worker's Execution Plan ` below. - -Viewing A Worker's Host Utilization -^^^^^^^^^^^^^^^^^^^^^ - -While viewing a worker's query information, clicking the **down arrow** expands to show the host resource utilization. - - - -The graphs show the resource utilization trends over time, and the **CPU memory** and **utilization** and the **GPU utilization** values on the right. You can hover over the graph to see more information about the activity at any point on the graph. - -Error notifications related to statements are displayed, and you can hover over them for more information about the error. - - -.. _view_worker_execution_plan_5.4.3: - -Viewing a Worker's Execution Plan -^^^^^^^^^^^^^^^^^^^^^ - -Clicking the ellipsis in a service shows the following additional options: - -* **Stop Query** - stops the query. -* **Show Execution Plan** - shows the execution plan as a table. The columns in the **Show Execution Plan** table can be sorted. - -For more information on the current query plan, see `SHOW_NODE_INFO `_. For more information on checking active sessions across the cluster, see `SHOW_SERVER_STATUS `_. - -.. include:: /reference/sql/sql_statements/monitoring_commands/show_server_status.rst - :start-line: 67 - :end-line: 84 - -Managing Worker Status -^^^^^^^^^^^^^^^^^^^^^ - -In some cases you may want to stop or restart workers for maintenance purposes. Each Worker line has a :kbd:`⋮` menu used for stopping, starting, or restarting workers. - - -Starting or restarting workers terminates all queries related to that worker. When you stop a worker, its background turns gray. - - - - -.. |icon-user| image:: /_static/images/studio_icon_user.png - :align: middle - -.. |icon-dots| image:: /_static/images/studio_icon_dots.png - :align: middle - -.. |icon-editor| image:: /_static/images/studio_icon_editor.png - :align: middle - -.. |icon-copy| image:: /_static/images/studio_icon_copy.png - :align: middle - -.. |icon-select| image:: /_static/images/studio_icon_select.png - :align: middle - -.. |icon-dots| image:: /_static/images/studio_icon_dots.png - :align: middle - -.. |icon-filter| image:: /_static/images/studio_icon_filter.png - :align: middle - -.. |icon-ddl-edit| image:: /_static/images/studio_icon_ddl_edit.png - :align: middle - -.. |icon-run-optimizer| image:: /_static/images/studio_icon_run_optimizer.png - :align: middle - -.. |icon-generate-create-statement| image:: /_static/images/studio_icon_generate_create_statement.png - :align: middle - -.. |icon-plus| image:: /_static/images/studio_icon_plus.png - :align: middle - -.. |icon-close| image:: /_static/images/studio_icon_close.png - :align: middle - -.. |icon-left| image:: /_static/images/studio_icon_left.png - :align: middle - -.. |icon-right| image:: /_static/images/studio_icon_right.png - :align: middle - -.. |icon-format-sql| image:: /_static/images/studio_icon_format.png - :align: middle - -.. |icon-download-query| image:: /_static/images/studio_icon_download_query.png - :align: middle - -.. |icon-open-query| image:: /_static/images/studio_icon_open_query.png - :align: middle - -.. |icon-execute| image:: /_static/images/studio_icon_execute.png - :align: middle - -.. |icon-stop| image:: /_static/images/studio_icon_stop.png - :align: middle - -.. |icon-dashboard| image:: /_static/images/studio_icon_dashboard.png - :align: middle - -.. |icon-expand| image:: /_static/images/studio_icon_expand.png - :align: middle - -.. |icon-scale| image:: /_static/images/studio_icon_scale.png - :align: middle - -.. |icon-expand-down| image:: /_static/images/studio_icon_expand_down.png - :align: middle - -.. |icon-add| image:: /_static/images/studio_icon_add.png - :align: middle - -.. |icon-add-worker| image:: /_static/images/studio_icon_add_worker.png - :align: middle - -.. |keep-tabs| image:: /_static/images/studio_keep_tabs.png - :align: middle - -:ref:`Back to Monitoring Workers and Services from the Dashboard` - - - -.. _license_information_5.4.3: - -License Information ----------------------- -The license information section shows the following: - - * The amount of time in days remaining on the license. - * The license storage capacity. - -.. image:: /_static/images/license_storage_capacity.png - - -:ref:`Back to Monitoring Workers and Services from the Dashboard` +.. _monitoring_workers_and_services_from_the_dashboard: + +.. _back_to_dashboard_5.4.6: + +**************************** +Monitoring Workers and Services from the Dashboard +**************************** +The **Dashboard** is used for the following: + +* Monitoring system health. +* Viewing, monitoring, and adding defined service queues. +* Viewing and managing worker status and add workers. + +The following is an image of the Dashboard: + +.. image:: /_static/images/dashboard.png + +You can only access the Dashboard if you signed in with a ``SUPERUSER`` role. + +The following is a brief description of the Dashboard panels: + +.. list-table:: + :widths: 10 25 65 + :header-rows: 1 + + * - No. + - Element + - Description + * - 1 + - :ref:`Services panel` + - Used for viewing and monitoring the defined service queues. + * - 2 + - :ref:`Workers panel` + - Monitors system health and shows each Sqreamd worker running in the cluster. + * - 3 + - :ref:`License information` + - Shows the remaining amount of days left on your license. + + +.. _data_storage_panel_5.4.6: + + + +:ref:`Back to Monitoring Workers and Services from the Dashboard` + +.. _services_panel_5.4.6: + +Subscribing to Workers from the Services Panel +-------------------------- +Services are used to categorize and associate (also known as **subscribing**) workers to particular services. The **Service** panel is used for viewing, monitoring, and adding defined `service queues `_. + + + +The following is a brief description of each pane: + +.. list-table:: + :widths: 10 90 + :header-rows: 1 + + * - No. + - Description + * - 1 + - Adds a worker to the selected service. + * - 2 + - Shows the service name. + * - 3 + - Shows a trend graph of queued statements loaded over time. + * - 4 + - Adds a service. + * - 5 + - Shows the currently processed queries belonging to the service/total queries for that service in the system (including queued queries). + +Adding A Service +^^^^^^^^^^^^^^^^^^^^^ +You can add a service by clicking **+ Add** and defining the service name. + +.. note:: If you do not associate a worker with the new service, it will not be created. + +You can manage workers from the **Workers** panel. For more information about managing workers, see the following: + +* :ref:`Managing Workers from the Workers Panel` +* `Workers `_ + +:ref:`Back to Monitoring Workers and Services from the Dashboard` + +.. _workers_panel_5.4.6: + +Managing Workers from the Workers Panel +------------ +From the **Workers** panel you can do the following: + +* :ref:`View workers ` +* :ref:`Add a worker to a service` +* :ref:`View a worker's active query information` +* :ref:`View a worker's execution plan` + +.. _view_workers_5.4.6: + +Viewing Workers +^^^^^^^^ +The **Worker** panel shows each worker (``sqreamd``) running in the cluster. Each worker has a status bar that represents the status over time. The status bar is divided into 20 equal segments, showing the most dominant activity in that segment. + +From the **Scale** dropdown menu you can set the time scale of the displayed information +You can hover over segments in the status bar to see the date and time corresponding to each activity type: + +* **Idle** – the worker is idle and available for statements. +* **Compiling** – the worker is compiling a statement and is preparing for execution. +* **Executing** – the worker is executing a statement after compilation. +* **Stopped** – the worker was stopped (either deliberately or due to an error). +* **Waiting** – the worker was waiting on an object locked by another worker. + +.. _add_worker_to_service_5.4.6: + +Adding A Worker to A Service +^^^^^^^^^^^^^^^^^^^^^ +You can add a worker to a service by clicking the **add** button. + + + +Clicking the **add** button shows the selected service's workers. You can add the selected worker to the service by clicking **Add Worker**. Adding a worker to a service does not break associations already made between that worker and other services. + + +.. _view_worker_query_information_5.4.6: + +Viewing A Worker's Active Query Information +^^^^^^^^^^^^^^^^^^^^^ +You can view a worker's active query information by clicking **Queries**, which displays them in the selected service. + + +Each statement shows the **query ID**, **status**, **service queue**, **elapsed time**, **execution time**, and **estimated completion status**. In addition, each statement can be stopped or expanded to show its execution plan and progress. For more information on viewing a statement's execution plan and progress, see :ref:`Viewing a Worker's Execution Plan ` below. + +Viewing A Worker's Host Utilization +^^^^^^^^^^^^^^^^^^^^^ + +While viewing a worker's query information, clicking the **down arrow** expands to show the host resource utilization. + + + +The graphs show the resource utilization trends over time, and the **CPU memory** and **utilization** and the **GPU utilization** values on the right. You can hover over the graph to see more information about the activity at any point on the graph. + +Error notifications related to statements are displayed, and you can hover over them for more information about the error. + + +.. _view_worker_execution_plan_5.4.6: + +Viewing a Worker's Execution Plan +^^^^^^^^^^^^^^^^^^^^^ + +Clicking the ellipsis in a service shows the following additional options: + +* **Stop Query** - stops the query. +* **Show Execution Plan** - shows the execution plan as a table. The columns in the **Show Execution Plan** table can be sorted. + +For more information on the current query plan, see `SHOW_NODE_INFO `_. For more information on checking active sessions across the cluster, see `SHOW_SERVER_STATUS `_. + +.. include:: /reference/sql/sql_statements/monitoring_commands/show_server_status.rst + :start-line: 67 + :end-line: 84 + +Managing Worker Status +^^^^^^^^^^^^^^^^^^^^^ + +In some cases you may want to stop or restart workers for maintenance purposes. Each Worker line has a :kbd:`⋮` menu used for stopping, starting, or restarting workers. + + +Starting or restarting workers terminates all queries related to that worker. When you stop a worker, its background turns gray. + + + + +.. |icon-user| image:: /_static/images/studio_icon_user.png + :align: middle + +.. |icon-dots| image:: /_static/images/studio_icon_dots.png + :align: middle + +.. |icon-editor| image:: /_static/images/studio_icon_editor.png + :align: middle + +.. |icon-copy| image:: /_static/images/studio_icon_copy.png + :align: middle + +.. |icon-select| image:: /_static/images/studio_icon_select.png + :align: middle + +.. |icon-dots| image:: /_static/images/studio_icon_dots.png + :align: middle + +.. |icon-filter| image:: /_static/images/studio_icon_filter.png + :align: middle + +.. |icon-ddl-edit| image:: /_static/images/studio_icon_ddl_edit.png + :align: middle + +.. |icon-run-optimizer| image:: /_static/images/studio_icon_run_optimizer.png + :align: middle + +.. |icon-generate-create-statement| image:: /_static/images/studio_icon_generate_create_statement.png + :align: middle + +.. |icon-plus| image:: /_static/images/studio_icon_plus.png + :align: middle + +.. |icon-close| image:: /_static/images/studio_icon_close.png + :align: middle + +.. |icon-left| image:: /_static/images/studio_icon_left.png + :align: middle + +.. |icon-right| image:: /_static/images/studio_icon_right.png + :align: middle + +.. |icon-format-sql| image:: /_static/images/studio_icon_format.png + :align: middle + +.. |icon-download-query| image:: /_static/images/studio_icon_download_query.png + :align: middle + +.. |icon-open-query| image:: /_static/images/studio_icon_open_query.png + :align: middle + +.. |icon-execute| image:: /_static/images/studio_icon_execute.png + :align: middle + +.. |icon-stop| image:: /_static/images/studio_icon_stop.png + :align: middle + +.. |icon-dashboard| image:: /_static/images/studio_icon_dashboard.png + :align: middle + +.. |icon-expand| image:: /_static/images/studio_icon_expand.png + :align: middle + +.. |icon-scale| image:: /_static/images/studio_icon_scale.png + :align: middle + +.. |icon-expand-down| image:: /_static/images/studio_icon_expand_down.png + :align: middle + +.. |icon-add| image:: /_static/images/studio_icon_add.png + :align: middle + +.. |icon-add-worker| image:: /_static/images/studio_icon_add_worker.png + :align: middle + +.. |keep-tabs| image:: /_static/images/studio_keep_tabs.png + :align: middle + +:ref:`Back to Monitoring Workers and Services from the Dashboard` + + + +.. _license_information_5.4.6: + +License Information +---------------------- +The license information section shows the following: + + * The amount of time in days remaining on the license. + * The license storage capacity. + +.. image:: /_static/images/license_storage_capacity.png + + +:ref:`Back to Monitoring Workers and Services from the Dashboard` diff --git a/sqream_studio_5.4.3/viewing_logs.rst b/sqream_studio_5.4.6/viewing_logs.rst similarity index 85% rename from sqream_studio_5.4.3/viewing_logs.rst rename to sqream_studio_5.4.6/viewing_logs.rst index 0a8350a45..e431550ed 100644 --- a/sqream_studio_5.4.3/viewing_logs.rst +++ b/sqream_studio_5.4.6/viewing_logs.rst @@ -1,122 +1,122 @@ -.. _viewing_logs: - -.. _logs_top_5.4.3: - -**************************** -Viewing Logs -**************************** -The **Logs** screen is used for viewing logs and includes the following elements: - -.. list-table:: - :widths: 15 75 - :header-rows: 1 - - * - Element - - Description - * - :ref:`Filter area` - - Lets you filter the data shown in the table. - * - :ref:`Query tab` - - Shows basic query information logs, such as query number and the time the query was run. - * - :ref:`Session tab` - - Shows basic session information logs, such as session ID and user name. - * - :ref:`System tab` - - Shows all system logs. - * - :ref:`Log lines tab` - - Shows the total amount of log lines. - - -.. _filter_5.4.3: - -Filtering Table Data -------------- -From the Logs tab, from the **FILTERS** area you can also apply the **TIMESPAN**, **ONLY ERRORS**, and additional filters (**Add**). The **Timespan** filter lets you select a timespan. The **Only Errors** toggle button lets you show all queries, or only queries that generated errors. The **Add** button lets you add additional filters to the data shown in the table. The **Filter** button applies the selected filter(s). - -Other filters require you to select an item from a dropdown menu: - -* INFO -* WARNING -* ERROR -* FATAL -* SYSTEM - -You can also export a record of all of your currently filtered logs in Excel format by clicking **Download** located above the Filter area. - -.. _queries_5.4.3: - -:ref:`Back to Viewing Logs` - - -Viewing Query Logs ----------- -The **QUERIES** log area shows basic query information, such as query number and the time the query was run. The number next to the title indicates the amount of queries that have been run. - -From the Queries area you can see and sort by the following: - -* Query ID -* Start time -* Query -* Compilation duration -* Execution duration -* Total duration -* Details (execution details, error details, successful query details) - -In the Queries table, you can click on the **Statement ID** and **Query** items to set them as your filters. In the **Details** column you can also access additional details by clicking one of the **Details** options for a more detailed explanation of the query. - -:ref:`Back to Viewing Logs` - -.. _sessions_5.4.3: - -Viewing Session Logs ----------- -The **SESSIONS** tab shows the sessions log table and is used for viewing activity that has occurred during your sessions. The number at the top indicates the amount of sessions that have occurred. - -From here you can see and sort by the following: - -* Timestamp -* Connection ID -* Username -* Client IP -* Login (Success or Failed) -* Duration (of session) -* Configuration Changes - -In the Sessions table, you can click on the **Timestamp**, **Connection ID**, and **Username** items to set them as your filters. - -:ref:`Back to Viewing Logs` - -.. _system_5.4.3: - -Viewing System Logs ----------- -The **SYSTEM** tab shows the system log table and is used for viewing all system logs. The number at the top indicates the amount of sessions that have occurred. Because system logs occur less frequently than queries and sessions, you may need to increase the filter timespan for the table to display any system logs. - -From here you can see and sort by the following: - -* Timestamp -* Log type -* Message - -In the Systems table, you can click on the **Timestamp** and **Log type** items to set them as your filters. In the **Message** column, you can also click on an item to show more information about the message. - -:ref:`Back to Viewing Logs` - -.. _log_lines_5.4.3: - -Viewing All Log Lines ----------- -The **LOG LINES** tab is used for viewing the total amount of log lines in a table. From here users can view a more granular breakdown of log information collected by Studio. The other tabs (QUERIES, SESSIONS, and SYSTEM) show a filtered form of the raw log lines. For example, the QUERIES tab shows an aggregation of several log lines. - -From here you can see and sort by the following: - -* Timestamp -* Message level -* Worker hostname -* Worker port -* Connection ID -* Database name -* User name -* Statement ID - -In the **LOG LINES** table, you can click on any of the items to set them as your filters. - -:ref:`Back to Viewing Logs` \ No newline at end of file +.. _viewing_logs: + +.. _logs_top_5.4.6: + +**************************** +Viewing Logs +**************************** +The **Logs** screen is used for viewing logs and includes the following elements: + +.. list-table:: + :widths: 15 75 + :header-rows: 1 + + * - Element + - Description + * - :ref:`Filter area` + - Lets you filter the data shown in the table. + * - :ref:`Query tab` + - Shows basic query information logs, such as query number and the time the query was run. + * - :ref:`Session tab` + - Shows basic session information logs, such as session ID and user name. + * - :ref:`System tab` + - Shows all system logs. + * - :ref:`Log lines tab` + - Shows the total amount of log lines. + + +.. _filter_5.4.6: + +Filtering Table Data +------------- +From the Logs tab, from the **FILTERS** area you can also apply the **TIMESPAN**, **ONLY ERRORS**, and additional filters (**Add**). The **Timespan** filter lets you select a timespan. The **Only Errors** toggle button lets you show all queries, or only queries that generated errors. The **Add** button lets you add additional filters to the data shown in the table. The **Filter** button applies the selected filter(s). + +Other filters require you to select an item from a dropdown menu: + +* INFO +* WARNING +* ERROR +* FATAL +* SYSTEM + +You can also export a record of all of your currently filtered logs in Excel format by clicking **Download** located above the Filter area. + +.. _queries_5.4.6: + +:ref:`Back to Viewing Logs` + + +Viewing Query Logs +---------- +The **QUERIES** log area shows basic query information, such as query number and the time the query was run. The number next to the title indicates the amount of queries that have been run. + +From the Queries area you can see and sort by the following: + +* Query ID +* Start time +* Query +* Compilation duration +* Execution duration +* Total duration +* Details (execution details, error details, successful query details) + +In the Queries table, you can click on the **Statement ID** and **Query** items to set them as your filters. In the **Details** column you can also access additional details by clicking one of the **Details** options for a more detailed explanation of the query. + +:ref:`Back to Viewing Logs` + +.. _sessions_5.4.6: + +Viewing Session Logs +---------- +The **SESSIONS** tab shows the sessions log table and is used for viewing activity that has occurred during your sessions. The number at the top indicates the amount of sessions that have occurred. + +From here you can see and sort by the following: + +* Timestamp +* Connection ID +* Username +* Client IP +* Login (Success or Failed) +* Duration (of session) +* Configuration Changes + +In the Sessions table, you can click on the **Timestamp**, **Connection ID**, and **Username** items to set them as your filters. + +:ref:`Back to Viewing Logs` + +.. _system_5.4.6: + +Viewing System Logs +---------- +The **SYSTEM** tab shows the system log table and is used for viewing all system logs. The number at the top indicates the amount of sessions that have occurred. Because system logs occur less frequently than queries and sessions, you may need to increase the filter timespan for the table to display any system logs. + +From here you can see and sort by the following: + +* Timestamp +* Log type +* Message + +In the Systems table, you can click on the **Timestamp** and **Log type** items to set them as your filters. In the **Message** column, you can also click on an item to show more information about the message. + +:ref:`Back to Viewing Logs` + +.. _log_lines_5.4.6: + +Viewing All Log Lines +---------- +The **LOG LINES** tab is used for viewing the total amount of log lines in a table. From here users can view a more granular breakdown of log information collected by Studio. The other tabs (QUERIES, SESSIONS, and SYSTEM) show a filtered form of the raw log lines. For example, the QUERIES tab shows an aggregation of several log lines. + +From here you can see and sort by the following: + +* Timestamp +* Message level +* Worker hostname +* Worker port +* Connection ID +* Database name +* User name +* Statement ID + +In the **LOG LINES** table, you can click on any of the items to set them as your filters. + +:ref:`Back to Viewing Logs` \ No newline at end of file From f5d562641a0ef4482e4c9b2baf8d6daf3142bf8c Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 4 Aug 2022 15:10:18 +0300 Subject: [PATCH 197/316] Updated Studio 5.4.3 to 5.4.6 Changed links to ref syntax. --- .../utility_commands/shutdown_server.rst | 2 -- .../configuring_your_instance_of_sqream.rst | 4 ++- ...ts_and_running_queries_from_the_editor.rst | 33 +++++++------------ ...started.rst => getting_started_sqream.rst} | 8 ++--- sqream_studio_5.4.6/index.rst | 2 +- ...orkers_and_services_from_the_dashboard.rst | 31 ++++++++--------- sqream_studio_5.4.6/viewing_logs.rst | 3 ++ 7 files changed, 36 insertions(+), 47 deletions(-) rename sqream_studio_5.4.6/{getting_started.rst => getting_started_sqream.rst} (86%) diff --git a/reference/sql/sql_statements/utility_commands/shutdown_server.rst b/reference/sql/sql_statements/utility_commands/shutdown_server.rst index ac0c4dc96..1f607e753 100644 --- a/reference/sql/sql_statements/utility_commands/shutdown_server.rst +++ b/reference/sql/sql_statements/utility_commands/shutdown_server.rst @@ -3,8 +3,6 @@ ******************** SHUTDOWN SERVER ******************** -**Comment** - When finished, add command to Utility Commands > shutdown_server. - The **SHUTDOWN_SERVER** guide describes the following: .. contents:: diff --git a/sqream_studio_5.4.6/configuring_your_instance_of_sqream.rst b/sqream_studio_5.4.6/configuring_your_instance_of_sqream.rst index 2b334cbfa..a0def6827 100644 --- a/sqream_studio_5.4.6/configuring_your_instance_of_sqream.rst +++ b/sqream_studio_5.4.6/configuring_your_instance_of_sqream.rst @@ -3,6 +3,8 @@ **************************** Configuring Your Instance of SQream **************************** +**Comment** - *Has this functionality been removed from Studio 5.4.6?* + The **Configuration** section lets you edit parameters from one centralized location. While you can edit these parameters from the **worker configuration file (config.json)** or from your CLI, you can also modify them in Studio in an easy-to-use format. Configuring your instance of SQream in Studio is session-based, which enables you to edit parameters per session on your own device. @@ -20,4 +22,4 @@ Exporting and Importing Configuration Files ------------------------- You can also export and import your configuration settings into a .json file. This allows you to easily edit your parameters and to share this file with other users if required. -For more information about configuring your instance of SQream, see `Configuration Guides `_. \ No newline at end of file +For more information about configuring your instance of SQream, see :ref:`configuration_guides`. \ No newline at end of file diff --git a/sqream_studio_5.4.6/executing_statements_and_running_queries_from_the_editor.rst b/sqream_studio_5.4.6/executing_statements_and_running_queries_from_the_editor.rst index 9640665da..8015b7c4a 100644 --- a/sqream_studio_5.4.6/executing_statements_and_running_queries_from_the_editor.rst +++ b/sqream_studio_5.4.6/executing_statements_and_running_queries_from_the_editor.rst @@ -14,7 +14,6 @@ The **Editor** is used for the following: The following is a brief description of the Editor panels: - .. list-table:: :widths: 10 34 56 :header-rows: 1 @@ -35,8 +34,6 @@ The following is a brief description of the Editor panels: - :ref:`Results panel` - Shows query results and execution information. - - .. _top_5.4.6: .. _studio_5.4.6_editor_toolbar: @@ -73,22 +70,16 @@ You can access the following from the Toolbar pane: * **Max Rows** - By default, the Editor fetches only the first 10,000 rows. You can modify this number by selecting an option from the **Max Rows** dropdown list. Note that setting a higher number may slow down your browser if the result is very large. This number is limited to 100,000 results. To see a higher number, you can save the results in a file or a table using the :ref:`create_table_as` command. - -For more information on stopping active statements, see the :ref:`STOP_STATEMENT` command. +For more information on stopping active statements, see the :ref:`SHUTDOWN_SERVER` command. :ref:`Back to Executing Statements and Running Queries from the Editor` - .. _studio_5.4.6_editor_db_tree: Performing Statement-Related Operations from the Database Tree ================ From the Database Tree you can perform statement-related operations and show metadata (such as a number indicating the amount of rows in the table). - - - - The database object functions are used to perform the following: * The **SELECT** statement - copies the selected table's **columns** into the Statement panel as ``SELECT`` parameters. @@ -179,7 +170,8 @@ The database object functions are used to perform the following: .. |keep-tabs| image:: /_static/images/studio_keep_tabs.png :align: middle - + + :ref:`insert` .. list-table:: :widths: 30 70 @@ -188,23 +180,23 @@ The database object functions are used to perform the following: * - Function - Description * - Insert statement - - Generates an `INSERT `_ statement for the selected table in the editing area. + - Generates an :ref:`insert` statement for the selected table in the editing area. * - Delete statement - - Generates a `DELETE `_ statement for the selected table in the editing area. + - Generates a :ref:`delete` statement for the selected table in the editing area. * - Create Table As statement - Generates a `CREATE TABLE AS `_ statement for the selected table in the editing area. * - Rename statement - - Generates an `RENAME TABLE AS `_ statement for renaming the selected table in the editing area. + - Generates an :ref:`rename_table` statement for renaming the selected table in the editing area. * - Adding column statement - - Generates an `ADD COLUMN `_ statement for adding columns to the selected table in the editing area. + - Generates an :ref:`add_column` statement for adding columns to the selected table in the editing area. * - Truncate table statement - - Generates a `TRUNCATE_IF_EXISTS `_ statement for the selected table in the editing area. + - Generates a :ref:`truncate` statement for the selected table in the editing area. * - Drop table statement - Generates a ``DROP`` statement for the selected object in the editing area. * - Table DDL - - Generates a DDL statement for the selected object in the editing area. To get the entire database DDL, click the |icon-ddl-edit| icon next to the database name in the tree root. See `Seeing System Objects as DDL `_. + - Generates a DDL statement for the selected object in the editing area. To get the entire database DDL, click the |icon-ddl-edit| icon next to the database name in the tree root. See :ref:`seeing_system_objects_as_ddl`. * - DDL Optimizer - - The `DDL Optimizer `_ lets you analyze database tables and recommends possible optimizations. + - The `DDL Optimizer `_ lets you analyze database tables and recommends possible optimizations. Optimizing Database Tables Using the DDL Optimizer ----------------------- @@ -229,7 +221,7 @@ The following table describes the DDL Optimizer screen: Clicking **Run Optimizer** adds a tab to the Statement panel showing the optimized results of the selected object. -For more information, see `Optimization and Best Practices `_. +For more information, see :ref:`sql_best_practices`. Executing Pre-Defined Queries from the System Queries Panel --------------- @@ -274,8 +266,7 @@ You can add and name new tabs for each statement that you need to execute, and S You can also rename the default tab name by double-clicking it and typing a new name and write multiple statements in tandem in the same tab by separating them with semicolons (``;``).If too many tabs to fit into the Statement Pane are open at the same time, the tab arrows are displayed. You can scroll through the tabs by clicking |icon-left| or |icon-right|, and close tabs by clicking |icon-close|. You can also close all tabs at once by clicking **Close all** located to the right of the tabs. -.. tip:: If this is your first time using SQream, see `Getting Started `_. - +.. tip:: If this is your first time using SQream, see :ref:`getting_started`. .. Keyboard shortcuts .. ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/sqream_studio_5.4.6/getting_started.rst b/sqream_studio_5.4.6/getting_started_sqream.rst similarity index 86% rename from sqream_studio_5.4.6/getting_started.rst rename to sqream_studio_5.4.6/getting_started_sqream.rst index 6b328ae67..10542277e 100644 --- a/sqream_studio_5.4.6/getting_started.rst +++ b/sqream_studio_5.4.6/getting_started_sqream.rst @@ -1,15 +1,13 @@ -.. _getting_started: +.. _getting_started_sqream: **************************** Getting Started with SQream Acceleration Studio 5.4.6 **************************** Setting Up and Starting Studio ---------------- +Studio is included with all dockerized installations of SQream. When starting Studio, it listens on the local machine on port 8080. -:ref:`installing-sqream-db-docker` - - -Studio is included with all `dockerized installations of SQream DB `_. When starting Studio, it listens on the local machine on port 8080. +For more information, see :ref:`running_sqream_in_a_docker_container`. Logging In to Studio --------------- diff --git a/sqream_studio_5.4.6/index.rst b/sqream_studio_5.4.6/index.rst index 83fd6d224..451a520ad 100644 --- a/sqream_studio_5.4.6/index.rst +++ b/sqream_studio_5.4.6/index.rst @@ -11,7 +11,7 @@ This section describes how to use the SQream Accleration Studio version 5.4.6: :maxdepth: 1 :glob: - getting_started + getting_started_sqream executing_statements_and_running_queries_from_the_editor monitoring_workers_and_services_from_the_dashboard viewing_logs diff --git a/sqream_studio_5.4.6/monitoring_workers_and_services_from_the_dashboard.rst b/sqream_studio_5.4.6/monitoring_workers_and_services_from_the_dashboard.rst index 00ec30eda..51dbb3941 100644 --- a/sqream_studio_5.4.6/monitoring_workers_and_services_from_the_dashboard.rst +++ b/sqream_studio_5.4.6/monitoring_workers_and_services_from_the_dashboard.rst @@ -34,22 +34,17 @@ The following is a brief description of the Dashboard panels: - Monitors system health and shows each Sqreamd worker running in the cluster. * - 3 - :ref:`License information` - - Shows the remaining amount of days left on your license. - + - Shows the remaining amount of days left on your license. .. _data_storage_panel_5.4.6: - - :ref:`Back to Monitoring Workers and Services from the Dashboard` .. _services_panel_5.4.6: Subscribing to Workers from the Services Panel -------------------------- -Services are used to categorize and associate (also known as **subscribing**) workers to particular services. The **Service** panel is used for viewing, monitoring, and adding defined `service queues `_. - - +Services are used to categorize and associate (also known as **subscribing**) workers to particular services. The **Service** panel is used for viewing, monitoring, and adding defined in the :ref:`workload_manager`. The following is a brief description of each pane: @@ -138,20 +133,27 @@ While viewing a worker's query information, clicking the **down arrow** expands The graphs show the resource utilization trends over time, and the **CPU memory** and **utilization** and the **GPU utilization** values on the right. You can hover over the graph to see more information about the activity at any point on the graph. -Error notifications related to statements are displayed, and you can hover over them for more information about the error. - +Error notifications related to statements are displayed, and you can hover over them for more information about the error. .. _view_worker_execution_plan_5.4.6: Viewing a Worker's Execution Plan -^^^^^^^^^^^^^^^^^^^^^ - +^^^^^^^^^^^^^^^^^^^^^ Clicking the ellipsis in a service shows the following additional options: * **Stop Query** - stops the query. + + :: + * **Show Execution Plan** - shows the execution plan as a table. The columns in the **Show Execution Plan** table can be sorted. -For more information on the current query plan, see `SHOW_NODE_INFO `_. For more information on checking active sessions across the cluster, see `SHOW_SERVER_STATUS `_. +For more information on the current query plan, see the following: + +* :ref:`show_node_info` + + :: + +* :ref:`show_server_status` .. include:: /reference/sql/sql_statements/monitoring_commands/show_server_status.rst :start-line: 67 @@ -159,15 +161,10 @@ For more information on the current query plan, see `SHOW_NODE_INFO ` - Shows the total amount of log lines. +.. note:: Because the logs are stored in the **system** database, you cannot search the logs without first creating a **system** database. When you access the **Logs** tab, SQream can automatically create a **system** database for you. .. _filter_5.4.6: @@ -104,6 +105,8 @@ In the Systems table, you can click on the **Timestamp** and **Log type** items Viewing All Log Lines ---------- +**Comment** - *Has this tab been removed from the GUI?* + The **LOG LINES** tab is used for viewing the total amount of log lines in a table. From here users can view a more granular breakdown of log information collected by Studio. The other tabs (QUERIES, SESSIONS, and SYSTEM) show a filtered form of the raw log lines. For example, the QUERIES tab shows an aggregation of several log lines. From here you can see and sort by the following: From 643334085b7468c01b70db4b8ce510805233d338 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 4 Aug 2022 15:33:44 +0300 Subject: [PATCH 198/316] Removed Configuration from Studio index --- index.rst | 2 +- sqream_studio_5.4.6/index.rst | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/index.rst b/index.rst index 23e2288c0..efeecb8e2 100644 --- a/index.rst +++ b/index.rst @@ -87,7 +87,7 @@ If you couldn't find what you're looking for, we're always happy to help. Visit This version of the documentation is for SQream DB Version 2022.1. -If you're looking for an older version of the documentation, versions 1.10 through 2019.2.1 are available at http://previous.sqream.com . +If you're looking for an older version of the documentation, versions 1.10 through 2019.2.1 are available at http://previous.sqream.com. .. toctree:: :caption: Contents: diff --git a/sqream_studio_5.4.6/index.rst b/sqream_studio_5.4.6/index.rst index 451a520ad..c4981ce81 100644 --- a/sqream_studio_5.4.6/index.rst +++ b/sqream_studio_5.4.6/index.rst @@ -15,5 +15,4 @@ This section describes how to use the SQream Accleration Studio version 5.4.6: executing_statements_and_running_queries_from_the_editor monitoring_workers_and_services_from_the_dashboard viewing_logs - creating_assigning_and_managing_roles_and_permissions - configuring_your_instance_of_sqream \ No newline at end of file + creating_assigning_and_managing_roles_and_permissions \ No newline at end of file From 4bdc8f6ba36a45b5ffd03ddd6316173c3fc451b7 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 4 Aug 2022 15:34:12 +0300 Subject: [PATCH 199/316] Delete configuring_your_instance_of_sqream.rst --- .../configuring_your_instance_of_sqream.rst | 25 ------------------- 1 file changed, 25 deletions(-) delete mode 100644 sqream_studio_5.4.6/configuring_your_instance_of_sqream.rst diff --git a/sqream_studio_5.4.6/configuring_your_instance_of_sqream.rst b/sqream_studio_5.4.6/configuring_your_instance_of_sqream.rst deleted file mode 100644 index a0def6827..000000000 --- a/sqream_studio_5.4.6/configuring_your_instance_of_sqream.rst +++ /dev/null @@ -1,25 +0,0 @@ -.. _configuring_your_instance_of_sqream: - -**************************** -Configuring Your Instance of SQream -**************************** -**Comment** - *Has this functionality been removed from Studio 5.4.6?* - -The **Configuration** section lets you edit parameters from one centralized location. While you can edit these parameters from the **worker configuration file (config.json)** or from your CLI, you can also modify them in Studio in an easy-to-use format. - -Configuring your instance of SQream in Studio is session-based, which enables you to edit parameters per session on your own device. -Because session-based configurations are not persistent and are deleted when your session ends, you can edit your required parameters while avoiding conflicts between parameters edited on different devices at different points in time. - -Editing Your Parameters -------------------------------- -When configuring your instance of SQream in Studio you can edit parameters for the **Generic** and **Admin** parameters only. - -Studio includes two types of parameters: toggle switches, such as **flipJoinOrder**, and text fields, such as **logSysLevel**. After editing a parameter, you can reset each one to its previous value or to its default value individually, or revert all parameters to their default setting simultaneously. Note that you must click **Save** to save your configurations. - -You can hover over the **information** icon located on each parameter to read a short description of its behavior. - -Exporting and Importing Configuration Files -------------------------- -You can also export and import your configuration settings into a .json file. This allows you to easily edit your parameters and to share this file with other users if required. - -For more information about configuring your instance of SQream, see :ref:`configuration_guides`. \ No newline at end of file From b072eabda389e4c26fea3d637195b29266f53092 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 4 Aug 2022 16:34:18 +0300 Subject: [PATCH 200/316] Updated --- feature_guides/query_healer.rst | 2 ++ .../utility_commands/shutdown_server.rst | 34 +++++-------------- 2 files changed, 11 insertions(+), 25 deletions(-) diff --git a/feature_guides/query_healer.rst b/feature_guides/query_healer.rst index 8f0b56d08..a2874e3bb 100644 --- a/feature_guides/query_healer.rst +++ b/feature_guides/query_healer.rst @@ -21,6 +21,8 @@ The following is an example of a log record for a query stuck in the query detec The ``healerMaxInactivityHours`` log frequency is calculated as 5% of the flag setting. When set to to five hours (the default setting), the Query Healer triggers an examination every 15 minutes. +.. note:: The logs are located in your cluster. + Configuring the Healer ------------------ The following **Administration Worker** flags are required to configure the Query Healer: diff --git a/reference/sql/sql_statements/utility_commands/shutdown_server.rst b/reference/sql/sql_statements/utility_commands/shutdown_server.rst index 1f607e753..334281929 100644 --- a/reference/sql/sql_statements/utility_commands/shutdown_server.rst +++ b/reference/sql/sql_statements/utility_commands/shutdown_server.rst @@ -11,7 +11,7 @@ The **SHUTDOWN_SERVER** guide describes the following: Overview =============== -SQream's current method for stopping the SQream server is running the ``shutdown_server ()`` utility command. Because this command abruptly shuts down the server while executing operations, it has been modified to perform a graceful shutdown, giving you more control over the following: +SQream's current method for stopping the SQream server is running the ``shutdown_server()`` utility command. Because this command abruptly shuts down the server while executing operations, it has been modified to perform a graceful shutdown, giving you more control over the following: * Preventing new queries from connecting to the server. @@ -29,7 +29,7 @@ Running the ``SHUTDOWN_SERVER`` command does the following: * Prevents new queries from entering the server by doing the following: - * Setting the SQream server to unavailable in the metadata server. **Comment** - *Is "unavailable" the official server setting?* + * Disabling incoming queries. :: @@ -39,9 +39,7 @@ Running the ``SHUTDOWN_SERVER`` command does the following: :: -* Waiting for the statement queue to be cleared - the graceful shutdown waits for queries that have been compiled on the server to be cleared from the statement queue. During this time - start executing on other available servers. - -**Comment** - *The last bullet requires clarification.* +* Waits for any queries that depend on server being shut down to leave the statement queue. Syntax ========== @@ -51,14 +49,12 @@ The following is the syntax for using the ``SHUTDOWN_SERVER`` command: select shutdown_server([is_graceful, [timeout]]); -**Comment** - *Is the below syntax correct?* - +The following is example of the ``SHUTDOWN_SERVER`` command: + .. code-block:: postgres select shutdown_server([true/false, [timeout]]); -**Comment** - *Can you set the timeout as a flag in Studio, or only in the CLI?* - Returns ========== Running the ``shutdown_server`` command returns no output. @@ -78,7 +74,7 @@ The following table shows the ``shutdown_server`` parameters: * - ``is_graceful`` - Determines the method used to shut down the server. - Selecting ``false`` shuts down the server while queries are running. Selecting ``true`` uses the graceful shutdown method. - - **Comment** - Is the default ``true`` or ``false``? + - ``false`` * - ``timeout`` - Sets the maximum amount of minutes for the graceful shutdown method to run before the server is shut down using the standard method. - ``30`` @@ -86,10 +82,8 @@ The following table shows the ``shutdown_server`` parameters: .. note:: Setting ``is_graceful`` to ``false`` and defining the ``timeout`` value shuts the server down mid-query after the defined time. -It is possible to pass as the second argument the timeout in minutes after which a forceful shutdown will run, regardless of the progression of the graceful shutdown. - -**Comment** - *How can the above be true given the following, "Note that running forced shutdown with a timeout, i.e. select shutdown_server(false, 30) will return an error message; forced shutdown has no timeout timer"?* - +It is possible to pass as the second argument the timeout in minutes after which a forceful shutdown will run after defining the graceful shutdown value, regardless of the progression of the graceful shutdown. + Note that you set the timeout value using the ``defaultGracefulShutdownTimeoutMinutes`` flag in Studio. For more information, see :ref:`graceful_shutdown`. @@ -98,16 +92,6 @@ For more information, see :ref:`graceful_shutdown`. Like shutdown_server() graceful shutdown will stop any query currently running on the server. -**Comment** - *The above makes it seem like it's a separate command, but that's not the case.* - -Relationship to Healer & Use Case -============================ -**Comment** - *Cannot document this section until I know what the Healer actually does.* - -Currently the Healer will not trigger a graceful shutdown upon detection of a stuck query. It will however log detection of such a query, prompting the user to run a graceful shutdown of the server, possibly saving existing queued queries. - Permissions ============= -Using the ``shutdown_server`` command requires no special permissions. - -**Comment** - *Confirm.* \ No newline at end of file +Using the ``shutdown_server`` command requires no special permissions. \ No newline at end of file From e0a7def00cccd2dcaf7d8521a19fa4b0d7bfa685 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 4 Aug 2022 22:21:22 +0300 Subject: [PATCH 201/316] Replaced 10.1 with 11.4 where necessary --- feature_guides/query_healer.rst | 2 +- .../installing_sqream_with_kubernetes.rst | 109 ++++++++++-------- .../running_sqream_in_a_docker_container.rst | 25 ++-- 3 files changed, 73 insertions(+), 63 deletions(-) diff --git a/feature_guides/query_healer.rst b/feature_guides/query_healer.rst index a2874e3bb..7068abc2d 100644 --- a/feature_guides/query_healer.rst +++ b/feature_guides/query_healer.rst @@ -17,7 +17,7 @@ The following is an example of a log record for a query stuck in the query detec .. code-block:: console - 2022/05/19::20:01:25|ERROR|Healer|(0x7f07147fc700)|Stuck query found. Statement ID: 72, Last chunk producer updated: 1 WriteTable, Started on: Thu May 19 14:01:25 2022, Last updated: Thu May 19 15:01:25 2022, Stuck time: 5 hours, Max allowed stuck query time: 5 hours + #SQ#|1659621825880088264|2022-05-19 20:01:25.880|INFO|0x00007f9a497fe700:Healer|192.168.4.65|5001|-1|master|sqream|-1|sqream|0|"[ERROR]|cpp/SqrmRT/healer.cpp:140 |"Stuck query found. Statement ID: 72, Last chunk producer updated: 1 WriteTable, Started on: Thu May 19 14:01:25 2022, Last updated: Thu May 19 15:01:25 2022, Stuck time: 5 hours, Max allowed stuck query time: 5 hours"|#EOM# The ``healerMaxInactivityHours`` log frequency is calculated as 5% of the flag setting. When set to to five hours (the default setting), the Query Healer triggers an examination every 15 minutes. diff --git a/installation_guides/installing_sqream_with_kubernetes.rst b/installation_guides/installing_sqream_with_kubernetes.rst index 093f21ba3..aa7e22422 100644 --- a/installation_guides/installing_sqream_with_kubernetes.rst +++ b/installation_guides/installing_sqream_with_kubernetes.rst @@ -197,27 +197,32 @@ After completing all of the steps above, you must check the CUDA version. .. code-block:: postgres - $ +-----------------------------------------------------------------------------+ - $ | NVIDIA-SMI 418.87.00 Driver Version: 418.87.00 CUDA Version: 10.1 | - $ |-------------------------------+----------------------+----------------------+ - $ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | - $ | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | - $ |===============================+======================+======================| - $ | 0 GeForce GTX 105... Off | 00000000:01:00.0 Off | N/A | - $ | 32% 38C P0 N/A / 75W | 0MiB / 4039MiB | 0% Default | - $ +-------------------------------+----------------------+----------------------+ - $ - $ +-----------------------------------------------------------------------------+ - $ | Processes: GPU Memory | - $ | GPU PID Type Process name Usage | - $ |=============================================================================| - $ | No running processes found | - $ +-----------------------------------------------------------------------------+ - -In the above output, the CUDA version is **10.1**. - -If the above output is not generated, CUDA has not been installed. To install CUDA, see `Installing the CUDA driver `_. + +-----------------------------------------------------------------------------+ + | NVIDIA-SMI 470.82.01 Driver Version: 470.82.01 CUDA Version: 11.4 | + |-------------------------------+----------------------+----------------------+ + | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | + | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | + | | | MIG M. | + |===============================+======================+======================| + | 0 NVIDIA A100-PCI... On | 00000000:17:00.0 Off | 0 | + | N/A 34C P0 64W / 300W | 79927MiB / 80994MiB | 0% Default | + | | | Disabled | + +-------------------------------+----------------------+----------------------+ + | 1 NVIDIA A100-PCI... On | 00000000:CA:00.0 Off | 0 | + | N/A 35C P0 60W / 300W | 79927MiB / 80994MiB | 0% Default | + | | | Disabled | + +-------------------------------+----------------------+----------------------+ + + +-----------------------------------------------------------------------------+ + | Processes: GPU Memory | + | GPU PID Type Process name Usage | + |=============================================================================| + | No running processes found | + +-----------------------------------------------------------------------------+ + +In the above output, the CUDA version is **11.4**. +If the above output is not generated, CUDA has not been installed. To install CUDA, see :ref:`installing-the-cuda-driver`. Go back to :ref:`Setting Up Your Hosts` @@ -795,40 +800,46 @@ Installing the NVIDIA Docker2 Toolkit on an x86_64 Bit Processor on CentOS .. code-block:: postgres - $ docker run --runtime=nvidia --rm nvidia/cuda:10.1-base nvidia-smi + $ docker run --runtime=nvidia --rm nvidia/cuda:11.4.3-base-centos7 nvidia-smi The following is an example of the correct output: .. code-block:: postgres - $ docker run --runtime=nvidia --rm nvidia/cuda:10.1-base nvidia-smi - $ Unable to find image 'nvidia/cuda:10.1-base' locally - $ 10.1-base: Pulling from nvidia/cuda - $ d519e2592276: Pull complete - $ d22d2dfcfa9c: Pull complete - $ b3afe92c540b: Pull complete - $ 13a10df09dc1: Pull complete - $ 4f0bc36a7e1d: Pull complete - $ cd710321007d: Pull complete - $ Digest: sha256:635629544b2a2be3781246fdddc55cc1a7d8b352e2ef205ba6122b8404a52123 - $ Status: Downloaded newer image for nvidia/cuda:10.1-base - $ Sun Feb 14 13:27:58 2021 - $ +-----------------------------------------------------------------------------+ - $ | NVIDIA-SMI 418.87.00 Driver Version: 418.87.00 CUDA Version: 10.1 | - $ |-------------------------------+----------------------+----------------------+ - $ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | - $ | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | - $ |===============================+======================+======================| - $ | 0 GeForce GTX 105... Off | 00000000:01:00.0 Off | N/A | - $ | 32% 37C P0 N/A / 75W | 0MiB / 4039MiB | 0% Default | - $ +-------------------------------+----------------------+----------------------+ - $ - $ +-----------------------------------------------------------------------------+ - $ | Processes: GPU Memory | - $ | GPU PID Type Process name Usage | - $ |=============================================================================| - $ | No running processes found | - $ +-----------------------------------------------------------------------------+ + docker run --runtime=nvidia --rm nvidia/cuda:11.4.3-base-centos7 nvidia-smi + Unable to find image 'nvidia/cuda:11.4.3-base-centos7' locally + 11.4.3-base-centos7: Pulling from nvidia/cuda + d519e2592276: Pull complete + d22d2dfcfa9c: Pull complete + b3afe92c540b: Pull complete + 13a10df09dc1: Pull complete + 4f0bc36a7e1d: Pull complete + cd710321007d: Pull complete + Digest: sha256:635629544b2a2be3781246fdddc55cc1a7d8b352e2ef205ba6122b8404a52123 + Status: Downloaded newer image for nvidia/cuda:11.4.3-base-centos7 + Sun Feb 14 13:27:58 2021 + +-----------------------------------------------------------------------------+ + | NVIDIA-SMI 470.82.01 Driver Version: 470.82.01 CUDA Version: 11.4 | + |-------------------------------+----------------------+----------------------+ + | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | + | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | + | | | MIG M. | + |===============================+======================+======================| + | 0 NVIDIA A100-PCI... On | 00000000:17:00.0 Off | 0 | + | N/A 34C P0 64W / 300W | 79927MiB / 80994MiB | 0% Default | + | | | Disabled | + +-------------------------------+----------------------+----------------------+ + | 1 NVIDIA A100-PCI... On | 00000000:CA:00.0 Off | 0 | + | N/A 35C P0 60W / 300W | 79927MiB / 80994MiB | 0% Default | + | | | Disabled | + +-------------------------------+----------------------+----------------------+ + + +-----------------------------------------------------------------------------+ + | Processes: GPU Memory | + | GPU PID Type Process name Usage | + |=============================================================================| + | No running processes found | + +-----------------------------------------------------------------------------+ For more information on installing the NVIDIA Docker2 Toolkit on an x86_64 Bit Processor on CentOS, see `NVIDIA Docker Installation - CentOS distributions `_ diff --git a/installation_guides/running_sqream_in_a_docker_container.rst b/installation_guides/running_sqream_in_a_docker_container.rst index e85eac925..dd8d07e50 100644 --- a/installation_guides/running_sqream_in_a_docker_container.rst +++ b/installation_guides/running_sqream_in_a_docker_container.rst @@ -248,7 +248,7 @@ Installing the Nvidia CUDA Driver nvidia-smi Wed Oct 30 14:05:42 2019 +-----------------------------------------------------------------------------+ - | NVIDIA-SMI 418.87.00 Driver Version: 418.87.00 CUDA Version: 10.1 | + | NVIDIA-SMI 470.82.01 Driver Version: 470.82.01 CUDA Version: 11.4 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | @@ -267,7 +267,7 @@ Installing the Nvidia CUDA Driver | No running processes found | +-----------------------------------------------------------------------------+ -#. Verify that the installed CUDA version shown in the output above is ``10.1``. +#. Verify that the installed CUDA version shown in the output above is ``11.4``. :: @@ -276,25 +276,25 @@ Installing the Nvidia CUDA Driver :: - 1. If CUDA version 10.1 has already been installed, skip to Docktime Runtime (Community Edition). + 1. If CUDA version 11.4 has already been installed, skip to Docktime Runtime (Community Edition). :: - 2. If CUDA version 10.1 has not been installed yet, continue with Step 7 below. + 2. If CUDA version 11.4 has not been installed yet, continue with Step 7 below. #. Do one of the following: - * Install :ref:`CUDA Driver version 10.1 for x86_64 `. + * Install :ref:`CUDA Driver version 11.4 for x86_64 `. :: * Install :ref:`CUDA driver version 10.1 for IBM Power9 `. -.. _CUDA_10.1_x8664: +.. _CUDA_11.4_x8664: -Installing the CUDA Driver Version 10.1 for x86_64 +Installing the CUDA Driver Version 11.4 for x86_64 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -**To install the CUDA driver version 10.1 for x86_64:** +**To install the CUDA driver version 11.4 for x86_64:** 1. Make the following target platform selections: @@ -314,7 +314,6 @@ For installer type, SQream recommends selecting **runfile (local)**. The availab wget http://developer.download.nvidia.com/compute/cuda/10.1/Prod/local_installers/cuda-repo-rhel7-10-1-local-10.1.243-418.87.00-1.0-1.x86_64.rpm - 3. Install the base installer for Linux CentOS 7 x86_64 by running the following commands: .. code-block:: @@ -353,7 +352,7 @@ For installer type, SQream recommends selecting **runfile (local)**. The availab nvidia-smi Wed Oct 30 14:05:42 2019 +-----------------------------------------------------------------------------+ - | NVIDIA-SMI 418.87.00 Driver Version: 418.87.00 CUDA Version: 10.1 | + | NVIDIA-SMI 470.82.01 Driver Version: 470.82.01 CUDA Version: 11.4 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | @@ -623,7 +622,7 @@ Installing the NVIDIA Docker2 Toolkit on a CentOS Operating System .. code-block:: - $ docker run --runtime=nvidia --rm nvidia/cuda:10.1-base nvidia-smi + $ docker run --runtime=nvidia --rm nvidia/cuda:11.4.3-base-centos7 nvidia-smi For more information on installing the NVIDIA Docker2 Toolkit on a CentOS operating system, see :ref:`Installing the NVIDIA Docker2 Toolkit on a CentOS operating system ` @@ -675,7 +674,7 @@ Installing the NVIDIA Docker2 Toolkit on an Ubuntu Operating System .. code-block:: - $ docker run --runtime=nvidia --rm nvidia/cuda:10.1-base nvidia-smi + $ docker run --runtime=nvidia --rm nvidia/cuda:11.4.3-base-centos7 nvidia-smi For more information on installing the NVIDIA Docker2 Toolkit on a CentOS operating system, see :ref:`Installing the NVIDIA Docker2 Toolkit on an Ubuntu operating system ` @@ -1063,7 +1062,7 @@ The following is an example of the correct output: METADATA_PORT=3105 PICKER_PORT=3108 NUM_OF_GPUS=2 - CUDA_VERSION=10.1 + CUDA_VERSION=11.4 NVIDIA_SMI_PATH=/usr/bin/nvidia-smi DOCKER_PATH=/usr/bin/docker NVIDIA_DRIVER=418 From e42dc04cb2778fb9be4caa4060a3cf4fb492e2d9 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 4 Aug 2022 22:30:17 +0300 Subject: [PATCH 202/316] Update healer_max_inactivity_hours.rst --- configuration_guides/healer_max_inactivity_hours.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configuration_guides/healer_max_inactivity_hours.rst b/configuration_guides/healer_max_inactivity_hours.rst index d05d46014..56ddb78fc 100644 --- a/configuration_guides/healer_max_inactivity_hours.rst +++ b/configuration_guides/healer_max_inactivity_hours.rst @@ -1,7 +1,7 @@ .. _healer_max_inactivity_hours: ************************* -Query Healer +Configuring the Query Healer ************************* The ``healerMaxInactivityHours`` flag is used for defining the threshold for creating a log recording a slow statement. The log includes information about the log memory, CPU and GPU. From 888673e4502ed3fccfc117c61d308cbf05f0df0b Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 4 Aug 2022 22:49:09 +0300 Subject: [PATCH 203/316] Added Graceful Shutdown Flag --- configuration_guides/admin_regular_flags.rst | 3 ++- configuration_guides/graceful_shutdown.rst | 22 ++++++++++++++++++ .../utility_commands/shutdown_server.rst | 12 +++++----- .../getting_started_sqream.rst | 2 -- sqream_studio_5.4.6/viewing_logs.rst | 23 +------------------ 5 files changed, 31 insertions(+), 31 deletions(-) create mode 100644 configuration_guides/graceful_shutdown.rst diff --git a/configuration_guides/admin_regular_flags.rst b/configuration_guides/admin_regular_flags.rst index 064fc4b1a..133641765 100644 --- a/configuration_guides/admin_regular_flags.rst +++ b/configuration_guides/admin_regular_flags.rst @@ -3,7 +3,7 @@ ************************* Regular Administration Flags ************************* -The **Regular Administration Flags** page describes **Regular** modification type flags, which can be modified by administrators on a session and cluster basis using the ``ALTER SYSTEM SET`` command: +The **Regular Administration Flags** page describes **Regular** modification type flags, which can be modified by administrators on a session and cluster basis using the ``ALTER SYSTEM SET`` command: * `Setting Bin Size `_ * `Setting CUDA Memory `_ @@ -12,6 +12,7 @@ The **Regular Administration Flags** page describes **Regular** modification typ * `Reducing CPU Hashtable Sizes `_ * `Setting Chunk Size for Copying from CPU to GPU `_ * `Indicating GPU Synchronicity `_ +* `Setting the Graceful Server Shutdown `_ * `Enabling Modification of R&D Flags `_ * `Checking for Post-Production CUDA Errors `_ * `Enabling Modification of clientLogger_debug File `_ diff --git a/configuration_guides/graceful_shutdown.rst b/configuration_guides/graceful_shutdown.rst new file mode 100644 index 000000000..8b4f4b55c --- /dev/null +++ b/configuration_guides/graceful_shutdown.rst @@ -0,0 +1,22 @@ +.. _graceful_shutdown: + +************************* +Setting the Graceful Server Shutdown +************************* +The ``defaultGracefulShutdownTimeoutMinutes`` flag is used for setting the amount of time to pass before SQream performs a graceful server shutdown. + +The following describes the ``defaultGracefulShutdownTimeoutMinutes`` flag: + +* **Data type** - size_t +* **Default value** - ``5`` +* **Allowed values** - 1-4000000000 + +For more information, see :ref:`shutdown_server`. + +For related flags, see the folowing: + +* :ref:`is_healer_on` + + :: + +* :ref:`healer_max_inactivity_hours` \ No newline at end of file diff --git a/reference/sql/sql_statements/utility_commands/shutdown_server.rst b/reference/sql/sql_statements/utility_commands/shutdown_server.rst index 334281929..b38834d7e 100644 --- a/reference/sql/sql_statements/utility_commands/shutdown_server.rst +++ b/reference/sql/sql_statements/utility_commands/shutdown_server.rst @@ -69,16 +69,16 @@ The following table shows the ``shutdown_server`` parameters: * - Parameter - Description - - Example - - Default + - Example + - Default * - ``is_graceful`` - Determines the method used to shut down the server. - - Selecting ``false`` shuts down the server while queries are running. Selecting ``true`` uses the graceful shutdown method. - - ``false`` + - Selecting ``false`` shuts down the server while queries are running. Selecting ``true`` uses the graceful shutdown method. + - ``false`` * - ``timeout`` - Sets the maximum amount of minutes for the graceful shutdown method to run before the server is shut down using the standard method. - - ``30`` - - Five minutes. + - ``30`` + - Five minutes. .. note:: Setting ``is_graceful`` to ``false`` and defining the ``timeout`` value shuts the server down mid-query after the defined time. diff --git a/sqream_studio_5.4.6/getting_started_sqream.rst b/sqream_studio_5.4.6/getting_started_sqream.rst index 10542277e..ea95f0c41 100644 --- a/sqream_studio_5.4.6/getting_started_sqream.rst +++ b/sqream_studio_5.4.6/getting_started_sqream.rst @@ -45,8 +45,6 @@ From here you can navigate between the main areas of the Studio: - Lets you view usage logs. * - :ref:`Roles` - Lets you create users and manage user permissions. - * - :ref:`Configuration` - - Lets you configure your instance of SQream. By clicking the user icon, you can also use it for logging out and viewing the following: diff --git a/sqream_studio_5.4.6/viewing_logs.rst b/sqream_studio_5.4.6/viewing_logs.rst index 99afde3d2..4b4654c4a 100644 --- a/sqream_studio_5.4.6/viewing_logs.rst +++ b/sqream_studio_5.4.6/viewing_logs.rst @@ -101,25 +101,4 @@ In the Systems table, you can click on the **Timestamp** and **Log type** items :ref:`Back to Viewing Logs` -.. _log_lines_5.4.6: - -Viewing All Log Lines ----------- -**Comment** - *Has this tab been removed from the GUI?* - -The **LOG LINES** tab is used for viewing the total amount of log lines in a table. From here users can view a more granular breakdown of log information collected by Studio. The other tabs (QUERIES, SESSIONS, and SYSTEM) show a filtered form of the raw log lines. For example, the QUERIES tab shows an aggregation of several log lines. - -From here you can see and sort by the following: - -* Timestamp -* Message level -* Worker hostname -* Worker port -* Connection ID -* Database name -* User name -* Statement ID - -In the **LOG LINES** table, you can click on any of the items to set them as your filters. - -:ref:`Back to Viewing Logs` \ No newline at end of file +.. _log_lines_5.4.6: \ No newline at end of file From bb28843d0130eb9553d8142fff5bc95bc182629e Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 4 Aug 2022 22:57:05 +0300 Subject: [PATCH 204/316] Update shutdown_server.rst --- .../sql/sql_statements/utility_commands/shutdown_server.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/reference/sql/sql_statements/utility_commands/shutdown_server.rst b/reference/sql/sql_statements/utility_commands/shutdown_server.rst index b38834d7e..7fa1571b5 100644 --- a/reference/sql/sql_statements/utility_commands/shutdown_server.rst +++ b/reference/sql/sql_statements/utility_commands/shutdown_server.rst @@ -88,9 +88,7 @@ Note that you set the timeout value using the ``defaultGracefulShutdownTimeoutMi For more information, see :ref:`graceful_shutdown`. -**Comment** - *I have not yet created the ``graceful_shutdown`` configuration flag. I need to know what category it belongs in before doing so.* - -Like shutdown_server() graceful shutdown will stop any query currently running on the server. +As with the ``shutdown_server`` command, the **graceful server shutdown** stops all queries currently running on your server. Permissions ============= From 50944519ccd025eb3662df831fab61e76a24d57c Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Thu, 4 Aug 2022 23:04:17 +0300 Subject: [PATCH 205/316] Corrected the links --- configuration_guides/admin_regular_flags.rst | 50 +++++++++---------- .../generic_regular_flags.rst | 26 +++++----- configuration_guides/generic_worker_flags.rst | 2 +- 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/configuration_guides/admin_regular_flags.rst b/configuration_guides/admin_regular_flags.rst index 133641765..902ff224b 100644 --- a/configuration_guides/admin_regular_flags.rst +++ b/configuration_guides/admin_regular_flags.rst @@ -5,28 +5,28 @@ Regular Administration Flags ************************* The **Regular Administration Flags** page describes **Regular** modification type flags, which can be modified by administrators on a session and cluster basis using the ``ALTER SYSTEM SET`` command: -* `Setting Bin Size `_ -* `Setting CUDA Memory `_ -* `Limiting Runtime to Utility Functions `_ -* `Enabling High Bin Control Granularity `_ -* `Reducing CPU Hashtable Sizes `_ -* `Setting Chunk Size for Copying from CPU to GPU `_ -* `Indicating GPU Synchronicity `_ -* `Setting the Graceful Server Shutdown `_ -* `Enabling Modification of R&D Flags `_ -* `Checking for Post-Production CUDA Errors `_ -* `Enabling Modification of clientLogger_debug File `_ -* `Activating the NVidia Profiler Markers `_ -* `Appending String at End of Log Lines `_ -* `Monitoring and Printing Pinned Allocation Reports `_ -* `Increasing Chunk Size to Reduce Query Speed `_ -* `Adding Rechunker before Expensing Chunk Producer `_ -* `Setting the Buffer Size `_ -* `Setting Memory Used to Abort Server `_ -* `Splitting Large Reads for Concurrent Execution `_ -* `Setting Worker Amount to Handle Concurrent Reads `_ -* `Setting Implicit Casts in ORC Files `_ -* `Setting Timeout Limit for Locking Objects before Executing Statements `_ -* `Interpreting Decimal Literals as Double Instead of Numeric `_ -* `Interpreting VARCHAR as TEXT `_ -* `VARCHAR Identifiers `_ +* `Setting Bin Size `_ +* `Setting CUDA Memory `_ +* `Limiting Runtime to Utility Functions `_ +* `Enabling High Bin Control Granularity `_ +* `Reducing CPU Hashtable Sizes `_ +* `Setting Chunk Size for Copying from CPU to GPU `_ +* `Indicating GPU Synchronicity `_ +* `Setting the Graceful Server Shutdown `_ +* `Enabling Modification of R&D Flags `_ +* `Checking for Post-Production CUDA Errors `_ +* `Enabling Modification of clientLogger_debug File `_ +* `Activating the NVidia Profiler Markers `_ +* `Appending String at End of Log Lines `_ +* `Monitoring and Printing Pinned Allocation Reports `_ +* `Increasing Chunk Size to Reduce Query Speed `_ +* `Adding Rechunker before Expensing Chunk Producer `_ +* `Setting the Buffer Size `_ +* `Setting Memory Used to Abort Server `_ +* `Splitting Large Reads for Concurrent Execution `_ +* `Setting Worker Amount to Handle Concurrent Reads `_ +* `Setting Implicit Casts in ORC Files `_ +* `Setting Timeout Limit for Locking Objects before Executing Statements `_ +* `Interpreting Decimal Literals as Double Instead of Numeric `_ +* `Interpreting VARCHAR as TEXT `_ +* `VARCHAR Identifiers `_ diff --git a/configuration_guides/generic_regular_flags.rst b/configuration_guides/generic_regular_flags.rst index 83afa9e8f..34ff6850c 100644 --- a/configuration_guides/generic_regular_flags.rst +++ b/configuration_guides/generic_regular_flags.rst @@ -6,16 +6,16 @@ Regular Generic Flags The **Regular Generic Flags** page describes **Regular** modification type flags, which can be modified by standard users on a session basis: -* `Flipping Join Order to Force Equijoins `_ -* `Determining Client Level `_ -* `Setting CPU to Compress Defined Columns `_ -* `Setting Query Memory Processing Limit `_ -* `Setting the Spool Memory `_ -* `Setting Cache Partitions `_ -* `Setting Cache Flushing `_ -* `Setting InMemory Spool Memory `_ -* `Setting Disk Spool Memory `_ -* `Setting Spool Saved File Directory Location `_ -* `Setting Data Stored Persistently on Cache `_ -* `Setting Persistent Spool Saved File Directory Location `_ -* `Setting Session Tag Name `_ \ No newline at end of file +* `Flipping Join Order to Force Equijoins `_ +* `Determining Client Level `_ +* `Setting CPU to Compress Defined Columns `_ +* `Setting Query Memory Processing Limit `_ +* `Setting the Spool Memory `_ +* `Setting Cache Partitions `_ +* `Setting Cache Flushing `_ +* `Setting InMemory Spool Memory `_ +* `Setting Disk Spool Memory `_ +* `Setting Spool Saved File Directory Location `_ +* `Setting Data Stored Persistently on Cache `_ +* `Setting Persistent Spool Saved File Directory Location `_ +* `Setting Session Tag Name `_ \ No newline at end of file diff --git a/configuration_guides/generic_worker_flags.rst b/configuration_guides/generic_worker_flags.rst index 59fb9ac7a..7ae2a0ee7 100644 --- a/configuration_guides/generic_worker_flags.rst +++ b/configuration_guides/generic_worker_flags.rst @@ -5,4 +5,4 @@ Worker Generic Flags ************************* The Worker Generic Flags** page describes **Worker** modification type flags, which can be modified by standard users on a session basis: - * `Persisting Your Cache Directory `_ \ No newline at end of file + * `Persisting Your Cache Directory `_ \ No newline at end of file From 98252ade3376b591bf3f37f95a988ab01113134b Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 8 Aug 2022 22:08:30 +0300 Subject: [PATCH 206/316] Removed enhancements to Update feature --- .../sql/sql_statements/dml_commands/update.rst | 16 ---------------- releases/2022.1.1.rst | 7 ------- releases/2022.1_index.rst | 3 --- 3 files changed, 26 deletions(-) diff --git a/reference/sql/sql_statements/dml_commands/update.rst b/reference/sql/sql_statements/dml_commands/update.rst index 6cc33f516..873cf6290 100644 --- a/reference/sql/sql_statements/dml_commands/update.rst +++ b/reference/sql/sql_statements/dml_commands/update.rst @@ -62,8 +62,6 @@ The following table describes the ``UPDATE`` parameters: - Specifies the column containing the data to be updated. * - ``additional_table_name`` - Specifies the column containing the data to be updated. - * - ``FROM`` |icon-new_2022.1.1| - - For making complex joins, specifies additional tables to be used in the WHERE condition. ``FROM`` is similar to the ``FROM`` clause in a ``DELETE`` statement. * - ``condition`` - Specifies the condition for updating the data. @@ -87,20 +85,6 @@ The following is an example of performing a simple update: UPDATE bands SET records_sold = records_sold + 1 WHERE name LIKE 'The %'; -Updating Tables that Contain Multi-Table Conditions ------------------ -The following shows an example of updating tables that contain multi-table conditions |icon-new_2022.1.1|: - -.. code-block:: postgres - - UPDATE bands - SET records_sold = records_sold + 1 - WHERE EXISTS ( - SELECT 1 FROM countries - WHERE countries.id=bands.country_id - AND country.name = 'Sweden' - ); - Triggering a Clean-Up ----------------- The following section shows an example of triggering a clean-up: diff --git a/releases/2022.1.1.rst b/releases/2022.1.1.rst index 517c11042..1421a82a6 100644 --- a/releases/2022.1.1.rst +++ b/releases/2022.1.1.rst @@ -14,7 +14,6 @@ Version Content The 2022.1.1 Release Notes describes the following: * Enhanced security features. -* New data manipulation command. * Additional data ingestion format. New Features @@ -25,12 +24,6 @@ The 2022.1.1 Release Notes include the following new features: :local: :depth: 1 -Update Feature -************ -The DML ``UPDATE`` statement has been enhanced to support running subqueries in the ``WHERE`` condition. - -For more information, see `UPDATE `_. - Password Security Compliance ************ In compliance with GDPR standards, SQream now requires a strong password policy when accessing the CLI or Studio. diff --git a/releases/2022.1_index.rst b/releases/2022.1_index.rst index 16a7d80ef..4018bedd1 100644 --- a/releases/2022.1_index.rst +++ b/releases/2022.1_index.rst @@ -35,9 +35,6 @@ The following enhancements were introduced in :ref:`August 2022 (2022.1.1) <2022 * - **Operational Guides** - :ref:`Password Security Compliance` - Integrated password security compliance measures when logging in to the CLI or Studio. - * - **Reference Guides** - - :ref:`update` - - The DML ``UPDATE`` statement has been enhanced to support running subqueries in the ``WHERE`` condition. July 2022 ================== From 99c9c020bdfb196ddb7fb55adbbd7d081ca6b6d9 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 9 Aug 2022 10:19:09 +0300 Subject: [PATCH 207/316] Prepared for 2022.1.1 Release Removed New for 2022.1 icons. Removed zlib compression. Removed compression from 2022.1.1 RN main page. Removed zlib and Update from 2022.1 RN main page. --- data_ingestion/avro.rst | 2 +- feature_guides/compression.rst | 4 ---- feature_guides/data_encryption.rst | 2 +- releases/2022.1.1.rst | 7 ------- releases/2022.1_index.rst | 5 +---- 5 files changed, 3 insertions(+), 17 deletions(-) diff --git a/data_ingestion/avro.rst b/data_ingestion/avro.rst index 753786376..b20e64d49 100644 --- a/data_ingestion/avro.rst +++ b/data_ingestion/avro.rst @@ -3,7 +3,7 @@ ************************** Inserting Data from Avro ************************** -The **Inserting Data from Avro** page |icon-new_2022.1| describes inserting data from Avro into SQream and includes the following: +The **Inserting Data from Avro** page describes inserting data from Avro into SQream and includes the following: .. |icon-new_2022.1| image:: /_static/images/new_2022.1.png :align: middle diff --git a/feature_guides/compression.rst b/feature_guides/compression.rst index ce5e922b6..4472c7ded 100644 --- a/feature_guides/compression.rst +++ b/feature_guides/compression.rst @@ -93,10 +93,6 @@ Compression strategies - Integer types - Optimized RLE + Delta type for built-in :ref:`identity columns`. - GPU - * - ``zlib`` |icon-new_dark_gray_2022.1.1.png| - - All types - - The **basic_zlib_compressor** and **basic_zlib_decompressor** compress and decompress data in the **ZLIB** format, using **DualUseFilters** for input and output. In general, compression filters are for output, and decompression filters for input. - - CPU .. _specifying_compressions: diff --git a/feature_guides/data_encryption.rst b/feature_guides/data_encryption.rst index 19aabb8e3..607d6c09a 100644 --- a/feature_guides/data_encryption.rst +++ b/feature_guides/data_encryption.rst @@ -3,7 +3,7 @@ *********************** Data Encryption *********************** -The **Data Encryption** page |icon-new_2022.1| describes the following: +The **Data Encryption** page describes the following: .. |icon-new_2022.1| image:: /_static/images/new_2022.1.png :align: middle diff --git a/releases/2022.1.1.rst b/releases/2022.1.1.rst index 1421a82a6..faec3add2 100644 --- a/releases/2022.1.1.rst +++ b/releases/2022.1.1.rst @@ -14,7 +14,6 @@ Version Content The 2022.1.1 Release Notes describes the following: * Enhanced security features. -* Additional data ingestion format. New Features ---------- @@ -30,12 +29,6 @@ In compliance with GDPR standards, SQream now requires a strong password policy For more information, see :ref:`access_control_password_policy`. -Compression -************ -SQream now supports the **zlib** compression format. - -For more information, see `Compression `_. - Known Issues --------- The following table lists the known issues for Version 2022.1.1: diff --git a/releases/2022.1_index.rst b/releases/2022.1_index.rst index 4018bedd1..eeb744d4e 100644 --- a/releases/2022.1_index.rst +++ b/releases/2022.1_index.rst @@ -29,9 +29,6 @@ The following enhancements were introduced in :ref:`August 2022 (2022.1.1) <2022 * - Topic - Feature - Description - * - **Feature Guides** - - :ref:`compression` - - SQream supports compressing and decompressing data in and from the **ZLIB** format. * - **Operational Guides** - :ref:`Password Security Compliance` - Integrated password security compliance measures when logging in to the CLI or Studio. @@ -54,5 +51,5 @@ The following enhancements were introduced in :ref:`July 2022 (2022.1) <2022.1>` - :ref:`data_encryption` - SQream has integrated data encryption mechanisms in accordance with General Data Protection Regulation (GDPR) standards. * - **Reference Guides** - - `UPDATE `_ + - `UPDATE `_ - The DML ``UPDATE`` statement has been introduced to support modifying the value of certain columns in existing rows. \ No newline at end of file From dfdcdea2f29f7c172ec4088ea2d0c7b57185967e Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 9 Aug 2022 11:14:00 +0300 Subject: [PATCH 208/316] Released 2022.1.1 --- operational_guides/access_control.rst | 2 +- releases/2022.1_index.rst | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/operational_guides/access_control.rst b/operational_guides/access_control.rst index d5d32394e..9d12ed712 100644 --- a/operational_guides/access_control.rst +++ b/operational_guides/access_control.rst @@ -8,8 +8,8 @@ Access Control :maxdepth: 1 :titlesonly: + access_control_password_policy access_control_overview access_control_managing_roles access_control_permissions - access_control_password_policy access_control_departmental_example \ No newline at end of file diff --git a/releases/2022.1_index.rst b/releases/2022.1_index.rst index eeb744d4e..284dc299f 100644 --- a/releases/2022.1_index.rst +++ b/releases/2022.1_index.rst @@ -45,11 +45,11 @@ The following enhancements were introduced in :ref:`July 2022 (2022.1) <2022.1>` - Feature - Description * - **Data Ingestion** - - :ref:`avro` + - `Inserting data from Avro `_ - SQream now supports ingesting data from Avro files. * - **Feature Guides** - - :ref:`data_encryption` + - `Data encryption `_ - SQream has integrated data encryption mechanisms in accordance with General Data Protection Regulation (GDPR) standards. * - **Reference Guides** - - `UPDATE `_ + - `UPDATE `_ - The DML ``UPDATE`` statement has been introduced to support modifying the value of certain columns in existing rows. \ No newline at end of file From e73416b9cd33d38f1bc71cd5eee16fa2a0e99711 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 9 Aug 2022 11:26:04 +0300 Subject: [PATCH 209/316] Corrected date in conf.py --- conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf.py b/conf.py index 95a622cd6..f8ee2ea90 100644 --- a/conf.py +++ b/conf.py @@ -26,7 +26,7 @@ # The full version, including alpha/beta/rc tags -release = '2021.2' +release = '2022.1.1' From c89c5bcf0ae213d56859b763352fec4b33798e68 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 9 Aug 2022 12:00:12 +0300 Subject: [PATCH 210/316] 2022.1.1 Removed New for 2022.1.1 icon (it doesn't look good). On main RN page, replaced ref syntax with absolute URL. --- configuration_guides/login_max_retries.rst | 2 +- operational_guides/access_control_password_policy.rst | 2 +- releases/2022.1.1.rst | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configuration_guides/login_max_retries.rst b/configuration_guides/login_max_retries.rst index af236c9c3..6938d990b 100644 --- a/configuration_guides/login_max_retries.rst +++ b/configuration_guides/login_max_retries.rst @@ -8,7 +8,7 @@ Adjusting Permitted Log-in Attempts :align: middle :width: 110 -The ``loginMaxRetries`` flag |icon-new_2022.1.1| sets the permitted log-in attempts. +The ``loginMaxRetries`` flag sets the permitted log-in attempts. The following describes the ``loginMaxRetries`` flag: diff --git a/operational_guides/access_control_password_policy.rst b/operational_guides/access_control_password_policy.rst index fc845ebc4..6f678dc10 100644 --- a/operational_guides/access_control_password_policy.rst +++ b/operational_guides/access_control_password_policy.rst @@ -8,7 +8,7 @@ Password Security Compliance (New!) :align: middle :width: 110 -As part of our compliance with GDPR standards |icon-new_gray_2022.1.1| SQream relies on a strong password policy when accessing the CLI or Studio. +As part of our compliance with GDPR standards SQream relies on a strong password policy when accessing the CLI or Studio. The following requirements apply when creating a password: diff --git a/releases/2022.1.1.rst b/releases/2022.1.1.rst index faec3add2..c830b15b6 100644 --- a/releases/2022.1.1.rst +++ b/releases/2022.1.1.rst @@ -27,7 +27,7 @@ Password Security Compliance ************ In compliance with GDPR standards, SQream now requires a strong password policy when accessing the CLI or Studio. -For more information, see :ref:`access_control_password_policy`. +For more information, see `Access Control Password Policy `_. Known Issues --------- From 38d2cb5d0ab202a806f544e2cee9fefce2bf0fad Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 9 Aug 2022 16:07:50 +0300 Subject: [PATCH 211/316] Returned 2020.3.2 --- releases/2020.3.2.rst | 28 ++++++++++++++++++++++++++++ releases/2020.3_index.rst | 3 ++- 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 releases/2020.3.2.rst diff --git a/releases/2020.3.2.rst b/releases/2020.3.2.rst new file mode 100644 index 000000000..c97e2bd47 --- /dev/null +++ b/releases/2020.3.2.rst @@ -0,0 +1,28 @@ +.. _2020.3.2: + +************************** +What's new in 2020.3.2 +************************** + +SQream DB v2020.3.2 contains major performance improvements and some bug fixes. + +Performance Enhancements +========================= +* Metadata on Demand optimization resulting in reduced latency and improved overall performance + + +Known Issues & Limitations +================================ +* Bug with STDDEV_SAMP,STDDEV_POP and STDEV functions +* Window function query returns wrong results +* rank() in window function sometimes returns garbage +* Window function on null value could have bad result +* Window function lead() on varchar can have garbage results +* Performance degradation when using "groupby" or outer_join + +Upgrading to v2020.3.2 +======================== + +Versions are available for IBM POWER9, RedHat (CentOS) 7, Ubuntu 18.04, and other OSs via Docker. + +Contact your account manager to get the latest release of SQream DB. diff --git a/releases/2020.3_index.rst b/releases/2020.3_index.rst index b13340b52..a662cb48a 100644 --- a/releases/2020.3_index.rst +++ b/releases/2020.3_index.rst @@ -3,7 +3,7 @@ ************************** Release Notes 2020.3 ************************** -The 2020.3 Release Notes describe the following releases: +The 2020.3 release notes describe the following releases: .. contents:: :local: @@ -14,5 +14,6 @@ The 2020.3 Release Notes describe the following releases: :glob: 2020.3.2.1 + 2020.3.2 2020.3.1 2020.3 \ No newline at end of file From a4f8bc94f4e9bd8c56e8cc8e1611c540a6e11a1f Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 9 Aug 2022 16:33:12 +0300 Subject: [PATCH 212/316] Divided bugs --- releases/2021.2.1.24.rst | 42 ++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/releases/2021.2.1.24.rst b/releases/2021.2.1.24.rst index 1d5407d89..aa60c701c 100644 --- a/releases/2021.2.1.24.rst +++ b/releases/2021.2.1.24.rst @@ -15,7 +15,7 @@ The 2021.2.1.24 Release Notes includes a query maintenance feature. New Features ---------- -The 2021.2.1.24 Release Notes include the following new features: +The 2021.2.1.24 Release Notes include the following new features: .. contents:: :local: @@ -27,35 +27,49 @@ The new **Query Healer** feature periodically examines the progress of running s For more information, see `Query Healer `_. -Known Issues +Resolved Issues --------- -The following table lists the known issues for Version 2021.2.1.24: +The following table lists the resolved issues for Version 2021.2.1.24: +-------------+------------------------------------------------------------------------------------------------------------------------------------+ | **SQ No.** | **Description** | +=============+====================================================================================================================================+ -| SQ-10071 | An error occurred on existing subqueries with ``TEXT`` and ``VARCHAR`` equality conditions. | -+-------------+------------------------------------------------------------------------------------------------------------------------------------+ | SQ-10606 | Queries were getting stuck in the queue for a prolonged time. | +-------------+------------------------------------------------------------------------------------------------------------------------------------+ | SQ-10691 | The DB schema identifier was causing an error when running queries from joins suite. | +-------------+------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10902 | Inserting a null value into non-null column was causing SQream to crash. | -+-------------+------------------------------------------------------------------------------------------------------------------------------------+ | SQ-10918 | The Workload Manager was only assigning jobs sequentially, delaying user SQLs assigned to workers running very large jobs. | +-------------+------------------------------------------------------------------------------------------------------------------------------------+ | SQ-10955 | Metadata filters were not being applied when users filtered by nullable dates using ``dateadd`` | +-------------+------------------------------------------------------------------------------------------------------------------------------------+ + +Known Issues +--------- +The following table lists the known issues for Version 2021.2.1.24: + ++-------------+------------------------------------------------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+====================================================================================================================================+ +| SQ-10071 | An error occurred on existing subqueries with ``TEXT`` and ``VARCHAR`` equality conditions. | ++-------------+------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-10902 | Inserting a null value into non-null column was causing SQream to crash. | ++-------------+------------------------------------------------------------------------------------------------------------------------------------+ | SQ-11088 | Specific workers caused low performance during compilation. | +-------------+------------------------------------------------------------------------------------------------------------------------------------+ -Resolved Issues ---------- -The Resolved Issues section is not relevant for Version 2021.2.1.24. +Operations and Configuration Changes +-------- +The following configuration flags were added: -Operational and Configuration Changes -------- -No relevant operational or configuration changes were made. + * :ref:`is_healer_on` + + :: + + * :ref:`healer_max_inactivity_hours` + + :: + + * :ref:`login_max_retries` Naming Changes ------- @@ -74,4 +88,4 @@ The End of Support section is not relevant to Version 2021.2.1.24. :glob: :hidden: - 2021.2.1.24 \ No newline at end of file + 2021.2.1.24 From 2629fc755633effc64451c9729b6ab55a9ebee67 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 9 Aug 2022 18:02:46 +0300 Subject: [PATCH 213/316] Reverted to 2022.1 Will restore 2022.1.1 when new release date is decided. --- operational_guides/access_control.rst | 1 - .../access_control_password_policy.rst | 73 -------- releases/2022.1.1.rst | 113 ------------ releases/2022.1_index.rst | 162 +++++++++++++----- 4 files changed, 122 insertions(+), 227 deletions(-) delete mode 100644 operational_guides/access_control_password_policy.rst delete mode 100644 releases/2022.1.1.rst diff --git a/operational_guides/access_control.rst b/operational_guides/access_control.rst index 9d12ed712..88a14d71b 100644 --- a/operational_guides/access_control.rst +++ b/operational_guides/access_control.rst @@ -8,7 +8,6 @@ Access Control :maxdepth: 1 :titlesonly: - access_control_password_policy access_control_overview access_control_managing_roles access_control_permissions diff --git a/operational_guides/access_control_password_policy.rst b/operational_guides/access_control_password_policy.rst deleted file mode 100644 index 6f678dc10..000000000 --- a/operational_guides/access_control_password_policy.rst +++ /dev/null @@ -1,73 +0,0 @@ -.. _access_control_password_policy: - -************** -Password Security Compliance (New!) -************** - -.. |icon-new_gray_2022.1.1| image:: /_static/images/new_gray_2022.1.1.png - :align: middle - :width: 110 - -As part of our compliance with GDPR standards SQream relies on a strong password policy when accessing the CLI or Studio. - -The following requirements apply when creating a password: - -* At least eight characters long. - - :: - -* At least one numeric character. - - :: - -* Should not include a username. - - :: - -* Must include at least one special character, such as **?**, **!**, **$**, etc. - - :: - -* Mandatory upper and lowercase letters. - -The following is the syntax for creating a password: - -.. code-block:: console - - CREATE ROLE ; - GRANT LOGIN ; - GRANT PASSWORD <'password'> to ; - -The following is an example of creating a password: - -.. code-block:: console - - CREATE ROLE user_a ; - GRANT LOGIN to user_a ; - GRANT PASSWORD 'BBAu47?fqPL' to user_a ; - -Creating a password that does not comply with the above requirements generates the following error message: - -.. code-block:: console - - The password you attempt to create does not comply with SQream security requirements. Please follow the requirements below: - - * At least 8 characters long. - - * Must include both upper and lower case letters. - - * Must include at least one numeric character. - - * Must not include your username. - - * Must include at least one “special” character (?, !, $, etc.). - -.. note:: When a new user is created in Studio, a message is displayed to help you determine what the constraints are. - -Unsuccessfully attempting to log in three times displays the following message: - -.. code-block:: console - - The user is locked. please contact your system administrator to reset the password and regain access functionality. - -For more information, see :ref:`login_max_retries`. \ No newline at end of file diff --git a/releases/2022.1.1.rst b/releases/2022.1.1.rst deleted file mode 100644 index c830b15b6..000000000 --- a/releases/2022.1.1.rst +++ /dev/null @@ -1,113 +0,0 @@ -.. _2022.1.1: - -************************** -Release Notes 2022.1.1 -************************** -The 2022.1.1 release notes were released on 7/19/2022 and describe the following: - -.. contents:: - :local: - :depth: 1 - -Version Content ----------- -The 2022.1.1 Release Notes describes the following: - -* Enhanced security features. - -New Features ----------- -The 2022.1.1 Release Notes include the following new features: - -.. contents:: - :local: - :depth: 1 - -Password Security Compliance -************ -In compliance with GDPR standards, SQream now requires a strong password policy when accessing the CLI or Studio. - -For more information, see `Access Control Password Policy `_. - -Known Issues ---------- -The following table lists the known issues for Version 2022.1.1: - -+-------------+------------------------------------------------------------------------------------------------+ -| **SQ No.** | **Description** | -+=============+================================================================================================+ -| SQ-6419 | An internal compiler error occurred when casting Numeric literals in an aggregation function. | -+-------------+------------------------------------------------------------------------------------------------+ - -Resolved Issues ---------- -The following table lists the issues that were resolved in Version 2022.1.1: - -+-------------+----------------------------------------------------------------------------------------+ -| **SQ No.** | **Description** | -+=============+========================================================================================+ -| SQ-10873 | Inserting 100K bytes into a text column resulted in an unclear error message. | -+-------------+----------------------------------------------------------------------------------------+ -| SQ-10892 | An unclear message was displayed when users ran ``UPDATE`` on foreign tables. | -+-------------+----------------------------------------------------------------------------------------+ - -Operations and Configuration Changes --------- -The ``login_max_retries`` configuration flag is required for adjusting the permitted log-in attempts. - -For more information, see `Adjusting the Permitted Log-In Attempts `_. - -Naming Changes -------- -No relevant naming changes were made. - -Deprecated Features -------- -No features were deprecated for Version 2022.1.1. - -End of Support -------- -The End of Support section is not relevant to Version 2022.1.1. - -Upgrading to v2022.1.1 -------- -1. Generate a back-up of the metadata by running the following command: - - .. code-block:: console - - $ select backup_metadata('out_path'); - - .. tip:: SQream recommends storing the generated back-up locally in case needed. - - SQream runs the Garbage Collector and creates a clean backup tarball package. - -2. Shut down all SQream services. - - :: - -3. Extract the recently created back-up file. - - :: - -4. Replace your current metadata with the metadata you stored in the back-up file. - - :: - -5. Navigate to the new SQream package bin folder. - - :: - -6. Run the following command: - - .. code-block:: console - - $ ./upgrade_storage - - .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version `_ procedure. - -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2022.1.1 \ No newline at end of file diff --git a/releases/2022.1_index.rst b/releases/2022.1_index.rst index 284dc299f..3d1517371 100644 --- a/releases/2022.1_index.rst +++ b/releases/2022.1_index.rst @@ -1,55 +1,137 @@ -.. _2022.1_index: +.. _2022.1: ************************** Release Notes 2022.1 ************************** -The 2022.1 Release Notes describe the following releases: +The 2022.1 release notes were released on 7/19/2022 and describe the following: -.. toctree:: - :maxdepth: 1 - :glob: +.. contents:: + :local: + :depth: 1 + +Version Content +---------- +The 2022.1 Release Notes describes the following: - 2022.1.1 - 2022.1 +* Enhanced security features. +* New data manipulation command. +* Additional data ingestion format. -You can also use the following tables for a summary of the new features in Version 2022.1 according to month: +New Features +---------- +The 2022.1 Release Notes include the following new features: .. contents:: :local: :depth: 1 + +Data Encryption +************ +SQream now supports data encryption mechanisms in accordance with **General Data Protection Regulation (GDPR)** standards. + +Using the data encryption feature may lead to a maximum of a 10% increase in performance degradation. + +For more information, see `Data Encryption `_. + +Update Feature +************ +SQream now supports the DML **Update** feature, which is used for modifying the value of certain columns in existing rows. + +For more information, see `UPDATE `_. + +Avro Ingestion +************ +SQream now supports ingesting data from Avro files. + +For more information, see `Inserting Data from Avro `_. + +Known Issues +--------- +The following table lists the known issues for Version 2022.1: + ++-------------+-------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+===========================================================================================+ +| SQ-7732 | Reading numeric columns from an external Parquet file generated an error. | ++-------------+-------------------------------------------------------------------------------------------+ +| SQ-9889 | Running a query including Thai characters generated an internal runtime error. | ++-------------+-------------------------------------------------------------------------------------------+ +| SQ-10071 | Error on existing subqueries with TEXT and VARCHAR equality condition | ++-------------+-------------------------------------------------------------------------------------------+ +| SQ-10191 | The ``ALTER DEFAULT SCHEMA`` command was not functioning correctly. | ++-------------+-------------------------------------------------------------------------------------------+ +| SQ-10629 | Inserting data into a table significantly slowed down running queries. | ++-------------+-------------------------------------------------------------------------------------------+ +| SQ-10659 | Using a comment generated a compile error. | ++-------------+-------------------------------------------------------------------------------------------+ + +Resolved Issues +--------- +The following table lists the issues that were resolved in Version 2022.1: + ++-------------+-------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+===========================================================================================+ +| SQ-10111 | Reading numeric columns from an external Parquet file generated an error. | ++-------------+-------------------------------------------------------------------------------------------+ + +Operations and Configuration Changes +-------- +No relevant operations and configuration changes were made. + +Naming Changes +------- +No relevant naming changes were made. -August 2022 -================== -The following enhancements were introduced in :ref:`August 2022 (2022.1.1) <2022.1.1>`: +Deprecated Features +------- +In SQream version 2022.1 the ``VARCHAR`` data type has been deprecated and replaced with ``TEXT``. SQream will maintain ``VARCHAR`` in all previous versions until completing the migration to ``TEXT``, at which point it will be deprecated in all earlier versions. SQream also provides an automated and secure tool to facilitate and simplify migration from ``VARCHAR`` to ``TEXT``. -.. list-table:: - :widths: 24 25 60 - :header-rows: 1 +If you are using an earlier version of SQream, see the `Using Legacy String Literals `_ configuration flag. + +End of Support +------- +The End of Support section is not relevant to Version 2022.1. + +Upgrading to v2022.1 +------- +1. Generate a back-up of the metadata by running the following command: + + .. code-block:: console + + $ select backup_metadata('out_path'); + + .. tip:: SQream recommends storing the generated back-up locally in case needed. - * - Topic - - Feature - - Description - * - **Operational Guides** - - :ref:`Password Security Compliance` - - Integrated password security compliance measures when logging in to the CLI or Studio. - -July 2022 -================== -The following enhancements were introduced in :ref:`July 2022 (2022.1) <2022.1>`: - -.. list-table:: - :widths: 20 20 60 - :header-rows: 1 + SQream runs the Garbage Collector and creates a clean backup tarball package. - * - Topic - - Feature - - Description - * - **Data Ingestion** - - `Inserting data from Avro `_ - - SQream now supports ingesting data from Avro files. - * - **Feature Guides** - - `Data encryption `_ - - SQream has integrated data encryption mechanisms in accordance with General Data Protection Regulation (GDPR) standards. - * - **Reference Guides** - - `UPDATE `_ - - The DML ``UPDATE`` statement has been introduced to support modifying the value of certain columns in existing rows. \ No newline at end of file +2. Shut down all SQream services. + + :: + +3. Extract the recently created back-up file. + + :: + +4. Replace your current metadata with the metadata you stored in the back-up file. + + :: + +5. Navigate to the new SQream package bin folder. + + :: + +6. Run the following command: + + .. code-block:: console + + $ ./upgrade_storage + + .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version `_ procedure. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2022.1 \ No newline at end of file From b833913c876a86b849819bebe068ea0b4e79a7a4 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Tue, 9 Aug 2022 18:06:04 +0300 Subject: [PATCH 214/316] Removed login_max_retries Will restore when new release date is announced. --- configuration_guides/admin_worker_flags.rst | 3 +-- configuration_guides/login_max_retries.rst | 16 ---------------- releases/2021.2.1.24.rst | 4 ---- 3 files changed, 1 insertion(+), 22 deletions(-) delete mode 100644 configuration_guides/login_max_retries.rst diff --git a/configuration_guides/admin_worker_flags.rst b/configuration_guides/admin_worker_flags.rst index edbc71465..b41a6a5cd 100644 --- a/configuration_guides/admin_worker_flags.rst +++ b/configuration_guides/admin_worker_flags.rst @@ -16,5 +16,4 @@ The **Worker Administration Flags** page describes **Worker** modification type * `Setting Port Used for Metadata Server Connection `_ * `Assigning Local Network IP `_ * `Enabling the Query Healer `_ -* `Configuring the Query Healer `_ -* `Adjusting the Permitted Log-In Attempts `_ |icon-new_gray_2022.1.1| \ No newline at end of file +* `Configuring the Query Healer `_ \ No newline at end of file diff --git a/configuration_guides/login_max_retries.rst b/configuration_guides/login_max_retries.rst deleted file mode 100644 index 6938d990b..000000000 --- a/configuration_guides/login_max_retries.rst +++ /dev/null @@ -1,16 +0,0 @@ -.. _login_max_retries: - -************************* -Adjusting Permitted Log-in Attempts -************************* - -.. |icon-new_2022.1.1| image:: /_static/images/new_2022.1.1.png - :align: middle - :width: 110 - -The ``loginMaxRetries`` flag sets the permitted log-in attempts. - -The following describes the ``loginMaxRetries`` flag: - -* **Data type** - size_t -* **Default value** - ``5`` \ No newline at end of file diff --git a/releases/2021.2.1.24.rst b/releases/2021.2.1.24.rst index aa60c701c..a89244934 100644 --- a/releases/2021.2.1.24.rst +++ b/releases/2021.2.1.24.rst @@ -67,10 +67,6 @@ The following configuration flags were added: * :ref:`healer_max_inactivity_hours` - :: - - * :ref:`login_max_retries` - Naming Changes ------- No relevant naming changes were made. From 220d97f436c797b23357d02da477336e0753a83a Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Wed, 10 Aug 2022 11:26:32 +0300 Subject: [PATCH 215/316] Started creating 2022.1.2 --- conf.py | 2 +- configuration_guides/admin_worker_flags.rst | 13 +- configuration_guides/login_max_retries.rst | 11 ++ operational_guides/access_control.rst | 1 + .../access_control_password_policy.rst | 42 ++++++ releases/2022.1.1.rst | 113 +++++++++++++++ releases/2022.1.2.rst | 129 ++++++++++++++++++ releases/2022.1_index.rst | 129 +----------------- 8 files changed, 309 insertions(+), 131 deletions(-) create mode 100644 configuration_guides/login_max_retries.rst create mode 100644 operational_guides/access_control_password_policy.rst create mode 100644 releases/2022.1.1.rst create mode 100644 releases/2022.1.2.rst diff --git a/conf.py b/conf.py index f8ee2ea90..4151da1c4 100644 --- a/conf.py +++ b/conf.py @@ -26,7 +26,7 @@ # The full version, including alpha/beta/rc tags -release = '2022.1.1' +release = '2022.1.2' diff --git a/configuration_guides/admin_worker_flags.rst b/configuration_guides/admin_worker_flags.rst index b41a6a5cd..130131b57 100644 --- a/configuration_guides/admin_worker_flags.rst +++ b/configuration_guides/admin_worker_flags.rst @@ -11,9 +11,10 @@ Worker Administration Flags The **Worker Administration Flags** page describes **Worker** modification type flags, which can be modified by administrators on a session and cluster basis using the ``ALTER SYSTEM SET`` command: -* `Setting Total Device Memory Usage in SQream Instance `_ -* `Enabling Manually Setting Reported IP `_ -* `Setting Port Used for Metadata Server Connection `_ -* `Assigning Local Network IP `_ -* `Enabling the Query Healer `_ -* `Configuring the Query Healer `_ \ No newline at end of file +* `Setting Total Device Memory Usage in SQream Instance `_ +* `Enabling Manually Setting Reported IP `_ +* `Setting Port Used for Metadata Server Connection `_ +* `Assigning Local Network IP `_ +* `Enabling the Query Healer `_ +* `Configuring the Query Healer `_ +* `Adjusting Permitted Log-in Attempts `_ \ No newline at end of file diff --git a/configuration_guides/login_max_retries.rst b/configuration_guides/login_max_retries.rst new file mode 100644 index 000000000..bf3ae6d40 --- /dev/null +++ b/configuration_guides/login_max_retries.rst @@ -0,0 +1,11 @@ +.. _login_max_retries: + +************************* +Adjusting Permitted Log-in Attempts +************************* +The ``loginMaxRetries`` flag sets the permitted log-in attempts. + +The following describes the ``loginMaxRetries`` flag: + +* **Data type** - size_t +* **Default value** - ``5`` \ No newline at end of file diff --git a/operational_guides/access_control.rst b/operational_guides/access_control.rst index 88a14d71b..8aba611eb 100644 --- a/operational_guides/access_control.rst +++ b/operational_guides/access_control.rst @@ -8,6 +8,7 @@ Access Control :maxdepth: 1 :titlesonly: + access_control_password_policy access_control_overview access_control_managing_roles access_control_permissions diff --git a/operational_guides/access_control_password_policy.rst b/operational_guides/access_control_password_policy.rst new file mode 100644 index 000000000..10a4f697f --- /dev/null +++ b/operational_guides/access_control_password_policy.rst @@ -0,0 +1,42 @@ +.. _access_control_password_policy: + +************** +Password Policy +************** +As part of our compliance with GDPR standards SQream relies on a strong password policy when accessing the CLI or Studio, with the following requirements: + +* At least eight characters long. + + :: + +* Mandatory upper and lowercase letters. + + :: + +* At least one numeric character. + + :: + +* May not include a username. + + :: + +* Must include at least one special character, such as **?**, **!**, **$**, etc. + +You can create a password through the Studio graphic interface or through the CLI, as in the following example command: + +.. code-block:: console + + CREATE ROLE user_a ; + GRANT LOGIN to user_a ; + GRANT PASSWORD 'BBAu47?fqPL' to user_a ; + +Creating a password that does not comply with the above requirements generates an error message with a request to modify it. + +Unsuccessfully attempting to log in three times displays the following message: + +.. code-block:: console + + The user is locked. please contact your system administrator to reset the password and regain access functionality. + +For more information, see :ref:`login_max_retries`. diff --git a/releases/2022.1.1.rst b/releases/2022.1.1.rst new file mode 100644 index 000000000..faec3add2 --- /dev/null +++ b/releases/2022.1.1.rst @@ -0,0 +1,113 @@ +.. _2022.1.1: + +************************** +Release Notes 2022.1.1 +************************** +The 2022.1.1 release notes were released on 7/19/2022 and describe the following: + +.. contents:: + :local: + :depth: 1 + +Version Content +---------- +The 2022.1.1 Release Notes describes the following: + +* Enhanced security features. + +New Features +---------- +The 2022.1.1 Release Notes include the following new features: + +.. contents:: + :local: + :depth: 1 + +Password Security Compliance +************ +In compliance with GDPR standards, SQream now requires a strong password policy when accessing the CLI or Studio. + +For more information, see :ref:`access_control_password_policy`. + +Known Issues +--------- +The following table lists the known issues for Version 2022.1.1: + ++-------------+------------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+================================================================================================+ +| SQ-6419 | An internal compiler error occurred when casting Numeric literals in an aggregation function. | ++-------------+------------------------------------------------------------------------------------------------+ + +Resolved Issues +--------- +The following table lists the issues that were resolved in Version 2022.1.1: + ++-------------+----------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+========================================================================================+ +| SQ-10873 | Inserting 100K bytes into a text column resulted in an unclear error message. | ++-------------+----------------------------------------------------------------------------------------+ +| SQ-10892 | An unclear message was displayed when users ran ``UPDATE`` on foreign tables. | ++-------------+----------------------------------------------------------------------------------------+ + +Operations and Configuration Changes +-------- +The ``login_max_retries`` configuration flag is required for adjusting the permitted log-in attempts. + +For more information, see `Adjusting the Permitted Log-In Attempts `_. + +Naming Changes +------- +No relevant naming changes were made. + +Deprecated Features +------- +No features were deprecated for Version 2022.1.1. + +End of Support +------- +The End of Support section is not relevant to Version 2022.1.1. + +Upgrading to v2022.1.1 +------- +1. Generate a back-up of the metadata by running the following command: + + .. code-block:: console + + $ select backup_metadata('out_path'); + + .. tip:: SQream recommends storing the generated back-up locally in case needed. + + SQream runs the Garbage Collector and creates a clean backup tarball package. + +2. Shut down all SQream services. + + :: + +3. Extract the recently created back-up file. + + :: + +4. Replace your current metadata with the metadata you stored in the back-up file. + + :: + +5. Navigate to the new SQream package bin folder. + + :: + +6. Run the following command: + + .. code-block:: console + + $ ./upgrade_storage + + .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version `_ procedure. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2022.1.1 \ No newline at end of file diff --git a/releases/2022.1.2.rst b/releases/2022.1.2.rst new file mode 100644 index 000000000..d94916d02 --- /dev/null +++ b/releases/2022.1.2.rst @@ -0,0 +1,129 @@ +.. _2022.1.2: + +************************** +Release Notes 2022.1.2 +************************** +The 2022.1.2 release notes were released on x/xx/2022 and describe the following: + +.. contents:: + :local: + :depth: 1 + +Version Content +---------- +The 2022.1.2 Release Notes describes the following: + +* Enhanced security features. + +New Features +---------- +The 2022.1.2 Release Notes include the following new features: + +.. contents:: + :local: + :depth: 1 + +Feature 1 +************ + + +For more information, see + +Feature 2 +************ + + +For more information, see + +Known Issues +--------- +The following table lists the known issues for Version 2022.1.2: + ++-------------+------------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+================================================================================================+ +| SQ-xxxx | Description | ++-------------+------------------------------------------------------------------------------------------------+ +| SQ-xxxx | Description | ++-------------+------------------------------------------------------------------------------------------------+ +| SQ-xxxx | Description | ++-------------+------------------------------------------------------------------------------------------------+ +| SQ-xxxx | Description | ++-------------+------------------------------------------------------------------------------------------------+ + +Resolved Issues +--------- +The following table lists the issues that were resolved in Version 2022.1.2: + ++-------------+------------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+================================================================================================+ +| SQ-xxxx | Description | ++-------------+------------------------------------------------------------------------------------------------+ +| SQ-xxxx | Description | ++-------------+------------------------------------------------------------------------------------------------+ +| SQ-xxxx | Description | ++-------------+------------------------------------------------------------------------------------------------+ +| SQ-xxxx | Description | ++-------------+------------------------------------------------------------------------------------------------+ + +Operations and Configuration Changes +-------- +The ``xxxx`` configuration flag is required for adjusting the permitted log-in attempts. + +For more information, see + +Naming Changes +------- +No relevant naming changes were made. + +Deprecated Features +------- +No features were deprecated for Version 2022.1.2. + +End of Support +------- +The End of Support section is not relevant to Version 2022.1.2. + +Upgrading to v2022.1.2 +------- +1. Generate a back-up of the metadata by running the following command: + + .. code-block:: console + + $ select backup_metadata('out_path'); + + .. tip:: SQream recommends storing the generated back-up locally in case needed. + + SQream runs the Garbage Collector and creates a clean backup tarball package. + +2. Shut down all SQream services. + + :: + +3. Extract the recently created back-up file. + + :: + +4. Replace your current metadata with the metadata you stored in the back-up file. + + :: + +5. Navigate to the new SQream package bin folder. + + :: + +6. Run the following command: + + .. code-block:: console + + $ ./upgrade_storage + + .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version `_ procedure. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2022.1.2 \ No newline at end of file diff --git a/releases/2022.1_index.rst b/releases/2022.1_index.rst index 3d1517371..5f53bcb38 100644 --- a/releases/2022.1_index.rst +++ b/releases/2022.1_index.rst @@ -1,137 +1,18 @@ -.. _2022.1: +.. _2022.1_index: ************************** Release Notes 2022.1 ************************** -The 2022.1 release notes were released on 7/19/2022 and describe the following: - -.. contents:: - :local: - :depth: 1 - -Version Content ----------- -The 2022.1 Release Notes describes the following: - -* Enhanced security features. -* New data manipulation command. -* Additional data ingestion format. - -New Features ----------- -The 2022.1 Release Notes include the following new features: +The 2022.1 Release Notes describe the following releases: .. contents:: :local: :depth: 1 - -Data Encryption -************ -SQream now supports data encryption mechanisms in accordance with **General Data Protection Regulation (GDPR)** standards. - -Using the data encryption feature may lead to a maximum of a 10% increase in performance degradation. - -For more information, see `Data Encryption `_. - -Update Feature -************ -SQream now supports the DML **Update** feature, which is used for modifying the value of certain columns in existing rows. - -For more information, see `UPDATE `_. - -Avro Ingestion -************ -SQream now supports ingesting data from Avro files. - -For more information, see `Inserting Data from Avro `_. - -Known Issues ---------- -The following table lists the known issues for Version 2022.1: - -+-------------+-------------------------------------------------------------------------------------------+ -| **SQ No.** | **Description** | -+=============+===========================================================================================+ -| SQ-7732 | Reading numeric columns from an external Parquet file generated an error. | -+-------------+-------------------------------------------------------------------------------------------+ -| SQ-9889 | Running a query including Thai characters generated an internal runtime error. | -+-------------+-------------------------------------------------------------------------------------------+ -| SQ-10071 | Error on existing subqueries with TEXT and VARCHAR equality condition | -+-------------+-------------------------------------------------------------------------------------------+ -| SQ-10191 | The ``ALTER DEFAULT SCHEMA`` command was not functioning correctly. | -+-------------+-------------------------------------------------------------------------------------------+ -| SQ-10629 | Inserting data into a table significantly slowed down running queries. | -+-------------+-------------------------------------------------------------------------------------------+ -| SQ-10659 | Using a comment generated a compile error. | -+-------------+-------------------------------------------------------------------------------------------+ - -Resolved Issues ---------- -The following table lists the issues that were resolved in Version 2022.1: - -+-------------+-------------------------------------------------------------------------------------------+ -| **SQ No.** | **Description** | -+=============+===========================================================================================+ -| SQ-10111 | Reading numeric columns from an external Parquet file generated an error. | -+-------------+-------------------------------------------------------------------------------------------+ - -Operations and Configuration Changes --------- -No relevant operations and configuration changes were made. - -Naming Changes -------- -No relevant naming changes were made. - -Deprecated Features -------- -In SQream version 2022.1 the ``VARCHAR`` data type has been deprecated and replaced with ``TEXT``. SQream will maintain ``VARCHAR`` in all previous versions until completing the migration to ``TEXT``, at which point it will be deprecated in all earlier versions. SQream also provides an automated and secure tool to facilitate and simplify migration from ``VARCHAR`` to ``TEXT``. - -If you are using an earlier version of SQream, see the `Using Legacy String Literals `_ configuration flag. - -End of Support -------- -The End of Support section is not relevant to Version 2022.1. - -Upgrading to v2022.1 -------- -1. Generate a back-up of the metadata by running the following command: - - .. code-block:: console - - $ select backup_metadata('out_path'); - - .. tip:: SQream recommends storing the generated back-up locally in case needed. - - SQream runs the Garbage Collector and creates a clean backup tarball package. - -2. Shut down all SQream services. - - :: - -3. Extract the recently created back-up file. - - :: - -4. Replace your current metadata with the metadata you stored in the back-up file. - - :: - -5. Navigate to the new SQream package bin folder. - - :: - -6. Run the following command: - - .. code-block:: console - - $ ./upgrade_storage - .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version `_ procedure. - .. toctree:: - :maxdepth: 2 + :maxdepth: 1 :glob: - :hidden: + 2022.1.2 + 2022.1.1 2022.1 \ No newline at end of file From 3b287ce61c88ec64386fcfd3d8a6c17a03fe2e6f Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 14 Aug 2022 19:05:17 +0300 Subject: [PATCH 216/316] Updated --- feature_guides/query_healer.rst | 26 +++- login_5.3.1.png | Bin 88126 -> 0 bytes .../access_control_password_policy.rst | 40 ++++++- reference/sql/sql_statements/index.rst | 4 +- .../utility_commands/shutdown_server.rst | 95 --------------- .../shutdown_server_command.rst | 113 ++++++++++++++++++ sqream_studio_5.4.6/index.rst | 18 --- .../configuring_your_instance_of_sqream.rst | 23 ++++ ...ing_and_managing_roles_and_permissions.rst | 12 +- ...ts_and_running_queries_from_the_editor.rst | 93 +++++++------- .../getting_started.rst | 14 +-- sqream_studio_5.4.7/index.rst | 19 +++ ...orkers_and_services_from_the_dashboard.rst | 77 ++++++------ .../viewing_logs.rst | 50 +++++--- studio_login_5.3.2.png | Bin 82674 -> 0 bytes 15 files changed, 353 insertions(+), 231 deletions(-) delete mode 100644 login_5.3.1.png delete mode 100644 reference/sql/sql_statements/utility_commands/shutdown_server.rst create mode 100644 reference/sql/sql_statements/utility_commands/shutdown_server_command.rst delete mode 100644 sqream_studio_5.4.6/index.rst create mode 100644 sqream_studio_5.4.7/configuring_your_instance_of_sqream.rst rename {sqream_studio_5.4.6 => sqream_studio_5.4.7}/creating_assigning_and_managing_roles_and_permissions.rst (97%) rename {sqream_studio_5.4.6 => sqream_studio_5.4.7}/executing_statements_and_running_queries_from_the_editor.rst (86%) rename sqream_studio_5.4.6/getting_started_sqream.rst => sqream_studio_5.4.7/getting_started.rst (78%) create mode 100644 sqream_studio_5.4.7/index.rst rename {sqream_studio_5.4.6 => sqream_studio_5.4.7}/monitoring_workers_and_services_from_the_dashboard.rst (84%) rename {sqream_studio_5.4.6 => sqream_studio_5.4.7}/viewing_logs.rst (73%) delete mode 100644 studio_login_5.3.2.png diff --git a/feature_guides/query_healer.rst b/feature_guides/query_healer.rst index 7068abc2d..0180150ea 100644 --- a/feature_guides/query_healer.rst +++ b/feature_guides/query_healer.rst @@ -17,11 +17,9 @@ The following is an example of a log record for a query stuck in the query detec .. code-block:: console - #SQ#|1659621825880088264|2022-05-19 20:01:25.880|INFO|0x00007f9a497fe700:Healer|192.168.4.65|5001|-1|master|sqream|-1|sqream|0|"[ERROR]|cpp/SqrmRT/healer.cpp:140 |"Stuck query found. Statement ID: 72, Last chunk producer updated: 1 WriteTable, Started on: Thu May 19 14:01:25 2022, Last updated: Thu May 19 15:01:25 2022, Stuck time: 5 hours, Max allowed stuck query time: 5 hours"|#EOM# + 2022/05/19::20:01:25|ERROR|Healer|(0x7f07147fc700)|Stuck query found. Statement ID: 72, Last chunk producer updated: 1 WriteTable, Started on: Thu May 19 14:01:25 2022, Last updated: Thu May 19 15:01:25 2022, Stuck time: 5 hours, Max allowed stuck query time: 5 hours -The ``healerMaxInactivityHours`` log frequency is calculated as 5% of the flag setting. When set to to five hours (the default setting), the Query Healer triggers an examination every 15 minutes. - -.. note:: The logs are located in your cluster. +The ``healerMaxInactivityHours`` log frequency is calculated as 5% of the flag setting. When set to to five hours (the default setting), the Query Healer triggers an examination every 15 minutes. Configuring the Healer ------------------ @@ -33,4 +31,22 @@ The following **Administration Worker** flags are required to configure the Quer * :ref:`healer_max_inactivity_hours` - Defines the threshold for creating a log recording a slow statement. The log includes information about the log memory, CPU and GPU. -The ``healerMaxInactivityHours`` log frequency is calculated as 5% of the flag setting. For example, setting ``healerMaxInactivityHours`` to five hours (the default setting) triggers an examination every 15 minutes. \ No newline at end of file +The ``healerMaxInactivityHours`` log frequency is calculated as 5% of the flag setting. For example, setting ``healerMaxInactivityHours`` to five hours (the default setting) triggers an examination every 15 minutes. + +Activating a Graceful Shutdown +------------------ +If your log entry says ``Stuck query found``, you must set the **shutdown_server** utility function to ``select shutdown_server(true);``, as in the following example: + +.. code-block:: console + + |INFO|0x00007f9a497fe700:Healer|192.168.4.65|5001|-1|master|sqream|-1|sqream|0|"[ERROR]|cpp/SqrmRT/healer.cpp:140 |"Stuck query found. Statement ID: 72, Last chunk producer updated: 1. + +Note that the log above identifies the IP (192.168.4.65) and port (5001) referring to the stuck query. + +For more information, see the following: + +* Activating the :ref:`shutdown_server_command` utility function. + + :: + +* Configuring the :ref:`shutdown_server` flag. \ No newline at end of file diff --git a/login_5.3.1.png b/login_5.3.1.png deleted file mode 100644 index 48c725a4c141b6a2bb04718c683646300bda009c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 88126 zcmc$_Wl$W^yEljj2?2sbaDoIFJh*#s2tfyz;F7`J-3hM20t5&aU~qT$;LhOg@^=3B zzI)%=PrJ1rwrVJ5db+B6PCw^4KRe+nN-~(}Bj$|Nh|R)M!uP;9d&l zB*i|v=^sAbK<-w6L%+cctG=%Z9-+zbSD(-+C|KEKf~=U0pS=CKYc$bAs7@HPc}5oQ6ha zX=_F66!M&b?-TN+jPL*LHFGP!OEXaSf{i5hU$5qu{&2Ky+W-CWGuogWY5?VbUO(xQ z694yks)`KsRR8_Ok8~9!@&Eopk~=Rm=)X><46~w6O1uqFP3$6!E>3mg{^&Zs|AtoW zK!Hy}u(7DdL$HIP-kk02oc8j%Rsf@gsK6Wh`L8!U>ejrf2B~sU*`uWu+2)?LUSH|1>;)P2=nKOCQHVNj#w4LHc%tWg^MP%|r{f z$KLEBH%1MSDm=hTuISitexOlkOc&(^eE_%pgs5U(^e2@uszQCJU>*`KIIv!Ix=@Od zWa?#OZX+CU2-^l)OyW;%7g(oAV%O033S%f9%-CyQ;&nAdNPO~2LlR2#z9>_S1B?dy z+g-@?=Kx)vQ0e~DqI2X-kd!tQ9tWnQ2hR>G`arpiJw3z?oMt@mSrOW*^1gsH=1fsj z6-ty7T^RygOf?=Po&E18#8nK9rPwjY2Mmj=wnElvxfrRz^&+oD?urr_%LItpmwvus zH#B7)6{YQs)Yv+6^pHTyhD_)Nd7V%H4kgN^h)kr&>!_v2##cpFpc$9C>`5x?@bFJu zD3fNO_m4CG!rX!CTJs#+yQVj}s2a;?;V0RJ!?OqNrBB>HC z3TeVJ*7`DBVV0jLAgr>RIU9le`iVW%sUtlqSD-qv$Es8AQ1YVe(*Ux{Qr3y%ib=i_s zp|>%ta?mAxO<5?eym*t{T_Mv6^t$@f90T)mutvtp{tkb*9M1O&dfpc14`5zxd>Dx2 z-An>Vjc`v!6l(omZf-16*hojvPzyg1bkD>9X0X^S^QQ;PpiOem3+jnU8_Pvc3~*x# zKA%<(gx@RhAu^L33UB!%6scd7xfG}5Xx)oXAZKMg$W!-f+h6Q6KO$qmK>K9M zM8tgJo0lX-XHU^yc0uNsKF)e*B@L(3#oYY7t zloW}2Zc&vm6*hf=t4>a%!st1L1?g3BmC&P=uL?5s%F-cbQ{w6plPnP&+z87hVUV6L zBkl~~D*Y5%aBCvlr%4v^-~y(C9CTSia`ZGhSaqnApQ~z2sQ+L3 zlQ5^o~1f>GT%;(Ge4;JxdXxBQ^a??qrXw$#^AcZCCvq3%|D8YH@KmqBP56a1tg5%~7zQ931xyDPn7G}^WpT)izj7|5pkGUC<+jq33!3P- zxDyh^i>4C$%Nb9g;+RE>7z~(0Vp>qON-3*|5`_M)25of)`YO-BDW+sYyqb1$V=WGT z!YdbdwFQZV?zbiJ$bk#QYy3xOlB2`0MYw)-gxkS7RmXx<-U%`y}Uj5yAXAkHE|l|3s7~SGyU47{^OQdP2-Mujw>J@?^c# zOkD0e^`1Vb3*^OZPL6`nr0FatZ~c)FVSAfC~pJz_RY-c|oIH2(sH3Z}zE4L%Og zD2RlCDk1a)Wwgs*jR~461Q;lnWf>=(!+7~BYf`kK*>4Ll=*y^=rCRcJCc$+LQm$ZI zw8^XB+tnU|6pEs*nK)3dh0_4DdDR_MQq7pw?(>?e(KzF_%=SQi!?y; z_Z(X&(Qm7&7k+OlVDA0-%o{Em%4iX%@F1=wwd6pNZ|8J-s82QJAsbF1S4ndmWC{7? z%<$?p#@`y~oqFIYh7$U(73Z*ly>|0{3W^j~8>jpHW)>oDD)M2PIl03xsn)(kG=nAD zR4^w*Lbw~G!pIRFJ?QPE+2G6?leV=>xEv2N2;8B82tyhC0G8an9mQ2e77wkKCzN|L zC--j#c2uptkL8LsQbLA62thkAVq;HceR+%Wl46hJD^7UGZT0xLJbTL>2?Eq>#4#ki` zm=}Gy-EDu4N;Pz@!|hU4zl%Oa*w$@i5rw z6eyPH1h5Q88U}78{!HDOODdJaM4wj3Ah1tlvB3VWjn+b7r>+Nmzb8|nE&PP~1re4` zyNr9+3{bjv}8_AvzLmg}}}99*i^fN%4Py_f{sWIDgS4`d!ZL~-7$t#R~0RA zEM3-JqAJx7roy$3)z@HOBZK@|!VExt%vC5;4t|W9xDoFkaj2&JWd-qY*s}C4f=&J% zrBRNKgBjwfBTi+epA~GG(vF^ROQW<9q^3JZVf~G|$W-VYkkwN|uB5{Y(T`M63@#uo z$%b?xOll~k7(fwPDoP>mHIfXV6G(G%2_W@RKlJx z0*t1aq>5D7WC2rdghRuN*TG*fw?byIHiL{!jWq#lM04}4yTom0}aTvr% z$JA?$+$v)4l~s^)o?H+t^{1s>Ae=R}El04sY!RF6~=~Pb>@UXcfbvM zqiDGf2i!a8>&S8VdtA*kt;9r*@i$ z`g6y3(2kpVPxX06BIxjoJamYT@KW6c<{^cE5~{2RrG`hOo-Q$?f{F8y8eqPI8P@{f zZ%|K++CFV=p|Qw+iZFmKzK(tSbwpwr0nZ#4f)cOgO$e|yWs4$l$FBij{BE#1Gu+%( zQsl}`pZd#O0jFMpl7~QD>yVWA)X8-jD4VcoZQ3%9bu9<<#mVVA4FRVig>V(60OU8t z?4JS5X~3{Ab>4qLgrC{^8?T@UfcRR1Zzv|kWB4cD-0!@}rS9W`9-qr>tpFgKE#Dy_ zXRWBf9&b;sU``AFG!X#Eb`4KByzKzkChFw+=vtHsUsR_jAj!} z`c}P$?n%k-D4{6`k3LW7Sk@ScN_Ln^y`m^!QiII6T@d3F;bL3^q;b_9j;wb@#|8FD zT%F9AK?*7-22cl7c^=y5`W&gr6a7Zc`|x%a=T|K0>Um#oyZ`cA`-qa84LqXd{>qLDKw}Y0)f36 zBjq&Jf`3AK5Kv?_$thYBpH&o0Els@hiu_9@S7`GRNg|1e1;RjU6d6!ZTzgaevk_nk6B zn$G1zdQ@5EXpE3M^d%2B>*kWnyXaz%eld1w$>(fGG_iy)=jNyW!$S!UbF%##$jahkR8PQrI7>4WK8r`QR5S!q z+IoabuC!|Tv{&jHGM`8*|zc=OasLAbEArE#3zaDHXmdB(~ zNTSO?uwZ+e?HgS8vNIDSpWUr0fhN-9eM=8_4?Ju7INk?2D%1@`1VDChTnX5-dXK$V zP4rU5d-2#^Lh<^>XWNZ*<52kz#k1QG{MOrk>WZ&R`F_mQfeA|el%lIo6Cqrrst?kK zx;f@F%tH~q*fi#j@pumMHX&;=u1gEcx1njOiFi~s*=6B{vsqR1a!t;$E@(OT12CWN z1zDow{p5r)QXQ-x7^kLPOGQ03a4fluTyBaNJ_S~;F5F(8YxA7>fxg)phis&f4#R@( z)YgID5#t1y&vO&5tV?h&pwUqDz=S=t)et`5%D`$9ch zr{@BCoU9*kUQ-faTw)n*z2@M=ka0DoV<1gpis&2^H+TBBn8ym?@!6E@i&Y}?we&E3 zDK+ojX5e1#flAK?;YZsbwNjDFAoy)H_E}X2Q7Qjs-pqNBa?MaG5tk|A=H z4p*J|o6v`&WQ)Gg_yNjkX`;c}FP7MP)WHuO4hC8Jk%FHDS^QsKW{0WjOM)3iLA7;0 zyH9<(tC=~OH}3N2tE=E_nU9gD>6SGvx2siDU&%{&H{BiMGSbA?sX~upYc>szt;GmJ zy#g&8-->q0er}y#JRiK=`#A)Q=G~mnUDbf#H8sGUICX+{>RW@>mmnR=`c9E;`*k?? z09Ws;EaNxqxd9_&4tK!-qw#r-rCwo7X7be;nJos8n+&xwpV`bq1%#_42Y24wulu)8 z=g$4?PpT=H74rW%f-5<6n5VZ!+8x-j#ZRpG%cvr7a@xV_i!5~VpK#MIBnA_Y4w&Q? zcv>+`0-#V-ceKlD+|0RejfpFSn=(O~%ggA?p&E@>UA=Rg%K$OU$5bMM4A$Dc(?dP| zTOHqrK3%NO@2TL4L<`=dYT=CYkUIB{@4(1-wPm5Gm^c+r?mllPEHswB1lDflV>Z>3 zmHFDbyvt+TWb=biIY~oRo(*>BS#9URG%YHDJ}rVm89mJH6hn>uA_L0beXp#Mwts>)7wWZN#PH1LxJuj^_TxHLB@GtJ_i(+9T1Tnmi zMql4%piChk;#uDytv*y7#Poz_xfICtx1_;K`Z!s*ZU&4Ec_9&G2@l9sSSnDrMk2d{ z>mW1j)Q4Y;=X!WKwqL8YuVHQK3g{NP``h1w2%$I&F zjjKH!vIvMEJT|2KjY%npe=NXxuswNOjQDal1j6`G*3EmT@Dx z?~D>`(%TF-<>a=UnES|$MMG_mvFqoEg!W$HFwb#)5EY>=%0I))9F7?WRD%q9wklI} z)Yk_Aqr$~?PCZEBnd#cx3*Jkuc_tE5I$=SK7GcG+Ulb}PkR>vCe#L8@4`(V_J8^DX z{bmcX_)?|Kx&3-CV0I&YI<4@SMX}i3Qp=>ow4&z8R=3Xxt-Otvp$~6Nhw^xQio#hCqB2jCdh$5b~ z=9Apqx&^=+t;>QSS08~Y?cF-(i5Y1V7P<~TmJaGnTg#nw`(1XGIJ4YPFxPV zn&4dJbALU6-$_;!e?yFLvqH@YR{wk9mD-oIb$_GK^1TtZ$qIo#raI0Kao)D&i|*_3??TzRDJmAvP6te0 zX{Hn_{Bh5UCM`COsp3odec&+@7S|4?!o z4Qi_$n1|ZS+3#MHOiJZiJDw9VS1-6{EwgUd!rta(BCTqr`czQBr4hRp_+2hiktkHq zs~=LKOpBrS@MI-e{ZRZPNMSiu>V!gszwi7>r(Kpk@};%VFP(_GNG19wOwDRgy{i&s zp<|#rUB8deuK+zh-9fGUGTosP5WaEf)in|;I7x&`b;Z7RBE72X1(qiBX1nh0sFwvw zt9R9lZ7ZuWK|yzJb@Mv)n*cg`nH;7fS=72hE{sIA>)3tj*`u72olymC+%HcP=kN1# zg(c%OPGhv45Snn$MZQKIw?E>oHgOl;{1zhK1mfpDxp;OtzdY*OPn#|6B!rR}WD)ZO ziA!CJDny7Rr(SsEF#h^^p!-Hpc$#y^C6A5=)ibsUlbIIs^z$WkDVwNE35jRgM$K;BR- zOcY-y=u7Wxpn`*nbu*iDFHSVoFQdmX^Wh^eXO~C1y8!H+&6y2xJ{ET~k7?XULRWIi zVt%6OSG&j`D=gxO-biqv4Jer?z-@0dBfyUkr);id?@-6j&O);^xsDtExW8bQzp}Ry zf_$_Q=DoFPD115vo5p^d0X#421j} zRFXTb3*ppF{oX*fA-s)M*l|>E%${Z|cie6!zHtNaSoBw&MBTB!QKjao_vSe2Vx~)N z63(4SZgk9#>@?9grAP4}Bbr8Dil-sW8$WsZ-g#*vnwz%UnF)?zaL6eO!drR+aK;R? zDUICho9c3me4&NJNo%v?7`~$C_()m$^(U;hWQrin8SrAYfe&>0`Jhn7T>ideZPSaJ&cuZf2hYw``R#_>B7vq^Ulg|?X?6*(TvTY-sygAWtFPpi9JXBi`cE0F&5o??_*JJ8>(`)@N?k0Fsz3}Xe8&D*Q3shLTP37cN_P( zyJUTUqxq6K!!(9p5Yjp?_1XQl(mvTa4*hc9(= zNNpUZ@!mf~p4)bG@N}fbiiHWGWO}$BFj?hWxLWQ2?QO;9*)jj<3-$D2TYBhH_g2p2 ze>Tw$Qo$*@I?E&PKVMG-r-oHt)tg)jFKUNgqG_WmY-Pp7*1x-*TIx2PxFAi91jd$T z+(I}5a~9*v2tW)*dC5+;ZCQfb|3V~9=nuazoAx){@+m-Ge%qy$u>&>ypAt46-Ftf7IfAtIYXO-kMNZZ)A&&A;;uq(! z3k#z+T2dbCS0qK2Td(5GYuDr*>`xp;oQ6c0dDu6C;p}+#M_ZOi`NMsz6|3$Rt|s*} zNZ*Jsk$cl_5cmTav#%QjMo?GP>u+k`}Ks`=$ETwUS~>88WSJ;wc|S@)znX2dTe7Qnm~5Pl5~ zUxKQB{0?FsU>GfIyP_T7qa90R*6N68juV4uA@vLWY?<-+0qVOk|=B9u#Gqx zMd@X}vuBQOp@&*|tn58Q5BLJ!+oYtpFjHg;c;g09>hNKtj#U{9!KZ82#A4ftuSu>K z)W+%!5o{@Uw|(h1-uAyq+3glKdu-OSX-JkEt53IEXXP)lF5Dr%o0d&QxyHQW@>E#c zomn0X(ujv16xRPDA;ugFa&tID?(1y;JtxOTy$1Sbz$Mo1lp{_SvMro9a#w2{!cv9S?&LU)d@IqT7 zzlg^3`EoAfB#RjTuO|0n%I0z1f#Qb?9S0oY%#mmm$L>Wpa`w2Ib5!2xN%5$c(v?C1 zMy!p@nww8?5pI=&+ZWk>$ zUm&Jy`(6od=Ma&E`HhsDT*64!ZN!C@!XeN zhq0tS@C4jnQu#|Q#Z`)9vtNN_8P`HW{0_|yN@|j-?j6FX`RaX(BOwkP@6Yv$HYlm8 zWb)&tUNZSq88j_K$+p~uaEqOuigYaYnb>06=~{rfHIp|&=(@agyc z@yjb^$e}J++#o31*!_=a{rGjwrbLvpgW^T&#+)6#>SujnFGwFyEG=9@0s3t>SH`iD zp5;X+*@yQ4W5;==vO5{F?3Q81t{69`)7*-9nMjrea zgQ8d!vc*vKAJMrqnOAJNy-R77S;rAJHm8(i&idwN@htRW0Pw1}*r~r1)+)%!&%1f` z8Oo|fR)*~K_D;NEf|{@s_~lgNl|b1%$#Ytu$&B)|`-$h`0v2iUL!~{R-{;V(1j1iQ z8H-r9bHnWAI7nh!faV*(TX|ayX;ghaXjXMIIq2A>Q##Vq{>l!+{(7x5;{64K*KV=E zpa-ofK*Pu|FtI()kaWp#-iXwZuUPO{D#xC0ZSIvszi-?{kbL8r#GS41$w^1fSAk1l zc^GsH_tKAJq6~RB>bC6V7qz-6T$%0Se=cLI^>5cddi%~?2QC)#3ZnCxh+v22yW!2? z#vc=#^a%f!0;4(7Z@BTDu_j;IRZa|MwvKva_FcV8>dnNiB93*6ri>r`_cx@YP>QYq zImwVi1I9!e7*6}8Pn`yF;SGaV^HqBWhWgY>fIVjDkL$05X^jmkKKqD|ZQ?%dI@eUl zkZaPXBZ)UnH^1z-G~XtWm%#?6o>G2-7Sw`}rWYOxF`HWF=bW_ahq+|2k>UyetMct5 zIW@VD9#mQ>IB=TuKGO?f+!p@s*JehpKiXnzVmT)&lX@r&3zFRxjXY} zX{az02{D%XH#|GJc6Tc)<~z|mlV58oRw~kbDeUURjaBx1-ZBq^nK1gd(qc{f%NT~4 zcL?3jX#$0?Er2ok+)#D3hM{hu#CN0+NX>vY&_&-=G2}WxP#y2-na*A?ugn&;5ZbMY z4p`LKfW1`We0Q(&Y~G@p$fAjxqOZa_oqHMM!9Eo*CM(8GHD%4la$FE+IgMw@R&psd zUhAL;98=?tPmi$dNO!8+=VjDn%7^Ks9Jg_OPKi8l)nBe9j2|TQ)Fmg~ zcX!+$e%2U?n#&j5mLtyzn4CdDd_d1My8UEu(8m2OEHO1UNfV0t&a-@nVhiJ4{PdH@ zs@8SkQE`KfSe#0~P7y2JPMQBl}9;TJK0?qdA?&KjLW3XXt z0X^jArtVYQUL+qQH-kQB{WwlE*|;V7;LW52Z0B8~aL%8p%-`BR>>vAwkqQ3VW;p{h zd?6p)oL{z{a4*P8^d$RK0qBk|Rb19+^5quwX>)SOcdz9NI)2}8!F*_G_YL?f>{f2R zZmS$Tqm_s##u6|DT-mgJUkd( zcL9?kwN-M>Tp=GL1Gq%2DxI1Gu{tz^8<_AZBF&}_LB@|cmk@%n(w-5rU@c=?mmcGr zpayR5y!p$B_e9%z>wYc@E~^16An(Ys7<1g{;vLO$^H(p%5MN&5{JQ(jO!}Ly+69;a z2R{%pvb^+I*yH-!0yq)Aydkaa@c#@1vK4HFeDz@}6fV=>o>yP6T-ztWys*n)_aUcc z(kQDar3Rg5I%XZcXZ%E_&MBsamPu0 zPsNRoZ6m%nrkXX58c(->9hm)5vR2Mz=YU>3$>LjA|Gnx>0fx;^agk64;XGafXk+LE z(}hz6Ov7{QupBdI-YY)v8K*@I8i^v{WjaV~sFPg5WUv10=G49Yn8Qh5O{O9Wy{(D& z7cNV?L-m7L)Xhdg78OwnlH7g$UQ8F)Pi|akRP-xW=2f>MCdnq$Qd-yv?Xth_{&204<0=iKp0r|Nh268vs-` z=e)I?9lB}djm}RU6PEVRnxda3>ymxvMw0EQ3>|0oK}K`VXJbfE#P~FP4A+j%+JW^z zpZ|m_{uD<+B5_gscAWqC#X$mpOgi6oBcc!@peT(vdl?L=Vu~2HyDpW^1jbtclA@gK z+{Wd%EJ;74!aJN!r&f~ZO$_NOLn;cOga}wF{BkXM(QE;Gk1bp$5u*xIeH39zNraZx z3}-k`kMg%h&EocMMsI;E4#~}S>3A%?sfz7aE4K0Z`>hk>YivYgPA^|GnXiB+(_K*4 z&=`qnSb+WDBosqGM|kySFI87PV$}JgokF-v?xtB{2fW|laG75($gc6CfUa*@;*);}NR`kLWG6|-iJk|BD{JN(t$ zkXIE>^+ZkdVPyVoSVgmWCa>w{1{@T0c3V}FntEg>xiv+hKF`Jy{9rp+g%~s}G}S4@ zgkWicWaHLT@-@v159gn~8=Yo<>PfQSx-a$Z#34DE$0FOq7q>dY97x(A zm<~;R8_Vd@)J(V5E1r5X{@>7FL(sg!I0#mS)iKP{*r)zE?(xG@8|x?@A!$LAv6E99 zy&*IX;wVe_x`l(&!$MQy4-Si|AIWqxz@hmBBx(FRbroTplW*3>q?s223# zk$$rGv#lvo9dl`FIVk<+nhQ_}Z>~PB&dj)3SO`7)zdTMob_cAc+`x=dO|p7yFJu#u z&Gsbn04Px+;WFG`DgEkTmvE^00D6814N=+SNi4QgZ}C%u@)cK_t?c%6o6U_Gd(TZi z?h5P^OMz!<2`w#RXSSm0<0zhQr_Y*Qzx!qUePeV-895|41E)ld+C@+>8_V)mO#J*P zvF}{J8d=Ej^rbLOLOg)^pr-`KIZIiVNlJZhwh|L|-uC^|U+0=aT~w{0WsYNLJ82ZP zAu3vMjZcRk70vPn5)KQ&FLVYaqD=kp5r%vk&N;8UMY!_0=;jG)}t(iw2WbsCSzx}_Ez8F z)omFHO@56>qlj%6SAa_mr;1zPCmL8E%oT%q9_U3S1IKkLN(pgeUg24lIQ*{)K6kwU zk-4|$qHMwLI9!-WiusJG1dRy#rF0$1WvW&j!B&%)=d)PzUsamvbSr)!6yZOeS`QW> z_sM(~aS9YySGR)=-W#D`P=6)qFXFQW-8~7U5DKsMpn&T9oFdjbaLGJtBd=v8kL90_ zYtt@c2^x5x7tV|%`R0%Qvy%3z?76C2{Mq)bS}x{~0pMRFy_M-yY02H3TK2)-X%2&A zDcix-mKj~NXYc09tt&gAxm)slD1Q02bi}{?n?_s;e9V;_q7!xP zh4pM)@L)gkE?_7UJ=0x+Hewc3QAvk-h9N6X&B^UA*-;}6@JBZc;`Ban8kncJ=ubNa zL#6G)%e;#6S;n^&?Q{*MeQ5F%t8#2q!@GX2!}vXyktHFa5%(04Ui1V2;250R3MU(O z4Ja}VzSq4%IZ7;!C2TasKtsC>QO&x!^I_-jpN7xb=S3ic8i&PvBps7>I8ZNL|Cb>I zx)tRW)T;@k5^~mzLDax)Hr1(wp7y1+PGj5Z69>!Zn$J_)nUW=R>ZvK!8Pe(jMTr5J z$u=G}MgK@cccVCOTKa{14!O`>qsdhY&v86Ro$)l^vhE+6idCkNIn>yC(1qd*M@N@OfEm9$KweTjbSrE}FFIxZF&{w6;r1ET-E!ng)_ItE zEV!S{A`y!ZdVK!WN*gClJtx(dCJo1R7h_HUdzVlf5uoKeZ}j41P
2k12sUQOc} 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
25hieY$j%?+_Jc9<6R}d~s2d%gu9h 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 diff --git a/operational_guides/access_control_password_policy.rst b/operational_guides/access_control_password_policy.rst index 10a4f697f..055d674bb 100644 --- a/operational_guides/access_control_password_policy.rst +++ b/operational_guides/access_control_password_policy.rst @@ -3,6 +3,14 @@ ************** Password Policy ************** +The **Password Policy** describes the following: + +.. contents:: + :local: + :depth: 1 + +Password Strength Requirements +============================== As part of our compliance with GDPR standards SQream relies on a strong password policy when accessing the CLI or Studio, with the following requirements: * At least eight characters long. @@ -23,7 +31,7 @@ As part of our compliance with GDPR standards SQream relies on a strong password * Must include at least one special character, such as **?**, **!**, **$**, etc. -You can create a password through the Studio graphic interface or through the CLI, as in the following example command: +You can grant a password through the Studio graphic interface or through the CLI, as in the following example command: .. code-block:: console @@ -31,12 +39,38 @@ You can create a password through the Studio graphic interface or through the CL GRANT LOGIN to user_a ; GRANT PASSWORD 'BBAu47?fqPL' to user_a ; -Creating a password that does not comply with the above requirements generates an error message with a request to modify it. +Granting a password that does not comply with the above requirements generates an error message with a request to modify it; + +.. code-block:: console + + The password you attempted to create does not comply with SQream's security requirements. + + Your password must: + + * Be at least eight characters long. + + * Contain upper and lowercase letters. + * Contain at least one numeric character. + + * Not include a username. + + * Include at least one special character, such as **?**, **!**, **$**, etc. + +Brute Force Prevention +============================== Unsuccessfully attempting to log in three times displays the following message: .. code-block:: console - The user is locked. please contact your system administrator to reset the password and regain access functionality. + The user is locked. Please contact your system administrator to reset the password and regain access functionality. + +You must have superuser permissions to release a locked user to grant a new password: + +.. code-block:: console + + GRANT PASSWORD '' to ; For more information, see :ref:`login_max_retries`. + +.. warning:: Because superusers can also be blocked, **you must have** at least two superusers per cluster. \ No newline at end of file diff --git a/reference/sql/sql_statements/index.rst b/reference/sql/sql_statements/index.rst index 5cac43122..960200937 100644 --- a/reference/sql/sql_statements/index.rst +++ b/reference/sql/sql_statements/index.rst @@ -130,8 +130,8 @@ The following table shows the Utility commands: - Returns a list of active sessions across the cluster * - :ref:`SHOW VERSION` - Returns the system version for SQream DB - * - :ref:`SHUTDOWN SERVER` - - Performs a graceful server shutdown + * - :ref:`SHUTDOWN_SERVER` + - Sets your server to finish compiling all active queries before shutting down according to a user-defined time value * - :ref:`STOP STATEMENT` - Stops or aborts an active statement diff --git a/reference/sql/sql_statements/utility_commands/shutdown_server.rst b/reference/sql/sql_statements/utility_commands/shutdown_server.rst deleted file mode 100644 index 7fa1571b5..000000000 --- a/reference/sql/sql_statements/utility_commands/shutdown_server.rst +++ /dev/null @@ -1,95 +0,0 @@ -.. _shutdown_server: - -******************** -SHUTDOWN SERVER -******************** -The **SHUTDOWN_SERVER** guide describes the following: - -.. contents:: - :local: - :depth: 1 - -Overview -=============== -SQream's current method for stopping the SQream server is running the ``shutdown_server()`` utility command. Because this command abruptly shuts down the server while executing operations, it has been modified to perform a graceful shutdown, giving you more control over the following: - -* Preventing new queries from connecting to the server. - - :: - -* The amount of time to wait before shutting down the server. - - :: - -* Configurations related to shutting down the server. - -How Does it Work? -======================== -Running the ``SHUTDOWN_SERVER`` command does the following: - -* Prevents new queries from entering the server by doing the following: - - * Disabling incoming queries. - - :: - - * Unsubscribing the server from its service. - -* Preventing new connections from being made to the server - attempting to establish a connection with the server after initiating a graceful shutdown displays the "Server is shutting down, no new connections are possible at the moment" messsge. - - :: - -* Waits for any queries that depend on server being shut down to leave the statement queue. - -Syntax -========== -The following is the syntax for using the ``SHUTDOWN_SERVER`` command: - -.. code-block:: postgres - - select shutdown_server([is_graceful, [timeout]]); - -The following is example of the ``SHUTDOWN_SERVER`` command: - -.. code-block:: postgres - - select shutdown_server([true/false, [timeout]]); - -Returns -========== -Running the ``shutdown_server`` command returns no output. - -Parameters -============ -The following table shows the ``shutdown_server`` parameters: - -.. list-table:: - :widths: auto - :header-rows: 1 - - * - Parameter - - Description - - Example - - Default - * - ``is_graceful`` - - Determines the method used to shut down the server. - - Selecting ``false`` shuts down the server while queries are running. Selecting ``true`` uses the graceful shutdown method. - - ``false`` - * - ``timeout`` - - Sets the maximum amount of minutes for the graceful shutdown method to run before the server is shut down using the standard method. - - ``30`` - - Five minutes. - -.. note:: Setting ``is_graceful`` to ``false`` and defining the ``timeout`` value shuts the server down mid-query after the defined time. - -It is possible to pass as the second argument the timeout in minutes after which a forceful shutdown will run after defining the graceful shutdown value, regardless of the progression of the graceful shutdown. - -Note that you set the timeout value using the ``defaultGracefulShutdownTimeoutMinutes`` flag in Studio. - -For more information, see :ref:`graceful_shutdown`. - -As with the ``shutdown_server`` command, the **graceful server shutdown** stops all queries currently running on your server. - -Permissions -============= -Using the ``shutdown_server`` command requires no special permissions. \ No newline at end of file diff --git a/reference/sql/sql_statements/utility_commands/shutdown_server_command.rst b/reference/sql/sql_statements/utility_commands/shutdown_server_command.rst new file mode 100644 index 000000000..ebc3d9184 --- /dev/null +++ b/reference/sql/sql_statements/utility_commands/shutdown_server_command.rst @@ -0,0 +1,113 @@ +.. _shutdown_server_command: + +******************** +SHUTDOWN SERVER +******************** +The **SHUTDOWN_SERVER** guide describes the following: + +.. contents:: + :local: + :depth: 1 + +Overview +=============== +SQream's current method for stopping the SQream server is running the ``shutdown_server ()`` utility command. Because this command abruptly shuts down the server while executing operations, it has been modified to perform a graceful shutdown by setting it to ``select shutdown_server([is_graceful, [timeout]]);``. This causes the server to wait for any queued statements to complete before shutting down. + +How Does it Work? +======================== +Running the ``SHUTDOWN_SERVER`` command gives you more control over the following: + +* Preventing new queries from connecting to the server by: + + * Setting the server as unavailable in the metadata server. + + :: + + * Unsubscribing the server from its service. + +* Stopping users from making new connections to the server. Attempting to connect to the server after activating a graceful shutdown displays the following message: + + .. code-block:: postgres + + Server is shutting down, no new connections are possible at the moment. + +* The amount of time to wait before shutting down the server. + + :: + +* Configurations related to shutting down the server. + +Syntax +========== +The following is the syntax for using the ``SHUTDOWN_SERVER`` command: + +.. code-block:: postgres + + select shutdown_server([true/false, [timeout]]); + +Returns +========== +Running the ``shutdown_server`` command returns no output. + +Parameters +============ +The following table shows the ``shutdown_server`` parameters: + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Parameter + - Description + - Example + - Default + * - ``is_graceful`` + - Determines the method used to shut down the server. + - Selecting ``false`` shuts down the server while queries are running. Selecting ``true`` uses the graceful shutdown method. + - NA + * - ``timeout`` + - Sets the maximum amount of minutes for the graceful shutdown method to run before the server is shut down using the standard method. + - ``([is_graceful, [30]]);`` + - Five minutes + +.. note:: Setting ``is_graceful`` to ``false`` and defining the ``timeout`` value shuts the server down mid-query after the defined time. + +You can define the ``timeout`` argument as the amount minutes after which a forceful shutdown will run, even if a graceful shutdown is in progress. + +Note that activating a forced shutdown with a timeout, such as ``select shutdown_server(false, 30)``, outputs the following error message: + +.. code-block:: postgres + + forced shutdown has no timeout timer + +.. note:: You can set the timeout value using the ``defaultGracefulShutdownTimeoutMinutes`` flag in the Acceleration Studio. + +For more information, see :ref:`shutdown_server`. + +Examples +=================== +This section shows the following examples: + +**Example 1 - Activating a Forceful Shutdown** + +.. code-block:: postgres + + shutdown_server () + +**Example 2 - Activating a Graceful Shutdown** + +.. code-block:: postgres + + shutdown_server (true) + +**Example 3 - Overriding the timeout Default with Another Value** + +.. code-block:: postgres + + shutdown_server (500) + +The ``timeout`` unit is minutes. + +Permissions +============= +Using the ``shutdown_server`` command requires no special permissions. \ No newline at end of file diff --git a/sqream_studio_5.4.6/index.rst b/sqream_studio_5.4.6/index.rst deleted file mode 100644 index c4981ce81..000000000 --- a/sqream_studio_5.4.6/index.rst +++ /dev/null @@ -1,18 +0,0 @@ -.. _sqream_studio_5.4.6: - -********************************** -SQream Acceleration Studio 5.4.6 -********************************** -The SQream Acceleration Studio is a web-based client for use with SQream. Studio provides users with all functionality available from the command line in an intuitive and easy-to-use format. This includes running statements, managing roles and permissions, and managing SQream clusters. - -This section describes how to use the SQream Accleration Studio version 5.4.6: - -.. toctree:: - :maxdepth: 1 - :glob: - - getting_started_sqream - executing_statements_and_running_queries_from_the_editor - monitoring_workers_and_services_from_the_dashboard - viewing_logs - creating_assigning_and_managing_roles_and_permissions \ No newline at end of file diff --git a/sqream_studio_5.4.7/configuring_your_instance_of_sqream.rst b/sqream_studio_5.4.7/configuring_your_instance_of_sqream.rst new file mode 100644 index 000000000..3fcac7861 --- /dev/null +++ b/sqream_studio_5.4.7/configuring_your_instance_of_sqream.rst @@ -0,0 +1,23 @@ +.. _configuring_your_instance_of_sqream: + +**************************** +Configuring Your Instance of SQreams +**************************** +The **Configuration** section lets you edit parameters from one centralized location. While you can edit these parameters from the **worker configuration file (config.json)** or from your CLI, you can also modify them in Studio in an easy-to-use format. + +Configuring your instance of SQream in Studio is session-based, which enables you to edit parameters per session on your own device. +Because session-based configurations are not persistent and are deleted when your session ends, you can edit your required parameters while avoiding conflicts between parameters edited on different devices at different points in time. + +Editing Your Parameters +------------------------------- +When configuring your instance of SQream in Studio you can edit parameters for the **Generic** and **Admin** parameters only. + +Studio includes two types of parameters: toggle switches, such as **flipJoinOrder**, and text fields, such as **logSysLevel**. After editing a parameter, you can reset each one to its previous value or to its default value individually, or revert all parameters to their default setting simultaneously. Note that you must click **Save** to save your configurations. + +You can hover over the **information** icon located on each parameter to read a short description of its behavior. + +Exporting and Importing Configuration Files +------------------------- +You can also export and import your configuration settings into a .json file. This allows you to easily edit your parameters and to share this file with other users if required. + +For more information about configuring your instance of SQream, see :ref:`Configuration`. \ No newline at end of file diff --git a/sqream_studio_5.4.6/creating_assigning_and_managing_roles_and_permissions.rst b/sqream_studio_5.4.7/creating_assigning_and_managing_roles_and_permissions.rst similarity index 97% rename from sqream_studio_5.4.6/creating_assigning_and_managing_roles_and_permissions.rst rename to sqream_studio_5.4.7/creating_assigning_and_managing_roles_and_permissions.rst index b87b6f2cf..9f0f7f39a 100644 --- a/sqream_studio_5.4.6/creating_assigning_and_managing_roles_and_permissions.rst +++ b/sqream_studio_5.4.7/creating_assigning_and_managing_roles_and_permissions.rst @@ -1,6 +1,6 @@ .. _creating_assigning_and_managing_roles_and_permissions: -.. _roles_5.4.6: +.. _roles_5.4.3: **************************** Creating, Assigning, and Managing Roles and Permissions @@ -32,7 +32,7 @@ The **Type** column displays one of the following assigned role types: .. note:: If you disable a password, when you enable it you have to create a new one. -:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` +:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` Viewing Information About a Role @@ -49,7 +49,7 @@ Clicking a role in the roles table displays the following information: * **Permissions** - displays the role's permissions. The arrow indicates the permissions that the role has inherited. Hovering over a permission displays the roles that the permission is inherited from. -:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` +:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` Creating a New Role @@ -73,7 +73,7 @@ From the New Role panel you view directly and indirectly (or inherited) granted When adding a new role, you must select the **Enable login for this role** and **Has password** check boxes. -:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` +:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` Editing a Role -------------------- @@ -89,10 +89,10 @@ Once you've created a role, clicking the **Edit Role** button lets you do the fo From the Edit Role panel you view directly and indirectly (or inherited) granted permissions. Disabled permissions have no connect permissions for the referenced database and are displayed in gray text. You can add or remove permissions from the **Add permissions** field. From the Edit Role panel you can also search and scroll through the permissions. In the **Search** field you can use the **and** operator to search for strings that fulfill multiple criteria. -:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` +:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` Deleting a Role ----------------- Clicking the **delete** icon displays a confirmation message with the amount of users and groups that will be impacted by deleting the role. -:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` \ No newline at end of file +:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` \ No newline at end of file diff --git a/sqream_studio_5.4.6/executing_statements_and_running_queries_from_the_editor.rst b/sqream_studio_5.4.7/executing_statements_and_running_queries_from_the_editor.rst similarity index 86% rename from sqream_studio_5.4.6/executing_statements_and_running_queries_from_the_editor.rst rename to sqream_studio_5.4.7/executing_statements_and_running_queries_from_the_editor.rst index 8015b7c4a..0a298fdbf 100644 --- a/sqream_studio_5.4.6/executing_statements_and_running_queries_from_the_editor.rst +++ b/sqream_studio_5.4.7/executing_statements_and_running_queries_from_the_editor.rst @@ -1,6 +1,6 @@ .. _executing_statements_and_running_queries_from_the_editor: -.. _editor_top_5.4.6: +.. _editor_top_5.4.3: **************************** Executing Statements and Running Queries from the Editor @@ -14,6 +14,7 @@ The **Editor** is used for the following: The following is a brief description of the Editor panels: + .. list-table:: :widths: 10 34 56 :header-rows: 1 @@ -22,21 +23,23 @@ The following is a brief description of the Editor panels: - Element - Description * - 1 - - :ref:`Toolbar` + - :ref:`Toolbar` - Used to select the active database you want to work on, limit the number of rows, save query, etc. * - 2 - - :ref:`Database Tree and System Queries panel` + - :ref:`Database Tree and System Queries panel` - Shows a hierarchy tree of databases, views, tables, and columns * - 3 - - :ref:`Statement panel` + - :ref:`Statement panel` - Used for writing queries and statements * - 4 - - :ref:`Results panel` + - :ref:`Results panel` - Shows query results and execution information. -.. _top_5.4.6: -.. _studio_5.4.6_editor_toolbar: + +.. _top_5.4.3: + +.. _studio_5.4.3_editor_toolbar: Executing Statements from the Toolbar ================ @@ -70,16 +73,22 @@ You can access the following from the Toolbar pane: * **Max Rows** - By default, the Editor fetches only the first 10,000 rows. You can modify this number by selecting an option from the **Max Rows** dropdown list. Note that setting a higher number may slow down your browser if the result is very large. This number is limited to 100,000 results. To see a higher number, you can save the results in a file or a table using the :ref:`create_table_as` command. -For more information on stopping active statements, see the :ref:`SHUTDOWN_SERVER` command. -:ref:`Back to Executing Statements and Running Queries from the Editor` +For more information on stopping active statements, see the :ref:`STOP_STATEMENT` command. -.. _studio_5.4.6_editor_db_tree: +:ref:`Back to Executing Statements and Running Queries from the Editor` + + +.. _studio_5.4.3_editor_db_tree: Performing Statement-Related Operations from the Database Tree ================ From the Database Tree you can perform statement-related operations and show metadata (such as a number indicating the amount of rows in the table). + + + + The database object functions are used to perform the following: * The **SELECT** statement - copies the selected table's **columns** into the Statement panel as ``SELECT`` parameters. @@ -170,8 +179,7 @@ The database object functions are used to perform the following: .. |keep-tabs| image:: /_static/images/studio_keep_tabs.png :align: middle - - :ref:`insert` + .. list-table:: :widths: 30 70 @@ -180,23 +188,23 @@ The database object functions are used to perform the following: * - Function - Description * - Insert statement - - Generates an :ref:`insert` statement for the selected table in the editing area. + - Generates an `INSERT `_ statement for the selected table in the editing area. * - Delete statement - - Generates a :ref:`delete` statement for the selected table in the editing area. + - Generates a `DELETE `_ statement for the selected table in the editing area. * - Create Table As statement - - Generates a `CREATE TABLE AS `_ statement for the selected table in the editing area. + - Generates a `CREATE TABLE AS `_ statement for the selected table in the editing area. * - Rename statement - - Generates an :ref:`rename_table` statement for renaming the selected table in the editing area. + - Generates an `RENAME TABLE AS `_ statement for renaming the selected table in the editing area. * - Adding column statement - - Generates an :ref:`add_column` statement for adding columns to the selected table in the editing area. + - Generates an `ADD COLUMN `_ statement for adding columns to the selected table in the editing area. * - Truncate table statement - - Generates a :ref:`truncate` statement for the selected table in the editing area. + - Generates a `TRUNCATE_IF_EXISTS `_ statement for the selected table in the editing area. * - Drop table statement - Generates a ``DROP`` statement for the selected object in the editing area. * - Table DDL - - Generates a DDL statement for the selected object in the editing area. To get the entire database DDL, click the |icon-ddl-edit| icon next to the database name in the tree root. See :ref:`seeing_system_objects_as_ddl`. + - Generates a DDL statement for the selected object in the editing area. To get the entire database DDL, click the |icon-ddl-edit| icon next to the database name in the tree root. See `Seeing System Objects as DDL `_. * - DDL Optimizer - - The `DDL Optimizer `_ lets you analyze database tables and recommends possible optimizations. + - The `DDL Optimizer `_ lets you analyze database tables and recommends possible optimizations. Optimizing Database Tables Using the DDL Optimizer ----------------------- @@ -221,7 +229,7 @@ The following table describes the DDL Optimizer screen: Clicking **Run Optimizer** adds a tab to the Statement panel showing the optimized results of the selected object. -For more information, see :ref:`sql_best_practices`. +For more information, see `Optimization and Best Practices `_. Executing Pre-Defined Queries from the System Queries Panel --------------- @@ -235,7 +243,7 @@ The **System Queries** panel lets you execute predefined queries and includes th Clicking an item pastes the query into the Statement pane, and you can undo a previous operation by pressing **Ctrl + Z**. -.. _studio_5.4.6_editor_statement_area: +.. _studio_5.4.3_editor_statement_area: Writing Statements and Queries from the Statement Panel ============== @@ -266,7 +274,8 @@ You can add and name new tabs for each statement that you need to execute, and S You can also rename the default tab name by double-clicking it and typing a new name and write multiple statements in tandem in the same tab by separating them with semicolons (``;``).If too many tabs to fit into the Statement Pane are open at the same time, the tab arrows are displayed. You can scroll through the tabs by clicking |icon-left| or |icon-right|, and close tabs by clicking |icon-close|. You can also close all tabs at once by clicking **Close all** located to the right of the tabs. -.. tip:: If this is your first time using SQream, see :ref:`getting_started`. +.. tip:: If this is your first time using SQream, see `Getting Started `_. + .. Keyboard shortcuts .. ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -279,13 +288,13 @@ You can also rename the default tab name by double-clicking it and typing a new .. :kbd:`Ctrl` + :kbd:`↓` - Switch to previous tab -.. _studio_editor_results_5.4.6: +.. _studio_editor_results_5.4.3: -:ref:`Back to Executing Statements and Running Queries from the Editor` +:ref:`Back to Executing Statements and Running Queries from the Editor` -.. _studio_5.4.6_editor_results: +.. _studio_5.4.3_editor_results: -.. _results_panel_5.4.6: +.. _results_panel_5.4.3: Viewing Statement and Query Results from the Results Panel ============== @@ -301,17 +310,17 @@ The following is a brief description of the Results panel views highlighted in t * - Element - Description - * - :ref:`Results view` + * - :ref:`Results view` - Lets you view search query results. - * - :ref:`Execution Details view` + * - :ref:`Execution Details view` - Lets you analyze your query for troubleshooting and optimization purposes. - * - :ref:`SQL view` + * - :ref:`SQL view` - Lets you see the SQL view. -.. _results_view_5.4.6: +.. _results_view_5.4.3: -:ref:`Back to Executing Statements and Running Queries from the Editor` +:ref:`Back to Executing Statements and Running Queries from the Editor` Searching Query Results in the Results View ---------------- @@ -329,7 +338,7 @@ Saving Results to the Clipboard ^^^^^^^^^^^^ The **Save results to clipboard** function lets you save your results to the clipboard to paste into another text editor or into Excel for further analysis. -.. _save_results_to_local_file_5.4.6: +.. _save_results_to_local_file_5.4.3: Saving Results to a Local File ^^^^^^^^^^^^ @@ -337,7 +346,7 @@ The **Save results to local file** functions lets you save your search query res In the Results view you can also run parallel statements, as described in **Running Parallel Statements** below. -.. _running_parallel_statements_5.4.6: +.. _running_parallel_statements_5.4.3: Running Parallel Statements ^^^^^^^^^^^^ @@ -355,11 +364,11 @@ The following shows the syntax for running parallel statements: $ $$ -:ref:`Back to Viewing Statement and Query Results from the Results Panel` +:ref:`Back to Viewing Statement and Query Results from the Results Panel` -.. _execution_details_view_5.4.6: +.. _execution_details_view_5.4.3: -.. _execution_tree_5.4.6: +.. _execution_tree_5.4.3: Execution Details View -------------- @@ -468,16 +477,16 @@ This can be seen in the **timeSum** column as follows: * **Rows highlighted orange** - medium runtime * **Rows highlighted yellow** - shortest runtime -:ref:`Back to Viewing Statement and Query Results from the Results Panel` +:ref:`Back to Viewing Statement and Query Results from the Results Panel` -.. _sql_view_5.4.6: +.. _sql_view_5.4.3: Viewing Wrapped Strings in the SQL View ------------------ The SQL View panel allows you to more easily view certain queries, such as a long string that appears on one line. The SQL View makes it easier to see by wrapping it so that you can see the entire string at once. It also reformats and organizes query syntax entered in the Statement panel for more easily locating particular segments of your queries. The SQL View is identical to the **Format SQL** feature in the Toolbar, allowing you to retain your originally constructed query while viewing a more intuitively structured snapshot of it. -.. _save_results_to_clipboard_5.4.6: +.. _save_results_to_clipboard_5.4.3: -:ref:`Back to Viewing Statement and Query Results from the Results Panel` +:ref:`Back to Viewing Statement and Query Results from the Results Panel` -:ref:`Back to Executing Statements and Running Queries from the Editor` +:ref:`Back to Executing Statements and Running Queries from the Editor` diff --git a/sqream_studio_5.4.6/getting_started_sqream.rst b/sqream_studio_5.4.7/getting_started.rst similarity index 78% rename from sqream_studio_5.4.6/getting_started_sqream.rst rename to sqream_studio_5.4.7/getting_started.rst index ea95f0c41..7f401f5fa 100644 --- a/sqream_studio_5.4.6/getting_started_sqream.rst +++ b/sqream_studio_5.4.7/getting_started.rst @@ -1,13 +1,11 @@ -.. _getting_started_sqream: +.. _getting_started: **************************** -Getting Started with SQream Acceleration Studio 5.4.6 +Getting Started with SQream Acceleration Studio 5.4.3 **************************** Setting Up and Starting Studio ---------------- -Studio is included with all dockerized installations of SQream. When starting Studio, it listens on the local machine on port 8080. - -For more information, see :ref:`running_sqream_in_a_docker_container`. +Studio is included with all `dockerized installations of SQream DB `_. When starting Studio, it listens on the local machine on port 8080. Logging In to Studio --------------- @@ -45,6 +43,8 @@ From here you can navigate between the main areas of the Studio: - Lets you view usage logs. * - :ref:`Roles` - Lets you create users and manage user permissions. + * - :ref:`Configuration` + - Lets you configure your instance of SQream. By clicking the user icon, you can also use it for logging out and viewing the following: @@ -56,6 +56,6 @@ By clicking the user icon, you can also use it for logging out and viewing the f * License storage capacity * Log out -.. _back_to_dashboard_5.4.6: +.. _back_to_dashboard_5.4.3: -.. _studio_dashboard_5.4.6: +.. _studio_dashboard_5.4.3: diff --git a/sqream_studio_5.4.7/index.rst b/sqream_studio_5.4.7/index.rst new file mode 100644 index 000000000..d98df64d5 --- /dev/null +++ b/sqream_studio_5.4.7/index.rst @@ -0,0 +1,19 @@ +.. _sqream_studio_: + +********************************** +SQream Acceleration Studio +********************************** +The SQream Acceleration Studio 5.4.3 is a web-based client for use with SQream. Studio provides users with all functionality available from the command line in an intuitive and easy-to-use format. This includes running statements, managing roles and permissions, and managing SQream clusters. + +This section describes how to use the SQream Accleration Studio version 5.4.3: + +.. toctree:: + :maxdepth: 1 + :glob: + + getting_started + monitoring_workers_and_services_from_the_dashboard + executing_statements_and_running_queries_from_the_editor + viewing_logs + creating_assigning_and_managing_roles_and_permissions + configuring_your_instance_of_sqream \ No newline at end of file diff --git a/sqream_studio_5.4.6/monitoring_workers_and_services_from_the_dashboard.rst b/sqream_studio_5.4.7/monitoring_workers_and_services_from_the_dashboard.rst similarity index 84% rename from sqream_studio_5.4.6/monitoring_workers_and_services_from_the_dashboard.rst rename to sqream_studio_5.4.7/monitoring_workers_and_services_from_the_dashboard.rst index 51dbb3941..4283f64a8 100644 --- a/sqream_studio_5.4.6/monitoring_workers_and_services_from_the_dashboard.rst +++ b/sqream_studio_5.4.7/monitoring_workers_and_services_from_the_dashboard.rst @@ -1,6 +1,6 @@ .. _monitoring_workers_and_services_from_the_dashboard: -.. _back_to_dashboard_5.4.6: +.. _back_to_dashboard_: **************************** Monitoring Workers and Services from the Dashboard @@ -27,24 +27,29 @@ The following is a brief description of the Dashboard panels: - Element - Description * - 1 - - :ref:`Services panel` + - :ref:`Services panel` - Used for viewing and monitoring the defined service queues. * - 2 - - :ref:`Workers panel` + - :ref:`Workers panel` - Monitors system health and shows each Sqreamd worker running in the cluster. * - 3 - - :ref:`License information` - - Shows the remaining amount of days left on your license. + - :ref:`License information` + - Shows the remaining amount of days left on your license. + + +.. _data_storage_panel_: + -.. _data_storage_panel_5.4.6: -:ref:`Back to Monitoring Workers and Services from the Dashboard` +:ref:`Back to Monitoring Workers and Services from the Dashboard` -.. _services_panel_5.4.6: +.. _services_panel_: Subscribing to Workers from the Services Panel -------------------------- -Services are used to categorize and associate (also known as **subscribing**) workers to particular services. The **Service** panel is used for viewing, monitoring, and adding defined in the :ref:`workload_manager`. +Services are used to categorize and associate (also known as **subscribing**) workers to particular services. The **Service** panel is used for viewing, monitoring, and adding defined `service queues `_. + + The following is a brief description of each pane: @@ -73,23 +78,23 @@ You can add a service by clicking **+ Add** and defining the service name. You can manage workers from the **Workers** panel. For more information about managing workers, see the following: -* :ref:`Managing Workers from the Workers Panel` -* `Workers `_ +* :ref:`Managing Workers from the Workers Panel` +* `Workers `_ -:ref:`Back to Monitoring Workers and Services from the Dashboard` +:ref:`Back to Monitoring Workers and Services from the Dashboard` -.. _workers_panel_5.4.6: +.. _workers_panel_: Managing Workers from the Workers Panel ------------ From the **Workers** panel you can do the following: -* :ref:`View workers ` -* :ref:`Add a worker to a service` -* :ref:`View a worker's active query information` -* :ref:`View a worker's execution plan` +* :ref:`View workers ` +* :ref:`Add a worker to a service` +* :ref:`View a worker's active query information` +* :ref:`View a worker's execution plan` -.. _view_workers_5.4.6: +.. _view_workers_: Viewing Workers ^^^^^^^^ @@ -104,7 +109,7 @@ You can hover over segments in the status bar to see the date and time correspon * **Stopped** – the worker was stopped (either deliberately or due to an error). * **Waiting** – the worker was waiting on an object locked by another worker. -.. _add_worker_to_service_5.4.6: +.. _add_worker_to_service_: Adding A Worker to A Service ^^^^^^^^^^^^^^^^^^^^^ @@ -115,14 +120,14 @@ You can add a worker to a service by clicking the **add** button. Clicking the **add** button shows the selected service's workers. You can add the selected worker to the service by clicking **Add Worker**. Adding a worker to a service does not break associations already made between that worker and other services. -.. _view_worker_query_information_5.4.6: +.. _view_worker_query_information_: Viewing A Worker's Active Query Information ^^^^^^^^^^^^^^^^^^^^^ You can view a worker's active query information by clicking **Queries**, which displays them in the selected service. -Each statement shows the **query ID**, **status**, **service queue**, **elapsed time**, **execution time**, and **estimated completion status**. In addition, each statement can be stopped or expanded to show its execution plan and progress. For more information on viewing a statement's execution plan and progress, see :ref:`Viewing a Worker's Execution Plan ` below. +Each statement shows the **query ID**, **status**, **service queue**, **elapsed time**, **execution time**, and **estimated completion status**. In addition, each statement can be stopped or expanded to show its execution plan and progress. For more information on viewing a statement's execution plan and progress, see :ref:`Viewing a Worker's Execution Plan ` below. Viewing A Worker's Host Utilization ^^^^^^^^^^^^^^^^^^^^^ @@ -133,27 +138,20 @@ While viewing a worker's query information, clicking the **down arrow** expands The graphs show the resource utilization trends over time, and the **CPU memory** and **utilization** and the **GPU utilization** values on the right. You can hover over the graph to see more information about the activity at any point on the graph. -Error notifications related to statements are displayed, and you can hover over them for more information about the error. +Error notifications related to statements are displayed, and you can hover over them for more information about the error. -.. _view_worker_execution_plan_5.4.6: + +.. _view_worker_execution_plan_: Viewing a Worker's Execution Plan -^^^^^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^ + Clicking the ellipsis in a service shows the following additional options: * **Stop Query** - stops the query. - - :: - * **Show Execution Plan** - shows the execution plan as a table. The columns in the **Show Execution Plan** table can be sorted. -For more information on the current query plan, see the following: - -* :ref:`show_node_info` - - :: - -* :ref:`show_server_status` +For more information on the current query plan, see `SHOW_NODE_INFO `_. For more information on checking active sessions across the cluster, see `SHOW_SERVER_STATUS `_. .. include:: /reference/sql/sql_statements/monitoring_commands/show_server_status.rst :start-line: 67 @@ -161,10 +159,15 @@ For more information on the current query plan, see the following: Managing Worker Status ^^^^^^^^^^^^^^^^^^^^^ + In some cases you may want to stop or restart workers for maintenance purposes. Each Worker line has a :kbd:`⋮` menu used for stopping, starting, or restarting workers. + Starting or restarting workers terminates all queries related to that worker. When you stop a worker, its background turns gray. + + + .. |icon-user| image:: /_static/images/studio_icon_user.png :align: middle @@ -243,11 +246,11 @@ Starting or restarting workers terminates all queries related to that worker. Wh .. |keep-tabs| image:: /_static/images/studio_keep_tabs.png :align: middle -:ref:`Back to Monitoring Workers and Services from the Dashboard` +:ref:`Back to Monitoring Workers and Services from the Dashboard` -.. _license_information_5.4.6: +.. _license_information_: License Information ---------------------- @@ -259,4 +262,4 @@ The license information section shows the following: .. image:: /_static/images/license_storage_capacity.png -:ref:`Back to Monitoring Workers and Services from the Dashboard` +:ref:`Back to Monitoring Workers and Services from the Dashboard` diff --git a/sqream_studio_5.4.6/viewing_logs.rst b/sqream_studio_5.4.7/viewing_logs.rst similarity index 73% rename from sqream_studio_5.4.6/viewing_logs.rst rename to sqream_studio_5.4.7/viewing_logs.rst index 4b4654c4a..7f98bea5e 100644 --- a/sqream_studio_5.4.6/viewing_logs.rst +++ b/sqream_studio_5.4.7/viewing_logs.rst @@ -1,6 +1,6 @@ .. _viewing_logs: -.. _logs_top_5.4.6: +.. _logs_top_5.4.3: **************************** Viewing Logs @@ -13,20 +13,19 @@ The **Logs** screen is used for viewing logs and includes the following elements * - Element - Description - * - :ref:`Filter area` + * - :ref:`Filter area` - Lets you filter the data shown in the table. - * - :ref:`Query tab` + * - :ref:`Query tab` - Shows basic query information logs, such as query number and the time the query was run. - * - :ref:`Session tab` + * - :ref:`Session tab` - Shows basic session information logs, such as session ID and user name. - * - :ref:`System tab` + * - :ref:`System tab` - Shows all system logs. - * - :ref:`Log lines tab` + * - :ref:`Log lines tab` - Shows the total amount of log lines. -.. note:: Because the logs are stored in the **system** database, you cannot search the logs without first creating a **system** database. When you access the **Logs** tab, SQream can automatically create a **system** database for you. -.. _filter_5.4.6: +.. _filter_5.4.3: Filtering Table Data ------------- @@ -42,9 +41,9 @@ Other filters require you to select an item from a dropdown menu: You can also export a record of all of your currently filtered logs in Excel format by clicking **Download** located above the Filter area. -.. _queries_5.4.6: +.. _queries_5.4.3: -:ref:`Back to Viewing Logs` +:ref:`Back to Viewing Logs` Viewing Query Logs @@ -63,9 +62,9 @@ From the Queries area you can see and sort by the following: In the Queries table, you can click on the **Statement ID** and **Query** items to set them as your filters. In the **Details** column you can also access additional details by clicking one of the **Details** options for a more detailed explanation of the query. -:ref:`Back to Viewing Logs` +:ref:`Back to Viewing Logs` -.. _sessions_5.4.6: +.. _sessions_5.4.3: Viewing Session Logs ---------- @@ -83,9 +82,9 @@ From here you can see and sort by the following: In the Sessions table, you can click on the **Timestamp**, **Connection ID**, and **Username** items to set them as your filters. -:ref:`Back to Viewing Logs` +:ref:`Back to Viewing Logs` -.. _system_5.4.6: +.. _system_5.4.3: Viewing System Logs ---------- @@ -99,6 +98,25 @@ From here you can see and sort by the following: In the Systems table, you can click on the **Timestamp** and **Log type** items to set them as your filters. In the **Message** column, you can also click on an item to show more information about the message. -:ref:`Back to Viewing Logs` +:ref:`Back to Viewing Logs` -.. _log_lines_5.4.6: \ No newline at end of file +.. _log_lines_5.4.3: + +Viewing All Log Lines +---------- +The **LOG LINES** tab is used for viewing the total amount of log lines in a table. From here users can view a more granular breakdown of log information collected by Studio. The other tabs (QUERIES, SESSIONS, and SYSTEM) show a filtered form of the raw log lines. For example, the QUERIES tab shows an aggregation of several log lines. + +From here you can see and sort by the following: + +* Timestamp +* Message level +* Worker hostname +* Worker port +* Connection ID +* Database name +* User name +* Statement ID + +In the **LOG LINES** table, you can click on any of the items to set them as your filters. + +:ref:`Back to Viewing Logs` \ No newline at end of file diff --git a/studio_login_5.3.2.png b/studio_login_5.3.2.png deleted file mode 100644 index e888aca13a8081b0ef7c196c969d1e4235845bd0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82674 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 z 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 N=x7;gma5x^{U4w+h_wI! From 0cef12c3b0f362021ba13c4602df8517cd31959a Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 15 Aug 2022 13:33:25 +0300 Subject: [PATCH 217/316] Updated with Dor. --- feature_guides/query_healer.rst | 42 +++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/feature_guides/query_healer.rst b/feature_guides/query_healer.rst index 0180150ea..f8bb7f694 100644 --- a/feature_guides/query_healer.rst +++ b/feature_guides/query_healer.rst @@ -11,42 +11,48 @@ The **Query Healer** page describes the following: Overview ---------- -The **Query Healer** periodically examines the progress of running statements, creating a log entry for all statements exceeding the ``healerMaxInactivityHours`` flag setting. The default setting of the ``healerMaxInactivityHours`` is five hours. +The **Query Healer** periodically examines the progress of running statements, creating a log entry for all statements exceeding the ``healerMaxInactivityHours`` flag setting. The default setting of the ``healerMaxInactivityHours`` is five hours. The ``healerMaxInactivityHours`` log frequency is calculated as 5% of the flag setting. When set to to five hours (the default setting), the Query Healer triggers an examination every 15 minutes. The following is an example of a log record for a query stuck in the query detection phase for more than five hours: .. code-block:: console - 2022/05/19::20:01:25|ERROR|Healer|(0x7f07147fc700)|Stuck query found. Statement ID: 72, Last chunk producer updated: 1 WriteTable, Started on: Thu May 19 14:01:25 2022, Last updated: Thu May 19 15:01:25 2022, Stuck time: 5 hours, Max allowed stuck query time: 5 hours + |INFO|0x00007f9a497fe700:Healer|192.168.4.65|5001|-1|master|sqream|-1|sqream|0|"[ERROR]|cpp/SqrmRT/healer.cpp:140 |"Stuck query found. Statement ID: 72, Last chunk producer updated: 1. -The ``healerMaxInactivityHours`` log frequency is calculated as 5% of the flag setting. When set to to five hours (the default setting), the Query Healer triggers an examination every 15 minutes. +Once you identify the stuck worker, you can execute the ``shutdown_server`` utility function from this specific worker, as described in the next section. -Configuring the Healer +Activating a Graceful Shutdown ------------------ -The following **Administration Worker** flags are required to configure the Query Healer: - - * :ref:`is_healer_on` - Enables the Query Healer. +You can activate a graceful shutdown if your log entry says ``Stuck query found``, as shown in the example above. You can do this by setting the **shutdown_server** utility function to ``select shutdown_server();``. - :: +**To activte a graceful shutdown:** - * :ref:`healer_max_inactivity_hours` - Defines the threshold for creating a log recording a slow statement. The log includes information about the log memory, CPU and GPU. +1. Locate the IP and the Port of the stuck worker from the logs. -The ``healerMaxInactivityHours`` log frequency is calculated as 5% of the flag setting. For example, setting ``healerMaxInactivityHours`` to five hours (the default setting) triggers an examination every 15 minutes. + .. note:: The log in the previous section identifies the IP **(192.168.4.65)** and port **(5001)** referring to the stuck query. -Activating a Graceful Shutdown ------------------- -If your log entry says ``Stuck query found``, you must set the **shutdown_server** utility function to ``select shutdown_server(true);``, as in the following example: +2. From the machine of the stuck query (IP: **192.168.4.65**, port: **5001**), connect to SQream SQL client: -.. code-block:: console + .. code-block:: console - |INFO|0x00007f9a497fe700:Healer|192.168.4.65|5001|-1|master|sqream|-1|sqream|0|"[ERROR]|cpp/SqrmRT/healer.cpp:140 |"Stuck query found. Statement ID: 72, Last chunk producer updated: 1. + ./sqream sql --port=$STUCK_WORKER_IP --username=$SQREAM_USER --password=$SQREAM_PASSWORD databasename=$SQREAM_DATABASE -Note that the log above identifies the IP (192.168.4.65) and port (5001) referring to the stuck query. +3. Execute ``shutdown_server``. For more information, see the following: -* Activating the :ref:`shutdown_server_command` utility function. +* Activating the :ref:`shutdown_server_command` utility function. This page describes all of ``shutdown_server`` options. :: -* Configuring the :ref:`shutdown_server` flag. \ No newline at end of file +* Configuring the :ref:`shutdown_server` flag. + +Configuring the Healer +------------------ +The following **Administration Worker** flags are required to configure the Query Healer: + + * :ref:`is_healer_on` - Enables the Query Healer. + + :: + + * :ref:`healer_max_inactivity_hours` - Defines the threshold for creating a log recording a slow statement. The log includes information about the log memory, CPU and GPU. \ No newline at end of file From 5bdfefd47bfd95612a17b90079eb729a8a6756f3 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 15 Aug 2022 14:03:40 +0300 Subject: [PATCH 218/316] Enhanced Automatic Adaptive Compression --- releases/2022.1.2.rst | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/releases/2022.1.2.rst b/releases/2022.1.2.rst index d94916d02..389925e9d 100644 --- a/releases/2022.1.2.rst +++ b/releases/2022.1.2.rst @@ -23,15 +23,11 @@ The 2022.1.2 Release Notes include the following new features: :local: :depth: 1 -Feature 1 +Enhanced Automatic Adaptive Compression ************ - +SQream's automatic adaptive compression has been enhanced with new compression methods. This mechanism automatically uses the best compression method for each scenario, improving the compression ratio by approximately twice of that in Version 2022.1 -For more information, see - -Feature 2 -************ - +.. note:: The compression ratio is highly dependent on the nature of the compressed data and on other variables, such as ordering, cardinality and data types. For more information, see From a14f6692dcedd72e7fc1e1a02590914cdd00450e Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 15 Aug 2022 14:38:55 +0300 Subject: [PATCH 219/316] Updated - not done --- feature_guides/compression.rst | 39 +++++++++++++++++----------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/feature_guides/compression.rst b/feature_guides/compression.rst index 4472c7ded..d39cf2df4 100644 --- a/feature_guides/compression.rst +++ b/feature_guides/compression.rst @@ -3,43 +3,37 @@ *********************** Compression *********************** +The **Compression** page describes the following: + +.. contents:: + :local: + :depth: 1 .. |icon-new_dark_gray_2022.1.1.png| image:: /_static/images/new_dark_gray_2022.1.1.png :align: middle :width: 110 -SQream DB uses compression and encoding techniques to optimize query performance and save on disk space. +SQream uses a variety of compression and encoding methods to optimize query performance and to save disk space. Encoding ============= +**Encoding** is an automatic operation used to convert data into common formats. For example, certain formats are often used for data stored in columnar format, in contrast with data stored in a CSV file, which stores all data in text format. -Encoding converts data into a common format. - -When data is stored in a columnar format, it is often in a common format. This is in contrast with data stored in CSVs for example, where everything is stored in a text format. - -Because encoding uses specific data formats and encodings, it increases performance and reduces data size. +Encoding enhances performance and reduces data size by using specific data formats and encoding methods. SQream encodes data in a number of ways in accordance with the data type. For example, a **date** is stored as an **integer**, starting with **March 1st 1CE**, which is significantly more efficient than encoding the date as a string. In addition, it offers a wider range than storing it relative to the Unix Epoch. -SQream DB encodes data in several ways depending on the data type. For example, a date is stored as an integer, with March 1st 1CE as the start. This is a lot more efficient than encoding the date as a string, and offers a wider range than storing it relative to the Unix Epoch. - -Compression +Lossless Compression ============== +**Compression** transforms data into a smaller format without sacrificing accuracy, known as **lossless compression**. -Compression transforms data into a smaller format without losing accuracy (lossless). - -After encoding a set of column values, SQream DB packs the data and compresses it. +After encoding a set of column values, SQream packs the data and compresses it and decompresses it to make it accessible to users. Depending on the compression scheme used, these operations can be performed on the CPU or the GPU. Some users find that GPU compressions provide better performance. -Before data can be accessed, SQream DB needs to decompress it. - -Depending on the compression scheme, the operations can be performed on the CPU or the GPU. Some users find that GPU compressions perform better for their data. - -Automatic compression +Automatic Compression ------------------------ - -By default, SQream DB automatically compresses every column (see :ref:`Specifying compressions` below for overriding default compressions). This feature is called **automatic adaptive compression** strategy. +By default, SQream automatically compresses every column (see :ref:`Specifying compressions` below for overriding default compressions). This feature is called **automatic adaptive compression** strategy. When loading data, SQream DB automatically decides on the compression schemes for specific chunks of data by trying several compression schemes and selecting the one that performs best. SQream DB tries to balance more agressive compressions with the time and CPU/GPU time required to compress and decompress the data. -Compression strategies +Compression Methods ------------------------ .. list-table:: @@ -93,6 +87,11 @@ Compression strategies - Integer types - Optimized RLE + Delta type for built-in :ref:`identity columns`. - GPU + * - ``zlib`` + - All types + - The **basic_zlib_compressor** and **basic_zlib_decompressor** compress and decompress data in the **ZLIB** format, using **DualUseFilters** for input and output. In general, compression filters are for output, and decompression filters for input. + + .. note:: Automatic compression does not select the **zlib** compression method. .. _specifying_compressions: From 7211281d357cec3d1fcac84a10a2ab54fdd394e8 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 15 Aug 2022 20:32:06 +0300 Subject: [PATCH 220/316] Restored additional Update functionality I removed this all per Ben Esh's request before publishing 2022.1.1, with the intent to restore it in the next release. as was done here. --- .../sql_statements/dml_commands/update.rst | 119 +++++++++++++++--- 1 file changed, 100 insertions(+), 19 deletions(-) diff --git a/reference/sql/sql_statements/dml_commands/update.rst b/reference/sql/sql_statements/dml_commands/update.rst index 873cf6290..9f1d321b9 100644 --- a/reference/sql/sql_statements/dml_commands/update.rst +++ b/reference/sql/sql_statements/dml_commands/update.rst @@ -5,7 +5,7 @@ UPDATE ********************** The **UPDATE** statement page describes the following: -.. |icon-new_2022.1.1| image:: /_static/images/new_2022.1.1.png +.. |icon-new_2022.1| image:: /_static/images/new_2022.1.png :align: middle :width: 110 @@ -15,7 +15,7 @@ The **UPDATE** statement page describes the following: Overview ========== -The ``UPDATE`` command is used to modify the value of certain columns in existing rows without creating a table. +The ``UPDATE`` statement is used to modify the value of certain columns in existing rows without creating a table. It can be used to do the following: @@ -27,6 +27,8 @@ It can be used to do the following: .. warning:: Using the ``UPDATE`` command on column clustered using a cluster key can undo your clustering. +The ``UPDATE`` statement cannot be used to reference other tables in the ``WHERE`` or ``SET`` clauses. + Syntax ========== The following is the correct syntax for the ``UPDATE`` command: @@ -35,8 +37,8 @@ The following is the correct syntax for the ``UPDATE`` command: UPDATE target_table_name [[AS] alias1] SET column_name = expression [,...] - [FROM additional_table_name [[AS] alias2][,...]] - [WHERE condition] + [FROM additional_table_name [[AS] alias2][,...]] + [WHERE condition] The following is the correct syntax for triggering a clean-up: @@ -44,7 +46,6 @@ The following is the correct syntax for triggering a clean-up: SELECT cleanup_chunks('schema_name','table_name'); SELECT cleanup_extents('schema_name','table_name'); - SELECT cleanup_discarded_chunks(‘public’,’t’); Parameters ============ @@ -61,13 +62,11 @@ The following table describes the ``UPDATE`` parameters: * - ``column_name`` - Specifies the column containing the data to be updated. * - ``additional_table_name`` - - Specifies the column containing the data to be updated. + - Additional tables used in the WHERE condition for performing complex joins. * - ``condition`` - Specifies the condition for updating the data. -.. note:: A single table can appear **both** as a ``DELETE`` target *and* as a ``FROM`` table. This can be useful for deleting data based on self-join conditions. A ``SET`` clause can contain columns from tables specified in a ``FROM`` clause. For example, using the join ``WHERE`` condition updates rows in the target tables with the values of one of the matching rows. - -.. note:: Similar to a ``DELETE`` statement, an ``UPDATE`` statement may leave some uncleaned data behind, which requires a clean-up operation. +.. note:: Similar to a DELETE statement, an UPDATE statement may leave some uncleaned data behind, which requires a cleanup operation. Examples =========== @@ -76,7 +75,31 @@ The **Examples** section includes the following examples: .. contents:: :local: :depth: 1 - + +Updating an Entire Table +----------------- +The Examples section shows how to modify the value of certain columns in existing rows without creating a table. The examples are based on the following tables: + +.. image:: /_static/images/delete_optimization.png + +The following methods for updating an entire table generate the same output, and result with the ``bands`` record set to ``NULL``: + +.. code-block:: postgres + + UPDATE bands SET records_sold = 0; + +.. code-block:: postgres + + UPDATE bands SET records_sold = 0 WHERE true; + +.. code-block:: postgres + + UPDATE bands SET records_sold = 0 USING countries; + +.. code-block:: postgres + + UPDATE bands SET records_sold = 0 USING countries WHERE 1=1; + Performing Simple Updates ----------------- The following is an example of performing a simple update: @@ -84,15 +107,73 @@ The following is an example of performing a simple update: .. code-block:: postgres UPDATE bands SET records_sold = records_sold + 1 WHERE name LIKE 'The %'; + +Updating Tables that Contain Multi-Table Conditions +----------------- +The following shows an example of updating tables that contain multi-table conditions: + +.. code-block:: postgres + + UPDATE bands + SET records_sold = records_sold + 1 + WHERE EXISTS ( + SELECT 1 FROM countries + WHERE countries.id=bands.country_id + AND country.name = 'Sweden' + ); + +You can also write the statement above using the FROM clause: + +.. code-block:: psql + + UPDATE bands + SET records_sold = records_sold + 1 + FROM countries + WHERE countries.id=bands.country_id AND country.name = 'Sweden'; + +Updating Tables that Contain Multi-Table Expressions +----------------- +The following shows an example of updating tables that contain multi-table expressions: + +.. code-block:: postgres + + UPDATE bands + SET records_sold = records_sold + + CASE + WHEN c.name = 'Israel' THEN 2 + ELSE 1 + END + FROM countries c -Triggering a Clean-Up +Configuring Update Behavior ----------------- -The following section shows an example of triggering a clean-up: +The ``failOnNondeterministicUpdate`` flag is used to configure ``UPDATE`` behavior when updating tables containing multi-table expressions. This flag is needed when you use the ``FROM`` clause along with a set expression containing columns from additional tables. Doing this can cause a match to occur between a row from the target table with multiple rows from the additional tables. + +For instance, the example in the previous section sets the records sold to ``2`` when the country name is Israel. If you were to insert a new entry into this table with Israel spelled in Hebrew (using the same country ID), you would have two rows with identical country ID's. + +When this happens, both rows 5 and 6 in the ``bands`` table match both Israel entries. Because no algorithm exists for determining which entry to use, updating this table may either increase ``records_sold`` by 2 (for Israel in English) or 1 (for Israel in Hebrew). + +You must set the ``failOnNondeterministicUpdate`` flag to ``FALSE`` to prevent an error from occuring. + +Note that a similar ambiguity can occur when the Hebrew spelling is used in the following example: + +.. code-block:: postgres + + UPDATE bands + SET record_count = record_count + 1 + FROM countries c + WHERE c.name = 'Israel' + +However, the ``WHERE`` clause above prevents a match with any entry other than the defined one. Because the target table row must match with the ``WHERE`` condition at least once to be included in the UPDATE statment, this scenario does not require configuring the ``failOnNondeterministicUpdate`` flag. + +Triggering a Clean-Up +--------------------------------------- +The following shows an example of triggering a clean-up: .. code-block:: psql SELECT * FROM sqream_catalog.discarded_chunks; - SELECT cleanup_discarded_chunks('public','t'); + SELECT cleanup_discarded_chunks('public','t'); The following is an example of the output generated from the above: @@ -100,14 +181,14 @@ The following is an example of the output generated from the above: * **table_id** - 24 * **column_id** - 1 * **extent_ID** - 0 - -Locking and Concurrency -============= -Executing the ``UPDATE`` statement obtains an exclusive ``UPDATE`` lock on the target table. - + Permissions ============= Executing an ``UPDATE`` statement requires the following permissions: * Both ``UPDATE`` and ``SELECT`` permissions on the target table. -* The ``SELECT`` permission for each additional table you reference in the statement (in ither the ``FROM`` clause or ``WHERE`` subquery section). \ No newline at end of file +* The ``SELECT`` permission for each additional table you reference in the statement (in ither the ``FROM`` clause or ``WHERE`` subquery section). + +Locking and Concurrency +============= +Executing the ``UPDATE`` statement obtains an exclusive UPDATE lock on the target table, but does not lock the destination tables. \ No newline at end of file From f1086363b279effae9cad39a60944b291d6e5e1c Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 15 Aug 2022 21:10:39 +0300 Subject: [PATCH 221/316] 2022.1.2 - Updated Compression Page Compression: added zlib method 2022.1.2 RN page: added link to Compression page --- feature_guides/compression.rst | 113 +++++++++++++++++---------------- releases/2022.1.2.rst | 9 ++- 2 files changed, 66 insertions(+), 56 deletions(-) diff --git a/feature_guides/compression.rst b/feature_guides/compression.rst index d39cf2df4..b44d78cf8 100644 --- a/feature_guides/compression.rst +++ b/feature_guides/compression.rst @@ -29,29 +29,30 @@ After encoding a set of column values, SQream packs the data and compresses it a Automatic Compression ------------------------ -By default, SQream automatically compresses every column (see :ref:`Specifying compressions` below for overriding default compressions). This feature is called **automatic adaptive compression** strategy. +By default, SQream automatically compresses every column (see :ref:`Specifying Compression Strategies` below for overriding default compressions). This feature is called **automatic adaptive compression** strategy. When loading data, SQream DB automatically decides on the compression schemes for specific chunks of data by trying several compression schemes and selecting the one that performs best. SQream DB tries to balance more agressive compressions with the time and CPU/GPU time required to compress and decompress the data. Compression Methods ------------------------ +The following table shows the available compression methods: .. list-table:: :widths: auto :header-rows: 1 - * - Compression name - - Supported data types + * - Compression Method + - Supported Data Types - Description - Location * - ``FLAT`` - All types - No compression (forced) - - - + - NA * - ``DEFAULT`` - All types - Automatic scheme selection - - - + - NA * - ``DICT`` - Integer types, dates and timestamps, short texts - @@ -89,23 +90,26 @@ Compression Methods - GPU * - ``zlib`` - All types - - The **basic_zlib_compressor** and **basic_zlib_decompressor** compress and decompress data in the **ZLIB** format, using **DualUseFilters** for input and output. In general, compression filters are for output, and decompression filters for input. - - .. note:: Automatic compression does not select the **zlib** compression method. + - The **basic_zlib_compressor** and **basic_zlib_decompressor** compress and decompress data in the **ZLIB** format, using **DualUseFilters** for input and output. In general, compression filters are for output, and decompression filters for input. + - **Comment - GPU, CPU?** + +.. note:: Automatic compression does not select the **zlib** compression method. .. _specifying_compressions: -Specifying compression strategies +Specifying Compression Strategies ---------------------------------- +When you create a table without defining any compression specifications, SQream defaults to automatic adaptive compression (``"default"``). However, you can prevent this by specifying a compression strategy when creating a table. -When creating a table without any compression specifications, SQream DB defaults to automatic adaptive compression (``"default"``). +This section describes the following compression strategies: -However, this can be overriden by specifying a compression strategy when creating a table. +.. contents:: + :local: + :depth: 1 -Explicitly specifying automatic compression +Explicitly Specifying Automatic Compression ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The following two are equivalent: +When you explicitly specify automatic compression, the following two are equivalent: .. code-block:: postgres @@ -123,11 +127,11 @@ In this version, the default compression is specified explicitly: y TEXT(50) CHECK('CS "default"') ); -Forcing no compression (flat) +Forcing No Compression ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +**Forcing no compression** is also known as "flat", and can be used in the event that you want to remove compression entirely on some columns. This may be useful for reducing CPU or GPU resource utilization at the expense of increased I/O. -In some cases, you may wish to remove compression entirely on some columns, -in order to reduce CPU or GPU resource utilization at the expense of increased I/O. +The following is an example of removing compression: .. code-block:: postgres @@ -136,14 +140,9 @@ in order to reduce CPU or GPU resource utilization at the expense of increased I y TEXT(50) -- This column will still be compressed automatically ); - -Forcing compressions +Forcing Compression ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -In some cases, you may wish to force SQream DB to use a specific compression scheme based -on your knowledge of the data. - -For example: +In other cases, you may want to force SQream to use a specific compression scheme based on your knowledge of the data, as shown in the following example: .. code-block:: postgres @@ -154,13 +153,19 @@ For example: ); - -Examining compression effectiveness +Examining Compression Effectiveness -------------------------------------- +Queries made on the internal metadata catalog can expose how effective the compression is, as well as what compression schemes were selected. -Queries to the internal metadata catalog can expose how effective the compression is, as well as what compression schemes were selected. +This section describes the following: -Here is a sample query we can use to query the catalog: +.. contents:: + :local: + :depth: 1 + +Querying the Catalog +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The following is a sample query that can be used to query the catalog: .. code-block:: postgres @@ -181,7 +186,9 @@ Here is a sample query we can use to query the catalog: GROUP BY 1, 2; -Example (subset) from the ``ontime`` table: +Example Subset from "Ontime" Table +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The following is an example (subset) from the ``ontime`` table: .. code-block:: psql @@ -271,43 +278,43 @@ Example (subset) from the ``ontime`` table: uniquecarrier | dict | 578221 | 7230705 | 11.96 | default year | rle | 6 | 2065915 | 317216.08 | default - -Notes on reading this table: +Notes on Reading the "Ontime" Table ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The following are some useful notes on reading the "Ontime" table shown above: -#. Higher numbers in the *effectiveness* column represent better compressions. 0 represents a column that wasn't compressed at all. +#. Higher numbers in the **Compression effectiveness** column represent better compressions. **0** represents a column that has **not been compressed**. -#. Column names are the internal representation. Names with ``@null`` and ``@val`` suffixes represent a nullable column's null (boolean) and values respectively, but are treated as one logical column. + :: +#. Column names are an internal representation. Names with ``@null`` and ``@val`` suffixes represent a nullable column's null (boolean) and values respectively, but are treated as one logical column. + + :: + #. The query lists all actual compressions for a column, so it may appear several times if the compression has changed mid-way through the loading (as with the ``carrierdelay`` column). -#. When ``default`` is the compression strategy, the system automatically selects the best compression. This can also mean no compression at all (``flat``). + :: + +#. When your compression strategy is ``default``, the system automatically selects the best compression, including no compression at all (``flat``). -Compression best practices +Best Practices ============================== +This section describes the best compression practices: -Let SQream DB decide on the compression strategy +.. contents:: + :local: + :depth: 1 + +Letting SQream Determine the Best Compression Strategy ---------------------------------------------------- +In general, SQream determines the best compression strategy for most cases. If you decide to override SQream's selected compression strategies, we recommend benchmarking your query and load performance **in addition to** your storage size. -In general, SQream DB will decide on the best compression strategy in most cases. - -When overriding compression strategies, we recommend benchmarking not just storage size but also query and load performance. - - -Maximize the advantage of each compression schemes +Maximizing the Advantage of Each Compression Scheme ------------------------------------------------------- - -Some compression schemes perform better when data is organized in a specific way. - -For example, to take advantage of RLE, sorting a column may result in better performance and reduced disk-space and I/O usage. +Some compression schemes perform better when data is organized in a specific way. For example, to take advantage of RLE, sorting a column may result in better performance and reduced disk-space and I/O usage. Sorting a column partially may also be beneficial. As a rule of thumb, aim for run-lengths of more than 10 consecutive values. -Choose data types that fit the data +Choosing Data Types that Fit Your Data --------------------------------------- +Adapting to the narrowest data type improves query performance while reducing disk space usage. However, smaller data types may compress better than larger types. -Adapting to the narrowest data type will improve query performance and also reduce disk space usage. -However, smaller data types may compress better than larger types. - -For example, use the smallest numeric data type that will accommodate your data. Using ``BIGINT`` for data that fits in ``INT`` or ``SMALLINT`` can use more disk space and memory for query execution. - -Using ``FLOAT`` to store integers will reduce compression's effectiveness significantly. \ No newline at end of file +For example, SQream recommends using the smallest numeric data type that will accommodate your data. Using ``BIGINT`` for data that fits in ``INT`` or ``SMALLINT`` can use more disk space and memory for query execution. Using ``FLOAT`` to store integers will reduce compression's effectiveness significantly. \ No newline at end of file diff --git a/releases/2022.1.2.rst b/releases/2022.1.2.rst index 389925e9d..c16b551a7 100644 --- a/releases/2022.1.2.rst +++ b/releases/2022.1.2.rst @@ -13,7 +13,7 @@ Version Content ---------- The 2022.1.2 Release Notes describes the following: -* Enhanced security features. +* Enhanced compression features. New Features ---------- @@ -27,9 +27,12 @@ Enhanced Automatic Adaptive Compression ************ SQream's automatic adaptive compression has been enhanced with new compression methods. This mechanism automatically uses the best compression method for each scenario, improving the compression ratio by approximately twice of that in Version 2022.1 -.. note:: The compression ratio is highly dependent on the nature of the compressed data and on other variables, such as ordering, cardinality and data types. +.. note:: The compression ratio depends on the nature of the compressed data and on other variables, such as ordering, cardinality and data types. -For more information, see +For more information, see :ref:`compression`. + +Parquet Read Optimization +************ Known Issues --------- From df0612b0bbcc2bfe8b6fd51e34ff0b4ac181efaa Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 15 Aug 2022 21:21:10 +0300 Subject: [PATCH 222/316] 2022.1.2 - Provided Parquet Read Optimization PRD Link --- releases/2022.1.2.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/releases/2022.1.2.rst b/releases/2022.1.2.rst index c16b551a7..7338c410f 100644 --- a/releases/2022.1.2.rst +++ b/releases/2022.1.2.rst @@ -29,10 +29,12 @@ SQream's automatic adaptive compression has been enhanced with new compression m .. note:: The compression ratio depends on the nature of the compressed data and on other variables, such as ordering, cardinality and data types. -For more information, see :ref:`compression`. +For more information, navigate to the **Compression Methods** table on the :ref:`compression` page. Parquet Read Optimization -************ +************ + +https://sqream.atlassian.net/wiki/spaces/PRODUCT/pages/2277998593/Parquet+read+optimization Known Issues --------- From c19e76e3b47d6efb3b507b1cacf60375836f0ddf Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 15 Aug 2022 23:50:36 +0300 Subject: [PATCH 223/316] 2022.1.2 - Update in progress --- ...automatic_foreign_table_ddl_resolution.rst | 46 +++++++++++++++++++ feature_guides/index.rst | 1 + releases/2022.1.2.rst | 6 +++ 3 files changed, 53 insertions(+) create mode 100644 feature_guides/automatic_foreign_table_ddl_resolution.rst diff --git a/feature_guides/automatic_foreign_table_ddl_resolution.rst b/feature_guides/automatic_foreign_table_ddl_resolution.rst new file mode 100644 index 000000000..3ce1cc49f --- /dev/null +++ b/feature_guides/automatic_foreign_table_ddl_resolution.rst @@ -0,0 +1,46 @@ +.. _automatic_foreign_table_ddl_resolution: + +*********************** +Automatic Foreign Table DDL Resolution +*********************** +The **Automatic Foreign Table DDL Resolution** page describes the following: + +.. contents:: + :local: + :depth: 1 + +Overview +---------- +SQream must be able to access a schema when reading and mapping external files to a foreign table. To facilitate this, you must specify the correct schema in the statement that creates the foreign table, which must also include the correct list of columns. To avoid human error related to this complex process SQream can now automatically identify the corresponding schema, saving you the time and effort required to build your schema manually. This is especially useful for particular file formats, such as Parquet, which include a built-in schema declaration. + +Usage Notes +---------- +The automatic foreign table DDL resolution feature supports Parquet, ORC, and Avro files, while using it with CSV files generates an error. You can activate this feature when you create a foreign table by omitting the column list, described in the **Syntax** section below. + +Using this feature the path you specify in the ``LOCATION`` option must point to at least one existing file. If no files exist for the schema to read, an error will be generated. You can specify the schema manually even in the event of the error above. + +.. note:: When using this feature, SQream assumes that all files in the path use the same schema. + +Syntax +---------- +The following is the syntax for using the automatic foreign table DDL resolution feature: + +.. code-block:: console + + CREATE FOREIGN TABLE table_name + [FOREIGN DATA] WRAPPER fdw_name + [OPTIONS (...)]; + +Example +---------- +The following is an example of using the automatic foreign table DDL resolution feature: + +.. code-block:: console + + create foreign table parquet_table + wrapper parquet_fdw + options (location = '/tmp/file.parquet'); + +Permissions +---------- +The automatic foreign table DDL resolution feature requires **Read** permissions. \ No newline at end of file diff --git a/feature_guides/index.rst b/feature_guides/index.rst index d70ceb705..abb975c5d 100644 --- a/feature_guides/index.rst +++ b/feature_guides/index.rst @@ -11,6 +11,7 @@ This section describes the following features: :maxdepth: 1 :titlesonly: + automatic_foreign_table_ddl_resolution query_healer data_encryption compression diff --git a/releases/2022.1.2.rst b/releases/2022.1.2.rst index 7338c410f..b5bbb34f0 100644 --- a/releases/2022.1.2.rst +++ b/releases/2022.1.2.rst @@ -23,6 +23,12 @@ The 2022.1.2 Release Notes include the following new features: :local: :depth: 1 +Automatic Foreign Table DDL Resolution +************ +When mapping external files to foreign tables, SQream now automatically identifies the required schema. This is especially useful for Parquet files, which include built-in schema declarations. + +For more information, see :ref:`automatic_foreign_table_ddl_resolution`. + Enhanced Automatic Adaptive Compression ************ SQream's automatic adaptive compression has been enhanced with new compression methods. This mechanism automatically uses the best compression method for each scenario, improving the compression ratio by approximately twice of that in Version 2022.1 From a6c452e77bdab2449177def5b1306f646d43e005 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 21 Aug 2022 11:31:23 +0300 Subject: [PATCH 224/316] Documented Parquet Optimization --- data_ingestion/avro.rst | 2 +- data_ingestion/parquet.rst | 153 +++++++++--------- external_storage_platforms/index.rst | 2 + .../storing_data_on_parquet.rst | 8 + feature_guides/compression.rst | 3 +- releases/2022.1.2.rst | 3 +- 6 files changed, 89 insertions(+), 82 deletions(-) create mode 100644 external_storage_platforms/storing_data_on_parquet.rst diff --git a/data_ingestion/avro.rst b/data_ingestion/avro.rst index b20e64d49..7679df816 100644 --- a/data_ingestion/avro.rst +++ b/data_ingestion/avro.rst @@ -352,7 +352,7 @@ The following is an example of loading a table from a directory of Avro files on CREATE TABLE users AS SELECT * FROM ext_users; -For more configuration option examples, see the `CREATE FOREIGN TABLE parameters `_. +For more configuration option examples, navigate to the :ref:`create_foreign_table` page and see the **Parameters** table. Loading a Table from a Directory of Avro Files on S3 -------------- diff --git a/data_ingestion/parquet.rst b/data_ingestion/parquet.rst index c5971e064..36ad8c613 100644 --- a/data_ingestion/parquet.rst +++ b/data_ingestion/parquet.rst @@ -3,16 +3,19 @@ ********************** Inserting Data from a Parquet File ********************** +This guide covers inserting data from Parquet files into SQream using :ref:`FOREIGN TABLE`, and describes the following; -This guide covers inserting data from Parquet files into SQream DB using :ref:`FOREIGN TABLE`. - -.. contents:: In this topic: +.. contents:: :local: + :depth: 1 -1. Prepare the files -===================== +Overview +=================== +As described in **Inserting Data from a Parquet File** section, you can insert data into SQream from Parquet files. However, because it is an open-source column-oriented data storage format, you may want to retain your data on external Parquet files instead of inserting it into SQream. SQream supports executing queries on external Parquet files. -Prepare the source Parquet files, with the following requirements: +Preparing Your Parquet Files +===================== +Prepare your source Parquet files according to the requirements described in the following table: .. list-table:: :widths: 40 5 20 20 20 20 5 5 5 5 10 @@ -120,7 +123,7 @@ Prepare the source Parquet files, with the following requirements: - - Supported [#f4]_ -* If a Parquet file has an unsupported type, such as ``enum``, ``uuid``, ``time``, ``json``, ``bson``, ``lists``, ``maps``, but the data is not referenced in the table (it does not appear in the :ref:`SELECT` query), the statement will succeed. If the column is referenced, an error will be thrown to the user, explaining that the type is not Supported, but the column may be ommited. This can be worked around. See more information in the examples. +* Your statements will succeed even if your Parquet file contains an unsupported type, such as ``enum``, ``uuid``, ``time``, ``json``, ``bson``, ``lists``, ``maps``, but the data is not referenced in the table (it does not appear in the :ref:`SELECT` query). If the column containing the unsupported type is referenced, an error message is displayed explaining that the type is not supported and that the column may be ommitted. For solutions to this error message, see more information in **Managing Unsupported Column Types** example in the **Example** section. .. rubric:: Footnotes @@ -132,35 +135,28 @@ Prepare the source Parquet files, with the following requirements: .. [#f4] Any microseconds will be rounded down to milliseconds. -2. Place Parquet files where SQream DB workers can access them +Making Parquet Files Accessible to Workers ================================================================ - -Any worker may try to access files (unless explicitly speficied with the :ref:`workload_manager`). -It is important that every node has the same view of the storage being used - meaning, every SQream DB worker should have access to the files. +To give workers access to files every node must have the same view of the storage being used. * For files hosted on NFS, ensure that the mount is accessible from all servers. -* For HDFS, ensure that SQream DB servers can access the HDFS name node with the correct user-id. See our :ref:`hdfs` guide for more information. +* For HDFS, ensure that SQream servers have access to the HDFS name node with the correct user-id. For more information, see :ref:`hdfs` guide for more information. -* For S3, ensure network access to the S3 endpoint. See our :ref:`s3` guide for more information. +* For S3, ensure network access to the S3 endpoint. For more information, see :ref:`s3` guide for more information. - -3. Figure out the table structure +Creating a Table =============================================== +Before loading data, you must build the CREATE TABLE to correspond with the file structure of the inserted table. -Prior to loading data, you will need to write out the table structure, so that it matches the file structure. - -For example, to import the data from ``nba.parquet``, we will first look at the source table: +The example in this section is based on the source nba.parquet table shown below: .. csv-table:: nba.parquet :file: nba-t10.csv :widths: auto :header-rows: 1 -* The file is stored on S3, at ``s3://sqream-demo-data/nba.parquet``. - - -We will make note of the file structure to create a matching ``CREATE EXTERNAL TABLE`` statement. +The following example shows the correct file structure used to create the ``CREATE EXTERNAL TABLE`` statement based on the nba.parquet table: .. code-block:: postgres @@ -182,71 +178,53 @@ We will make note of the file structure to create a matching ``CREATE EXTERNAL T LOCATION = 's3://sqream-demo-data/nba.parquet' ); -.. tip:: - - Types in SQream DB must match Parquet types exactly. - - If the column type isn't Supported, a possible workaround is to set it to any arbitrary type and then exclude it from subsequent queries. - - -4. Verify table contents -==================================== - -External tables do not verify file integrity or structure, so verify that the table definition matches up and contains the correct data. - -.. code-block:: psql - - t=> SELECT * FROM ext_nba LIMIT 10; - Name | Team | Number | Position | Age | Height | Weight | College | Salary - --------------+----------------+--------+----------+-----+--------+--------+-------------------+--------- - Avery Bradley | Boston Celtics | 0 | PG | 25 | 6-2 | 180 | Texas | 7730337 - Jae Crowder | Boston Celtics | 99 | SF | 25 | 6-6 | 235 | Marquette | 6796117 - John Holland | Boston Celtics | 30 | SG | 27 | 6-5 | 205 | Boston University | - R.J. Hunter | Boston Celtics | 28 | SG | 22 | 6-5 | 185 | Georgia State | 1148640 - Jonas Jerebko | Boston Celtics | 8 | PF | 29 | 6-10 | 231 | | 5000000 - Amir Johnson | Boston Celtics | 90 | PF | 29 | 6-9 | 240 | | 12000000 - Jordan Mickey | Boston Celtics | 55 | PF | 21 | 6-8 | 235 | LSU | 1170960 - Kelly Olynyk | Boston Celtics | 41 | C | 25 | 7-0 | 238 | Gonzaga | 2165160 - Terry Rozier | Boston Celtics | 12 | PG | 22 | 6-2 | 190 | Louisville | 1824360 - Marcus Smart | Boston Celtics | 36 | PG | 22 | 6-4 | 220 | Oklahoma State | 3431040 +.. tip:: An exact match must exist between the SQream and Parquet types. For unsupported column types, you can set the type to any type and exclude it from subsequent queries. -If any errors show up at this stage, verify the structure of the Parquet files and match them to the external table structure you created. +.. note:: The **nba.parquet** file is stored on S3 at ``s3://sqream-demo-data/nba.parquet``. -5. Copying data into SQream DB +Ingesting Data into SQream =================================== +This section describes the following: -To load the data into SQream DB, use the :ref:`create_table_as` statement: +.. contents:: + :local: + :depth: 1 + +Syntax +----------- +You can use the :ref:`create_table_as` statement to load the data into SQream, as shown below: .. code-block:: postgres CREATE TABLE nba AS SELECT * FROM ext_nba; -Working around unSupported column types ---------------------------------------------- +Examples +---------------- +This section describes the following examples: -Suppose you only want to load some of the columns - for example, if one of the columns isn't Supported. +.. contents:: + :local: + :depth: 1 -By ommitting unSupported columns from queries that access the ``EXTERNAL TABLE``, they will never be called, and will not cause a "type mismatch" error. +Omitting Unsupported Column Types +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When loading data, you can omit columns using the NULL as argument. You can use this argument to omit unsupported columns from queries that access external tables. By omitting them, these columns will not be called and will avoid generating a “type mismatch” error. -For this example, assume that the ``Position`` column isn't Supported because of its type. +In the example below, the ``Position column`` is not supported due its type. .. code-block:: postgres CREATE TABLE nba AS SELECT Name, Team, Number, NULL as Position, Age, Height, Weight, College, Salary FROM ext_nba; - - -- We ommitted the unSupported column `Position` from this query, and replaced it with a default ``NULL`` value, to maintain the same table structure. - -Modifying data during the copy process ------------------------------------------- +Modifying Data Before Loading +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +One of the main reasons for staging data using the ``EXTERNAL TABLE`` argument is to examine and modify table contents before loading it into SQream. -One of the main reasons for staging data with ``EXTERNAL TABLE`` is to examine the contents and modify them before loading them. +For example, we can replace **pounds** with **kilograms** using the ``CREATE TABLE AS`` statement. -Assume we are unhappy with weight being in pounds, because we want to use kilograms instead. We can apply the transformation as part of the :ref:`create_table_as` statement. - -Similar to the previous example, we will also set the ``Position`` column as a default ``NULL``. +In the example below, the ``Position column`` is set to the default ``NULL``. .. code-block:: postgres @@ -255,15 +233,9 @@ Similar to the previous example, we will also set the ``Position`` column as a d FROM ext_nba ORDER BY weight; - -Further Parquet loading examples -======================================= - -:ref:`create_foreign_table` contains several configuration options. See more in :ref:`the CREATE FOREIGN TABLE parameters section`. - - -Loading a table from a directory of Parquet files on HDFS ------------------------------------------------------------- +Loading a Table from a Directory of Parquet Files on HDFS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The following is an example of loading a table from a directory of Parquet files on HDFS: .. code-block:: postgres @@ -277,8 +249,9 @@ Loading a table from a directory of Parquet files on HDFS CREATE TABLE users AS SELECT * FROM ext_users; -Loading a table from a bucket of files on S3 ------------------------------------------------ +Loading a Table from a Directory of Parquet Files on S3 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The following is an example of loading a table from a directory of Parquet files on S3: .. code-block:: postgres @@ -292,3 +265,29 @@ Loading a table from a bucket of files on S3 ); CREATE TABLE users AS SELECT * FROM ext_users; + +For more configuration option examples, navigate to the :ref:`create_foreign_table` page and see the **Parameters** table. + +Best Practices +============ +Because external tables do not automatically verify the file integrity or structure, SQream recommends manually verifying your table output when ingesting Parquet files into SQream. This lets you determine if your table output is identical to your originally inserted table. + +The following is an example of the output based on the **nba.parquet** table: + +.. code-block:: psql + + t=> SELECT * FROM ext_nba LIMIT 10; + Name | Team | Number | Position | Age | Height | Weight | College | Salary + --------------+----------------+--------+----------+-----+--------+--------+-------------------+--------- + Avery Bradley | Boston Celtics | 0 | PG | 25 | 6-2 | 180 | Texas | 7730337 + Jae Crowder | Boston Celtics | 99 | SF | 25 | 6-6 | 235 | Marquette | 6796117 + John Holland | Boston Celtics | 30 | SG | 27 | 6-5 | 205 | Boston University | + R.J. Hunter | Boston Celtics | 28 | SG | 22 | 6-5 | 185 | Georgia State | 1148640 + Jonas Jerebko | Boston Celtics | 8 | PF | 29 | 6-10 | 231 | | 5000000 + Amir Johnson | Boston Celtics | 90 | PF | 29 | 6-9 | 240 | | 12000000 + Jordan Mickey | Boston Celtics | 55 | PF | 21 | 6-8 | 235 | LSU | 1170960 + Kelly Olynyk | Boston Celtics | 41 | C | 25 | 7-0 | 238 | Gonzaga | 2165160 + Terry Rozier | Boston Celtics | 12 | PG | 22 | 6-2 | 190 | Louisville | 1824360 + Marcus Smart | Boston Celtics | 36 | PG | 22 | 6-4 | 220 | Oklahoma State | 3431040 + +.. note:: If your table output has errors, verify that the structure of the Parquet files correctly corresponds to the external table structure that you created. \ No newline at end of file diff --git a/external_storage_platforms/index.rst b/external_storage_platforms/index.rst index 92c35ee63..b7a591d65 100644 --- a/external_storage_platforms/index.rst +++ b/external_storage_platforms/index.rst @@ -23,3 +23,5 @@ For more information, see the following: :: * :ref:`copy_to` + +.. note:: While you can ingest data into SQream from Parquet files, you can also store and run queries on data located on external Parquet files. For more information, see :ref:`parquet`. \ No newline at end of file diff --git a/external_storage_platforms/storing_data_on_parquet.rst b/external_storage_platforms/storing_data_on_parquet.rst new file mode 100644 index 000000000..0aa54dbc4 --- /dev/null +++ b/external_storage_platforms/storing_data_on_parquet.rst @@ -0,0 +1,8 @@ +.. _storing_data_on_parquet: + +*********************** +Storing Data on Parquet +*********************** +As described in the **Data Ingestion Sources** section, users can insert data into SQream from Parquet files. However, because it is an open-source column-oriented data storage format, users may want to retain their data there instead of inserting it into SQream. This requires SQream users to be able to execute queries on external Parquet files. + + diff --git a/feature_guides/compression.rst b/feature_guides/compression.rst index b44d78cf8..ee36f27f9 100644 --- a/feature_guides/compression.rst +++ b/feature_guides/compression.rst @@ -90,8 +90,7 @@ The following table shows the available compression methods: - GPU * - ``zlib`` - All types - - The **basic_zlib_compressor** and **basic_zlib_decompressor** compress and decompress data in the **ZLIB** format, using **DualUseFilters** for input and output. In general, compression filters are for output, and decompression filters for input. - - **Comment - GPU, CPU?** + - The **basic_zlib_compressor** and **basic_zlib_decompressor** compress and decompress data in the **ZLIB** format, using **DualUseFilters** for input and output. In general, compression filters are for output, and decompression filters for input. .. note:: Automatic compression does not select the **zlib** compression method. diff --git a/releases/2022.1.2.rst b/releases/2022.1.2.rst index b5bbb34f0..bd8be6a61 100644 --- a/releases/2022.1.2.rst +++ b/releases/2022.1.2.rst @@ -39,8 +39,7 @@ For more information, navigate to the **Compression Methods** table on the :ref: Parquet Read Optimization ************ - -https://sqream.atlassian.net/wiki/spaces/PRODUCT/pages/2277998593/Parquet+read+optimization +SQream now supports storing and running queries on data located on external Parquet files. For more information, see :ref:`parquet`. Known Issues --------- From bc994e8ac3c5c7633678358b103b566423a52107 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 21 Aug 2022 12:09:51 +0300 Subject: [PATCH 225/316] Prepared for release - See comment about SQ-11291 --- data_ingestion/parquet.rst | 36 ++++++++++++++++++++++-- feature_guides/compression.rst | 3 +- releases/2022.1.2.rst | 50 +++++++++++++--------------------- 3 files changed, 55 insertions(+), 34 deletions(-) diff --git a/data_ingestion/parquet.rst b/data_ingestion/parquet.rst index 36ad8c613..df09891d3 100644 --- a/data_ingestion/parquet.rst +++ b/data_ingestion/parquet.rst @@ -21,19 +21,51 @@ Prepare your source Parquet files according to the requirements described in the :widths: 40 5 20 20 20 20 5 5 5 5 10 :header-rows: 1 - * - SQream DB type → + * - SQream Type → - Parquet source + :: + + Parquet Source ↓ - ``BOOL`` + + :: + - ``TINYINT`` + + :: + - ``SMALLINT`` + + :: + - ``INT`` + + :: + - ``BIGINT`` + + :: + - ``REAL`` + + :: + - ``DOUBLE`` + + :: + - ``TEXT`` [#f0]_ + + :: + - ``DATE`` + + :: + - ``DATETIME`` + + :: + * - ``BOOLEAN`` - Supported - diff --git a/feature_guides/compression.rst b/feature_guides/compression.rst index ee36f27f9..ab26e9986 100644 --- a/feature_guides/compression.rst +++ b/feature_guides/compression.rst @@ -91,8 +91,9 @@ The following table shows the available compression methods: * - ``zlib`` - All types - The **basic_zlib_compressor** and **basic_zlib_decompressor** compress and decompress data in the **ZLIB** format, using **DualUseFilters** for input and output. In general, compression filters are for output, and decompression filters for input. + - CPU -.. note:: Automatic compression does not select the **zlib** compression method. +.. note:: Automatic compression does **not** select the ``zlib`` compression method. .. _specifying_compressions: diff --git a/releases/2022.1.2.rst b/releases/2022.1.2.rst index bd8be6a61..b3ff083e9 100644 --- a/releases/2022.1.2.rst +++ b/releases/2022.1.2.rst @@ -3,7 +3,7 @@ ************************** Release Notes 2022.1.2 ************************** -The 2022.1.2 release notes were released on x/xx/2022 and describe the following: +The 2022.1.2 release notes were released on 8/24/2022 and describe the following: .. contents:: :local: @@ -13,8 +13,16 @@ Version Content ---------- The 2022.1.2 Release Notes describes the following: +* Automatic schema identification. + + :: + * Enhanced compression features. + :: + +* Support for external Parquet files. + New Features ---------- The 2022.1.2 Release Notes include the following new features: @@ -41,43 +49,23 @@ Parquet Read Optimization ************ SQream now supports storing and running queries on data located on external Parquet files. For more information, see :ref:`parquet`. -Known Issues ---------- -The following table lists the known issues for Version 2022.1.2: - -+-------------+------------------------------------------------------------------------------------------------+ -| **SQ No.** | **Description** | -+=============+================================================================================================+ -| SQ-xxxx | Description | -+-------------+------------------------------------------------------------------------------------------------+ -| SQ-xxxx | Description | -+-------------+------------------------------------------------------------------------------------------------+ -| SQ-xxxx | Description | -+-------------+------------------------------------------------------------------------------------------------+ -| SQ-xxxx | Description | -+-------------+------------------------------------------------------------------------------------------------+ - Resolved Issues --------- The following table lists the issues that were resolved in Version 2022.1.2: -+-------------+------------------------------------------------------------------------------------------------+ -| **SQ No.** | **Description** | -+=============+================================================================================================+ -| SQ-xxxx | Description | -+-------------+------------------------------------------------------------------------------------------------+ -| SQ-xxxx | Description | -+-------------+------------------------------------------------------------------------------------------------+ -| SQ-xxxx | Description | -+-------------+------------------------------------------------------------------------------------------------+ -| SQ-xxxx | Description | -+-------------+------------------------------------------------------------------------------------------------+ ++-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+===========================================================================================================================================+ +| SQ-11273 | Clustering ``partial-partial`` optimization only occurs when copying data from CSV files. | ++-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11291 | Metadata filters were not applied when using the ``LIKE`` function, causing certain queries to run on full tables instead of sorted data. | ++-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + +**Comment** - *Was SQ-11291 just removed?* Operations and Configuration Changes -------- -The ``xxxx`` configuration flag is required for adjusting the permitted log-in attempts. - -For more information, see +No configuration changes were made. Naming Changes ------- From 30f70a8ad7394346535a1f6a54152dd426bcd96f Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 21 Aug 2022 12:19:33 +0300 Subject: [PATCH 226/316] Updated Configuration Section --- configuration_guides/configuring_sqream.rst | 22 + .../current_configuration_method.rst | 729 ------------------ .../current_method_all_configurations.rst | 431 +++++++++++ .../current_method_command_examples.rst | 36 + .../current_method_configuration_levels.rst | 33 + .../current_method_configuration_roles.rst | 17 + ...thod_configuring_your_parameter_values.rst | 40 + .../current_method_flag_types.rst | 20 + .../current_method_modification_methods.rst | 50 ++ ...showing_all_flags_in_the_catalog_table.rst | 21 + configuration_guides/index.rst | 6 +- releases/2022.1.2.rst | 2 + 12 files changed, 674 insertions(+), 733 deletions(-) create mode 100644 configuration_guides/configuring_sqream.rst delete mode 100644 configuration_guides/current_configuration_method.rst create mode 100644 configuration_guides/current_method_all_configurations.rst create mode 100644 configuration_guides/current_method_command_examples.rst create mode 100644 configuration_guides/current_method_configuration_levels.rst create mode 100644 configuration_guides/current_method_configuration_roles.rst create mode 100644 configuration_guides/current_method_configuring_your_parameter_values.rst create mode 100644 configuration_guides/current_method_flag_types.rst create mode 100644 configuration_guides/current_method_modification_methods.rst create mode 100644 configuration_guides/current_method_showing_all_flags_in_the_catalog_table.rst diff --git a/configuration_guides/configuring_sqream.rst b/configuration_guides/configuring_sqream.rst new file mode 100644 index 000000000..901af9e3d --- /dev/null +++ b/configuration_guides/configuring_sqream.rst @@ -0,0 +1,22 @@ +.. _configuring_sqream: + +************************* +Configuring SQream +************************* +The **Configuring SQream** page describes the following configuration topics: + +.. toctree:: + :maxdepth: 1 + :glob: + :titlesonly: + + current_method_configuration_levels + current_method_flag_types + current_method_configuration_roles + current_method_modification_methods + current_method_configuring_your_parameter_values + current_method_command_examples + current_method_showing_all_flags_in_the_catalog_table + current_method_all_configurations + + diff --git a/configuration_guides/current_configuration_method.rst b/configuration_guides/current_configuration_method.rst deleted file mode 100644 index 078e2dac2..000000000 --- a/configuration_guides/current_configuration_method.rst +++ /dev/null @@ -1,729 +0,0 @@ -.. _current_configuration_method: - -************************** -Configuring SQream -************************** -The **Configuring SQream** page describes SQream’s method for configuring your instance of SQream and includes the following topics: - -.. contents:: - :local: - :depth: 1 - -Overview ------ -Modifications that you make to your configurations are persistent based on whether they are made at the session or cluster level. Persistent configurations are modifications made to attributes that are retained after shutting down your system. - -Modifying Your Configuration ----- -The **Modifying Your Configuration** section describes the following: - -.. contents:: - :local: - :depth: 1 - -Modifying Your Configuration Using the Worker Configuration File -~~~~~~~~~~~ -You can modify your configuration using the **worker configuration file (config.json)**. Changes that you make to worker configuration files are persistent. Note that you can only set the attributes in your worker configuration file **before** initializing your SQream worker, and while your worker is active these attributes are read-only. - -The following is an example of a worker configuration file: - -.. code-block:: postgres - - { - “cluster”: “/home/test_user/sqream_testing_temp/sqreamdb”, - “gpu”: 0, - “licensePath”: “home/test_user/SQream/tests/license.enc”, - “machineIP”: “127.0.0.1”, - “metadataServerIp”: “127.0.0.1”, - “metadataServerPort”: “3105, - “port”: 5000, - “useConfigIP”” true, - “legacyConfigFilePath”: “home/SQream_develop/SqrmRT/utils/json/legacy_congif.json” - } - -You can access the legacy configuration file from the ``legacyConfigFilePath`` parameter shown above. If all (or most) of your workers require the same flag settings, you can set the ``legacyConfigFilePath`` attribute to the same legacy file. - -Modifying Your Configuration Using a Legacy Configuration File -~~~~~~~~~~~ -You can modify your configuration using a legacy configuration file. - -The Legacy configuration file provides access to the read/write flags used in SQream’s previous configuration method. A link to this file is provided in the **legacyConfigFilePath** parameter in the worker configuration file. - -The following is an example of the legacy configuration file: - -.. code-block:: postgres - - { - “developerMode”: true, - “reextentUse”: false, - “useClientLog”: true, - “useMetadataServer”” false - } - -Session vs Cluster Based Configuration -============================== -.. contents:: - :local: - :depth: 1 - -Cluster-Based Configuration --------------- -SQream uses cluster-based configuration, enabling you to centralize configurations for all workers on the cluster. Only flags set to the regular or cluster flag type have access to cluster-based configuration. Configurations made on the cluster level are persistent and stored at the metadata level. The parameter settings in this file are applied globally to all workers connected to it. - -For more information, see the following: - -* `Using SQream SQL `_ - modifying flag attributes from the CLI. -* `SQream Acceleration Studio `_ - modifying flag attributes from Studio. - -For more information on flag-based access to cluster-based configuration, see **Configuration Flag Types** below. - -Session-Based Configuration ----------------- -Session-based configurations are not persistent and are deleted when your session ends. This method enables you to modify all required configurations while avoiding conflicts between flag attributes modified on different devices at different points in time. - -The **SET flag_name** command is used to modify flag attributes. Any modifications you make with the **SET flag_name** command apply only to your open session, and are not saved when it ends - -For example, when the query below has completed executing, the values configured will be restored to its previous setting: - -.. code-block:: console - - set spoolMemoryGB=700; - select * from table a where date='2021-11-11' - -For more information, see the following: - -* `Using SQream SQL `_ - modifying flag attributes from the CLI. -* `SQream Acceleration Studio `_ - modifying flag attributes from Studio. - -Configuration Flag Types -========== -The flag type attribute can be set for each flag and determines its write access as follows: - -* **Administration:** session-based read/write flags that can be stored in the metadata file. -* **Cluster:** global cluster-based read/write flags that can be stored in the metadata file. -* **Worker:** single worker-based read-only flags that can be stored in the worker configuration file. - -The flag type determines which files can be accessed and which commands or commands sets users can run. - -The following table describes the file or command modification rights for each flag type: - -.. list-table:: - :widths: 20 20 20 20 - :header-rows: 1 - - * - **Flag Type** - - **Legacy Configuration File** - - **ALTER SYSTEM SET** - - **Worker Configuration File** - * - :ref:`Regular` - - Can modify - - Can modify - - Cannot modify - * - :ref:`Cluster` - - Cannot modify - - Can modify - - Cannot modify - * - :ref:`Worker` - - Cannot modify - - Cannot modify - - Can modify - -.. _regular_flag_types: - -Regular Flag Types ---------------------- -The following is an example of the correct syntax for running a **Regular** flag type command: - -.. code-block:: console - - SET spoolMemoryGB= 11; - executed - -The following table describes the Regular flag types: - -.. list-table:: - :widths: 2 5 10 - :header-rows: 1 - - * - **Command** - - **Description** - - **Example** - * - ``SET `` - - Used for modifying flag attributes. - - ``SET developerMode=true`` - * - ``SHOW / ALL`` - - Used to preset either a specific flag value or all flag values. - - ``SHOW `` - * - ``SHOW ALL LIKE`` - - Used as a wildcard character for flag names. - - ``SHOW `` - * - ``show_conf_UF`` - - Used to print all flags with the following attributes: - - * Flag name - * Default value - * Is developer mode (Boolean) - * Flag category - * Flag type - - ``rechunkThreshold,90,true,RND,regular`` - * - ``show_conf_extended UF`` - - Used to print all information output by the show_conf UF command, in addition to description, usage, data type, default value and range. - - ``compilerGetsOnlyUFs,false,generic,regular,Makes runtime pass to compiler only`` - ``utility functions names,boolean,true,false`` - * - ``show_md_flag UF`` - - Used to show a specific flag/all flags stored in the metadata file. - - - * Example 1: ``* master=> ALTER SYSTEM SET heartbeatTimeout=111;`` - * Example 2: ``* master=> select show_md_flag(‘all’); heartbeatTimeout,111`` - * Example 3: ``* master=> select show_md_flag(‘heartbeatTimeout’); heartbeatTimeout,111`` - -.. _cluster_flag_types: - -Cluster Flag Types ---------------------- -The following is an example of the correct syntax for running a **Cluster** flag type command: - -.. code-block:: console - - ALTER SYSTEM RESET useMetadataServer; - executed - -The following table describes the Cluster flag types: - -.. list-table:: - :widths: 1 5 10 - :header-rows: 1 - - * - **Command** - - **Description** - - **Example** - * - ``ALTER SYSTEM SET `` - - Used to storing or modifying flag attributes in the metadata file. - - ``ALTER SYSTEM SET `` - * - ``ALTER SYSTEM RESET `` - - Used to remove a flag or all flag attributes from the metadata file. - - ``ALTER SYSTEM RESET `` - * - ``SHOW / ALL`` - - Used to print the value of a specified value or all flag values. - - ``SHOW `` - * - ``SHOW ALL LIKE`` - - Used as a wildcard character for flag names. - - ``SHOW `` - * - ``show_conf_UF`` - - Used to print all flags with the following attributes: - - * Flag name - * Default value - * Is developer mode (Boolean) - * Flag category - * Flag type - - ``rechunkThreshold,90,true,RND,regular`` - * - ``show_conf_extended UF`` - - Used to print all information output by the show_conf UF command, in addition to description, usage, data type, default value and range. - - ``compilerGetsOnlyUFs,false,generic,regular,Makes runtime pass to compiler only`` - ``utility functions names,boolean,true,false`` - * - ``show_md_flag UF`` - - Used to show a specific flag/all flags stored in the metadata file. - - - * Example 1: ``* master=> ALTER SYSTEM SET heartbeatTimeout=111;`` - * Example 2: ``* master=> select show_md_flag(‘all’); heartbeatTimeout,111`` - * Example 3: ``* master=> select show_md_flag(‘heartbeatTimeout’); heartbeatTimeout,111`` - -.. _worker_flag_types: - -Worker Flag Types ---------------------- -The following is an example of the correct syntax for running a **Worker** flag type command: - -.. code-block:: console - - SHOW spoolMemoryGB; - -The following table describes the Worker flag types: - -.. list-table:: - :widths: 1 5 10 - :header-rows: 1 - - * - **Command** - - **Description** - - **Example** - * - ``ALTER SYSTEM SET `` - - Used to storing or modifying flag attributes in the metadata file. - - ``ALTER SYSTEM SET `` - * - ``ALTER SYSTEM RESET `` - - Used to remove a flag or all flag attributes from the metadata file. - - ``ALTER SYSTEM RESET `` - * - ``SHOW / ALL`` - - Used to print the value of a specified value or all flag values. - - ``SHOW `` - * - ``SHOW ALL LIKE`` - - Used as a wildcard character for flag names. - - ``SHOW `` - * - ``show_conf_UF`` - - Used to print all flags with the following attributes: - - * Flag name - * Default value - * Is developer mode (Boolean) - * Flag category - * Flag type - - ``rechunkThreshold,90,true,RND,regular`` - * - ``show_conf_extended UF`` - - Used to print all information output by the show_conf UF command, in addition to description, usage, data type, default value and range. - - - ``compilerGetsOnlyUFs,false,generic,regular,Makes runtime pass to compiler only`` - ``utility functions names,boolean,true,false`` - * - ``show_md_flag UF`` - - Used to show a specific flag/all flags stored in the metadata file. - - - * Example 1: ``* master=> ALTER SYSTEM SET heartbeatTimeout=111;`` - * Example 2: ``* master=> select show_md_flag(‘all’); heartbeatTimeout,111`` - * Example 3: ``* master=> select show_md_flag(‘heartbeatTimeout’); heartbeatTimeout,111`` - -All Configurations ---------------------- -The following table describes the **Generic** and **Administration** configuration flags: - -.. list-table:: - :header-rows: 1 - :widths: 1 2 1 15 1 20 - :class: my-class - :name: my-name - - * - Flag Name - - Access Control - - Modification Type - - Description - - Data Type - - Default Value - - * - ``binSizes`` - - Administration - - Regular - - Sets the custom bin size in the cache to enable high granularity bin control. - - string - - - ``16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,`` - ``131072,262144,524288,1048576,2097152,4194304,8388608,16777216,`` - ``33554432,67108864,134217728,268435456,536870912,786432000,107374,`` - ``1824,1342177280,1610612736,1879048192,2147483648,2415919104,`` - ``2684354560,2952790016,3221225472`` - - * - ``checkCudaMemory`` - - Administration - - Regular - - Sets the pad device memory allocations with safety buffers to catch out-of-bounds writes. - - boolean - - ``FALSE`` - - * - ``compilerGetsOnlyUFs`` - - Administration - - Regular - - Sets the runtime to pass only utility functions names to the compiler. - - boolean - - ``FALSE`` - - * - ``copyToRestrictUtf8`` - - Administration - - Regular - - Sets the custom bin size in the cache to enable high granularity bin control. - - boolean - - ``FALSE`` - - * - ``cpuReduceHashtableSize`` - - Administration - - Regular - - Sets the hash table size of the CpuReduce. - - uint - - ``10000`` - - * - ``csvLimitRowLength`` - - Administration - - Cluster - - Sets the maximum supported CSV row length. - - uint - - ``100000`` - - * - ``cudaMemcpyMaxSizeBytes`` - - Administration - - Regular - - Sets the chunk size for copying from CPU to GPU. If set to 0, do not divide. - - uint - - ``0`` - - * - ``CudaMemcpySynchronous`` - - Administration - - Regular - - Indicates if copying from/to GPU is synchronous. - - boolean - - ``FALSE`` - - * - ``cudaMemQuota`` - - Administration - - Worker - - Sets the percentage of total device memory to be used by the instance. - - uint - - ``90`` - - * - ``developerMode`` - - Administration - - Regular - - Enables modifying R&D flags. - - boolean - - ``FALSE`` - - * - ``enableDeviceDebugMessages`` - - Administration - - Regular - - Activates the Nvidia profiler (nvprof) markers. - - boolean - - ``FALSE`` - - * - ``enableLogDebug`` - - Administration - - Regular - - Enables creating and logging in the clientLogger_debug file. - - boolean - - ``TRUE`` - - * - ``enableNvprofMarkers`` - - Administration - - Regular - - Activates the Nvidia profiler (nvprof) markers. - - boolean - - ``FALSE`` - - * - ``endLogMessage`` - - Administration - - Regular - - Appends a string at the end of every log line. - - string - - ``EOM`` - - - - * - ``varcharIdentifiers`` - - Administration - - Regular - - Activates using varchar as an identifier. - - boolean - - ``true`` - - - - * - ``extentStorageFileSizeMB`` - - Administration - - Cluster - - Sets the minimum size in mebibytes of extents for table bulk data. - - uint - - ``20`` - - * - ``gatherMemStat`` - - Administration - - Regular - - Monitors all pinned allocations and all **memcopies** to/from device, and prints a report of pinned allocations that were not memcopied to/from the device using the **dump_pinned_misses** utility function. - - boolean - - ``FALSE`` - - * - ``increaseChunkSizeBeforeReduce`` - - Administration - - Regular - - Increases the chunk size to reduce query speed. - - boolean - - ``FALSE`` - - * - ``increaseMemFactors`` - - Administration - - Regular - - Adds rechunker before expensive chunk producer. - - boolean - - ``TRUE`` - - * - ``leveldbWriteBufferSize`` - - Administration - - Regular - - Sets the buffer size. - - uint - - ``524288`` - - * - ``machineIP`` - - Administration - - Worker - - Manual setting of reported IP. - - string - - ``127.0.0.1`` - - - - - * - ``memoryResetTriggerMB`` - - Administration - - Regular - - Sets the size of memory used during a query to trigger aborting the server. - - uint - - ``0`` - - * - ``metadataServerPort`` - - Administration - - Worker - - Sets the port used to connect to the metadata server. SQream recommends using port ranges above 1024† because ports below 1024 are usually reserved, although there are no strict limitations. Any positive number (1 - 65535) can be used. - - uint - - ``3105`` - - * - ``mtRead`` - - Administration - - Regular - - Splits large reads to multiple smaller ones and executes them concurrently. - - boolean - - ``FALSE`` - - * - ``mtReadWorkers`` - - Administration - - Regular - - Sets the number of workers to handle smaller concurrent reads. - - uint - - ``30`` - - * - ``orcImplicitCasts`` - - Administration - - Regular - - Sets the implicit cast in orc files, such as **int** to **tinyint** and vice versa. - - boolean - - ``TRUE`` - - * - ``statementLockTimeout`` - - Administration - - Regular - - Sets the timeout (seconds) for acquiring object locks before executing statements. - - uint - - ``3`` - - * - ``useConfigIP`` - - Administration - - Worker - - Activates the machineIP (true). Setting to false ignores the machineIP and automatically assigns a local network IP. This cannot be activated in a cloud scenario (on-premises only). - - boolean - - ``FALSE`` - - * - ``useLegacyDecimalLiterals`` - - Administration - - Regular - - Interprets decimal literals as **Double** instead of **Numeric**. Used to preserve legacy behavior in existing customers. - - boolean - - ``FALSE`` - - * - ``useLegacyStringLiterals`` - - Administration - - Regular - - Interprets ASCII-only strings as **VARCHAR** instead of **TEXT**. Used to preserve legacy behavior in existing customers. - - boolean - - ``FALSE`` - - * - ``flipJoinOrder`` - - Generic - - Regular - - Reorders join to force equijoins and/or equijoins sorted by table size. - - boolean - - ``FALSE`` - - * - ``limitQueryMemoryGB`` - - Generic - - Worker - - Prevents a query from processing more memory than the flag’s value. - - uint - - ``100000`` - - * - ``cacheEvictionMilliseconds`` - - Generic - - Regular - - Sets how long the cache stores contents before being flushed. - - size_t - - ``2000`` - - - * - ``cacheDiskDir`` - - Generic - - Regular - - Sets the ondisk directory location for the spool to save files on. - - size_t - - Any legal string - - - * - ``cacheDiskGB`` - - Generic - - Regular - - Sets the amount of memory (GB) to be used by Spool on the disk. - - size_t - - ``128`` - - * - ``cachePartitions`` - - Generic - - Regular - - Sets the number of partitions that the cache is split into. - - size_t - - ``4`` - - - * - ``cachePersistentDir`` - - Generic - - Regular - - Sets the persistent directory location for the spool to save files on. - - string - - Any legal string - - - * - ``cachePersistentGB`` - - Generic - - Regular - - Sets the amount of data (GB) for the cache to store persistently. - - size_t - - ``128`` - - - * - ``cacheRamGB`` - - Generic - - Regular - - Sets the amount of memory (GB) to be used by Spool InMemory. - - size_t - - ``16`` - - - - - - - - * - ``logSysLevel`` - - Generic - - Regular - - - Determines the client log level: - 0 - L_SYSTEM, - 1 - L_FATAL, - 2 - L_ERROR, - 3 - L_WARN, - 4 - L_INFO, - 5 - L_DEBUG, - 6 - L_TRACE - - uint - - ``100000`` - - * - ``maxAvgBlobSizeToCompressOnGpu`` - - Generic - - Regular - - Sets the CPU to compress columns with size above (flag’s value) * (row count). - - uint - - ``120`` - - - * - ``sessionTag`` - - Generic - - Regular - - Sets the name of the session tag. - - string - - Any legal string - - - - * - ``spoolMemoryGB`` - - Generic - - Regular - - Sets the amount of memory (GB) to be used by the server for spooling. - - uint - - ``8`` - -Configuration Commands -========== -The configuration commands are associated with particular flag types based on permissions. - -The following table describes the commands or command sets that can be run based on their flag type. Note that the flag names described in the following table are described in the :ref:`Configuration Roles` section below. - -.. list-table:: - :header-rows: 1 - :widths: 1 2 10 17 - :class: my-class - :name: my-name - - * - Flag Type - - Command - - Description - - Example - * - Regular - - ``SET `` - - Used for modifying flag attributes. - - ``SET developerMode=true`` - * - Cluster - - ``ALTER SYSTEM SET `` - - Used to storing or modifying flag attributes in the metadata file. - - ``ALTER SYSTEM SET `` - * - Cluster - - ``ALTER SYSTEM RESET `` - - Used to remove a flag or all flag attributes from the metadata file. - - ``ALTER SYSTEM RESET `` - * - Regular, Cluster, Worker - - ``SHOW / ALL`` - - Used to print the value of a specified value or all flag values. - - ``SHOW `` - * - Regular, Cluster, Worker - - ``SHOW ALL LIKE`` - - Used as a wildcard character for flag names. - - ``SHOW `` - * - Regular, Cluster, Worker - - ``show_conf_UF`` - - Used to print all flags with the following attributes: - - * Flag name - * Default value - * Is developer mode (Boolean) - * Flag category - * Flag type - - - - - ``rechunkThreshold,90,true,RND,regular`` - * - Regular, Cluster, Worker - - ``show_conf_extended UF`` - - Used to print all information output by the show_conf UF command, in addition to description, usage, data type, default value and range. - - ``spoolMemoryGB,15,false,generic,regular,Amount of memory (GB)`` - ``the server can use for spooling,”Statement that perform “”group by””,`` - ``“”order by”” or “”join”” operation(s) on large set of data will run`` - ``much faster if given enough spool memory, otherwise disk spooling will`` - ``be used resulting in performance hit.”,uint,,0-5000`` - * - Regular, Cluster, Worker - - ``show_md_flag UF`` - - Used to show a specific flag/all flags stored in the metadata file. - - - * Example 1: ``* master=> ALTER SYSTEM SET heartbeatTimeout=111;`` - * Example 2: ``* master=> select show_md_flag(‘all’); heartbeatTimeout,111`` - * Example 3: ``* master=> select show_md_flag(‘heartbeatTimeout’); heartbeatTimeout,111`` - -.. _configuration_roles: - -Configuration Roles -=========== -SQream divides flags into the following roles, each with their own set of permissions: - -* `Administration flags `_: can be modified by administrators on a session and cluster basis using the ``ALTER SYSTEM SET`` command. -* `Generic flags `_: can be modified by standard users on a session basis. - -Showing All Flags in the Catalog Table -======= -SQream uses the **sqream_catalog.parameters** catalog table for showing all flags, providing the scope (default, cluster and session), description, default value and actual value. - -The following is the correct syntax for a catalog table query: - -.. code-block:: console - - SELECT * FROM sqream_catalog.settings - -The following is an example of a catalog table query: - -.. code-block:: console - - externalTableBlobEstimate, 100, 100, default, - varcharEncoding, ascii, ascii, default, Changes the expected encoding for Varchar columns - useCrcForTextJoinKeys, true, true, default, - hiveStyleImplicitStringCasts, false, false, default, - -This guide covers the configuration files and the ``SET`` statement. \ No newline at end of file diff --git a/configuration_guides/current_method_all_configurations.rst b/configuration_guides/current_method_all_configurations.rst new file mode 100644 index 000000000..7385066af --- /dev/null +++ b/configuration_guides/current_method_all_configurations.rst @@ -0,0 +1,431 @@ +.. _current_method_all_configurations: + +************************** +All Configurations +************************** +The following table describes all **Generic** and **Administration** configuration flags: + +.. list-table:: + :header-rows: 1 + :widths: 1 2 1 15 1 20 + :class: my-class + :name: my-name + + * - Flag Name + - Access Control + - Modification Type + - Description + - Data Type + - Default Value + + * - ``binSizes`` + - Admin + - Regular + - Sets the custom bin size in the cache to enable high granularity bin control. + - string + - + ``16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,`` + ``131072,262144,524288,1048576,2097152,4194304,8388608,16777216,`` + ``33554432,67108864,134217728,268435456,536870912,786432000,107374,`` + ``1824,1342177280,1610612736,1879048192,2147483648,2415919104,`` + ``2684354560,2952790016,3221225472`` + + * - ``cacheEvictionMilliseconds`` + - Generic + - Regular + - Sets how long the cache stores contents before being flushed. + - size_t + - ``2000`` + + + * - ``cacheDiskDir`` + - Generic + - Regular + - Sets the ondisk directory location for the spool to save files on. + - size_t + - Any legal string + + + * - ``cacheDiskGB`` + - Generic + - Regular + - Sets the amount of memory (GB) to be used by Spool on the disk. + - size_t + - ``128`` + + * - ``cachePartitions`` + - Generic + - Regular + - Sets the number of partitions that the cache is split into. + - size_t + - ``4`` + + + * - ``cachePersistentDir`` + - Generic + - Regular + - Sets the persistent directory location for the spool to save files on. + - string + - Any legal string + + + * - ``cachePersistentGB`` + - Generic + - Regular + - Sets the amount of data (GB) for the cache to store persistently. + - size_t + - ``128`` + + + * - ``cacheRamGB`` + - Generic + - Regular + - Sets the amount of memory (GB) to be used by Spool InMemory. + - size_t + - ``16`` + + + + * - ``checkCudaMemory`` + - Admin + - Regular + - Sets the pad device memory allocations with safety buffers to catch out-of-bounds writes. + - boolean + - ``FALSE`` + + * - ``compilerGetsOnlyUFs`` + - Admin + - Regular + - Sets the runtime to pass only utility functions names to the compiler. + - boolean + - ``FALSE`` + + * - ``copyToRestrictUtf8`` + - Admin + - Regular + - Sets the custom bin size in the cache to enable high granularity bin control. + - boolean + - ``FALSE`` + + * - ``cpuReduceHashtableSize`` + - Admin + - Regular + - Sets the hash table size of the CpuReduce. + - uint + - ``10000`` + + * - ``csvLimitRowLength`` + - Admin + - Cluster + - Sets the maximum supported CSV row length. + - uint + - ``100000`` + + * - ``cudaMemcpyMaxSizeBytes`` + - Admin + - Regular + - Sets the chunk size for copying from CPU to GPU. If set to 0, do not divide. + - uint + - ``0`` + + * - ``CudaMemcpySynchronous`` + - Admin + - Regular + - Indicates if copying from/to GPU is synchronous. + - boolean + - ``FALSE`` + + * - ``cudaMemQuota`` + - Admin + - Worker + - Sets the percentage of total device memory to be used by the instance. + - uint + - ``90`` + + * - ``developerMode`` + - Admin + - Regular + - Enables modifying R&D flags. + - boolean + - ``FALSE`` + + * - ``enableDeviceDebugMessages`` + - Admin + - Regular + - Activates the Nvidia profiler (nvprof) markers. + - boolean + - ``FALSE`` + + * - ``enableLogDebug`` + - Admin + - Regular + - Enables creating and logging in the clientLogger_debug file. + - boolean + - ``TRUE`` + + * - ``enableNvprofMarkers`` + - Admin + - Regular + - Activates the Nvidia profiler (nvprof) markers. + - boolean + - ``FALSE`` + + * - ``endLogMessage`` + - Admin + - Regular + - Appends a string at the end of every log line. + - string + - ``EOM`` + + + + + + + + * - ``extentStorageFileSizeMB`` + - Admin + - Cluster + - Sets the minimum size in mebibytes of extents for table bulk data. + - uint + - ``20`` + + + * - ``externalTableBlobEstimate`` + - ? + - Regular + - ? + - ? + - ? + + + + + + * - ``flipJoinOrder`` + - Generic + - Regular + - Reorders join to force equijoins and/or equijoins sorted by table size. + - boolean + - ``FALSE`` + + + + * - ``gatherMemStat`` + - Admin + - Regular + - Monitors all pinned allocations and all **memcopies** to/from device, and prints a report of pinned allocations that were not memcopied to/from the device using the **dump_pinned_misses** utility function. + - boolean + - ``FALSE`` + + + * - ``healerMaxInactivityHours`` + - Admin + - Worker + - Defines the threshold for creating a log recording a slow statement. + - size_t + - ``5`` + + + + + * - ``increaseChunkSizeBeforeReduce`` + - Admin + - Regular + - Increases the chunk size to reduce query speed. + - boolean + - ``FALSE`` + + * - ``increaseMemFactors`` + - Admin + - Regular + - Adds rechunker before expensive chunk producer. + - boolean + - ``TRUE`` + + + * - ``isHealerOn`` + - Admin + - Worker + - Periodically examines the progress of running statements and logs statements exceeding the ``healerMaxInactivityHours`` flag setting. + - boolean + - ``TRUE`` + + + + + + * - ``leveldbWriteBufferSize`` + - Admin + - Regular + - Sets the buffer size. + - uint + - ``524288`` + + * - ``limitQueryMemoryGB`` + - Generic + - Worker + - Prevents a query from processing more memory than the flag’s value. + - uint + - ``100000`` + + + + + * - ``loginMaxRetries`` + - Admin + - Worker + - Sets the permitted log-in attempts. + - size_t + - ``5`` + + + + * - ``logSysLevel`` + - Generic + - Regular + - + Determines the client log level: + 0 - L_SYSTEM, + 1 - L_FATAL, + 2 - L_ERROR, + 3 - L_WARN, + 4 - L_INFO, + 5 - L_DEBUG, + 6 - L_TRACE + - uint + - ``100000`` + + + + + + * - ``machineIP`` + - Admin + - Worker + - Manual setting of reported IP. + - string + - ``127.0.0.1`` + + + * - ``maxAvgBlobSizeToCompressOnGpu`` + - Generic + - Regular + - Sets the CPU to compress columns with size above (flag’s value) * (row count). + - uint + - ``120`` + + + * - ``maxPinnedPercentageOfTotalRAM`` + - Admin + - Regular + - Sets the maximum percentage CPU RAM that pinned memory can use. + - uint + - ``70`` + + + + * - ``memMergeBlobOffsetsCount`` + - Admin + - Regular + - Sets the size of memory used during a query to trigger aborting the server. + - uint + - ``0`` + + + + * - ``memoryResetTriggerMB`` + - Admin + - Regular + - Sets the size of memory used during a query to trigger aborting the server. + - uint + - ``0`` + + * - ``metadataServerPort`` + - Admin + - Worker + - Sets the port used to connect to the metadata server. SQream recommends using port ranges above 1024† because ports below 1024 are usually reserved, although there are no strict limitations. Any positive number (1 - 65535) can be used. + - uint + - ``3105`` + + * - ``mtRead`` + - Admin + - Regular + - Splits large reads to multiple smaller ones and executes them concurrently. + - boolean + - ``FALSE`` + + * - ``mtReadWorkers`` + - Admin + - Regular + - Sets the number of workers to handle smaller concurrent reads. + - uint + - ``30`` + + * - ``orcImplicitCasts`` + - Admin + - Regular + - Sets the implicit cast in orc files, such as **int** to **tinyint** and vice versa. + - boolean + - ``TRUE`` + + + * - ``sessionTag`` + - Generic + - Regular + - Sets the name of the session tag. + - string + - Any legal string + + + + * - ``spoolMemoryGB`` + - Generic + - Regular + - Sets the amount of memory (GB) to be used by the server for spooling. + - uint + - ``8`` + + + * - ``statementLockTimeout`` + - Admin + - Regular + - Sets the timeout (seconds) for acquiring object locks before executing statements. + - uint + - ``3`` + + * - ``useConfigIP`` + - Admin + - Worker + - Activates the machineIP (true). Setting to false ignores the machineIP and automatically assigns a local network IP. This cannot be activated in a cloud scenario (on-premises only). + - boolean + - ``FALSE`` + + * - ``useLegacyDecimalLiterals`` + - Admin + - Regular + - Interprets decimal literals as **Double** instead of **Numeric**. Used to preserve legacy behavior in existing customers. + - boolean + - ``FALSE`` + + * - ``useLegacyStringLiterals`` + - Admin + - Regular + - Interprets ASCII-only strings as **VARCHAR** instead of **TEXT**. Used to preserve legacy behavior in existing customers. + - boolean + - ``FALSE`` + + + + + + + + + + * - ``varcharIdentifiers`` + - Admin + - Regular + - Activates using varchar as an identifier. + - boolean + - ``true`` \ No newline at end of file diff --git a/configuration_guides/current_method_command_examples.rst b/configuration_guides/current_method_command_examples.rst new file mode 100644 index 000000000..2f75a4711 --- /dev/null +++ b/configuration_guides/current_method_command_examples.rst @@ -0,0 +1,36 @@ +.. _current_method_command_examples: + +************************** +Command Examples +************************** +This section includes the following command examples: + +.. contents:: + :local: + :depth: 1 + +Running a Regular Flag Type Command +--------------------- +The following is an example of running a **Regular** flag type command: + +.. code-block:: console + + SET spoolMemoryGB= 11; + executed + +Running a Worker Flag Type Command +--------------------- +The following is an example of running a **Worker** flag type command: + +.. code-block:: console + + SHOW spoolMemoryGB; + +Running a Cluster Flag Type Command +--------------------- +The following is an example of running a **Cluster** flag type command: + +.. code-block:: console + + ALTER SYSTEM RESET useMetadataServer; + executed \ No newline at end of file diff --git a/configuration_guides/current_method_configuration_levels.rst b/configuration_guides/current_method_configuration_levels.rst new file mode 100644 index 000000000..47ccf32b3 --- /dev/null +++ b/configuration_guides/current_method_configuration_levels.rst @@ -0,0 +1,33 @@ +.. _current_method_configuration_levels: + +************************** +Configuration Levels +************************** +SQream's configuration parameters are based on the following hierarchy: + +.. contents:: + :local: + :depth: 1 + +Cluster-Based Configuration +-------------- +Cluster-based configuration lets you centralize configurations for all workers on the cluster. Only Regular and Cluster flag types can be modified on the cluster level. These modifications are persistent and stored at the metadata level, which are applied globally to all workers in the cluster. + +.. note:: While cluster-based configuration was designed for configuring Workers, you can only configure Worker values set to the Regular or Cluster type. + +Worker-Based Configuration +-------------- +Worker-based configuration lets you modify the configuration belong to individual workers from the worker configuration file. + +For more information on making configurations from the worker configuration file, see `Modifying Your Configuration Using a Legacy Configuration File `_. + +Session-Based Configuration +-------------- +Session-based configurations are not persistent and are deleted when your session ends. This method enables you to modify all required configurations while avoiding conflicts between flag attributes modified on different devices at different points in time. The **SET flag_name** command is used to modify flag values on the session level. Any modifications you make with the **SET flag_name** command apply only to your open session, and are not saved when it ends. + +For example, when the query below has completed executing, the values configured will be restored to its previous setting: + +.. code-block:: console + + set spoolMemoryGB=700; + select * from table a where date='2021-11-11' \ No newline at end of file diff --git a/configuration_guides/current_method_configuration_roles.rst b/configuration_guides/current_method_configuration_roles.rst new file mode 100644 index 000000000..11b7e4bfb --- /dev/null +++ b/configuration_guides/current_method_configuration_roles.rst @@ -0,0 +1,17 @@ +.. _current_method_configuration_roles: + +************************** +Configuration Roles +************************** +SQream divides flags into the following roles, each with their own set of permissions: + +* :ref:`admin_flags` - can be modified by administrators on a session and cluster basis using the ``ALTER SYSTEM SET`` command: **Comment** - *I don't think we need to mention the command here, as it's described below, and also not mentioned for Generic Flags.* + + * Regular + * Worker + * Cluster + +* :ref:`generic_flags` - can be modified by standard users on a session basis: + + * Regular + * Worker \ No newline at end of file diff --git a/configuration_guides/current_method_configuring_your_parameter_values.rst b/configuration_guides/current_method_configuring_your_parameter_values.rst new file mode 100644 index 000000000..d082db693 --- /dev/null +++ b/configuration_guides/current_method_configuring_your_parameter_values.rst @@ -0,0 +1,40 @@ +.. _current_method_configuring_your_parameter_values: + +************************** +Configuring Your Parameter Values +************************** +The method you must use to configure your parameter values depends on the configuration level. Each configuration level has its own command or set of commands used to configure values, as shown below: + ++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Configuration Level** | ++=================================================================================================================================================================================================================================================================================================================+ +| **Regular, Worker, and Cluster** | ++-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| **Command** | **Description** | **Example** | ++-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| ``SET `` | Used for modifying flag attributes. | ``SET developerMode=true`` | ++-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| ``SHOW / ALL`` | Used to preset either a specific flag value or all flag values. | ``SHOW `` | ++-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| ``SHOW ALL LIKE`` | Used as a wildcard character for flag names. | ``SHOW `` | ++-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| ``show_conf_UF`` | Used to print all flags with the following attributes: | ``rechunkThreshold,90,true,RND,regular`` | +| | | | +| | * Flag name | | +| | * Default value | | +| | * Is Developer Mode (Boolean) | | +| | * Flag category | | +| | * Flag type | | ++-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| ``show_conf_extended UF`` | Used to print all information output by the show_conf UF command, in addition to description, usage, data type, default value and range. | ``rechunkThreshold,90,true,RND,regular`` | ++-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| ``show_md_flag UF`` | Used to show a specific flag/all flags stored in the metadata file. |* Example 1: ``* master=> ALTER SYSTEM SET heartbeatTimeout=111;`` | +| | |* Example 2: ``* master=> select show_md_flag(‘all’); heartbeatTimeout,111`` | +| | |* Example 3: ``* master=> select show_md_flag(‘heartbeatTimeout’); heartbeatTimeout,111`` | ++-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| **Worker and Cluster** | ++-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| ``ALTER SYSTEM SET `` | Used for storing or modifying flag attributes in the metadata file. | ``ALTER SYSTEM SET `` | ++-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+ +| ``ALTER SYSTEM RESET `` | Used to remove a flag or all flag attributes from the metadata file. | ``ALTER SYSTEM RESET `` | ++-----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------+ \ No newline at end of file diff --git a/configuration_guides/current_method_flag_types.rst b/configuration_guides/current_method_flag_types.rst new file mode 100644 index 000000000..b1bedecba --- /dev/null +++ b/configuration_guides/current_method_flag_types.rst @@ -0,0 +1,20 @@ +.. _current_method_flag_types: + +************************** +Flag Types +************************** +SQream uses three flag types, **Cluster**, **Worker**, and **Regular**. Each of these flag types is associated with one of three hierarchical configuration levels described earlier, making it easier to configure your system. + +The highest level in the hierarchy is Cluster, which lets you set configurations across all workers in a given cluster. Modifying cluster values is **persistent**, meaning that any configurations you set are retained after shutting down your system. Configurations set at the Cluster level take the highest priority and override settings made on the Regular and Worker level **Comment** - *Confirm*. This is known as **cluster-based configuration**. Note that Cluster-based configuration lets you modify Cluster *and* Regular flag types. An example of a Cluster flag is **persisting your cache directory.** + +The second level is Worker, which lets you configure individual workers. Modifying Worker values are also **persistent**. This is known as **worker-based configuration**. Some examples of Worker flags includes **setting total device memory usage** and **setting metadata server connection port**. + +The lowest level is Regular, which means that modifying values of Regular flags affects only your current session and are not persistent. This means that they are automatically restored to their default value when the session ends. This is known as **session-based configuration**. Some examples of Regular flags includes **setting your bin size** and **setting CUDA memory**. + +To see each flag's default value, see one of the following: + +* The **Default Value** column in the :ref:`All Configurations` section. + + :: + +* The flag's individual description page, such as :ref:`Setting CUDA Memory`. \ No newline at end of file diff --git a/configuration_guides/current_method_modification_methods.rst b/configuration_guides/current_method_modification_methods.rst new file mode 100644 index 000000000..05825b07a --- /dev/null +++ b/configuration_guides/current_method_modification_methods.rst @@ -0,0 +1,50 @@ +.. _current_method_modification_methods: + +************************** +Modification Methods +************************** +SQream provides two different ways to modify your configurations. The current method is based on hierarchical configuration as described above. This method is based on making modifications on the **worker configuration file**, while you can still make modifications using the previous method using the **legacy configuration file**, both described below: + +.. contents:: + :local: + :depth: 1 + +Modifying Your Configuration Using the Worker Configuration File +------------------- +You can modify your configuration using the **worker configuration file (config.json)**. Changes that you make to worker configuration files are persistent. Note that you can only set the attributes in your worker configuration file **before** initializing your SQream worker, and while your worker is active these attributes are read-only. + +The following is an example of a worker configuration file: + +.. code-block:: postgres + + { + “cluster”: “/home/test_user/sqream_testing_temp/sqreamdb”, + “gpu”: 0, + “licensePath”: “home/test_user/SQream/tests/license.enc”, + “machineIP”: “127.0.0.1”, + “metadataServerIp”: “127.0.0.1”, + “metadataServerPort”: “3105, + “port”: 5000, + “useConfigIP”” true, + “legacyConfigFilePath”: “home/SQream_develop/SqrmRT/utils/json/legacy_congif.json” + } + +You can access the legacy configuration file from the ``legacyConfigFilePath`` parameter shown above. If all (or most) of your workers require the same flag settings, you can set the ``legacyConfigFilePath`` attribute to the same legacy file. + +Modifying Your Configuration Using a Legacy Configuration File +--------------------- +You can modify your configuration using a legacy configuration file. + +The Legacy configuration file provides access to the read/write flags used in SQream’s previous configuration method. A link to this file is provided in the **legacyConfigFilePath** parameter in the worker configuration file. + +The following is an example of the legacy configuration file: + +.. code-block:: postgres + + { + “developerMode”: true, + “reextentUse”: false, + “useClientLog”: true, + “useMetadataServer”” false + } +For more information on using the previous configuration method, see :ref:`previous_configuration_method`. \ No newline at end of file diff --git a/configuration_guides/current_method_showing_all_flags_in_the_catalog_table.rst b/configuration_guides/current_method_showing_all_flags_in_the_catalog_table.rst new file mode 100644 index 000000000..647a401b6 --- /dev/null +++ b/configuration_guides/current_method_showing_all_flags_in_the_catalog_table.rst @@ -0,0 +1,21 @@ +.. _current_method_showing_all_flags_in_the_catalog_table: + +************************** +Showing All Flags in the Catalog Table +************************** +SQream uses the **sqream_catalog.parameters** catalog table for showing all flags, providing the scope (default, cluster and session), description, default value and actual value. + +The following is the correct syntax for a catalog table query: + +.. code-block:: console + + SELECT * FROM sqream_catalog.settings + +The following is an example of a catalog table query: + +.. code-block:: console + + externalTableBlobEstimate, 100, 100, default, + varcharEncoding, ascii, ascii, default, Changes the expected encoding for Varchar columns + useCrcForTextJoinKeys, true, true, default, + hiveStyleImplicitStringCasts, false, false, default, \ No newline at end of file diff --git a/configuration_guides/index.rst b/configuration_guides/index.rst index 6a65853f0..6805bc188 100644 --- a/configuration_guides/index.rst +++ b/configuration_guides/index.rst @@ -11,8 +11,6 @@ The **Configuration Guides** page describes the following configuration informat :glob: spooling - configuration_methods + configuring_sqream configuration_flags - - - + previous_configuration_method \ No newline at end of file diff --git a/releases/2022.1.2.rst b/releases/2022.1.2.rst index b3ff083e9..385216c21 100644 --- a/releases/2022.1.2.rst +++ b/releases/2022.1.2.rst @@ -56,6 +56,8 @@ The following table lists the issues that were resolved in Version 2022.1.2: +-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ | **SQ No.** | **Description** | +=============+===========================================================================================================================================+ +| SQ-10892 | An incorrect error message was displayed when users ran the ``UPDATE`` command on foreign tables. | ++-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ | SQ-11273 | Clustering ``partial-partial`` optimization only occurs when copying data from CSV files. | +-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ | SQ-11291 | Metadata filters were not applied when using the ``LIKE`` function, causing certain queries to run on full tables instead of sorted data. | From bf59f8c7aff5844f4092acbb7be64db20047dbbb Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 21 Aug 2022 12:24:14 +0300 Subject: [PATCH 227/316] Studio 5.4.7 --- index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.rst b/index.rst index efeecb8e2..d6a37d4f7 100644 --- a/index.rst +++ b/index.rst @@ -104,7 +104,7 @@ If you're looking for an older version of the documentation, versions 1.10 throu loading_and_unloading_data/index feature_guides/index operational_guides/index - sqream_studio_5.4.6/index + sqream_studio_5.4.7/index architecture/index configuration_guides/index reference/index From 4fbc81d46972ec6a81c966d69b5aed353174c2df Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 21 Aug 2022 12:26:01 +0300 Subject: [PATCH 228/316] Studio 5.4.7 --- ...ing_and_managing_roles_and_permissions.rst | 12 ++-- ...ts_and_running_queries_from_the_editor.rst | 60 +++++++++---------- sqream_studio_5.4.7/getting_started.rst | 6 +- sqream_studio_5.4.7/index.rst | 4 +- sqream_studio_5.4.7/viewing_logs.rst | 32 +++++----- 5 files changed, 57 insertions(+), 57 deletions(-) diff --git a/sqream_studio_5.4.7/creating_assigning_and_managing_roles_and_permissions.rst b/sqream_studio_5.4.7/creating_assigning_and_managing_roles_and_permissions.rst index 9f0f7f39a..31ff716cb 100644 --- a/sqream_studio_5.4.7/creating_assigning_and_managing_roles_and_permissions.rst +++ b/sqream_studio_5.4.7/creating_assigning_and_managing_roles_and_permissions.rst @@ -1,6 +1,6 @@ .. _creating_assigning_and_managing_roles_and_permissions: -.. _roles_5.4.3: +.. _roles_5.4.7: **************************** Creating, Assigning, and Managing Roles and Permissions @@ -32,7 +32,7 @@ The **Type** column displays one of the following assigned role types: .. note:: If you disable a password, when you enable it you have to create a new one. -:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` +:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` Viewing Information About a Role @@ -49,7 +49,7 @@ Clicking a role in the roles table displays the following information: * **Permissions** - displays the role's permissions. The arrow indicates the permissions that the role has inherited. Hovering over a permission displays the roles that the permission is inherited from. -:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` +:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` Creating a New Role @@ -73,7 +73,7 @@ From the New Role panel you view directly and indirectly (or inherited) granted When adding a new role, you must select the **Enable login for this role** and **Has password** check boxes. -:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` +:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` Editing a Role -------------------- @@ -89,10 +89,10 @@ Once you've created a role, clicking the **Edit Role** button lets you do the fo From the Edit Role panel you view directly and indirectly (or inherited) granted permissions. Disabled permissions have no connect permissions for the referenced database and are displayed in gray text. You can add or remove permissions from the **Add permissions** field. From the Edit Role panel you can also search and scroll through the permissions. In the **Search** field you can use the **and** operator to search for strings that fulfill multiple criteria. -:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` +:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` Deleting a Role ----------------- Clicking the **delete** icon displays a confirmation message with the amount of users and groups that will be impacted by deleting the role. -:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` \ No newline at end of file +:ref:`Back to Creating, Assigning, and Managing Roles and Permissions` \ No newline at end of file diff --git a/sqream_studio_5.4.7/executing_statements_and_running_queries_from_the_editor.rst b/sqream_studio_5.4.7/executing_statements_and_running_queries_from_the_editor.rst index 0a298fdbf..882b226e0 100644 --- a/sqream_studio_5.4.7/executing_statements_and_running_queries_from_the_editor.rst +++ b/sqream_studio_5.4.7/executing_statements_and_running_queries_from_the_editor.rst @@ -1,6 +1,6 @@ .. _executing_statements_and_running_queries_from_the_editor: -.. _editor_top_5.4.3: +.. _editor_top_5.4.7: **************************** Executing Statements and Running Queries from the Editor @@ -23,23 +23,23 @@ The following is a brief description of the Editor panels: - Element - Description * - 1 - - :ref:`Toolbar` + - :ref:`Toolbar` - Used to select the active database you want to work on, limit the number of rows, save query, etc. * - 2 - - :ref:`Database Tree and System Queries panel` + - :ref:`Database Tree and System Queries panel` - Shows a hierarchy tree of databases, views, tables, and columns * - 3 - - :ref:`Statement panel` + - :ref:`Statement panel` - Used for writing queries and statements * - 4 - - :ref:`Results panel` + - :ref:`Results panel` - Shows query results and execution information. -.. _top_5.4.3: +.. _top_5.4.7: -.. _studio_5.4.3_editor_toolbar: +.. _studio_5.4.7_editor_toolbar: Executing Statements from the Toolbar ================ @@ -76,10 +76,10 @@ You can access the following from the Toolbar pane: For more information on stopping active statements, see the :ref:`STOP_STATEMENT` command. -:ref:`Back to Executing Statements and Running Queries from the Editor` +:ref:`Back to Executing Statements and Running Queries from the Editor` -.. _studio_5.4.3_editor_db_tree: +.. _studio_5.4.7_editor_db_tree: Performing Statement-Related Operations from the Database Tree ================ @@ -204,7 +204,7 @@ The database object functions are used to perform the following: * - Table DDL - Generates a DDL statement for the selected object in the editing area. To get the entire database DDL, click the |icon-ddl-edit| icon next to the database name in the tree root. See `Seeing System Objects as DDL `_. * - DDL Optimizer - - The `DDL Optimizer `_ lets you analyze database tables and recommends possible optimizations. + - The `DDL Optimizer `_ lets you analyze database tables and recommends possible optimizations. Optimizing Database Tables Using the DDL Optimizer ----------------------- @@ -243,7 +243,7 @@ The **System Queries** panel lets you execute predefined queries and includes th Clicking an item pastes the query into the Statement pane, and you can undo a previous operation by pressing **Ctrl + Z**. -.. _studio_5.4.3_editor_statement_area: +.. _studio_5.4.7_editor_statement_area: Writing Statements and Queries from the Statement Panel ============== @@ -288,13 +288,13 @@ You can also rename the default tab name by double-clicking it and typing a new .. :kbd:`Ctrl` + :kbd:`↓` - Switch to previous tab -.. _studio_editor_results_5.4.3: +.. _studio_editor_results_5.4.7: -:ref:`Back to Executing Statements and Running Queries from the Editor` +:ref:`Back to Executing Statements and Running Queries from the Editor` -.. _studio_5.4.3_editor_results: +.. _studio_5.4.7_editor_results: -.. _results_panel_5.4.3: +.. _results_panel_5.4.7: Viewing Statement and Query Results from the Results Panel ============== @@ -310,17 +310,17 @@ The following is a brief description of the Results panel views highlighted in t * - Element - Description - * - :ref:`Results view` + * - :ref:`Results view` - Lets you view search query results. - * - :ref:`Execution Details view` + * - :ref:`Execution Details view` - Lets you analyze your query for troubleshooting and optimization purposes. - * - :ref:`SQL view` + * - :ref:`SQL view` - Lets you see the SQL view. -.. _results_view_5.4.3: +.. _results_view_5.4.7: -:ref:`Back to Executing Statements and Running Queries from the Editor` +:ref:`Back to Executing Statements and Running Queries from the Editor` Searching Query Results in the Results View ---------------- @@ -338,7 +338,7 @@ Saving Results to the Clipboard ^^^^^^^^^^^^ The **Save results to clipboard** function lets you save your results to the clipboard to paste into another text editor or into Excel for further analysis. -.. _save_results_to_local_file_5.4.3: +.. _save_results_to_local_file_5.4.7: Saving Results to a Local File ^^^^^^^^^^^^ @@ -346,7 +346,7 @@ The **Save results to local file** functions lets you save your search query res In the Results view you can also run parallel statements, as described in **Running Parallel Statements** below. -.. _running_parallel_statements_5.4.3: +.. _running_parallel_statements_5.4.7: Running Parallel Statements ^^^^^^^^^^^^ @@ -364,11 +364,11 @@ The following shows the syntax for running parallel statements: $ $$ -:ref:`Back to Viewing Statement and Query Results from the Results Panel` +:ref:`Back to Viewing Statement and Query Results from the Results Panel` -.. _execution_details_view_5.4.3: +.. _execution_details_view_5.4.7: -.. _execution_tree_5.4.3: +.. _execution_tree_5.4.7: Execution Details View -------------- @@ -477,16 +477,16 @@ This can be seen in the **timeSum** column as follows: * **Rows highlighted orange** - medium runtime * **Rows highlighted yellow** - shortest runtime -:ref:`Back to Viewing Statement and Query Results from the Results Panel` +:ref:`Back to Viewing Statement and Query Results from the Results Panel` -.. _sql_view_5.4.3: +.. _sql_view_5.4.7: Viewing Wrapped Strings in the SQL View ------------------ The SQL View panel allows you to more easily view certain queries, such as a long string that appears on one line. The SQL View makes it easier to see by wrapping it so that you can see the entire string at once. It also reformats and organizes query syntax entered in the Statement panel for more easily locating particular segments of your queries. The SQL View is identical to the **Format SQL** feature in the Toolbar, allowing you to retain your originally constructed query while viewing a more intuitively structured snapshot of it. -.. _save_results_to_clipboard_5.4.3: +.. _save_results_to_clipboard_5.4.7: -:ref:`Back to Viewing Statement and Query Results from the Results Panel` +:ref:`Back to Viewing Statement and Query Results from the Results Panel` -:ref:`Back to Executing Statements and Running Queries from the Editor` +:ref:`Back to Executing Statements and Running Queries from the Editor` diff --git a/sqream_studio_5.4.7/getting_started.rst b/sqream_studio_5.4.7/getting_started.rst index 7f401f5fa..21d9348c0 100644 --- a/sqream_studio_5.4.7/getting_started.rst +++ b/sqream_studio_5.4.7/getting_started.rst @@ -1,7 +1,7 @@ .. _getting_started: **************************** -Getting Started with SQream Acceleration Studio 5.4.3 +Getting Started with SQream Acceleration Studio 5.4.7 **************************** Setting Up and Starting Studio ---------------- @@ -56,6 +56,6 @@ By clicking the user icon, you can also use it for logging out and viewing the f * License storage capacity * Log out -.. _back_to_dashboard_5.4.3: +.. _back_to_dashboard_5.4.7: -.. _studio_dashboard_5.4.3: +.. _studio_dashboard_5.4.7: diff --git a/sqream_studio_5.4.7/index.rst b/sqream_studio_5.4.7/index.rst index d98df64d5..d57789b49 100644 --- a/sqream_studio_5.4.7/index.rst +++ b/sqream_studio_5.4.7/index.rst @@ -3,9 +3,9 @@ ********************************** SQream Acceleration Studio ********************************** -The SQream Acceleration Studio 5.4.3 is a web-based client for use with SQream. Studio provides users with all functionality available from the command line in an intuitive and easy-to-use format. This includes running statements, managing roles and permissions, and managing SQream clusters. +The SQream Acceleration Studio 5.4.7 is a web-based client for use with SQream. Studio provides users with all functionality available from the command line in an intuitive and easy-to-use format. This includes running statements, managing roles and permissions, and managing SQream clusters. -This section describes how to use the SQream Accleration Studio version 5.4.3: +This section describes how to use the SQream Accleration Studio version 5.4.7: .. toctree:: :maxdepth: 1 diff --git a/sqream_studio_5.4.7/viewing_logs.rst b/sqream_studio_5.4.7/viewing_logs.rst index 7f98bea5e..c4e4b73a3 100644 --- a/sqream_studio_5.4.7/viewing_logs.rst +++ b/sqream_studio_5.4.7/viewing_logs.rst @@ -1,6 +1,6 @@ .. _viewing_logs: -.. _logs_top_5.4.3: +.. _logs_top_5.4.7: **************************** Viewing Logs @@ -13,19 +13,19 @@ The **Logs** screen is used for viewing logs and includes the following elements * - Element - Description - * - :ref:`Filter area` + * - :ref:`Filter area` - Lets you filter the data shown in the table. - * - :ref:`Query tab` + * - :ref:`Query tab` - Shows basic query information logs, such as query number and the time the query was run. - * - :ref:`Session tab` + * - :ref:`Session tab` - Shows basic session information logs, such as session ID and user name. - * - :ref:`System tab` + * - :ref:`System tab` - Shows all system logs. - * - :ref:`Log lines tab` + * - :ref:`Log lines tab` - Shows the total amount of log lines. -.. _filter_5.4.3: +.. _filter_5.4.7: Filtering Table Data ------------- @@ -41,9 +41,9 @@ Other filters require you to select an item from a dropdown menu: You can also export a record of all of your currently filtered logs in Excel format by clicking **Download** located above the Filter area. -.. _queries_5.4.3: +.. _queries_5.4.7: -:ref:`Back to Viewing Logs` +:ref:`Back to Viewing Logs` Viewing Query Logs @@ -62,9 +62,9 @@ From the Queries area you can see and sort by the following: In the Queries table, you can click on the **Statement ID** and **Query** items to set them as your filters. In the **Details** column you can also access additional details by clicking one of the **Details** options for a more detailed explanation of the query. -:ref:`Back to Viewing Logs` +:ref:`Back to Viewing Logs` -.. _sessions_5.4.3: +.. _sessions_5.4.7: Viewing Session Logs ---------- @@ -82,9 +82,9 @@ From here you can see and sort by the following: In the Sessions table, you can click on the **Timestamp**, **Connection ID**, and **Username** items to set them as your filters. -:ref:`Back to Viewing Logs` +:ref:`Back to Viewing Logs` -.. _system_5.4.3: +.. _system_5.4.7: Viewing System Logs ---------- @@ -98,9 +98,9 @@ From here you can see and sort by the following: In the Systems table, you can click on the **Timestamp** and **Log type** items to set them as your filters. In the **Message** column, you can also click on an item to show more information about the message. -:ref:`Back to Viewing Logs` +:ref:`Back to Viewing Logs` -.. _log_lines_5.4.3: +.. _log_lines_5.4.7: Viewing All Log Lines ---------- @@ -119,4 +119,4 @@ From here you can see and sort by the following: In the **LOG LINES** table, you can click on any of the items to set them as your filters. -:ref:`Back to Viewing Logs` \ No newline at end of file +:ref:`Back to Viewing Logs` \ No newline at end of file From 13261d752364c298c848b73f9f2397f4164ad217 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Sun, 21 Aug 2022 17:04:11 +0300 Subject: [PATCH 229/316] Changed title to 5.4.7 --- sqream_studio_5.4.7/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sqream_studio_5.4.7/index.rst b/sqream_studio_5.4.7/index.rst index d57789b49..17c7ae05c 100644 --- a/sqream_studio_5.4.7/index.rst +++ b/sqream_studio_5.4.7/index.rst @@ -1,7 +1,7 @@ .. _sqream_studio_: ********************************** -SQream Acceleration Studio +SQream Acceleration Studio 5.4.7 ********************************** The SQream Acceleration Studio 5.4.7 is a web-based client for use with SQream. Studio provides users with all functionality available from the command line in an intuitive and easy-to-use format. This includes running statements, managing roles and permissions, and managing SQream clusters. From 5bb47aaef6c231fbcacb9572eb1d65014e6123ae Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 22 Aug 2022 17:43:10 +0300 Subject: [PATCH 230/316] Absolute links --- releases/2022.1.2.rst | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/releases/2022.1.2.rst b/releases/2022.1.2.rst index 385216c21..8f7fcc8f6 100644 --- a/releases/2022.1.2.rst +++ b/releases/2022.1.2.rst @@ -35,7 +35,7 @@ Automatic Foreign Table DDL Resolution ************ When mapping external files to foreign tables, SQream now automatically identifies the required schema. This is especially useful for Parquet files, which include built-in schema declarations. -For more information, see :ref:`automatic_foreign_table_ddl_resolution`. +For more information, see `Automatic Foreign Table DDL Resolution `_. Enhanced Automatic Adaptive Compression ************ @@ -43,11 +43,11 @@ SQream's automatic adaptive compression has been enhanced with new compression m .. note:: The compression ratio depends on the nature of the compressed data and on other variables, such as ordering, cardinality and data types. -For more information, navigate to the **Compression Methods** table on the :ref:`compression` page. +For more information, navigate to the **Compression Methods** table on the `Compression `_ page. Parquet Read Optimization ************ -SQream now supports storing and running queries on data located on external Parquet files. For more information, see :ref:`parquet`. +SQream now supports storing and running queries on data located on external Parquet files. For more information, see `Inserting Data from a Parquet File `_. Resolved Issues --------- @@ -60,10 +60,6 @@ The following table lists the issues that were resolved in Version 2022.1.2: +-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ | SQ-11273 | Clustering ``partial-partial`` optimization only occurs when copying data from CSV files. | +-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11291 | Metadata filters were not applied when using the ``LIKE`` function, causing certain queries to run on full tables instead of sorted data. | -+-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ - -**Comment** - *Was SQ-11291 just removed?* Operations and Configuration Changes -------- From db8995e55df536c9c1fdeb62e0a4774d7bffa687 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Mon, 22 Aug 2022 17:59:29 +0300 Subject: [PATCH 231/316] Update parquet.rst --- data_ingestion/parquet.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_ingestion/parquet.rst b/data_ingestion/parquet.rst index df09891d3..9a8e4c24b 100644 --- a/data_ingestion/parquet.rst +++ b/data_ingestion/parquet.rst @@ -11,7 +11,7 @@ This guide covers inserting data from Parquet files into SQream using :ref:`FORE Overview =================== -As described in **Inserting Data from a Parquet File** section, you can insert data into SQream from Parquet files. However, because it is an open-source column-oriented data storage format, you may want to retain your data on external Parquet files instead of inserting it into SQream. SQream supports executing queries on external Parquet files. +SQream supports inserting data into SQream from Parquet files. However, because it is an open-source column-oriented data storage format, you may want to retain your data on external Parquet files instead of inserting it into SQream. SQream supports executing queries on external Parquet files. Preparing Your Parquet Files ===================== From 242709e9e707ed47e80ce15a2fcf0bfa7d9cfd48 Mon Sep 17 00:00:00 2001 From: Ben Date: Tue, 23 Aug 2022 17:49:23 +0300 Subject: [PATCH 232/316] Corrected the 2022.1.2 release notes --- releases/2022.1.2.rst | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/releases/2022.1.2.rst b/releases/2022.1.2.rst index 8f7fcc8f6..076da49d9 100644 --- a/releases/2022.1.2.rst +++ b/releases/2022.1.2.rst @@ -17,11 +17,11 @@ The 2022.1.2 Release Notes describes the following: :: -* Enhanced compression features. +* Added `zlib` compression. :: -* Support for external Parquet files. +* Optimized queries on external Parquet tables. New Features ---------- @@ -37,17 +37,13 @@ When mapping external files to foreign tables, SQream now automatically identifi For more information, see `Automatic Foreign Table DDL Resolution `_. -Enhanced Automatic Adaptive Compression +Added `zlib` compression ************ -SQream's automatic adaptive compression has been enhanced with new compression methods. This mechanism automatically uses the best compression method for each scenario, improving the compression ratio by approximately twice of that in Version 2022.1 - -.. note:: The compression ratio depends on the nature of the compressed data and on other variables, such as ordering, cardinality and data types. - -For more information, navigate to the **Compression Methods** table on the `Compression `_ page. +Added support for the `zlib` compression algorithm. For more information, navigate to the **Compression Methods** table on the `Compression `_ page. Parquet Read Optimization ************ -SQream now supports storing and running queries on data located on external Parquet files. For more information, see `Inserting Data from a Parquet File `_. +Querying Parquet foreign tables has been optimized and is now up to 20x faster than in previous versions. Resolved Issues --------- @@ -58,7 +54,7 @@ The following table lists the issues that were resolved in Version 2022.1.2: +=============+===========================================================================================================================================+ | SQ-10892 | An incorrect error message was displayed when users ran the ``UPDATE`` command on foreign tables. | +-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11273 | Clustering ``partial-partial`` optimization only occurs when copying data from CSV files. | +| SQ-11273 | Clustering optimization only occurs when copying data from CSV files. | +-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ Operations and Configuration Changes @@ -118,4 +114,4 @@ Upgrading to v2022.1.2 :glob: :hidden: - 2022.1.2 \ No newline at end of file + 2022.1.2 From 775cd692cd19fb5d1910250420b3646aec679c5c Mon Sep 17 00:00:00 2001 From: Ben Date: Tue, 23 Aug 2022 18:08:59 +0300 Subject: [PATCH 233/316] Removed mentions of zlib in 2022.1.2 Since it was already released in 2022.1.1 --- releases/2022.1.2.rst | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/releases/2022.1.2.rst b/releases/2022.1.2.rst index 076da49d9..3a01464f0 100644 --- a/releases/2022.1.2.rst +++ b/releases/2022.1.2.rst @@ -17,10 +17,6 @@ The 2022.1.2 Release Notes describes the following: :: -* Added `zlib` compression. - - :: - * Optimized queries on external Parquet tables. New Features @@ -36,10 +32,6 @@ Automatic Foreign Table DDL Resolution When mapping external files to foreign tables, SQream now automatically identifies the required schema. This is especially useful for Parquet files, which include built-in schema declarations. For more information, see `Automatic Foreign Table DDL Resolution `_. - -Added `zlib` compression -************ -Added support for the `zlib` compression algorithm. For more information, navigate to the **Compression Methods** table on the `Compression `_ page. Parquet Read Optimization ************ @@ -54,7 +46,9 @@ The following table lists the issues that were resolved in Version 2022.1.2: +=============+===========================================================================================================================================+ | SQ-10892 | An incorrect error message was displayed when users ran the ``UPDATE`` command on foreign tables. | +-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11273 | Clustering optimization only occurs when copying data from CSV files. | +| SQ-11273 | Clustering optimization only occurs when copying data from CSV files. | ++-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11273 | Clustering optimization only occurs when copying data from CSV files. | +-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ Operations and Configuration Changes From 788b6edfe601c0e4147c890fe1e1ad97375e49b1 Mon Sep 17 00:00:00 2001 From: Ben Date: Tue, 23 Aug 2022 18:10:50 +0300 Subject: [PATCH 234/316] Fixed resolved issues table --- releases/2022.1.2.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/releases/2022.1.2.rst b/releases/2022.1.2.rst index 3a01464f0..aad45464c 100644 --- a/releases/2022.1.2.rst +++ b/releases/2022.1.2.rst @@ -48,8 +48,6 @@ The following table lists the issues that were resolved in Version 2022.1.2: +-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ | SQ-11273 | Clustering optimization only occurs when copying data from CSV files. | +-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11273 | Clustering optimization only occurs when copying data from CSV files. | -+-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ Operations and Configuration Changes -------- From 476eb971fa6fcf9134632f42fb77852db88849c6 Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 24 Aug 2022 16:36:27 +0300 Subject: [PATCH 235/316] Update JDBC version --- connecting_to_sqream/client_drivers/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connecting_to_sqream/client_drivers/index.rst b/connecting_to_sqream/client_drivers/index.rst index b230faaef..fb772853c 100644 --- a/connecting_to_sqream/client_drivers/index.rst +++ b/connecting_to_sqream/client_drivers/index.rst @@ -17,7 +17,7 @@ The following are applicable to all operating systems: * **JDBC** - recommended installation via ``mvn``: - * `JDBC .jar file `_ - sqream-jdbc-4.5.3 (.jar) + * `JDBC .jar file `_ - sqream-jdbc-4.5.4 (.jar) * `JDBC driver `_ .. _tableau_connector: @@ -81,4 +81,4 @@ If you couldn't find what you're looking for, we're always happy to help. Visit .. rubric:: Looking for older drivers? -If you're looking for an older version of SQream DB drivers, versions 1.10 through 2019.2.1 are available at https://sqream.com/product/client-drivers/. \ No newline at end of file +If you're looking for an older version of SQream DB drivers, versions 1.10 through 2019.2.1 are available at https://sqream.com/product/client-drivers/. From 0f01559929702ff0c6bbfd2b69ecc4fbbc1f0da3 Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 24 Aug 2022 16:38:59 +0300 Subject: [PATCH 236/316] Removed explicit mention of the auto schema feature --- releases/2022.1.2.rst | 6 ------ 1 file changed, 6 deletions(-) diff --git a/releases/2022.1.2.rst b/releases/2022.1.2.rst index aad45464c..a44d83d83 100644 --- a/releases/2022.1.2.rst +++ b/releases/2022.1.2.rst @@ -27,12 +27,6 @@ The 2022.1.2 Release Notes include the following new features: :local: :depth: 1 -Automatic Foreign Table DDL Resolution -************ -When mapping external files to foreign tables, SQream now automatically identifies the required schema. This is especially useful for Parquet files, which include built-in schema declarations. - -For more information, see `Automatic Foreign Table DDL Resolution `_. - Parquet Read Optimization ************ Querying Parquet foreign tables has been optimized and is now up to 20x faster than in previous versions. From 1165daf511033824c002c27750392bcb1b446709 Mon Sep 17 00:00:00 2001 From: Yaniv Gerowitz Date: Fri, 26 Aug 2022 13:27:54 -0700 Subject: [PATCH 237/316] Update 2022.1.2.rst --- releases/2022.1.2.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releases/2022.1.2.rst b/releases/2022.1.2.rst index a44d83d83..769bf60bc 100644 --- a/releases/2022.1.2.rst +++ b/releases/2022.1.2.rst @@ -100,4 +100,4 @@ Upgrading to v2022.1.2 :glob: :hidden: - 2022.1.2 + 2022.1.2 \ No newline at end of file From 0fc7ddda88024a4b91c6b7387b483c501e4aee4d Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Thu, 8 Sep 2022 08:24:11 +0300 Subject: [PATCH 238/316] Add 2022.1.3 RN page --- releases/2022.1.3.rst | 103 ++++++++++++++++++++++++++++++++++++++ releases/2022.1_index.rst | 1 + 2 files changed, 104 insertions(+) create mode 100644 releases/2022.1.3.rst diff --git a/releases/2022.1.3.rst b/releases/2022.1.3.rst new file mode 100644 index 000000000..769bf60bc --- /dev/null +++ b/releases/2022.1.3.rst @@ -0,0 +1,103 @@ +.. _2022.1.2: + +************************** +Release Notes 2022.1.2 +************************** +The 2022.1.2 release notes were released on 8/24/2022 and describe the following: + +.. contents:: + :local: + :depth: 1 + +Version Content +---------- +The 2022.1.2 Release Notes describes the following: + +* Automatic schema identification. + + :: + +* Optimized queries on external Parquet tables. + +New Features +---------- +The 2022.1.2 Release Notes include the following new features: + +.. contents:: + :local: + :depth: 1 + +Parquet Read Optimization +************ +Querying Parquet foreign tables has been optimized and is now up to 20x faster than in previous versions. + +Resolved Issues +--------- +The following table lists the issues that were resolved in Version 2022.1.2: + ++-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+===========================================================================================================================================+ +| SQ-10892 | An incorrect error message was displayed when users ran the ``UPDATE`` command on foreign tables. | ++-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11273 | Clustering optimization only occurs when copying data from CSV files. | ++-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ + +Operations and Configuration Changes +-------- +No configuration changes were made. + +Naming Changes +------- +No relevant naming changes were made. + +Deprecated Features +------- +No features were deprecated for Version 2022.1.2. + +End of Support +------- +The End of Support section is not relevant to Version 2022.1.2. + +Upgrading to v2022.1.2 +------- +1. Generate a back-up of the metadata by running the following command: + + .. code-block:: console + + $ select backup_metadata('out_path'); + + .. tip:: SQream recommends storing the generated back-up locally in case needed. + + SQream runs the Garbage Collector and creates a clean backup tarball package. + +2. Shut down all SQream services. + + :: + +3. Extract the recently created back-up file. + + :: + +4. Replace your current metadata with the metadata you stored in the back-up file. + + :: + +5. Navigate to the new SQream package bin folder. + + :: + +6. Run the following command: + + .. code-block:: console + + $ ./upgrade_storage + + .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version `_ procedure. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2022.1.2 \ No newline at end of file diff --git a/releases/2022.1_index.rst b/releases/2022.1_index.rst index 5f53bcb38..beceab0b6 100644 --- a/releases/2022.1_index.rst +++ b/releases/2022.1_index.rst @@ -13,6 +13,7 @@ The 2022.1 Release Notes describe the following releases: :maxdepth: 1 :glob: + 2022.1.3 2022.1.2 2022.1.1 2022.1 \ No newline at end of file From cc7ff075f5b7c66cc672e704dfce80e669c5a040 Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Thu, 8 Sep 2022 08:37:32 +0300 Subject: [PATCH 239/316] Update 2022.1.3.rst --- releases/2022.1.3.rst | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/releases/2022.1.3.rst b/releases/2022.1.3.rst index 769bf60bc..beeb68679 100644 --- a/releases/2022.1.3.rst +++ b/releases/2022.1.3.rst @@ -1,9 +1,9 @@ -.. _2022.1.2: +.. _2022.1.3: ************************** -Release Notes 2022.1.2 +Release Notes 2022.1.3 ************************** -The 2022.1.2 release notes were released on 8/24/2022 and describe the following: +The 2022.1.3 release notes were released on 9/8/2022 and describe the following: .. contents:: :local: @@ -11,7 +11,7 @@ The 2022.1.2 release notes were released on 8/24/2022 and describe the following Version Content ---------- -The 2022.1.2 Release Notes describes the following: +The 2022.1.3 Release Notes describes the following: * Automatic schema identification. @@ -21,7 +21,7 @@ The 2022.1.2 Release Notes describes the following: New Features ---------- -The 2022.1.2 Release Notes include the following new features: +The 2022.1.3 Release Notes include the following new features: .. contents:: :local: @@ -33,7 +33,7 @@ Querying Parquet foreign tables has been optimized and is now up to 20x faster t Resolved Issues --------- -The following table lists the issues that were resolved in Version 2022.1.2: +The following table lists the issues that were resolved in Version 2022.1.3: +-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ | **SQ No.** | **Description** | @@ -53,13 +53,13 @@ No relevant naming changes were made. Deprecated Features ------- -No features were deprecated for Version 2022.1.2. +No features were deprecated for Version 2022.1.3. End of Support ------- -The End of Support section is not relevant to Version 2022.1.2. +The End of Support section is not relevant to Version 2022.1.3. -Upgrading to v2022.1.2 +Upgrading to v2022.1.3 ------- 1. Generate a back-up of the metadata by running the following command: @@ -93,11 +93,11 @@ Upgrading to v2022.1.2 $ ./upgrade_storage - .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version `_ procedure. + .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version `_ procedure. .. toctree:: :maxdepth: 2 :glob: :hidden: - 2022.1.2 \ No newline at end of file + 2022.1.3 \ No newline at end of file From 3297854d25a65da7150bbbbb43d6aa60667cba75 Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Thu, 8 Sep 2022 09:31:40 +0300 Subject: [PATCH 240/316] Update 2022.1.3.rst --- releases/2022.1.3.rst | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/releases/2022.1.3.rst b/releases/2022.1.3.rst index beeb68679..37b9e90c6 100644 --- a/releases/2022.1.3.rst +++ b/releases/2022.1.3.rst @@ -13,11 +13,20 @@ Version Content ---------- The 2022.1.3 Release Notes describes the following: -* Automatic schema identification. +* Optimize the delete operation by removing redundant calls. :: -* Optimized queries on external Parquet tables. +* Support LIKE condition for filtering metadata. + + :: + +* Migration tool for converting VARCHAR columns into TEXT columns. + + :: + +* Support sub-queries in the UPDATE condition. + New Features ---------- @@ -27,9 +36,9 @@ The 2022.1.3 Release Notes include the following new features: :local: :depth: 1 -Parquet Read Optimization +Support sub-queries in the UPDATE condition ************ -Querying Parquet foreign tables has been optimized and is now up to 20x faster than in previous versions. +Update functionality has been enhanced to support sub-queries allowing to update table and / or columns based on other table and / or columns. Resolved Issues --------- @@ -38,9 +47,19 @@ The following table lists the issues that were resolved in Version 2022.1.3: +-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ | **SQ No.** | **Description** | +=============+===========================================================================================================================================+ -| SQ-10892 | An incorrect error message was displayed when users ran the ``UPDATE`` command on foreign tables. | +| SQ-11487 | COPY FROM with offset = 0 (which is an unsupported option) is stuck up to the query timeout. | ++-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11378 | Python connector fails to run multi threaded per one connection. | ++-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11373 | SQL statement fails after changing the foreign table the statement tries to query. | ++-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11320 | Locked users are not being released on system reset. | ++-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11310 | Using "create table like" on foreign tables results in flat compression of the created table. | ++-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ +| SQ-11287 | SQL User Defined Function declaration fails when UDF contains parenthesis. | +-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11273 | Clustering optimization only occurs when copying data from CSV files. | +| SQ-10892 | Update || enhanced error message when trying to run update on foreign table. | +-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ Operations and Configuration Changes @@ -57,7 +76,10 @@ No features were deprecated for Version 2022.1.3. End of Support ------- -The End of Support section is not relevant to Version 2022.1.3. +SQream is declaring end of support of VARCHAR data type, the decision resulted by SQream's effort to enhance its core functionalities and with respect to ever changing echo system requirements. +VARCHAR is no longer supported for new customers - effective immanently. +TEXT data type is replacing VARCHAR - SQream will maintain VARCHAR data type support until 09/30/2023. +As part of this release 2022.1.3, SQream provides an automated and secured migration tool to help customers with the conversion phase from VARCHAR to TEXT data type, please address delivery for further information. Upgrading to v2022.1.3 ------- From dbfeb529b16b61c4f0cf925126990ba228e2ee8e Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Thu, 8 Sep 2022 09:51:52 +0300 Subject: [PATCH 241/316] Update VARCHAR deprecation msg --- releases/2022.1.1.rst | 4 +++- releases/2022.1.2.rst | 4 +++- releases/2022.1.3.rst | 3 --- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/releases/2022.1.1.rst b/releases/2022.1.1.rst index faec3add2..d5c76b361 100644 --- a/releases/2022.1.1.rst +++ b/releases/2022.1.1.rst @@ -63,7 +63,9 @@ No relevant naming changes were made. Deprecated Features ------- -No features were deprecated for Version 2022.1.1. +In SQream version 2022.1 the ``VARCHAR`` data type has been deprecated and replaced with ``TEXT``. SQream will maintain ``VARCHAR`` in all previous versions until completing the migration to ``TEXT``, at which point it will be deprecated in all earlier versions. SQream also provides an automated and secure tool to facilitate and simplify migration from ``VARCHAR`` to ``TEXT``. + +If you are using an earlier version of SQream, see the `Using Legacy String Literals `_ configuration flag. End of Support ------- diff --git a/releases/2022.1.2.rst b/releases/2022.1.2.rst index 769bf60bc..0c9a4f3b3 100644 --- a/releases/2022.1.2.rst +++ b/releases/2022.1.2.rst @@ -53,7 +53,9 @@ No relevant naming changes were made. Deprecated Features ------- -No features were deprecated for Version 2022.1.2. +In SQream version 2022.1 the ``VARCHAR`` data type has been deprecated and replaced with ``TEXT``. SQream will maintain ``VARCHAR`` in all previous versions until completing the migration to ``TEXT``, at which point it will be deprecated in all earlier versions. SQream also provides an automated and secure tool to facilitate and simplify migration from ``VARCHAR`` to ``TEXT``. + +If you are using an earlier version of SQream, see the `Using Legacy String Literals `_ configuration flag. End of Support ------- diff --git a/releases/2022.1.3.rst b/releases/2022.1.3.rst index 37b9e90c6..46199e037 100644 --- a/releases/2022.1.3.rst +++ b/releases/2022.1.3.rst @@ -32,9 +32,6 @@ New Features ---------- The 2022.1.3 Release Notes include the following new features: -.. contents:: - :local: - :depth: 1 Support sub-queries in the UPDATE condition ************ From aae33c7a9553fabd6cffe577e046353993c21fb0 Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Thu, 8 Sep 2022 10:06:35 +0300 Subject: [PATCH 242/316] Update 2022.1.3.rst --- releases/2022.1.3.rst | 47 ++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/releases/2022.1.3.rst b/releases/2022.1.3.rst index 46199e037..fea508cb6 100644 --- a/releases/2022.1.3.rst +++ b/releases/2022.1.3.rst @@ -41,23 +41,25 @@ Resolved Issues --------- The following table lists the issues that were resolved in Version 2022.1.3: -+-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| **SQ No.** | **Description** | -+=============+===========================================================================================================================================+ -| SQ-11487 | COPY FROM with offset = 0 (which is an unsupported option) is stuck up to the query timeout. | -+-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11378 | Python connector fails to run multi threaded per one connection. | -+-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11373 | SQL statement fails after changing the foreign table the statement tries to query. | -+-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11320 | Locked users are not being released on system reset. | -+-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11310 | Using "create table like" on foreign tables results in flat compression of the created table. | -+-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-11287 | SQL User Defined Function declaration fails when UDF contains parenthesis. | -+-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ -| SQ-10892 | Update || enhanced error message when trying to run update on foreign table. | -+-------------+-------------------------------------------------------------------------------------------------------------------------------------------+ ++-------------+-------------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+=================================================================================================+ +| SQ-11487 | COPY FROM with offset = 0 (which is an unsupported option) is stuck up to the query timeout. | ++-------------+-------------------------------------------------------------------------------------------------+ +| SQ-11378 | Python connector fails to run multi threaded per one connection. | ++-------------+-------------------------------------------------------------------------------------------------+ +| SQ-11373 | SQL statement fails after changing the foreign table the statement tries to query. | ++-------------+-------------------------------------------------------------------------------------------------+ +| SQ-11320 | Locked users are not being released on system reset. | ++-------------+-------------------------------------------------------------------------------------------------+ +| SQ-11310 | Using "create table like" on foreign tables results in flat compression of the created table. | ++-------------+-------------------------------------------------------------------------------------------------+ +| SQ-11287 | SQL User Defined Function declaration fails when UDF contains parenthesis. | ++-------------+-------------------------------------------------------------------------------------------------+ +| SQ-10892 | Update - enhanced error message when trying to run update on foreign table. | ++-------------+-------------------------------------------------------------------------------------------------+ + + Operations and Configuration Changes -------- @@ -69,15 +71,18 @@ No relevant naming changes were made. Deprecated Features ------- -No features were deprecated for Version 2022.1.3. - -End of Support -------- SQream is declaring end of support of VARCHAR data type, the decision resulted by SQream's effort to enhance its core functionalities and with respect to ever changing echo system requirements. + VARCHAR is no longer supported for new customers - effective immanently. + TEXT data type is replacing VARCHAR - SQream will maintain VARCHAR data type support until 09/30/2023. + As part of this release 2022.1.3, SQream provides an automated and secured migration tool to help customers with the conversion phase from VARCHAR to TEXT data type, please address delivery for further information. +End of Support +------- +No End of Support changes were made. + Upgrading to v2022.1.3 ------- 1. Generate a back-up of the metadata by running the following command: From 2d678574f10a5bf4fc8e94cf10c4dff95ed77936 Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Thu, 8 Sep 2022 14:45:45 +0300 Subject: [PATCH 243/316] Update 2022.1.3.rst --- releases/2022.1.3.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/releases/2022.1.3.rst b/releases/2022.1.3.rst index fea508cb6..37b731a0a 100644 --- a/releases/2022.1.3.rst +++ b/releases/2022.1.3.rst @@ -46,8 +46,6 @@ The following table lists the issues that were resolved in Version 2022.1.3: +=============+=================================================================================================+ | SQ-11487 | COPY FROM with offset = 0 (which is an unsupported option) is stuck up to the query timeout. | +-------------+-------------------------------------------------------------------------------------------------+ -| SQ-11378 | Python connector fails to run multi threaded per one connection. | -+-------------+-------------------------------------------------------------------------------------------------+ | SQ-11373 | SQL statement fails after changing the foreign table the statement tries to query. | +-------------+-------------------------------------------------------------------------------------------------+ | SQ-11320 | Locked users are not being released on system reset. | From e973e38343a45febcb324b4644f4f89742c7c6eb Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Mon, 12 Sep 2022 08:35:25 +0300 Subject: [PATCH 244/316] Update 2022.1.3.rst --- releases/2022.1.3.rst | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/releases/2022.1.3.rst b/releases/2022.1.3.rst index 37b731a0a..486ed2244 100644 --- a/releases/2022.1.3.rst +++ b/releases/2022.1.3.rst @@ -27,15 +27,16 @@ The 2022.1.3 Release Notes describes the following: * Support sub-queries in the UPDATE condition. +Known Issues +--------- +The following table lists the issues that are known limitations in Version 2022.1.3: -New Features ----------- -The 2022.1.3 Release Notes include the following new features: ++-------------+--------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+============================================================================================+ +| SQ-11677 | UPADTE or DELETE using a sub-query that includes '%' (modulo) is crashing SQreamDB worker | ++-------------+--------------------------------------------------------------------------------------------+ - -Support sub-queries in the UPDATE condition -************ -Update functionality has been enhanced to support sub-queries allowing to update table and / or columns based on other table and / or columns. Resolved Issues --------- From 8bbf57ec1862f4373b40309fe92e134100c99b5a Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Mon, 12 Sep 2022 14:28:02 +0300 Subject: [PATCH 245/316] Update 2022.1.3.rst --- releases/2022.1.3.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/releases/2022.1.3.rst b/releases/2022.1.3.rst index 486ed2244..7d49b64c3 100644 --- a/releases/2022.1.3.rst +++ b/releases/2022.1.3.rst @@ -53,8 +53,6 @@ The following table lists the issues that were resolved in Version 2022.1.3: +-------------+-------------------------------------------------------------------------------------------------+ | SQ-11310 | Using "create table like" on foreign tables results in flat compression of the created table. | +-------------+-------------------------------------------------------------------------------------------------+ -| SQ-11287 | SQL User Defined Function declaration fails when UDF contains parenthesis. | -+-------------+-------------------------------------------------------------------------------------------------+ | SQ-10892 | Update - enhanced error message when trying to run update on foreign table. | +-------------+-------------------------------------------------------------------------------------------------+ From e357e7ab04b4a72e98ca2bd56b1dc08eb8bcf7b3 Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 14 Sep 2022 10:50:44 +0300 Subject: [PATCH 246/316] GETDATE is not supported as a default value --- reference/sql/sql_statements/ddl_commands/create_table.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reference/sql/sql_statements/ddl_commands/create_table.rst b/reference/sql/sql_statements/ddl_commands/create_table.rst index eb25baa8a..9fd4bacf5 100644 --- a/reference/sql/sql_statements/ddl_commands/create_table.rst +++ b/reference/sql/sql_statements/ddl_commands/create_table.rst @@ -74,7 +74,7 @@ Default Value Constraints The ``DEFAULT`` value constraint specifies a value to use if one is not defined in an :ref:`insert` or :ref:`copy_from` statement. -The value may either be a literal, **GETDATE()**, or Null, which is evaluated at the time the row is created. +The value may either be NULL or a literal. .. note:: The ``DEFAULT`` constraint only applies if the column does not have a value specified in the :ref:`insert` or :ref:`copy_from` statement. You can still insert a ``NULL`` into an nullable column by explicitly inserting ``NULL``. For example, ``INSERT INTO cool_animals VALUES (1, 'Gnu', NULL)``. @@ -293,4 +293,4 @@ The following table describes the properties that must be copied from the target Permissions ============= -The role must have the ``CREATE`` permission at the schema level. \ No newline at end of file +The role must have the ``CREATE`` permission at the schema level. From cf5277a47ef364040426cd4532110c5123c7ea05 Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Sun, 18 Sep 2022 10:48:21 +0300 Subject: [PATCH 247/316] Update 2022.1.3.rst --- releases/2022.1.3.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/releases/2022.1.3.rst b/releases/2022.1.3.rst index 7d49b64c3..b1412f577 100644 --- a/releases/2022.1.3.rst +++ b/releases/2022.1.3.rst @@ -55,7 +55,8 @@ The following table lists the issues that were resolved in Version 2022.1.3: +-------------+-------------------------------------------------------------------------------------------------+ | SQ-10892 | Update - enhanced error message when trying to run update on foreign table. | +-------------+-------------------------------------------------------------------------------------------------+ - +https://sqream.atlassian.net/browse/SQ-11287 +https://sqream.atlassian.net/browse/SQ-11187 Operations and Configuration Changes From f4ea9959802cc0ec6fef957c31953496a1b549b8 Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Tue, 20 Sep 2022 11:25:00 +0300 Subject: [PATCH 248/316] Update 2022.1.3.rst --- releases/2022.1.3.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/releases/2022.1.3.rst b/releases/2022.1.3.rst index b1412f577..a237f1ee6 100644 --- a/releases/2022.1.3.rst +++ b/releases/2022.1.3.rst @@ -53,10 +53,13 @@ The following table lists the issues that were resolved in Version 2022.1.3: +-------------+-------------------------------------------------------------------------------------------------+ | SQ-11310 | Using "create table like" on foreign tables results in flat compression of the created table. | +-------------+-------------------------------------------------------------------------------------------------+ +| SQ-11287 | SQL User Defined Function fails when function definition contain parenthesis | ++-------------+-------------------------------------------------------------------------------------------------+ +| SQ-11187 | FLAT compression is wrongly chosen when dealing with data sets starting with all-nulls | ++-------------+-------------------------------------------------------------------------------------------------+ | SQ-10892 | Update - enhanced error message when trying to run update on foreign table. | +-------------+-------------------------------------------------------------------------------------------------+ -https://sqream.atlassian.net/browse/SQ-11287 -https://sqream.atlassian.net/browse/SQ-11187 + Operations and Configuration Changes @@ -115,7 +118,7 @@ Upgrading to v2022.1.3 $ ./upgrade_storage - .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version `_ procedure. + .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version <../installation_guides/installing_sqream_with_binary.html#upgrading-sqream-version>`_ procedure. .. toctree:: :maxdepth: 2 From 74b740074bcf3f9b9ffe5cf0407832430400f826 Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Tue, 20 Sep 2022 11:33:07 +0300 Subject: [PATCH 249/316] Update 2022.1.3.rst --- releases/2022.1.3.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releases/2022.1.3.rst b/releases/2022.1.3.rst index a237f1ee6..548c8673c 100644 --- a/releases/2022.1.3.rst +++ b/releases/2022.1.3.rst @@ -3,7 +3,7 @@ ************************** Release Notes 2022.1.3 ************************** -The 2022.1.3 release notes were released on 9/8/2022 and describe the following: +The 2022.1.3 release notes were released on 9/20/2022 and describe the following: .. contents:: :local: From e43dbdb42b90cc51237e27a91cbac6b3c4cfa25a Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Tue, 20 Sep 2022 16:34:29 +0300 Subject: [PATCH 250/316] Update index.rst Fix misspells --- connecting_to_sqream/client_drivers/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connecting_to_sqream/client_drivers/index.rst b/connecting_to_sqream/client_drivers/index.rst index fb772853c..5365380b9 100644 --- a/connecting_to_sqream/client_drivers/index.rst +++ b/connecting_to_sqream/client_drivers/index.rst @@ -40,7 +40,7 @@ Windows -------------- The following are applicable to Windows: -* **ODBC installer** - SQream Drivers v2020.2.0, with Tableau customizations. Please contact your `SSream represenative `_ for this installer. +* **ODBC installer** - SQream Drivers v2020.2.0, with Tableau customization. Please contact your `SQream representative `_ for this installer. For more information on installing and configuring ODBC on Windows, see :ref:`Install and configure ODBC on Windows `. From 6c7cf5116b0297a92853fa8337b24c21a707450e Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Wed, 21 Sep 2022 10:03:23 +0300 Subject: [PATCH 251/316] Add non production HW specs and fix some broken links --- getting_started/hardware_guide.rst | 4 +- .../non_production_hardware_guide.rst | 49 +++++++++++++++++++ index.rst | 6 +-- 3 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 getting_started/non_production_hardware_guide.rst diff --git a/getting_started/hardware_guide.rst b/getting_started/hardware_guide.rst index 5337db9cd..c502f60bf 100644 --- a/getting_started/hardware_guide.rst +++ b/getting_started/hardware_guide.rst @@ -225,4 +225,6 @@ For clustered scale-out installations, SQream relies on NAS/SAN storage. For sta SQream recommends using enterprise-grade SAS SSD or NVMe drives. For a 32-user configuration, the number of GPUs should roughly match the number of users. SQream recommends 1 Tesla V100 or A100 GPU per 2 users, for full, uninterrupted dedicated access. -Download the full `SQream Reference Architecture `_ document. \ No newline at end of file +Download the full `SQream Reference Architecture `_ document. + +.. note:: Non production HW requirements may be found at `Non Production HW Requirements `_ \ No newline at end of file diff --git a/getting_started/non_production_hardware_guide.rst b/getting_started/non_production_hardware_guide.rst new file mode 100644 index 000000000..03c738887 --- /dev/null +++ b/getting_started/non_production_hardware_guide.rst @@ -0,0 +1,49 @@ +.. non_production_hardware_guide: + +*************************************** +Staging and Development Hardware Guide +*************************************** +The **Staging and Development Hardware Guide** describes the SQream recommended HW for development, staging and or QA desktop and servers. + +.. warning:: The HW specification in this page are not intended for production use! + +Development Desktop +----------------------------------- + ++------------------+-----------------------------------------------+ +| **Component** | **Type** | ++==================+===============================================+ +| Server | PC | ++------------------+-----------------------------------------------+ +| Processor | Intel i7 | ++------------------+-----------------------------------------------+ +| RAM | 64GB RAM | ++------------------+-----------------------------------------------+ +| Onboard storage | 2TB SSD | ++------------------+-----------------------------------------------+ +| GPU | 1x NVIDIA RTX A4000 16GB | ++------------------+-----------------------------------------------+ +| Operating System | Red Hat Enterprise Linux v7.9 or CentOS v7.9 | ++------------------+-----------------------------------------------+ + + +Lab Server +----------------------------------- + ++------------------+------------------------------------------------------------+ +| **Component** | **Type** | ++==================+============================================================+ +| Server | Dell R640 or similar | ++------------------+------------------------------------------------------------+ +| Processor | x2 Intel(R) Xeon(R) Silver 4112 CPU @ 2.60GHz | ++------------------+------------------------------------------------------------+ +| RAM | 128 or 256 GB | ++------------------+------------------------------------------------------------+ +| Onboard storage | "2x 960GB SSD 2.5in hot plug for OS, RAID1 | ++------------------+------------------------------------------------------------+ +| | 1(or more)x 3.84TB SSD 2.5in Hot plug for storage, RAID5" | ++------------------+------------------------------------------------------------+ +| GPU | 1xNVIDIA T4 or A40 or A10 | ++------------------+------------------------------------------------------------+ +| Operating System | Red Hat Enterprise Linux v7.9 or CentOS v7.9 | ++------------------+------------------------------------------------------------+ diff --git a/index.rst b/index.rst index d6a37d4f7..c4bee46da 100644 --- a/index.rst +++ b/index.rst @@ -8,7 +8,7 @@ SQream DB Documentation .. tip:: Want to read this offline? - `Download the documentation as a single PDF `_ . + `Download the documentation as a single PDF `_ . .. only:: pdf or latex @@ -33,7 +33,7 @@ SQream DB easily plugs in to third-party tools like :ref:`Tableau`_ + `Getting Started `_ :ref:`sql_feature_support` @@ -45,7 +45,7 @@ SQream DB easily plugs in to third-party tools like :ref:`Tableau`_ + `Setting up SQream `_ :ref:`Best practices` From 072320e0bb312af20cf3bcaa8e632f6efd7d55bc Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Wed, 21 Sep 2022 10:27:33 +0300 Subject: [PATCH 252/316] Update conf.py Update latest version to 2022.1.3 --- conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf.py b/conf.py index 4151da1c4..305be5597 100644 --- a/conf.py +++ b/conf.py @@ -26,7 +26,7 @@ # The full version, including alpha/beta/rc tags -release = '2022.1.2' +release = '2022.1.3' From 853c8a1440defc7be09afbadb38f0c3f520a930c Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Thu, 29 Sep 2022 15:25:52 +0300 Subject: [PATCH 253/316] Update query_healer.rst --- feature_guides/query_healer.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature_guides/query_healer.rst b/feature_guides/query_healer.rst index f8bb7f694..305875447 100644 --- a/feature_guides/query_healer.rst +++ b/feature_guides/query_healer.rst @@ -11,7 +11,7 @@ The **Query Healer** page describes the following: Overview ---------- -The **Query Healer** periodically examines the progress of running statements, creating a log entry for all statements exceeding the ``healerMaxInactivityHours`` flag setting. The default setting of the ``healerMaxInactivityHours`` is five hours. The ``healerMaxInactivityHours`` log frequency is calculated as 5% of the flag setting. When set to to five hours (the default setting), the Query Healer triggers an examination every 15 minutes. +The **Query Healer** periodically examines the progress of running statements, creating a log entry for all statements exceeding the ``healerMaxInactivityHours`` flag setting. The default setting of the ``healerMaxInactivityHours`` is five hours. The ``healerMaxInactivityHours`` log frequency is calculated as 5% of the flag setting. When set to five hours (the default setting), the Query Healer triggers an examination every 15 minutes. The following is an example of a log record for a query stuck in the query detection phase for more than five hours: From 06bc8165ae5e323c631b9c8d0bb1e491149f400d Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Thu, 6 Oct 2022 12:28:41 +0300 Subject: [PATCH 254/316] Create 2022.1.4.rst --- releases/2022.1.4.rst | 127 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 releases/2022.1.4.rst diff --git a/releases/2022.1.4.rst b/releases/2022.1.4.rst new file mode 100644 index 000000000..43b1b1330 --- /dev/null +++ b/releases/2022.1.4.rst @@ -0,0 +1,127 @@ +.. _2022.1.4: + +************************** +Release Notes 2022.1.4 +************************** +The 2022.1.4 release notes were released on 10/XX/2022 and describe the following: + +.. contents:: + :local: + :depth: 1 + +Version Content +---------- +The 2022.1.4 Release Notes describes the following: + +* Optimize the delete operation by removing redundant calls. + + :: + +* Support LIKE condition for filtering metadata. + + :: + +* Migration tool for converting VARCHAR columns into TEXT columns. + + :: + +* Support sub-queries in the UPDATE condition. + +Known Issues +--------- +The following table lists the issues that are known limitations in Version 2022.1.4: + ++-------------+--------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+============================================================================================+ +| SQ-11677 | UPADTE or DELETE using a sub-query that includes '%' (modulo) is crashing SQreamDB worker | ++-------------+--------------------------------------------------------------------------------------------+ + + +Resolved Issues +--------- +The following table lists the issues that were resolved in Version 2022.1.4: + ++-------------+-------------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=============+=================================================================================================+ +| SQ-11487 | COPY FROM with offset = 0 (which is an unsupported option) is stuck up to the query timeout. | ++-------------+-------------------------------------------------------------------------------------------------+ +| SQ-11373 | SQL statement fails after changing the foreign table the statement tries to query. | ++-------------+-------------------------------------------------------------------------------------------------+ +| SQ-11320 | Locked users are not being released on system reset. | ++-------------+-------------------------------------------------------------------------------------------------+ +| SQ-11310 | Using "create table like" on foreign tables results in flat compression of the created table. | ++-------------+-------------------------------------------------------------------------------------------------+ +| SQ-11287 | SQL User Defined Function fails when function definition contain parenthesis | ++-------------+-------------------------------------------------------------------------------------------------+ +| SQ-11187 | FLAT compression is wrongly chosen when dealing with data sets starting with all-nulls | ++-------------+-------------------------------------------------------------------------------------------------+ +| SQ-10892 | Update - enhanced error message when trying to run update on foreign table. | ++-------------+-------------------------------------------------------------------------------------------------+ + + + +Operations and Configuration Changes +-------- +No configuration changes were made. + +Naming Changes +------- +No relevant naming changes were made. + +Deprecated Features +------- +SQream is declaring end of support of VARCHAR data type, the decision resulted by SQream's effort to enhance its core functionalities and with respect to ever changing echo system requirements. + +VARCHAR is no longer supported for new customers - effective from Version 2022.1.3 (September 2022). + +TEXT data type is replacing VARCHAR - SQream will maintain VARCHAR data type support until 09/30/2023. + + +End of Support +------- +No End of Support changes were made. + +Upgrading to v2022.1.4 +------- +1. Generate a back-up of the metadata by running the following command: + + .. code-block:: console + + $ select backup_metadata('out_path'); + + .. tip:: SQream recommends storing the generated back-up locally in case needed. + + SQream runs the Garbage Collector and creates a clean backup tarball package. + +2. Shut down all SQream services. + + :: + +3. Extract the recently created back-up file. + + :: + +4. Replace your current metadata with the metadata you stored in the back-up file. + + :: + +5. Navigate to the new SQream package bin folder. + + :: + +6. Run the following command: + + .. code-block:: console + + $ ./upgrade_storage + + .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version <../installation_guides/installing_sqream_with_binary.html#upgrading-sqream-version>`_ procedure. + +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2022.1.4 \ No newline at end of file From 4175f1d2ec633a215e6a520085eab544a7e6bde1 Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Thu, 6 Oct 2022 12:32:12 +0300 Subject: [PATCH 255/316] Update 2022.1.3.rst fix misspell --- releases/2022.1.3.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releases/2022.1.3.rst b/releases/2022.1.3.rst index 548c8673c..9887f7a04 100644 --- a/releases/2022.1.3.rst +++ b/releases/2022.1.3.rst @@ -74,7 +74,7 @@ Deprecated Features ------- SQream is declaring end of support of VARCHAR data type, the decision resulted by SQream's effort to enhance its core functionalities and with respect to ever changing echo system requirements. -VARCHAR is no longer supported for new customers - effective immanently. +VARCHAR is no longer supported for new customers - effective immediately. TEXT data type is replacing VARCHAR - SQream will maintain VARCHAR data type support until 09/30/2023. From 620a3167cb811b95ea88105f88806cbafa91ee6f Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Tue, 11 Oct 2022 15:33:07 +0300 Subject: [PATCH 256/316] Remove irrelevant toctree --- releases/2022.1.1.rst | 6 ---- releases/2022.1.2.rst | 6 ---- releases/2022.1.4.rst | 59 ++++++++++++--------------------------- releases/2022.1_index.rst | 1 + 4 files changed, 19 insertions(+), 53 deletions(-) diff --git a/releases/2022.1.1.rst b/releases/2022.1.1.rst index d5c76b361..436287c6c 100644 --- a/releases/2022.1.1.rst +++ b/releases/2022.1.1.rst @@ -107,9 +107,3 @@ Upgrading to v2022.1.1 .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version `_ procedure. -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2022.1.1 \ No newline at end of file diff --git a/releases/2022.1.2.rst b/releases/2022.1.2.rst index 0c9a4f3b3..5c007f0ec 100644 --- a/releases/2022.1.2.rst +++ b/releases/2022.1.2.rst @@ -97,9 +97,3 @@ Upgrading to v2022.1.2 .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version `_ procedure. -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2022.1.2 \ No newline at end of file diff --git a/releases/2022.1.4.rst b/releases/2022.1.4.rst index 43b1b1330..6b9cbb5a0 100644 --- a/releases/2022.1.4.rst +++ b/releases/2022.1.4.rst @@ -3,7 +3,7 @@ ************************** Release Notes 2022.1.4 ************************** -The 2022.1.4 release notes were released on 10/XX/2022 and describe the following: +The 2022.1.4 release notes were released on 10/11/2022 and describe the following: .. contents:: :local: @@ -13,52 +13,35 @@ Version Content ---------- The 2022.1.4 Release Notes describes the following: -* Optimize the delete operation by removing redundant calls. +* Security enhancement - Disable Python UDFs by default. :: -* Support LIKE condition for filtering metadata. - - :: - -* Migration tool for converting VARCHAR columns into TEXT columns. - - :: - -* Support sub-queries in the UPDATE condition. Known Issues --------- -The following table lists the issues that are known limitations in Version 2022.1.4: - -+-------------+--------------------------------------------------------------------------------------------+ -| **SQ No.** | **Description** | -+=============+============================================================================================+ -| SQ-11677 | UPADTE or DELETE using a sub-query that includes '%' (modulo) is crashing SQreamDB worker | -+-------------+--------------------------------------------------------------------------------------------+ +No relevant Known Issues. Resolved Issues --------- The following table lists the issues that were resolved in Version 2022.1.4: -+-------------+-------------------------------------------------------------------------------------------------+ -| **SQ No.** | **Description** | -+=============+=================================================================================================+ -| SQ-11487 | COPY FROM with offset = 0 (which is an unsupported option) is stuck up to the query timeout. | -+-------------+-------------------------------------------------------------------------------------------------+ -| SQ-11373 | SQL statement fails after changing the foreign table the statement tries to query. | -+-------------+-------------------------------------------------------------------------------------------------+ -| SQ-11320 | Locked users are not being released on system reset. | -+-------------+-------------------------------------------------------------------------------------------------+ -| SQ-11310 | Using "create table like" on foreign tables results in flat compression of the created table. | -+-------------+-------------------------------------------------------------------------------------------------+ -| SQ-11287 | SQL User Defined Function fails when function definition contain parenthesis | -+-------------+-------------------------------------------------------------------------------------------------+ -| SQ-11187 | FLAT compression is wrongly chosen when dealing with data sets starting with all-nulls | -+-------------+-------------------------------------------------------------------------------------------------+ -| SQ-10892 | Update - enhanced error message when trying to run update on foreign table. | -+-------------+-------------------------------------------------------------------------------------------------+ ++--------------+------------------------------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++==============+==================================================================================================================+ +| SQ-11487 | Alter default permissions to grant update results in error | ++--------------+------------------------------------------------------------------------------------------------------------------+ +| SQ-11771 | Wrong results returned when execute select subquery | ++--------------+------------------------------------------------------------------------------------------------------------------+ +| SQ-11740 | A correlated subquery is blocked when having 'not exist' where clause in update query | ++--------------+------------------------------------------------------------------------------------------------------------------+ +| SQ-11584 | CUDA malloc error | ++--------------+------------------------------------------------------------------------------------------------------------------+ +| SQ-10602 | Group by clause error | ++--------------+------------------------------------------------------------------------------------------------------------------+ +| SQ-9813 | When executing copy from a parquet file that contain date values earlier than 1970, values are changed to 1970. | ++--------------+------------------------------------------------------------------------------------------------------------------+ @@ -119,9 +102,3 @@ Upgrading to v2022.1.4 .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version <../installation_guides/installing_sqream_with_binary.html#upgrading-sqream-version>`_ procedure. -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2022.1.4 \ No newline at end of file diff --git a/releases/2022.1_index.rst b/releases/2022.1_index.rst index beceab0b6..e5c24021d 100644 --- a/releases/2022.1_index.rst +++ b/releases/2022.1_index.rst @@ -13,6 +13,7 @@ The 2022.1 Release Notes describe the following releases: :maxdepth: 1 :glob: + 2022.1.4 2022.1.3 2022.1.2 2022.1.1 From c022974310478f16887810e2984fe81067acce08 Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Tue, 11 Oct 2022 16:06:25 +0300 Subject: [PATCH 257/316] Update python_functions.rst --- feature_guides/python_functions.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/feature_guides/python_functions.rst b/feature_guides/python_functions.rst index 3717cdcd8..7aaea5051 100644 --- a/feature_guides/python_functions.rst +++ b/feature_guides/python_functions.rst @@ -6,6 +6,8 @@ Python UDF (User-Defined Functions) User-defined functions (UDFs) are a feature that extends SQream DB's built in SQL functionality. SQream DB's Python UDFs allow developers to create new functionality in SQL by writing the lower-level language implementation in Python. +.. note:: Starting v2022.1.4, Python UDF are disabled by default in order to enhance product security. Use the ``enablePythonUdfs`` configuration flag in order to enable Python UDF. + .. contents:: In this topic: :local: From 5fe9d223e9bb82f8470390bb94107b7e2fdebe67 Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Wed, 12 Oct 2022 14:13:44 +0300 Subject: [PATCH 258/316] Update 2022.1.4.rst --- releases/2022.1.4.rst | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/releases/2022.1.4.rst b/releases/2022.1.4.rst index 6b9cbb5a0..0f3a6add0 100644 --- a/releases/2022.1.4.rst +++ b/releases/2022.1.4.rst @@ -27,21 +27,22 @@ Resolved Issues --------- The following table lists the issues that were resolved in Version 2022.1.4: -+--------------+------------------------------------------------------------------------------------------------------------------+ -| **SQ No.** | **Description** | -+==============+==================================================================================================================+ -| SQ-11487 | Alter default permissions to grant update results in error | -+--------------+------------------------------------------------------------------------------------------------------------------+ -| SQ-11771 | Wrong results returned when execute select subquery | -+--------------+------------------------------------------------------------------------------------------------------------------+ -| SQ-11740 | A correlated subquery is blocked when having 'not exist' where clause in update query | -+--------------+------------------------------------------------------------------------------------------------------------------+ -| SQ-11584 | CUDA malloc error | -+--------------+------------------------------------------------------------------------------------------------------------------+ -| SQ-10602 | Group by clause error | -+--------------+------------------------------------------------------------------------------------------------------------------+ -| SQ-9813 | When executing copy from a parquet file that contain date values earlier than 1970, values are changed to 1970. | -+--------------+------------------------------------------------------------------------------------------------------------------+ ++---------------------+------------------------------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++=====================+==================================================================================================================+ +| SQ-11782 | Alter default permissions to grant update results in error | ++---------------------+------------------------------------------------------------------------------------------------------------------+ +| SQ-11771 | Wrong results returned when execute select subquery | ++---------------------+------------------------------------------------------------------------------------------------------------------+ +| SQ-11740 | A correlated subquery is blocked when having 'not exist' where clause in update query | ++---------------------+------------------------------------------------------------------------------------------------------------------+ +| SQ-11686, SQ-11584 | CUDA malloc error | ++---------------------+------------------------------------------------------------------------------------------------------------------+ +| SQ-10602 | Group by clause error | ++---------------------+------------------------------------------------------------------------------------------------------------------+ +| SQ-9813 | When executing copy from a parquet file that contain date values earlier than 1970, values are changed to 1970. | ++---------------------+------------------------------------------------------------------------------------------------------------------+ + From 7aafdb3e9871e088e43cfbd53ae911441c4d16c9 Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Wed, 19 Oct 2022 11:44:32 +0300 Subject: [PATCH 259/316] New file for 2022.1.5 release New file for 2022.1.5 release --- releases/2022.1.5.rst | 91 +++++++++++++++++++++++++++++++++++++++ releases/2022.1_index.rst | 1 + 2 files changed, 92 insertions(+) create mode 100644 releases/2022.1.5.rst diff --git a/releases/2022.1.5.rst b/releases/2022.1.5.rst new file mode 100644 index 000000000..828ac3d5f --- /dev/null +++ b/releases/2022.1.5.rst @@ -0,0 +1,91 @@ +.. _2022.1.5: + +************************** +Release Notes 2022.1.5 +************************** +The 2022.1.5 release notes were released on 10/XX/2022 and describe the following: + +.. contents:: + :local: + :depth: 1 + +Version Content +---------- +The 2022.1.5 Release Notes describes the following: + +XXXXXX TBD XXXXXXXXXXXXXXXXXXXX + + :: + + +Known Issues +--------- +No relevant Known Issues. + + +Resolved Issues +--------- +The following table lists the issues that were resolved in Version 2022.1.5: + +XXXXXX TBD XXXXXXXXXXXXXXXXXXXX + + + + +Operations and Configuration Changes +-------- +No configuration changes were made. + +Naming Changes +------- +No relevant naming changes were made. + +Deprecated Features +------- +SQream is declaring end of support of VARCHAR data type, the decision resulted by SQream's effort to enhance its core functionalities and with respect to ever changing echo system requirements. + +VARCHAR is no longer supported for new customers - effective from Version 2022.1.3 (September 2022). + +TEXT data type is replacing VARCHAR - SQream will maintain VARCHAR data type support until 09/30/2023. + + +End of Support +------- +No End of Support changes were made. + +Upgrading to v2022.1.5 +------- +1. Generate a back-up of the metadata by running the following command: + + .. code-block:: console + + $ select backup_metadata('out_path'); + + .. tip:: SQream recommends storing the generated back-up locally in case needed. + + SQream runs the Garbage Collector and creates a clean backup tarball package. + +2. Shut down all SQream services. + + :: + +3. Extract the recently created back-up file. + + :: + +4. Replace your current metadata with the metadata you stored in the back-up file. + + :: + +5. Navigate to the new SQream package bin folder. + + :: + +6. Run the following command: + + .. code-block:: console + + $ ./upgrade_storage + + .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version <../installation_guides/installing_sqream_with_binary.html#upgrading-sqream-version>`_ procedure. + diff --git a/releases/2022.1_index.rst b/releases/2022.1_index.rst index e5c24021d..d6522a59b 100644 --- a/releases/2022.1_index.rst +++ b/releases/2022.1_index.rst @@ -13,6 +13,7 @@ The 2022.1 Release Notes describe the following releases: :maxdepth: 1 :glob: + 2022.1.5 2022.1.4 2022.1.3 2022.1.2 From 84d8101cf9443126a3f9831911cbd77b166e7de8 Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Wed, 19 Oct 2022 11:49:15 +0300 Subject: [PATCH 260/316] Remove redundent toc tree that causes error --- releases/2022.1.3.rst | 6 ------ releases/2022.1.rst | 6 ------ 2 files changed, 12 deletions(-) diff --git a/releases/2022.1.3.rst b/releases/2022.1.3.rst index 9887f7a04..b88eb78d9 100644 --- a/releases/2022.1.3.rst +++ b/releases/2022.1.3.rst @@ -120,9 +120,3 @@ Upgrading to v2022.1.3 .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version <../installation_guides/installing_sqream_with_binary.html#upgrading-sqream-version>`_ procedure. -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2022.1.3 \ No newline at end of file diff --git a/releases/2022.1.rst b/releases/2022.1.rst index 3d1517371..6614d6458 100644 --- a/releases/2022.1.rst +++ b/releases/2022.1.rst @@ -129,9 +129,3 @@ Upgrading to v2022.1 .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version `_ procedure. -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2022.1 \ No newline at end of file From 90f0d9772ef43bdb62e8a196503c17071da57b08 Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Wed, 19 Oct 2022 11:54:44 +0300 Subject: [PATCH 261/316] Remove redundent toc tree that causes error --- releases/2019.2.1.rst | 94 ---------------------------------------- releases/2020.1.rst | 6 --- releases/2020.2.rst | 6 --- releases/2020.3.1.rst | 6 --- releases/2020.3.2.1.rst | 6 --- releases/2021.1.2.rst | 6 --- releases/2021.1.rst | 6 --- releases/2021.2.1.24.rst | 6 --- releases/2021.2.1.rst | 6 --- releases/2021.2.rst | 6 --- 10 files changed, 148 deletions(-) delete mode 100644 releases/2019.2.1.rst diff --git a/releases/2019.2.1.rst b/releases/2019.2.1.rst deleted file mode 100644 index c9c96b59b..000000000 --- a/releases/2019.2.1.rst +++ /dev/null @@ -1,94 +0,0 @@ -.. _2019.2.1: - -****************************** -Release Notes 2019.2.1 -****************************** - -* 250 bugs fixed. Thanks to all of our customers and an unprecedented number of deployments for helping us find and fix these! -* Improved Unicode text handling on the GPU -* Improved logging and monitoring of statements -* Alibaba DataX connector - - -Improvements -===================== - -* We’ve updated the ``show_server_status()`` function to more accurately reflect the status of statements across the cluster: - - * Preparing – Initial validation - * In queue – Waiting for execution - * Initializing – Pre-execution processing - * Executing – statement is running - -* We’ve improved our log files and have unified them into a single file per worker, per date. Each message type has a unique code which can help identify potential issues. See the documentation for full details on the changes to the log structures. - -* ``WITH ADMIN OPTION`` added in ``GRANT``/``REVOKE`` operations, allowing roles to grant their own permissions to others. - -* HA cluster fully supports qualified hostnames, and no longer requires explicit IP addresses. - -* SQream DB CLI’s history can be disabled, by passing ``./ClientCmd --no-history`` - - -Behaviour Changes -===================== - -* SQream DB no longer applies an implicit cast from a long text column to a shorter text column (``VARCHAR``/``TEXT``). This means some ``INSERT``/``COPY`` operations will now error instead of truncating the text. This is intended to prevent accidental truncation of text columns. If you want the old truncation behaviour, you can use the ``SUBSTRING`` function to truncate the text. - - -Operations -===================== - -* The client-server protocol has been updated to support a wider range of encodings. End users are required to use only the latest ClientCmd, JDBC, and ODBC drivers delivered with this version. - -* Clients such as SecureCRT and other shells must have locale set as ``cp874`` or equivalent - -* When upgrading from SQream DB v3.2 or lower, the storage version must be upgraded using the :ref:`upgrade_storage_cli_reference` utility: ``./bin/upgrade_storage /path/to/storage/sqreamdb/`` - - -Known Issues and Limitations -=================================== - -* TEXT columns cannot be used as a ``GROUP BY`` key when there are multiple ``COUNT (DISTINCT …)`` operations in a query - -* TEXT columns cannot be used in a statement containing window functions - -* TEXT is not supported as a join key - -* The following functions are not supported on ``TEXT`` column types: ``chr``, ``min``, ``max``, ``patindex``, ``to_binary``, ``to_hex``, ``rlike``, ``regexp_count``, ``regexp_instr``, ``regexp_substr`` - -* SQream Dashboard: Only works with a HA clustered installation - -* SQream Editor: External tables and UDFs don’t appear in the DB Tree but do appear in the relevant sqream_catalog entries. - - -Fixes -===================== - -250 bugs and issues fixed, including: - -* Variety of performance improvements: - -* Improved performance of ``TEXT`` by up to 315% for a variety of scenarios, including ``COPY FROM``, ``INNER JOIN``, ``LEFT JOIN``. - -* Improved load performance from previous versions - -* Faster compilation times for very complex queries - -* DWLM: - - * Fixed situation where queries were not distributed correctly among all available workers - * Fixed ``cannot execute - reconnectDb error`` error - * Fixed occasional hanging statement - * Fixed occasional ``Connection refused`` - -* Window functions: - - * Fixed window function edge-case ``error WindowA with no functions`` - * Fixed situations where the SUM window function is applied on a column, partitioned by a second, and sorted by a third would return wrong results when scanning very large datasets - -* Other bugs: - - * Fixed situation where many concurrent statements running would result in ``map::at`` appearing - * Fixed situation where SQream DB would restart when force-stopping an ``INSERT`` over the network - * Fixed situation where RAM wasn’t released immediately after statement has been executed - * Fixed Type doesn’t have a fixed size error that appeared when using an external table joined with a standard SQream DB table diff --git a/releases/2020.1.rst b/releases/2020.1.rst index 86b619d54..769fa0ebb 100644 --- a/releases/2020.1.rst +++ b/releases/2020.1.rst @@ -187,9 +187,3 @@ Versions are available for IBM POWER9, RedHat (CentOS) 7, Ubuntu 18.04, and othe Contact your account manager to get the latest release of SQream. -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2020.1 \ No newline at end of file diff --git a/releases/2020.2.rst b/releases/2020.2.rst index 917d80800..5a66e99bd 100644 --- a/releases/2020.2.rst +++ b/releases/2020.2.rst @@ -114,9 +114,3 @@ Versions are available for IBM POWER9, RedHat (CentOS) 7, Ubuntu 18.04, and othe Contact your account manager to get the latest release of SQream. -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2020.2 \ No newline at end of file diff --git a/releases/2020.3.1.rst b/releases/2020.3.1.rst index b66454c75..9fa40cbb0 100644 --- a/releases/2020.3.1.rst +++ b/releases/2020.3.1.rst @@ -71,9 +71,3 @@ Versions are available for IBM POWER9, RedHat (CentOS) 7, Ubuntu 18.04, and othe Contact your account manager to get the latest release of SQream. -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2020.3.1 \ No newline at end of file diff --git a/releases/2020.3.2.1.rst b/releases/2020.3.2.1.rst index 8fef047f6..29f3b3e88 100644 --- a/releases/2020.3.2.1.rst +++ b/releases/2020.3.2.1.rst @@ -30,9 +30,3 @@ Versions are available for IBM POWER9, RedHat (CentOS) 7, Ubuntu 18.04, and othe Contact your account manager to get the latest release of SQream. -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2020.3.2.1 \ No newline at end of file diff --git a/releases/2021.1.2.rst b/releases/2021.1.2.rst index 750420260..ee33cfbd8 100644 --- a/releases/2021.1.2.rst +++ b/releases/2021.1.2.rst @@ -60,9 +60,3 @@ The following list describes the resolved issues: * The ``REPLACE`` function only supported constant values as arguments. This was fixed. * The ``LIKE`` function did not check for incorrect patterns or handle escape characters. This was fixed. -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2021.1.2 \ No newline at end of file diff --git a/releases/2021.1.rst b/releases/2021.1.rst index 389655262..02d5377d5 100644 --- a/releases/2021.1.rst +++ b/releases/2021.1.rst @@ -212,9 +212,3 @@ Upgrading to v2021.1 ------- Due to the known issue of a limitation on the amount of access requests that can be simultaneously sent to AWS, deploying S3 requires setting the ``ObjectStoreClients`` parameter to ``40``. -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2021.1 \ No newline at end of file diff --git a/releases/2021.2.1.24.rst b/releases/2021.2.1.24.rst index a89244934..d277ea51a 100644 --- a/releases/2021.2.1.24.rst +++ b/releases/2021.2.1.24.rst @@ -79,9 +79,3 @@ End of Support ------- The End of Support section is not relevant to Version 2021.2.1.24. -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2021.2.1.24 diff --git a/releases/2021.2.1.rst b/releases/2021.2.1.rst index e1a01a147..d50f1084e 100644 --- a/releases/2021.2.1.rst +++ b/releases/2021.2.1.rst @@ -78,9 +78,3 @@ Deprecated Features ------ The **Deprecated Components** section is not relevant to Version 2021.2.1. -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2021.2.1 \ No newline at end of file diff --git a/releases/2021.2.rst b/releases/2021.2.rst index 2140dc6be..f95de16a5 100644 --- a/releases/2021.2.rst +++ b/releases/2021.2.rst @@ -168,9 +168,3 @@ A new configuration method is used starting with Version 2021.2. For more information about configuring your instance of SQream, see `Client Drivers for 2021.2 `_. -.. toctree:: - :maxdepth: 2 - :glob: - :hidden: - - 2021.2 \ No newline at end of file From ff8d1d8d4f56daf27e803d8b6e3618dfc250164a Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Wed, 19 Oct 2022 14:18:13 +0300 Subject: [PATCH 262/316] Update remedying_slow_queries.rst Fix broken links --- troubleshooting/remedying_slow_queries.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/troubleshooting/remedying_slow_queries.rst b/troubleshooting/remedying_slow_queries.rst index 8a109f0c0..9bd05b324 100644 --- a/troubleshooting/remedying_slow_queries.rst +++ b/troubleshooting/remedying_slow_queries.rst @@ -33,7 +33,7 @@ The following table is a checklist you can use to identify the cause of your slo - Use ``SELECT show_cluster_nodes();`` to list the active cluster workers. - If the worker list is incomplete, follow the :ref:`cluster troubleshooting` section below. + If the worker list is incomplete, locate and start the missing worker(s). If all workers are up, continue to step 4. * - 4 @@ -73,7 +73,7 @@ The following table is a checklist you can use to identify the cause of your slo - Check free memory across hosts - #. Check free memory across the hosts by running ``$ free -th`` from the terminal. - #. If the machine has less than 5% free memory, consider **lowering** the ``limitQueryMemoryGB`` and ``spoolMemoryGB`` settings. Refer to the :ref:`configuration` guide. + #. If the machine has less than 5% free memory, consider **lowering** the ``limitQueryMemoryGB`` and ``spoolMemoryGB`` settings. Refer to the :ref:`spooling` guide. #. If the machine has a lot of free memory, consider **increasing** the ``limitQueryMemoryGB`` and ``spoolMemoryGB`` settings. If performance does not improve, contact SQream support for more help. \ No newline at end of file From 2596e3da9e04a54d10d183141590f84ce8e08e0b Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Thu, 20 Oct 2022 10:38:15 +0300 Subject: [PATCH 263/316] Update 2022.1.4.rst Remove customer sensitive bug --- releases/2022.1.4.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/releases/2022.1.4.rst b/releases/2022.1.4.rst index 0f3a6add0..338fdf164 100644 --- a/releases/2022.1.4.rst +++ b/releases/2022.1.4.rst @@ -32,8 +32,6 @@ The following table lists the issues that were resolved in Version 2022.1.4: +=====================+==================================================================================================================+ | SQ-11782 | Alter default permissions to grant update results in error | +---------------------+------------------------------------------------------------------------------------------------------------------+ -| SQ-11771 | Wrong results returned when execute select subquery | -+---------------------+------------------------------------------------------------------------------------------------------------------+ | SQ-11740 | A correlated subquery is blocked when having 'not exist' where clause in update query | +---------------------+------------------------------------------------------------------------------------------------------------------+ | SQ-11686, SQ-11584 | CUDA malloc error | From 89b87fcd68993fb8084b6bd66ba561932f1ae59e Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Sun, 30 Oct 2022 13:40:30 +0200 Subject: [PATCH 264/316] Cuda 11.4 rollback Rollback Cude descriptions from 11.4 to 10.1 as 11.4 is yet to be released --- .../installing_sqream_with_kubernetes.rst | 16 ++++++------- .../running_sqream_in_a_docker_container.rst | 24 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/installation_guides/installing_sqream_with_kubernetes.rst b/installation_guides/installing_sqream_with_kubernetes.rst index aa7e22422..fbf2566ed 100644 --- a/installation_guides/installing_sqream_with_kubernetes.rst +++ b/installation_guides/installing_sqream_with_kubernetes.rst @@ -198,7 +198,7 @@ After completing all of the steps above, you must check the CUDA version. .. code-block:: postgres +-----------------------------------------------------------------------------+ - | NVIDIA-SMI 470.82.01 Driver Version: 470.82.01 CUDA Version: 11.4 | + | NVIDIA-SMI 470.82.01 Driver Version: 470.82.01 CUDA Version: 10.1 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | @@ -220,7 +220,7 @@ After completing all of the steps above, you must check the CUDA version. | No running processes found | +-----------------------------------------------------------------------------+ -In the above output, the CUDA version is **11.4**. +In the above output, the CUDA version is **10.1**. If the above output is not generated, CUDA has not been installed. To install CUDA, see :ref:`installing-the-cuda-driver`. @@ -800,15 +800,15 @@ Installing the NVIDIA Docker2 Toolkit on an x86_64 Bit Processor on CentOS .. code-block:: postgres - $ docker run --runtime=nvidia --rm nvidia/cuda:11.4.3-base-centos7 nvidia-smi + $ docker run --runtime=nvidia --rm nvidia/cuda:10.1.3-base-centos7 nvidia-smi The following is an example of the correct output: .. code-block:: postgres - docker run --runtime=nvidia --rm nvidia/cuda:11.4.3-base-centos7 nvidia-smi - Unable to find image 'nvidia/cuda:11.4.3-base-centos7' locally - 11.4.3-base-centos7: Pulling from nvidia/cuda + docker run --runtime=nvidia --rm nvidia/cuda:10.1.3-base-centos7 nvidia-smi + Unable to find image 'nvidia/cuda:10.1.3-base-centos7' locally + 10.1.3-base-centos7: Pulling from nvidia/cuda d519e2592276: Pull complete d22d2dfcfa9c: Pull complete b3afe92c540b: Pull complete @@ -816,10 +816,10 @@ Installing the NVIDIA Docker2 Toolkit on an x86_64 Bit Processor on CentOS 4f0bc36a7e1d: Pull complete cd710321007d: Pull complete Digest: sha256:635629544b2a2be3781246fdddc55cc1a7d8b352e2ef205ba6122b8404a52123 - Status: Downloaded newer image for nvidia/cuda:11.4.3-base-centos7 + Status: Downloaded newer image for nvidia/cuda:10.1.3-base-centos7 Sun Feb 14 13:27:58 2021 +-----------------------------------------------------------------------------+ - | NVIDIA-SMI 470.82.01 Driver Version: 470.82.01 CUDA Version: 11.4 | + | NVIDIA-SMI 470.82.01 Driver Version: 470.82.01 CUDA Version: 10.1 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | diff --git a/installation_guides/running_sqream_in_a_docker_container.rst b/installation_guides/running_sqream_in_a_docker_container.rst index dd8d07e50..2a2454164 100644 --- a/installation_guides/running_sqream_in_a_docker_container.rst +++ b/installation_guides/running_sqream_in_a_docker_container.rst @@ -248,7 +248,7 @@ Installing the Nvidia CUDA Driver nvidia-smi Wed Oct 30 14:05:42 2019 +-----------------------------------------------------------------------------+ - | NVIDIA-SMI 470.82.01 Driver Version: 470.82.01 CUDA Version: 11.4 | + | NVIDIA-SMI 470.82.01 Driver Version: 470.82.01 CUDA Version: 10.1 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | @@ -267,7 +267,7 @@ Installing the Nvidia CUDA Driver | No running processes found | +-----------------------------------------------------------------------------+ -#. Verify that the installed CUDA version shown in the output above is ``11.4``. +#. Verify that the installed CUDA version shown in the output above is ``10.1``. :: @@ -276,25 +276,25 @@ Installing the Nvidia CUDA Driver :: - 1. If CUDA version 11.4 has already been installed, skip to Docktime Runtime (Community Edition). + 1. If CUDA version 10.1 has already been installed, skip to Docktime Runtime (Community Edition). :: - 2. If CUDA version 11.4 has not been installed yet, continue with Step 7 below. + 2. If CUDA version 10.1 has not been installed yet, continue with Step 7 below. #. Do one of the following: - * Install :ref:`CUDA Driver version 11.4 for x86_64 `. + * Install :ref:`CUDA Driver version 10.1 for x86_64 `. :: * Install :ref:`CUDA driver version 10.1 for IBM Power9 `. -.. _CUDA_11.4_x8664: +.. _CUDA_10.1_x8664: -Installing the CUDA Driver Version 11.4 for x86_64 +Installing the CUDA Driver Version 10.1 for x86_64 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -**To install the CUDA driver version 11.4 for x86_64:** +**To install the CUDA driver version 10.1 for x86_64:** 1. Make the following target platform selections: @@ -352,7 +352,7 @@ For installer type, SQream recommends selecting **runfile (local)**. The availab nvidia-smi Wed Oct 30 14:05:42 2019 +-----------------------------------------------------------------------------+ - | NVIDIA-SMI 470.82.01 Driver Version: 470.82.01 CUDA Version: 11.4 | + | NVIDIA-SMI 470.82.01 Driver Version: 470.82.01 CUDA Version: 10.1 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | @@ -622,7 +622,7 @@ Installing the NVIDIA Docker2 Toolkit on a CentOS Operating System .. code-block:: - $ docker run --runtime=nvidia --rm nvidia/cuda:11.4.3-base-centos7 nvidia-smi + $ docker run --runtime=nvidia --rm nvidia/cuda:10.1.3-base-centos7 nvidia-smi For more information on installing the NVIDIA Docker2 Toolkit on a CentOS operating system, see :ref:`Installing the NVIDIA Docker2 Toolkit on a CentOS operating system ` @@ -674,7 +674,7 @@ Installing the NVIDIA Docker2 Toolkit on an Ubuntu Operating System .. code-block:: - $ docker run --runtime=nvidia --rm nvidia/cuda:11.4.3-base-centos7 nvidia-smi + $ docker run --runtime=nvidia --rm nvidia/cuda:10.1.3-base-centos7 nvidia-smi For more information on installing the NVIDIA Docker2 Toolkit on a CentOS operating system, see :ref:`Installing the NVIDIA Docker2 Toolkit on an Ubuntu operating system ` @@ -1062,7 +1062,7 @@ The following is an example of the correct output: METADATA_PORT=3105 PICKER_PORT=3108 NUM_OF_GPUS=2 - CUDA_VERSION=11.4 + CUDA_VERSION=10.1 NVIDIA_SMI_PATH=/usr/bin/nvidia-smi DOCKER_PATH=/usr/bin/docker NVIDIA_DRIVER=418 From 7d2e27c0d70e16f5709c0b3f52a04c1f229ca1db Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Sun, 30 Oct 2022 13:58:42 +0200 Subject: [PATCH 265/316] Update 2022.1.5.rst Add bug list --- releases/2022.1.5.rst | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/releases/2022.1.5.rst b/releases/2022.1.5.rst index 828ac3d5f..318934b41 100644 --- a/releases/2022.1.5.rst +++ b/releases/2022.1.5.rst @@ -3,7 +3,7 @@ ************************** Release Notes 2022.1.5 ************************** -The 2022.1.5 release notes were released on 10/XX/2022 and describe the following: +The 2022.1.5 release notes were released on 11/02/2022 and describe the following: .. contents:: :local: @@ -27,7 +27,22 @@ Resolved Issues --------- The following table lists the issues that were resolved in Version 2022.1.5: -XXXXXX TBD XXXXXXXXXXXXXXXXXXXX ++--------------+------------------------------------------------------------------------------------------+ +| **SQ No.** | **Description** | ++==============+==========================================================================================+ +| SQ-11473 | SQream Command Line Interface connectivity issues | ++--------------+------------------------------------------------------------------------------------------+ +| SQ-11551 | SQream Studio Logs pages filtering issues | ++--------------+------------------------------------------------------------------------------------------+ +| SQ-11631 | Log related configuration flags are not working as expected | ++--------------+------------------------------------------------------------------------------------------+ +| SQ-11745 | Missing validation of sufficient GPU memory | ++--------------+------------------------------------------------------------------------------------------+ +| SQ-11792 | CUME_DIST function causes query execution errors | ++--------------+------------------------------------------------------------------------------------------+ +| SQ-11905 | GetDate casting to as text returns DATE with 0s in the time part or no time part at all | ++--------------+------------------------------------------------------------------------------------------+ + From 1572206fde5df85eeadb39331fad00131dc28a95 Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Mon, 31 Oct 2022 08:56:43 +0200 Subject: [PATCH 266/316] add features details --- releases/2022.1.5.rst | 16 ++++++++++++---- troubleshooting/lock_related_issues.rst | 2 ++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/releases/2022.1.5.rst b/releases/2022.1.5.rst index 318934b41..2ff841d42 100644 --- a/releases/2022.1.5.rst +++ b/releases/2022.1.5.rst @@ -9,13 +9,21 @@ The 2022.1.5 release notes were released on 11/02/2022 and describe the followin :local: :depth: 1 -Version Content +New Features ---------- -The 2022.1.5 Release Notes describes the following: +The 2022.1.5 Release Notes include the following new features: + +* keys_evaluate utility function enhancement - add problematic chunk ID to the function's output report. -XXXXXX TBD XXXXXXXXXXXXXXXXXXXX + :: - :: +* Automatically close database connections that have been open for 24 hours without any active statements. + + :: + +* release_defunct_locks utility function enhancement to receive new optional input parameter to specify timeout - for more details see `Lock Related Issues <../troubleshooting/lock_related_issues.html>`_. + + Known Issues diff --git a/troubleshooting/lock_related_issues.rst b/troubleshooting/lock_related_issues.rst index 1a15858ec..ed1e21579 100644 --- a/troubleshooting/lock_related_issues.rst +++ b/troubleshooting/lock_related_issues.rst @@ -26,4 +26,6 @@ If the locks still appear in the :ref:`show_locks` utility, we can force remove t=> SELECT RELEASE_DEFUNCT_LOCKS(); executed +.. tip:: ``RELEASE_DEFUNCT_LOCKS`` has an optional input parameter to specify the number of seconds, after which ``RELEASE_DEFUNCT_LOCKS`` will execute. + .. warning:: This operation can cause some statements to fail on the specific worker on which they are queued. This is intended as a "last resort" to solve stale locks. \ No newline at end of file From 0d17c656203004634229eb5e1f14f0b07ecdfe74 Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Mon, 31 Oct 2022 12:53:59 +0200 Subject: [PATCH 267/316] Update 2022.1.5.rst --- releases/2022.1.5.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/releases/2022.1.5.rst b/releases/2022.1.5.rst index 2ff841d42..1466882cc 100644 --- a/releases/2022.1.5.rst +++ b/releases/2022.1.5.rst @@ -17,7 +17,7 @@ The 2022.1.5 Release Notes include the following new features: :: -* Automatically close database connections that have been open for 24 hours without any active statements. +* Automatically close database client connections that have been open for 24 hours without any active statements. :: @@ -28,7 +28,7 @@ The 2022.1.5 Release Notes include the following new features: Known Issues --------- -No relevant Known Issues. +Recently discovered issue with the encryption feature, at this time SQream recommends to avoid using this feature - a fix will be introduced in the near future. Resolved Issues From 1e139a42cf6bc62f5ac9d9889772d7fc92e7f5a6 Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Tue, 1 Nov 2022 06:20:22 +0200 Subject: [PATCH 268/316] Update 2022.1.5.rst --- releases/2022.1.5.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/releases/2022.1.5.rst b/releases/2022.1.5.rst index 1466882cc..d63bf3b7a 100644 --- a/releases/2022.1.5.rst +++ b/releases/2022.1.5.rst @@ -38,6 +38,8 @@ The following table lists the issues that were resolved in Version 2022.1.5: +--------------+------------------------------------------------------------------------------------------+ | **SQ No.** | **Description** | +==============+==========================================================================================+ +| SQ-11081 | Tableau connection are not getting closed | ++--------------+------------------------------------------------------------------------------------------+ | SQ-11473 | SQream Command Line Interface connectivity issues | +--------------+------------------------------------------------------------------------------------------+ | SQ-11551 | SQream Studio Logs pages filtering issues | From 2a5ea06da042851b5bbe51827ebaf29b731313e4 Mon Sep 17 00:00:00 2001 From: RosinTalia Date: Sun, 6 Nov 2022 11:58:52 +0200 Subject: [PATCH 269/316] Update catalog_reference_catalog_tables.rst --- reference/catalog_reference_catalog_tables.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/reference/catalog_reference_catalog_tables.rst b/reference/catalog_reference_catalog_tables.rst index 7ddb9c148..4f4d60b76 100644 --- a/reference/catalog_reference_catalog_tables.rst +++ b/reference/catalog_reference_catalog_tables.rst @@ -303,8 +303,6 @@ The ``roles`` data object identifies the roles in the database, as shown in the - Identifies whether the role can be used to log in to SQream (``1`` - yes, ``0`` - no). * - ``has_password`` - Identifies whether the role has a password (``1`` - yes, ``0`` - no). - * - ``can_create_function`` - - Identifies whether role can create UDFs (``1`` - yes, ``0`` - no). Role Memberships *********** From f6a1a094e274396619bf3f81d105045b1179364a Mon Sep 17 00:00:00 2001 From: RosinTalia Date: Tue, 8 Nov 2022 10:54:20 +0200 Subject: [PATCH 270/316] Create external_data.rst --- operational_guides/external_data.rst | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 operational_guides/external_data.rst diff --git a/operational_guides/external_data.rst b/operational_guides/external_data.rst new file mode 100644 index 000000000..c9a6cfb33 --- /dev/null +++ b/operational_guides/external_data.rst @@ -0,0 +1,26 @@ +.. _external_data: + +********************************** +Working with External Data +********************************** +SQream supports the following external data sources: + +.. toctree:: + :maxdepth: 1 + :titlesonly: + + s3 + hdfs + mounting_an_nfs_shared_drive + +For more information, see the following: + +* :ref:`external_tables` + + :: + +* :ref:`copy_from` + + :: + +* :ref:`copy_to` \ No newline at end of file From ae7a7c79f6e3f8a24800ae1ce2ab4a9fa9fe52fd Mon Sep 17 00:00:00 2001 From: RosinTalia Date: Tue, 8 Nov 2022 11:38:39 +0200 Subject: [PATCH 271/316] Removed NFS + Relocate Exteranl storage data Removed NFS + Relocate Exteranl storage data --- index.rst | 221 ++++++++++++++++++++--------- operational_guides/hdfs.rst | 265 +++++++++++++++++++++++++++++++++++ operational_guides/index.rst | 3 + operational_guides/s3.rst | 129 +++++++++++++++++ 4 files changed, 552 insertions(+), 66 deletions(-) create mode 100644 operational_guides/hdfs.rst create mode 100644 operational_guides/s3.rst diff --git a/index.rst b/index.rst index c4bee46da..00c01f392 100644 --- a/index.rst +++ b/index.rst @@ -4,6 +4,8 @@ SQream DB Documentation ************************* +For SQream version 2021.2. + .. only:: html .. tip:: @@ -14,67 +16,155 @@ SQream DB Documentation .. tip:: This documentation is available online at https://docs.sqream.com/ -SQream DB is a columnar analytic SQL database management system. - -SQream DB supports regular SQL including :ref:`a substantial amount of ANSI SQL`, uses :ref:`serializable transactions`, and :ref:`scales horizontally` for concurrent statements. - -Even a :ref:`basic SQream DB machine` can support tens to hundreds of terabytes of data. - -SQream DB easily plugs in to third-party tools like :ref:`Tableau` comes with standard SQL client drivers, including :ref:`JDBC`, :ref:`ODBC`, and :ref:`Python DB-API`. - -.. - .. ref`features_tour` - -.. list-table:: - :widths: 33 33 33 - :header-rows: 0 - - * - **Get Started** - - **Reference** - - **Guides** - * - - `Getting Started `_ - - :ref:`sql_feature_support` - - :ref:`Bulk load CSVs` - - - :ref:`SQL Reference` - - :ref:`sql_statements` - - :ref:`sql_functions` - - - `Setting up SQream `_ - - :ref:`Best practices` - - - * - **Releases** - - **Driver and Deployment** - - **Help and Support** - * - - :ref:`2022.1<2022.1>` - - :ref:`2021.2<2021.2>` - - :ref:`2021.1<2021.1>` - - :ref:`2020.3<2020.3>` - - :ref:`2020.2<2020.2>` - - :ref:`2020.1<2020.1>` - - :ref:`All recent releases` - - - - :ref:`Client drivers` - - - - :ref:`troubleshooting` guide - - :ref:`information_for_support` +SQream DB is a columnar analytic SQL database management system. SQream DB supports regular SQL including :ref:`a substantial amount of ANSI SQL`, uses :ref:`serializable transactions`, and :ref:`scales horizontally` for concurrent statements. Even a :ref:`basic SQream DB machine` can support tens to hundreds of terabytes of data. SQream DB easily plugs in to third-party tools like :ref:`Tableau` comes with standard SQL client drivers, including :ref:`JDBC`, :ref:`ODBC`, and :ref:`Python DB-API`. + +:ref:`client_platforms` + ++---------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ +| Topic | Description | ++===================================================+========================================================================================================================================+ +| **Getting Started** | ++---------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ +| :ref:`preparing_your_machine_to_install_sqream` | Set up your local machine according to SQream’s recommended pre-installation configurations. | ++---------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ +| :ref:`executing_statements_in_sqream` | Provides more information about the available methods for executing statements in SQream. | ++---------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ +| :ref:`performing_basic_sqream_operations` | Provides more information on performing basic operations. | ++---------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ +| :ref:`hardware_guide` | Describes SQream’s mandatory and recommended hardware settings, designed for a technical audience. | ++---------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ +| **Installation Guides** | ++---------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ +| :ref:`installing_and_launching_sqream` | Refers to SQream’s installation guides. | ++---------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ +| :ref:`sqream_studio_installation` | Refers to all installation guides required for installations related to Studio. | ++---------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ +| **Ingesting Data** | ++--------------------------+------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ +| :ref:`csv` | :ref:`avro` | | ++--------------------------+------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ +| :ref:`parquet` | :ref:`orc` | | ++--------------------------+------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ +| :ref:`oracle` | ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| **Connecting to SQream** | ++--------------------------+------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ +| :ref:`client_platforms` | Describes how to install and connect a variety of third party connection platforms and tools. | ++---------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ +| :ref:`client_drivers` | Describes how to use the SQream client drivers and client applications with SQream. | ++---------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ +| **External Storage Platforms** | ++---------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ +| :ref:`s3` | Describes how to insert data over a native S3 connector. | ++---------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ +| :ref:`hdfs` | Describes how to configure an HDFS environment for the user sqream and is only relevant for users with an HDFS environment. | ++---------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ + + + Loading and unloading data: + + * Loading data: + + * Overview of loading data + * Alternatives to loading data (foreign tables) + * Supported data types + * Ingesting data from external sources + * Inserting data from external tables + * Ingesting data from third party client platforms + * Using the **COPY FROM** statement + * Importing data using Studio + * Loading data using Amazon S3 + + * Unloading data: + + * Overview of unloading data + * Using the **COPY TO** statement + + Feature guides: + + * Query Healer + * Automatic schema Identification + * Compression + * Python UDF (User-Defined Functions) + * Workload Manager + * Transactions + * Concurrency and locks + * Concurrency and scaling in SQream DB + + Operational guides: + + * Access control + * Creating or cloning storage clusters + * Foreign tables + * Deleting data + * Exporting data + * Logging + * Monitoring query performance + * Security + * Saved queries + * Seeing system objects as DDL + * Optimization and best practices + + SQream Accelerated Studio 5.4.3: + + * Getting started with SQream Acceleration Studio 5.4.3 + * Monitoring workers and services from the dashboard + * Executing statements and running queries from the Editor + * Viewing logs + * Creating, assigning, and managing roles and permissions + * Configuring Your instance of SQream + + System architecture: + + * Internals and architecture + * Filesystem and usage + + Configuring SQream: + + * Configuration methods + * Configuration flags + + Reference guides: + + * SQL syntax, statements, and functions + * Catalog reference guide + * Command Line programs + * SQL feature checklist + * Python API reference guide + + Data type guides: + + * Converting and casting + * Supported data types + * Supported casts + + Release notes: + + * 2022.1 + * 2021.2 + * 2021.1 + * 2020.3 + * 2020.2 + * 2020.1 + + Troubleshooting: + + * Remedying slow queries + * Resolving common issues + * Examining logs + * Identifying configuration issues + * Lock related issues + * SAS Viya related issues + * Tableau related issues + * Solving “Code 126” ODBC errors + * Log related issues + * Node.js related issues + * Core dumping related issues + * SQream SQL installation related issues + * Gathering information for SQream support + + Glossary + @@ -85,9 +175,9 @@ If you couldn't find what you're looking for, we're always happy to help. Visit .. rubric:: Looking for older versions? -This version of the documentation is for SQream DB Version 2022.1. +This version of the documentation is for SQream DB Version 2021.2. -If you're looking for an older version of the documentation, versions 1.10 through 2019.2.1 are available at http://previous.sqream.com. +If you're looking for an older version of the documentation, versions 1.10 through 2019.2.1 are available at http://previous.sqream.com . .. toctree:: :caption: Contents: @@ -100,7 +190,6 @@ If you're looking for an older version of the documentation, versions 1.10 throu installation_guides/index data_ingestion/index connecting_to_sqream/index - external_storage_platforms/index loading_and_unloading_data/index feature_guides/index operational_guides/index @@ -114,9 +203,9 @@ If you're looking for an older version of the documentation, versions 1.10 throu glossary .. - Indices and Tables + Indices and tables ================== * :ref:`genindex` * :ref:`modindex` - * :ref:`search` \ No newline at end of file + * :ref:`search` diff --git a/operational_guides/hdfs.rst b/operational_guides/hdfs.rst new file mode 100644 index 000000000..e59c49cc7 --- /dev/null +++ b/operational_guides/hdfs.rst @@ -0,0 +1,265 @@ +.. _hdfs: + +.. _back_to_top_hdfs: + +Using SQream in an HDFS Environment +======================================= + +.. _configuring_an_hdfs_environment_for_the_user_sqream: + +Configuring an HDFS Environment for the User **sqream** +---------------------------------------------------------- + +This section describes how to configure an HDFS environment for the user **sqream** and is only relevant for users with an HDFS environment. + +**To configure an HDFS environment for the user sqream:** + +1. Open your **bash_profile** configuration file for editing: + + .. code-block:: console + + $ vim /home/sqream/.bash_profile + +.. + Comment: - see below; do we want to be a bit more specific on what changes we're talking about? + + .. code-block:: console + + $ #PATH=$PATH:$HOME/.local/bin:$HOME/bin + + $ #export PATH + + $ # PS1 + $ #MYIP=$(curl -s -XGET "http://ip-api.com/json" | python -c 'import json,sys; jstr=json.load(sys.stdin); print jstr["query"]') + $ #PS1="\[\e[01;32m\]\D{%F %T} \[\e[01;33m\]\u@\[\e[01;36m\]$MYIP \[\e[01;31m\]\w\[\e[37;36m\]\$ \[\e[1;37m\]" + + $ SQREAM_HOME=/usr/local/sqream + $ export SQREAM_HOME + + $ export JAVA_HOME=${SQREAM_HOME}/hdfs/jdk + $ export HADOOP_INSTALL=${SQREAM_HOME}/hdfs/hadoop + $ export CLASSPATH=`${HADOOP_INSTALL}/bin/hadoop classpath --glob` + $ export HADOOP_COMMON_LIB_NATIVE_DIR=${HADOOP_INSTALL}/lib/native + $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${SQREAM_HOME}/lib:$HADOOP_COMMON_LIB_NATIVE_DIR + + + $ PATH=$PATH:$HOME/.local/bin:$HOME/bin:${SQREAM_HOME}/bin/:${JAVA_HOME}/bin:$HADOOP_INSTALL/bin + $ export PATH + +2. Verify that the edits have been made: + + .. code-block:: console + + source /home/sqream/.bash_profile + +3. Check if you can access Hadoop from your machine: + + .. code-block:: console + + $ hadoop fs -ls hdfs://:8020/ + +.. + Comment: - + **NOTICE:** If you cannot access Hadoop from your machine because it uses Kerberos, see `Connecting a SQream Server to Cloudera Hadoop with Kerberos `_ + + +4. Verify that an HDFS environment exists for SQream services: + + .. code-block:: console + + $ ls -l /etc/sqream/sqream_env.sh + +.. _step_6: + + +5. If an HDFS environment does not exist for SQream services, create one (sqream_env.sh): + + .. code-block:: console + + $ #!/bin/bash + + $ SQREAM_HOME=/usr/local/sqream + $ export SQREAM_HOME + + $ export JAVA_HOME=${SQREAM_HOME}/hdfs/jdk + $ export HADOOP_INSTALL=${SQREAM_HOME}/hdfs/hadoop + $ export CLASSPATH=`${HADOOP_INSTALL}/bin/hadoop classpath --glob` + $ export HADOOP_COMMON_LIB_NATIVE_DIR=${HADOOP_INSTALL}/lib/native + $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${SQREAM_HOME}/lib:$HADOOP_COMMON_LIB_NATIVE_DIR + + + $ PATH=$PATH:$HOME/.local/bin:$HOME/bin:${SQREAM_HOME}/bin/:${JAVA_HOME}/bin:$HADOOP_INSTALL/bin + $ export PATH + +:ref:`Back to top ` + +.. _authenticate_hadoop_servers_that_require_kerberos: + +Authenticating Hadoop Servers that Require Kerberos +--------------------------------------------------- +If your Hadoop server requires Kerberos authentication, do the following: + +1. Create a principal for the user **sqream**. + + .. code-block:: console + + $ kadmin -p root/admin@SQ.COM + $ addprinc sqream@SQ.COM + +2. If you do not know yor Kerberos root credentials, connect to the Kerberos server as a root user with ssh and run **kadmin.local**: + + .. code-block:: console + + $ kadmin.local + + Running **kadmin.local** does not require a password. + +3. If a password is not required, change your password to **sqream@SQ.COM**. + + .. code-block:: console + + $ change_password sqream@SQ.COM + +4. Connect to the hadoop name node using ssh: + + .. code-block:: console + + $ cd /var/run/cloudera-scm-agent/process + +5. Check the most recently modified content of the directory above: + + .. code-block:: console + + $ ls -lrt + +6. Look for a recently updated folder containing the text **hdfs**. + + The following is an example of the correct folder name: + + .. code-block:: console + + cd -hdfs- + + This folder should contain a file named **hdfs.keytab** or another similar .keytab file. + + + +.. + Comment: - Does "something" need to be replaced with "file name" + + +7. Copy the .keytab file to user **sqream's** Home directory on the remote machines that you are planning to use Hadoop on. + + :: + +8. Copy the following files to the **sqream sqream@server:/hdfs/hadoop/etc/hadoop:** directory: + + * core-site.xml + * hdfs-site.xml + +9. Connect to the sqream server and verify that the .keytab file's owner is a user sqream and is granted the correct permissions: + + .. code-block:: console + + $ sudo chown sqream:sqream /home/sqream/hdfs.keytab + $ sudo chmod 600 /home/sqream/hdfs.keytab + +10. Log into the sqream server. + + :: + +11. Log in as the user **sqream**. + + :: + +12. Navigate to the Home directory and check the name of a Kerberos principal represented by the following .keytab file: + + .. code-block:: console + + $ klist -kt hdfs.keytab + + The following is an example of the correct output: + + .. code-block:: console + + $ sqream@Host-121 ~ $ klist -kt hdfs.keytab + $ Keytab name: FILE:hdfs.keytab + $ KVNO Timestamp Principal + $ ---- ------------------- ------------------------------------------------------ + $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 HTTP/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM + $ 5 09/15/2020 18:03:05 hdfs/nn1@SQ.COM + +13. Verify that the hdfs service named **hdfs/nn1@SQ.COM** is shown in the generated output above. + + :: + +14. Run the following: + + .. code-block:: console + + $ kinit -kt hdfs.keytab hdfs/nn1@SQ.COM + +15. Verify that the output is correct: + + .. code-block:: console + + $ klist + + The following is an example of the correct output: + + .. code-block:: console + + $ Ticket cache: FILE:/tmp/krb5cc_1000 + $ Default principal: sqream@SQ.COM + $ + $ Valid starting Expires Service principal + $ 09/16/2020 13:44:18 09/17/2020 13:44:18 krbtgt/SQ.COM@SQ.COM + +16. List the files located at the defined server name or IP address: + + .. code-block:: console + + $ hadoop fs -ls hdfs://:8020/ + +17. Do one of the following: + + :: + + * If the list below is output, continue with Step 18. + + :: + + * If the list is not output, verify that your environment has been set up correctly. + +If any of the following are empty, verify that you followed :ref:`Step 6 ` in the **Configuring an HDFS Environment for the User sqream** section above correctly: + + .. code-block:: console + + $ echo $JAVA_HOME + $ echo $SQREAM_HOME + $ echo $CLASSPATH + $ echo $HADOOP_COMMON_LIB_NATIVE_DIR + $ echo $LD_LIBRARY_PATH + $ echo $PATH + +18. Verify that you copied the correct keytab file. + + :: + +19. Review this procedure to verify that you have followed each step. + +:ref:`Back to top ` \ No newline at end of file diff --git a/operational_guides/index.rst b/operational_guides/index.rst index 25e2cdff2..048efb06f 100644 --- a/operational_guides/index.rst +++ b/operational_guides/index.rst @@ -14,12 +14,15 @@ This section summarizes the following operational guides: access_control creating_or_cloning_a_storage_cluster + external_data foreign_tables delete_guide exporting_data logging monitoring_query_performance security + saved_queries seeing_system_objects_as_ddl configuration optimization_best_practices + hardware_guide diff --git a/operational_guides/s3.rst b/operational_guides/s3.rst new file mode 100644 index 000000000..5e4f8b264 --- /dev/null +++ b/operational_guides/s3.rst @@ -0,0 +1,129 @@ +.. _s3: + +*********************** +Inserting Data Using Amazon S3 +*********************** +SQream uses a native S3 connector for directly inserting data from a number of external sources directly into SQream. This is done using the ``s3://`` URI to specify an external file path on an S3 bucket. Your files can be saved in CSV or columnar format, such as Parquet and ORC, and your file names can include wildcard characters. + +The **Amazon S3** page describes the following topics: + +.. contents:: + :local: + :depth: 1 + +Configuring Amazon S3 +============================== +Any database host with access to S3 endpoints can access S3 without any configuration. To read files from an S3 bucket, the database must have listable files. + +Setting the S3 URI Format +=============== +With S3, specify a location for a file (or files) when using :ref:`copy_from` or :ref:`external_tables`. + +The following is an example of the general S3 syntax: + +.. code-block:: console + + s3://bucket_name/path + +Authenticating Users +================= + +SQream supports ``AWS ID`` and ``AWS SECRET`` authentication. These should be specified when executing a statement. + +Examples +========== +You can use a foreign table to stage data from S3 before loading from CSV, Parquet, or ORC files. + +This section includes the following examples: + +.. contents:: + :local: + :depth: 1 + +Planning for Data Staging +-------------------------------- +The examples in this section are based on the CSV file shown in the following table: + +.. csv-table:: nba-t10 + :file: ../_static/samples/nba-t10.csv + :widths: auto + :header-rows: 1 + +This CSV file is stored on Amazon S3, and this bucket is public and listable. To create a matching ``CREATE FOREIGN TABLE`` statement you can make a record of your source file's structure and use it to reproduce a corresponding foreign table, as shown in the following section. + +Creating a Foreign Table +----------------------------- +Based on the source file's structure above, you can create a foreign table with the structure you want and point it to your file, as shown in the following example: + +.. code-block:: postgres + + CREATE FOREIGN TABLE nba + ( + Name text(40), + Team text(40), + Number tinyint, + Position text(2), + Age tinyint, + Height text(4), + Weight real, + College text(40), + Salary float + ) + WRAPPER csv_fdw + OPTIONS + ( + LOCATION = 's3://sqream-demo-data/nba_players.csv', + RECORD_DELIMITER = '\r\n' -- DOS delimited file + ) + ; + +.. note:: In the example above the file format is CSV and is stored as an S3 object. If your file has an HDFS path, you must change the URI accordingly. Note that the record delimiter is a DOS newline (``\r\n``). + +For more information, see the following: + +* **Creating a foreign table** - see :ref:`creating a foreign table`. +* **Using SQream in an HDFS environment** - see :ref:`hdfs`. + +Querying Foreign Tables +------------------------------ +The following shows the data located in the foreign table: + +.. code-block:: psql + + t=> SELECT * FROM nba LIMIT 10; + name | team | number | position | age | height | weight | college | salary + --------------+----------------+--------+----------+-----+--------+--------+-------------------+--------- + Avery Bradley | Boston Celtics | 0 | PG | 25 | 6-2 | 180 | Texas | 7730337 + Jae Crowder | Boston Celtics | 99 | SF | 25 | 6-6 | 235 | Marquette | 6796117 + John Holland | Boston Celtics | 30 | SG | 27 | 6-5 | 205 | Boston University | + R.J. Hunter | Boston Celtics | 28 | SG | 22 | 6-5 | 185 | Georgia State | 1148640 + Jonas Jerebko | Boston Celtics | 8 | PF | 29 | 6-10 | 231 | | 5000000 + Amir Johnson | Boston Celtics | 90 | PF | 29 | 6-9 | 240 | | 12000000 + Jordan Mickey | Boston Celtics | 55 | PF | 21 | 6-8 | 235 | LSU | 1170960 + Kelly Olynyk | Boston Celtics | 41 | C | 25 | 7-0 | 238 | Gonzaga | 2165160 + Terry Rozier | Boston Celtics | 12 | PG | 22 | 6-2 | 190 | Louisville | 1824360 + Marcus Smart | Boston Celtics | 36 | PG | 22 | 6-4 | 220 | Oklahoma State | 3431040 + +Bulk Loading a File from a Public S3 Bucket +---------------------------------------------- +Youc an use the ``COPY FROM`` command to load data without staging it first. + +.. note:: The bucket must be publicly available and objects can be listed. + +The following is an example of bulk loading a file from a public S3 bucket: + +.. code-block:: postgres + + COPY nba FROM 's3://sqream-demo-data/nba.csv' WITH OFFSET 2 RECORD DELIMITER '\r\n'; + +For more information on the ``COPY FROM`` command, see :ref:`copy_from`. + +Loading Files from an Authenticated S3 Bucket +--------------------------------------------------- +The following is an example of loading fles from an authenticated S3 bucket: + +.. code-block:: postgres + + COPY nba FROM 's3://secret-bucket/*.csv' WITH OFFSET 2 RECORD DELIMITER '\r\n' + AWS_ID '12345678' + AWS_SECRET 'super_secretive_secret'; \ No newline at end of file From 491cbfbe35c659fd7e84b7efcd7369300f90f14a Mon Sep 17 00:00:00 2001 From: RosinTalia Date: Tue, 8 Nov 2022 15:24:32 +0200 Subject: [PATCH 272/316] Update copy_to.rst --- reference/sql/sql_statements/dml_commands/copy_to.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reference/sql/sql_statements/dml_commands/copy_to.rst b/reference/sql/sql_statements/dml_commands/copy_to.rst index bd32a325f..0edb0a4d6 100644 --- a/reference/sql/sql_statements/dml_commands/copy_to.rst +++ b/reference/sql/sql_statements/dml_commands/copy_to.rst @@ -32,7 +32,7 @@ The following is the correct syntax for using the **COPY TO** statement: ) ; - fdw_name ::= csw_fdw | parquet_fdw | orc_fdw + fdw_name ::= csv_fdw | parquet_fdw | orc_fdw schema_name ::= identifer @@ -84,7 +84,7 @@ The following table shows the ``COPY_TO`` elements: * - ``query`` - An SQL query that returns a table result, or a table name * - ``fdw_name`` - - The name of the Foreign Data Wrapper to use. Supported FDWs are ``csv_fdw``, ``orc_fdw``, or ``parquet_fdw``. + - The name of the Foreign Data Wrapper to use. Supported FDWs are ``csv_fdw``, ``orc_fdw``, ``avro_fdw`` or ``parquet_fdw``. * - ``LOCATION`` - A path on the local filesystem, S3, or HDFS URI. For example, ``/tmp/foo.csv``, ``s3://my-bucket/foo.csv``, or ``hdfs://my-namenode:8020/foo.csv``. The local path must be an absolute path that SQream DB can access. * - ``HEADER`` @@ -545,4 +545,4 @@ The following is an example of exporting a table to an ORC file: Permissions ============= -The role must have the ``SELECT`` permission on every table or schema that is referenced by the statement. +The role must have the ``SELECT`` permission on every table or schema that is referenced by the statement. \ No newline at end of file From b3c10858a94ff2b92b1bbc39632af9d7d99b67f5 Mon Sep 17 00:00:00 2001 From: RosinTalia Date: Wed, 16 Nov 2022 13:29:14 +0200 Subject: [PATCH 273/316] Update create_table.rst --- reference/sql/sql_statements/ddl_commands/create_table.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference/sql/sql_statements/ddl_commands/create_table.rst b/reference/sql/sql_statements/ddl_commands/create_table.rst index 9fd4bacf5..f32afe2dd 100644 --- a/reference/sql/sql_statements/ddl_commands/create_table.rst +++ b/reference/sql/sql_statements/ddl_commands/create_table.rst @@ -74,7 +74,7 @@ Default Value Constraints The ``DEFAULT`` value constraint specifies a value to use if one is not defined in an :ref:`insert` or :ref:`copy_from` statement. -The value may either be NULL or a literal. +The default value may be a literal, GETDATE(), or NULL. .. note:: The ``DEFAULT`` constraint only applies if the column does not have a value specified in the :ref:`insert` or :ref:`copy_from` statement. You can still insert a ``NULL`` into an nullable column by explicitly inserting ``NULL``. For example, ``INSERT INTO cool_animals VALUES (1, 'Gnu', NULL)``. From d063297e31ef6cbbd17ea88fc063d0458e96996a Mon Sep 17 00:00:00 2001 From: RosinTalia Date: Sun, 20 Nov 2022 16:26:31 +0200 Subject: [PATCH 274/316] Password policy --- operational_guides/access_control_password_policy.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/operational_guides/access_control_password_policy.rst b/operational_guides/access_control_password_policy.rst index 055d674bb..6c69257ed 100644 --- a/operational_guides/access_control_password_policy.rst +++ b/operational_guides/access_control_password_policy.rst @@ -31,7 +31,7 @@ As part of our compliance with GDPR standards SQream relies on a strong password * Must include at least one special character, such as **?**, **!**, **$**, etc. -You can grant a password through the Studio graphic interface or through the CLI, as in the following example command: +You can create a password by using the Studio graphic interface or using the CLI, as in the following example command: .. code-block:: console @@ -39,7 +39,7 @@ You can grant a password through the Studio graphic interface or through the CLI GRANT LOGIN to user_a ; GRANT PASSWORD 'BBAu47?fqPL' to user_a ; -Granting a password that does not comply with the above requirements generates an error message with a request to modify it; +Creating a password which does not comply with the password policy generates an error message with a request to include any of the missing above requirements: .. code-block:: console @@ -59,7 +59,7 @@ Granting a password that does not comply with the above requirements generates a Brute Force Prevention ============================== -Unsuccessfully attempting to log in three times displays the following message: +Unsuccessfully attempting to log in five times displays the following message: .. code-block:: console From 65223761de32ad26d886606b7f66ed98949ca294 Mon Sep 17 00:00:00 2001 From: RosinTalia Date: Sun, 20 Nov 2022 17:31:13 +0200 Subject: [PATCH 275/316] Update index.rst --- index.rst | 125 ++++-------------------------------------------------- 1 file changed, 8 insertions(+), 117 deletions(-) diff --git a/index.rst b/index.rst index 00c01f392..c3d41c39c 100644 --- a/index.rst +++ b/index.rst @@ -4,21 +4,9 @@ SQream DB Documentation ************************* -For SQream version 2021.2. - -.. only:: html - - .. tip:: - Want to read this offline? - `Download the documentation as a single PDF `_ . - -.. only:: pdf or latex - - .. tip:: This documentation is available online at https://docs.sqream.com/ SQream DB is a columnar analytic SQL database management system. SQream DB supports regular SQL including :ref:`a substantial amount of ANSI SQL`, uses :ref:`serializable transactions`, and :ref:`scales horizontally` for concurrent statements. Even a :ref:`basic SQream DB machine` can support tens to hundreds of terabytes of data. SQream DB easily plugs in to third-party tools like :ref:`Tableau` comes with standard SQL client drivers, including :ref:`JDBC`, :ref:`ODBC`, and :ref:`Python DB-API`. -:ref:`client_platforms` +---------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ | Topic | Description | @@ -61,111 +49,15 @@ SQream DB is a columnar analytic SQL database management system. SQream DB suppo +---------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ - Loading and unloading data: - - * Loading data: - - * Overview of loading data - * Alternatives to loading data (foreign tables) - * Supported data types - * Ingesting data from external sources - * Inserting data from external tables - * Ingesting data from third party client platforms - * Using the **COPY FROM** statement - * Importing data using Studio - * Loading data using Amazon S3 - - * Unloading data: - - * Overview of unloading data - * Using the **COPY TO** statement - - Feature guides: - - * Query Healer - * Automatic schema Identification - * Compression - * Python UDF (User-Defined Functions) - * Workload Manager - * Transactions - * Concurrency and locks - * Concurrency and scaling in SQream DB - - Operational guides: - - * Access control - * Creating or cloning storage clusters - * Foreign tables - * Deleting data - * Exporting data - * Logging - * Monitoring query performance - * Security - * Saved queries - * Seeing system objects as DDL - * Optimization and best practices - - SQream Accelerated Studio 5.4.3: - - * Getting started with SQream Acceleration Studio 5.4.3 - * Monitoring workers and services from the dashboard - * Executing statements and running queries from the Editor - * Viewing logs - * Creating, assigning, and managing roles and permissions - * Configuring Your instance of SQream - - System architecture: - - * Internals and architecture - * Filesystem and usage - - Configuring SQream: - - * Configuration methods - * Configuration flags - - Reference guides: - - * SQL syntax, statements, and functions - * Catalog reference guide - * Command Line programs - * SQL feature checklist - * Python API reference guide - - Data type guides: - - * Converting and casting - * Supported data types - * Supported casts - - Release notes: - - * 2022.1 - * 2021.2 - * 2021.1 - * 2020.3 - * 2020.2 - * 2020.1 - - Troubleshooting: - - * Remedying slow queries - * Resolving common issues - * Examining logs - * Identifying configuration issues - * Lock related issues - * SAS Viya related issues - * Tableau related issues - * Solving “Code 126” ODBC errors - * Log related issues - * Node.js related issues - * Core dumping related issues - * SQream SQL installation related issues - * Gathering information for SQream support - - Glossary +.. only:: html + .. tip:: + Want to read this offline? + `Download the documentation as a single PDF `_ . +.. only:: pdf or latex + + .. tip:: This documentation is available online at https://docs.sqream.com/ .. rubric:: Need help? @@ -175,9 +67,8 @@ If you couldn't find what you're looking for, we're always happy to help. Visit .. rubric:: Looking for older versions? -This version of the documentation is for SQream DB Version 2021.2. -If you're looking for an older version of the documentation, versions 1.10 through 2019.2.1 are available at http://previous.sqream.com . +If you're looking for an older version of the documentation, go to http://previous.sqream.com . .. toctree:: :caption: Contents: From 5537d5a4167805632352d1e354997626ea74e608 Mon Sep 17 00:00:00 2001 From: RosinTalia Date: Tue, 22 Nov 2022 12:02:40 +0200 Subject: [PATCH 276/316] Update filesystem_and_filesystem_usage.rst --- architecture/filesystem_and_filesystem_usage.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/architecture/filesystem_and_filesystem_usage.rst b/architecture/filesystem_and_filesystem_usage.rst index d1838d4e8..c4e2e1d80 100644 --- a/architecture/filesystem_and_filesystem_usage.rst +++ b/architecture/filesystem_and_filesystem_usage.rst @@ -27,7 +27,7 @@ The **cluster root** is the directory in which all data for SQream DB is stored. The databases directory houses all of the actual data in tables and columns. -Each database is stored as it's own directory. Each table is stored under it's respective database, and columns are stored in their respective table. +Each database is stored as its own directory. Each table is stored under it's respective database, and columns are stored in their respective table. .. figure:: /_static/images/table_columns_storage.png From 1b885eace944f80c93a492106be0ecc92ae26b99 Mon Sep 17 00:00:00 2001 From: RosinTalia Date: Tue, 22 Nov 2022 14:15:14 +0200 Subject: [PATCH 277/316] Update index.rst --- connecting_to_sqream/client_drivers/index.rst | 47 +++++++++++++++---- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/connecting_to_sqream/client_drivers/index.rst b/connecting_to_sqream/client_drivers/index.rst index 5365380b9..957fa3505 100644 --- a/connecting_to_sqream/client_drivers/index.rst +++ b/connecting_to_sqream/client_drivers/index.rst @@ -1,7 +1,7 @@ .. _client_drivers: ************************************ -Client Drivers for 2022.1 +Client Drivers for 2022.1.6 ************************************ The guides on this page describe how to use the Sqream DB client drivers and client applications with SQream. @@ -17,15 +17,39 @@ The following are applicable to all operating systems: * **JDBC** - recommended installation via ``mvn``: - * `JDBC .jar file `_ - sqream-jdbc-4.5.4 (.jar) - * `JDBC driver `_ + * `JDBC .jar file `_ - sqream-jdbc-4.5.3 (.jar) + * `JDBC driver `_ + +.. _.net: + +* **.NET**: + + * `.NET .dll file `_ + * `.NET driver `_ + + +.. _python: + +* **Python** - Recommended installation via ``pip``: + + * `Python .tar file `_ - pysqream v3.1.3 (.tar.gz) + * `Python driver `_ + + +.. _nodejs: + +* **Node.JS** - Recommended installation via ``npm``: + + * `Node.JS `_ - sqream-v4.2.4 (.tar.gz) + * `Node.JS driver `_ + .. _tableau_connector: * **Tableau**: * `Tableau connector `_ - SQream (.taco) - * `Tableau manual installation `_ + * `Tableau manual installation `_ .. _powerbi_connector: @@ -33,17 +57,18 @@ The following are applicable to all operating systems: * **Power BI**: * `Power BI PowerQuery connector `_ - SQream (.mez) - * `Power BI manual installation `_ + * `Power BI manual installation `_ Windows -------------- The following are applicable to Windows: -* **ODBC installer** - SQream Drivers v2020.2.0, with Tableau customization. Please contact your `SQream representative `_ for this installer. +* **ODBC installer** - SQream Drivers v2020.2.0, with Tableau customizations. Please contact your `Sqream represenative `_ for this installer. For more information on installing and configuring ODBC on Windows, see :ref:`Install and configure ODBC on Windows `. + * **Net driver** - `SQream .Net driver v3.0.2 `_ @@ -53,25 +78,29 @@ Linux The following are applicable to Linux: * `SQream SQL (x86_64) `_ - sqream-sql-v2020.1.1_stable.x86_64.tar.gz -* `Sqream SQL CLI Reference `_ - Interactive command-line SQL client for Intel-based machines +* `Sqream SQL CLI Reference `_ - Interactive command-line SQL client for Intel-based machines :: * `SQream SQL*(IBM POWER9) `_ - sqream-sql-v2020.1.1_stable.ppc64le.tar.gz -* `Sqream SQL CLI Reference `_ - Interactive command-line SQL client for IBM POWER9-based machines +* `Sqream SQL CLI Reference `_ - Interactive command-line SQL client for IBM POWER9-based machines :: * ODBC Installer - Please contact your SQream representative for this installer. + .. toctree:: :maxdepth: 4 :caption: Client Driver Documentation: :titlesonly: jdbc/index + python/index + nodejs/index odbc/index + dotnet/index @@ -81,4 +110,4 @@ If you couldn't find what you're looking for, we're always happy to help. Visit .. rubric:: Looking for older drivers? -If you're looking for an older version of SQream DB drivers, versions 1.10 through 2019.2.1 are available at https://sqream.com/product/client-drivers/. +If you're looking for an older version of SQream DB drivers, versions 1.10 through 2019.2.1 are available at https://sqream.com/product/client-drivers/. \ No newline at end of file From 4773151173b31e1658b669dfa84bac93de2ed072 Mon Sep 17 00:00:00 2001 From: RosinTalia Date: Tue, 22 Nov 2022 15:08:15 +0200 Subject: [PATCH 278/316] .NET --- .../client_drivers/dotnet/index.rst | 131 ++++ .../client_drivers/dotnet/sample.cs | 93 +++ .../client_drivers/nodejs/index.rst | 382 ++++++++++++ .../client_drivers/nodejs/sample.js | 21 + .../client_drivers/python/index.rst | 568 ++++++++++++++++++ .../client_drivers/python/nba-t10.csv | 10 + .../client_drivers/python/test.py | 37 ++ 7 files changed, 1242 insertions(+) create mode 100644 connecting_to_sqream/client_drivers/dotnet/index.rst create mode 100644 connecting_to_sqream/client_drivers/dotnet/sample.cs create mode 100644 connecting_to_sqream/client_drivers/nodejs/index.rst create mode 100644 connecting_to_sqream/client_drivers/nodejs/sample.js create mode 100644 connecting_to_sqream/client_drivers/python/index.rst create mode 100644 connecting_to_sqream/client_drivers/python/nba-t10.csv create mode 100644 connecting_to_sqream/client_drivers/python/test.py diff --git a/connecting_to_sqream/client_drivers/dotnet/index.rst b/connecting_to_sqream/client_drivers/dotnet/index.rst new file mode 100644 index 000000000..1d28069a7 --- /dev/null +++ b/connecting_to_sqream/client_drivers/dotnet/index.rst @@ -0,0 +1,131 @@ +.. _net: + +************************* +.NET +************************* +The SqreamNet ADO.NET Data Provider lets you connect to SQream through your .NET environment. + +The .NET page includes the following sections: + +.. contents:: + :local: + :depth: 1 + +Integrating SQreamNet +================================== +The **Integrating SQreamNet** section describes the following: + +.. contents:: + :local: + :depth: 1 + +Prerequisites +---------------- +The SqreamNet provider requires a .NET version 6 or newer. + +Getting the DLL file +---------------- +The .NET driver is available for download from the :ref:`client drivers download page`. + +Integrating SQreamNet +------------------------- +After downloading the .NET driver, save the archive file to a known location. Next, in your IDE, add a Sqreamnet.dll reference to your project. + +If you wish to upgrade SQreamNet within an existing project, you may replace the existing .dll file with an updated one or change the project's reference location to a new one. + + +Known Driver Limitations +---------------------------- + * Unicode characters are not supported when using ``INSERT INTO AS SELECT``. + + * To avoid possible casting issues, use ``getDouble`` when using ``FLOAT``. + +Connecting to SQream For the First Time +============================================== +An initial connection to SQream must be established by creating a **SqreamConnection** object using a connection string. + +.. contents:: + :local: + :depth: 1 + + +Connection String +-------------------- +To connect to SQream, instantiate a **SqreamConnection** object using this connection string. + +The following is the syntax for SQream: + +.. code-block:: text + + "Data Source=,;User=;Password=;Initial Catalog=;Integrated Security=true"; + +Connection Parameters +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Item + - State + - Default + - Description + * - ```` + - Mandatory + - None + - Hostname/IP/FQDN and port of the SQream DB worker. For example, ``127.0.0.1:5000``, ``sqream.mynetwork.co:3108`` + * - ```` + - Mandatory + - None + - Database name to connect to. For example, ``master`` + * - ```` + - Mandatory + - None + - Username of a role to use for connection. For example, ``username=rhendricks`` + * - ```` + - Mandatory + - None + - Specifies the password of the selected role. For example, ``password=Tr0ub4dor&3`` + * - ```` + - Optional + - ``sqream`` + - Specifices service queue to use. For example, ``service=etl`` + * - ```` + - Optional + - ``false`` + - Specifies SSL for this connection. For example, ``ssl=true`` + * - ```` + - Optional + - ``true`` + - Connect via load balancer (use only if exists, and check port). + +Connection String Examples +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The following is an example of a SQream cluster with load balancer and no service queues (with SSL): + +.. code-block:: text + + Data Source=sqream.mynetwork.co,3108;User=rhendricks;Password=Tr0ub4dor&3;Initial Catalog=master;Integrated Security=true;ssl=true;cluster=true; + + +The following is a minimal example for a local standalone SQream database: + +.. code-block:: text + + + Data Source=127.0.0.1,5000;User=rhendricks;Password=Tr0ub4dor&3;Initial Catalog=master; + +The following is an example of a SQream cluster with load balancer and a specific service queue named ``etl``, to the database named ``raviga`` + +.. code-block:: text + + Data Source=sqream.mynetwork.co,3108;User=rhendricks;Password=Tr0ub4dor&3;Initial Catalog=raviga;Integrated Security=true;service=etl;cluster=true; + +Sample C# Program +-------------------- +You can download the :download:`.NET Application Sample File ` below by right-clicking and saving it to your computer. + +.. literalinclude:: sample.cs + :language: C# + :caption: .NET Application Sample + :linenos: diff --git a/connecting_to_sqream/client_drivers/dotnet/sample.cs b/connecting_to_sqream/client_drivers/dotnet/sample.cs new file mode 100644 index 000000000..54a19e0da --- /dev/null +++ b/connecting_to_sqream/client_drivers/dotnet/sample.cs @@ -0,0 +1,93 @@ + public void Test() + { + var connection = OpenConnection("192.168.4.62", 5000, "sqream", "sqream", "master"); + + ExecuteSQLCommand(connection, "create or replace table tbl_example as select 1 as x , 'a' as y;"); + + var tableData = ReadExampleData(connection, "select * from tbl_example;"); + } + + /// + /// Builds a connection string to sqream server and opens a connection + /// + /// host to connect + /// port sqreamd is running on + /// role username + /// role password + /// database name + /// optional - set to true when the ip,port endpoint is a server picker process + /// + /// SQream connection object + /// Throws SqreamException if fails to open a connction + /// + public SqreamConnection OpenConnection(string ipAddress, int port, string username, string password, string databaseName, bool isCluster = false) + { + // create the connection string according to the format + var connectionString = string.Format( + "Data Source={0},{1};User={2};Password={3};Initial Catalog={4};Cluster={5}", + ipAddress, + port, + username, + password, + databaseName, + isCluster + ); + + // create a sqeram connection object + var connection = new SqreamConnection(connectionString); + + // open a connection + connection.Open(); + + // returns the connection object + return connection; + } + + /// + /// Executes a SQL command to sqream server + /// + /// connection to sqream server + /// sql command + /// thrown when the connection is not open + public void ExecuteSQLCommand(SqreamConnection connection, string sql) + { + // validates the connection is open and throws exception if not + if (connection.State != System.Data.ConnectionState.Open) + throw new InvalidOperationException(string.Format("connection to sqream is not open. connection.State: {0}", connection.State)); + + // creates a new command object utilizing the sql and the connection + var command = new SqreamCommand(sql, connection); + + // executes the command + command.ExecuteNonQuery(); + } + + /// + /// Executes a SQL command to sqream server, and reads the result set usiing DataReader + /// + /// connection to sqream server + /// sql command + /// thrown when the connection is not open + public List> ReadExampleData(SqreamConnection connection, string sql) + { + // validates the connection is open and throws exception if not + if (connection.State != System.Data.ConnectionState.Open) + throw new InvalidOperationException(string.Format("connection to sqream is not open. connection.State: {0}", connection.State)); + + // creates a new command object utilizing the sql and the connection + var command = new SqreamCommand(sql, connection); + + // creates a reader object to iterate over the result set + var reader = (SqreamDataReader)command.ExecuteReader(); + + // list of results + var result = new List>(); + + //iterate the reader and read the table int,string values into a result tuple object + while (reader.Read()) + result.Add(new Tuple(reader.GetInt32(0), reader.GetString(1))); + + // return the result set + return result; + } + diff --git a/connecting_to_sqream/client_drivers/nodejs/index.rst b/connecting_to_sqream/client_drivers/nodejs/index.rst new file mode 100644 index 000000000..8ddd0d0bc --- /dev/null +++ b/connecting_to_sqream/client_drivers/nodejs/index.rst @@ -0,0 +1,382 @@ +.. _nodejs: + +************************* +Node.JS +************************* + +The SQream DB Node.JS driver allows Javascript applications and tools connect to SQream DB. +This tutorial shows you how to write a Node application using the Node.JS interface. + +The driver requires Node 10 or newer. + +.. contents:: In this topic: + :local: + +Installing the Node.JS driver +================================== + +Prerequisites +---------------- + +* Node.JS 10 or newer. Follow instructions at `nodejs.org `_ . + +Install with NPM +------------------- + +Installing with npm is the easiest and most reliable method. +If you need to install the driver in an offline system, see the offline method below. + +.. code-block:: console + + $ npm install @sqream/sqreamdb + +Install from an offline package +------------------------------------- + +The Node driver is provided as a tarball for download from the `SQream Drivers page `_ . + +After downloading the tarball, use ``npm`` to install the offline package. + +.. code-block:: console + + $ sudo npm install sqreamdb-4.0.0.tgz + + +Connect to SQream DB with a Node.JS application +==================================================== + +Create a simple test +------------------------------------------ + +Replace the connection parameters with real parameters for a SQream DB installation. + +.. code-block:: javascript + :caption: sqreamdb-test.js + + const Connection = require('@sqream/sqreamdb'); + + const config = { + host: 'localhost', + port: 3109, + username: 'rhendricks', + password: 'super_secret_password', + connectDatabase: 'raviga', + cluster: true, + is_ssl: true, + service: 'sqream' + }; + + const query1 = 'SELECT 1 AS test, 2*6 AS "dozen"'; + + const sqream = new Connection(config); + sqream.execute(query1).then((data) => { + console.log(data); + }, (err) => { + console.error(err); + }); + + +Run the test +---------------- + +A successful run should look like this: + +.. code-block:: console + + $ node sqreamdb-test.js + [ { test: 1, dozen: 12 } ] + + +API reference +==================== + +Connection parameters +--------------------------- + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Item + - Optional + - Default + - Description + * - ``host`` + - ✗ + - None + - Hostname for SQream DB worker. For example, ``127.0.0.1``, ``sqream.mynetwork.co`` + * - ``port`` + - ✗ + - None + - Port for SQream DB end-point. For example, ``3108`` for the load balancer, ``5000`` for a worker. + * - ``username`` + - ✗ + - None + - Username of a role to use for connection. For example, ``rhendricks`` + * - ``password`` + - ✗ + - None + - Specifies the password of the selected role. For example, ``Tr0ub4dor&3`` + * - ``connectDatabase`` + - ✗ + - None + - Database name to connect to. For example, ``master`` + * - ``service`` + - ✓ + - ``sqream`` + - Specifices service queue to use. For example, ``etl`` + * - ``is_ssl`` + - ✓ + - ``false`` + - Specifies SSL for this connection. For example, ``true`` + * - ``cluster`` + - ✓ + - ``false`` + - Connect via load balancer (use only if exists, and check port). For example, ``true`` + +Events +------------- + +The connector handles event returns with an event emitter + +getConnectionId + The ``getConnectionId`` event returns the executing connection ID. + +getStatementId + The ``getStatementId`` event returns the executing statement ID. + +getTypes + The ``getTypes`` event returns the results columns types. + +Example +^^^^^^^^^^^^^^^^^ + +.. code-block:: javascript + + const myConnection = new Connection(config); + + myConnection.runQuery(query1, function (err, data){ + myConnection.events.on('getConnectionId', function(data){ + console.log('getConnectionId', data); + }); + + myConnection.events.on('getStatementId', function(data){ + console.log('getStatementId', data); + }); + + myConnection.events.on('getTypes', function(data){ + console.log('getTypes', data); + }); + }); + +Input placeholders +------------------------- + +The Node.JS driver can replace parameters in a statement. + +Input placeholders allow values like user input to be passed as parameters into queries, with proper escaping. + +The valid placeholder formats are provided in the table below. + +.. list-table:: + :widths: auto + :header-rows: 1 + + * - Placeholder + - Type + * - ``%i`` + - Identifier (e.g. table name, column name) + * - ``%s`` + - A text string + * - ``%d`` + - A number value + * - ``%b`` + - A boolean value + +See the :ref:`input placeholders example` below. + +Examples +=============== + +Setting configuration flags +----------------------------------- + +SQream DB configuration flags can be set per statement, as a parameter to ``runQuery``. + +For example: + +.. code-block:: javascript + + const setFlag = 'SET showfullexceptioninfo = true;'; + + const query_string = 'SELECT 1'; + + const myConnection = new Connection(config); + myConnection.runQuery(query_string, function (err, data){ + console.log(err, data); + }, setFlag); + + +Lazyloading +----------------------------------- + +To process rows without keeping them in memory, you can lazyload the rows with an async: + +.. code-block:: javascript + + + const Connection = require('@sqream/sqreamdb'); + + const config = { + host: 'localhost', + port: 3109, + username: 'rhendricks', + password: 'super_secret_password', + connectDatabase: 'raviga', + cluster: true, + is_ssl: true, + service: 'sqream' + }; + + const sqream = new Connection(config); + + const query = "SELECT * FROM public.a_very_large_table"; + + (async () => { + const cursor = await sqream.executeCursor(query); + let count = 0; + for await (let rows of cursor.fetchIterator(100)) { + // fetch rows in chunks of 100 + count += rows.length; + } + await cursor.close(); + return count; + })().then((total) => { + console.log('Total rows', total); + }, (err) => { + console.error(err); + }); + + +Reusing a connection +----------------------------------- + +It is possible to execeute multiple queries with the same connection (although only one query can be executed at a time). + +.. code-block:: javascript + + const Connection = require('@sqream/sqreamdb'); + + const config = { + host: 'localhost', + port: 3109, + username: 'rhendricks', + password: 'super_secret_password', + connectDatabase: 'raviga', + cluster: true, + is_ssl: true, + service: 'sqream' + }; + + const sqream = new Connection(config); + + (async () => { + + const conn = await sqream.connect(); + try { + const res1 = await conn.execute("SELECT 1"); + const res2 = await conn.execute("SELECT 2"); + const res3 = await conn.execute("SELECT 3"); + conn.disconnect(); + return {res1, res2, res3}; + } catch (err) { + conn.disconnect(); + throw err; + } + + })().then((res) => { + console.log('Results', res) + }, (err) => { + console.error(err); + }); + + +.. _input_placeholders_example: + +Using placeholders in queries +----------------------------------- + +Input placeholders allow values like user input to be passed as parameters into queries, with proper escaping. + +.. code-block:: javascript + + const Connection = require('@sqream/sqreamdb'); + + const config = { + host: 'localhost', + port: 3109, + username: 'rhendricks', + password: 'super_secret_password', + connectDatabase: 'raviga', + cluster: true, + is_ssl: true, + service: 'sqream' + }; + + const sqream = new Connection(config); + + const sql = "SELECT %i FROM public.%i WHERE name = %s AND num > %d AND active = %b"; + + sqream.execute(sql, "col1", "table2", "john's", 50, true); + + +The query that will run is ``SELECT col1 FROM public.table2 WHERE name = 'john''s' AND num > 50 AND active = true`` + + +Troubleshooting and recommended configuration +================================================ + + +Preventing ``heap out of memory`` errors +-------------------------------------------- + +Some workloads may cause Node.JS to fail with the error: + +.. code-block:: none + + FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory + +To prevent this error, modify the heap size configuration by setting the ``--max-old-space-size`` run flag. + +For example, set the space size to 2GB: + +.. code-block:: console + + $ node --max-old-space-size=2048 my-application.js + +BIGINT support +------------------------ + +The Node.JS connector supports fetching ``BIGINT`` values from SQream DB. However, some applications may encounter an error when trying to serialize those values. + +The error that appears is: +.. code-block:: none + + TypeError: Do not know how to serialize a BigInt + +This is because JSON specification do not support BIGINT values, even when supported by Javascript engines. + +To resolve this issue, objects with BIGINT values should be converted to string before serializing, and converted back after deserializing. + +For example: + +.. code-block:: javascript + + const rows = [{test: 1n}] + const json = JSON.stringify(rows, , (key, value) => + typeof value === 'bigint' + ? value.toString() + : value // return everything else unchanged + )); + console.log(json); // [{"test": "1"}] + diff --git a/connecting_to_sqream/client_drivers/nodejs/sample.js b/connecting_to_sqream/client_drivers/nodejs/sample.js new file mode 100644 index 000000000..cf3e19099 --- /dev/null +++ b/connecting_to_sqream/client_drivers/nodejs/sample.js @@ -0,0 +1,21 @@ +const Connection = require('@sqream/sqreamdb'); + +const config = { + host: 'localhost', + port: 3109, + username: 'rhendricks', + password: 'super_secret_password', + connectDatabase: 'raviga', + cluster: true, + is_ssl: true, + service: 'sqream' + }; + +const query1 = 'SELECT 1 AS test, 2*6 AS "dozen"'; + +const sqream = new Connection(config); +sqream.execute(query1).then((data) => { + console.log(data); +}, (err) => { + console.error(err); +}); \ No newline at end of file diff --git a/connecting_to_sqream/client_drivers/python/index.rst b/connecting_to_sqream/client_drivers/python/index.rst new file mode 100644 index 000000000..e03df343d --- /dev/null +++ b/connecting_to_sqream/client_drivers/python/index.rst @@ -0,0 +1,568 @@ +.. _pysqream: + +************************* +Python (pysqream) +************************* +The **Python** connector page describes the following: + +.. contents:: + :local: + :depth: 1 + +Overview +============= +The SQream Python connector is a set of packages that allows Python programs to connect to SQream DB. + +* ``pysqream`` is a pure Python connector. It can be installed with ``pip`` on any operating system, including Linux, Windows, and macOS. + +* ``pysqream-sqlalchemy`` is a SQLAlchemy dialect for ``pysqream`` + +The connector supports Python 3.6.5 and newer. The base ``pysqream`` package conforms to Python DB-API specifications `PEP-249 `_. + +Installing the Python Connector +================================== + +Prerequisites +---------------- +Installing the Python connector includes the following prerequisites: + +.. contents:: + :local: + :depth: 1 + +Python +^^^^^^^^^^^^ + +The connector requires Python 3.6.5 or newer. To verify your version of Python: + +.. code-block:: console + + $ python --version + Python 3.7.3 + + +.. note:: If both Python 2.x and 3.x are installed, you can run ``python3`` and ``pip3`` instead of ``python`` and ``pip`` respectively for the rest of this guide + +.. warning:: If you're running on an older version, ``pip`` will fetch an older version of ``pysqream``, with version <3.0.0. This version is currently not supported. + +PIP +^^^^^^^^^^^^ +The Python connector is installed via ``pip``, the Python package manager and installer. + +We recommend upgrading to the latest version of ``pip`` before installing. To verify that you are on the latest version, run the following command: + +.. code-block:: console + + $ python -m pip install --upgrade pip + Collecting pip + Downloading https://files.pythonhosted.org/packages/00/b6/9cfa56b4081ad13874b0c6f96af8ce16cfbc1cb06bedf8e9164ce5551ec1/pip-19.3.1-py2.py3-none-any.whl (1.4MB) + |████████████████████████████████| 1.4MB 1.6MB/s + Installing collected packages: pip + Found existing installation: pip 19.1.1 + Uninstalling pip-19.1.1: + Successfully uninstalled pip-19.1.1 + Successfully installed pip-19.3.1 + +.. note:: + * On macOS, you may want to use virtualenv to install Python and the connector, to ensure compatibility with the built-in Python environment + * If you encounter an error including ``SSLError`` or ``WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.`` - please be sure to reinstall Python with SSL enabled, or use virtualenv or Anaconda. + +OpenSSL for Linux +^^^^^^^^^^^^^^^^^^^^^^^^^^ +Some distributions of Python do not include OpenSSL. The Python connector relies on OpenSSL for secure connections to SQream DB. + +* To install OpenSSL on RHEL/CentOS + + .. code-block:: console + + $ sudo yum install -y libffi-devel openssl-devel + +* To install OpenSSL on Ubuntu + + .. code-block:: console + + $ sudo apt-get install libssl-dev libffi-dev -y + +Installing via PIP +----------------- +The Python connector is available via `PyPi `_. + +Install the connector with ``pip``: + +.. code-block:: console + + $ pip install pysqream pysqream-sqlalchemy + +``pip`` will automatically install all necessary libraries and modules. + +Upgrading an Existing Installation +-------------------------------------- +The Python drivers are updated periodically. To upgrade an existing pysqream installation, use pip's ``-U`` flag: + +.. code-block:: console + + $ pip install pysqream pysqream-sqlalchemy -U + +Validating Your Installation +----------------------------- +This section describes how to validate your installation. + +**To validate your installation**: + +1. Create a file called ``test.py``, containing the following: + +.. literalinclude:: test.py + :language: python + :caption: pysqream Validation Script + :linenos: + +2. Verify that the parameters in the connection have been replaced with your respective SQream installation parameters. + + :: + +3. Run the test file to verify that you can connect to SQream: + + .. code-block:: console + + $ python test.py + Version: v2020.1 + + If the validation was successful, you can build an application using the SQream Python connector. If you receive a connection error, verify the following: + + * You have access to a running SQream database. + + :: + + * The connection parameters are correct. + +SQLAlchemy Examples +======================== +SQLAlchemy is an **Object-Relational Mapper (ORM) for Python. When you install the SQream dialect (``pysqream-sqlalchemy``) you can use frameworks such as Pandas, TensorFlow, and Alembic to query SQream directly. + +This section includes the following examples: + +.. contents:: + :local: + :depth: 1 + +Standard Connection Example +--------------------------------- +The following is a standard connection example: + +.. code-block:: python + + import sqlalchemy as sa + from sqlalchemy.engine.url import URL + + engine_url = URL('sqream' + , username='rhendricks' + , password='secret_passwor" + , host='localhost' + , port=5000 + , database='raviga' + , query={'use_ssl': False}) + + engine = sa.create_engine(engine_url) + + res = engine.execute('create table test (ints int)') + res = engine.execute('insert into test values (5), (6)') + res = engine.execute('select * from test') + +Pulling a Table into Pandas +--------------------------------- +The following example shows how to pull a table in Pandas. This examples uses the URL method to create the connection string: + +.. code-block:: python + + import sqlalchemy as sa + import pandas as pd + from sqlalchemy.engine.url import URL + + + engine_url = URL('sqream' + , username='rhendricks' + , password='secret_passwor" + , host='localhost' + , port=5000 + , database='raviga' + , query={'use_ssl': False}) + + engine = sa.create_engine(engine_url) + + table_df = pd.read_sql("select * from nba", con=engine) + +API Examples +=============== +This section includes the following examples: + +.. contents:: + :local: + :depth: 1 + +Describing Your Connection +--------------------------------------- +This example shows how to describe the connection. + +**Describing your connection**: + +1. Import the package and create a connection: + + .. code-block:: python + + # Import pysqream package + + import pysqream + + """ + Connection parameters include: + * IP/Hostname + * Port + * database name + * username + * password + * Connect through load balancer, or direct to worker (Default: false - direct to worker) + * use SSL connection (default: false) + * Optional service queue (default: 'sqream') + """ + + # Create a connection object + + con = pysqream.connect(host='127.0.0.1', port=3108, database='raviga' + , username='rhendricks', password='Tr0ub4dor&3' + , clustered=True) + +2. Run a query and fetch the results: + + .. code-block:: python + + cur = con.cursor() # Create a new cursor + # Prepare and execute a query + cur.execute('select show_version()') + + result = cur.fetchall() # `fetchall` gets the entire data set + + print (f"Version: {result[0][0]}") + + The SQream version should be output, such as ``v2020.1``. + +3. Close the connection: + + .. code-block:: python + + con.close() + +Using the Cursor +-------------------------------------------- +The DB-API specification includes several methods for fetching results from the cursor. This sections shows an example using the ``nba`` table, which looks as follows: + +.. csv-table:: nba + :file: nba-t10.csv + :widths: auto + :header-rows: 1 + +As before, you must import the library and create a :py:meth:`~Connection`, followed by :py:meth:`~Connection.execute` on a simple ``SELECT *`` query: + +.. code-block:: python + + import pysqream + con = pysqream.connect(host='127.0.0.1', port=3108, database='master' + , username='rhendricks', password='Tr0ub4dor&3' + , clustered=True) + + cur = con.cursor() # Create a new cursor + # The select statement: + statement = 'SELECT * FROM nba' + cur.execute(statement) + +When the statement has finished executing, you have a :py:meth:`Connection` cursor object waiting. A cursor is iterable, meaning that it advances the cursor to the next row when fetched. + +You can use :py:meth:`~Connection.fetchone` to fetch one record at a time: + +.. code-block:: python + + first_row = cur.fetchone() # Fetch one row at a time (first row) + + second_row = cur.fetchone() # Fetch one row at a time (second row) + +To fetch several rows at a time, use :py:meth:`~Connection.fetchmany`: + +.. code-block:: python + + # executing `fetchone` twice is equivalent to this form: + third_and_fourth_rows = cur.fetchmany(2) + +To fetch all rows at once, use :py:meth:`~Connection.fetchall`: + +.. code-block:: python + + # To get all rows at once, use `fetchall` + remaining_rows = cur.fetchall() + + # Close the connection when done + con.close() + +The following is an example of the contents of the row variables used in our examples: + +.. code-block:: pycon + + >>> print(first_row) + ('Avery Bradley', 'Boston Celtics', 0, 'PG', 25, '6-2', 180, 'Texas', 7730337) + >>> print(second_row) + ('Jae Crowder', 'Boston Celtics', 99, 'SF', 25, '6-6', 235, 'Marquette', 6796117) + >>> print(third_and_fourth_rows) + [('John Holland', 'Boston Celtics', 30, 'SG', 27, '6-5', 205, 'Boston University', None), ('R.J. Hunter', 'Boston Celtics', 28, 'SG', 22, '6-5', 185, 'Georgia State', 1148640)] + >>> print(remaining_rows) + [('Jonas Jerebko', 'Boston Celtics', 8, 'PF', 29, '6-10', 231, None, 5000000), ('Amir Johnson', 'Boston Celtics', 90, 'PF', 29, '6-9', 240, None, 12000000), ('Jordan Mickey', 'Boston Celtics', 55, 'PF', 21, '6-8', 235, 'LSU', 1170960), ('Kelly Olynyk', 'Boston Celtics', 41, 'C', 25, '7-0', 238, 'Gonzaga', 2165160), + [...] + +.. note:: Calling a fetch command after all rows have been fetched will return an empty array (``[]``). + +Reading Result Metadata +---------------------------- +When you execute a statement, the connection object also contains metadata about the result set, such as **column names**, **types**, etc). + +The metadata is stored in the :py:attr:`Connection.description` object of the cursor: + +.. code-block:: pycon + + >>> import pysqream + >>> con = pysqream.connect(host='127.0.0.1', port=3108, database='master' + ... , username='rhendricks', password='Tr0ub4dor&3' + ... , clustered=True) + >>> cur = con.cursor() + >>> statement = 'SELECT * FROM nba' + >>> cur.execute(statement) + + >>> print(cur.description) + [('Name', 'STRING', 24, 24, None, None, True), ('Team', 'STRING', 22, 22, None, None, True), ('Number', 'NUMBER', 1, 1, None, None, True), ('Position', 'STRING', 2, 2, None, None, True), ('Age (as of 2018)', 'NUMBER', 1, 1, None, None, True), ('Height', 'STRING', 4, 4, None, None, True), ('Weight', 'NUMBER', 2, 2, None, None, True), ('College', 'STRING', 21, 21, None, None, True), ('Salary', 'NUMBER', 4, 4, None, None, True)] + +You can fetch a list of column names by iterating over the ``description`` list: + +.. code-block:: pycon + + >>> [ i[0] for i in cur.description ] + ['Name', 'Team', 'Number', 'Position', 'Age (as of 2018)', 'Height', 'Weight', 'College', 'Salary'] + +Loading Data into a Table +--------------------------- +This example shows how to load 10,000 rows of dummy data to an instance of SQream. + +**To load data 10,000 rows of dummy data to an instance of SQream:** + +1. Run the following: + + .. code-block:: python + + import pysqream + from datetime import date, datetime + from time import time + + con = pysqream.connect(host='127.0.0.1', port=3108, database='master' + , username='rhendricks', password='Tr0ub4dor&3' + , clustered=True) + +2. Create a table for loading: + + .. code-block:: python + + create = 'create or replace table perf (b bool, t tinyint, sm smallint, i int, bi bigint, f real, d double, s varchar(12), ss text, dt date, dtt datetime)' + con.execute(create) + +3. Load your data into table using the ``INSERT`` command. + + :: + +4. Create dummy data matching the table you created: + + .. code-block:: python + + data = (False, 2, 12, 145, 84124234, 3.141, -4.3, "Marty McFly" , u"キウイは楽しい鳥です" , date(2019, 12, 17), datetime(1955, 11, 4, 1, 23, 0, 0)) + + row_count = 10**4 + +5. Get a new cursor: + + .. code-block:: python + + cur = con.cursor() + insert = 'insert into perf values (?,?,?,?,?,?,?,?,?,?,?)' + start = time() + cur.executemany(insert, [data] * row_count) + print (f"Total insert time for {row_count} rows: {time() - start} seconds") + +6. Close this cursor: + + .. code-block:: python + + cur.close() + +7. Verify that the data was inserted correctly. + + :: + +8. Get a new cursor: + + .. code-block:: python + + cur = con.cursor() + cur.execute('select count(*) from perf') + result = cur.fetchall() # `fetchall` collects the entire data set + print (f"Count of inserted rows: {result[0][0]}") + +9. Close the cursor: + + .. code-block:: python + + cur.close() + +10. Close the connection: + + .. code-block:: python + + con.close() + +Reading Data from a CSV File for Loading into a Table +---------------------------------------------------------- +This example shows how to write a helper function to create an :ref:`insert` statement, by reading an existing table's metadata. + +**To read data from a CSV file for loading into a table:** + +1. Run the following: + + .. code-block:: python + + import pysqream + import datetime + + def insert_from_csv(cur, table_name, csv_filename, field_delimiter = ',', null_markers = []): + """ +2. Ask SQream for some table information. + + This is important for determining the number of columns, and helps create a matching ``INSERT`` statement: + + .. code-block:: python + + """ + + column_info = cur.execute(f"SELECT * FROM {table_name} LIMIT 0").description + + + def parse_datetime(v): + try: + return datetime.datetime.strptime(row[i], '%Y-%m-%d %H:%M:%S.%f') + except ValueError: + try: + return datetime.datetime.strptime(row[i], '%Y-%m-%d %H:%M:%S') + except ValueError: + return datetime.datetime.strptime(row[i], '%Y-%m-%d') + +3. Create enough placeholders (`?`) for the ``INSERT`` query string: + + + .. code-block:: python + + qstring = ','.join(['?'] * len(column_info)) + insert_statement = f"insert into {table_name} values ({qstring})" + +4. Open the CSV file: + + .. code-block:: python + + with open(csv_filename, mode='r') as csv_file: + csv_reader = csv.reader(csv_file, delimiter=field_delimiter) + +5. Execute the ``INSERT`` statement with the CSV data: + + .. code-block:: python + + cur.executemany(insert_statement, [row for row in csv_reader]) + + + con = pysqream.connect(host='127.0.0.1', port=3108, database='master' + , username='rhendricks', password='Tr0ub4dor&3' + , clustered=True) + + cur = con.cursor() + insert_from_csv(cur, 'nba', 'nba.csv', field_delimiter = ',', null_markers = []) + + con.close() + +Using SQLAlchemy ORM to Create and Populate Tables +----------------------------------------------------------------------- +This section shows how to use the ORM to create and populate tables from Python objects. + +**To use SQLAlchemy ORM to create and populate tables:** + +1. Run the following: + + .. code-block:: python + + import sqlalchemy as sa + import pandas as pd + from sqlalchemy.engine.url import URL + + + engine_url = URL('sqream' + , username='rhendricks' + , password='secret_passwor" + , host='localhost' + , port=5000 + , database='raviga' + , query={'use_ssl': False}) + + engine = sa.create_engine(engine_url) + +2. Build a metadata object and bind it: + + .. code-block:: python + + metadata = sa.MetaData() + metadata.bind = engine + +3. Create a table in the local metadata: + + .. code-block:: python + + employees = sa.Table( + 'employees' + , metadata + , sa.Column('id', sa.Integer) + , sa.Column('name', sa.VARCHAR(32)) + , sa.Column('lastname', sa.VARCHAR(32)) + , sa.Column('salary', sa.Float) + ) + + The ``create_all()`` function uses the SQream engine object. + +4. Create all the defined table objects: + + .. code-block:: python + + metadata.create_all(engine) + +5. Populate your table. + + :: + +6. Build the data rows: + + .. code-block:: python + + insert_data = [ {'id': 1, 'name': 'Richard','lastname': 'Hendricks', 'salary': 12000.75} + ,{'id': 3, 'name': 'Bertram', 'lastname': 'Gilfoyle', 'salary': 8400.0} + ,{'id': 8, 'name': 'Donald', 'lastname': 'Dunn', 'salary': 6500.40} + ] + +7. Build the ``INSERT`` command: + + .. code-block:: python + + ins = employees.insert(insert_data) + +8. Execute the command: + + .. code-block:: python + + result = engine.execute(ins) + +For more information, see the :ref:`python_api_reference_guide`. \ No newline at end of file diff --git a/connecting_to_sqream/client_drivers/python/nba-t10.csv b/connecting_to_sqream/client_drivers/python/nba-t10.csv new file mode 100644 index 000000000..024530355 --- /dev/null +++ b/connecting_to_sqream/client_drivers/python/nba-t10.csv @@ -0,0 +1,10 @@ +Name,Team,Number,Position,Age,Height,Weight,College,Salary +Avery Bradley,Boston Celtics,0.0,PG,25.0,6-2,180.0,Texas,7730337.0 +Jae Crowder,Boston Celtics,99.0,SF,25.0,6-6,235.0,Marquette,6796117.0 +John Holland,Boston Celtics,30.0,SG,27.0,6-5,205.0,Boston University, +R.J. Hunter,Boston Celtics,28.0,SG,22.0,6-5,185.0,Georgia State,1148640.0 +Jonas Jerebko,Boston Celtics,8.0,PF,29.0,6-10,231.0,,5000000.0 +Amir Johnson,Boston Celtics,90.0,PF,29.0,6-9,240.0,,12000000.0 +Jordan Mickey,Boston Celtics,55.0,PF,21.0,6-8,235.0,LSU,1170960.0 +Kelly Olynyk,Boston Celtics,41.0,C,25.0,7-0,238.0,Gonzaga,2165160.0 +Terry Rozier,Boston Celtics,12.0,PG,22.0,6-2,190.0,Louisville,1824360.0 diff --git a/connecting_to_sqream/client_drivers/python/test.py b/connecting_to_sqream/client_drivers/python/test.py new file mode 100644 index 000000000..d7de6305a --- /dev/null +++ b/connecting_to_sqream/client_drivers/python/test.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +import pysqream + +""" +Connection parameters include: +* IP/Hostname +* Port +* database name +* username +* password +* Connect through load balancer, or direct to worker (Default: false - direct to worker) +* use SSL connection (default: false) +* Optional service queue (default: 'sqream') +""" + +# Create a connection object + +con = pysqream.connect(host='127.0.0.1', port=5000, database='master' + , username='sqream', password='sqream' + , clustered=False) + +# Create a new cursor +cur = con.cursor() + +# Prepare and execute a query +cur.execute('select show_version()') + +result = cur.fetchall() # `fetchall` gets the entire data set + +print (f"Version: {result[0][0]}") + +# This should print the SQream DB version. For example ``Version: v2020.1``. + +# Finally, close the connection + +con.close() \ No newline at end of file From 4171e999fe83cffacac73f9dcda875aa9b6bdbb0 Mon Sep 17 00:00:00 2001 From: RosinTalia Date: Tue, 22 Nov 2022 16:52:50 +0200 Subject: [PATCH 279/316] CEIL + Python driver --- .../client_drivers/python/index.rst | 153 ++---------------- .../python/{test.py => sample.py} | 5 + .../scalar_functions/numeric/ceiling.rst | 5 +- 3 files changed, 23 insertions(+), 140 deletions(-) rename connecting_to_sqream/client_drivers/python/{test.py => sample.py} (96%) diff --git a/connecting_to_sqream/client_drivers/python/index.rst b/connecting_to_sqream/client_drivers/python/index.rst index e03df343d..7f8baac93 100644 --- a/connecting_to_sqream/client_drivers/python/index.rst +++ b/connecting_to_sqream/client_drivers/python/index.rst @@ -41,10 +41,6 @@ The connector requires Python 3.6.5 or newer. To verify your version of Python: Python 3.7.3 -.. note:: If both Python 2.x and 3.x are installed, you can run ``python3`` and ``pip3`` instead of ``python`` and ``pip`` respectively for the rest of this guide - -.. warning:: If you're running on an older version, ``pip`` will fetch an older version of ``pysqream``, with version <3.0.0. This version is currently not supported. - PIP ^^^^^^^^^^^^ The Python connector is installed via ``pip``, the Python package manager and installer. @@ -53,7 +49,7 @@ We recommend upgrading to the latest version of ``pip`` before installing. To ve .. code-block:: console - $ python -m pip install --upgrade pip + $ python3 -m pip install --upgrade pip Collecting pip Downloading https://files.pythonhosted.org/packages/00/b6/9cfa56b4081ad13874b0c6f96af8ce16cfbc1cb06bedf8e9164ce5551ec1/pip-19.3.1-py2.py3-none-any.whl (1.4MB) |████████████████████████████████| 1.4MB 1.6MB/s @@ -91,9 +87,9 @@ Install the connector with ``pip``: .. code-block:: console - $ pip install pysqream pysqream-sqlalchemy + $ pip3 install pysqream pysqream-sqlalchemy -``pip`` will automatically install all necessary libraries and modules. +``pip3`` will automatically install all necessary libraries and modules. Upgrading an Existing Installation -------------------------------------- @@ -101,7 +97,7 @@ The Python drivers are updated periodically. To upgrade an existing pysqream ins .. code-block:: console - $ pip install pysqream pysqream-sqlalchemy -U + $ pip3 install pysqream pysqream-sqlalchemy -U Validating Your Installation ----------------------------- @@ -109,9 +105,9 @@ This section describes how to validate your installation. **To validate your installation**: -1. Create a file called ``test.py``, containing the following: +1. Create a file called ``sample.py``, containing the following: -.. literalinclude:: test.py +.. literalinclude:: sample.py :language: python :caption: pysqream Validation Script :linenos: @@ -120,11 +116,11 @@ This section describes how to validate your installation. :: -3. Run the test file to verify that you can connect to SQream: +3. Run the sample file to verify that you can connect to SQream: .. code-block:: console - $ python test.py + $ python sample.py Version: v2020.1 If the validation was successful, you can build an application using the SQream Python connector. If you receive a connection error, verify the following: @@ -199,57 +195,6 @@ This section includes the following examples: :local: :depth: 1 -Describing Your Connection ---------------------------------------- -This example shows how to describe the connection. - -**Describing your connection**: - -1. Import the package and create a connection: - - .. code-block:: python - - # Import pysqream package - - import pysqream - - """ - Connection parameters include: - * IP/Hostname - * Port - * database name - * username - * password - * Connect through load balancer, or direct to worker (Default: false - direct to worker) - * use SSL connection (default: false) - * Optional service queue (default: 'sqream') - """ - - # Create a connection object - - con = pysqream.connect(host='127.0.0.1', port=3108, database='raviga' - , username='rhendricks', password='Tr0ub4dor&3' - , clustered=True) - -2. Run a query and fetch the results: - - .. code-block:: python - - cur = con.cursor() # Create a new cursor - # Prepare and execute a query - cur.execute('select show_version()') - - result = cur.fetchall() # `fetchall` gets the entire data set - - print (f"Version: {result[0][0]}") - - The SQream version should be output, such as ``v2020.1``. - -3. Close the connection: - - .. code-block:: python - - con.close() Using the Cursor -------------------------------------------- @@ -298,6 +243,9 @@ To fetch all rows at once, use :py:meth:`~Connection.fetchall`: # To get all rows at once, use `fetchall` remaining_rows = cur.fetchall() + cur.close() + + # Close the connection when done con.close() @@ -360,13 +308,13 @@ This example shows how to load 10,000 rows of dummy data to an instance of SQrea con = pysqream.connect(host='127.0.0.1', port=3108, database='master' , username='rhendricks', password='Tr0ub4dor&3' , clustered=True) - + , cur = con.cursor() 2. Create a table for loading: .. code-block:: python create = 'create or replace table perf (b bool, t tinyint, sm smallint, i int, bi bigint, f real, d double, s varchar(12), ss text, dt date, dtt datetime)' - con.execute(create) + cur.execute(create) 3. Load your data into table using the ``INSERT`` command. @@ -384,7 +332,6 @@ This example shows how to load 10,000 rows of dummy data to an instance of SQrea .. code-block:: python - cur = con.cursor() insert = 'insert into perf values (?,?,?,?,?,?,?,?,?,?,?)' start = time() cur.executemany(insert, [data] * row_count) @@ -396,11 +343,7 @@ This example shows how to load 10,000 rows of dummy data to an instance of SQrea cur.close() -7. Verify that the data was inserted correctly. - - :: - -8. Get a new cursor: +7. Verify that the data was inserted correctly: .. code-block:: python @@ -409,83 +352,19 @@ This example shows how to load 10,000 rows of dummy data to an instance of SQrea result = cur.fetchall() # `fetchall` collects the entire data set print (f"Count of inserted rows: {result[0][0]}") -9. Close the cursor: +8. Close the cursor: .. code-block:: python cur.close() -10. Close the connection: +9. Close the connection: .. code-block:: python con.close() -Reading Data from a CSV File for Loading into a Table ----------------------------------------------------------- -This example shows how to write a helper function to create an :ref:`insert` statement, by reading an existing table's metadata. - -**To read data from a CSV file for loading into a table:** - -1. Run the following: - .. code-block:: python - - import pysqream - import datetime - - def insert_from_csv(cur, table_name, csv_filename, field_delimiter = ',', null_markers = []): - """ -2. Ask SQream for some table information. - - This is important for determining the number of columns, and helps create a matching ``INSERT`` statement: - - .. code-block:: python - - """ - - column_info = cur.execute(f"SELECT * FROM {table_name} LIMIT 0").description - - - def parse_datetime(v): - try: - return datetime.datetime.strptime(row[i], '%Y-%m-%d %H:%M:%S.%f') - except ValueError: - try: - return datetime.datetime.strptime(row[i], '%Y-%m-%d %H:%M:%S') - except ValueError: - return datetime.datetime.strptime(row[i], '%Y-%m-%d') - -3. Create enough placeholders (`?`) for the ``INSERT`` query string: - - - .. code-block:: python - - qstring = ','.join(['?'] * len(column_info)) - insert_statement = f"insert into {table_name} values ({qstring})" - -4. Open the CSV file: - - .. code-block:: python - - with open(csv_filename, mode='r') as csv_file: - csv_reader = csv.reader(csv_file, delimiter=field_delimiter) - -5. Execute the ``INSERT`` statement with the CSV data: - - .. code-block:: python - - cur.executemany(insert_statement, [row for row in csv_reader]) - - - con = pysqream.connect(host='127.0.0.1', port=3108, database='master' - , username='rhendricks', password='Tr0ub4dor&3' - , clustered=True) - - cur = con.cursor() - insert_from_csv(cur, 'nba', 'nba.csv', field_delimiter = ',', null_markers = []) - - con.close() Using SQLAlchemy ORM to Create and Populate Tables ----------------------------------------------------------------------- diff --git a/connecting_to_sqream/client_drivers/python/test.py b/connecting_to_sqream/client_drivers/python/sample.py similarity index 96% rename from connecting_to_sqream/client_drivers/python/test.py rename to connecting_to_sqream/client_drivers/python/sample.py index d7de6305a..637c90c74 100644 --- a/connecting_to_sqream/client_drivers/python/test.py +++ b/connecting_to_sqream/client_drivers/python/sample.py @@ -32,6 +32,11 @@ # This should print the SQream DB version. For example ``Version: v2020.1``. +# Close cursor + +cur.close() + + # Finally, close the connection con.close() \ No newline at end of file diff --git a/reference/sql/sql_functions/scalar_functions/numeric/ceiling.rst b/reference/sql/sql_functions/scalar_functions/numeric/ceiling.rst index 2f4e2d988..39d150268 100644 --- a/reference/sql/sql_functions/scalar_functions/numeric/ceiling.rst +++ b/reference/sql/sql_functions/scalar_functions/numeric/ceiling.rst @@ -15,7 +15,7 @@ Syntax CEILING( expr ) - CEIL ( expr ) --> DOUBLE + CEIL ( expr ) Arguments ============ @@ -32,9 +32,8 @@ Arguments Returns ============ -* ``CEIL`` Always returns a floating point result. -* ``CEILING`` returns the same type as the argument supplied. +``CEILING`` returns the same type as the argument supplied. Notes ======= From d1b6b6e4489126cc562903ac20020ef595d811bf Mon Sep 17 00:00:00 2001 From: RosinTalia Date: Tue, 22 Nov 2022 16:56:02 +0200 Subject: [PATCH 280/316] Update index.rst --- connecting_to_sqream/client_drivers/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connecting_to_sqream/client_drivers/index.rst b/connecting_to_sqream/client_drivers/index.rst index 957fa3505..d46da0184 100644 --- a/connecting_to_sqream/client_drivers/index.rst +++ b/connecting_to_sqream/client_drivers/index.rst @@ -33,7 +33,7 @@ The following are applicable to all operating systems: * **Python** - Recommended installation via ``pip``: * `Python .tar file `_ - pysqream v3.1.3 (.tar.gz) - * `Python driver `_ + * `Python driver `_ .. _nodejs: From fb3df9618c78dbd496c65009138e886a4a9dfe13 Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Sun, 27 Nov 2022 16:40:41 +0200 Subject: [PATCH 281/316] New branding --- .../SQream_logo_without background-15.png | Bin 0 -> 128962 bytes conf.py | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 _static/images/SQream_logo_without background-15.png diff --git a/_static/images/SQream_logo_without background-15.png b/_static/images/SQream_logo_without background-15.png new file mode 100644 index 0000000000000000000000000000000000000000..1a4460581981aa00ed03e21f2691a33389cc4c39 GIT binary patch literal 128962 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

HW& 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 lN(g=(&k+CDXNc#hZ%glfyYYjE_|dNxE7yH_ Date: Tue, 29 Nov 2022 09:37:27 +0200 Subject: [PATCH 282/316] Update data_encryption_methods.rst --- feature_guides/data_encryption_methods.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/feature_guides/data_encryption_methods.rst b/feature_guides/data_encryption_methods.rst index 0e5638058..db789d02f 100644 --- a/feature_guides/data_encryption_methods.rst +++ b/feature_guides/data_encryption_methods.rst @@ -5,9 +5,6 @@ Encryption Methods *********************** Data exists in one of following states and determines the encryption method: -.. contents:: - :local: - :depth: 1 Encrypting Data in Transit ---------------- From a502ebce7534a0230cb0d6641ad140988a042149 Mon Sep 17 00:00:00 2001 From: RosinTalia Date: Tue, 29 Nov 2022 11:28:15 +0200 Subject: [PATCH 283/316] Update index.rst --- connecting_to_sqream/client_drivers/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connecting_to_sqream/client_drivers/index.rst b/connecting_to_sqream/client_drivers/index.rst index d46da0184..0790dec3d 100644 --- a/connecting_to_sqream/client_drivers/index.rst +++ b/connecting_to_sqream/client_drivers/index.rst @@ -1,7 +1,7 @@ .. _client_drivers: ************************************ -Client Drivers for 2022.1.6 +Client Drivers for 2022.1.5 ************************************ The guides on this page describe how to use the Sqream DB client drivers and client applications with SQream. @@ -25,7 +25,7 @@ The following are applicable to all operating systems: * **.NET**: * `.NET .dll file `_ - * `.NET driver `_ + * `.NET driver `_ .. _python: From 116a3f04781e75a768d11727e93147dd3ac2528e Mon Sep 17 00:00:00 2001 From: RosinTalia Date: Sun, 11 Dec 2022 14:31:55 +0200 Subject: [PATCH 284/316] Architecture --- _static/images/chunks_and_extents.png | Bin 75743 -> 70037 bytes _static/images/storage_organization.png | Bin 84955 -> 79471 bytes _static/images/table_columns_storage.png | Bin 46261 -> 54784 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/_static/images/chunks_and_extents.png b/_static/images/chunks_and_extents.png index bb092fab7dc403e87f92cc405d41f2ddf8150f67..8b3cc8d0523a62b8c4b841ecb92d8bce58c8f8d9 100644 GIT binary patch literal 70037 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

RSYQTD~ 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 literal 75743 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 F{{YiA!f^lq diff --git a/_static/images/storage_organization.png b/_static/images/storage_organization.png index 8cde6d70e90f6784b7e2c12b784edda47d4acf6e..d6a06d7635e20e31f31f136389bf242b7b47494a 100644 GIT binary patch literal 79471 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 O!<-%54l?b7&;JWR(f17i literal 84955 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 diff --git a/_static/images/table_columns_storage.png b/_static/images/table_columns_storage.png index 322538dac74c289c8fff79fae17a2ff9f0170899..071e140ea75048555667656b476d5a72daa6a721 100644 GIT binary patch literal 54784 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 NR#1CfAaC;ee*kz~kShQH literal 46261 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 Iz$Nm30F(WRBme*a From 407179e3f72b597e8376e0f01082fef71ddf31cb Mon Sep 17 00:00:00 2001 From: RosinTalia <talia@sqreamtech.com> Date: Sun, 11 Dec 2022 14:42:21 +0200 Subject: [PATCH 285/316] Update index.rst --- connecting_to_sqream/client_drivers/index.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/connecting_to_sqream/client_drivers/index.rst b/connecting_to_sqream/client_drivers/index.rst index 0790dec3d..cfb77eae2 100644 --- a/connecting_to_sqream/client_drivers/index.rst +++ b/connecting_to_sqream/client_drivers/index.rst @@ -1,8 +1,8 @@ .. _client_drivers: -************************************ -Client Drivers for 2022.1.5 -************************************ +************** +Client Drivers +************** The guides on this page describe how to use the Sqream DB client drivers and client applications with SQream. From 108b86c17481d98ea770e8a015e08e13e50f461e Mon Sep 17 00:00:00 2001 From: RosinTalia <117294941+TaliaSQream@users.noreply.github.com> Date: Tue, 10 Jan 2023 14:08:51 +0200 Subject: [PATCH 286/316] Comment --- configuration_guides/current_method_configuration_roles.rst | 2 +- configuration_guides/current_method_flag_types.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configuration_guides/current_method_configuration_roles.rst b/configuration_guides/current_method_configuration_roles.rst index 11b7e4bfb..b3afc2b46 100644 --- a/configuration_guides/current_method_configuration_roles.rst +++ b/configuration_guides/current_method_configuration_roles.rst @@ -5,7 +5,7 @@ Configuration Roles ************************** SQream divides flags into the following roles, each with their own set of permissions: -* :ref:`admin_flags` - can be modified by administrators on a session and cluster basis using the ``ALTER SYSTEM SET`` command: **Comment** - *I don't think we need to mention the command here, as it's described below, and also not mentioned for Generic Flags.* +* :ref:`admin_flags` - can be modified by administrators on a session and cluster basis using the ``ALTER SYSTEM SET`` command: * Regular * Worker diff --git a/configuration_guides/current_method_flag_types.rst b/configuration_guides/current_method_flag_types.rst index b1bedecba..7908e65d0 100644 --- a/configuration_guides/current_method_flag_types.rst +++ b/configuration_guides/current_method_flag_types.rst @@ -5,7 +5,7 @@ Flag Types ************************** SQream uses three flag types, **Cluster**, **Worker**, and **Regular**. Each of these flag types is associated with one of three hierarchical configuration levels described earlier, making it easier to configure your system. -The highest level in the hierarchy is Cluster, which lets you set configurations across all workers in a given cluster. Modifying cluster values is **persistent**, meaning that any configurations you set are retained after shutting down your system. Configurations set at the Cluster level take the highest priority and override settings made on the Regular and Worker level **Comment** - *Confirm*. This is known as **cluster-based configuration**. Note that Cluster-based configuration lets you modify Cluster *and* Regular flag types. An example of a Cluster flag is **persisting your cache directory.** +The highest level in the hierarchy is Cluster, which lets you set configurations across all workers in a given cluster. Modifying cluster values is **persistent**, meaning that any configurations you set are retained after shutting down your system. Configurations set at the Cluster level take the highest priority and override settings made on the Regular and Worker level. This is known as **cluster-based configuration**. Note that Cluster-based configuration lets you modify Cluster *and* Regular flag types. An example of a Cluster flag is **persisting your cache directory.** The second level is Worker, which lets you configure individual workers. Modifying Worker values are also **persistent**. This is known as **worker-based configuration**. Some examples of Worker flags includes **setting total device memory usage** and **setting metadata server connection port**. From 54f5330eb870b6e4898d0a9a3ac16394b52b24f6 Mon Sep 17 00:00:00 2001 From: RosinTalia <117294941+TaliaSQream@users.noreply.github.com> Date: Tue, 21 Feb 2023 10:05:59 +0200 Subject: [PATCH 287/316] Transactions --- feature_guides/index.rst | 1 - feature_guides/transactions.rst | 17 ----------------- reference/sql_feature_support.rst | 6 ++---- 3 files changed, 2 insertions(+), 22 deletions(-) delete mode 100644 feature_guides/transactions.rst diff --git a/feature_guides/index.rst b/feature_guides/index.rst index abb975c5d..4fe0652ce 100644 --- a/feature_guides/index.rst +++ b/feature_guides/index.rst @@ -17,6 +17,5 @@ This section describes the following features: compression python_functions workload_manager - transactions concurrency_and_locks concurrency_and_scaling_in_sqream \ No newline at end of file diff --git a/feature_guides/transactions.rst b/feature_guides/transactions.rst deleted file mode 100644 index 675957d51..000000000 --- a/feature_guides/transactions.rst +++ /dev/null @@ -1,17 +0,0 @@ -.. _transactions: - -*********************** -Transactions -*********************** - -SQream DB supports serializable transactions. This is also called 'ACID compliance'. - -The implementation of transactions means that commit, rollback and recovery are all extremely fast. - -SQream DB has extremely fast bulk insert speed, with minimal slowdown when running concurrent inserts. There is no performance reason to break large inserts up into multiple transactions. - -The phrase "supporting transactions" for a database system sometimes means having good performance for OLTP workloads, SQream DB's transaction system does not have high performance for high concurrency OLTP workloads. - -SQream DB also supports :ref:`transactional DDL<ddl_commands_list>`. - - diff --git a/reference/sql_feature_support.rst b/reference/sql_feature_support.rst index 4443d631a..d940215b0 100644 --- a/reference/sql_feature_support.rst +++ b/reference/sql_feature_support.rst @@ -64,10 +64,10 @@ Read more about :ref:`Yes data types<data_types>`. - Can be stored as a text string or as part of a ``DATETIME`` -Contraints +Constraints =============== -.. list-table:: Contraints +.. list-table:: Constraints :widths: auto :header-rows: 1 @@ -92,8 +92,6 @@ SQream DB treats each statement as an auto-commit transaction. Each transaction If a statement fails, the entire transaction is cancelled and rolled back. The database is unchanged. -Read more about :ref:`transactions in SQream DB<transactions>`. - Indexes ============ From b4a646af182a7a44a8dceef8dac51cf2b26c83c5 Mon Sep 17 00:00:00 2001 From: RosinTalia <117294941+TaliaSQream@users.noreply.github.com> Date: Thu, 2 Mar 2023 14:34:24 +0200 Subject: [PATCH 288/316] Update decode.rst --- .../scalar_functions/string/decode.rst | 59 ++++++++++++------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/reference/sql/sql_functions/scalar_functions/string/decode.rst b/reference/sql/sql_functions/scalar_functions/string/decode.rst index 1ed10e399..f2048e2b4 100644 --- a/reference/sql/sql_functions/scalar_functions/string/decode.rst +++ b/reference/sql/sql_functions/scalar_functions/string/decode.rst @@ -3,7 +3,7 @@ ******************** DECODE ******************** -The **DECODE** function is a PostgreSQL function used for decoding or extracting binary data from a textual input string. +The ``DECODE`` function takes an expression or column and compares it to a series of search values. It returns a result value that corresponds to the first matching search value, or the default value ``NULL`` if no matches are found. Syntax ========== @@ -11,7 +11,7 @@ The following shows the correct syntax for the DECODE function: .. code-block:: postgres - decode(string input_text, format type_text) + DECODE( <expr> , <search1> , <result1> [ , <search2> , <result2> ... ] [ , <default> ] ) Parameters ============ @@ -23,25 +23,40 @@ The following table shows the DECODE parameters: * - Parameter - Description - * - ``input_text`` - - Defines the input text string. - * - ``type_text`` - - Defines the format used for decoding the input text. - -Returns -========= -**Comment** - *What does it return?* - -Notes -=========== -**Comment** - *Are there any relevant notes?* - -Examples -=========== -**Comment** - *What does the actual output look like? Can you provide an example?* + * - ``expr`` + - The expression to be evaluated. + * - ``search`` + - A value that ``expr`` is compared against. + * - ``result1`` + - A value that is returnd if ``expr`` matches ``search``. + +Return +====== + +Returns the same type as the argument supplied. + +Example +======= + +.. code-block:: postgres + + CREATE TABLE test1 (european_size int not null); + INSERT INTO test1 values (8),(9),(10),(11); + + SELECT european_size,DECODE(european_size,8,40,9,41,10,42,99) from test1; + + Output: + +---------------+---------+ + |european_size |decode | + +-------------------------+ + |8 |40 | + +---------------+---------+ + |9 |41 | + +-------------------------+ + |10 |42 | + +-------------------------+ + |11 |99 | + +-------------------------+ -Permissions -============= -**Comment** - *Please confirm what permissions the role requires.* -The role must have the ``SUPERUSER`` permissions. \ No newline at end of file + From d534c0580b6e3409ad1651adc9606e2735714860 Mon Sep 17 00:00:00 2001 From: RosinTalia <117294941+TaliaSQream@users.noreply.github.com> Date: Tue, 7 Mar 2023 15:34:03 +0200 Subject: [PATCH 289/316] Update 2022.1.5.rst --- releases/2022.1.5.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/releases/2022.1.5.rst b/releases/2022.1.5.rst index d63bf3b7a..2c3149039 100644 --- a/releases/2022.1.5.rst +++ b/releases/2022.1.5.rst @@ -23,7 +23,10 @@ The 2022.1.5 Release Notes include the following new features: * release_defunct_locks utility function enhancement to receive new optional input parameter to specify timeout - for more details see `Lock Related Issues <../troubleshooting/lock_related_issues.html>`_. - +Storage Version +--------------- + +The storage version presently in effect is version 42. Known Issues From f6139405b8785bbceb65ebad6f87985b317d7e7f Mon Sep 17 00:00:00 2001 From: RosinTalia <117294941+TaliaSQream@users.noreply.github.com> Date: Tue, 7 Mar 2023 15:48:59 +0200 Subject: [PATCH 290/316] Storage --- releases/2022.1.1.rst | 42 ++++++++++++++++++++++++------------------ releases/2022.1.2.rst | 15 ++++++++++++--- releases/2022.1.3.rst | 12 ++++++++++++ releases/2022.1.4.rst | 5 +++++ releases/2022.1.rst | 11 +++++++++++ 5 files changed, 64 insertions(+), 21 deletions(-) diff --git a/releases/2022.1.1.rst b/releases/2022.1.1.rst index 436287c6c..3ba0cb8b6 100644 --- a/releases/2022.1.1.rst +++ b/releases/2022.1.1.rst @@ -13,7 +13,13 @@ Version Content ---------- The 2022.1.1 Release Notes describes the following: -* Enhanced security features. +* Enhanced security features +* For more information, see `SQream Acceleration Studio 5.4.7 <https://docs.sqream.com/en/v2022.1.1/sqream_studio_5.4.7/index.html>`_. + +Storage Version +--------------- + +The storage version presently in effect is version 40. New Features ---------- @@ -27,29 +33,25 @@ Password Security Compliance ************ In compliance with GDPR standards, SQream now requires a strong password policy when accessing the CLI or Studio. -For more information, see :ref:`access_control_password_policy`. +For more information, see `Password Policy <https://docs.sqream.com/en/v2022.1.1/operational_guides/access_control_password_policy.html>`_. Known Issues --------- -The following table lists the known issues for Version 2022.1.1: +There were no known issues in Version 2022.1.1. + +Resolved Issues +--------- +The following table lists the issues that were resolved in Version 2022.1.1: +-------------+------------------------------------------------------------------------------------------------+ | **SQ No.** | **Description** | +=============+================================================================================================+ | SQ-6419 | An internal compiler error occurred when casting Numeric literals in an aggregation function. | +-------------+------------------------------------------------------------------------------------------------+ - -Resolved Issues ---------- -The following table lists the issues that were resolved in Version 2022.1.1: - -+-------------+----------------------------------------------------------------------------------------+ -| **SQ No.** | **Description** | -+=============+========================================================================================+ -| SQ-10873 | Inserting 100K bytes into a text column resulted in an unclear error message. | -+-------------+----------------------------------------------------------------------------------------+ -| SQ-10892 | An unclear message was displayed when users ran ``UPDATE`` on foreign tables. | -+-------------+----------------------------------------------------------------------------------------+ +| SQ-10873 | Inserting 100K bytes into a text column resulted in an unclear error message. | ++-------------+------------------------------------------------------------------------------------------------+ +| SQ-10955 | Unneeded reads were occurring when filtering by date. | ++-------------+------------------------------------------------------------------------------------------------+ Operations and Configuration Changes -------- @@ -63,9 +65,7 @@ No relevant naming changes were made. Deprecated Features ------- -In SQream version 2022.1 the ``VARCHAR`` data type has been deprecated and replaced with ``TEXT``. SQream will maintain ``VARCHAR`` in all previous versions until completing the migration to ``TEXT``, at which point it will be deprecated in all earlier versions. SQream also provides an automated and secure tool to facilitate and simplify migration from ``VARCHAR`` to ``TEXT``. - -If you are using an earlier version of SQream, see the `Using Legacy String Literals <https://docs.sqream.com/en/v2022.1/configuration_guides/use_legacy_string_literals.html>`_ configuration flag. +In `SQream Acceleration Studio 5.4.7 <https://docs.sqream.com/en/v2022.1.1/sqream_studio_5.4.7/index.html>`_, the **Configuration** section has been temporarily disabled and will be enabled at a later date. In addition, the **Log Lines** tab in the **Log** section has been removed. End of Support ------- @@ -107,3 +107,9 @@ Upgrading to v2022.1.1 .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version <https://docs.sqream.com/en/v2022.1.1/installation_guides/installing_sqream_with_binary.html#upgrading-sqream-version>`_ procedure. +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2022.1.1 \ No newline at end of file diff --git a/releases/2022.1.2.rst b/releases/2022.1.2.rst index 5c007f0ec..cbefa3f00 100644 --- a/releases/2022.1.2.rst +++ b/releases/2022.1.2.rst @@ -19,6 +19,11 @@ The 2022.1.2 Release Notes describes the following: * Optimized queries on external Parquet tables. +Storage Version +--------------- + +The storage version presently in effect is version 41. + New Features ---------- The 2022.1.2 Release Notes include the following new features: @@ -53,9 +58,7 @@ No relevant naming changes were made. Deprecated Features ------- -In SQream version 2022.1 the ``VARCHAR`` data type has been deprecated and replaced with ``TEXT``. SQream will maintain ``VARCHAR`` in all previous versions until completing the migration to ``TEXT``, at which point it will be deprecated in all earlier versions. SQream also provides an automated and secure tool to facilitate and simplify migration from ``VARCHAR`` to ``TEXT``. - -If you are using an earlier version of SQream, see the `Using Legacy String Literals <https://docs.sqream.com/en/v2022.1/configuration_guides/use_legacy_string_literals.html>`_ configuration flag. +No features were deprecated for Version 2022.1.2. End of Support ------- @@ -97,3 +100,9 @@ Upgrading to v2022.1.2 .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version <https://docs.sqream.com/en/v2022.1.2/installation_guides/installing_sqream_with_binary.html#upgrading-sqream-version>`_ procedure. +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2022.1.2 \ No newline at end of file diff --git a/releases/2022.1.3.rst b/releases/2022.1.3.rst index b88eb78d9..e31c6728f 100644 --- a/releases/2022.1.3.rst +++ b/releases/2022.1.3.rst @@ -27,6 +27,12 @@ The 2022.1.3 Release Notes describes the following: * Support sub-queries in the UPDATE condition. +Storage Version +--------------- + +The storage version presently in effect is version 42. + + Known Issues --------- The following table lists the issues that are known limitations in Version 2022.1.3: @@ -120,3 +126,9 @@ Upgrading to v2022.1.3 .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version <../installation_guides/installing_sqream_with_binary.html#upgrading-sqream-version>`_ procedure. +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2022.1.3 \ No newline at end of file diff --git a/releases/2022.1.4.rst b/releases/2022.1.4.rst index 338fdf164..30a81b231 100644 --- a/releases/2022.1.4.rst +++ b/releases/2022.1.4.rst @@ -18,6 +18,11 @@ The 2022.1.4 Release Notes describes the following: :: +Storage Version +--------------- + +The storage version presently in effect is version 42. + Known Issues --------- No relevant Known Issues. diff --git a/releases/2022.1.rst b/releases/2022.1.rst index 6614d6458..be50ab11b 100644 --- a/releases/2022.1.rst +++ b/releases/2022.1.rst @@ -17,6 +17,11 @@ The 2022.1 Release Notes describes the following: * New data manipulation command. * Additional data ingestion format. +Storage Version +--------------- + +The storage version presently in effect is version 40. + New Features ---------- The 2022.1 Release Notes include the following new features: @@ -129,3 +134,9 @@ Upgrading to v2022.1 .. note:: Upgrading from a major version to another major version requires you to follow the **Upgrade Storage** step. This is described in Step 7 of the `Upgrading SQream Version <https://docs.sqream.com/en/v2022.1/installation_guides/installing_sqream_with_binary.html#upgrading-sqream-version>`_ procedure. +.. toctree:: + :maxdepth: 2 + :glob: + :hidden: + + 2022.1 From af38bcf35b9b5b08d0f8a242d91d36f6a75ce3f6 Mon Sep 17 00:00:00 2001 From: RosinTalia <117294941+TaliaSQream@users.noreply.github.com> Date: Tue, 14 Mar 2023 17:21:34 +0200 Subject: [PATCH 291/316] Update 2022.1.rst --- releases/2022.1.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/releases/2022.1.rst b/releases/2022.1.rst index be50ab11b..1343107ab 100644 --- a/releases/2022.1.rst +++ b/releases/2022.1.rst @@ -108,7 +108,7 @@ Upgrading to v2022.1 .. tip:: SQream recommends storing the generated back-up locally in case needed. - SQream runs the Garbage Collector and creates a clean backup tarball package. + SQream runs the Garbage Collector and creates a multi-file directory as specified in the ``out_path``. 2. Shut down all SQream services. From b2c99d9348f735912e01331afe46e078f069f502 Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Sun, 19 Mar 2023 09:59:34 +0200 Subject: [PATCH 292/316] Update 2022.1.5.rst --- releases/2022.1.5.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/releases/2022.1.5.rst b/releases/2022.1.5.rst index 2c3149039..290adc27b 100644 --- a/releases/2022.1.5.rst +++ b/releases/2022.1.5.rst @@ -55,6 +55,8 @@ The following table lists the issues that were resolved in Version 2022.1.5: +--------------+------------------------------------------------------------------------------------------+ | SQ-11905 | GetDate casting to as text returns DATE with 0s in the time part or no time part at all | +--------------+------------------------------------------------------------------------------------------+ +| SQ-12580 | Server Picker and Meta Data server may not be deployed on servers without GPU | ++--------------+------------------------------------------------------------------------------------------+ From a5f8090646aecf225232ab49ddf3ae0605ec8f52 Mon Sep 17 00:00:00 2001 From: RosinTalia <117294941+TaliaSQream@users.noreply.github.com> Date: Mon, 1 May 2023 09:43:50 +0300 Subject: [PATCH 293/316] Enabling High Bin Control Granularity --- configuration_guides/copy_to_restrict_utf8.rst | 4 ++-- configuration_guides/cpu_reduce_hashtable_size.rst | 11 ----------- 2 files changed, 2 insertions(+), 13 deletions(-) delete mode 100644 configuration_guides/cpu_reduce_hashtable_size.rst diff --git a/configuration_guides/copy_to_restrict_utf8.rst b/configuration_guides/copy_to_restrict_utf8.rst index 5d5990243..869de3bea 100644 --- a/configuration_guides/copy_to_restrict_utf8.rst +++ b/configuration_guides/copy_to_restrict_utf8.rst @@ -3,10 +3,10 @@ ************************* Enabling High Bin Control Granularity ************************* -The ``copyToRestrictUtf8`` flag sets sets the custom bin size in the cache to enable high bin control granularity. +The ``copyToRestrictUtf8`` flag sets the custom bin size in the cache to enable high bin control granularity. The following describes the ``copyToRestrictUtf8`` flag: * **Data type** - boolean * **Default value** - ``false`` -* **Allowed values** - ``true``, ``false`` \ No newline at end of file +* **Allowed values** - ``true``, ``false`` diff --git a/configuration_guides/cpu_reduce_hashtable_size.rst b/configuration_guides/cpu_reduce_hashtable_size.rst deleted file mode 100644 index c2b01604c..000000000 --- a/configuration_guides/cpu_reduce_hashtable_size.rst +++ /dev/null @@ -1,11 +0,0 @@ -.. _cpu_reduce_hashtable_size: - -************************* -Enabling High Bin Control Granularity -************************* -The ``copyToRestrictUtf8`` flag sets the custom bin size in the cache to enable high bin control granularity. - -The following describes the ``checkCudaMemory`` flag: - -* **Data type** - boolean -* **Default value** - ``FALSE`` \ No newline at end of file From e59426a157cb6a2ac383449a64b954efa0c8d971 Mon Sep 17 00:00:00 2001 From: RosinTalia <117294941+TaliaSQream@users.noreply.github.com> Date: Mon, 1 May 2023 10:06:42 +0300 Subject: [PATCH 294/316] Update trunc.rst --- .../sql_functions/scalar_functions/date_and_time/trunc.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reference/sql/sql_functions/scalar_functions/date_and_time/trunc.rst b/reference/sql/sql_functions/scalar_functions/date_and_time/trunc.rst index 1e888cfe5..e3511281f 100644 --- a/reference/sql/sql_functions/scalar_functions/date_and_time/trunc.rst +++ b/reference/sql/sql_functions/scalar_functions/date_and_time/trunc.rst @@ -1,7 +1,7 @@ .. _date_trunc: ************************** -TRUNC +Date and Time TRUNC ************************** Truncates a ``DATE`` or ``DATETIME`` value to a specified resolution. @@ -104,7 +104,7 @@ For these examples, consider the following table and contents: .. code-block:: postgres - CREATE TABLE cool_dates(name TEXT(40), d DATE, dt DATETIME); + CREATE TABLE cool_dates(name VARCHAR(40), d DATE, dt DATETIME); INSERT INTO cool_dates VALUES ('Marty McFly goes back to this time','1955-11-05','1955-11-05 01:21:00.000') , ('Marty McFly came from this time', '1985-10-26', '1985-10-26 01:22:00.000') From 100f0c30f991db031ec1582d8e066004245eca62 Mon Sep 17 00:00:00 2001 From: RosinTalia <117294941+TaliaSQream@users.noreply.github.com> Date: Thu, 4 May 2023 09:18:52 +0300 Subject: [PATCH 295/316] Update supported_data_types.rst --- data_type_guides/supported_data_types.rst | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/data_type_guides/supported_data_types.rst b/data_type_guides/supported_data_types.rst index afc735ad1..5889307ff 100644 --- a/data_type_guides/supported_data_types.rst +++ b/data_type_guides/supported_data_types.rst @@ -51,21 +51,16 @@ The following table shows the supported data types. - 8 bytes - ``0.000003`` - ``FLOAT``/``DOUBLE PRECISION`` - * - ``TEXT [(n)]`` + * - ``TEXT (n)`` - Variable length string - UTF-8 unicode - - Up to ``4*n`` bytes - - ``'キウイは楽しい鳥です'`` + - Up to ``4`` bytes + - ``'Kiwis have tiny wings, but cannot fly.'`` - ``CHAR VARYING``, ``CHAR``, ``CHARACTER VARYING``, ``CHARACTER``, ``NATIONAL CHARACTER VARYING``, ``NATIONAL CHARACTER``, ``NCHAR VARYING``, ``NCHAR`` * - ``NUMERIC`` - 38 digits - 16 bytes - ``0.123245678901234567890123456789012345678`` - ``DECIMAL`` - * - ``TEXT (n)`` - - Variable length string - ASCII only - - ``n`` bytes - - ``'Kiwis have tiny wings, but cannot fly.'`` - - ``SQL VARIANT`` * - ``DATE`` - Date - 4 bytes From 9ac007d382d89f3ad319c840a0639ddec66f4978 Mon Sep 17 00:00:00 2001 From: RosinTalia <117294941+TaliaSQream@users.noreply.github.com> Date: Mon, 15 May 2023 09:11:34 +0300 Subject: [PATCH 296/316] Update index.rst --- .../client_drivers/python/index.rst | 66 ++++++++++++++----- 1 file changed, 48 insertions(+), 18 deletions(-) diff --git a/connecting_to_sqream/client_drivers/python/index.rst b/connecting_to_sqream/client_drivers/python/index.rst index 7f8baac93..3e3879d2a 100644 --- a/connecting_to_sqream/client_drivers/python/index.rst +++ b/connecting_to_sqream/client_drivers/python/index.rst @@ -1,7 +1,7 @@ .. _pysqream: ************************* -Python (pysqream) +Connecting to SQream Using Python (pysqream) ************************* The **Python** connector page describes the following: @@ -143,29 +143,58 @@ This section includes the following examples: Standard Connection Example --------------------------------- -The following is a standard connection example: + .. code-block:: python - import sqlalchemy as sa - from sqlalchemy.engine.url import URL + import sqlalchemy as sa + from sqlalchemy.engine.url import URL - engine_url = URL('sqream' - , username='rhendricks' - , password='secret_passwor" - , host='localhost' - , port=5000 - , database='raviga' - , query={'use_ssl': False}) + engine_url = URL('sqream' + , username='rhendricks' + , password='secret_password" + , host='localhost' + , port=5000 + , database='raviga' + , query={'use_ssl': False}) - engine = sa.create_engine(engine_url) + engine = sa.create_engine(engine_url) + + res = engine.execute('create or replace table test (ints int, ints2 int)') + res = engine.execute('insert into test (ints,ints2) values (5,1), (6,2)') + res = engine.execute('select * from test') + for item in res: + print(item) + +Multi Cluster Connection Example +------------------------ + +The following example is for using a ServerPicker: + +.. code-block:: python + + import sqlalchemy as sa + from sqlalchemy.engine.url import URL + + + engine_url = URL('sqream' + , username='rhendricks' + , password='secret_password' + , host='localhost' + , port=5000 + , database='raviga') + + engine = sa.create_engine(engine_url,connect_args={"clustered": True}) + + res = engine.execute("create or replace table test100 (dor int);") + res = engine.execute('insert into test100 values (5), (6);') + res = engine.execute('select * from test100') + for item in res: + print(item) - res = engine.execute('create table test (ints int)') - res = engine.execute('insert into test values (5), (6)') - res = engine.execute('select * from test') Pulling a Table into Pandas ---------------------------------- +--------------------------- The following example shows how to pull a table in Pandas. This examples uses the URL method to create the connection string: .. code-block:: python @@ -177,7 +206,7 @@ The following example shows how to pull a table in Pandas. This examples uses th engine_url = URL('sqream' , username='rhendricks' - , password='secret_passwor" + , password='secret_password" , host='localhost' , port=5000 , database='raviga' @@ -309,6 +338,7 @@ This example shows how to load 10,000 rows of dummy data to an instance of SQrea , username='rhendricks', password='Tr0ub4dor&3' , clustered=True) , cur = con.cursor() + 2. Create a table for loading: .. code-block:: python @@ -383,7 +413,7 @@ This section shows how to use the ORM to create and populate tables from Python engine_url = URL('sqream' , username='rhendricks' - , password='secret_passwor" + , password='secret_password" , host='localhost' , port=5000 , database='raviga' From e175f84b147ed1dfea0605e4800f2f4633374b28 Mon Sep 17 00:00:00 2001 From: RosinTalia <117294941+TaliaSQream@users.noreply.github.com> Date: Tue, 18 Jul 2023 08:52:48 +0300 Subject: [PATCH 297/316] Update 404.rst --- 404.rst | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/404.rst b/404.rst index aa18f4738..44f92acfd 100644 --- a/404.rst +++ b/404.rst @@ -1,18 +1,14 @@ :orphan: -********************************* - Couldn't find the page - 404 -********************************* +************************** +Page Cannot Be Found - 404 +************************** -Unfortunately we could not find this page. - -Use the **search bar**, or use the navigation sidebar to find what you're looking for. - -.. rubric:: Looking for the old documentation? - -If you're looking for an older version of the documentation, versions 1.10 through 2019.2.1 are available at http://previous.sqream.com . +Use the **Search docs** bar, or use the navigation sidebar to find what you're looking for. .. rubric:: Need help? -If you couldn't find what you're looking for, we're always happy to help. Visit `SQream's support portal <https://support.sqream.com>`_ for additional support. +If you couldn't find what you're looking for, we're always happy to help. + +Visit the `SQreamDB support portal <https://sqream.atlassian.net/servicedesk/customer/portal/2/group/8/create/26>`_ for additional help. From 7bf2da55b1a87b91eaa85d00b8606c617abb8bf3 Mon Sep 17 00:00:00 2001 From: RosinTalia <117294941+TaliaSQream@users.noreply.github.com> Date: Mon, 24 Jul 2023 09:45:14 +0300 Subject: [PATCH 298/316] Update 2022.1.5.rst --- releases/2022.1.5.rst | 48 ++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/releases/2022.1.5.rst b/releases/2022.1.5.rst index 290adc27b..e6324e9cb 100644 --- a/releases/2022.1.5.rst +++ b/releases/2022.1.5.rst @@ -1,8 +1,9 @@ .. _2022.1.5: -************************** +********************** Release Notes 2022.1.5 -************************** +********************** + The 2022.1.5 release notes were released on 11/02/2022 and describe the following: .. contents:: @@ -10,18 +11,23 @@ The 2022.1.5 release notes were released on 11/02/2022 and describe the followin :depth: 1 New Features ----------- +------------ + The 2022.1.5 Release Notes include the following new features: -* keys_evaluate utility function enhancement - add problematic chunk ID to the function's output report. +* ``keys_evaluate`` utility function enhancement - add problematic chunk ID to the function's output report + + :: + +* Automatically close database client connections that have been open for 24 hours without any active statements :: -* Automatically close database client connections that have been open for 24 hours without any active statements. +* ``release_defunct_locks`` utility function enhancement to receive new optional input parameter to specify timeout - for more details see :ref:`Lock Related Issues <lock_related_issues>`. :: -* release_defunct_locks utility function enhancement to receive new optional input parameter to specify timeout - for more details see `Lock Related Issues <../troubleshooting/lock_related_issues.html>`_. +* Metadata scale up process improvement through RocksDB configuration improvements Storage Version --------------- @@ -30,12 +36,14 @@ The storage version presently in effect is version 42. Known Issues ---------- +------------ + Recently discovered issue with the encryption feature, at this time SQream recommends to avoid using this feature - a fix will be introduced in the near future. Resolved Issues ---------- +--------------- + The following table lists the issues that were resolved in Version 2022.1.5: +--------------+------------------------------------------------------------------------------------------+ @@ -57,21 +65,27 @@ The following table lists the issues that were resolved in Version 2022.1.5: +--------------+------------------------------------------------------------------------------------------+ | SQ-12580 | Server Picker and Meta Data server may not be deployed on servers without GPU | +--------------+------------------------------------------------------------------------------------------+ - - - +| SQ-12690 | Worker thread increase | ++--------------+------------------------------------------------------------------------------------------+ +| SQ-13775 | Worker down issue | ++--------------+------------------------------------------------------------------------------------------+ +| SQ-13947 | Non-Unicode character query execution error | ++--------------+------------------------------------------------------------------------------------------+ Operations and Configuration Changes --------- +------------------------------------ + No configuration changes were made. Naming Changes -------- +-------------- + No relevant naming changes were made. Deprecated Features -------- +------------------- + SQream is declaring end of support of VARCHAR data type, the decision resulted by SQream's effort to enhance its core functionalities and with respect to ever changing echo system requirements. VARCHAR is no longer supported for new customers - effective from Version 2022.1.3 (September 2022). @@ -80,11 +94,13 @@ TEXT data type is replacing VARCHAR - SQream will maintain VARCHAR data type sup End of Support -------- +-------------- + No End of Support changes were made. Upgrading to v2022.1.5 -------- +---------------------- + 1. Generate a back-up of the metadata by running the following command: .. code-block:: console From 04cc4075debb0b619131cde15226b30c2723d046 Mon Sep 17 00:00:00 2001 From: shaharf111 <112806728+shaharf111@users.noreply.github.com> Date: Tue, 25 Jul 2023 08:32:36 +0300 Subject: [PATCH 299/316] Update 2022.1.5.rst --- releases/2022.1.5.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/releases/2022.1.5.rst b/releases/2022.1.5.rst index e6324e9cb..d9113d6ad 100644 --- a/releases/2022.1.5.rst +++ b/releases/2022.1.5.rst @@ -65,11 +65,9 @@ The following table lists the issues that were resolved in Version 2022.1.5: +--------------+------------------------------------------------------------------------------------------+ | SQ-12580 | Server Picker and Meta Data server may not be deployed on servers without GPU | +--------------+------------------------------------------------------------------------------------------+ -| SQ-12690 | Worker thread increase | -+--------------+------------------------------------------------------------------------------------------+ | SQ-13775 | Worker down issue | +--------------+------------------------------------------------------------------------------------------+ -| SQ-13947 | Non-Unicode character query execution error | +| SQ-13947 | Non-UTF-8 character query execution error | +--------------+------------------------------------------------------------------------------------------+ From 5034eabf8647142678d8ba3c01c914cd4af7c14c Mon Sep 17 00:00:00 2001 From: RosinTalia <117294941+TaliaSQream@users.noreply.github.com> Date: Thu, 27 Jul 2023 08:03:25 +0300 Subject: [PATCH 300/316] Update char_length.rst --- .../scalar_functions/string/char_length.rst | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/reference/sql/sql_functions/scalar_functions/string/char_length.rst b/reference/sql/sql_functions/scalar_functions/string/char_length.rst index 47d517975..25e684c82 100644 --- a/reference/sql/sql_functions/scalar_functions/string/char_length.rst +++ b/reference/sql/sql_functions/scalar_functions/string/char_length.rst @@ -1,8 +1,8 @@ .. _char_length: -************************** -CHAR_LENGTH -************************** +****************************** +CHARACTER_LENGTH / CHAR_LENGTH +****************************** Calculates the number of characters in a string. @@ -11,14 +11,15 @@ Calculates the number of characters in a string. * To get the length in bytes, see :ref:`octet_length`. Syntax -========== +====== .. code-block:: postgres - CHAR_LEN( text_expr ) --> INT + CHAR_LENGTH( text_expr ) --> INT + CHARACTER_LENGTH( text_expr ) --> INT Arguments -============ +========= .. list-table:: :widths: auto @@ -30,19 +31,19 @@ Arguments - ``TEXT`` expression Returns -============ +======= -Returns an integer containing the number of characters in the string. +Return an integer containing the number of characters in the string. Notes -======= +===== * To get the length in bytes, see :ref:`octet_length` * If the value is NULL, the result is NULL. Examples -=========== +======== For these examples, consider the following table and contents: @@ -55,11 +56,11 @@ For these examples, consider the following table and contents: , ('אבגדהוזחטיכלמנסעפצקרשת'); Length in characters and bytes of strings --------------------------------------------------- +----------------------------------------- ASCII characters take up 1 byte per character, while Thai takes up 3 bytes and Hebrew takes up 2 bytes. -Unlike :ref:`len`, ``CHAR_LENGTH`` preserves the trailing whitespaces. +Unlike :ref:`len`, ``CHARACTER_LENGTH`` and ``CHAR_LENGTH`` preserve the trailing white spaces. .. code-block:: psql From 1d685c7c18d46ed97f349d3ade2c1fdf742fdeed Mon Sep 17 00:00:00 2001 From: RosinTalia <117294941+TaliaSQream@users.noreply.github.com> Date: Wed, 2 Aug 2023 14:35:35 +0300 Subject: [PATCH 301/316] Update index.rst --- index.rst | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/index.rst b/index.rst index c3d41c39c..a25419840 100644 --- a/index.rst +++ b/index.rst @@ -51,24 +51,12 @@ SQream DB is a columnar analytic SQL database management system. SQream DB suppo .. only:: html - .. tip:: - Want to read this offline? - `Download the documentation as a single PDF <https://docs.sqream.com/_/downloads/en/latest/pdf/>`_ . - -.. only:: pdf or latex - - .. tip:: This documentation is available online at https://docs.sqream.com/ - .. rubric:: Need help? If you couldn't find what you're looking for, we're always happy to help. Visit `SQream's support portal <https://sqream.atlassian.net/servicedesk/>`_ for additional support. -.. rubric:: Looking for older versions? - - -If you're looking for an older version of the documentation, go to http://previous.sqream.com . .. toctree:: :caption: Contents: From 38fcea8314e4841b719e5f1e981b8ad44ae54f1c Mon Sep 17 00:00:00 2001 From: RosinTalia <117294941+TaliaSQream@users.noreply.github.com> Date: Wed, 2 Aug 2023 14:50:20 +0300 Subject: [PATCH 302/316] Update sas_viya.rst --- .../client_platforms/sas_viya.rst | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/connecting_to_sqream/client_platforms/sas_viya.rst b/connecting_to_sqream/client_platforms/sas_viya.rst index ef4a338a4..2ddcab433 100644 --- a/connecting_to_sqream/client_platforms/sas_viya.rst +++ b/connecting_to_sqream/client_platforms/sas_viya.rst @@ -1,11 +1,12 @@ .. _connect_to_sas_viya: -************************* -Connect to SQream Using SAS Viya -************************* +******** +SAS Viya +******** Overview -========== +======== + SAS Viya is a cloud-enabled analytics engine used for producing useful insights. The **Connect to SQream Using SAS Viya** page describes how to connect to SAS Viya, and describes the following: .. contents:: @@ -14,6 +15,7 @@ SAS Viya is a cloud-enabled analytics engine used for producing useful insights. Installing SAS Viya ------------------- + The **Installing SAS Viya** section describes the following: .. contents:: @@ -21,13 +23,15 @@ The **Installing SAS Viya** section describes the following: :depth: 1 Downloading SAS Viya -~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~ + Integrating with SQream has been tested with SAS Viya v.03.05 and newer. To download SAS Viya, see `SAS Viya <https://www.sas.com/en_us/software/viya.html>`_. Installing the JDBC Driver -~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~ + The SQream JDBC driver is required for establishing a connection between SAS Viya and SQream. **To install the JDBC driver:** @@ -41,7 +45,8 @@ The SQream JDBC driver is required for establishing a connection between SAS Viy SQream recommends creating the directory ``/opt/sqream`` on the SAS Viya server. Configuring SAS Viya -------------------- +-------------------- + After installing the JDBC driver, you must configure the JDBC driver from the SAS Studio so that it can be used with SQream Studio. **To configure the JDBC driver from the SAS Studio:** @@ -62,7 +67,8 @@ After installing the JDBC driver, you must configure the JDBC driver from the SA For more information about writing a connection string, see **Connect to SQream DB with a JDBC Application** and navigate to `Connection String <https://docs.sqream.com/en/v2022.1/connecting_to_sqream/client_drivers/jdbc/index.html#connection-string-examples>`_. Operating SAS Viya --------------------- +------------------ + The **Operating SAS Viya** section describes the following: .. contents:: @@ -70,12 +76,13 @@ The **Operating SAS Viya** section describes the following: :depth: 1 Using SAS Viya Visual Analytics -~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + This section describes how to use SAS Viya Visual Analytics. **To use SAS Viya Visual Analytics:** -#. Log in to `SAS Viya Visual Analytics <http://192.168.4.63/SASLogon/login>`_ using your credentials: +#. Log in to SAS Viya Visual Analytics using your credentials: :: @@ -137,7 +144,8 @@ If your connection is not successful, see :ref:`troubleshooting_sas_viya` below. .. _troubleshooting_sas_viya: Troubleshooting SAS Viya -------------------------- +------------------------ + The **Best Practices and Troubleshooting** section describes the following best practices and troubleshooting procedures when connecting to SQream using SAS Viya: .. contents:: @@ -145,7 +153,8 @@ The **Best Practices and Troubleshooting** section describes the following best :depth: 1 Inserting Only Required Data -~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + When using SAS Viya, SQream recommends using only data that you need, as described below: * Insert only the data sources you need into SAS Viya, excluding tables that don’t require analysis. @@ -155,11 +164,13 @@ When using SAS Viya, SQream recommends using only data that you need, as describ * To increase query performance, add filters before analyzing. Every modification you make while analyzing data queries the SQream database, sometimes several times. Adding filters to the datasource before exploring limits the amount of data analyzed and increases query performance. Creating a Separate Service for SAS Viya -~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + SQream recommends creating a separate service for SAS Viya with the DWLM. This reduces the impact that Tableau has on other applications and processes, such as ETL. In addition, this works in conjunction with the load balancer to ensure good performance. Locating the SQream JDBC Driver -~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + In some cases, SAS Viya cannot locate the SQream JDBC driver, generating the following error message: .. code-block:: text @@ -178,8 +189,9 @@ In some cases, SAS Viya cannot locate the SQream JDBC driver, generating the fol 3. Restart SAS Viya. -For more troubleshooting assistance, see the `SQream Support Portal <https://sqream.atlassian.net/servicedesk/customer/portals>`_. +For more troubleshooting assistance, see the `SQream Support Portal <https://sqream.atlassian.net/servicedesk/>`_. Supporting TEXT -~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~ + In SAS Viya versions lower than 4.0, casting ``TEXT`` to ``CHAR`` changes the size to 1,024, such as when creating a table including a ``TEXT`` column. This is resolved by casting ``TEXT`` into ``CHAR`` when using the JDBC driver. \ No newline at end of file From 4d8862edec74dd1f9059e642a40abac9a4eaab12 Mon Sep 17 00:00:00 2001 From: RosinTalia <117294941+TaliaSQream@users.noreply.github.com> Date: Wed, 2 Aug 2023 15:05:33 +0300 Subject: [PATCH 303/316] Update microstrategy.rst --- .../client_platforms/microstrategy.rst | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/connecting_to_sqream/client_platforms/microstrategy.rst b/connecting_to_sqream/client_platforms/microstrategy.rst index 370312a0d..57afb861e 100644 --- a/connecting_to_sqream/client_platforms/microstrategy.rst +++ b/connecting_to_sqream/client_platforms/microstrategy.rst @@ -1,14 +1,15 @@ .. _microstrategy: -************************* -Connect to SQream Using MicroStrategy -************************* +************* +MicroStrategy +************* .. _ms_top: Overview ---------------- +-------- + This document is a Quick Start Guide that describes how to install MicroStrategy and connect a datasource to the MicroStrategy dasbhoard for analysis. @@ -20,12 +21,9 @@ The **Connecting to SQream Using MicroStrategy** page describes the following: :local: - - - - What is MicroStrategy? -================ +====================== + MicroStrategy is a Business Intelligence software offering a wide variety of data analytics capabilities. SQream uses the MicroStrategy connector for reading and loading data into SQream. MicroStrategy provides the following: @@ -48,7 +46,7 @@ For more information about Microstrategy, see `MicroStrategy <https://www.micros Connecting a Data Source -======================= +======================== 1. Activate the **MicroStrategy Desktop** app. The app displays the Dossiers panel to the right. @@ -125,7 +123,7 @@ Connecting a Data Source odbc:Driver={SqreamODBCDriver};DSN={SQreamDB ODBC};Server=<Host>;Port=<Port>;Database=<database name>;User=<username>;Password=<password>;Cluster=<boolean>; - For more information about the available **connection parameters** and other examples, see `Connection Parameters <https://docs.sqream.com/en/latest/guides/client_drivers/jdbc/index.html#connection-parameters>`_. + For more information about the available **connection parameters** and other examples, see `Connection Parameters <java_jdbc>`. 7. In the **User** and **Password** fields, fill out your user name and password. @@ -172,7 +170,7 @@ Your populated dashboard is displayed and is ready for data discovery and analyt :ref:`Back to Overview <ms_top>` Supported SQream Drivers -================ +======================== The following list shows the supported SQream drivers and versions: From 625fd694d34b76d684a1260b40b68b410981e8f3 Mon Sep 17 00:00:00 2001 From: RosinTalia <117294941+TaliaSQream@users.noreply.github.com> Date: Wed, 2 Aug 2023 15:08:17 +0300 Subject: [PATCH 304/316] Update microstrategy.rst --- connecting_to_sqream/client_platforms/microstrategy.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/connecting_to_sqream/client_platforms/microstrategy.rst b/connecting_to_sqream/client_platforms/microstrategy.rst index 57afb861e..f4869b468 100644 --- a/connecting_to_sqream/client_platforms/microstrategy.rst +++ b/connecting_to_sqream/client_platforms/microstrategy.rst @@ -123,7 +123,7 @@ Connecting a Data Source odbc:Driver={SqreamODBCDriver};DSN={SQreamDB ODBC};Server=<Host>;Port=<Port>;Database=<database name>;User=<username>;Password=<password>;Cluster=<boolean>; - For more information about the available **connection parameters** and other examples, see `Connection Parameters <java_jdbc>`. + For more information about the available **connection parameters** and other examples, see :ref:`Connection Parameters <java_jdbc>`. 7. In the **User** and **Password** fields, fill out your user name and password. @@ -132,6 +132,7 @@ Connecting a Data Source 8. In the **Data Source Name** field, type **SQreamDB**. :: + :: 9. Click **Save**. The SQreamDB that you picked in the Data Source panel is displayed. From 4fb39903de16d37e4ae835b1bafbff350b82d3af Mon Sep 17 00:00:00 2001 From: RosinTalia <117294941+TaliaSQream@users.noreply.github.com> Date: Wed, 2 Aug 2023 15:14:20 +0300 Subject: [PATCH 305/316] Update index.rst --- connecting_to_sqream/client_drivers/odbc/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connecting_to_sqream/client_drivers/odbc/index.rst b/connecting_to_sqream/client_drivers/odbc/index.rst index 3ee093692..3541d7911 100644 --- a/connecting_to_sqream/client_drivers/odbc/index.rst +++ b/connecting_to_sqream/client_drivers/odbc/index.rst @@ -44,7 +44,7 @@ Other distributions may also work, but are not officially supported by SQream. Downloading the ODBC driver ================================== -The SQream DB ODBC driver is distributed by your SQream account manager. Before contacting your account manager, verify which platform the ODBC driver will be used on. Go to `SQream Support <http://support.sqream.com/>`_ or contact your SQream account manager to get the driver. +The SQream DB ODBC driver is distributed by your SQream account manager. Before contacting your account manager, verify which platform the ODBC driver will be used on. Go to `SQream Support <https://sqream.atlassian.net/servicedesk/>`_ or contact your SQream account manager to get the driver. The driver is provided as an executable installer for Windows, or a compressed tarball for Linux platforms. After downloading the driver, follow the relevant instructions to install and configure the driver for your platform: From 68219bc297f4db77bb5822399a17cbbb7ee48962 Mon Sep 17 00:00:00 2001 From: TaliaSQream <117294941+TaliaSQream@users.noreply.github.com> Date: Tue, 15 Aug 2023 08:57:21 +0300 Subject: [PATCH 306/316] Add files via upload --- readthedocs.yaml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 readthedocs.yaml diff --git a/readthedocs.yaml b/readthedocs.yaml new file mode 100644 index 000000000..77b6f73c2 --- /dev/null +++ b/readthedocs.yaml @@ -0,0 +1,28 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the version of Python and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + # You can also specify other tool versions: + # nodejs: "19" + # rust: "1.64" + # golang: "1.19" + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: conf.py + +# If using Sphinx, optionally build your docs in additional formats such as PDF +formats: [htmlzip,pdf] + +# Optionally declare the Python requirements required to build your docs +python: + install: + - requirements: requirements.txt \ No newline at end of file From 634fa6b9ca5e87025d90ea8526e1dc9fd3ef0b35 Mon Sep 17 00:00:00 2001 From: TaliaSQream <117294941+TaliaSQream@users.noreply.github.com> Date: Tue, 15 Aug 2023 09:01:04 +0300 Subject: [PATCH 307/316] Update conf.py --- conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf.py b/conf.py index b880b11f2..eeeac558f 100644 --- a/conf.py +++ b/conf.py @@ -26,7 +26,7 @@ # The full version, including alpha/beta/rc tags -release = '2022.1.5' +release = '2022.1.4' From c0d670a6b75cfcba8a8ad48041b7f652b0cc5a75 Mon Sep 17 00:00:00 2001 From: TaliaSQream <117294941+TaliaSQream@users.noreply.github.com> Date: Tue, 15 Aug 2023 09:07:52 +0300 Subject: [PATCH 308/316] Update requirements.txt --- requirements.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 806fe2730..575f023b1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,10 @@ # File: docs/requirements.txt # Defining the exact version will make sure things don't break -sphinx==3.5.3 -sphinx_rtd_theme==0.5.2 +sphinx==5.3.0 +sphinx_rtd_theme==1.2.0 +urllib3<=2.0.0 +openssl-python>=0.1.1 sphinx-notfound-page Pygments>=2.4.0 +pdftex From efd7d31fe78c50ac77baafc992f72308e5b8383e Mon Sep 17 00:00:00 2001 From: TaliaSQream <117294941+TaliaSQream@users.noreply.github.com> Date: Tue, 15 Aug 2023 09:28:14 +0300 Subject: [PATCH 309/316] Update current_method_configuration_levels.rst --- configuration_guides/current_method_configuration_levels.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configuration_guides/current_method_configuration_levels.rst b/configuration_guides/current_method_configuration_levels.rst index 47ccf32b3..d32c8956f 100644 --- a/configuration_guides/current_method_configuration_levels.rst +++ b/configuration_guides/current_method_configuration_levels.rst @@ -19,7 +19,7 @@ Worker-Based Configuration -------------- Worker-based configuration lets you modify the configuration belong to individual workers from the worker configuration file. -For more information on making configurations from the worker configuration file, see `Modifying Your Configuration Using a Legacy Configuration File <https://docs.sqream.com/en/latest/configuration_guides/current_configuration_method.html#modifying-your-configuration-using-a-legacy-configuration-file>`_. +For more information on making configurations from the worker configuration file, see `Modifying Your Configuration Using a Legacy Configuration File <https://docs.sqream.com/en/2022.1.5/configuration_guides/current_method_modification_methods.html>`_. Session-Based Configuration -------------- @@ -30,4 +30,4 @@ For example, when the query below has completed executing, the values configured .. code-block:: console set spoolMemoryGB=700; - select * from table a where date='2021-11-11' \ No newline at end of file + select * from table a where date='2021-11-11' From 39cab10f06d8717ddd044b194f69238925c16c67 Mon Sep 17 00:00:00 2001 From: TaliaSQream <117294941+TaliaSQream@users.noreply.github.com> Date: Tue, 15 Aug 2023 09:28:52 +0300 Subject: [PATCH 310/316] Update conf.py --- conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf.py b/conf.py index eeeac558f..b880b11f2 100644 --- a/conf.py +++ b/conf.py @@ -26,7 +26,7 @@ # The full version, including alpha/beta/rc tags -release = '2022.1.4' +release = '2022.1.5' From d9957423c2f049156d2f63785d3bfe12cb920469 Mon Sep 17 00:00:00 2001 From: TaliaSQream <117294941+TaliaSQream@users.noreply.github.com> Date: Tue, 15 Aug 2023 10:08:43 +0300 Subject: [PATCH 311/316] Update spooling.rst --- configuration_guides/spooling.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configuration_guides/spooling.rst b/configuration_guides/spooling.rst index 45c88d3ee..6b7fbfb3d 100644 --- a/configuration_guides/spooling.rst +++ b/configuration_guides/spooling.rst @@ -66,4 +66,4 @@ The following is an example of setting ``spoolMemoryGB`` value in the previous c For more information about configuring the ``spoolMemoryGB`` flag, see the following: * `Current configuration method <https://docs.sqream.com/en/latest/configuration_guides/spool_memory_gb.html>`_ -* `Previous configuration method <https://docs.sqream.com/en/latest/configuration_guides/previous_configuration_method.html#id2>`_ \ No newline at end of file +* `Previous configuration method <https://docs.sqream.com/en/2022.1.5/configuration_guides/previous_configuration_method.html>`_ From 5abebda166fa521dac3ddc1675daa31d041c5289 Mon Sep 17 00:00:00 2001 From: TaliaSQream <117294941+TaliaSQream@users.noreply.github.com> Date: Tue, 15 Aug 2023 10:48:45 +0300 Subject: [PATCH 312/316] Update executing_statements_and_running_queries_from_the_editor.rst --- ...executing_statements_and_running_queries_from_the_editor.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/sqream_studio_5.4.7/executing_statements_and_running_queries_from_the_editor.rst b/sqream_studio_5.4.7/executing_statements_and_running_queries_from_the_editor.rst index 882b226e0..d037a357e 100644 --- a/sqream_studio_5.4.7/executing_statements_and_running_queries_from_the_editor.rst +++ b/sqream_studio_5.4.7/executing_statements_and_running_queries_from_the_editor.rst @@ -274,8 +274,6 @@ You can add and name new tabs for each statement that you need to execute, and S You can also rename the default tab name by double-clicking it and typing a new name and write multiple statements in tandem in the same tab by separating them with semicolons (``;``).If too many tabs to fit into the Statement Pane are open at the same time, the tab arrows are displayed. You can scroll through the tabs by clicking |icon-left| or |icon-right|, and close tabs by clicking |icon-close|. You can also close all tabs at once by clicking **Close all** located to the right of the tabs. -.. tip:: If this is your first time using SQream, see `Getting Started <https://docs.sqream.com/en/latest/first_steps.html#first-steps>`_. - .. Keyboard shortcuts .. ^^^^^^^^^^^^^^^^^^^^^^^^^ From a9a6a6cb7a8e21f2d24e2472c81f7587ff5eb692 Mon Sep 17 00:00:00 2001 From: RosinTalia <117294941+TaliaSQream@users.noreply.github.com> Date: Wed, 16 Aug 2023 08:52:30 +0300 Subject: [PATCH 313/316] Update executing_statements_and_running_queries_from_the_editor.rst --- ...ts_and_running_queries_from_the_editor.rst | 60 ++++++++++++------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/sqream_studio_5.4.7/executing_statements_and_running_queries_from_the_editor.rst b/sqream_studio_5.4.7/executing_statements_and_running_queries_from_the_editor.rst index d037a357e..76baf51c2 100644 --- a/sqream_studio_5.4.7/executing_statements_and_running_queries_from_the_editor.rst +++ b/sqream_studio_5.4.7/executing_statements_and_running_queries_from_the_editor.rst @@ -2,9 +2,10 @@ .. _editor_top_5.4.7: -**************************** +******************************************************** Executing Statements and Running Queries from the Editor -**************************** +******************************************************** + The **Editor** is used for the following: * Selecting an active database and executing queries. @@ -42,7 +43,8 @@ The following is a brief description of the Editor panels: .. _studio_5.4.7_editor_toolbar: Executing Statements from the Toolbar -================ +===================================== + You can access the following from the Toolbar pane: * **Database dropdown list** - select a database that you want to run statements on. @@ -82,7 +84,8 @@ For more information on stopping active statements, see the :ref:`STOP_STATEMENT .. _studio_5.4.7_editor_db_tree: Performing Statement-Related Operations from the Database Tree -================ +============================================================== + From the Database Tree you can perform statement-related operations and show metadata (such as a number indicating the amount of rows in the table). @@ -197,8 +200,6 @@ The database object functions are used to perform the following: - Generates an `RENAME TABLE AS <https://docs.sqream.com/en/latest/reference/sql/sql_statements/ddl_commands/rename_table.html#rename-table>`_ statement for renaming the selected table in the editing area. * - Adding column statement - Generates an `ADD COLUMN <https://docs.sqream.com/en/latest/reference/sql/sql_statements/ddl_commands/add_column.html#add-column>`_ statement for adding columns to the selected table in the editing area. - * - Truncate table statement - - Generates a `TRUNCATE_IF_EXISTS <https://docs.sqream.com/en/latest/reference/sql/sql_statements/dml_commands/truncate_if_exists.html#truncate>`_ statement for the selected table in the editing area. * - Drop table statement - Generates a ``DROP`` statement for the selected object in the editing area. * - Table DDL @@ -207,8 +208,9 @@ The database object functions are used to perform the following: - The `DDL Optimizer <https://docs.sqream.com/en/latest/sqream_studio_5.4.7/executing_statements_and_running_queries_from_the_editor.html#optimizing-database-tables-using-the-ddl-optimizer>`_ lets you analyze database tables and recommends possible optimizations. Optimizing Database Tables Using the DDL Optimizer ------------------------ -The **DDL Optimizer** tab analyzes database tables and recommends possible optimizations according to SQream's best practices. +-------------------------------------------------- + +The **DDL Optimizer** tab analyzes database tables and recommends possible optimizations according to SQreamDB's best practices. As described in the previous table, you can access the DDL Optimizer by clicking the **additional options icon** and selecting **DDL Optimizer**. @@ -232,21 +234,23 @@ Clicking **Run Optimizer** adds a tab to the Statement panel showing the optimiz For more information, see `Optimization and Best Practices <https://docs.sqream.com/en/latest/operational_guides/optimization_best_practices.html>`_. Executing Pre-Defined Queries from the System Queries Panel ---------------- +----------------------------------------------------------- + The **System Queries** panel lets you execute predefined queries and includes the following system query types: * **Catalog queries** - Used for analyzing table compression rates, users and permissions, etc. :: -* **Admin queries** - Queries useful for SQream database management. +* **Admin queries** - Queries useful for SQreamDB database management. Clicking an item pastes the query into the Statement pane, and you can undo a previous operation by pressing **Ctrl + Z**. .. _studio_5.4.7_editor_statement_area: Writing Statements and Queries from the Statement Panel -============== +======================================================= + The multi-tabbed statement area is used for writing queries and statements, and is used in tandem with the toolbar. When writing and executing statements, you must first select a database from the **Database** dropdown menu in the toolbar. When you execute a statement, it passes through a series of statuses until completed. Knowing the status helps you with statement maintenance, and the statuses are shown in the **Results panel**. The auto-complete feature assists you when writing statements by suggesting statement options. @@ -274,9 +278,11 @@ You can add and name new tabs for each statement that you need to execute, and S You can also rename the default tab name by double-clicking it and typing a new name and write multiple statements in tandem in the same tab by separating them with semicolons (``;``).If too many tabs to fit into the Statement Pane are open at the same time, the tab arrows are displayed. You can scroll through the tabs by clicking |icon-left| or |icon-right|, and close tabs by clicking |icon-close|. You can also close all tabs at once by clicking **Close all** located to the right of the tabs. +.. tip:: If this is your first time using SQreamDB, see :ref:`Getting Started <getting_started>`. + .. Keyboard shortcuts -.. ^^^^^^^^^^^^^^^^^^^^^^^^^ +.. ^^^^^^^^^^^^^^^^^^ .. :kbd:`Ctrl` +: kbd:`Enter` - Execute all queries in the statement area, or just the highlighted part of the query. @@ -295,7 +301,8 @@ You can also rename the default tab name by double-clicking it and typing a new .. _results_panel_5.4.7: Viewing Statement and Query Results from the Results Panel -============== +========================================================== + The results panel shows statement and query results. By default, only the first 10,000 results are returned, although you can modify this from the :ref:`studio_editor_toolbar`, as described above. By default, executing several statements together opens a separate results tab for each statement. Executing statements together executes them serially, and any failed statement cancels all subsequent executions. .. image:: /_static/images/results_panel.png @@ -321,7 +328,8 @@ The following is a brief description of the Results panel views highlighted in t :ref:`Back to Executing Statements and Running Queries from the Editor<editor_top_5.4.7>` Searching Query Results in the Results View ----------------- +------------------------------------------- + The **Results view** lets you view search query results. From this view you can also do the following: @@ -333,13 +341,15 @@ From this view you can also do the following: * Sort column results. Saving Results to the Clipboard -^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + The **Save results to clipboard** function lets you save your results to the clipboard to paste into another text editor or into Excel for further analysis. .. _save_results_to_local_file_5.4.7: Saving Results to a Local File -^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + The **Save results to local file** functions lets you save your search query results to a local file. Clicking **Save results to local file** downloads the contents of the Results panel to an Excel sheet. You can then use copy and paste this content into other editors as needed. In the Results view you can also run parallel statements, as described in **Running Parallel Statements** below. @@ -347,7 +357,8 @@ In the Results view you can also run parallel statements, as described in **Runn .. _running_parallel_statements_5.4.7: Running Parallel Statements -^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + While Studio's default functionality is to open a new tab for each executed statement, Studio supports running parallel statements in one statement tab. Running parallel statements requires using macros and is useful for advanced users. The following shows the syntax for running parallel statements: @@ -369,7 +380,8 @@ The following shows the syntax for running parallel statements: .. _execution_tree_5.4.7: Execution Details View --------------- +---------------------- + The **Execution Details View** section describes the following: .. contents:: @@ -377,7 +389,8 @@ The **Execution Details View** section describes the following: :depth: 1 Overview -^^^^^^^^^^^^ +^^^^^^^^ + Clicking **Execution Details View** displays the **Execution Tree**, which is a chronological tree of processes that occurred to execute your queries. The purpose of the Execution Tree is to analyze all aspects of your query for troubleshooting and optimization purposes, such as resolving queries with an exceptionally long runtime. .. note:: The **Execution Details View** button is enabled only when a query takes longer than five seconds. @@ -413,7 +426,8 @@ Each node displays a number displaying its **node ID**, its **type**, **table na .. image:: /_static/images/nodes.png Viewing Query Statistics -^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^^ + The following statistical information is displayed in the top left corner, as shown in the figure above: * **Query Statistics**: @@ -458,7 +472,8 @@ Note that you can scroll the Node Statistics table. You can also download the ex :align: middle Using the Plain View -^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^ + You can use the **Plain View** instead of viewing the execution tree by clicking **Plain View** |icon-plain| in the top right corner. The plain view displays the same information as shown in the execution tree in table format. .. |icon-plain| image:: /_static/images/studio_icon_plain.png @@ -480,7 +495,8 @@ This can be seen in the **timeSum** column as follows: .. _sql_view_5.4.7: Viewing Wrapped Strings in the SQL View ------------------- +--------------------------------------- + The SQL View panel allows you to more easily view certain queries, such as a long string that appears on one line. The SQL View makes it easier to see by wrapping it so that you can see the entire string at once. It also reformats and organizes query syntax entered in the Statement panel for more easily locating particular segments of your queries. The SQL View is identical to the **Format SQL** feature in the Toolbar, allowing you to retain your originally constructed query while viewing a more intuitively structured snapshot of it. .. _save_results_to_clipboard_5.4.7: From d47d05b69dcab234ed02f24705d706792b369569 Mon Sep 17 00:00:00 2001 From: RosinTalia <117294941+TaliaSQream@users.noreply.github.com> Date: Wed, 16 Aug 2023 08:56:57 +0300 Subject: [PATCH 314/316] Update executing_statements_and_running_queries_from_the_editor.rst --- ...xecuting_statements_and_running_queries_from_the_editor.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sqream_studio_5.4.7/executing_statements_and_running_queries_from_the_editor.rst b/sqream_studio_5.4.7/executing_statements_and_running_queries_from_the_editor.rst index 76baf51c2..cf85bf811 100644 --- a/sqream_studio_5.4.7/executing_statements_and_running_queries_from_the_editor.rst +++ b/sqream_studio_5.4.7/executing_statements_and_running_queries_from_the_editor.rst @@ -278,9 +278,8 @@ You can add and name new tabs for each statement that you need to execute, and S You can also rename the default tab name by double-clicking it and typing a new name and write multiple statements in tandem in the same tab by separating them with semicolons (``;``).If too many tabs to fit into the Statement Pane are open at the same time, the tab arrows are displayed. You can scroll through the tabs by clicking |icon-left| or |icon-right|, and close tabs by clicking |icon-close|. You can also close all tabs at once by clicking **Close all** located to the right of the tabs. -.. tip:: If this is your first time using SQreamDB, see :ref:`Getting Started <getting_started>`. - + .. Keyboard shortcuts .. ^^^^^^^^^^^^^^^^^^ From b4a6aefde18f4144be7fd2998397c255a5199c10 Mon Sep 17 00:00:00 2001 From: TaliaSQream <117294941+TaliaSQream@users.noreply.github.com> Date: Sun, 27 Aug 2023 13:58:07 +0300 Subject: [PATCH 315/316] Update 2022.1.rst --- releases/2022.1.rst | 49 ++++++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/releases/2022.1.rst b/releases/2022.1.rst index 1343107ab..fb06ffa8d 100644 --- a/releases/2022.1.rst +++ b/releases/2022.1.rst @@ -3,6 +3,7 @@ ************************** Release Notes 2022.1 ************************** + The 2022.1 release notes were released on 7/19/2022 and describe the following: .. contents:: @@ -10,8 +11,9 @@ The 2022.1 release notes were released on 7/19/2022 and describe the following: :depth: 1 Version Content ----------- -The 2022.1 Release Notes describes the following: +---------------- + +The 2022.1 Release Notes describe the following: * Enhanced security features. * New data manipulation command. @@ -23,7 +25,8 @@ Storage Version The storage version presently in effect is version 40. New Features ----------- +------------- + The 2022.1 Release Notes include the following new features: .. contents:: @@ -31,7 +34,8 @@ The 2022.1 Release Notes include the following new features: :depth: 1 Data Encryption -************ +***************** + SQream now supports data encryption mechanisms in accordance with **General Data Protection Regulation (GDPR)** standards. Using the data encryption feature may lead to a maximum of a 10% increase in performance degradation. @@ -39,19 +43,22 @@ Using the data encryption feature may lead to a maximum of a 10% increase in per For more information, see `Data Encryption <https://docs.sqream.com/en/v2022.1/feature_guides/data_encryption.html>`_. Update Feature -************ +**************** + SQream now supports the DML **Update** feature, which is used for modifying the value of certain columns in existing rows. For more information, see `UPDATE <https://docs.sqream.com/en/v2022.1/reference/sql/sql_statements/dml_commands/update.html#update>`_. Avro Ingestion -************ +*************** + SQream now supports ingesting data from Avro files. For more information, see `Inserting Data from Avro <https://docs.sqream.com/en/v2022.1/data_ingestion/avro.html>`_. Known Issues ---------- +------------- + The following table lists the known issues for Version 2022.1: +-------------+-------------------------------------------------------------------------------------------+ @@ -71,7 +78,8 @@ The following table lists the known issues for Version 2022.1: +-------------+-------------------------------------------------------------------------------------------+ Resolved Issues ---------- +---------------- + The following table lists the issues that were resolved in Version 2022.1: +-------------+-------------------------------------------------------------------------------------------+ @@ -81,32 +89,37 @@ The following table lists the issues that were resolved in Version 2022.1: +-------------+-------------------------------------------------------------------------------------------+ Operations and Configuration Changes --------- +---------------------------------------- + No relevant operations and configuration changes were made. Naming Changes -------- +----------------- + No relevant naming changes were made. Deprecated Features -------- +--------------------- + In SQream version 2022.1 the ``VARCHAR`` data type has been deprecated and replaced with ``TEXT``. SQream will maintain ``VARCHAR`` in all previous versions until completing the migration to ``TEXT``, at which point it will be deprecated in all earlier versions. SQream also provides an automated and secure tool to facilitate and simplify migration from ``VARCHAR`` to ``TEXT``. If you are using an earlier version of SQream, see the `Using Legacy String Literals <https://docs.sqream.com/en/v2022.1/configuration_guides/use_legacy_string_literals.html>`_ configuration flag. End of Support -------- +---------------- + The End of Support section is not relevant to Version 2022.1. Upgrading to v2022.1 -------- -1. Generate a back-up of the metadata by running the following command: +----------------------- + +1. Generate a backup of the metadata by running the following command: .. code-block:: console - $ select backup_metadata('out_path'); + $ select backup_metadata('out_path', 'single_file'); - .. tip:: SQream recommends storing the generated back-up locally in case needed. + .. tip:: SQream recommends storing the generated backup locally in case needed. SQream runs the Garbage Collector and creates a multi-file directory as specified in the ``out_path``. @@ -114,11 +127,11 @@ Upgrading to v2022.1 :: -3. Extract the recently created back-up file. +3. Extract the recently created backup file. :: -4. Replace your current metadata with the metadata you stored in the back-up file. +4. Replace your current metadata with the metadata you stored in the backup file. :: From b3e323b6a9c36d2503358baf800f112483603213 Mon Sep 17 00:00:00 2001 From: TaliaSQream <117294941+TaliaSQream@users.noreply.github.com> Date: Tue, 30 Jul 2024 10:08:27 +0300 Subject: [PATCH 316/316] Update requirements.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 575f023b1..f42754033 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ # Defining the exact version will make sure things don't break sphinx==5.3.0 -sphinx_rtd_theme==1.2.0 +sphinx-rtd-theme>=2.1.0rc1 urllib3<=2.0.0 openssl-python>=0.1.1 sphinx-notfound-page