├── .github └── workflows │ └── ci.yaml ├── .gitignore ├── AUTHORS ├── CONTRIBUTING.md ├── LICENSE ├── MANIFEST.in ├── README.md ├── Vagrantfile ├── requirements-dev.txt ├── setup.py ├── tox.ini └── vertica_python ├── __init__.py ├── compat.py ├── datatypes.py ├── errors.py ├── os_utils.py ├── tests ├── __init__.py ├── common │ ├── __init__.py │ ├── base.py │ └── vp_test.conf.example ├── conftest.py ├── integration_tests │ ├── __init__.py │ ├── base.py │ ├── test_authentication.py │ ├── test_cancel.py │ ├── test_column.py │ ├── test_connection.py │ ├── test_cursor.py │ ├── test_datatypes.py │ ├── test_dates.py │ ├── test_errors.py │ ├── test_loadbalance.py │ ├── test_timezones.py │ ├── test_tls.py │ ├── test_transfer_format.py │ └── test_unicode.py └── unit_tests │ ├── __init__.py │ ├── base.py │ ├── test_errors.py │ ├── test_logging.py │ ├── test_notice.py │ ├── test_parsedsn.py │ ├── test_sql_literal.py │ └── test_timestamps.py └── vertica ├── __init__.py ├── column.py ├── connection.py ├── cursor.py ├── deserializer.py ├── log.py ├── messages ├── __init__.py ├── backend_messages │ ├── __init__.py │ ├── authentication.py │ ├── backend_key_data.py │ ├── bind_complete.py │ ├── close_complete.py │ ├── command_complete.py │ ├── command_description.py │ ├── copy_done_response.py │ ├── copy_in_response.py │ ├── data_row.py │ ├── empty_query_response.py │ ├── end_of_batch_response.py │ ├── error_response.py │ ├── load_balance_response.py │ ├── load_file.py │ ├── no_data.py │ ├── notice_response.py │ ├── parameter_description.py │ ├── parameter_status.py │ ├── parse_complete.py │ ├── portal_suspended.py │ ├── ready_for_query.py │ ├── row_description.py │ ├── unknown.py │ ├── verify_files.py │ └── write_file.py ├── frontend_messages │ ├── __init__.py │ ├── bind.py │ ├── cancel_request.py │ ├── close.py │ ├── copy_data.py │ ├── copy_done.py │ ├── copy_error.py │ ├── copy_fail.py │ ├── crypt_windows.py │ ├── describe.py │ ├── end_of_batch_request.py │ ├── execute.py │ ├── flush.py │ ├── load_balance_request.py │ ├── parse.py │ ├── password.py │ ├── query.py │ ├── ssl_request.py │ ├── startup.py │ ├── sync.py │ ├── terminate.py │ └── verified_files.py └── message.py ├── mixins ├── __init__.py └── notice_response_attr.py └── tlsmode.py /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | strategy: 10 | matrix: 11 | python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13', 'pypy3.10'] 12 | 13 | env: 14 | REALM: test 15 | USER: oauth_user 16 | PASSWORD: password 17 | CLIENT_ID: vertica 18 | CLIENT_SECRET: P9f8350QQIUhFfK1GF5sMhq4Dm3P6Sbs 19 | 20 | steps: 21 | - name: Check out repository 22 | uses: actions/checkout@v4 23 | - name: Set up Python ${{ matrix.python-version }} 24 | uses: actions/setup-python@v5 25 | with: 26 | python-version: ${{ matrix.python-version }} 27 | - name: Set up a Keycloak docker container 28 | timeout-minutes: 5 29 | run: | 30 | docker network create -d bridge my-network 31 | docker run -d -p 8080:8080 \ 32 | --name keycloak --network my-network \ 33 | -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin \ 34 | quay.io/keycloak/keycloak:23.0.4 start-dev 35 | docker container ls 36 | 37 | - name: Set up a Vertica server docker container 38 | timeout-minutes: 15 39 | run: | 40 | docker run -d -p 5433:5433 -p 5444:5444 \ 41 | --name vertica_docker --network my-network \ 42 | opentext/vertica-ce:24.4.0-0 43 | echo "Vertica startup ..." 44 | until docker exec vertica_docker test -f /data/vertica/VMart/agent_start.out; do \ 45 | echo "..."; \ 46 | sleep 3; \ 47 | done; 48 | echo "Vertica is up" 49 | docker exec -u dbadmin vertica_docker /opt/vertica/bin/vsql -c "\l" 50 | docker exec -u dbadmin vertica_docker /opt/vertica/bin/vsql -c "select version()" 51 | 52 | - name: Configure Keycloak 53 | run: | 54 | echo "Wait for keycloak ready ..." 55 | bash -c 'while true; do curl -s localhost:8080 &>/dev/null; ret=$?; [[ $ret -eq 0 ]] && break; echo "..."; sleep 3; done' 56 | 57 | docker exec -i keycloak /bin/bash < access_token.txt 78 | 79 | docker exec -u dbadmin vertica_docker /opt/vertica/bin/vsql -c "CREATE AUTHENTICATION v_oauth METHOD 'oauth' HOST '0.0.0.0/0';" 80 | docker exec -u dbadmin vertica_docker /opt/vertica/bin/vsql -c "ALTER AUTHENTICATION v_oauth SET client_id = '${CLIENT_ID}';" 81 | docker exec -u dbadmin vertica_docker /opt/vertica/bin/vsql -c "ALTER AUTHENTICATION v_oauth SET client_secret = '${CLIENT_SECRET}';" 82 | docker exec -u dbadmin vertica_docker /opt/vertica/bin/vsql -c "ALTER AUTHENTICATION v_oauth SET discovery_url = 'http://`hostname`:8080/realms/${REALM}/.well-known/openid-configuration';" 83 | docker exec -u dbadmin vertica_docker /opt/vertica/bin/vsql -c "ALTER AUTHENTICATION v_oauth SET introspect_url = 'http://`hostname`:8080/realms/${REALM}/protocol/openid-connect/token/introspect';" 84 | docker exec -u dbadmin vertica_docker /opt/vertica/bin/vsql -c "SELECT * FROM client_auth WHERE auth_name='v_oauth';" 85 | docker exec -u dbadmin vertica_docker /opt/vertica/bin/vsql -c "CREATE USER ${USER};" 86 | docker exec -u dbadmin vertica_docker /opt/vertica/bin/vsql -c "GRANT AUTHENTICATION v_oauth TO ${USER};" 87 | docker exec -u dbadmin vertica_docker /opt/vertica/bin/vsql -c "GRANT ALL ON SCHEMA PUBLIC TO ${USER};" 88 | # A dbadmin-specific authentication record (connect remotely) is needed after setting up an OAuth user 89 | docker exec -u dbadmin vertica_docker /opt/vertica/bin/vsql -c "CREATE AUTHENTICATION v_dbadmin_hash METHOD 'hash' HOST '0.0.0.0/0';" 90 | docker exec -u dbadmin vertica_docker /opt/vertica/bin/vsql -c "ALTER AUTHENTICATION v_dbadmin_hash PRIORITY 10000;" 91 | docker exec -u dbadmin vertica_docker /opt/vertica/bin/vsql -c "GRANT AUTHENTICATION v_dbadmin_hash TO dbadmin;" 92 | 93 | - name: Install dependencies 94 | run: pip install tox 95 | - name: Run tests 96 | run: | 97 | export VP_TEST_USER=dbadmin 98 | export VP_TEST_OAUTH_ACCESS_TOKEN=`cat access_token.txt` 99 | export VP_TEST_OAUTH_USER=${USER} 100 | tox -e py 101 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | test.py 3 | 4 | # Test configuration 5 | vp_test.conf 6 | 7 | # C extensions 8 | *.so 9 | 10 | # Packages 11 | *.egg 12 | *.egg-info 13 | dist 14 | build 15 | eggs 16 | parts 17 | bin 18 | var 19 | sdist 20 | develop-eggs 21 | .installed.cfg 22 | lib64 23 | 24 | # Installer logs 25 | pip-log.txt 26 | 27 | # Unit test / coverage reports 28 | .coverage 29 | .tox 30 | nosetests.xml 31 | 32 | # Translations 33 | *.mo 34 | 35 | # Mr Developer 36 | .mr.developer.cfg 37 | .project 38 | .pydevproject 39 | .DS_Store 40 | *.iml 41 | 42 | # vagrant 43 | .vagrant 44 | 45 | # pycharm 46 | .idea 47 | 48 | # default virtual environment 49 | /env/ 50 | 51 | # pyenv 52 | .python-version 53 | 54 | # backup files end in ~ 55 | *~ -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | vertica-python was originally created in 2013 at Uber Technologies, Inc. 2 | This is a non-exhaustive list of vertica-python contributors. 3 | This does not necessarily list everyone who has contributed code. 4 | To see the full list of contributors, see the revision history in source control 5 | 6 | Aditya Sarawgi 7 | Aiden Scandella 8 | Aiden Scandella 9 | Alex Kim 10 | Alex Kim 11 | Alvin Wu 12 | asamasoma 13 | Ben Feinstein 14 | Berton Earnshaw 15 | Brad Hurley 16 | Carl Ekerot 17 | Conrad Whelan 18 | Deepak Prakash 19 | Dennis O'Brien 20 | Eric Sayle 21 | esmioley 22 | Flo 23 | Fredrik Appelros 24 | Gabriel Haim 25 | Heli Wang 26 | Heli Wang 27 | Ian Zelikman 28 | Jakub Jedelsky 29 | James Brown 30 | James Brown 31 | jberka 32 | Jean Baptiste Favre 33 | Jeff Kim 34 | Johan Olofsson 35 | Josh Varner 36 | jsingh3 37 | Justin Berka 38 | Justin Berka 39 | Kenneth Tran 40 | kennethdamica 41 | Kevin Sweeney 42 | Konstantin 43 | lemeryfertitta 44 | Lubo 45 | Lubo Slivka 46 | luke 47 | Mark R. 48 | nchammas 49 | Nicholas Travers 50 | Paulius Šileikis 51 | Peder Andersen 52 | pedercandersen 53 | Peter M. Landwehr 54 | Praveen Jain 55 | Rahul Agarwal 56 | rforgione 57 | Richard Tom 58 | Ruwen Jin 59 | Sevag Hanssian 60 | Shiva M 61 | Steven van Stiphout 62 | Thom Neale 63 | Thom Neale 64 | Timothy Heys 65 | tudit 66 | tumuluru 67 | twneale 68 | Udit Tumuluri 69 | zer0n 70 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE 2 | include requirements.txt 3 | include README.md 4 | recursive-include vertica_python *.py 5 | recursive-exclude vertica_python *.pyc 6 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | ENV["VAGRANT_DEFAULT_PROVIDER"] ||= "docker" 5 | 6 | VAGRANTFILE_API_VERSION = "2" 7 | 8 | ####################################################################### 9 | # This will set up a box with Vertica Community Edition 7.1.1 10 | # running inside the box in a Docker container. 11 | # 12 | # The purpose is to have a Vertica instance that can be used by tests. 13 | # 14 | # Vertica's port 5433 is exposed to host machine. 15 | # Database 'docker' is available. 16 | # User is 'dbadmin' with no password. 17 | # 18 | # >>> 19 | # ! As is, any data stored inside Vertica will not live through 20 | # ! container or VM restart. 21 | # >>> 22 | ####################################################################### 23 | 24 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 25 | 26 | config.vm.provider "docker" do |d| 27 | d.image = "sumitchawla/vertica:latest" 28 | d.ports = ["5433:5433"] 29 | end 30 | 31 | config.vm.synced_folder ".", "/vagrant", disabled: true 32 | 33 | end 34 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | pytest 2 | pytest-timeout 3 | python-dateutil 4 | tox 5 | #kerberos 6 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | #!/usr/bin/env python 37 | import collections 38 | from setuptools import setup, find_packages 39 | 40 | 41 | ReqOpts = collections.namedtuple('ReqOpts', ['skip_requirements_regex', 'default_vcs']) 42 | 43 | opts = ReqOpts(None, 'git') 44 | 45 | # version should use the format 'x.x.x' (instead of 'vx.x.x') 46 | setup( 47 | name='vertica-python', 48 | version='1.4.0', 49 | description='Official native Python client for the Vertica database.', 50 | long_description="vertica-python is the official Vertica database client for the Python programming language. Please check the [project homepage](https://github.com/vertica/vertica-python) for the details.", 51 | long_description_content_type='text/markdown', 52 | author='Justin Berka, Alex Kim, Siting Ren', 53 | author_email='justin.berka@gmail.com, alex.kim@uber.com, sitingren@hotmail.com', 54 | url='https://github.com/vertica/vertica-python', 55 | keywords="database vertica", 56 | packages=find_packages(), 57 | license="Apache License 2.0", 58 | # 'pip install' will check this and refuse to install the project if the version does not match. 59 | python_requires=">=3.8", 60 | install_requires=[ 61 | 'python-dateutil>=1.5', 62 | ], 63 | classifiers=[ 64 | "Development Status :: 5 - Production/Stable", 65 | "Intended Audience :: Developers", 66 | "License :: OSI Approved :: Apache Software License", 67 | "Programming Language :: Python", 68 | "Programming Language :: Python :: 3", 69 | "Programming Language :: Python :: 3.8", 70 | "Programming Language :: Python :: 3.9", 71 | "Programming Language :: Python :: 3.10", 72 | "Programming Language :: Python :: 3.11", 73 | "Programming Language :: Python :: 3.12", 74 | "Programming Language :: Python :: 3.13", 75 | "Topic :: Database", 76 | "Topic :: Database :: Database Engines/Servers", 77 | "Topic :: Database :: Front-Ends", 78 | "Topic :: Software Development :: Libraries :: Python Modules", 79 | "Operating System :: OS Independent" 80 | ] 81 | ) 82 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = py38,py39,py310,py311,py312,py313 3 | 4 | [testenv] 5 | passenv = * 6 | commands = 7 | pytest {posargs} 8 | deps = 9 | pytest 10 | pytest-timeout 11 | parameterized 12 | python-dateutil 13 | mock 14 | -------------------------------------------------------------------------------- /vertica_python/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from .vertica.connection import Connection, connect, parse_dsn 39 | 40 | # Importing exceptions for compatibility with dbapi 2.0. 41 | # See: PEP 249 - Python Database API 2.0 42 | # https://www.python.org/dev/peps/pep-0249/#exceptions 43 | from . import errors 44 | from .errors import ( 45 | Error, Warning, DataError, DatabaseError, IntegrityError, InterfaceError, 46 | InternalError, NotSupportedError, OperationalError, ProgrammingError) 47 | 48 | # Main module for this library. 49 | __author__ = 'Vertica' 50 | __copyright__ = 'Copyright (c) 2018-2024 Open Text.' 51 | __license__ = 'Apache 2.0' 52 | 53 | __all__ = ['Connection', 'PROTOCOL_VERSION', 'version_info', 'apilevel', 'threadsafety', 54 | 'paramstyle', 'connect', 'parse_dsn', 'Error', 'Warning', 'DataError', 'DatabaseError', 55 | 'IntegrityError', 'InterfaceError', 'InternalError', 'NotSupportedError', 56 | 'OperationalError', 'ProgrammingError'] 57 | 58 | # The version number of this library. 59 | version_info = (1, 4, 0) 60 | __version__ = '.'.join(map(str, version_info)) 61 | 62 | # The protocol version (3.16) implemented in this library. 63 | PROTOCOL_VERSION = 3 << 16 | 16 64 | 65 | apilevel = 2.0 66 | threadsafety = 1 # Threads may share the module, but not connections! 67 | 68 | # Accepted paramstyles are 69 | # 'qmark' = Question mark style, e.g. '...WHERE name=?' 70 | # 'named' = Named style, e.g. '...WHERE name=:name' 71 | # 'format' = ANSI C printf format codes, e.g. '...WHERE name=%s' 72 | paramstyle = 'named' 73 | -------------------------------------------------------------------------------- /vertica_python/compat.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | 37 | # Copyright 2015 The TensorFlow Authors. All Rights Reserved. 38 | # 39 | # Licensed under the Apache License, Version 2.0 (the "License"); 40 | # you may not use this file except in compliance with the License. 41 | # You may obtain a copy of the License at 42 | # 43 | # http://www.apache.org/licenses/LICENSE-2.0 44 | # 45 | # Unless required by applicable law or agreed to in writing, software 46 | # distributed under the License is distributed on an "AS IS" BASIS, 47 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 48 | # See the License for the specific language governing permissions and 49 | # limitations under the License. 50 | # ============================================================================== 51 | 52 | """Functions for Python 2 vs. 3 compatibility. 53 | ## Conversion routines 54 | @@as_bytes 55 | @@as_str 56 | """ 57 | 58 | 59 | def as_bytes(bytes_or_text, encoding='utf-8'): 60 | """Converts either bytes or unicode to `bytes`, using utf-8 encoding for text. 61 | Args: 62 | bytes_or_text: A `bytes`, `bytearray`, or `str` object. 63 | encoding: A string indicating the charset for encoding unicode. 64 | Returns: 65 | A `bytes` object. 66 | Raises: 67 | TypeError: If `bytes_or_text` is not a binary or unicode string. 68 | """ 69 | if isinstance(bytes_or_text, str): 70 | return bytes_or_text.encode(encoding) 71 | elif isinstance(bytes_or_text, (bytes, bytearray)): 72 | return bytes(bytes_or_text) 73 | else: 74 | raise TypeError('Expected binary or unicode string, got %r' % bytes_or_text) 75 | 76 | 77 | def as_str(bytes_or_text, encoding='utf-8'): 78 | """Returns the given argument as a unicode string. 79 | Args: 80 | bytes_or_text: A `bytes`, `bytearray`, or `str` object. 81 | encoding: A string indicating the charset for decoding unicode. 82 | Returns: 83 | A `str` object. 84 | Raises: 85 | TypeError: If `bytes_or_text` is not a binary or unicode string. 86 | """ 87 | if isinstance(bytes_or_text, str): 88 | return bytes_or_text 89 | elif isinstance(bytes_or_text, (bytes, bytearray)): 90 | return bytes_or_text.decode(encoding) 91 | else: 92 | raise TypeError('Expected binary or unicode string, got %r' % bytes_or_text) 93 | 94 | -------------------------------------------------------------------------------- /vertica_python/os_utils.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020-2024 Open Text. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | from __future__ import annotations 17 | 18 | import errno 19 | import os 20 | 21 | 22 | def ensure_dir_exists(filepath: str) -> None: 23 | """Ensure that a directory exists 24 | 25 | If it doesn't exist, try to create it and protect against a race condition 26 | if another process is doing the same. 27 | """ 28 | directory = os.path.dirname(filepath) 29 | if directory != '' and not os.path.exists(directory): 30 | try: 31 | os.makedirs(directory) 32 | except OSError as e: 33 | if e.errno != errno.EEXIST: 34 | raise 35 | 36 | def check_file_readable(filename: str) -> None: 37 | """Ensure this is a readable file""" 38 | if not os.path.exists(filename): 39 | raise OSError('{} does not exist'.format(filename)) 40 | elif not os.path.isfile(filename): 41 | raise OSError('{} is not a file'.format(filename)) 42 | elif not os.access(filename, os.R_OK): 43 | raise OSError('{} is not readable'.format(filename)) 44 | 45 | def check_file_writable(filename: str) -> None: 46 | """Ensure this is a writable file. If the file doesn't exist, 47 | ensure its directory is writable. 48 | """ 49 | if os.path.exists(filename): 50 | if not os.path.isfile(filename): 51 | raise OSError('{} is not a file'.format(filename)) 52 | if not os.access(filename, os.W_OK): 53 | raise OSError('{} is not writable'.format(filename)) 54 | # If target does not exist, check permission on parent dir 55 | ensure_dir_exists(filename) 56 | pdir = os.path.dirname(filename) 57 | if not pdir: 58 | pdir = '.' 59 | if not os.path.isdir(pdir): 60 | raise OSError('{} is not a directory'.format(pdir)) 61 | if not os.access(pdir, os.W_OK): 62 | raise OSError('Directory {} is not writable'.format(pdir)) 63 | 64 | -------------------------------------------------------------------------------- /vertica_python/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. -------------------------------------------------------------------------------- /vertica_python/tests/common/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. -------------------------------------------------------------------------------- /vertica_python/tests/common/vp_test.conf.example: -------------------------------------------------------------------------------- 1 | # To override default configuration information for the driver test system, 2 | # create a new file called 'vp_test.conf' in this directory with the following syntax 3 | 4 | [vp_test_config] 5 | 6 | # Connection information 7 | VP_TEST_HOST=10.0.0.2 8 | VP_TEST_PORT=5000 9 | VP_TEST_USER=dbadmin 10 | #VP_TEST_DATABASE=vdb1 11 | #VP_TEST_PASSWORD=abcdef1234 12 | 13 | # Logging information 14 | # Valid VP_TEST_LOG_LEVEL options: 'NOTSET', 'DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL' 15 | VP_TEST_LOG_LEVEL=DEBUG 16 | VP_TEST_LOG_DIR=mylog/vp_tox_tests_log 17 | 18 | # OAuth authentication information 19 | #VP_TEST_OAUTH_USER= 20 | #VP_TEST_OAUTH_ACCESS_TOKEN=****** 21 | -------------------------------------------------------------------------------- /vertica_python/tests/conftest.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2019-2024 Open Text. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | def pytest_configure(config): 16 | config.addinivalue_line( 17 | "markers", "integration_tests: mark test to be an integration test" 18 | ) 19 | config.addinivalue_line( 20 | "markers", "unit_tests: mark test to be an unit test" 21 | ) 22 | -------------------------------------------------------------------------------- /vertica_python/tests/integration_tests/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. -------------------------------------------------------------------------------- /vertica_python/tests/integration_tests/test_cancel.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2019-2024 Open Text. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import annotations 16 | 17 | from multiprocessing import Process 18 | import pytest 19 | import time 20 | 21 | from .base import VerticaPythonIntegrationTestCase 22 | from ... import errors 23 | 24 | 25 | class CancelTestCase(VerticaPythonIntegrationTestCase): 26 | 27 | def test_cursor_cancel(self): 28 | # Cursor.cancel() should be not supported any more 29 | with self._connect() as conn: 30 | cursor = conn.cursor() 31 | with self.assertRaises(errors.NotSupportedError): 32 | cursor.cancel() 33 | 34 | def test_connection_cancel_no_query(self): 35 | with self._connect() as conn: 36 | cur = conn.cursor() 37 | # No query is being executed, cancel does nothing 38 | conn.cancel() 39 | 40 | @pytest.mark.timeout(30) 41 | def test_connection_cancel_running_query(self): 42 | def cancel_query(conn, delay=5): 43 | time.sleep(delay) 44 | conn.cancel() 45 | 46 | with self._connect() as conn: 47 | cur = conn.cursor() 48 | p1 = Process(target=cancel_query, args=(conn,)) 49 | p1.start() 50 | with self.assertRaises(errors.QueryCanceled): 51 | long_running_query = ('select count(*) from ' 52 | '(select node_name from CONFIGURATION_PARAMETERS) as a cross join ' 53 | '(select node_name from CONFIGURATION_PARAMETERS) as b cross join ' 54 | '(select node_name from CONFIGURATION_PARAMETERS) as c') 55 | cur.execute(long_running_query) 56 | p1.join() 57 | 58 | # Must be able to successfully run next query 59 | cur.execute("SELECT 1") 60 | res = cur.fetchall() 61 | self.assertListOfListsEqual(res, [[1]]) 62 | 63 | def test_connection_cancel_returned_query(self): 64 | with self._connect() as conn: 65 | cur = conn.cursor() 66 | cur.execute("DROP TABLE IF EXISTS vptest") 67 | try: 68 | # Creating and loading table 69 | cur.execute("CREATE TABLE vptest(id INTEGER, time TIMESTAMP)") 70 | cur.execute("INSERT INTO vptest" 71 | " SELECT row_number() OVER(), slice_time" 72 | " FROM(" 73 | " SELECT slice_time FROM(" 74 | " SELECT '2021-01-01'::timestamp s UNION ALL SELECT '2022-01-01'::timestamp s" 75 | " ) sq TIMESERIES slice_time AS '1 second' OVER(ORDER BY s)" 76 | " ) sq2") 77 | 78 | # This query returns over 30,000,000 rows. We cancel the command after 79 | # reading 100 of them, and then continue reading results. This quickly 80 | # results in an exception being thrown due to the cancel having taken effect. 81 | cur.execute("SELECT id, time FROM vptest") 82 | 83 | nCount = 0 84 | with self.assertRaises(errors.QueryCanceled): 85 | while cur.fetchone(): 86 | nCount += 1 87 | if nCount == 100: 88 | conn.cancel() 89 | 90 | # The number of rows read after the cancel message is sent to the server can vary. 91 | # 1,000,000 seems to leave a safe margin while still falling well short of 92 | # the 30,000,000+ rows we'd have read if the cancel didn't work. 93 | self.assertTrue(100 <= nCount < 1000000) 94 | 95 | # Must be able to successfully run next query 96 | cur.execute("SELECT 1") 97 | res = cur.fetchall() 98 | self.assertListOfListsEqual(res, [[1]]) 99 | finally: 100 | cur.execute("DROP TABLE IF EXISTS vptest") 101 | 102 | 103 | exec(CancelTestCase.createPrepStmtClass()) 104 | -------------------------------------------------------------------------------- /vertica_python/tests/integration_tests/test_column.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from .base import VerticaPythonIntegrationTestCase 39 | 40 | 41 | class ColumnTestCase(VerticaPythonIntegrationTestCase): 42 | def test_column_names_query(self): 43 | columns = ['isocode', 'name', '\uFF04'] 44 | 45 | with self._connect() as conn: 46 | cur = conn.cursor() 47 | cur.execute(""" 48 | SELECT 'US' AS {0}, 'United States' AS {1}, 'USD' AS {2} 49 | UNION ALL SELECT 'CA', 'Canada', 'CAD' 50 | UNION ALL SELECT 'MX', 'Mexico', 'MXN' """.format(*columns)) 51 | description = cur.description 52 | 53 | self.assertListEqual([d.name for d in description], columns) 54 | 55 | def test_column_description(self): 56 | type_descriptions = [ 57 | ['boolVal', 5, 1, 1, None, None, True], 58 | ['intVal', 6, 20, 8, None, None, True], 59 | ['floatVal', 7, 22, 8, None, None, True], 60 | ['charVal', 8, 1, -1, None, None, True], 61 | ['varCharVal', 9, 128, -1, None, None, True], 62 | ['dateVal', 10, 13, 8, None, None, True], 63 | ['timestampVal', 12, 29, 8, 6, None, True], 64 | ['timestampTZVal', 13, 35, 8, 6, None, True], 65 | ['intervalVal', 14, 24, 8, 4, None, True], 66 | ['intervalYMVal', 114, 22, 8, 0, None, True], 67 | ['timeVal', 11, 15, 8, 6, None, True], 68 | ['timeTZVal', 15, 21, 8, 6, None, True], 69 | ['varBinVal', 17, 80, -1, None, None, True], 70 | ['uuidVal', 20, 36, 16, None, None, True], 71 | ['lVarCharVal', 115, 65536, -1, None, None, True], 72 | ['lVarBinaryVal', 116, 65536, -1, None, None, True], 73 | ['binaryVal', 117, 1, -1, None, None, True], 74 | ['numericVal', 16, 1002, -1, 1000, 18, True]] 75 | 76 | with self._connect() as conn: 77 | cur = conn.cursor() 78 | cur.execute("DROP TABLE IF EXISTS full_type_tbl") 79 | cur.execute("""CREATE TABLE full_type_tbl( 80 | boolVal BOOLEAN, 81 | intVal INT, 82 | floatVal FLOAT, 83 | charVal CHAR, 84 | varCharVal VARCHAR(128), 85 | dateVal DATE, 86 | timestampVal TIMESTAMP, 87 | timestampTZVal TIMESTAMPTZ, 88 | intervalVal INTERVAL DAY TO SECOND(4), 89 | intervalYMVal INTERVAL YEAR TO MONTH, 90 | timeVal TIME, 91 | timeTZVal TIMETZ, 92 | varBinVal VARBINARY, 93 | uuidVal UUID, 94 | lVarCharVal LONG VARCHAR(65536), 95 | lVarBinaryVal LONG VARBINARY(65536), 96 | binaryVal BINARY, 97 | numericVal NUMERIC(1000,18))""") 98 | cur.execute("SELECT * FROM full_type_tbl") 99 | self.assertListOfListsEqual([list(i) for i in cur.description], type_descriptions) 100 | cur.execute("DROP TABLE IF EXISTS full_type_tbl") 101 | 102 | 103 | exec(ColumnTestCase.createPrepStmtClass()) 104 | -------------------------------------------------------------------------------- /vertica_python/tests/integration_tests/test_errors.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from .base import VerticaPythonIntegrationTestCase 39 | 40 | from ... import errors 41 | 42 | 43 | class ErrorTestCase(VerticaPythonIntegrationTestCase): 44 | def test_missing_schema(self): 45 | with self._connect() as conn: 46 | cur = conn.cursor() 47 | with self.assertRaises(errors.MissingSchema): 48 | cur.execute("SELECT 1 FROM missing_schema.table") 49 | 50 | def test_missing_relation(self): 51 | with self._connect() as conn: 52 | cur = conn.cursor() 53 | with self.assertRaises(errors.MissingRelation): 54 | cur.execute("SELECT 1 FROM missing_table") 55 | 56 | def test_duplicate_object(self): 57 | with self._connect() as conn: 58 | cur = conn.cursor() 59 | cur.execute("DROP TABLE IF EXISTS duplicate_table") 60 | query = "CREATE TABLE duplicate_table (a BOOLEAN)" 61 | cur.execute(query) 62 | with self.assertRaises(errors.DuplicateObject): 63 | cur.execute(query) 64 | cur.execute("DROP TABLE IF EXISTS duplicate_table") 65 | 66 | 67 | exec(ErrorTestCase.createPrepStmtClass()) 68 | -------------------------------------------------------------------------------- /vertica_python/tests/integration_tests/test_timezones.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from collections import namedtuple 39 | from datetime import datetime 40 | from dateutil import tz 41 | 42 | from .base import VerticaPythonIntegrationTestCase 43 | 44 | TimeZoneTestingCase = namedtuple("TimeZoneTestingCase", ["string", "template", "timestamp"]) 45 | 46 | 47 | class TimeZoneTestCase(VerticaPythonIntegrationTestCase): 48 | def _test_ts(self, test_cases): 49 | with self._connect() as conn: 50 | cur = conn.cursor() 51 | for tc in test_cases: 52 | cur.execute("SELECT TO_TIMESTAMP('{0}', '{1}')".format(tc.string, tc.template)) 53 | res = cur.fetchone() 54 | self.assertEqual(tc.timestamp.toordinal(), res[0].toordinal()) 55 | 56 | def test_simple_ts_query(self): 57 | template = 'YYYY-MM-DD HH:MI:SS.MS' 58 | test_cases = [ 59 | TimeZoneTestingCase( 60 | string='2016-05-15 13:15:17.789', template=template, 61 | timestamp=datetime(year=2016, month=5, day=15, hour=13, minute=15, second=17, 62 | microsecond=789000) 63 | ), 64 | ] 65 | self._test_ts(test_cases=test_cases) 66 | 67 | def test_simple_ts_with_tz_query(self): 68 | template = 'YYYY-MM-DD HH:MI:SS.MS TZ' 69 | test_cases = [ 70 | TimeZoneTestingCase( 71 | string='2016-05-15 13:15:17.789 UTC', template=template, 72 | timestamp=datetime(year=2016, month=5, day=15, hour=13, minute=15, second=17, 73 | microsecond=789000, tzinfo=tz.tzutc()) 74 | ), 75 | ] 76 | self._test_ts(test_cases=test_cases) 77 | 78 | def test_simple_ts_with_offset_query(self): 79 | template = 'YYYY-MM-DD HH:MI:SS.MS+00' 80 | test_cases = [ 81 | TimeZoneTestingCase( 82 | string='2016-05-15 13:15:17.789 UTC', template=template, 83 | timestamp=datetime(year=2016, month=5, day=15, hour=13, minute=15, second=17, 84 | microsecond=789000, tzinfo=tz.tzutc()) 85 | ), 86 | ] 87 | self._test_ts(test_cases=test_cases) 88 | 89 | 90 | exec(TimeZoneTestCase.createPrepStmtClass()) 91 | -------------------------------------------------------------------------------- /vertica_python/tests/integration_tests/test_unicode.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from .base import VerticaPythonIntegrationTestCase 39 | 40 | 41 | class UnicodeTestCase(VerticaPythonIntegrationTestCase): 42 | def test_unicode_query(self): 43 | value = '\u16a0' 44 | query = "SELECT '{0}'".format(value) 45 | 46 | with self._connect() as conn: 47 | cur = conn.cursor() 48 | cur.execute(query) 49 | res = cur.fetchone() 50 | 51 | self.assertEqual(value, res[0]) 52 | 53 | def test_unicode_list_parameter(self): 54 | values = ['\u00f1', 'foo', 3] 55 | query = "SELECT {0}".format(", ".join(["%s"] * len(values))) 56 | 57 | with self._connect() as conn: 58 | cur = conn.cursor() 59 | cur.execute(query, tuple(values)) 60 | results = cur.fetchone() 61 | 62 | for val, res in zip(values, results): 63 | self.assertEqual(val, res) 64 | 65 | def test_unicode_named_parameter_binding(self): 66 | values = ['\u16b1', 'foo', 3] 67 | keys = ['\u16a0', 'foo', 3] 68 | 69 | query = "SELECT {0}".format(", ".join([":{0}".format(key) for key in keys])) 70 | 71 | with self._connect() as conn: 72 | cur = conn.cursor() 73 | cur.execute(query, dict(zip(keys, values))) 74 | results = cur.fetchone() 75 | 76 | for val, res in zip(values, results): 77 | self.assertEqual(val, res) 78 | 79 | def test_string_query(self): 80 | value = 'test' 81 | query = "SELECT '{0}'".format(value) 82 | 83 | with self._connect() as conn: 84 | cur = conn.cursor() 85 | cur.execute(query) 86 | res = cur.fetchone() 87 | 88 | self.assertEqual(value, res[0]) 89 | 90 | def test_string_named_parameter_binding(self): 91 | key = 'test' 92 | value = 'value' 93 | query = "SELECT :{0}".format(key) 94 | 95 | with self._connect() as conn: 96 | cur = conn.cursor() 97 | cur.execute(query, {key: value}) 98 | res = cur.fetchone() 99 | 100 | self.assertEqual(value, res[0]) 101 | 102 | # unit test for issue #160 103 | def test_null_named_parameter_binding(self): 104 | key = 'test' 105 | value = None 106 | query = "SELECT :{0}".format(key) 107 | 108 | with self._connect() as conn: 109 | cur = conn.cursor() 110 | cur.execute(query, {key: value}) 111 | res = cur.fetchone() 112 | 113 | self.assertEqual(value, res[0]) 114 | 115 | # unit test for issue #160 116 | def test_null_list_parameter(self): 117 | values = ['\u00f1', 'foo', None] 118 | query = "SELECT {0}".format(", ".join(["%s"] * len(values))) 119 | 120 | with self._connect() as conn: 121 | cur = conn.cursor() 122 | cur.execute(query, tuple(values)) 123 | results = cur.fetchone() 124 | 125 | for val, res in zip(values, results): 126 | self.assertEqual(val, res) 127 | -------------------------------------------------------------------------------- /vertica_python/tests/unit_tests/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. -------------------------------------------------------------------------------- /vertica_python/tests/unit_tests/base.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | import pytest 39 | from ..common.base import VerticaPythonTestCase 40 | 41 | 42 | @pytest.mark.unit_tests 43 | class VerticaPythonUnitTestCase(VerticaPythonTestCase): 44 | """ 45 | Base class for tests that do not require database connection; 46 | simple unit testing of individual classes and functions 47 | """ 48 | @classmethod 49 | def setUpClass(cls): 50 | cls.test_config = cls._load_test_config(['log_dir', 'log_level']) 51 | cls._setup_logger('unit_tests', cls.test_config['log_dir'], cls.test_config['log_level']) 52 | 53 | @classmethod 54 | def tearDownClass(cls): 55 | pass 56 | -------------------------------------------------------------------------------- /vertica_python/tests/unit_tests/test_errors.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | from __future__ import annotations 17 | 18 | from .base import VerticaPythonUnitTestCase 19 | from ...errors import VerticaSyntaxError 20 | from ...vertica.messages.backend_messages.error_response import ErrorResponse 21 | 22 | import pickle 23 | 24 | # Using a subclass of ErrorResponse for this test, to avoid the complexity of 25 | # creating an ErrorResponse object. At the time of writing, ErrorResponse and 26 | # other BackendMessage instances can only be created from server-provided data. 27 | # 28 | # This subclass allows for simpler instantiation without binding to any details 29 | # of server data serialization, a la NoticeResponseAttrMixin and NoticeResponse 30 | class MockErrorResponse(ErrorResponse): 31 | def __init__(self): 32 | # does NOT call super 33 | self._notice_attrs = {} 34 | 35 | def error_message(self): 36 | return "Manufactured error message for testing" 37 | 38 | class ErrorsTestCase(VerticaPythonUnitTestCase): 39 | def test_pickling(self): 40 | err_response = MockErrorResponse() 41 | sql = "select 1;" 42 | exc = VerticaSyntaxError(err_response, sql) 43 | 44 | serde = pickle.loads(pickle.dumps(exc)) 45 | 46 | assert isinstance(serde, VerticaSyntaxError) 47 | assert str(serde) == str(exc) 48 | assert isinstance(serde.error_response, MockErrorResponse) 49 | assert serde.error_response.error_message() == err_response.error_message() 50 | assert serde.sql == exc.sql 51 | -------------------------------------------------------------------------------- /vertica_python/tests/unit_tests/test_logging.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2019-2024 Open Text. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import annotations 16 | 17 | import logging 18 | import os 19 | 20 | from ...vertica.log import VerticaLogging 21 | from .base import VerticaPythonUnitTestCase 22 | 23 | 24 | class LoggingTestCase(VerticaPythonUnitTestCase): 25 | 26 | def test_file_handler(self): 27 | logger_name = "test_file_handler" 28 | 29 | logger = logging.getLogger(logger_name) 30 | self.assertNotEqual(logging.getLevelName(logger.getEffectiveLevel()), 'DEBUG') 31 | 32 | log_file = os.path.join(self.test_config['log_dir'], 'test_file_handler.log') 33 | VerticaLogging.setup_logging(logger_name, log_file, 'DEBUG') 34 | 35 | self.assertEqual(len(logger.handlers), 1) 36 | self.assertEqual(logging.getLevelName(logger.getEffectiveLevel()), 'DEBUG') 37 | 38 | def test_missing_file(self): 39 | logger_name = "test_missing_file" 40 | logger = logging.getLogger(logger_name) 41 | 42 | VerticaLogging.setup_logging(logger_name, None, 'DEBUG') 43 | VerticaLogging.setup_logging(logger_name, '', 'DEBUG') 44 | 45 | self.assertEqual(len(logger.handlers), 0) 46 | self.assertEqual(logging.getLevelName(logger.getEffectiveLevel()), 'DEBUG') 47 | -------------------------------------------------------------------------------- /vertica_python/tests/unit_tests/test_notice.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2019-2024 Open Text. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import annotations 16 | 17 | import mock 18 | 19 | from .base import VerticaPythonUnitTestCase 20 | from ...vertica.messages import NoticeResponse 21 | from ...errors import QueryError 22 | 23 | 24 | class NoticeTestCase(VerticaPythonUnitTestCase): 25 | SAMPLE_DATA = {b'S': 'FATAL', 26 | b'H': 'This is a test hint', 27 | b'L': '9999', 28 | b'M': 'Failure is on purpose'} 29 | 30 | @mock.patch.object(NoticeResponse, '_unpack_data') 31 | def test_error_message(self, mock_unpack_data): 32 | mock_unpack_data.return_value = NoticeTestCase.SAMPLE_DATA 33 | 34 | notice = NoticeResponse(b'ignored-due-to-mock') 35 | self.assertEqual( 36 | notice.error_message(), 37 | 'Severity: FATAL, Message: Failure is on purpose, Hint: This is a test hint, Line: 9999' 38 | ) 39 | 40 | @mock.patch.object(NoticeResponse, '_unpack_data') 41 | def test_attribute_properties(self, mock_unpack_data): 42 | mock_unpack_data.return_value = NoticeTestCase.SAMPLE_DATA 43 | 44 | notice = NoticeResponse(b'ignored-due-to-mock') 45 | self.assertEqual(notice.severity, 'FATAL') 46 | self.assertEqual(notice.hint, 'This is a test hint') 47 | # yes, line is still a string. 48 | self.assertEqual(notice.line, '9999') 49 | self.assertEqual(notice.message, 'Failure is on purpose') 50 | self.assertIsNone(notice.detail) 51 | self.assertIsNone(notice.sqlstate) 52 | 53 | @mock.patch.object(NoticeResponse, '_unpack_data') 54 | def test_labeled_values(self, mock_unpack_data): 55 | mock_unpack_data.return_value = NoticeTestCase.SAMPLE_DATA 56 | 57 | notice = NoticeResponse(b'ignored-due-to-mock') 58 | self.assertEqual(notice.values, { 59 | 'Severity': 'FATAL', 60 | 'Hint': 'This is a test hint', 61 | 'Line': '9999', 62 | 'Message': 'Failure is on purpose'}) 63 | 64 | @mock.patch.object(NoticeResponse, '_unpack_data') 65 | def test_query_error(self, mock_unpack_data): 66 | mock_unpack_data.return_value = NoticeTestCase.SAMPLE_DATA 67 | 68 | notice = NoticeResponse(b'ignored-due-to-mock') 69 | query_error = QueryError(notice, 'Select Fake();') 70 | 71 | self.assertEqual(query_error.severity, 'FATAL') 72 | self.assertEqual(query_error.hint, 'This is a test hint') 73 | self.assertEqual(query_error.line, '9999') 74 | self.assertEqual(query_error.message, 'Failure is on purpose') 75 | self.assertIsNone(query_error.detail) 76 | self.assertIsNone(query_error.sqlstate) 77 | 78 | self.assertEqual( 79 | str(query_error), 80 | 'Severity: FATAL, Message: Failure is on purpose, Hint: This is a test hint, Line: 9999, SQL: \'Select Fake();\'') 81 | -------------------------------------------------------------------------------- /vertica_python/tests/unit_tests/test_parsedsn.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | from __future__ import annotations 17 | 18 | from .base import VerticaPythonUnitTestCase 19 | from ...vertica.connection import parse_dsn 20 | 21 | 22 | class ParseDSNTestCase(VerticaPythonUnitTestCase): 23 | def test_basic(self): 24 | dsn = 'vertica://admin@192.168.10.1' 25 | expected = {'host': '192.168.10.1', 'user': 'admin'} 26 | parsed = parse_dsn(dsn) 27 | self.assertDictEqual(expected, parsed) 28 | 29 | dsn = 'vertica://mike@127.0.0.1/db1' 30 | expected = {'host': '127.0.0.1', 'user': 'mike', 'database': 'db1'} 31 | parsed = parse_dsn(dsn) 32 | self.assertDictEqual(expected, parsed) 33 | 34 | dsn = 'vertica://john:pwd@example.com:5433/db1' 35 | expected = {'database': 'db1', 'host': 'example.com', 'password': 'pwd', 36 | 'port': 5433, 'user': 'john'} 37 | parsed = parse_dsn(dsn) 38 | self.assertDictEqual(expected, parsed) 39 | 40 | def test_str_arguments(self): 41 | dsn = ('vertica://john:pwd@localhost:5433/db1?' 42 | 'session_label=vpclient&unicode_error=strict&' 43 | 'log_path=/home/admin/vClient.log&log_level=DEBUG&' 44 | 'oauth_access_token=GciOiJSUzI1NiI&' 45 | 'workload=python_test_workload&tlsmode=verify-ca&' 46 | 'tls_cafile=tls/ca_cert.pem&tls_certfile=tls/cert.pem&' 47 | 'tls_keyfile=tls/key.pem&' 48 | 'kerberos_service_name=krb_service&kerberos_host_name=krb_host') 49 | expected = {'database': 'db1', 'host': 'localhost', 'user': 'john', 50 | 'password': 'pwd', 'port': 5433, 'log_level': 'DEBUG', 51 | 'session_label': 'vpclient', 'unicode_error': 'strict', 52 | 'log_path': '/home/admin/vClient.log', 53 | 'oauth_access_token': 'GciOiJSUzI1NiI', 54 | 'workload': 'python_test_workload', 55 | 'tlsmode': 'verify-ca', 56 | 'tls_cafile': 'tls/ca_cert.pem', 57 | 'tls_certfile': 'tls/cert.pem', 58 | 'tls_keyfile': 'tls/key.pem', 59 | 'kerberos_service_name': 'krb_service', 60 | 'kerberos_host_name': 'krb_host'} 61 | parsed = parse_dsn(dsn) 62 | self.assertDictEqual(expected, parsed) 63 | 64 | def test_boolean_arguments(self): 65 | dsn = ('vertica://mike@127.0.0.1/db1?connection_load_balance=True&' 66 | 'use_prepared_statements=0&ssl=false&disable_copy_local=on&' 67 | 'autocommit=true&binary_transfer=1&request_complex_types=off') 68 | expected = {'database': 'db1', 'connection_load_balance': True, 69 | 'use_prepared_statements': False, 'ssl': False, 70 | 'disable_copy_local': True, 'autocommit': True, 71 | 'binary_transfer': True, 'request_complex_types': False, 72 | 'host': '127.0.0.1', 'user': 'mike'} 73 | parsed = parse_dsn(dsn) 74 | self.assertDictEqual(expected, parsed) 75 | 76 | def test_numeric_arguments(self): 77 | dsn = 'vertica://mike@127.0.0.1/db1?connection_timeout=1.5&log_level=10' 78 | expected = {'host': '127.0.0.1', 'user': 'mike', 'database': 'db1', 79 | 'connection_timeout': 1.5, 'log_level': 10} 80 | parsed = parse_dsn(dsn) 81 | self.assertDictEqual(expected, parsed) 82 | 83 | def test_ignored_arguments(self): 84 | # Invalid value 85 | dsn = ('vertica://mike@127.0.0.1/db1?ssl=ssl_context&' 86 | 'connection_load_balance=unknown') 87 | expected = {'host': '127.0.0.1', 'user': 'mike', 'database': 'db1'} 88 | parsed = parse_dsn(dsn) 89 | self.assertDictEqual(expected, parsed) 90 | 91 | # Unsupported argument 92 | dsn = 'vertica://mike@127.0.0.1/db1?backup_server_node=123.456.789.123' 93 | expected = {'host': '127.0.0.1', 'user': 'mike', 'database': 'db1'} 94 | parsed = parse_dsn(dsn) 95 | self.assertDictEqual(expected, parsed) 96 | 97 | def test_overwrite_arguments(self): 98 | dsn = 'vertica://mike@127.0.0.1/db1?ssl=on&ssl=off&ssl=1&ssl=0' 99 | expected = {'host': '127.0.0.1', 'user': 'mike', 'database': 'db1', 100 | 'ssl': False} 101 | parsed = parse_dsn(dsn) 102 | self.assertDictEqual(expected, parsed) 103 | 104 | def test_arguments_blank_values(self): 105 | dsn = ('vertica://mike@127.0.0.1/db1?connection_timeout=1.5&log_path=&' 106 | 'ssl=&connection_timeout=2&log_path=&connection_timeout=') 107 | expected = {'host': '127.0.0.1', 'user': 'mike', 'database': 'db1', 108 | 'connection_timeout': 2.0, 'log_path': ''} 109 | parsed = parse_dsn(dsn) 110 | self.assertDictEqual(expected, parsed) 111 | -------------------------------------------------------------------------------- /vertica_python/tests/unit_tests/test_sql_literal.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020-2024 Open Text. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import annotations 16 | 17 | from collections import namedtuple 18 | from decimal import Decimal 19 | from uuid import UUID 20 | import datetime 21 | import pytest 22 | 23 | from ...vertica.cursor import Cursor 24 | from .base import VerticaPythonUnitTestCase 25 | 26 | 27 | class SqlLiteralTestCase(VerticaPythonUnitTestCase): 28 | 29 | def test_default_adapters(self): 30 | cursor = Cursor(None, self.logger) 31 | # None 32 | self.assertEqual(cursor.object_to_sql_literal(None), "NULL") 33 | # Boolean 34 | self.assertEqual(cursor.object_to_sql_literal(True), "True") 35 | self.assertEqual(cursor.object_to_sql_literal(False), "False") 36 | # Numeric 37 | self.assertEqual(cursor.object_to_sql_literal(123), "123") 38 | self.assertEqual(cursor.object_to_sql_literal(123.45), "123.45") 39 | self.assertEqual(cursor.object_to_sql_literal(Decimal("10.00000")), "10.00000") 40 | # UUID 41 | self.assertEqual(cursor.object_to_sql_literal( 42 | UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')), 43 | "'00010203-0405-0607-0809-0a0b0c0d0e0f'") 44 | # Time 45 | self.assertEqual(cursor.object_to_sql_literal( 46 | datetime.datetime(2018, 9, 7, 15, 38, 19, 769000)), "'2018-09-07 15:38:19.769000'") 47 | self.assertEqual(cursor.object_to_sql_literal(datetime.date(2018, 9, 7)), "'2018-09-07'") 48 | self.assertEqual(cursor.object_to_sql_literal(datetime.time(13, 50, 9)), "'13:50:09'") 49 | # String 50 | self.assertEqual(cursor.object_to_sql_literal("string'1"), "'string''1'") 51 | self.assertEqual(cursor.object_to_sql_literal(b"string'1"), "'string''1'") 52 | # Tuple and namedtuple 53 | self.assertEqual(cursor.object_to_sql_literal( 54 | (123, "string'1", None)), "(123,'string''1',NULL)") 55 | self.assertEqual(cursor.object_to_sql_literal( 56 | ((1, "a"), (2, "b"), (3, "c"))), "((1,'a'),(2,'b'),(3,'c'))") 57 | Point = namedtuple('Point', ['x', 'y', 'z']) 58 | p = Point(x=11, y=22, z=33) 59 | self.assertEqual(cursor.object_to_sql_literal(p), "(11,22,33)") 60 | 61 | def test_register_adapters(self): 62 | class Point: 63 | def __init__(self, x, y): 64 | self.x = x 65 | self.y = y 66 | 67 | def adapt_point(point): 68 | return "STV_GeometryPoint({},{})".format(point.x, point.y) 69 | 70 | cursor = Cursor(None, self.logger) 71 | 72 | err_msg = "Please register a new adapter for this type" 73 | with pytest.raises(TypeError, match=err_msg): 74 | result = cursor.object_to_sql_literal(Point(-71.13, 42.36)) 75 | 76 | err_msg = "The adapter is not callable" 77 | with pytest.raises(TypeError, match=err_msg): 78 | cursor.register_sql_literal_adapter(Point, "not-callable") 79 | 80 | cursor.register_sql_literal_adapter(Point, adapt_point) 81 | self.assertEqual( 82 | cursor.object_to_sql_literal(Point(-71.13, 42.36)), 83 | "STV_GeometryPoint(-71.13,42.36)") 84 | -------------------------------------------------------------------------------- /vertica_python/tests/unit_tests/test_timestamps.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from collections import namedtuple 39 | from datetime import datetime 40 | 41 | from .base import VerticaPythonUnitTestCase 42 | from ...vertica.deserializer import load_timestamp_text 43 | 44 | TimestampTestingCase = namedtuple("TimestampTestingCase", ["string", "timestamp"]) 45 | 46 | 47 | class TimestampParsingTestCase(VerticaPythonUnitTestCase): 48 | def _test_timestamps(self, test_cases, msg=None): 49 | for tc in test_cases: 50 | self.assertEqual(load_timestamp_text(tc.string, None), tc.timestamp, msg=msg) 51 | 52 | def test_timestamp_second_resolution(self): 53 | test_cases = [ # back to the future dates 54 | TimestampTestingCase( 55 | '1985-10-26 01:25:01', 56 | datetime(year=1985, month=10, day=26, hour=1, minute=25, second=1) 57 | ), 58 | TimestampTestingCase( 59 | '1955-11-12 22:55:02', 60 | datetime(year=1955, month=11, day=12, hour=22, minute=55, second=2) 61 | ), 62 | TimestampTestingCase( 63 | '2015-10-21 11:12:03', 64 | datetime(year=2015, month=10, day=21, hour=11, minute=12, second=3) 65 | ), 66 | TimestampTestingCase( 67 | '1885-01-01 01:02:04', 68 | datetime(year=1885, month=1, day=1, hour=1, minute=2, second=4) 69 | ), 70 | TimestampTestingCase( 71 | '1885-09-02 02:03:05', 72 | datetime(year=1885, month=9, day=2, hour=2, minute=3, second=5) 73 | ), 74 | ] 75 | self._test_timestamps(test_cases=test_cases, msg='timestamp second resolution') 76 | 77 | def test_timestamp_microsecond_resolution(self): 78 | test_cases = [ # back to the future dates 79 | TimestampTestingCase( 80 | '1985-10-26 01:25:01.1', 81 | datetime(year=1985, month=10, day=26, hour=1, minute=25, second=1, 82 | microsecond=100000) 83 | ), 84 | TimestampTestingCase( 85 | '1955-11-12 22:55:02.01', 86 | datetime(year=1955, month=11, day=12, hour=22, minute=55, second=2, 87 | microsecond=10000) 88 | ), 89 | TimestampTestingCase( 90 | '2015-10-21 11:12:03.001', 91 | datetime(year=2015, month=10, day=21, hour=11, minute=12, second=3, 92 | microsecond=1000) 93 | ), 94 | TimestampTestingCase( 95 | '1885-01-01 01:02:04.000001', 96 | datetime(year=1885, month=1, day=1, hour=1, minute=2, second=4, 97 | microsecond=1) 98 | ), 99 | TimestampTestingCase( 100 | '1885-09-02 02:03:05.002343', 101 | datetime(year=1885, month=9, day=2, hour=2, minute=3, second=5, 102 | microsecond=2343) 103 | ), 104 | ] 105 | self._test_timestamps(test_cases=test_cases, msg='timestamp microsecond resolution') 106 | 107 | -------------------------------------------------------------------------------- /vertica_python/vertica/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | -------------------------------------------------------------------------------- /vertica_python/vertica/column.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | 37 | from __future__ import annotations 38 | 39 | from typing import TYPE_CHECKING, NamedTuple 40 | if TYPE_CHECKING: 41 | from typing import Optional 42 | 43 | from ..datatypes import getDisplaySize, getPrecision, getScale 44 | 45 | 46 | # Data of a particular SQL data type might be transmitted in either "text" format or "binary" format. 47 | # The desired format for any column is specified by a format code. 48 | class FormatCode: 49 | TEXT = 0 50 | BINARY = 1 51 | 52 | 53 | class ColumnTuple(NamedTuple): 54 | name: str 55 | type_code: int 56 | display_size: Optional[int] 57 | internal_size: int 58 | precision: Optional[int] 59 | scale: Optional[int] 60 | null_ok: bool 61 | 62 | 63 | class Column: 64 | def __init__(self, col) -> None: 65 | # Describe one query result column 66 | self.name = col['name'] 67 | self.type_code = col['data_type_oid'] 68 | self.type_name = col['data_type_name'] 69 | self.table_oid = col['table_oid'] 70 | self.schema_name = col['schema_name'] 71 | self.table_name = col['table_name'] 72 | self.attribute_number = col['attribute_number'] 73 | self.display_size = getDisplaySize(col['data_type_oid'], col['type_modifier']) 74 | self.internal_size = col['data_type_size'] 75 | self.precision = getPrecision(col['data_type_oid'], col['type_modifier']) 76 | self.scale = getScale(col['data_type_oid'], col['type_modifier']) 77 | self.null_ok = col['null_ok'] 78 | self.is_identity = col['is_identity'] 79 | self.format_code = col['format_code'] 80 | self.child_columns = None 81 | self.props = ColumnTuple(self.name, self.type_code, self.display_size, self.internal_size, 82 | self.precision, self.scale, self.null_ok) 83 | 84 | def add_child_column(self, col: Column) -> None: 85 | """ 86 | Complex types involve multiple columns arranged in a hierarchy of parents and children. 87 | Each parent column stores references to child columns in a list. 88 | """ 89 | if self.child_columns is None: 90 | self.child_columns = [] 91 | self.child_columns.append(col) 92 | 93 | def debug_info(self) -> str: 94 | childs = "" 95 | if self.child_columns: 96 | c = ", ".join([col.debug_info() for col in self.child_columns]) 97 | childs = f", child_columns=[{c}]" 98 | return (f"Column(name={self.name}, data_type_oid={self.type_code}, data_type_name={self.type_name}, " 99 | f"schema_name={self.schema_name}, table_name={self.table_name}, table_oid={self.table_oid}, " 100 | f"attribute_number={self.attribute_number}, precision={self.precision}, scale={self.scale}, " 101 | f"null_ok={self.null_ok}, is_identity={self.is_identity}, format_code={self.format_code}, " 102 | f"internal_size={self.internal_size}, display_size={self.display_size}{childs}" 103 | ")") 104 | 105 | def __str__(self): 106 | return str(self.props) 107 | 108 | def __repr__(self): 109 | return str(self.props) 110 | 111 | def __iter__(self): 112 | for prop in self.props: 113 | yield prop 114 | 115 | def __getitem__(self, key): 116 | return self.props[key] 117 | 118 | def __len__(self): 119 | return len(self.props) 120 | -------------------------------------------------------------------------------- /vertica_python/vertica/log.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | 37 | from __future__ import annotations 38 | 39 | import logging 40 | from typing import TYPE_CHECKING 41 | if TYPE_CHECKING: 42 | from typing import Union 43 | from ..os_utils import ensure_dir_exists 44 | 45 | class VerticaLogging: 46 | 47 | @classmethod 48 | def setup_logging(cls, logger_name: str, logfile: str, 49 | log_level: Union[int, str] = logging.INFO, 50 | context: str = '') -> None: 51 | logger = logging.getLogger(logger_name) 52 | logger.setLevel(log_level) 53 | 54 | if logfile: 55 | formatter = logging.Formatter( 56 | fmt=('%(asctime)s.%(msecs)03d [%(module)s] ' 57 | '{}/%(process)d:0x%(thread)x <%(levelname)s> ' 58 | '%(message)s'.format(context)), 59 | datefmt='%Y-%m-%d %H:%M:%S') 60 | ensure_dir_exists(logfile) 61 | file_handler = logging.FileHandler(logfile, encoding='utf-8') 62 | file_handler.setFormatter(formatter) 63 | logger.addHandler(file_handler) 64 | 65 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | 37 | from __future__ import annotations 38 | 39 | from ..messages import backend_messages 40 | from ..messages.backend_messages import * 41 | 42 | from ..messages import frontend_messages 43 | from ..messages.frontend_messages import * 44 | 45 | __all__ = backend_messages.__all__ + frontend_messages.__all__ 46 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from .authentication import Authentication 39 | from .backend_key_data import BackendKeyData 40 | from .bind_complete import BindComplete 41 | from .close_complete import CloseComplete 42 | from .command_complete import CommandComplete 43 | from .command_description import CommandDescription 44 | from .copy_done_response import CopyDoneResponse 45 | from .copy_in_response import CopyInResponse 46 | from .data_row import DataRow 47 | from .empty_query_response import EmptyQueryResponse 48 | from .end_of_batch_response import EndOfBatchResponse 49 | from .error_response import ErrorResponse 50 | from .load_balance_response import LoadBalanceResponse 51 | from .load_file import LoadFile 52 | from .no_data import NoData 53 | from .notice_response import NoticeResponse 54 | from .parameter_description import ParameterDescription 55 | from .parameter_status import ParameterStatus 56 | from .parse_complete import ParseComplete 57 | from .portal_suspended import PortalSuspended 58 | from .ready_for_query import ReadyForQuery 59 | from .row_description import RowDescription 60 | from .unknown import Unknown 61 | from .verify_files import VerifyFiles 62 | from .write_file import WriteFile 63 | 64 | __all__ = ['Authentication', 'BackendKeyData', 'BindComplete', 'CloseComplete', 65 | 'CommandComplete', 'CommandDescription', 'CopyDoneResponse', 'CopyInResponse', 'DataRow', 66 | 'EmptyQueryResponse', 'EndOfBatchResponse', 'ErrorResponse', 'LoadBalanceResponse', 67 | 'LoadFile', 'NoData', 'NoticeResponse', 'ParameterDescription', 'ParameterStatus', 68 | 'ParseComplete', 'PortalSuspended', 'ReadyForQuery', 'RowDescription', 69 | 'Unknown', 'VerifyFiles', 'WriteFile'] 70 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/authentication.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from struct import unpack 39 | 40 | from ..message import BackendMessage 41 | from .... import errors 42 | 43 | 44 | class Authentication(BackendMessage): 45 | message_id = b'R' 46 | 47 | OK = 0 48 | KERBEROS_V4 = 1 49 | KERBEROS_V5 = 2 50 | CLEARTEXT_PASSWORD = 3 51 | CRYPT_PASSWORD = 4 # obsolete 52 | MD5_PASSWORD = 5 53 | SCM_CREDENTIAL = 6 54 | GSS = 7 55 | GSS_CONTINUE = 8 56 | CHANGE_PASSWORD = 9 57 | PASSWORD_CHANGED = 10 # client doesn't do password changing, this should never be seen 58 | PASSWORD_GRACE = 11 59 | OAUTH = 12 60 | HASH = 65536 61 | HASH_MD5 = 65536 + 5 62 | HASH_SHA512 = 65536 + 512 63 | 64 | def __init__(self, data): 65 | BackendMessage.__init__(self) 66 | self.code, other = unpack('!I{0}s'.format(len(data) - 4), data) 67 | 68 | if self.code == self.CRYPT_PASSWORD: 69 | self.salt = other 70 | elif self.code in (self.MD5_PASSWORD, self.HASH_MD5): 71 | self.salt = other[:4] 72 | elif self.code in (self.HASH, self.HASH_SHA512): 73 | self.salt = other[:4] 74 | userSaltLen = unpack('!I', other[4:8])[0] 75 | if userSaltLen != 16: 76 | raise errors.MessageError( 77 | 'Received wrong user salt size: {}'.format(userSaltLen)) 78 | self.usersalt = unpack('!{0}s'.format(userSaltLen), other[8:])[0] 79 | elif self.code in [self.GSS_CONTINUE]: 80 | self.auth_data = other 81 | 82 | def __str__(self): 83 | return "Authentication: type={}".format(self.code) 84 | 85 | 86 | BackendMessage.register(Authentication) 87 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/backend_key_data.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from struct import unpack 39 | 40 | from ..message import BackendMessage 41 | 42 | 43 | class BackendKeyData(BackendMessage): 44 | message_id = b'K' 45 | 46 | def __init__(self, data): 47 | BackendMessage.__init__(self) 48 | unpacked = unpack('!2I', data) 49 | self.pid = unpacked[0] 50 | self.key = unpacked[1] 51 | 52 | def __str__(self): 53 | return "BackendKeyData: pid = {}, key = {}".format(self.pid, self.key) 54 | 55 | 56 | BackendMessage.register(BackendKeyData) 57 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/bind_complete.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from ..message import BackendMessage 39 | 40 | 41 | class BindComplete(BackendMessage): 42 | message_id = b'2' 43 | 44 | def __init__(self, data): 45 | BackendMessage.__init__(self) 46 | 47 | 48 | BackendMessage.register(BindComplete) 49 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/close_complete.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from ..message import BackendMessage 39 | 40 | 41 | class CloseComplete(BackendMessage): 42 | message_id = b'3' 43 | 44 | def __init__(self, data): 45 | BackendMessage.__init__(self) 46 | 47 | 48 | BackendMessage.register(CloseComplete) 49 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/command_complete.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | """ 37 | CommandComplete message 38 | 39 | The server prompt that indicates a command has completed. The command tag 40 | string is the name of the command that was run. 41 | """ 42 | 43 | from __future__ import annotations 44 | 45 | import re 46 | import warnings 47 | 48 | from struct import unpack 49 | 50 | from ..message import BackendMessage 51 | 52 | 53 | class CommandComplete(BackendMessage): 54 | message_id = b'C' 55 | 56 | def __init__(self, data): 57 | BackendMessage.__init__(self) 58 | data = unpack('{0}sx'.format(len(data) - 1), data)[0] 59 | try: 60 | self.command_tag = data.decode('utf-8') 61 | except Exception as e: 62 | # VER-86494 63 | warnings.warn( 64 | f"\n{'-'*70}\n" 65 | "Hit a known server bug (#493). To fix it,\n" 66 | "please upgrade your server to 12.0.4-3 or higher version.\n" 67 | f"{'-'*70}\n") 68 | self.command_tag = 'x' 69 | 70 | def __str__(self): 71 | return 'CommandComplete: command_tag = "{}"'.format(self.command_tag) 72 | 73 | 74 | BackendMessage.register(CommandComplete) 75 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/command_description.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | """ 37 | CommandDescription message -- part of the response to a Describe request message. 38 | 39 | This response informs the client about the type of command being executed. 40 | If the command is a parameterized INSERT statement, the copy_rewrite field may 41 | include a semantically-equivalent COPY STDIN statement. Clients can choose to 42 | run this statement instead to achieve better performance when loading many 43 | batches of parameters. 44 | """ 45 | 46 | from __future__ import annotations 47 | 48 | from struct import unpack 49 | 50 | from ..message import BackendMessage 51 | 52 | 53 | class CommandDescription(BackendMessage): 54 | message_id = b'm' 55 | 56 | def __init__(self, data): 57 | BackendMessage.__init__(self) 58 | pos = data.find(b'\x00') 59 | unpacked = unpack("!{0}sxH{1}sx".format(pos, len(data) - pos - 4), data) 60 | 61 | self.command_tag = unpacked[0].decode('utf-8') 62 | self.has_copy_rewrite = (unpacked[1] == 1) 63 | self.copy_rewrite = unpacked[2].decode('utf-8') 64 | 65 | def __str__(self): 66 | return ('CommandDescription: command_tag = "{}", has_copy_rewrite = {},' 67 | ' copy_rewrite = "{}"'.format( 68 | self.command_tag, self.has_copy_rewrite, self.copy_rewrite)) 69 | 70 | 71 | BackendMessage.register(CommandDescription) 72 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/copy_done_response.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020-2024 Open Text. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | from __future__ import annotations 17 | 18 | from ..message import BackendMessage 19 | 20 | 21 | class CopyDoneResponse(BackendMessage): 22 | message_id = b'c' 23 | 24 | def __init__(self, data): 25 | BackendMessage.__init__(self) 26 | 27 | 28 | BackendMessage.register(CopyDoneResponse) 29 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/copy_in_response.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from struct import unpack 39 | 40 | from ..message import BackendMessage 41 | 42 | 43 | class CopyInResponse(BackendMessage): 44 | message_id = b'G' 45 | 46 | def __init__(self, data): 47 | BackendMessage.__init__(self) 48 | values = unpack('!B{0}H'.format((len(data) - 1) // 2), data) 49 | self.format = values[0] 50 | self.column_formats = values[2::] 51 | 52 | 53 | BackendMessage.register(CopyInResponse) 54 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/data_row.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from struct import unpack_from 39 | 40 | from ..message import BackendMessage 41 | 42 | 43 | class DataRow(BackendMessage): 44 | message_id = b'D' 45 | 46 | def __init__(self, data): 47 | BackendMessage.__init__(self) 48 | field_count = unpack_from('!H', data, 0)[0] 49 | self.values = [None] * field_count 50 | pos = 2 51 | 52 | for i in range(field_count): 53 | size = unpack_from('!i', data, pos)[0] 54 | pos += 4 55 | 56 | if size != -1: 57 | self.values[i] = data[pos : pos + size] 58 | pos += size 59 | 60 | 61 | BackendMessage.register(DataRow) 62 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/empty_query_response.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from ..message import BackendMessage 39 | 40 | 41 | class EmptyQueryResponse(BackendMessage): 42 | message_id = b'I' 43 | 44 | def __init__(self, data): 45 | BackendMessage.__init__(self) 46 | 47 | 48 | BackendMessage.register(EmptyQueryResponse) 49 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/end_of_batch_response.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020-2024 Open Text. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | from __future__ import annotations 17 | 18 | from ..message import BackendMessage 19 | 20 | 21 | class EndOfBatchResponse(BackendMessage): 22 | message_id = b'J' 23 | 24 | def __init__(self, data): 25 | BackendMessage.__init__(self) 26 | 27 | 28 | BackendMessage.register(EndOfBatchResponse) 29 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/error_response.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from ..message import BackendMessage 39 | from vertica_python.vertica.messages.backend_messages.notice_response import NoticeResponse 40 | 41 | 42 | class ErrorResponse(NoticeResponse, BackendMessage): 43 | message_id = b'E' 44 | 45 | def __str__(self): 46 | return "ErrorResponse: {}".format(self.error_message()) 47 | 48 | 49 | BackendMessage.register(ErrorResponse) 50 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/load_balance_response.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from ..message import BackendMessage 39 | from struct import unpack 40 | 41 | 42 | class LoadBalanceResponse(BackendMessage): 43 | message_id = b'Y' 44 | 45 | def __init__(self, data): 46 | BackendMessage.__init__(self) 47 | unpacked = unpack('!I{0}sx'.format(len(data) - 5), data) 48 | self.port = unpacked[0] 49 | self.host = unpacked[1].decode('utf-8') 50 | 51 | def get_port(self) -> int: 52 | return self.port 53 | 54 | def get_host(self) -> str: 55 | return self.host 56 | 57 | def __str__(self): 58 | return "LoadBalanceResponse: host={}, port={}".format(self.host, self.port) 59 | 60 | 61 | BackendMessage.register(LoadBalanceResponse) 62 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/load_file.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020-2024 Open Text. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | from __future__ import annotations 17 | 18 | from struct import unpack 19 | 20 | from ..message import BackendMessage 21 | 22 | 23 | class LoadFile(BackendMessage): 24 | message_id = b'H' 25 | 26 | def __init__(self, data): 27 | BackendMessage.__init__(self) 28 | unpacked = unpack('!{0}sx'.format(data.find(b'\x00')), data) 29 | self.filename = unpacked[0].decode('utf-8') 30 | 31 | def __str__(self): 32 | return "LoadFile: name = {}".format(self.filename) 33 | 34 | 35 | BackendMessage.register(LoadFile) 36 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/no_data.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from ..message import BackendMessage 39 | 40 | 41 | class NoData(BackendMessage): 42 | message_id = b'n' 43 | 44 | def __init__(self, data): 45 | BackendMessage.__init__(self) 46 | 47 | 48 | BackendMessage.register(NoData) 49 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/notice_response.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from struct import unpack_from 39 | 40 | from ...mixins.notice_response_attr import _NoticeResponseAttrMixin 41 | from ..message import BackendMessage 42 | 43 | 44 | class NoticeResponse(_NoticeResponseAttrMixin, BackendMessage): 45 | message_id = b'N' 46 | 47 | def __init__(self, data): 48 | BackendMessage.__init__(self) 49 | # `_notice_attrs` is required by _NoticeResponseAttrMixin and also used 50 | # by QueryError 51 | self._notice_attrs = NoticeResponse._unpack_data(data) 52 | 53 | def error_message(self): 54 | return ', '.join([ 55 | "{0}: {1}".format(name, value) 56 | for (name, value) in self.values.items() 57 | ]) 58 | 59 | def __str__(self): 60 | return "NoticeResponse: {}".format(self.error_message()) 61 | 62 | @property 63 | def values(self): 64 | """ 65 | A mapping of server-provided values describing this notice. 66 | 67 | The keys of this mapping are user-facing strings. The contents of any 68 | given NoticeResponse can vary based on the context or version of 69 | Vertica. 70 | 71 | For access to specific values, the appropriate property getter is 72 | recommended. 73 | 74 | Example return value: 75 | 76 | ``` 77 | { 78 | 'Severity': 'ERROR', 79 | 'Message': 'Syntax error at or near "foobar"', 80 | 'Sqlstate': '42601', 81 | 'Position': '1', 82 | 'Routine': 'base_yyerror', 83 | 'File': '/data/.../vertica/Parser/scan.l', 84 | 'Line': '1043', 85 | 'Error Code': '4856' 86 | } 87 | ``` 88 | """ 89 | return self._get_labeled_values() 90 | 91 | @staticmethod 92 | def _unpack_data(data): 93 | data_mapping = {} 94 | 95 | pos = 0 96 | while pos < len(data) - 1: 97 | null_byte = data.find(b'\x00', pos) 98 | 99 | unpacked = unpack_from('c{0}sx'.format(null_byte - 1 - pos), data, pos) 100 | key = unpacked[0] 101 | value = unpacked[1] 102 | data_mapping[key] = value.decode('utf-8', 'backslashreplace') 103 | 104 | pos += (len(value) + 2) 105 | 106 | return data_mapping 107 | 108 | BackendMessage.register(NoticeResponse) 109 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/parameter_description.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from struct import unpack, unpack_from, calcsize 39 | 40 | from ..message import BackendMessage 41 | from ....datatypes import getTypeName 42 | 43 | 44 | class ParameterDescription(BackendMessage): 45 | message_id = b't' 46 | 47 | def __init__(self, data): 48 | BackendMessage.__init__(self) 49 | self.parameters = [] 50 | self.parameter_count = unpack('!H', data[0:2])[0] 51 | if self.parameter_count == 0: 52 | return 53 | 54 | # read type pool 55 | # used for special types e.g. GEOMETRY, GEOGRAPHY 56 | user_types = [] 57 | type_pool_count = unpack('!I', data[2:6])[0] 58 | pos = 6 59 | for _ in range(type_pool_count): 60 | base_type_oid = unpack('!I', data[pos:(pos + 4)])[0] 61 | pos += 4 62 | type_name = unpack_from("!{0}sx".format(data.find(b'\x00', pos) - pos), data, pos)[0] 63 | pos += len(type_name) + 1 64 | user_types.append((base_type_oid, type_name)) 65 | 66 | # read info of each parameter 67 | offset = calcsize("!BIiH") 68 | for _ in range(self.parameter_count): 69 | field_info = unpack_from("!BIiH", data, pos) 70 | pos += offset 71 | 72 | if field_info[0] == 1: 73 | data_type_oid, data_type_name = user_types[field_info[1]] 74 | else: 75 | data_type_oid = field_info[1] 76 | data_type_name = getTypeName(data_type_oid, field_info[2]) 77 | 78 | self.parameters.append({ 79 | 'data_type_oid': data_type_oid, 80 | 'data_type_name': data_type_name, 81 | 'type_modifier': field_info[2], 82 | 'null_ok': field_info[3] != 1, 83 | }) 84 | 85 | def __str__(self): 86 | return "ParameterDescription: {}".format(self.parameters) 87 | 88 | 89 | BackendMessage.register(ParameterDescription) 90 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/parameter_status.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | """ 37 | ParameterStatus message 38 | 39 | A ParameterStatus message will be generated whenever the backend believes the 40 | frontend should know about a setting parameter value. For example, when you do 41 | SET SESSION AUTOCOMMIT ON | OFF, you get back a parameter status telling you the 42 | new value of autocommit. 43 | 44 | At present Vertica supports a handful of parameters, they are: 45 | standard_conforming_strings, server_version, client_locale, client_label, 46 | long_string_types, protocol_version, auto_commit, MARS 47 | 48 | More parameters would be added in the future. Accordingly, a frontend should 49 | simply ignore ParameterStatus for parameters that it does not understand or care 50 | about. 51 | """ 52 | 53 | from __future__ import annotations 54 | 55 | from struct import unpack 56 | 57 | from ..message import BackendMessage 58 | 59 | 60 | class ParameterStatus(BackendMessage): 61 | message_id = b'S' 62 | 63 | def __init__(self, data): 64 | BackendMessage.__init__(self) 65 | null_byte = data.find(b'\x00') 66 | unpacked = unpack('{0}sx{1}sx'.format(null_byte, len(data) - null_byte - 2), data) 67 | self.name = unpacked[0].decode('utf-8') 68 | self.value = unpacked[1].decode('utf-8') 69 | 70 | def __str__(self): 71 | return "ParameterStatus: {} = {}".format(self.name, self.value) 72 | 73 | 74 | BackendMessage.register(ParameterStatus) 75 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/parse_complete.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from ..message import BackendMessage 39 | 40 | 41 | class ParseComplete(BackendMessage): 42 | message_id = b'1' 43 | 44 | def __init__(self, data): 45 | BackendMessage.__init__(self) 46 | 47 | 48 | BackendMessage.register(ParseComplete) 49 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/portal_suspended.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | """ 37 | PortalSuspended message 38 | 39 | A PortalSuspended message indicates that a portal has stopped execution. 40 | Vertica does not support portals in the same way postgres does. A portal is 41 | never truly "suspended" because Vertica always returns all results, regardless 42 | of how many were requested in a Bind message. This effectively means 43 | PortalSuspended has the same meaning as a CommandComplete message. The only 44 | meaningful difference being PortalSuspended occurs during the extended query 45 | protocol, while CommandComplete happens with the simple query protocol. 46 | In the future, Vertica may change to restore semantics more similar to those 47 | intended by Postgres. 48 | """ 49 | 50 | from __future__ import annotations 51 | 52 | from ..message import BackendMessage 53 | 54 | 55 | class PortalSuspended(BackendMessage): 56 | message_id = b's' 57 | 58 | def __init__(self, data): 59 | BackendMessage.__init__(self) 60 | 61 | 62 | BackendMessage.register(PortalSuspended) 63 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/ready_for_query.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | """ 37 | ReadyForQuery message 38 | 39 | The backend informs the frontend that it may safely send a new command. 40 | The ReadyForQuery message is the same one that the backend will issue after each 41 | command cycle. 42 | """ 43 | 44 | from __future__ import annotations 45 | 46 | from struct import unpack 47 | 48 | from ..message import BackendMessage 49 | 50 | 51 | class ReadyForQuery(BackendMessage): 52 | message_id = b'Z' 53 | 54 | STATUSES = { 55 | b'I': 'no_transaction', 56 | b'T': 'in_transaction', 57 | b'E': 'failed_transaction' 58 | } 59 | 60 | def __init__(self, data): 61 | BackendMessage.__init__(self) 62 | self.transaction_status = self.STATUSES[unpack('c', data)[0]] 63 | 64 | def __str__(self): 65 | return "ReadyForQuery: status = {}".format(self.transaction_status) 66 | 67 | 68 | BackendMessage.register(ReadyForQuery) 69 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/unknown.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from ..message import BackendMessage 39 | 40 | 41 | class Unknown(BackendMessage): 42 | def __init__(self, message_id, data): 43 | BackendMessage.__init__(self) 44 | self._message_id = message_id 45 | self.data = data 46 | 47 | @property 48 | def message_id(self): 49 | return self._message_id 50 | 51 | def __str__(self): 52 | return 'Unknown: message_id = {}, data = {}'.format( 53 | self._message_id, repr(self.data)) 54 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/verify_files.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020-2024 Open Text. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | """ 17 | VerifyFiles message 18 | 19 | VerifyFiles message is sent by the server when the client issues 20 | a COPY FROM LOCAL command. The server parses the file names out 21 | of the command, and sends them back to the client in this message. 22 | The client has to verify that these files exist and are readable 23 | before running the copy. 24 | """ 25 | 26 | from __future__ import annotations 27 | 28 | from struct import unpack_from 29 | 30 | from ..message import BackendMessage 31 | 32 | 33 | class VerifyFiles(BackendMessage): 34 | message_id = b'F' 35 | 36 | def __init__(self, data): 37 | BackendMessage.__init__(self) 38 | files_count = unpack_from('!H', data, 0)[0] 39 | self.input_files = [None] * files_count 40 | pos = 2 41 | for i in range(files_count): 42 | filename = unpack_from("!{0}sx".format(data.find(b'\x00', pos) - pos), data, pos)[0] 43 | self.input_files[i] = filename.decode('utf-8') 44 | pos += len(filename) + 1 45 | 46 | filename = unpack_from("!{0}sx".format(data.find(b'\x00', pos) - pos), data, pos)[0] 47 | self.rejections_file = filename.decode('utf-8') 48 | pos += len(filename) + 1 49 | 50 | filename = unpack_from("!{0}sx".format(data.find(b'\x00', pos) - pos), data, pos)[0] 51 | self.exceptions_file = filename.decode('utf-8') 52 | 53 | def __str__(self): 54 | return "VerifyFiles: InputFiles = {}, RejectedDataFile = {}, ExceptionsFile = {}".format( 55 | self.input_files, self.rejections_file, self.exceptions_file) 56 | 57 | 58 | BackendMessage.register(VerifyFiles) 59 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/backend_messages/write_file.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020-2024 Open Text. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | """ 17 | WriteFile message 18 | 19 | In the copy-local protocol, the server may send a WriteFile message when it 20 | receives a batch of copy data. If the COPY FROM LOCAL command uses the 21 | REJECTED DATA and/or EXCEPTIONS parameters, this message contains content of 22 | rejected rows or exceptions output files. If the command uses the 23 | RETURNREJECTED parameters instead, this message is a series of row numbers 24 | saying which rows in the load were rejected. 25 | """ 26 | 27 | from __future__ import annotations 28 | 29 | from struct import unpack_from 30 | 31 | from ..message import BackendMessage 32 | 33 | 34 | class WriteFile(BackendMessage): 35 | message_id = b'O' 36 | 37 | def __init__(self, filename, file_length, data=None): 38 | BackendMessage.__init__(self) 39 | self.filename = filename 40 | self.file_length = file_length 41 | 42 | # Parse RETURNREJECTED data 43 | if self.filename == '': 44 | row_count = self.file_length // 8 45 | # Rejected row numbers come in little endian format 46 | self.rejected_rows = unpack_from('<{0}Q'.format(row_count), data) 47 | 48 | def write_to_disk(self, connection, buffer_size): 49 | # Read the rest of the message from wire and write the file 50 | bytes_left = self.file_length 51 | with open(self.filename, 'ab') as f: 52 | pos = 0 53 | while bytes_left > 0: 54 | bytes_to_read = min(buffer_size, bytes_left) 55 | content = connection.read_bytes(bytes_to_read) 56 | f.write(content) 57 | bytes_left -= bytes_to_read 58 | 59 | def __str__(self): 60 | return "WriteFile: Filename = {}, FileLength = {}".format(self.filename, self.file_length) 61 | 62 | 63 | BackendMessage.register(WriteFile) 64 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/frontend_messages/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | 37 | from __future__ import annotations 38 | 39 | from .bind import Bind 40 | from .cancel_request import CancelRequest 41 | from .close import Close 42 | from .copy_data import CopyData 43 | from .copy_done import CopyDone 44 | from .copy_error import CopyError 45 | from .copy_fail import CopyFail 46 | from .describe import Describe 47 | from .end_of_batch_request import EndOfBatchRequest 48 | from .execute import Execute 49 | from .flush import Flush 50 | from .load_balance_request import LoadBalanceRequest 51 | from .parse import Parse 52 | from .password import Password 53 | from .query import Query 54 | from .ssl_request import SslRequest 55 | from .startup import Startup 56 | from .sync import Sync 57 | from .terminate import Terminate 58 | from .verified_files import VerifiedFiles 59 | 60 | __all__ = ['Bind', 'CancelRequest', 'Close', 'CopyData', 'CopyDone', 'CopyError', 61 | 'CopyFail', 'Describe', 'EndOfBatchRequest', 'Execute', 'Flush', 62 | 'LoadBalanceRequest', 'Parse', 'Password', 'Query', 'SslRequest', 'Startup', 63 | 'Sync', 'Terminate', 'VerifiedFiles'] 64 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/frontend_messages/bind.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | """ 37 | Bind message 38 | 39 | In the extended query protocol, the frontend sends a Bind message to bind values 40 | to parameter placeholders present in an existing prepared statement. 41 | 42 | The response is either BindComplete or ErrorResponse. 43 | """ 44 | 45 | from __future__ import annotations 46 | 47 | from struct import pack 48 | 49 | from ..message import BulkFrontendMessage 50 | from ....datatypes import VerticaType 51 | from ....compat import as_bytes 52 | 53 | BACKSLASH = b'\\' 54 | BACKSLASH_ESCAPE = b'\\134' 55 | 56 | 57 | class Bind(BulkFrontendMessage): 58 | message_id = b'B' 59 | 60 | def __init__(self, portal_name: str, prepared_statement_name: str, parameter_values, 61 | parameter_type_oids, binary_transfer: bool) -> None: 62 | BulkFrontendMessage.__init__(self) 63 | self._portal_name = portal_name 64 | self._prepared_statement_name = prepared_statement_name 65 | self._parameter_values = parameter_values 66 | self._parameter_type_oids = parameter_type_oids 67 | self._binary_transfer = binary_transfer 68 | 69 | def read_bytes(self): 70 | utf_portal_name = self._portal_name.encode('utf-8') 71 | utf_prepared_statement_name = self._prepared_statement_name.encode('utf-8') 72 | 73 | bytes_ = pack('!{0}sx{1}sx'.format(len(utf_portal_name), len(utf_prepared_statement_name)), 74 | utf_portal_name, utf_prepared_statement_name) 75 | 76 | # Parameter format codes -- use the default format (text) 77 | bytes_ += pack('!H', 0) 78 | 79 | # Number of parameters 80 | bytes_ += pack('!H', len(self._parameter_type_oids)) 81 | 82 | param_bytes_ = b'' 83 | for oid, val in zip(self._parameter_type_oids, self._parameter_values): 84 | # Parameter type oids 85 | bytes_ += pack('!I', oid) 86 | # Parameter values 87 | if val is None: # -1 indicates a NULL parameter value 88 | param_bytes_ += pack('!i', -1) 89 | elif oid in (VerticaType.BINARY, VerticaType.VARBINARY, VerticaType.LONGVARBINARY): 90 | # Encode binary data as UTF8 bytes 91 | val = as_bytes(val) 92 | # Escape the byte value \ with "\134"(octal for backslash) 93 | val = val.replace(BACKSLASH, BACKSLASH_ESCAPE) 94 | param_bytes_ += pack('!I{0}s'.format(len(val)), len(val), val) 95 | else: 96 | # Convert input to string 97 | if oid == VerticaType.BOOL: 98 | val = '1' if str(val).lower() in ('t', 'true', 'y', 'yes', '1') else '0' 99 | elif not isinstance(val, (str, bytes)): 100 | val = str(val) 101 | # Encode string as UTF8 bytes 102 | val = val.encode('utf-8') if not isinstance(val, bytes) else val 103 | param_bytes_ += pack('!I{0}s'.format(len(val)), len(val), val) 104 | 105 | bytes_ += param_bytes_ 106 | 107 | # Result column transfer format 108 | if self._binary_transfer: 109 | bytes_ += pack('!H', 1) # Specify the number of format codes followed 110 | bytes_ += pack('!H', 1) # Use binary format for all result columns 111 | else: 112 | # Use the default format (text) for all result columns 113 | bytes_ += pack('!H', 0) 114 | 115 | return bytes_ 116 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/frontend_messages/cancel_request.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | """ 37 | CancelRequest message 38 | 39 | The frontend sends a CancelRequest message to cancel the processing of the 40 | current operation. The cancel request must be sent across a new connection to 41 | the server. The server will process this request and then close the connection. 42 | 43 | The cancel request might or might not have any effect. If the cancellation is 44 | effective, the current command will terminate early and return an error message. 45 | If the cancellation fails (e.g. the server has finished processing the command), 46 | then there will be no visible result at all. 47 | """ 48 | 49 | from __future__ import annotations 50 | 51 | from struct import pack 52 | 53 | from ..message import BulkFrontendMessage 54 | 55 | 56 | class CancelRequest(BulkFrontendMessage): 57 | message_id = None 58 | 59 | def __init__(self, backend_pid, backend_key): 60 | BulkFrontendMessage.__init__(self) 61 | self._backend_pid = backend_pid # The process ID of the target backend 62 | self._backend_key = backend_key # The secret key of the target backend 63 | 64 | def read_bytes(self): 65 | bytes_ = pack('!3I', 80877102, self._backend_pid, self._backend_key) 66 | return bytes_ 67 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/frontend_messages/close.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | """ 37 | Close message 38 | 39 | In the extended query protocol, the frontend sends a Close message to close an 40 | existing prepared statement or portal and release resources. 41 | 42 | The response is either CloseComplete or ErrorResponse. It is not an error to 43 | issue Close against a nonexistent statement or portal name. 44 | """ 45 | 46 | from __future__ import annotations 47 | 48 | from struct import pack 49 | 50 | from ..message import BulkFrontendMessage 51 | 52 | 53 | class Close(BulkFrontendMessage): 54 | message_id = b'C' 55 | 56 | def __init__(self, close_type, close_name): 57 | BulkFrontendMessage.__init__(self) 58 | 59 | self._close_name = close_name 60 | 61 | if close_type == 'portal': 62 | self._close_type = b'P' 63 | elif close_type == 'prepared_statement': 64 | self._close_type = b'S' 65 | else: 66 | raise ValueError("{0} is not a valid close_type. " 67 | "Must be either portal or prepared_statement".format(close_type)) 68 | 69 | def read_bytes(self): 70 | utf_close_name = self._close_name.encode('utf-8') 71 | bytes_ = pack('c{0}sx'.format(len(utf_close_name)), self._close_type, utf_close_name) 72 | return bytes_ 73 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/frontend_messages/copy_data.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from ..message import BulkFrontendMessage 39 | 40 | 41 | class CopyData(BulkFrontendMessage): 42 | message_id = b'd' 43 | 44 | def __init__(self, data, unicode_error='strict'): 45 | BulkFrontendMessage.__init__(self) 46 | if isinstance(data, str): 47 | self.bytes_ = data.encode(encoding='utf-8', errors=unicode_error) 48 | elif isinstance(data, bytes): 49 | self.bytes_ = data 50 | else: 51 | raise TypeError("Data should be string or bytes") 52 | 53 | def read_bytes(self): 54 | return self.bytes_ 55 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/frontend_messages/copy_done.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from ..message import BulkFrontendMessage 39 | 40 | 41 | class CopyDone(BulkFrontendMessage): 42 | message_id = b'c' 43 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/frontend_messages/copy_error.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020-2024 Open Text. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """ 16 | CopyError message 17 | 18 | In the copy-local protocol, the frontend can terminate the cycle by sending a 19 | CopyError message, which will cause the COPY SQL statement to fail with an error. 20 | """ 21 | 22 | from __future__ import annotations 23 | 24 | from struct import pack 25 | 26 | from ..message import BulkFrontendMessage 27 | 28 | 29 | class CopyError(BulkFrontendMessage): 30 | message_id = b'e' 31 | 32 | def __init__(self, error_msg, stack_trace=None): 33 | BulkFrontendMessage.__init__(self) 34 | self.error_msg = error_msg.encode('utf-8') 35 | self.file_name = stack_trace[0].encode('utf-8') if stack_trace else b'' 36 | self.line_number = stack_trace[1] if stack_trace else 0 37 | self.func_name = stack_trace[2].encode('utf-8') if stack_trace else b'' 38 | 39 | def read_bytes(self): 40 | bytes_ = pack('!{0}sxI{1}sx{2}sx'.format( 41 | len(self.file_name), len(self.func_name), len(self.error_msg)), 42 | self.file_name, self.line_number, self.func_name, self.error_msg) 43 | return bytes_ 44 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/frontend_messages/copy_fail.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | """ 37 | CopyFail message 38 | 39 | In the copy-in protocol, the frontend can terminate the cycle by sending a 40 | CopyFail message, which will cause the COPY SQL statement to fail with an error. 41 | """ 42 | 43 | from __future__ import annotations 44 | 45 | from struct import pack 46 | 47 | from ..message import BulkFrontendMessage 48 | 49 | 50 | class CopyFail(BulkFrontendMessage): 51 | message_id = b'f' 52 | 53 | def __init__(self, error_message): 54 | BulkFrontendMessage.__init__(self) 55 | # An error message to report as the cause of failure 56 | self._error_message = error_message.encode('utf-8') 57 | 58 | def read_bytes(self): 59 | bytes_ = pack('{0}sx'.format(len(self._error_message)), self._error_message) 60 | return bytes_ 61 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/frontend_messages/describe.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | """ 37 | Describe message 38 | 39 | In the extended query protocol, the frontend sends a Describe message, which 40 | specifies the name of an existing prepared statement. 41 | 42 | The first response is a ParameterDescription message describing the parameters 43 | needed by the statement. The second response is a RowDescription message 44 | describing the rows that will be returned when the statement is eventually 45 | executed (or a NoData message if the statement will not return rows). The third 46 | response is a CommandDescription message describing the type of command to be 47 | executed and any semantically-equivalent COPY statement. 48 | """ 49 | 50 | from __future__ import annotations 51 | 52 | from struct import pack 53 | 54 | from ..message import BulkFrontendMessage 55 | 56 | 57 | class Describe(BulkFrontendMessage): 58 | message_id = b'D' 59 | 60 | def __init__(self, describe_type, describe_name): 61 | BulkFrontendMessage.__init__(self) 62 | 63 | self._describe_name = describe_name 64 | 65 | if describe_type == 'portal': 66 | self._describe_type = b'P' 67 | elif describe_type == 'prepared_statement': 68 | self._describe_type = b'S' 69 | else: 70 | raise ValueError("{0} is not a valid describe_type. " 71 | "Must be either portal or prepared_statement".format(describe_type)) 72 | 73 | def read_bytes(self): 74 | utf_name = self._describe_name.encode('utf-8') 75 | bytes_ = pack('c{0}sx'.format(len(utf_name)), self._describe_type, utf_name) 76 | return bytes_ 77 | 78 | def __str__(self): 79 | return 'Describe: type = {}, name = "{}"'.format( 80 | 'Portal' if self._describe_type == b'P' else 'Prepared Statement' , self._describe_name) 81 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/frontend_messages/end_of_batch_request.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020-2024 Open Text. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | """ 17 | EndOfBatchRequest message 18 | 19 | EndOfBatchRequest message signals that a batch of rows has been sent, and 20 | the frontend is expecting an acknowledgment and possibly rejected row 21 | descriptions from the backend. 22 | """ 23 | 24 | from __future__ import annotations 25 | 26 | from ..message import BulkFrontendMessage 27 | 28 | 29 | class EndOfBatchRequest(BulkFrontendMessage): 30 | message_id = b'j' 31 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/frontend_messages/execute.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | """ 37 | Execute message 38 | 39 | In the extended query protocol, the frontend sends a Execute message once a 40 | portal exists. Execute doesn't cause RowDescription response message to be 41 | issued, so the frontend should issue Describe before issuing Execute, to ensure 42 | that it knows how to interpret the result rows it will get back. 43 | 44 | The Execute message specifies the portal name and a maximum result-row count. 45 | Currently, Vertica backend will ignore this result-row count and send all the 46 | rows regardless of what you put here. 47 | """ 48 | 49 | from __future__ import annotations 50 | 51 | from struct import pack 52 | 53 | from ..message import BulkFrontendMessage 54 | 55 | 56 | class Execute(BulkFrontendMessage): 57 | message_id = b'E' 58 | 59 | def __init__(self, portal_name, max_rows): 60 | BulkFrontendMessage.__init__(self) 61 | self._portal_name = portal_name 62 | self._max_rows = max_rows 63 | 64 | def read_bytes(self): 65 | utf_portal_name = self._portal_name.encode('utf-8') 66 | bytes_ = pack('!{0}sxI'.format(len(utf_portal_name)), utf_portal_name, self._max_rows) 67 | return bytes_ 68 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/frontend_messages/flush.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | """ 37 | Flush message 38 | 39 | The Flush message does not cause any specific output to be generated, but forces 40 | the backend to deliver any data pending in its output buffers. For example, in 41 | the extended query protocol, a Flush must be sent after any extended-query 42 | command except Sync, if the frontend wishes to examine the results of that 43 | command before issuing more commands. 44 | """ 45 | 46 | from __future__ import annotations 47 | 48 | from ..message import BulkFrontendMessage 49 | 50 | 51 | class Flush(BulkFrontendMessage): 52 | message_id = b'H' 53 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/frontend_messages/load_balance_request.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from struct import pack 39 | 40 | from ..message import BulkFrontendMessage 41 | 42 | 43 | class LoadBalanceRequest(BulkFrontendMessage): 44 | message_id = None 45 | LOADBALANCE_REQUEST = 80936960 46 | 47 | def read_bytes(self): 48 | bytes_ = pack('!I', self.LOADBALANCE_REQUEST) 49 | return bytes_ 50 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/frontend_messages/parse.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | """ 37 | Parse message 38 | 39 | In the extended query protocol, the frontend first sends a Parse message, which 40 | contains a textual query string. The query string leaves certain values 41 | unspecified with parameter placeholders (i.e. question mark '?'). 42 | 43 | The response is either ParseComplete or ErrorResponse. The query string cannot 44 | include more than one SQL statement; else an ErrorResponse is reported. The 45 | error message would be something like 46 | "Cannot insert multiple commands into a prepared statement" 47 | """ 48 | 49 | from __future__ import annotations 50 | 51 | from struct import pack 52 | 53 | from ..message import BulkFrontendMessage 54 | 55 | 56 | class Parse(BulkFrontendMessage): 57 | message_id = b'P' 58 | 59 | def __init__(self, name, query, param_types): 60 | BulkFrontendMessage.__init__(self) 61 | 62 | self._name = name 63 | self._query = query 64 | self._param_types = param_types 65 | 66 | def read_bytes(self): 67 | utf_name = self._name.encode('utf-8') 68 | utf_query = self._query.encode('utf-8') 69 | 70 | bytes_ = pack('!{0}sx{1}sxH'.format(len(utf_name), len(utf_query)), 71 | utf_name, utf_query, len(self._param_types)) 72 | 73 | for param in self._param_types: 74 | bytes_ += pack('!I', param) 75 | 76 | return bytes_ 77 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/frontend_messages/password.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | import hashlib 39 | from struct import pack 40 | 41 | from ..message import BulkFrontendMessage 42 | from ..backend_messages.authentication import Authentication 43 | from ....compat import as_bytes 44 | 45 | from . import crypt_windows as crypt 46 | 47 | 48 | class Password(BulkFrontendMessage): 49 | message_id = b'p' 50 | 51 | def __init__(self, password, auth_method=None, options=None): 52 | BulkFrontendMessage.__init__(self) 53 | 54 | self._password = as_bytes(password) 55 | self._options = options or {} 56 | if auth_method is not None: 57 | self._auth_method = auth_method 58 | else: 59 | self._auth_method = Authentication.CLEARTEXT_PASSWORD 60 | 61 | def encoded_password(self): 62 | if self._auth_method == Authentication.CLEARTEXT_PASSWORD: 63 | return self._password 64 | elif self._auth_method == Authentication.CRYPT_PASSWORD: 65 | return crypt.crypt(self._password, self._options['salt']) 66 | elif self._auth_method in (Authentication.MD5_PASSWORD, 67 | Authentication.HASH, 68 | Authentication.HASH_MD5, 69 | Authentication.HASH_SHA512): 70 | # Encodes user/password/salt information in the following way: 71 | # MD5(MD5(password + user) + salt) 72 | # SHA512(SHA512(password + userSalt) + salt) 73 | useMD5 = self._auth_method in (Authentication.MD5_PASSWORD, Authentication.HASH_MD5) 74 | user = self._options['user'].encode('utf-8') if useMD5 else self._options['usersalt'] 75 | for key in (user, self._options['salt']): 76 | m = hashlib.md5() if useMD5 else hashlib.sha512() 77 | m.update(self._password + key) 78 | hexdigest = m.hexdigest() 79 | self._password = hexdigest.encode('utf-8') 80 | prefix = b'md5' if useMD5 else b'sha512' 81 | return prefix + self._password 82 | elif self._auth_method == Authentication.GSS: 83 | return self._password 84 | elif self._auth_method == Authentication.OAUTH: 85 | return self._password 86 | else: 87 | raise ValueError(f"unsupported authentication method: {self._auth_method}") 88 | 89 | def read_bytes(self): 90 | encoded_pw = self.encoded_password() 91 | # Vertica server handles GSS messages differently from other passwords 92 | if self._auth_method == Authentication.GSS: 93 | bytes_ = pack('{0}s'.format(len(encoded_pw)), encoded_pw) 94 | else: 95 | bytes_ = pack('{0}sx'.format(len(encoded_pw)), encoded_pw) 96 | return bytes_ 97 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/frontend_messages/query.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | """ 37 | Query message 38 | 39 | In the simple query protocol, the frontend sends a Query message, which contains 40 | an SQL command (or commands) expressed as a text string. The backend then sends 41 | one or more response messages depending on the contents of the query command 42 | string, and finally a ReadyForQuery message. 43 | """ 44 | 45 | from __future__ import annotations 46 | 47 | from struct import pack 48 | 49 | from ..message import BulkFrontendMessage 50 | 51 | 52 | class Query(BulkFrontendMessage): 53 | message_id = b'Q' 54 | 55 | def __init__(self, query_string): 56 | BulkFrontendMessage.__init__(self) 57 | self._query_string = query_string 58 | 59 | def read_bytes(self): 60 | encoded = self._query_string.encode('utf-8') 61 | bytes_ = pack('{0}sx'.format(len(encoded)), encoded) 62 | return bytes_ 63 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/frontend_messages/ssl_request.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from struct import pack 39 | 40 | from ..message import BulkFrontendMessage 41 | 42 | 43 | class SslRequest(BulkFrontendMessage): 44 | message_id = None 45 | SSL_REQUEST = 80877103 46 | 47 | def read_bytes(self): 48 | bytes_ = pack('!I', self.SSL_REQUEST) 49 | return bytes_ 50 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/frontend_messages/startup.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | """ 37 | Startup message 38 | 39 | To begin a session, the frontend opens a connection to the backend and sends a 40 | Startup message. 41 | """ 42 | 43 | from __future__ import annotations 44 | 45 | import platform 46 | import os 47 | import socket 48 | import warnings 49 | from struct import pack 50 | 51 | # noinspection PyUnresolvedReferences,PyCompatibility 52 | 53 | import vertica_python 54 | from ..message import BulkFrontendMessage 55 | 56 | 57 | class Startup(BulkFrontendMessage): 58 | message_id = None 59 | 60 | def __init__(self, user, database, session_label, os_user_name, autocommit, 61 | binary_transfer, request_complex_types, oauth_access_token, 62 | workload, auth_category): 63 | BulkFrontendMessage.__init__(self) 64 | 65 | try: 66 | os_platform = platform.platform() 67 | except Exception as e: 68 | os_platform = '' 69 | warnings.warn(f"Cannot get the OS info: {str(e)}") 70 | 71 | try: 72 | pid = str(os.getpid()) 73 | except Exception as e: 74 | pid = '0' 75 | warnings.warn(f"Cannot get the process ID: {str(e)}") 76 | 77 | try: 78 | os_hostname = socket.gethostname() 79 | except Exception as e: 80 | os_hostname = '' 81 | warnings.warn(f"Cannot get the OS hostname: {str(e)}") 82 | 83 | request_complex_types = 'true' if request_complex_types else 'false' 84 | 85 | self.parameters = { 86 | b'user': user, 87 | b'database': database, 88 | b'client_label': session_label, 89 | b'client_type': 'vertica-python', 90 | b'client_version': vertica_python.__version__, 91 | b'client_os': os_platform, 92 | b'client_os_user_name': os_user_name, 93 | b'client_os_hostname': os_hostname, 94 | b'client_pid': pid, 95 | b'autocommit': 'on' if autocommit else 'off', 96 | b'binary_data_protocol': '1' if binary_transfer else '0', # Defaults to text format '0' 97 | b'protocol_features': '{"request_complex_types":' + request_complex_types + '}', 98 | b'protocol_compat': 'VER', 99 | b'workload': workload, 100 | b'auth_category': auth_category, 101 | } 102 | 103 | if len(oauth_access_token) > 0: 104 | # compatibility for protocol version 3.11 105 | self.parameters[b'oauth_access_token'] = oauth_access_token 106 | 107 | def read_bytes(self): 108 | # The fixed protocol version is followed by pairs of parameter name and value strings. 109 | # A zero byte is required as a terminator after the last name/value pair. 110 | # Parameters can appear in any order. 111 | fixed_protocol_version = 3 << 16 | 5 112 | bytes_ = pack('!I', fixed_protocol_version) 113 | 114 | # The frontend sends a requested protocol version to the backend. 115 | # Old servers (protocol < 3.7) ignore this value and use the fixed protocol version. 116 | # New servers (protocol >= 3.7) would try to find the common protocol 117 | # version in use for both client and server, and send back a ParameterStatus 118 | # message (key='protocol_version', value=) 119 | bytes_ += pack('!16sxIx', b'protocol_version', vertica_python.PROTOCOL_VERSION) 120 | 121 | for k in self.parameters: 122 | v = self.parameters[k].encode('utf-8') 123 | bytes_ += pack('!{}sx{}sx'.format(len(k), len(v)), k, v) 124 | 125 | bytes_ += pack('x') 126 | return bytes_ 127 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/frontend_messages/sync.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from ..message import BulkFrontendMessage 39 | 40 | 41 | class Sync(BulkFrontendMessage): 42 | message_id = b'S' 43 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/frontend_messages/terminate.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2024 Open Text. 2 | # Copyright (c) 2018 Uber Technologies, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Copyright (c) 2013-2017 Uber Technologies, Inc. 17 | # 18 | # Permission is hereby granted, free of charge, to any person obtaining a copy 19 | # of this software and associated documentation files (the "Software"), to deal 20 | # in the Software without restriction, including without limitation the rights 21 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | # copies of the Software, and to permit persons to whom the Software is 23 | # furnished to do so, subject to the following conditions: 24 | # 25 | # The above copyright notice and this permission notice shall be included in 26 | # all copies or substantial portions of the Software. 27 | # 28 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 34 | # THE SOFTWARE. 35 | 36 | from __future__ import annotations 37 | 38 | from ..message import BulkFrontendMessage 39 | 40 | 41 | class Terminate(BulkFrontendMessage): 42 | message_id = b'X' 43 | -------------------------------------------------------------------------------- /vertica_python/vertica/messages/frontend_messages/verified_files.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020-2024 Open Text. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | from __future__ import annotations 17 | 18 | import os 19 | from struct import pack 20 | 21 | from ..message import BulkFrontendMessage 22 | 23 | 24 | class VerifiedFiles(BulkFrontendMessage): 25 | message_id = b'F' 26 | 27 | def __init__(self, file_list, protocol_version): 28 | BulkFrontendMessage.__init__(self) 29 | self.filenames = file_list 30 | self.protocol_version = protocol_version 31 | 32 | def read_bytes(self): 33 | if self.protocol_version >= (3 << 16 | 15): 34 | bytes_ = pack('!I', len(self.filenames)) # Int32 35 | else: 36 | bytes_ = pack('!H', len(self.filenames)) # Int16 37 | for filename in self.filenames: 38 | utf_filename = filename.encode('utf-8') 39 | bytes_ += pack('!{0}sx'.format(len(utf_filename)), utf_filename) 40 | bytes_ += pack('!Q', os.path.getsize(filename)) 41 | 42 | return bytes_ 43 | 44 | def __str__(self): 45 | return "VerifiedFiles: {}".format(self.filenames) 46 | -------------------------------------------------------------------------------- /vertica_python/vertica/mixins/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2019-2024 Open Text. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import annotations 16 | -------------------------------------------------------------------------------- /vertica_python/vertica/mixins/notice_response_attr.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2019-2024 Open Text. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from __future__ import annotations 16 | 17 | from collections import OrderedDict 18 | 19 | FIELD_DEFINITIONS = [ 20 | {'type': b'q', 'name': "Internal Query", 'attribute': 'internal_query'}, 21 | {'type': b'S', 'name': "Severity", 'attribute': 'severity'}, 22 | {'type': b'M', 'name': "Message", 'attribute': 'message'}, 23 | {'type': b'C', 'name': "Sqlstate", 'attribute': 'sqlstate'}, 24 | {'type': b'D', 'name': "Detail", 'attribute': 'detail'}, 25 | {'type': b'H', 'name': "Hint", 'attribute': 'hint'}, 26 | {'type': b'P', 'name': "Position", 'attribute': 'position'}, 27 | {'type': b'W', 'name': "Where", 'attribute': 'where'}, 28 | {'type': b'p', 'name': "Internal Position", 'attribute': 'internal_position'}, 29 | {'type': b'R', 'name': "Routine", 'attribute': 'routine'}, 30 | {'type': b'F', 'name': "File", 'attribute': 'file'}, 31 | {'type': b'L', 'name': "Line", 'attribute': 'line'}, 32 | {'type': b'V', 'name': "Error Code", 'attribute': 'error_code'} 33 | ] 34 | FIELD_ATTR_TO_TYPE = {field['attribute']: field['type'] for field in FIELD_DEFINITIONS} 35 | 36 | 37 | class _NoticeResponseAttrMixin: 38 | # class must have `self._notice_attrs` property that provides a mapping from 39 | # the type indicator (see `FIELD_DEFINITIONS`) to value. 40 | 41 | @property 42 | def internal_query(self): 43 | return self._notice_attrs.get(FIELD_ATTR_TO_TYPE['internal_query']) 44 | 45 | @property 46 | def severity(self): 47 | return self._notice_attrs.get(FIELD_ATTR_TO_TYPE['severity']) 48 | 49 | @property 50 | def message(self): 51 | return self._notice_attrs.get(FIELD_ATTR_TO_TYPE['message']) 52 | 53 | @property 54 | def sqlstate(self): 55 | return self._notice_attrs.get(FIELD_ATTR_TO_TYPE['sqlstate']) 56 | 57 | @property 58 | def detail(self): 59 | return self._notice_attrs.get(FIELD_ATTR_TO_TYPE['detail']) 60 | 61 | @property 62 | def hint(self): 63 | return self._notice_attrs.get(FIELD_ATTR_TO_TYPE['hint']) 64 | 65 | @property 66 | def position(self): 67 | return self._notice_attrs.get(FIELD_ATTR_TO_TYPE['position']) 68 | 69 | @property 70 | def where(self): 71 | return self._notice_attrs.get(FIELD_ATTR_TO_TYPE['where']) 72 | 73 | @property 74 | def internal_position(self): 75 | return self._notice_attrs.get(FIELD_ATTR_TO_TYPE['internal_position']) 76 | 77 | @property 78 | def routine(self): 79 | return self._notice_attrs.get(FIELD_ATTR_TO_TYPE['routine']) 80 | 81 | @property 82 | def file(self): 83 | return self._notice_attrs.get(FIELD_ATTR_TO_TYPE['file']) 84 | 85 | @property 86 | def line(self): 87 | return self._notice_attrs.get(FIELD_ATTR_TO_TYPE['line']) 88 | 89 | @property 90 | def error_code(self): 91 | return self._notice_attrs.get(FIELD_ATTR_TO_TYPE['error_code']) 92 | 93 | def _get_labeled_values(self): 94 | values_mapping = OrderedDict() 95 | 96 | for field_def in FIELD_DEFINITIONS: 97 | if field_def['type'] in self._notice_attrs: 98 | values_mapping[field_def['name']] = self._notice_attrs[field_def['type']] 99 | 100 | return values_mapping 101 | -------------------------------------------------------------------------------- /vertica_python/vertica/tlsmode.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Open Text. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | from __future__ import annotations 17 | 18 | import ssl 19 | import warnings 20 | from enum import Enum 21 | from typing import TYPE_CHECKING 22 | if TYPE_CHECKING: 23 | from typing import Optional 24 | 25 | 26 | class TLSMode(Enum): 27 | DISABLE = 'disable' 28 | PREFER = 'prefer' 29 | REQUIRE = 'require' 30 | VERIFY_CA = 'verify-ca' 31 | VERIFY_FULL = 'verify-full' 32 | 33 | def requests_encryption(self) -> bool: 34 | return self != TLSMode.DISABLE 35 | 36 | def requires_encryption(self) -> bool: 37 | return self not in (TLSMode.DISABLE, TLSMode.PREFER) 38 | 39 | def verify_certificate(self) -> bool: 40 | return self in (TLSMode.VERIFY_CA, TLSMode.VERIFY_FULL) 41 | 42 | def verify_hostname(self) -> bool: 43 | return self == TLSMode.VERIFY_FULL 44 | 45 | def get_sslcontext(self, cafile: Optional[str] = None, 46 | certfile: Optional[str] = None, 47 | keyfile: Optional[str] = None) -> ssl.SSLContext: 48 | ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) 49 | ssl_context.check_hostname = self.verify_hostname() 50 | if self.verify_certificate(): 51 | ssl_context.verify_mode = ssl.CERT_REQUIRED 52 | if cafile: 53 | ssl_context.load_verify_locations(cafile=cafile) 54 | # mutual mode 55 | if certfile or keyfile: 56 | ssl_context.load_cert_chain(certfile=certfile, keyfile=keyfile) 57 | else: 58 | ssl_context.verify_mode = ssl.CERT_NONE 59 | if cafile or certfile or keyfile: 60 | ignore_cert_msg = ("Ignore TLS certificate files and skip certificates" 61 | f" validation as tlsmode is not '{TLSMode.VERIFY_CA.value}'" 62 | f" or '{TLSMode.VERIFY_FULL.value}'.") 63 | warnings.warn(ignore_cert_msg) 64 | return ssl_context 65 | 66 | --------------------------------------------------------------------------------