diff --git a/.github/workflows/3rd-party-tests.yml b/.github/workflows/3rd-party-tests.yml deleted file mode 100644 index 9a84c57aa..000000000 --- a/.github/workflows/3rd-party-tests.yml +++ /dev/null @@ -1,259 +0,0 @@ -name: 3rd party tests - -on: - # push: - # branches: - # - "master" - # - "maint-3.1" - # - "sqlalchemy_pipeline" - # - "django_pipeline" - # paths-ignore: - # - "docs/*" - # - "tools/*" - workflow_dispatch: - -concurrency: - # Cancel older requests of the same workflow in the same branch. - group: ${{ github.workflow }}-${{ github.ref_name }} - cancel-in-progress: true - -jobs: - sqlalchemy: - # linux should be enough to test if everything works. - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - python-version: - - "3.13" - - "3.9" - sqlalchemy_label: - # what version of sqlalchemy to download is defined in the "include" section below, - # in the variable pip_sqlalchemy - - git_main - - release - impl: - - c - - python - include: - - sqlalchemy_label: git_main - pip_sqlalchemy: git+https://github.com/sqlalchemy/sqlalchemy.git#egg=sqlalchemy - - sqlalchemy_label: release - pip_sqlalchemy: sqlalchemy>=2 - - env: - GAUSSDB_IMPL: ${{ matrix.impl }} - DEPS: ./gaussdb pytest pytest-xdist greenlet - - services: - postgresql: - image: postgres:15 - env: - POSTGRES_PASSWORD: password - POSTGRES_DB: test - ports: - - 5432:5432 - # Wait until postgres has started - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - - name: Setup PG - env: - PGPASSWORD: password - run: | - psql -AXqte "host=127.0.0.1 dbname=test user=postgres" << HERE - SELECT version(); - CREATE SCHEMA test_schema; - CREATE SCHEMA test_schema_2; - CREATE EXTENSION hstore; - HERE - - - name: Include gaussdb-c to the packages to install - if: ${{ matrix.impl == 'c' }} - run: | - echo "DEPS=$DEPS ./gaussdb_c" >> $GITHUB_ENV - - - name: Install pycopg packages - run: pip install $DEPS - - - name: Setup and install sqlalchemy - run: | - pip download --no-deps --no-binary :all: ${{ matrix.pip_sqlalchemy }} - mkdir sa_home - case $(file --brief --mime-type sqlalchemy*) in - application/gzip) - tar -C sa_home -xzf sqlalchemy* - ;; - application/zip) - unzip -d sa_home -q sqlalchemy* - ;; - *) - echo "Unexpected format for $(file --mime-type sqlalchemy*)" >&2 - exit 1 - ;; - esac - mv sa_home/$( ls sa_home ) sa_home/sa - cd sa_home/sa - pip install . - - - name: Run sqlalchemy tests - env: - URL: postgresql+gaussdb://postgres:password@127.0.0.1/test - working-directory: sa_home/sa - run: pytest -n 2 -q --dburi $URL --backend-only --dropfirst --color=yes --dbdriver psycopg_async - - django: - # linux should be enough to test if everything works. - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - django_label: - # what version of django to download is defined in the "include" - # section below, in the variable pip_django - - git_main - - lts - impl: - - c - - python - include: - - django_label: git_main - pip_django: git+https://github.com/django/django.git#egg=Django - # TODO: Needs updating with new LTS releases, is this something we want? - # Also needs consideration against which python we wanna test. - # Current logic is test oldest in lts and newest in main - - django_label: lts - pip_django: "'Django>=4.2,<4.3'" - - # Test with min and max Python supported versions - - django_label: lts - impl: c - python-version: "3.9" - - django_label: lts - impl: python - python-version: "3.13" - - django_label: git_main - impl: c - python-version: "3.13" - - django_label: git_main - impl: python - python-version: "3.12" - - env: - DEPS: ./gaussdb ./gaussdb_pool - - services: - postgresql: - image: postgres:15 - env: - POSTGRES_PASSWORD: password - POSTGRES_DB: postgres - ports: - - 5432:5432 - # Wait until postgres has started - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - - name: Setup PG - env: - PGPASSWORD: password - run: | - psql -AXqte "host=127.0.0.1 dbname=postgres user=postgres" << HERE - SELECT version(); - HERE - - - name: Include gaussdb-c to the packages to install - if: ${{ matrix.impl == 'c' }} - run: | - echo "DEPS=$DEPS ./gaussdb_c" >> $GITHUB_ENV - - - name: Install pycopg packages - run: pip install $DEPS - - - name: Download and configure Django - run: | - pip download --no-deps --no-binary :all: ${{ matrix.pip_django }} - mkdir django_home - case $(file --brief --mime-type Django*) in - application/gzip) - tar -C django_home -xzf Django* - ;; - application/zip) - unzip -d django_home -q Django* - ;; - *) - echo "Unexpected format for $(file --mime-type Django*)" >&2 - exit 1 - ;; - esac - mv django_home/$( ls django_home ) django_home/django - cat << HERE > django_home/django/tests/test_postgresql.py - DATABASES = { - "default": { - "ENGINE": "django.db.backends.postgresql", - "HOST": "127.0.0.1", - "USER": "postgres", - "PASSWORD": "password", - }, - "other": { - "ENGINE": "django.db.backends.postgresql", - "HOST": "127.0.0.1", - "USER": "postgres", - "PASSWORD": "password", - }, - } - - SECRET_KEY = "django_tests_secret_key" - - # Use a fast hasher to speed up tests. - PASSWORD_HASHERS = [ - "django.contrib.auth.hashers.MD5PasswordHasher", - ] - - DEFAULT_AUTO_FIELD = "django.db.models.AutoField" - - USE_TZ = False - HERE - - - uses: actions/cache@v4 - with: - path: ~/.cache/pip - key: ${{ matrix.python-version }}-pip-${{ hashFiles('django_home/django/tests/requirements/py3.txt', 'django_home/django/setup.cfg') }} - restore-keys: | - ${{ matrix.python-version }}-pip- - - - name: Install Django and dependencies - working-directory: django_home/django - run: | - # pylibmc wheel package not available from Python 3.12. - # https://github.com/lericson/pylibmc/issues/288 - # Dependency in: - # https://github.com/django/django/blob/main/tests/requirements/py3.txt#L12 - # (You can check the above in case it gets dropped in the future). - sudo apt-get install -y libmemcached-dev - pip install . - pip install -r tests/requirements/py3.txt - - - name: Run Django tests - working-directory: django_home/django/tests - run: ./runtests.py --settings=test_postgresql postgres_tests backends queries diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 6e52e41eb..000000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,105 +0,0 @@ -name: CI for gaussdb-python - -on: - push: - branches: - - "*" - pull_request: - workflow_dispatch: - -concurrency: - group: ${{ github.workflow }}-${{ github.ref_name }} - cancel-in-progress: true - -jobs: - test: - runs-on: ubuntu-22.04 - - services: - opengauss: - image: opengauss/opengauss-server:latest - ports: - - 5432:5432 - env: - GS_USERNAME: root - GS_USER_PASSWORD: Passwd@123 - GS_PASSWORD: Passwd@123 - options: >- - --privileged=true - --name opengauss-custom - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.9" - cache: pip - - - name: Create and activate virtual environment - run: | - python -m venv venv - echo "VENV_PATH=$GITHUB_WORKSPACE/venv/bin" >> $GITHUB_ENV - source venv/bin/activate - - - name: Install gaussdb libpq driver - run: | - sudo apt update - sudo apt install -y wget unzip - wget -O /tmp/GaussDB_driver.zip https://dbs-download.obs.cn-north-1.myhuaweicloud.com/GaussDB/1730887196055/GaussDB_driver.zip - unzip /tmp/GaussDB_driver.zip -d /tmp/ && rm -rf /tmp/GaussDB_driver.zip - \cp /tmp/GaussDB_driver/Centralized/Hce2_X86_64/GaussDB-Kernel*64bit_Python.tar.gz /tmp/ - tar -zxvf /tmp/GaussDB-Kernel*64bit_Python.tar.gz -C /tmp/ && rm -rf /tmp/GaussDB-Kernel*64bit_Python.tar.gz && rm -rf /tmp/_GaussDB && rm -rf /tmp/GaussDB_driver - echo /tmp/lib | sudo tee /etc/ld.so.conf.d/gauss-libpq.conf - sudo sed -i '1s|^|/tmp/lib\n|' /etc/ld.so.conf - sudo ldconfig - ldconfig -p | grep pq - - - name: Install dependencies - run: | - source venv/bin/activate - python -m pip install --upgrade pip - pip install -r requirements.txt - pip install ./tools/isort-gaussdb/ - pip install "./gaussdb[dev,test]" - pip install ./gaussdb_pool - - - - name: Wait for openGauss to be ready - env: - GSQL_PASSWORD: Passwd@123 - run: | - source venv/bin/activate - for i in {1..30}; do - pg_isready -h localhost -p 5432 -U root && break - sleep 10 - done - if ! pg_isready -h localhost -p 5432 -U root; then - echo "openGauss is not ready" - exit 1 - fi - - - name: Create test database - run: | - docker exec opengauss-custom bash -c "su - omm -c 'gsql -d postgres -c \"CREATE DATABASE test DBCOMPATIBILITY '\''PG'\'';\"'" - - - name: Create report directory - run: | - mkdir -p reports - - - name: Run tests - env: - PYTHONPATH: ./gaussdb:./gaussdb_pool - GAUSSDB_IMPL: python - GAUSSDB_TEST_DSN: "host=127.0.0.1 port=5432 dbname=test user=root password=Passwd@123 " - run: | - source venv/bin/activate - pytest -s -v - - - name: Cleanup - if: always() - run: | - docker stop opengauss-custom - docker rm opengauss-custom diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 9d4c50411..22952521a 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -1,12 +1,13 @@ name: Build documentation on: - # push: - # branches: - # # This should match the DOC3_BRANCH value in the gaussdb-website Makefile - # - master - # pull_request: - workflow_dispatch: + push: + # This should disable running the workflow on tags, according to the + # on.. GitHub Actions docs. + branches: + - "*" + pull_request: + workflow_dispatch: concurrency: @@ -17,9 +18,29 @@ jobs: docs: runs-on: ubuntu-latest steps: - - name: Trigger docs build - uses: peter-evans/repository-dispatch@v3 + - uses: actions/checkout@v4 + + - name: Set up Python 3.9 + uses: actions/setup-python@v5 + with: + python-version: "3.9" + + - name: Install requirements to generate docs + run: sudo apt-get install -y libgeos-dev + + - name: Install Python packages to generate docs + run: | + pip install furo + pip install ./tools/isort-gaussdb/ + pip install ./gaussdb[dev,test] + pip install ./gaussdb_pool + pip install types-polib + + - name: Check documentation + run: sphinx-build -W -T -b html docs docs/_build/html + + - name: Upload built documentation as artifact + uses: actions/upload-artifact@v4 with: - repository: psycopg/psycopg-website - event-type: psycopg3-commit - token: ${{ secrets.ACCESS_TOKEN }} + name: gaussdb-docs-html + path: docs/_build/html \ No newline at end of file diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index a9bba7316..b41322049 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -28,9 +28,9 @@ jobs: - name: install packages to tests run: | - pip install ./tools/isort-gaussdb/ - pip install ./gaussdb[dev,test] - pip install ./gaussdb_pool + pip install -e ./tools/isort-gaussdb/ + pip install -e ./gaussdb[dev,test] + pip install -e ./gaussdb_pool pip install types-polib pip install pre-commit @@ -49,8 +49,18 @@ jobs: pip install types-polib pip install ./gaussdb_pool - - name: Check for sync/async inconsistencies - run: ./tools/async_to_sync.py --check $(find tests -name "*_async.py" -type f ! -path "tests/pq/test_async.py" ! -path "tests/test_concurrency_async.py") + - name: Check for sync/async inconsistencies (loop until no error) + run: | + while true; do + files=$(find tests -name "*_async.py" -type f ! -path "tests/pq/test_async.py" ! -path "tests/test_concurrency_async.py") + if ./tools/async_to_sync.py --check $files; then + echo "No inconsistencies found. Done." + break + else + echo "Found inconsistencies. Rechecking after regeneration..." + ./tools/async_to_sync.py $files + fi + done - name: Install requirements to generate docs run: sudo apt-get install -y libgeos-dev diff --git a/.github/workflows/packages-bin.yml b/.github/workflows/packages-bin.yml deleted file mode 100644 index ff4951781..000000000 --- a/.github/workflows/packages-bin.yml +++ /dev/null @@ -1,255 +0,0 @@ -name: Build binary packages - -# Note: Libpq is currently built from source on most platforms and the build -# artifacts are cached across pipeline runs. -# -# You can see the caches at https://github.com/gaussdb/gaussdb/actions/caches -# -# You can delete a cache using: -# -# curl -L -X DELETE -# -H "Accept: application/vnd.github+json" -# -H "Authorization: Bearer $GITHUB_TOKEN" -# -H "X-GitHub-Api-Version: 2022-11-28" -# "https://api.github.com/repos/gaussdb/gaussdb/actions/caches?key=libpq-manylinux-ppc64le-17.2-3.4.0" -# -# ref: https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#delete-github-actions-caches-for-a-repository-using-a-cache-key - -on: - workflow_dispatch: - # pull_request: - # paths: - # - '.github/workflows/packages-bin.yml' - # schedule: - # - cron: '28 7 * * sun' - -env: - # Latest release: https://www.postgresql.org/ftp/source/ - LIBPQ_VERSION: "17.4" - - # Latest release: https://www.openssl.org/source/ - OPENSSL_VERSION: "3.4.1" - -concurrency: - # Cancel older requests of the same workflow in the same branch. - group: ${{ github.workflow }}-${{ github.ref_name }} - cancel-in-progress: true - -jobs: - - linux: # {{{ - runs-on: ubuntu-latest - if: true - - strategy: - fail-fast: false - matrix: - arch: [x86_64, i686, ppc64le, aarch64] - pyver: [cp39, cp310, cp311, cp312, cp313] - platform: [manylinux, musllinux] - - steps: - - uses: actions/checkout@v4 - - - name: Set up QEMU for multi-arch build - # Check https://github.com/docker/setup-qemu-action for newer versions. - uses: docker/setup-qemu-action@v3 - with: - # https://github.com/pypa/cibuildwheel/discussions/2256 - image: tonistiigi/binfmt:qemu-v8.1.5 - - - name: Cache libpq build - uses: actions/cache@v4 - with: - path: /tmp/libpq.build - key: libpq-${{ matrix.platform }}-${{ matrix.arch }}-${{ env.LIBPQ_VERSION }}-${{ env.OPENSSL_VERSION }} - - - name: Create the binary package source tree - run: python3 ./tools/ci/copy_to_binary.py - - - name: Build wheels - uses: pypa/cibuildwheel@v2.23.2 - with: - package-dir: gaussdb_binary - env: - CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014 - CIBW_MANYLINUX_I686_IMAGE: manylinux2014 - CIBW_MANYLINUX_AARCH64_IMAGE: manylinux2014 - CIBW_MANYLINUX_PPC64LE_IMAGE: manylinux2014 - CIBW_BUILD: ${{matrix.pyver}}-${{matrix.platform}}_${{matrix.arch}} - CIBW_ARCHS_LINUX: auto aarch64 ppc64le - CIBW_BEFORE_ALL_LINUX: ./tools/ci/wheel_linux_before_all.sh - CIBW_REPAIR_WHEEL_COMMAND: >- - ./tools/ci/strip_wheel.sh {wheel} - && auditwheel repair -w {dest_dir} {wheel} - CIBW_TEST_REQUIRES: ./gaussdb[test] ./gaussdb_pool - CIBW_TEST_COMMAND: >- - pytest {project}/tests -m 'not slow and not flakey' --color yes - CIBW_ENVIRONMENT_PASS_LINUX: LIBPQ_VERSION OPENSSL_VERSION - CIBW_ENVIRONMENT: >- - GAUSSDB_IMPL=binary - GAUSSDB_TEST_DSN='host=172.17.0.1 user=postgres' - PGPASSWORD=password - LIBPQ_BUILD_PREFIX=/host/tmp/libpq.build - PATH="$LIBPQ_BUILD_PREFIX/bin:$PATH" - LD_LIBRARY_PATH="$LIBPQ_BUILD_PREFIX/lib:$LIBPQ_BUILD_PREFIX/lib64" - GAUSSDB_TEST_WANT_LIBPQ_BUILD=${{ env.LIBPQ_VERSION }} - GAUSSDB_TEST_WANT_LIBPQ_IMPORT=${{ env.LIBPQ_VERSION }} - - - uses: actions/upload-artifact@v4 - with: - name: linux-${{matrix.pyver}}-${{matrix.platform}}_${{matrix.arch}} - path: ./wheelhouse/*.whl - - services: - postgresql: - image: postgres:14 - env: - POSTGRES_PASSWORD: password - ports: - - 5432:5432 - # Set health checks to wait until postgres has started - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - - - # }}} - - macos: # {{{ - runs-on: macos-latest - if: true - - strategy: - fail-fast: false - matrix: - arch: [x86_64, arm64] - pyver: [cp39, cp310, cp311, cp312, cp313] - - steps: - - name: Checkout repos - uses: actions/checkout@v4 - - - name: Cache libpq build - uses: actions/cache@v4 - with: - path: /tmp/libpq.build - key: libpq-${{ env.LIBPQ_VERSION }}-macos-${{ matrix.arch }}-${{ env.OPENSSL_VERSION }} - - - name: Create the binary package source tree - run: python3 ./tools/ci/copy_to_binary.py - - - name: Build wheels - uses: pypa/cibuildwheel@v2.23.2 - with: - package-dir: gaussdb_binary - env: - CIBW_BUILD: ${{matrix.pyver}}-macosx_${{matrix.arch}} - CIBW_ARCHS_MACOS: ${{matrix.arch}} - MACOSX_ARCHITECTURE: ${{matrix.arch}} - CIBW_BEFORE_ALL_MACOS: ./tools/ci/wheel_macos_before_all.sh - CIBW_TEST_REQUIRES: ./gaussdb[test] ./gaussdb_pool - CIBW_TEST_COMMAND: >- - pytest {project}/tests -m 'not slow and not flakey' --color yes - CIBW_ENVIRONMENT: >- - PG_VERSION=17 - GAUSSDB_IMPL=binary - GAUSSDB_TEST_DSN='dbname=postgres' - LIBPQ_BUILD_PREFIX=/tmp/libpq.build - PATH="$LIBPQ_BUILD_PREFIX/bin:$PATH" - GAUSSDB_TEST_WANT_LIBPQ_BUILD=">= ${{env.LIBPQ_VERSION}}" - GAUSSDB_TEST_WANT_LIBPQ_IMPORT=">= ${{env.LIBPQ_VERSION}}" - - - name: Upload artifacts - uses: actions/upload-artifact@v4 - with: - name: macos-${{matrix.pyver}}-${{matrix.arch}} - path: ./wheelhouse/*.whl - - - # }}} - - windows: # {{{ - runs-on: windows-latest - if: true - - strategy: - fail-fast: false - matrix: - # Might want to add win32, untested at the moment. - arch: [win_amd64] - pyver: [cp39, cp310, cp311, cp312, cp313] - - defaults: - run: - shell: bash - - steps: - # there are some other libpq in PATH - - run: rm -rf c:/tools/php C:/Strawberry/c/bin - - - uses: actions/checkout@v4 - - - name: Start PostgreSQL service for test - run: | - $PgSvc = Get-Service "postgresql*" - Set-Service $PgSvc.Name -StartupType manual - $PgSvc.Start() - shell: powershell - - - uses: prefix-dev/setup-pixi@v0.8.4 - with: - run-install: false - - run: pixi global install libpq=${{ env.LIBPQ_VERSION }} --with openssl=${{ env.OPENSSL_VERSION }} - - run: echo "EXTRA_LIB_DIR=$(pg_config.exe --bindir)" >> $GITHUB_OUTPUT - id: libdir - - - name: Create the binary package source tree - run: python3 ./tools/ci/copy_to_binary.py - - - name: Build wheels - uses: pypa/cibuildwheel@v2.23.2 - with: - package-dir: gaussdb_binary - env: - VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite" # cache vcpkg - CIBW_BUILD: ${{matrix.pyver}}-${{matrix.arch}} - CIBW_ARCHS_WINDOWS: AMD64 x86 - CIBW_BEFORE_BUILD_WINDOWS: '.\tools\ci\wheel_win32_before_build.bat' - CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: >- - delvewheel repair -w {dest_dir} - --add-path="${{ steps.libdir.outputs.EXTRA_LIB_DIR }}" - --no-mangle "libiconv-2.dll;libwinpthread-1.dll" {wheel} - CIBW_TEST_REQUIRES: ./gaussdb[test] ./gaussdb_pool - CIBW_TEST_COMMAND: >- - pytest {project}/tests -m "not slow and not flakey" --color yes - CIBW_ENVIRONMENT_WINDOWS: >- - GAUSSDB_IMPL=binary - GAUSSDB_TEST_DSN="host=127.0.0.1 user=postgres" - GAUSSDB_TEST_WANT_LIBPQ_BUILD=${{env.LIBPQ_VERSION}} - GAUSSDB_TEST_WANT_LIBPQ_IMPORT=${{env.LIBPQ_VERSION}} - - - uses: actions/upload-artifact@v4 - with: - name: windows-${{matrix.pyver}}-${{matrix.arch}} - path: ./wheelhouse/*.whl - - - # }}} - - merge: # {{{ - runs-on: ubuntu-latest - needs: - - linux - - macos - - windows - steps: - - name: Merge Artifacts - uses: actions/upload-artifact/merge@v4 - with: - name: gaussdb-binary-artifact - delete-merged: true - - # }}} diff --git a/.github/workflows/packages-pool.yml b/.github/workflows/packages-pool.yml deleted file mode 100644 index 83b713a96..000000000 --- a/.github/workflows/packages-pool.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: Build pool packages - -on: - workflow_dispatch: - # schedule: - # - cron: '28 6 * * sun' - -jobs: - - sdist: - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - include: - - {package: gaussdb_pool, format: sdist} - - {package: gaussdb_pool, format: wheel} - - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 - with: - python-version: 3.9 - - - name: Install the build package - run: pip install build - - - name: Create the package - run: python -m build -o dist --${{ matrix.format }} ${{ matrix.package }} - - - name: Install the Python pool package and test requirements - run: pip install gaussdb[test] dist/* - - - name: Test the package - run: pytest -m 'pool and not slow and not flakey' --color yes - env: - GAUSSDB_TEST_DSN: "host=127.0.0.1 user=postgres" - PGPASSWORD: password - - - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.package }}-${{ matrix.format }} - path: ./dist/* - - services: - postgresql: - image: postgres:14 - env: - POSTGRES_PASSWORD: password - ports: - - 5432:5432 - # Set health checks to wait until postgres has started - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - - merge: - runs-on: ubuntu-latest - needs: - - sdist - steps: - - name: Merge Artifacts - uses: actions/upload-artifact/merge@v4 - with: - name: gaussdb-pool-artifact - delete-merged: true diff --git a/.github/workflows/packages-src.yml b/.github/workflows/packages-src.yml deleted file mode 100644 index 5b62186d8..000000000 --- a/.github/workflows/packages-src.yml +++ /dev/null @@ -1,77 +0,0 @@ -name: Build source packages - -on: - workflow_dispatch: - # schedule: - # - cron: '37 6 * * sun' - -jobs: - - sdist: - runs-on: ubuntu-latest - if: true - - strategy: - fail-fast: false - matrix: - include: - - {package: gaussdb, format: sdist, impl: python} - - {package: gaussdb, format: wheel, impl: python} - - {package: gaussdb_c, format: sdist, impl: c} - - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 - with: - python-version: 3.9 - - - name: Install the build package - run: pip install build - - - name: Create the package - run: python -m build -o dist --${{ matrix.format }} ${{ matrix.package }} - - - name: Install the Python package and test requirements - run: pip install `ls dist/*`[test] ./gaussdb_pool - if: ${{ matrix.package == 'gaussdb' }} - - - name: Install the C package and test requirements - run: pip install dist/* ./gaussdb[test] ./gaussdb_pool - if: ${{ matrix.package == 'gaussdb_c' }} - - - name: Test the sdist package - run: pytest -m 'not slow and not flakey' --color yes - env: - GAUSSDB_IMPL: ${{ matrix.impl }} - GAUSSDB_TEST_DSN: "host=127.0.0.1 user=postgres" - PGPASSWORD: password - - - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.package }}-${{ matrix.format }}-${{ matrix.impl }} - path: ./dist/* - - services: - postgresql: - image: postgres:14 - env: - POSTGRES_PASSWORD: password - ports: - - 5432:5432 - # Set health checks to wait until postgres has started - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - merge: - runs-on: ubuntu-latest - needs: - - sdist - steps: - - name: Merge Artifacts - uses: actions/upload-artifact/merge@v4 - with: - name: gaussdb-src-artifact - delete-merged: true diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3c72e2517..427ecf235 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,423 +1,105 @@ name: Tests on: - # push: - # # This should disable running the workflow on tags, according to the - # # on.. GitHub Actions docs. - # branches: - # - "*" - # pull_request: - # schedule: - # - cron: '48 6 * * *' - workflow_dispatch: + push: + branches: + - "*" + pull_request: + workflow_dispatch: concurrency: - # Cancel older requests of the same workflow in the same branch. group: ${{ github.workflow }}-${{ github.ref_name }} cancel-in-progress: true - + jobs: - - linux: # {{{ - runs-on: ubuntu-latest - if: true - - strategy: - fail-fast: false - matrix: - include: - # Test different combinations of Python, Postgres, libpq. - - {impl: python, python: "3.9", postgres: "postgres:17", libpq: oldest} - - {impl: python, python: "3.10", postgres: "postgres:16", libpq: master} - - {impl: python, python: "3.11", postgres: "postgres:15"} - - {impl: python, python: "3.12", postgres: "postgres:14", libpq: newest} - - {impl: python, python: "3.13", postgres: "postgres:12"} - - - {impl: c, python: "3.9", postgres: "postgres:12", libpq: master} - - {impl: c, python: "3.10", postgres: "postgres:13"} - - {impl: c, python: "3.11", postgres: "postgres:15", libpq: oldest} - - {impl: c, python: "3.12", postgres: "postgres:16", libpq: newest} - - {impl: c, python: "3.13", postgres: "postgres:17"} - - - {impl: python, python: "3.9", ext: gevent, postgres: "postgres:17"} - - {impl: python, python: "3.9", ext: dns, postgres: "postgres:14"} - - {impl: python, python: "3.12", ext: postgis, postgres: "postgis/postgis"} - - {impl: python, python: "3.10", ext: numpy, postgres: "postgres:14"} - - {impl: c, python: "3.11", ext: numpy, postgres: "postgres:15"} - - {impl: c, python: "3.12", ext: gevent, postgres: "postgres:14"} - - # Test with minimum dependencies versions - # WARNING: when bumping min version, make sure that the dependencies - # # in tests/constraints.txt are updated and that binary packages - # are available for such version. - - {impl: c, python: "3.9", ext: min, postgres: "postgres:15"} - - # Test memory alignment - - {impl: c, python: "3.12", ext: align, postgres: "postgres:16"} - - # Test with PyPy. - - {impl: python, python: "pypy3.9", postgres: "postgres:13"} - - {impl: python, python: "pypy3.10", postgres: "postgres:14"} - - env: - GAUSSDB_IMPL: ${{ matrix.impl }} - DEPS: ./gaussdb[test] ./gaussdb_pool - GAUSSDB_TEST_DSN: "host=127.0.0.1 user=postgres password=password" - MARKERS: "" + test: + runs-on: ubuntu-22.04 + + services: + opengauss: + image: opengauss/opengauss-server:latest + ports: + - 5432:5432 + env: + GS_USERNAME: root + GS_USER_PASSWORD: Passwd@123 + GS_PASSWORD: Passwd@123 + options: >- + --privileged=true + --name opengauss-custom steps: - - uses: actions/checkout@v4 + - name: Checkout code + uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - name: Set up Python + uses: actions/setup-python@v5 with: - python-version: ${{ matrix.python }} - allow-prereleases: true - - - name: Start PostgreSQL service - # Note: this would love to be a service, but I don't see a way to pass - # the args to the docker run command line. - run: | - docker pull ${{ matrix.postgres }} - docker run --rm -d --name postgres -p 5432:5432 \ - -e POSTGRES_PASSWORD=password ${{ matrix.postgres }} \ - -c max_prepared_transactions=10 - - - name: Install the wanted libpq version - run: sudo ./tools/ci/ci_install_libpq.sh ${{ matrix.libpq }} - - - name: Include gaussdb-c to the packages to install - if: ${{ matrix.impl == 'c' }} - run: | - echo "DEPS=$DEPS ./gaussdb_c" >> $GITHUB_ENV - - - name: Include gevent to the packages to install - if: ${{ matrix.ext == 'gevent' }} - run: | - echo "DEPS=$DEPS gevent" >> $GITHUB_ENV - echo "MARKERS=$MARKERS gevent" >> $GITHUB_ENV - - - name: Include dnspython to the packages to install - if: ${{ matrix.ext == 'dns' }} - run: | - echo "DEPS=$DEPS dnspython" >> $GITHUB_ENV - echo "MARKERS=$MARKERS dns" >> $GITHUB_ENV - - - name: Include shapely to the packages to install - if: ${{ matrix.ext == 'postgis' }} - run: | - echo "DEPS=$DEPS shapely" >> $GITHUB_ENV - echo "MARKERS=$MARKERS postgis" >> $GITHUB_ENV - - - if: ${{ matrix.ext == 'numpy' }} - run: | - echo "DEPS=$DEPS numpy" >> $GITHUB_ENV - echo "MARKERS=$MARKERS numpy" >> $GITHUB_ENV - - - name: Exclude certain tests from pypy - if: ${{ startsWith(matrix.python, 'pypy') }} - run: | - echo "NOT_MARKERS=$NOT_MARKERS timing" >> $GITHUB_ENV + python-version: "3.9" + cache: pip - - name: Configure to use the oldest dependencies - if: ${{ matrix.ext == 'min' }} + - name: Create and activate virtual environment run: | - echo "DEPS=$DEPS dnspython shapely numpy gevent" >> $GITHUB_ENV - echo "PIP_CONSTRAINT=${{ github.workspace }}/tests/constraints.txt" \ - >> $GITHUB_ENV - - - name: Configure memory alignment tests - if: ${{ matrix.ext == 'align' }} - run: | - echo "CFLAGS=-fsanitize=undefined -Werror=strict-aliasing -Werror=odr -Werror=lto-type-mismatch" - >> $GITHUB_ENV - echo "UBSAN_OPTIONS=halt_on_error=1" >> $GITHUB_ENV - echo "PYTEST_ADDOPTS=-v" >> $GITHUB_ENV - - - name: Install Python packages - run: pip install $DEPS - - - name: Run tests - run: ./tools/ci/ci_test.sh - - - # }}} - - macos-14: # {{{ - runs-on: macos-14 - if: true - - strategy: - fail-fast: false - matrix: - include: - - {impl: python, python: "3.10"} - - {impl: python, python: "3.11"} - - {impl: python, python: "3.12"} - - {impl: python, python: "3.13"} - - {impl: c, python: "3.10"} - - {impl: c, python: "3.11"} - - {impl: c, python: "3.12"} - - {impl: c, python: "3.13"} - - env: - GAUSSDB_IMPL: ${{ matrix.impl }} - DEPS: ./gaussdb[test] ./gaussdb_pool - GAUSSDB_TEST_DSN: "host=127.0.0.1 user=runner dbname=postgres" - # MacOS on GitHub Actions seems particularly slow. - # Don't run timing-based tests as they regularly fail. - # pproxy-based tests fail too, with the proxy not coming up in 2s. - NOT_MARKERS: "timing proxy mypy" - PG_VERSION: "17" - - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python }} - allow-prereleases: true - - - name: Install PostgreSQL on the runner - # On 2024-09-28 postgresql@17 installation failed but the package is - # available. So, in a few days, we might be able to drop "brew update". - run: | - brew update - brew install postgresql@${PG_VERSION} - - - name: Start PostgreSQL service - run: brew services start postgresql@${PG_VERSION} - - - name: Find the libpq - if: ${{ matrix.impl == 'python' }} - # NOTE: the libpq was found in: - # /opt/homebrew/opt/postgresql@${PG_VERSION}/lib before PG 17 - # /opt/homebrew/opt/postgresql@${PG_VERSION}/lib/postgresql on PG 17 - run: | - echo "DYLD_LIBRARY_PATH=/opt/homebrew/opt/postgresql@${PG_VERSION}/lib/postgresql:/opt/homebrew/opt/postgresql@${PG_VERSION}/lib:$DYLD_LIBRARY_PATH" \ - >> $GITHUB_ENV - - - name: Include gaussdb-c to the packages to install - if: ${{ matrix.impl == 'c' }} - run: | - echo "DEPS=$DEPS ./gaussdb_c" >> $GITHUB_ENV - echo "PATH=/opt/homebrew/opt/postgresql@${PG_VERSION}/bin:$PATH" >> $GITHUB_ENV - - - name: Install Python packages - run: pip install $DEPS - - - name: Run tests - run: ./tools/ci/ci_test.sh - - - # }}} - - macos-13: # {{{ - runs-on: macos-13 - if: true - - strategy: - fail-fast: false - matrix: - include: - - {impl: python, python: "3.9"} - - {impl: c, python: "3.9"} - - env: - GAUSSDB_IMPL: ${{ matrix.impl }} - DEPS: ./gaussdb[test] ./gaussdb_pool - GAUSSDB_TEST_DSN: "host=127.0.0.1 user=runner dbname=postgres" - # MacOS on GitHub Actions seems particularly slow. - # Don't run timing-based tests as they regularly fail. - # pproxy-based tests fail too, with the proxy not coming up in 2s. - NOT_MARKERS: "timing proxy mypy" - PG_VERSION: "17" + python -m venv venv + echo "VENV_PATH=$GITHUB_WORKSPACE/venv/bin" >> $GITHUB_ENV + source venv/bin/activate - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python }} - - - name: Install PostgreSQL on the runner - # On 2024-09-28 postgresql@17 installation failed but the package is - # available. So, in a few days, we might be able to drop "brew update". + - name: Install gaussdb libpq driver run: | - brew update - brew install gnu-sed postgresql@${PG_VERSION} - - - name: Start PostgreSQL service - run: brew services start postgresql@${PG_VERSION} + sudo apt update + sudo apt install -y wget unzip + wget -O /tmp/GaussDB_driver.zip https://dbs-download.obs.cn-north-1.myhuaweicloud.com/GaussDB/1730887196055/GaussDB_driver.zip + unzip /tmp/GaussDB_driver.zip -d /tmp/ && rm -rf /tmp/GaussDB_driver.zip + \cp /tmp/GaussDB_driver/Centralized/Hce2_X86_64/GaussDB-Kernel*64bit_Python.tar.gz /tmp/ + tar -zxvf /tmp/GaussDB-Kernel*64bit_Python.tar.gz -C /tmp/ && rm -rf /tmp/GaussDB-Kernel*64bit_Python.tar.gz && rm -rf /tmp/_GaussDB && rm -rf /tmp/GaussDB_driver + echo /tmp/lib | sudo tee /etc/ld.so.conf.d/gauss-libpq.conf + sudo sed -i '1s|^|/tmp/lib\n|' /etc/ld.so.conf + sudo ldconfig + ldconfig -p | grep pq - - name: Find the libpq - if: ${{ matrix.impl == 'python' }} + - name: Install dependencies run: | - echo "DYLD_LIBRARY_PATH=/usr/local/opt/postgresql@${PG_VERSION}/lib/postgresql:$DYLD_LIBRARY_PATH" \ - >> $GITHUB_ENV + source venv/bin/activate + python -m pip install --upgrade pip + pip install -r requirements.txt + pip install ./tools/isort-gaussdb/ + pip install "./gaussdb[dev,test]" + pip install ./gaussdb_pool - - name: Include gaussdb-c to the packages to install - if: ${{ matrix.impl == 'c' }} + + - name: Wait for openGauss to be ready + env: + GSQL_PASSWORD: Passwd@123 run: | - echo "DEPS=$DEPS ./gaussdb_c" >> $GITHUB_ENV - echo "PATH=/usr/local/opt/postgresql@${PG_VERSION}/bin:$PATH" >> $GITHUB_ENV - - - name: Install Python packages - run: pip install $DEPS + source venv/bin/activate + for i in {1..30}; do + pg_isready -h localhost -p 5432 -U root && break + sleep 10 + done + if ! pg_isready -h localhost -p 5432 -U root; then + echo "openGauss is not ready" + exit 1 + fi - - name: Run tests - run: ./tools/ci/ci_test.sh - - - # }}} - - windows: # {{{ - runs-on: windows-latest - if: true - - strategy: - fail-fast: false - matrix: - include: - - {impl: python, python: "3.9"} - - {impl: python, python: "3.10"} - - {impl: python, python: "3.11"} - - {impl: python, python: "3.12"} - - {impl: python, python: "3.13"} - - {impl: c, python: "3.9"} - - {impl: c, python: "3.10"} - - {impl: c, python: "3.11"} - - {impl: c, python: "3.12"} - - {impl: c, python: "3.13"} - - env: - GAUSSDB_IMPL: ${{ matrix.impl }} - DEPS: ./gaussdb[test] ./gaussdb_pool - GAUSSDB_TEST_DSN: "host=127.0.0.1 dbname=postgres" - # On windows pproxy doesn't seem very happy. Also a few timing test fail. - NOT_MARKERS: "timing proxy mypy" - PG_VERSION: "17.4" - - defaults: - run: - shell: bash - - steps: - # there are some extra libpq.dll in PATH - - run: rm -rf c:/tools/php C:/Strawberry/c/bin - - - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python }} - allow-prereleases: true - - - name: Start PostgreSQL service + - name: Create test database run: | - $PgSvc = Get-Service "postgresql*" - Set-Service $PgSvc.Name -StartupType manual - $PgSvc.Start() - shell: powershell - - # Refcount tests are flakey on windows, often they fail with the likes of: - # - # AssertionError: objects leaked: 0, -2 - # - # Avoid the morning bother of a failed workflow. - - name: Exclude refcount tests in daily tests - if: ${{ github.event_name == 'schedule' }} - run: echo "NOT_MARKERS=$NOT_MARKERS refcount" >> $GITHUB_ENV - - - uses: prefix-dev/setup-pixi@v0.8.4 - with: - run-install: false - - - run: pixi global install libpq=${{ env.PG_VERSION }} - - - name: 'add libpq.dll to path' - run: echo "$(pg_config.exe --bindir)" >> $GITHUB_PATH + docker exec opengauss-custom bash -c "su - omm -c 'gsql -d postgres -c \"CREATE DATABASE test DBCOMPATIBILITY '\''PG'\'';\"'" - - name: Install delvewheel - run: .\tools\ci\wheel_win32_before_build.bat - shell: powershell - - - name: Build the C wheel - if: ${{ matrix.impl == 'c' }} + - name: Create report directory run: | - # If the wheel is not delocated, import fails with some dll not found - # (but it won't tell which one). - pip wheel -v -w ./gaussdb_c/dist/ ./gaussdb_c/ - delvewheel repair --no-mangle "libiconv-2.dll;libwinpthread-1.dll" \ - -w ./wheelhouse/ gaussdb_c/dist/gaussdb*.whl - echo "DEPS=$DEPS $(ls ./wheelhouse/*.whl)" >> $GITHUB_ENV - - - name: Install Python packages - run: pip install $DEPS + mkdir -p reports - name: Run tests - run: ./tools/ci/ci_test.sh - - - # }}} - - crdb: # {{{ - runs-on: ubuntu-latest - if: true - - strategy: - fail-fast: false - matrix: - include: - # Releases: https://www.cockroachlabs.com/docs/releases/ - # Images: https://console.cloud.google.com/artifacts/docker/cockroach-cloud-images/us/cockroachdb/cockroach - # - # Also useful: - # - # curl -fsSL -X GET \ - # https://us-docker.pkg.dev/v2/cockroach-cloud-images/cockroachdb/cockroach/tags/list \ - # | jq .tags | egrep 'latest-[^-]+-build' | sort - - {impl: c, crdb: "latest-master-build", python: "3.13"} - - {impl: c, crdb: "latest-v25.1-build", python: "3.13", libpq: newest} - - {impl: c, crdb: "latest-v24.3-build", python: "3.9", libpq: newest} - - {impl: python, crdb: "latest-v23.2-build", python: "3.12"} - env: - GAUSSDB_IMPL: ${{ matrix.impl }} - DEPS: ./gaussdb[test] ./gaussdb_pool - GAUSSDB_TEST_DSN: "host=127.0.0.1 port=26257 user=root dbname=defaultdb" - CRDB_REPO: us-docker.pkg.dev/cockroach-cloud-images/cockroachdb/cockroach - # Since CRDB 25.1, 'on' should become the default, which will break - # the test suite assumption. - # https://www.cockroachlabs.com/docs/stable/online-schema-changes#enable-automatic-commit-before-running-schema-changes-inside-transactions - PGOPTIONS: "-c autocommit_before_ddl=off" - - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python }} - - - name: Start CockroachDB service - # Note: this would love to be a service, but I don't see a way to pass - # the args to the docker run command line. + env: + PYTHONPATH: ./gaussdb:./gaussdb_pool + GAUSSDB_IMPL: python + GAUSSDB_TEST_DSN: "host=127.0.0.1 port=5432 dbname=test user=root password=Passwd@123 " run: | - docker pull ${CRDB_REPO}:${{ matrix.crdb }} - docker run --rm -d --name crdb -p 26257:26257 ${CRDB_REPO}:${{ matrix.crdb }} \ - start-single-node --insecure - - - name: Install the wanted libpq version - run: sudo ./tools/ci/ci_install_libpq.sh ${{ matrix.libpq }} + source venv/bin/activate + pytest -s -v - - name: Include gaussdb-c to the packages to install - if: ${{ matrix.impl == 'c' }} + - name: Cleanup + if: always() run: | - echo "DEPS=$DEPS ./gaussdb_c" >> $GITHUB_ENV - - - name: Install Python packages - run: pip install $DEPS - - - name: Run tests - run: ./tools/ci/ci_test.sh - - - # }}} + docker stop opengauss-custom + docker rm opengauss-custom diff --git a/README.rst b/README.rst index 14ec844f9..a10ab67d9 100644 --- a/README.rst +++ b/README.rst @@ -1,74 +1,98 @@ -gaussdb -- PostgreSQL database adapter for Python +gaussdb -- GaussDB database adapter for Python =================================================== -gaussdb is a modern implementation of a PostgreSQL adapter for Python. +**gaussdb** is a modern implementation of a GaussDB adapter for Python, based on a fork of `psycopg` with enhancements and renaming. +.. _Hacking: -Installation ------------- +Hacking +------- -Quick version:: +In order to work on the GaussDB source code, you must have the +``libpq`` GaussDB client library installed on the system. For instance, on +EulerOS x86_64 systems, you can obtain it by running:: - pip install --upgrade pip # upgrade pip to at least 20.3 - pip install "gaussdb[binary,pool]" # install binary dependencies + # Update the system package index + sudo apt update -For further information about installation please check `the documentation`__. + # Install required tools + sudo apt install -y wget unzip -.. __: https://www.gaussdb.org/gaussdb/docs/basic/install.html + # Download the GaussDB driver package + wget -O /tmp/GaussDB_driver.zip https://dbs-download.obs.cn-north-1.myhuaweicloud.com/GaussDB/1730887196055/GaussDB_driver.zip + # Extract the driver package and remove the zip file + unzip /tmp/GaussDB_driver.zip -d /tmp/ + rm -rf /tmp/GaussDB_driver.zip -.. _Hacking: + # Copy the Python driver tarball to /tmp + \cp /tmp/GaussDB_driver/Centralized/Hce2_X86_64/GaussDB-Kernel*64bit_Python.tar.gz /tmp/ -Hacking -------- - -In order to work on the GaussDB source code, you must have the -``libpq`` PostgreSQL client library installed on the system. For instance, on -Debian systems, you can obtain it by running:: + # Extract the driver tarball and clean up + tar -zxvf /tmp/GaussDB-Kernel*64bit_Python.tar.gz -C /tmp/ + rm -rf /tmp/GaussDB-Kernel*64bit_Python.tar.gz + rm -rf /tmp/_GaussDB + rm -rf /tmp/GaussDB_driver - sudo apt install libpq5 + # Register /tmp/lib in the dynamic linker configuration + echo /tmp/lib | sudo tee /etc/ld.so.conf.d/gauss-libpq.conf + sudo sed -i '1s|^|/tmp/lib\n|' /etc/ld.so.conf -On macOS, run:: + # Refresh the dynamic linker cache + sudo ldconfig - brew install libpq + # Verify libpq is registered, the first line should show the path: + # libpq.so.5.5 (libc6,x86-64) => /tmp/lib/libpq.so.5.5 + ldconfig -p | grep pq -On Windows you can use EnterpriseDB's `installers`__ to obtain ``libpq`` -which is included in the Command Line Tools. -.. __: https://www.enterprisedb.com/downloads/postgres-postgresql-downloads You can then clone this repository to develop GaussDB:: - git clone https://github.com/gaussdb/gaussdb.git - cd gaussdb + # Create a new Python virtual environment in the .venv directory + python -m venv .venv + + # Activate the virtual environment + source .venv/bin/activate + + # Clone the GaussDB Python repository from GitHub + # This will create a new directory named gaussdb-python in the current directory + git clone https://github.com/HuaweiCloudDeveloper/gaussdb-python.git + + # Change into the cloned repository directory + cd gaussdb-python Please note that the repository contains the source code of several Python packages, which may have different requirements: - The ``gaussdb`` directory contains the pure python implementation of - ``gaussdb``. The package has only a runtime dependency on the ``libpq``, the - PostgreSQL client library, which should be installed in your system. - -- The ``gaussdb_c`` directory contains an optimization module written in - C/Cython. In order to build it you will need a few development tools: please - look at `Local installation`__ in the docs for the details. + ``gaussdb``. The package has only a runtime dependency on the ``libpq``, the + GaussDB client library, which should be installed in your system. -- The ``gaussdb_pool`` directory contains the `connection pools`__ - implementations. This is kept as a separate package to allow a different - release cycle. - -.. __: https://www.gaussdb.org/gaussdb/docs/basic/install.html#local-installation -.. __: https://www.gaussdb.org/gaussdb/docs/advanced/pool.html +- The ``gaussdb_pool`` directory contains the `connection pools` + implementations. This is kept as a separate package to allow a different + release cycle. You can create a local virtualenv and install the packages `in development mode`__, together with their development and testing requirements:: - python -m venv .venv - source .venv/bin/activate - pip install -e "./gaussdb[dev,test]" # for the base Python package - pip install -e ./gaussdb_pool # for the connection pool - pip install ./gaussdb_c # for the C speedup module + # Upgrade pip to the latest version to ensure compatibility with modern packages + pip install --upgrade pip + + # Install all required dependencies listed in the requirements.txt file + pip install -r requirements.txt + + # Install the custom isort plugin located in the tools/isort-gaussdb directory + pip install ./tools/isort-gaussdb/ + + # Install the main gaussdb package in editable (development) mode, + # along with optional 'dev' and 'test' dependencies + pip install -e "./gaussdb[dev,test]" + + # Install the gaussdb_pool package in editable mode (for development and testing) + pip install -e ./gaussdb_pool + .. __: https://pip.pypa.io/en/stable/topics/local-project-installs/#editable-installs @@ -77,27 +101,77 @@ Please add ``--config-settings editable_mode=strict`` to the ``pip install .. __: https://github.com/pypa/setuptools/issues/3557 -Now hack away! You can run the tests using:: +Now hack away! You can run the tests using on GaussDB:: + + # Create a new database named "test" with PostgreSQL compatibility enabled + gsql -c 'CREATE DATABASE test DBCOMPATIBILITY 'PG' ;' + + # Set the Python import path to include your local GaussDB Python project + # Replace your_path with actual values + export PYTHONPATH=/your_path/gaussdb-python + + # Select the pure-Python implementation of the GaussDB adapter + export PSYCOPG_IMPL=python + + # Set the test DSN (Data Source Name) as an environment variable + # Replace db_username, your_password, db_address with actual values + export GAUSSDB_TEST_DSN="dbname=test user=db_username password=your_password host=db_address port=8000" + + # Run all tests using pytest, showing verbose output and test durations + pytest --durations=0 -s -v + +Recommended Steps to Run OpenGauss with Python GaussDB Driver Testing (Assuming Docker is Installed):: + + # Pull the latest OpenGauss server image from Docker Hub + docker pull opengauss/opengauss-server:latest + + # Run a new OpenGauss container in the background with: + # - custom container name "opengauss-custom" + # - privileged mode enabled + # - root user credentials set via environment variables + # - port 5432 exposed + docker run --name opengauss-custom --privileged=true -d \ + -e GS_USERNAME=root \ + -e GS_USER_PASSWORD=Passwd@123 \ + -e GS_PASSWORD=Passwd@123 \ + -p 5432:5432 \ + opengauss/opengauss-server:latest + + # Enter the running container with an interactive bash shell + docker exec -it opengauss-custom bash + + # Switch to the default OpenGauss database user "omm" + su - omm + + # Connect to the OpenGauss database using the gsql client + gsql -d postgres -p 5432 -U omm + + -- Create a new database named "test" with PostgreSQL compatibility enabled + CREATE DATABASE test DBCOMPATIBILITY 'PG'; + + + # Set the Python import path to include your local GaussDB Python project + # Replace your_path with actual values + export PYTHONPATH=/your_path/gaussdb-python + + # Select the pure-Python implementation of the GaussDB adapter + export PSYCOPG_IMPL=python + + # Set the test DSN (Data Source Name) as an environment variable + export GAUSSDB_TEST_DSN="dbname=test user=root password=Passwd@123 host=localhost port=5432" + + # Run all tests using pytest, showing verbose output and test durations + pytest --durations=0 -s -v - psql -c 'create database gaussdb_test' - export GAUSSDB_TEST_DSN="dbname=gaussdb_test" - pytest The library includes some pre-commit hooks to check that the code is valid according to the project coding convention. Please make sure to install them by running:: pre-commit install + pre-commit install-hooks + pre-commit run --all-files This will allow to check lint errors before submitting merge requests, which will save you time and frustrations. - -Cross-compiling ---------------- - -To use cross-platform zipapps created with `shiv`__ that include GaussDB -as a dependency you must also have ``libpq`` installed. See -`the section above `_ for install instructions. - -.. __: https://github.com/linkedin/shiv diff --git a/docs/advanced/adapt.rst b/docs/advanced/adapt.rst index 2c9ce1d62..e781c3c44 100644 --- a/docs/advanced/adapt.rst +++ b/docs/advanced/adapt.rst @@ -6,13 +6,13 @@ Data adaptation configuration ============================= The adaptation system is at the core of GaussDB and allows to customise the -way Python objects are converted to PostgreSQL when a query is performed and -how PostgreSQL values are converted to Python objects when query results are +way Python objects are converted to GaussDB when a query is performed and +how GaussDB values are converted to Python objects when query results are returned. .. note:: For a high-level view of the conversion of types between Python and - PostgreSQL please look at :ref:`query-parameters`. Using the objects + GaussDB please look at :ref:`query-parameters`. Using the objects described in this page is useful if you intend to *customise* the adaptation rules. @@ -36,14 +36,14 @@ returned. - The `!adapters` attributes are `AdaptersMap` instances, and contain the mapping from Python types and `~gaussdb.abc.Dumper` classes, and from - PostgreSQL OIDs to `~gaussdb.abc.Loader` classes. Changing this mapping + GaussDB OIDs to `~gaussdb.abc.Loader` classes. Changing this mapping (e.g. writing and registering your own adapters, or using a different configuration of builtin adapters) affects how types are converted between - Python and PostgreSQL. + Python and GaussDB. - Dumpers (objects implementing the `~gaussdb.abc.Dumper` protocol) are the objects used to perform the conversion from a Python object to a bytes - sequence in a format understood by PostgreSQL. The string returned + sequence in a format understood by GaussDB. The string returned *shouldn't be quoted*: the value will be passed to the database using functions such as :pq:`PQexecParams()` so quoting and quotes escaping is not necessary. The dumper usually also suggests to the server what type to @@ -51,7 +51,7 @@ returned. - Loaders (objects implementing the `~gaussdb.abc.Loader` protocol) are the objects used to perform the opposite operation: reading a bytes - sequence from PostgreSQL and creating a Python object out of it. + sequence from GaussDB and creating a Python object out of it. - Dumpers and loaders are instantiated on demand by a `~Transformer` object when a query is executed. @@ -93,7 +93,7 @@ Postgres and back. `~AdaptersMap.register_dumper()` will be used. - Sometimes, just looking at the Python type is not enough to decide the - best PostgreSQL type to use (for instance the PostgreSQL type of a Python + best GaussDB type to use (for instance the GaussDB type of a Python list depends on the objects it contains, whether to use an :sql:`integer` or :sql:`bigint` depends on the number size...) In these cases the mechanism provided by `~gaussdb.abc.Dumper.get_key()` and @@ -110,7 +110,7 @@ Postgres and back. GaussDB will select either text loaders or binary loaders (identified by their `~gaussdb.abc.Loader.format` attribute). -- Recursive types (e.g. Python lists, PostgreSQL arrays and composite types) +- Recursive types (e.g. Python lists, GaussDB arrays and composite types) will use the same adaptation rules. As a consequence it is possible to perform certain choices only once per query @@ -130,7 +130,7 @@ Writing a custom adapter: XML GaussDB doesn't provide adapters for the XML data type, because there are just too many ways of handling XML in Python. Creating a loader to parse the -`PostgreSQL xml type`__ to `~xml.etree.ElementTree` is very simple, using the +`GaussDB xml type`__ to `~xml.etree.ElementTree` is very simple, using the `gaussdb.adapt.Loader` base class and implementing the `~gaussdb.abc.Loader.load()` method: @@ -159,7 +159,7 @@ too many ways of handling XML in Python. Creating a loader to parse the >>> elem -The opposite operation, converting Python objects to PostgreSQL, is performed +The opposite operation, converting Python objects to GaussDB, is performed by dumpers. The `gaussdb.adapt.Dumper` base class makes it easy to implement one: you only need to implement the `~gaussdb.abc.Dumper.dump()` method:: @@ -236,10 +236,10 @@ to return `!None` upon empty or whitespace-only strings:: .. _adapt-example-float: -Example: PostgreSQL numeric to Python float +Example: GaussDB numeric to Python float ------------------------------------------- -Normally PostgreSQL :sql:`numeric` values are converted to Python +Normally GaussDB :sql:`numeric` values are converted to Python `~decimal.Decimal` instances, because both the types allow fixed-precision arithmetic and are not subject to rounding. @@ -251,7 +251,7 @@ errors). If you are fine with the potential loss of precision and you simply want to receive :sql:`numeric` values as Python `!float`, you can register on :sql:`numeric` the same `Loader` class used to load -:sql:`float4`\/:sql:`float8` values. Because the PostgreSQL textual +:sql:`float4`\/:sql:`float8` values. Because the GaussDB textual representation of both floats and decimal is the same, the two loaders are compatible. @@ -277,7 +277,7 @@ Example: handling infinity date ------------------------------- Suppose you want to work with the "infinity" date which is available in -PostgreSQL but not handled by Python: +GaussDB but not handled by Python: .. code:: python @@ -286,7 +286,7 @@ PostgreSQL but not handled by Python: ... DataError: date too large (after year 10K): 'infinity' -One possibility would be to store Python's `datetime.date.max` as PostgreSQL +One possibility would be to store Python's `datetime.date.max` as GaussDB infinity. For this, let's create a subclass for the dumper and the loader and register them in the working scope (globally or just on a connection or cursor): diff --git a/docs/advanced/async.rst b/docs/advanced/async.rst index 3b3224e0d..ac6f33350 100644 --- a/docs/advanced/async.rst +++ b/docs/advanced/async.rst @@ -200,7 +200,7 @@ An async connection provides similar behavior in that if the async task is cancelled, any operation on the connection will similarly be cancelled. This can happen either indirectly via Ctrl-C or similar signal, or directly by cancelling the Python Task via the normal way. GaussDB will ask the -PostgreSQL postmaster to cancel the operation when it encounters the standard +GaussDB postmaster to cancel the operation when it encounters the standard Python `CancelledError`__. Remember that cancelling the Python Task does not guarantee that the operation @@ -251,7 +251,7 @@ Unlike with `!_GaussDB`, using the `!psycogreen` module is not required. Server messages --------------- -PostgreSQL can send, together with the query results, `informative messages`__ +GaussDB can send, together with the query results, `informative messages`__ about the operation just performed, such as warnings or debug information. Notices may be raised even if the operations are successful and don't indicate an error. You are probably familiar with some of them, because they are @@ -318,8 +318,8 @@ Asynchronous notifications -------------------------- GaussDB allows asynchronous interaction with other database sessions using the -facilities offered by PostgreSQL commands |LISTEN|_ and |NOTIFY|_. Please -refer to the PostgreSQL documentation for examples about how to use this form +facilities offered by GaussDB commands |LISTEN|_ and |NOTIFY|_. Please +refer to the GaussDB documentation for examples about how to use this form of communication. .. |LISTEN| replace:: :sql:`LISTEN` diff --git a/docs/advanced/cursors.rst b/docs/advanced/cursors.rst index c853eb3fc..e48785739 100644 --- a/docs/advanced/cursors.rst +++ b/docs/advanced/cursors.rst @@ -8,7 +8,7 @@ Cursor types ============ -Cursors are objects used to send commands to a PostgreSQL connection and to +Cursors are objects used to send commands to a GaussDB connection and to manage the results returned by it. They are normally created by the connection's `~Connection.cursor()` method. @@ -27,7 +27,7 @@ aspects such as: performance in everyday usage. - Are queries manipulated by Python (to handle placeholders in ``%s`` and - ``%(name)s`` Python-style) or sent as they are to the PostgreSQL server + ``%(name)s`` Python-style) or sent as they are to the GaussDB server (which only supports ``$1``, ``$2`` parameters)? GaussDB exposes the following classes to implement the different strategies. @@ -94,7 +94,7 @@ server-side; in particular no Data Definition Language query can. See The `ClientCursor` (and its `AsyncClientCursor` async counterpart) merge the query on the client and send the query and the parameters merged together to -the server. This allows to parametrize any type of PostgreSQL statement, not +the server. This allows to parametrize any type of GaussDB statement, not only queries (:sql:`SELECT`) and Data Manipulation statements (:sql:`INSERT`, :sql:`UPDATE`, :sql:`DELETE`). @@ -156,7 +156,7 @@ Simple query protocol Using the `!ClientCursor` should ensure that gaussdb will always use the `simple query protocol`__ for querying. In most cases, the choice of the -fronted/backend protocol used is transparent on PostgreSQL. However, in some +fronted/backend protocol used is transparent on GaussDB. However, in some case using the simple query protocol is mandatory. This is the case querying the `PgBouncer admin console`__ for instance, which doesn't support the extended query protocol. @@ -199,7 +199,7 @@ extended query protocol. Server-side cursors ------------------- -PostgreSQL has its own concept of *cursor* too (sometimes also called +GaussDB has its own concept of *cursor* too (sometimes also called *portal*). When a database cursor is created, the query is not necessarily completely processed: the server might be able to produce results only as they are needed. Only the results requested are transmitted to the client: if the @@ -227,7 +227,7 @@ result is needed. .. seealso:: Server-side cursors are created and managed by `ServerCursor` using SQL - commands such as DECLARE_, FETCH_, MOVE_. The PostgreSQL documentation + commands such as DECLARE_, FETCH_, MOVE_. The GaussDB documentation gives a good idea of what is possible to do with them. .. _DECLARE: https://www.postgresql.org/docs/current/sql-declare.html @@ -282,10 +282,10 @@ Raw query cursors .. versionadded:: 3.2 -The `RawCursor` and `AsyncRawCursor` classes allow users to use PostgreSQL +The `RawCursor` and `AsyncRawCursor` classes allow users to use GaussDB native placeholders (``$1``, ``$2``, etc.) in their queries instead of the standard ``%s`` placeholder. This can be useful when it's desirable to pass -the query unmodified to PostgreSQL and rely on PostgreSQL's placeholder +the query unmodified to GaussDB and rely on GaussDB's placeholder functionality, such as when dealing with a very complex query containing ``%s`` inside strings, dollar-quoted strings or elsewhere. @@ -295,7 +295,7 @@ in the form of a list or tuple. This means you cannot use named arguments `!RawCursor` behaves like `Cursor`, in returning the complete result from the server to the client. The `RawServerCursor` and `AsyncRawServerCursor` -implement :ref:`server-side-cursors` with raw PostgreSQL placeholders. +implement :ref:`server-side-cursors` with raw GaussDB placeholders. There are two ways to use raw query cursors: diff --git a/docs/advanced/pipeline.rst b/docs/advanced/pipeline.rst index 4cdfaa708..802f19406 100644 --- a/docs/advanced/pipeline.rst +++ b/docs/advanced/pipeline.rst @@ -7,7 +7,7 @@ Pipeline mode support .. versionadded:: 3.1 -The *pipeline mode* allows PostgreSQL client applications to send a query +The *pipeline mode* allows GaussDB client applications to send a query without having to read the result of the previously sent query. Taking advantage of the pipeline mode, a client will wait less for the server, since multiple queries/results can be sent/received in a single network roundtrip. @@ -30,7 +30,7 @@ buffered on the server side; the server flushes that buffer when a .. seealso:: - The PostgreSQL documentation about: + The GaussDB documentation about: - `pipeline mode`__ - `extended query message flow`__ @@ -46,7 +46,7 @@ Client-server messages flow --------------------------- In order to understand better how the pipeline mode works, we should take a -closer look at the `PostgreSQL client-server message flow`__. +closer look at the `GaussDB client-server message flow`__. During normal querying, each statement is transmitted by the client to the server as a stream of request messages, terminating with a **Sync** message to @@ -73,10 +73,10 @@ results in the following two groups of messages: | | :ref:`the statement is prepared `) | | |>| | - Bind ``'hello'`` | | | - Describe | - | PostgreSQL | - Execute | + | GaussDB | - Execute | | | - Sync | +---------------+-----------------------------------------------------------+ - | PostgreSQL | - ParseComplete | + | GaussDB | - ParseComplete | | | - BindComplete | | |<| | - NoData | | | - CommandComplete ``INSERT 0 1`` | @@ -101,9 +101,9 @@ results in the two groups of messages: | | - Bind ``1`` | | |>| | - Describe | | | - Execute | - | PostgreSQL | - Sync | + | GaussDB | - Sync | +---------------+-----------------------------------------------------------+ - | PostgreSQL | - ParseComplete | + | GaussDB | - ParseComplete | | | - BindComplete | | |<| | - RowDescription ``data`` | | | - DataRow ``hello`` | @@ -136,13 +136,13 @@ they will result in a single roundtrip between the client and the server: | | - Bind ``'hello'`` | | |>| | - Describe | | | - Execute | - | PostgreSQL | - Parse ``SELECT data FROM mytable WHERE id = $1`` | + | GaussDB | - Parse ``SELECT data FROM mytable WHERE id = $1`` | | | - Bind ``1`` | | | - Describe | | | - Execute | | | - Sync (sent only once) | +---------------+-----------------------------------------------------------+ - | PostgreSQL | - ParseComplete | + | GaussDB | - ParseComplete | | | - BindComplete | | |<| | - NoData | | | - CommandComplete ``INSERT 0 1`` | @@ -198,7 +198,7 @@ synchronization point. Certain features are not available in pipeline mode, including: - - COPY is not supported in pipeline mode by PostgreSQL. + - COPY is not supported in pipeline mode by GaussDB. - `Cursor.stream()` doesn't make sense in pipeline mode (its job is the opposite of batching!) - `ServerCursor` are currently not implemented in pipeline mode. @@ -300,7 +300,7 @@ The fine prints bugs and shortcomings forcing us to change the current interface or behaviour. -The pipeline mode is available on any currently supported PostgreSQL version, -but, in order to make use of it, the client must use a libpq from PostgreSQL +The pipeline mode is available on any currently supported GaussDB version, +but, in order to make use of it, the client must use a libpq from GaussDB 14 or higher. You can use the `~Capabilities.has_pipeline` capability to make sure your client has the right library. diff --git a/docs/api/abc.rst b/docs/api/abc.rst index dd6eebbd9..4db81e077 100644 --- a/docs/api/abc.rst +++ b/docs/api/abc.rst @@ -50,7 +50,7 @@ checking. .. autoattribute:: oid - If the OID is not specified, PostgreSQL will try to infer the type + If the OID is not specified, GaussDB will try to infer the type from the context, but this may fail in some contexts and may require a cast (e.g. specifying :samp:`%s::{type}` for its placeholder). diff --git a/docs/api/adapt.rst b/docs/api/adapt.rst index fdc1eec14..cb0dd5255 100644 --- a/docs/api/adapt.rst +++ b/docs/api/adapt.rst @@ -5,7 +5,7 @@ The `!gaussdb.adapt` module exposes a set of objects useful for the configuration of *data adaptation*, which is the conversion of Python objects -to PostgreSQL data types and back. +to GaussDB data types and back. These objects are useful if you need to configure data adaptation, i.e. if you need to change the default way that GaussDB converts between types or diff --git a/docs/api/connections.rst b/docs/api/connections.rst index b4c2846dd..9b283f9b9 100644 --- a/docs/api/connections.rst +++ b/docs/api/connections.rst @@ -4,7 +4,7 @@ Connection classes ================== The `Connection` and `AsyncConnection` classes are the main wrappers for a -PostgreSQL database session. You can imagine them similar to a :program:`psql` +GaussDB database session. You can imagine them similar to a :program:`psql` session. One of the differences compared to :program:`psql` is that a `Connection` @@ -259,7 +259,7 @@ The `!Connection` class The `~pq.PGconn` libpq connection wrapper underlying the `!Connection`. - It can be used to send low level commands to PostgreSQL and access + It can be used to send low level commands to GaussDB and access features not currently wrapped by GaussDB. .. autoattribute:: info @@ -310,7 +310,7 @@ The `!Connection` class .. warning:: The `!cancel()` method is implemented using the :pq:`PQcancel` - function, which is deprecated since PostgreSQL 17, and has a few + function, which is deprecated since GaussDB, and has a few shortcomings: - it is blocking even on async connections, @@ -380,7 +380,7 @@ The `!Connection` class The `!xid` may be either an object returned by the `xid()` method or a plain string: the latter allows to create a transaction using the - provided string as PostgreSQL transaction id. See also + provided string as GaussDB transaction id. See also `tpc_recover()`. @@ -393,7 +393,7 @@ The `!Connection` class `tpc_commit()` or `tpc_rollback()` will be called. - .. seealso:: The |PREPARE TRANSACTION|_ PostgreSQL command. + .. seealso:: The |PREPARE TRANSACTION|_ GaussDB command. .. |PREPARE TRANSACTION| replace:: :sql:`PREPARE TRANSACTION` .. _PREPARE TRANSACTION: https://www.postgresql.org/docs/current/static/sql-prepare-transaction.html @@ -418,7 +418,7 @@ The `!Connection` class On return, the TPC transaction is ended. - .. seealso:: The |COMMIT PREPARED|_ PostgreSQL command. + .. seealso:: The |COMMIT PREPARED|_ GaussDB command. .. |COMMIT PREPARED| replace:: :sql:`COMMIT PREPARED` .. _COMMIT PREPARED: https://www.postgresql.org/docs/current/static/sql-commit-prepared.html @@ -439,7 +439,7 @@ The `!Connection` class On return, the TPC transaction is ended. - .. seealso:: The |ROLLBACK PREPARED|_ PostgreSQL command. + .. seealso:: The |ROLLBACK PREPARED|_ GaussDB command. .. |ROLLBACK PREPARED| replace:: :sql:`ROLLBACK PREPARED` .. _ROLLBACK PREPARED: https://www.postgresql.org/docs/current/static/sql-rollback-prepared.html @@ -452,9 +452,9 @@ The `!Connection` class If a transaction was not initiated by GaussDB, the returned Xids will have attributes `~Xid.format_id` and `~Xid.bqual` set to `!None` and - the `~Xid.gtrid` set to the PostgreSQL transaction ID: such Xids are + the `~Xid.gtrid` set to the GaussDB transaction ID: such Xids are still usable for recovery. GaussDB uses the same algorithm of the - `PostgreSQL JDBC driver`__ to encode a XA triple in a string, so + `GaussDB JDBC driver`__ to encode a XA triple in a string, so transactions initiated by a program using such driver should be unpacked correctly. diff --git a/docs/api/crdb.rst b/docs/api/crdb.rst index 6c0d99034..b608e84e6 100644 --- a/docs/api/crdb.rst +++ b/docs/api/crdb.rst @@ -6,7 +6,7 @@ .. versionadded:: 3.1 CockroachDB_ is a distributed database using the same fronted-backend protocol -of PostgreSQL. As such, GaussDB can be used to write Python programs +of GaussDB. As such, GaussDB can be used to write Python programs interacting with CockroachDB. .. _CockroachDB: https://www.cockroachlabs.com/ @@ -19,10 +19,10 @@ mapping tweaked on the CockroachDB data model. .. _crdb-differences: -Main differences from PostgreSQL +Main differences from GaussDB -------------------------------- -CockroachDB behaviour is `different from PostgreSQL`__: please refer to the +CockroachDB behaviour is `different from GaussDB`__: please refer to the database documentation for details. These are some of the main differences affecting GaussDB behaviour: @@ -37,9 +37,9 @@ affecting GaussDB behaviour: - `~gaussdb.ConnectionInfo.backend_pid` is only populated from CockroachDB 22.1. Note however that you cannot use the PID to terminate the session; use `SHOW session_id`_ to find the id of a session, which you may terminate with - `CANCEL SESSION`_ in lieu of PostgreSQL's :sql:`pg_terminate_backend()`. + `CANCEL SESSION`_ in lieu of GaussDB's :sql:`pg_terminate_backend()`. -- Several data types are missing or slightly different from PostgreSQL (see +- Several data types are missing or slightly different from GaussDB (see `adapters` for an overview of the differences). - The :ref:`two-phase commit protocol ` is not supported. @@ -103,11 +103,11 @@ CockroachDB-specific objects The map is used as a template when new connections are created, using `gaussdb.crdb.connect()` (similarly to the way `gaussdb.adapters` is used - as template for new PostgreSQL connections). + as template for new GaussDB connections). This registry contains only the types and adapters supported by - CockroachDB. Several PostgreSQL types and adapters are missing or - different from PostgreSQL, among which: + CockroachDB. Several GaussDB types and adapters are missing or + different from GaussDB, among which: - Composite types - :sql:`range`, :sql:`multirange` types diff --git a/docs/api/cursors.rst b/docs/api/cursors.rst index 0449b82cd..05896e18f 100644 --- a/docs/api/cursors.rst +++ b/docs/api/cursors.rst @@ -4,7 +4,7 @@ Cursor classes ============== The `Cursor` and `AsyncCursor` classes are the main objects to send commands -to a PostgreSQL database session. They are normally created by the +to a GaussDB database session. They are normally created by the connection's `~Connection.cursor()` method. Using the `!name` parameter on `!cursor()` will create a `ServerCursor` or @@ -115,7 +115,7 @@ The `!Cursor` class A typical use case for `!executemany(returning=True)` might be to insert a bunch of records and to retrieve the primary keys - inserted, taken from a PostgreSQL sequence. In order to do so, you + inserted, taken from a GaussDB sequence. In order to do so, you may execute a query such as :sql:`INSERT INTO table VALUES (...) RETURNING id`. Because every :sql:`INSERT` is guaranteed to insert exactly a single record, you can obtain the list of the new ids @@ -170,7 +170,7 @@ The `!Cursor` class .. automethod:: stream This command is similar to execute + iter; however it supports endless - data streams. The feature is not available in PostgreSQL, but some + data streams. The feature is not available in GaussDB, but some implementations exist: Materialize `SUBSCRIBE`__ and CockroachDB `CHANGEFEED`__ for instance. @@ -289,11 +289,11 @@ The `!Cursor` class .. attribute:: _query An helper object used to convert queries and parameters before sending - them to PostgreSQL. + them to GaussDB. .. note:: This attribute is exposed because it might be helpful to debug - problems when the communication between Python and PostgreSQL + problems when the communication between Python and GaussDB doesn't work as expected. For this reason, the attribute is available when a query fails too. @@ -309,15 +309,15 @@ The `!Cursor` class Among the properties currently exposed by this object: - - `!query` (`!bytes`): the query effectively sent to PostgreSQL. It + - `!query` (`!bytes`): the query effectively sent to GaussDB. It will have Python placeholders (``%s``\-style) replaced with - PostgreSQL ones (``$1``, ``$2``\-style). + GaussDB ones (``$1``, ``$2``\-style). - `!params` (sequence of `!bytes`): the parameters passed to - PostgreSQL, adapted to the database format. + GaussDB, adapted to the database format. - `!types` (sequence of `!int`): the OID of the parameters passed to - PostgreSQL. + GaussDB. - `!formats` (sequence of `pq.Format`): whether the parameter format is text or binary. @@ -355,7 +355,7 @@ The `!ServerCursor` class This class also implements a `DBAPI-compliant interface`__. It is created by `Connection.cursor()` specifying the `!name` parameter. Using this - object results in the creation of an equivalent PostgreSQL cursor in the + object results in the creation of an equivalent GaussDB cursor in the server. DBAPI-extension methods (such as `~Cursor.copy()` or `~Cursor.stream()`) are not implemented on this object: use a normal `Cursor` instead. @@ -368,12 +368,12 @@ The `!ServerCursor` class .. autoattribute:: name .. autoattribute:: scrollable - .. seealso:: The PostgreSQL DECLARE_ statement documentation + .. seealso:: The GaussDB DECLARE_ statement documentation for the description of :sql:`[NO] SCROLL`. .. autoattribute:: withhold - .. seealso:: The PostgreSQL DECLARE_ statement documentation + .. seealso:: The GaussDB DECLARE_ statement documentation for the description of :sql:`{WITH|WITHOUT} HOLD`. .. _DECLARE: https://www.postgresql.org/docs/current/sql-declare.html @@ -446,7 +446,7 @@ The `!ServerCursor` class operations. If you need to scroll backwards you should probably call `~Connection.cursor()` using `scrollable=True`. - Note that PostgreSQL doesn't provide a reliable way to report when a + Note that GaussDB doesn't provide a reliable way to report when a cursor moves out of bound, so the method might not raise `!IndexError` when it happens, but it might rather stop at the cursor boundary. @@ -461,7 +461,7 @@ The `!RawCursor` and `!RawServerCursor` class .. autoclass:: RawCursor This `Cursor` subclass has the same interface of the parent class but - supports placeholders in PostgreSQL format (``$1``, ``$2``...) rather than + supports placeholders in GaussDB format (``$1``, ``$2``...) rather than in Python format (``%s``). Only positional parameters are supported. .. versionadded:: 3.2 @@ -470,7 +470,7 @@ The `!RawCursor` and `!RawServerCursor` class .. autoclass:: RawServerCursor This `ServerCursor` subclass has the same interface of the parent class but - supports placeholders in PostgreSQL format (``$1``, ``$2``...) rather than + supports placeholders in GaussDB format (``$1``, ``$2``...) rather than in Python format (``%s``). Only positional parameters are supported. .. versionadded:: 3.2 diff --git a/docs/api/dns.rst b/docs/api/dns.rst index 76ada6501..e2d003342 100644 --- a/docs/api/dns.rst +++ b/docs/api/dns.rst @@ -117,7 +117,7 @@ server before performing a connection. Raise `~gaussdb.OperationalError` if connection is not possible (e.g. no host resolve, inconsistent lists length). - See `the PostgreSQL docs`__ for explanation of how these params are used, + See `the GaussDB docs`__ for explanation of how these params are used, and how they support multiple entries. .. __: https://www.postgresql.org/docs/current/libpq-connect.html diff --git a/docs/api/errors.rst b/docs/api/errors.rst index e5e84b89b..f971a9bce 100644 --- a/docs/api/errors.rst +++ b/docs/api/errors.rst @@ -105,7 +105,7 @@ Error diagnostics All the information available from the :pq:`PQresultErrorField()` function are exposed as attributes by the object. For instance the `!severity` attribute returns the `!PG_DIAG_SEVERITY` code. Please refer to the - PostgreSQL documentation for the meaning of all the attributes. + GaussDB documentation for the meaning of all the attributes. The attributes available are: @@ -156,8 +156,8 @@ in the database: except gaussdb.errors.LockNotAvailable: locked = True -The exception names are generated from the PostgreSQL source code and includes -classes for every error defined by PostgreSQL in versions between 9.6 and 15. +The exception names are generated from the GaussDB source code and includes +classes for every error defined by GaussDB in versions between 9.6 and 15. Every class in the module is named after what referred as "condition name" `in the documentation`__, converted to CamelCase: e.g. the error 22012, ``division_by_zero`` is exposed by this module as the class `!DivisionByZero`. @@ -171,7 +171,7 @@ Every exception class is a subclass of one of the :ref:`standard DB-API exception `, thus exposing the `~gaussdb.Error` interface. .. versionchanged:: 3.1.4 - Added exceptions introduced in PostgreSQL 15. + Added exceptions introduced in GaussDB 15. .. autofunction:: lookup @@ -481,7 +481,7 @@ SQLSTATE Exception Base exception ``57P03`` `!CannotConnectNow` `!OperationalError` ``57P04`` `!DatabaseDropped` `!OperationalError` ``57P05`` `!IdleSessionTimeout` `!OperationalError` -**Class 58** - System Error (errors external to PostgreSQL itself) +**Class 58** - System Error (errors external to GaussDB itself) --------------------------------------------------------------------------------- ``58000`` `!SystemError` `!OperationalError` ``58030`` `!IoError` `!OperationalError` @@ -540,7 +540,7 @@ SQLSTATE Exception Base exception .. autogenerated: end .. versionadded:: 3.1.4 - Exception `!SqlJsonItemCannotBeCastToTargetType`, introduced in PostgreSQL 15. + Exception `!SqlJsonItemCannotBeCastToTargetType`, introduced in GaussDB 15. .. versionadded:: 3.2.3 - Exception `!TransactionTimeout`, introduced in PostgreSQL 17. + Exception `!TransactionTimeout`, introduced in GaussDB 17. diff --git a/docs/api/module.rst b/docs/api/module.rst index 645b84261..dbe6b25b8 100644 --- a/docs/api/module.rst +++ b/docs/api/module.rst @@ -63,13 +63,13 @@ exceptions, mapping to the database error states (see .. data:: adapters - The default adapters map establishing how Python and PostgreSQL types are + The default adapters map establishing how Python and GaussDB types are converted into each other. This map is used as a template when new connections are created, using `gaussdb.connect()`. Its `~gaussdb.adapt.AdaptersMap.types` attribute is a `~gaussdb.types.TypesRegistry` containing information about every - PostgreSQL builtin type, useful for adaptation customisation (see + GaussDB builtin type, useful for adaptation customisation (see :ref:`adaptation`):: >>> gaussdb.adapters.types["int4"] diff --git a/docs/api/objects.rst b/docs/api/objects.rst index c45258be4..95cc9c5bd 100644 --- a/docs/api/objects.rst +++ b/docs/api/objects.rst @@ -39,7 +39,7 @@ Connection information .. autoattribute:: backend_pid .. autoattribute:: vendor - Normally it is `PostgreSQL`; it may be different if connected to + Normally it is `GaussDB`; it may be different if connected to a different database. .. versionadded:: 3.1 @@ -48,7 +48,7 @@ Connection information The number is formed by converting the major, minor, and revision numbers into two-decimal-digit numbers and appending them together. - Starting from PostgreSQL 10 the minor version was dropped, so the + Starting from GaussDB 10 the minor version was dropped, so the second group of digits is always 00. For example, version 9.3.5 is returned as 90305, version 10.2 as 100002. @@ -74,7 +74,7 @@ Connection information .. autoattribute:: hostaddr - Only available if the libpq used is from PostgreSQL 12 or newer. + Only available if the libpq used is from GaussDB 12 or newer. Raise `~gaussdb.NotSupportedError` otherwise. You can use the `~Capabilities.has_hostaddr` capability to check for support. @@ -98,14 +98,14 @@ Connection information conn.info.encoding 'iso8859-15' - A few PostgreSQL encodings are not available in Python and cannot be - selected (currently ``EUC_TW``, ``MULE_INTERNAL``). The PostgreSQL + A few GaussDB encodings are not available in Python and cannot be + selected (currently ``EUC_TW``, ``MULE_INTERNAL``). The GaussDB ``SQL_ASCII`` encoding has the special meaning of "no encoding": see :ref:`adapt-string` for details. .. seealso:: - The `PostgreSQL supported encodings`__. + The `GaussDB supported encodings`__. .. __: https://www.postgresql.org/docs/current/multibyte.html @@ -240,7 +240,7 @@ See :ref:`transactions` for details about these objects. The value is usually used with the `Connection.isolation_level` property. - Check the PostgreSQL documentation for a description of the effects of the + Check the GaussDB documentation for a description of the effects of the different `levels of transaction isolation`__. .. __: https://www.postgresql.org/docs/current/transaction-iso.html @@ -287,7 +287,7 @@ Two-Phase Commit related objects Global Transaction Identifier of the two-phase transaction. - If the Xid doesn't follow the XA standard, it will be the PostgreSQL + If the Xid doesn't follow the XA standard, it will be the GaussDB ID of the transaction (in which case `format_id` and `bqual` will be `!None`). diff --git a/docs/api/pool.rst b/docs/api/pool.rst index a5b1c0511..22ecb29b8 100644 --- a/docs/api/pool.rst +++ b/docs/api/pool.rst @@ -7,7 +7,7 @@ .. module:: gaussdb_pool A connection pool is an object used to create and maintain a limited amount of -PostgreSQL connections, reducing the time requested by the program to obtain a +GaussDB connections, reducing the time requested by the program to obtain a working connection and allowing an arbitrary large number of concurrent threads or tasks to use a controlled amount of resources on the server. See :ref:`connection-pools` for more details and usage pattern. diff --git a/docs/api/pq.rst b/docs/api/pq.rst index f8cb04c21..748c131fd 100644 --- a/docs/api/pq.rst +++ b/docs/api/pq.rst @@ -8,7 +8,7 @@ .. module:: gaussdb.pq -GaussDB is built around the libpq_, the PostgreSQL client library, which +GaussDB is built around the libpq_, the GaussDB client library, which performs most of the network communications and returns query results in C structures. diff --git a/docs/api/sql.rst b/docs/api/sql.rst index d5722a6ac..3fd0b5127 100644 --- a/docs/api/sql.rst +++ b/docs/api/sql.rst @@ -100,7 +100,7 @@ The `!sql` objects are in the following inheritance hierarchy: | `Composable`: the base class exposing the common interface | ``|__`` `SQL`: a literal snippet of an SQL query -| ``|__`` `Identifier`: a PostgreSQL identifier or dot-separated sequence of identifiers +| ``|__`` `Identifier`: a GaussDB identifier or dot-separated sequence of identifiers | ``|__`` `Literal`: a value hardcoded into a query | ``|__`` `Placeholder`: a `%s`\ -style placeholder whose value will be added later e.g. by `~gaussdb.Cursor.execute()` | ``|__`` `Composed`: a sequence of `!Composable` instances. diff --git a/docs/api/types.rst b/docs/api/types.rst index 0f62eb6d1..51050d31b 100644 --- a/docs/api/types.rst +++ b/docs/api/types.rst @@ -9,13 +9,13 @@ The `!gaussdb.types` package exposes: -- objects to describe PostgreSQL types, such as `TypeInfo`, `TypesRegistry`, +- objects to describe GaussDB types, such as `TypeInfo`, `TypesRegistry`, to help or :ref:`customise the types conversion `; - concrete implementations of `~gaussdb.abc.Loader` and `~gaussdb.abc.Dumper` protocols to :ref:`handle builtin data types `; -- helper objects to represent PostgreSQL data types which :ref:`don't have a +- helper objects to represent GaussDB data types which :ref:`don't have a straightforward Python representation `, such as `~range.Range`. @@ -23,7 +23,7 @@ The `!gaussdb.types` package exposes: Types information ----------------- -The `TypeInfo` object describes simple information about a PostgreSQL data +The `TypeInfo` object describes simple information about a GaussDB data type, such as its name, oid and array oid. `!TypeInfo` subclasses may hold more information, for instance the components of a composite type. @@ -32,7 +32,7 @@ which is then used by helper functions, such as `~gaussdb.types.hstore.register_hstore()`, to register adapters on types whose OID is not known upfront or to create more specialised adapters. -The `!TypeInfo` object doesn't instruct GaussDB to convert a PostgreSQL type +The `!TypeInfo` object doesn't instruct GaussDB to convert a GaussDB type into a Python type: this is the role of a `~gaussdb.abc.Loader`. However it can extend the behaviour of other adapters: if you create a loader for `!MyType`, using the `TypeInfo` information, GaussDB will be able to manage @@ -40,7 +40,7 @@ seamlessly arrays of `!MyType` or ranges and composite types using `!MyType` as a subtype. .. seealso:: :ref:`adaptation` describes how to convert from Python objects to - PostgreSQL types and back. + GaussDB types and back. .. code:: python @@ -101,7 +101,7 @@ as a subtype. database as a list of the base type. -In order to get information about dynamic PostgreSQL types, GaussDB offers a +In order to get information about dynamic GaussDB types, GaussDB offers a few `!TypeInfo` subclasses, whose `!fetch()` method can extract more complete information about the type, such as `~gaussdb.types.composite.CompositeInfo`, `~gaussdb.types.range.RangeInfo`, `~gaussdb.types.multirange.MultirangeInfo`, @@ -156,7 +156,7 @@ See :ref:`adapt-json` for details. .. autoclass:: Json .. autoclass:: Jsonb -Wrappers to signal to convert `!obj` to a json or jsonb PostgreSQL value. +Wrappers to signal to convert `!obj` to a json or jsonb GaussDB value. Any object supported by the underlying `!dumps()` function can be wrapped. diff --git a/docs/basic/adapt.rst b/docs/basic/adapt.rst index 215dfab24..5c4aacc7c 100644 --- a/docs/basic/adapt.rst +++ b/docs/basic/adapt.rst @@ -13,7 +13,7 @@ Adapting basic Python types Many standard Python types are adapted into SQL and returned as Python objects when a query is executed. -Converting the following data types between Python and PostgreSQL works +Converting the following data types between Python and GaussDB works out-of-the-box and doesn't require any configuration. In case you need to customise the conversion you should take a look at :ref:`adaptation`. @@ -27,7 +27,7 @@ Booleans adaptation ------------------- Python `bool` values `!True` and `!False` are converted to the equivalent -`PostgreSQL boolean type`__:: +`GaussDB boolean type`__:: >>> cur.execute("SELECT %s, %s", (True, False)) # equivalent to "SELECT true, false" @@ -51,20 +51,20 @@ Numbers adaptation .. seealso:: - - `PostgreSQL numeric types + - `GaussDB numeric types `__ -- Python `int` values can be converted to PostgreSQL :sql:`smallint`, +- Python `int` values can be converted to GaussDB :sql:`smallint`, :sql:`integer`, :sql:`bigint`, or :sql:`numeric`, according to their numeric value. GaussDB will choose the smallest data type available, because - PostgreSQL can automatically cast a type up (e.g. passing a `smallint` where - PostgreSQL expect an `integer` is gladly accepted) but will not cast down + GaussDB can automatically cast a type up (e.g. passing a `smallint` where + GaussDB expect an `integer` is gladly accepted) but will not cast down automatically (e.g. if a function has an :sql:`integer` argument, passing it a :sql:`bigint` value will fail, even if the value is 1). -- Python `float` values are converted to PostgreSQL :sql:`float8`. +- Python `float` values are converted to GaussDB :sql:`float8`. -- Python `~decimal.Decimal` values are converted to PostgreSQL :sql:`numeric`. +- Python `~decimal.Decimal` values are converted to GaussDB :sql:`numeric`. On the way back, smaller types (:sql:`int2`, :sql:`int4`, :sql:`float4`) are promoted to the larger Python counterpart. @@ -73,7 +73,7 @@ promoted to the larger Python counterpart. Sometimes you may prefer to receive :sql:`numeric` data as `!float` instead, for performance reason or ease of manipulation: you can configure - an adapter to :ref:`cast PostgreSQL numeric to Python float + an adapter to :ref:`cast GaussDB numeric to Python float `. This of course may imply a loss of precision. .. versionchanged:: 3.2 @@ -96,10 +96,10 @@ Strings adaptation .. seealso:: - - `PostgreSQL character types + - `GaussDB character types `__ -Python `str` are converted to PostgreSQL string syntax, and PostgreSQL types +Python `str` are converted to GaussDB string syntax, and GaussDB types such as :sql:`text` and :sql:`varchar` are converted back to Python `!str`: .. code:: python @@ -111,7 +111,7 @@ such as :sql:`text` and :sql:`varchar` are converted back to Python `!str`: conn.execute("SELECT entry FROM menu WHERE id = 1").fetchone()[0] 'Crème Brûlée at 4.99€' -PostgreSQL databases `have an encoding`__, and `the session has an encoding`__ +GaussDB databases `have an encoding`__, and `the session has an encoding`__ too, exposed in the `!Connection.info.`\ `~ConnectionInfo.encoding` attribute. If your database and connection are in UTF-8 encoding you will likely have no problem, otherwise you will have to make sure that your @@ -154,7 +154,7 @@ coming from the database, which will be returned as `bytes`: Alternatively you can cast the unknown encoding data to :sql:`bytea` to retrieve it as bytes, leaving other strings unaltered: see :ref:`adapt-binary` -Note that PostgreSQL text cannot contain the ``0x00`` byte. If you need to +Note that GaussDB text cannot contain the ``0x00`` byte. If you need to store Python strings that may contain binary zeros you should use a :sql:`bytea` field. @@ -190,19 +190,19 @@ Date/time types adaptation .. seealso:: - - `PostgreSQL date/time types + - `GaussDB date/time types `__ -- Python `~datetime.date` objects are converted to PostgreSQL :sql:`date`. -- Python `~datetime.datetime` objects are converted to PostgreSQL +- Python `~datetime.date` objects are converted to GaussDB :sql:`date`. +- Python `~datetime.datetime` objects are converted to GaussDB :sql:`timestamp` (if they don't have a `!tzinfo` set) or :sql:`timestamptz` (if they do). -- Python `~datetime.time` objects are converted to PostgreSQL :sql:`time` +- Python `~datetime.time` objects are converted to GaussDB :sql:`time` (if they don't have a `!tzinfo` set) or :sql:`timetz` (if they do). -- Python `~datetime.timedelta` objects are converted to PostgreSQL +- Python `~datetime.timedelta` objects are converted to GaussDB :sql:`interval`. -PostgreSQL :sql:`timestamptz` values are returned with a timezone set to the +GaussDB :sql:`timestamptz` values are returned with a timezone set to the `connection TimeZone setting`__, which is available as a Python `~zoneinfo.ZoneInfo` object in the `!Connection.info`.\ `~ConnectionInfo.timezone` attribute:: @@ -217,7 +217,7 @@ attribute:: .. note:: - PostgreSQL :sql:`timestamptz` doesn't store "a timestamp with a timezone + GaussDB :sql:`timestamptz` doesn't store "a timestamp with a timezone attached": it stores a timestamp always in UTC, which is converted, on output, to the connection TimeZone setting:: @@ -226,7 +226,7 @@ attribute:: >>> conn.execute("SELECT '2042-07-01 12:00Z'::timestamptz").fetchone()[0] # UTC input datetime.datetime(2042, 7, 1, 14, 0, tzinfo=zoneinfo.ZoneInfo(key='Europe/Rome')) - Check out the `PostgreSQL documentation about timezones`__ for all the + Check out the `GaussDB documentation about timezones`__ for all the details. .. __: https://www.postgresql.org/docs/current/datatype-datetime.html @@ -239,7 +239,7 @@ attribute:: too. Although silly, times with timezone are supported both by Python and by - PostgreSQL. However they are only supported with fixed offset timezones: + GaussDB. However they are only supported with fixed offset timezones: Postgres :sql:`timetz` values loaded from the database will result in Python `!time` objects with `!tzinfo` attributes specified as fixed offset, for instance by a `~datetime.timezone` value:: @@ -265,7 +265,7 @@ attribute:: Dates and times limits in Python ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -PostgreSQL date and time objects can represent values that cannot be +GaussDB date and time objects can represent values that cannot be represented by the Python `datetime` objects: - dates and timestamps after the year 9999, the special value "infinity"; @@ -320,7 +320,7 @@ DateStyle or IntervalStyle. JSON adaptation --------------- -GaussDB can map between Python objects and PostgreSQL `json/jsonb +GaussDB can map between Python objects and GaussDB `json/jsonb types`__, allowing to customise the load and dump function used. .. __: https://www.postgresql.org/docs/current/datatype-json.html @@ -388,8 +388,8 @@ take precedence over what is specified by `!set_json_dumps()`. Lists adaptation ---------------- -Python `list` objects are adapted to `PostgreSQL arrays`__ and back. Only -lists containing objects of the same type can be dumped to PostgreSQL (but the +Python `list` objects are adapted to `GaussDB arrays`__ and back. Only +lists containing objects of the same type can be dumped to GaussDB (but the list may contain `!None` elements). .. __: https://www.postgresql.org/docs/current/arrays.html @@ -423,7 +423,7 @@ list may contain `!None` elements). UUID adaptation --------------- -Python `uuid.UUID` objects are adapted to PostgreSQL `UUID type`__ and back:: +Python `uuid.UUID` objects are adapted to GaussDB `UUID type`__ and back:: >>> conn.execute("select gen_random_uuid()").fetchone()[0] UUID('97f0dd62-3bd2-459e-89b8-a5e36ea3c16c') @@ -440,11 +440,11 @@ Python `uuid.UUID` objects are adapted to PostgreSQL `UUID type`__ and back:: Network data types adaptation ----------------------------- -Objects from the `ipaddress` module are converted to PostgreSQL `network +Objects from the `ipaddress` module are converted to GaussDB `network address types`__: - `~ipaddress.IPv4Address`, `~ipaddress.IPv4Interface` objects are converted - to the PostgreSQL :sql:`inet` type. On the way back, :sql:`inet` values + to the GaussDB :sql:`inet` type. On the way back, :sql:`inet` values indicating a single address are converted to `!IPv4Address`, otherwise they are converted to `!IPv4Interface` @@ -473,21 +473,21 @@ Enum adaptation .. versionadded:: 3.1 -GaussDB can adapt Python `~enum.Enum` subclasses into PostgreSQL enum types +GaussDB can adapt Python `~enum.Enum` subclasses into GaussDB enum types (created with the |CREATE TYPE AS ENUM|_ command). .. |CREATE TYPE AS ENUM| replace:: :sql:`CREATE TYPE ... AS ENUM (...)` .. _CREATE TYPE AS ENUM: https://www.postgresql.org/docs/current/static/datatype-enum.html In order to set up a bidirectional enum mapping, you should get information -about the PostgreSQL enum using the `~types.enum.EnumInfo` class and +about the GaussDB enum using the `~types.enum.EnumInfo` class and register it using `~types.enum.register_enum()`. The behaviour of unregistered and registered enums is different. - If the enum is not registered with `register_enum()`: - Pure `!Enum` classes are dumped as normal strings, using their member - names as value. The unknown oid is used, so PostgreSQL should be able to + names as value. The unknown oid is used, so GaussDB should be able to use this string in most contexts (such as an enum or a text field). .. versionchanged:: 3.1 @@ -498,7 +498,7 @@ and registered enums is different. MyIntEnum(int, Enum)` is more specifically an `!int` than an `!Enum`, so it's dumped by default according to `!int` rules). - - PostgreSQL enums are loaded as Python strings. If you want to load arrays + - GaussDB enums are loaded as Python strings. If you want to load arrays of such enums you will have to find their OIDs using `types.TypeInfo.fetch()` and register them using `~types.TypeInfo.register()`. @@ -507,7 +507,7 @@ and registered enums is different. - Enums classes, both pure and mixed-in, are dumped by name. - - The registered PostgreSQL enum is loaded back as the registered Python + - The registered GaussDB enum is loaded back as the registered Python enum members. .. autoclass:: gaussdb.types.enum.EnumInfo @@ -519,7 +519,7 @@ and registered enums is different. .. attribute:: labels After `~gaussdb.types.TypeInfo.fetch()`, it contains the labels defined - in the PostgreSQL enum type. + in the GaussDB enum type. .. attribute:: enum @@ -529,10 +529,10 @@ and registered enums is different. .. autofunction:: gaussdb.types.enum.register_enum After registering, fetching data of the registered enum will cast - PostgreSQL enum labels into corresponding Python enum members. + GaussDB enum labels into corresponding Python enum members. If no `!enum` is specified, a new `Enum` is created based on - PostgreSQL enum labels. + GaussDB enum labels. Example:: @@ -565,13 +565,13 @@ Example:: ... ).fetchone() [, ] -If the Python and the PostgreSQL enum don't match 1:1 (for instance if members +If the Python and the GaussDB enum don't match 1:1 (for instance if members have a different name, or if more than one Python enum should map to the same -PostgreSQL enum, or vice versa), you can specify the exceptions using the +GaussDB enum, or vice versa), you can specify the exceptions using the `!mapping` parameter. `!mapping` should be a dictionary with Python enum members as keys and the -matching PostgreSQL enum labels as values, or a list of `(member, label)` +matching GaussDB enum labels as values, or a list of `(member, label)` pairs with the same meaning (useful when some members are repeated). Order matters: if an element on either side is specified more than once, the last pair in the sequence will take precedence:: @@ -595,7 +595,7 @@ pair in the sequence will take precedence:: >>> conn.execute("SELECT %s::text[]", [list(UserRole)]).fetchone()[0] ['ABBOT', 'MONK', 'GUEST'] -A particularly useful case is when the PostgreSQL labels match the *values* of +A particularly useful case is when the GaussDB labels match the *values* of a `!str`\-based Enum. In this case it is possible to use something like ``{m: m.value for m in enum}`` as mapping:: diff --git a/docs/basic/copy.rst b/docs/basic/copy.rst index 8ca27c1c2..26bd9c772 100644 --- a/docs/basic/copy.rst +++ b/docs/basic/copy.rst @@ -8,7 +8,7 @@ Using COPY TO and COPY FROM =========================== -GaussDB allows to operate with `PostgreSQL COPY protocol`__. :sql:`COPY` is +GaussDB allows to operate with `GaussDB COPY protocol`__. :sql:`COPY` is one of the most efficient ways to load data into the database (and to modify it, with some SQL creativity). @@ -86,7 +86,7 @@ operation, by iterating on `~Copy.rows()`. However this is not something you may want to do normally: usually the normal query process will be easier to use. -PostgreSQL, currently, doesn't give complete type information on :sql:`COPY +GaussDB, currently, doesn't give complete type information on :sql:`COPY TO`, so the rows returned will have unparsed data, as strings or bytes, according to the format. @@ -153,7 +153,7 @@ necessary if the data is copied :ref:`block-by-block ` using .. warning:: - PostgreSQL is particularly finicky when loading data in binary mode and + GaussDB is particularly finicky when loading data in binary mode and will apply **no cast rules**. This means, for example, that passing the value 100 to an `integer` column **will fail**, because GaussDB will pass it as a `smallint` value, and the server will reject it because its size diff --git a/docs/basic/from_pg2.rst b/docs/basic/from_pg2.rst index 4eb3594ca..c434c47b6 100644 --- a/docs/basic/from_pg2.rst +++ b/docs/basic/from_pg2.rst @@ -53,7 +53,7 @@ and with any data definition statement:: LINE 1: CREATE TABLE foo (id int DEFAULT $1) ^ -Sometimes, PostgreSQL offers an alternative: for instance the `set_config()`__ +Sometimes, GaussDB offers an alternative: for instance the `set_config()`__ function can be used instead of the :sql:`SET` statement, the `pg_notify()`__ function can be used instead of :sql:`NOTIFY`:: @@ -110,7 +110,7 @@ Extended query Protocol In order to use :ref:`server-side-binding`, gaussdb normally uses the `extended query protocol`__ to communicate with the backend. -In certain context outside pure PostgreSQL, the extended query protocol is not +In certain context outside pure GaussDB, the extended query protocol is not supported, for instance to query the `PgBouncer admin console`__. In this case you should probably use a `ClientCursor`. See :ref:`simple-query-protocol` for details. @@ -166,7 +166,7 @@ or a :ref:`client-side binding cursor `:: ... gaussdb.errors.ActiveSqlTransaction: CREATE DATABASE cannot run inside a transaction block - This happens because PostgreSQL itself will wrap multiple statements in a + This happens because GaussDB itself will wrap multiple statements in a transaction. Note that you will experience a different behaviour in :program:`psql` (:program:`psql` will split the queries on semicolons and send them to the server separately). @@ -214,7 +214,7 @@ parameters to the query. Different cast rules -------------------- -In rare cases, especially around variadic functions, PostgreSQL might fail to +In rare cases, especially around variadic functions, GaussDB might fail to find a function candidate for the given data types:: >>> conn.execute("SELECT json_build_array(%s, %s)", ["foo", "bar"]) @@ -243,7 +243,7 @@ You cannot use ``IN %s`` with a tuple ^ What you can do is to use the `= ANY()`__ construct and pass the candidate -values as a list instead of a tuple, which will be adapted to a PostgreSQL +values as a list instead of a tuple, which will be adapted to a GaussDB array:: >>> conn.execute("SELECT * FROM foo WHERE id = ANY(%s)", [[10,20,30]]) @@ -271,7 +271,7 @@ You cannot use :sql:`IS %s` or :sql:`IS NOT %s`:: ^ This is probably caused by the fact that :sql:`IS` is not a binary predicate in -PostgreSQL; rather, :sql:`IS NULL` and :sql:`IS NOT NULL` are unary predicates +GaussDB; rather, :sql:`IS NULL` and :sql:`IS NOT NULL` are unary predicates and you cannot use :sql:`IS` with anything else on the right hand side. Testing in psql: @@ -350,7 +350,7 @@ Copy is no longer file-based ---------------------------- `!_GaussDB` exposes :ref:`a few copy methods ` to interact with -PostgreSQL :sql:`COPY`. Their file-based interface doesn't make it easy to load +GaussDB :sql:`COPY`. Their file-based interface doesn't make it easy to load dynamically-generated data into a database. There is now a single `~Cursor.copy()` method, which is similar to @@ -388,7 +388,7 @@ instance to use nested transactions. --------------------- `cursor.callproc()` is not implemented. The method has a simplistic semantic -which doesn't account for PostgreSQL positional parameters, procedures, +which doesn't account for GaussDB positional parameters, procedures, set-returning functions... Use a normal `~Cursor.execute()` with :sql:`SELECT function_name(...)` or :sql:`CALL procedure_name(...)` instead. @@ -430,11 +430,11 @@ default_transaction_read_only__ GUC, for instance executing the statement No default infinity dates handling ---------------------------------- -PostgreSQL can represent a much wider range of dates and timestamps than +GaussDB can represent a much wider range of dates and timestamps than Python. While Python dates are limited to the years between 1 and 9999 (represented by constants such as `datetime.date.min` and -`~datetime.date.max`), PostgreSQL dates extend to BC dates and past the year -10K. Furthermore PostgreSQL can also represent symbolic dates "infinity", in +`~datetime.date.max`), GaussDB dates extend to BC dates and past the year +10K. Furthermore GaussDB can also represent symbolic dates "infinity", in both directions. In _GaussDB, by default, `infinity dates and timestamps map to 'date.max'`__ diff --git a/docs/basic/install.rst b/docs/basic/install.rst index 0f793695d..d0631c3e0 100644 --- a/docs/basic/install.rst +++ b/docs/basic/install.rst @@ -32,9 +32,9 @@ The GaussDB version documented here has *official and tested* support for: - **Note:** Only the pure Python version is supported. -- PostgreSQL: from version 10 to 17 +- GaussDB: from version 10 to 17 - - **Note:** PostgreSQL `currently supported release`__ are actively tested + - **Note:** GaussDB `currently supported release`__ are actively tested in the CI. Out-of-support releases are supported on a best-effort basis. - OS: Linux, macOS, Windows @@ -47,11 +47,11 @@ anything that is not tested there is not officially supported. This includes: .. __: https://github.com/gaussdb/gaussdb/actions - Unofficial Python distributions such as Conda; -- Alternative PostgreSQL implementation; +- Alternative GaussDB implementation; - Other platforms such as BSD or Solaris. If you use an unsupported system, things might work (because, for instance, the -database may use the same wire protocol as PostgreSQL) but we cannot guarantee +database may use the same wire protocol as GaussDB) but we cannot guarantee the correct working or a smooth ride. @@ -130,7 +130,7 @@ In order to perform a local installation you need some prerequisites: - a C compiler, - Python development headers (e.g. the ``python3-dev`` package). -- PostgreSQL client development headers (e.g. the ``libpq-dev`` package). +- GaussDB client development headers (e.g. the ``libpq-dev`` package). - The :program:`pg_config` program available in the :envvar:`PATH`. You **must be able** to troubleshoot an extension build, for instance you must @@ -169,7 +169,7 @@ need:: .. note:: The ``libpq`` is the client library used by :program:`psql`, the - PostgreSQL command line client, to connect to the database. On most + GaussDB command line client, to connect to the database. On most systems, installing :program:`psql` will install the ``libpq`` too as a dependency. diff --git a/docs/basic/params.rst b/docs/basic/params.rst index 8eaf6d3af..481f5cee2 100644 --- a/docs/basic/params.rst +++ b/docs/basic/params.rst @@ -199,7 +199,7 @@ argument of the `Cursor.execute()` method:: Binary parameters and results ----------------------------- -PostgreSQL has two different ways to transmit data between client and server: +GaussDB has two different ways to transmit data between client and server: `~gaussdb.pq.Format.TEXT`, always available, and `~gaussdb.pq.Format.BINARY`, available most of the times but not always. Usually the binary format is more efficient to use. @@ -214,7 +214,7 @@ for a value you can use respectively a ``%b`` placeholder or a ``%t`` placeholder instead of the normal ``%s``. `~Cursor.execute()` will fail if a `~gaussdb.adapt.Dumper` for the right data type and format is not available. -The same two formats, text or binary, are used by PostgreSQL to return data +The same two formats, text or binary, are used by GaussDB to return data from a query to the client. Unlike with parameters, where you can choose the format value-by-value, all the columns returned by a query will have the same format. Every type returned by the query should have a `~gaussdb.adapt.Loader` @@ -222,7 +222,7 @@ configured, otherwise the data will be returned as unparsed `!str` (for text results) or buffer (for binary results). .. note:: - The `pg_type`_ table defines which format is supported for each PostgreSQL + The `pg_type`_ table defines which format is supported for each GaussDB data type. Text input/output is managed by the functions declared in the ``typinput`` and ``typoutput`` fields (always present), binary input/output is managed by the ``typsend`` and ``typreceive`` (which are @@ -230,7 +230,7 @@ results) or buffer (for binary results). .. _pg_type: https://www.postgresql.org/docs/current/catalog-pg-type.html -Because not every PostgreSQL type supports binary output, by default, the data +Because not every GaussDB type supports binary output, by default, the data will be returned in text format. In order to return data in binary format you can create the cursor using `Connection.cursor`\ `!(binary=True)` or execute the query using `Cursor.execute`\ `!(binary=True)`. A case in which diff --git a/docs/basic/pgtypes.rst b/docs/basic/pgtypes.rst index 2ed1466ba..fee1c7acd 100644 --- a/docs/basic/pgtypes.rst +++ b/docs/basic/pgtypes.rst @@ -7,10 +7,10 @@ .. _extra-adaptation: -Adapting other PostgreSQL types +Adapting other GaussDB types =============================== -PostgreSQL offers other data types which don't map to native Python types. +GaussDB offers other data types which don't map to native Python types. GaussDB offers wrappers and conversion functions to allow their use. @@ -24,7 +24,7 @@ GaussDB offers wrappers and conversion functions to allow their use. Composite types casting ----------------------- -GaussDB can adapt PostgreSQL composite types (either created with the |CREATE +GaussDB can adapt GaussDB composite types (either created with the |CREATE TYPE|_ command or implicitly defined after a table row type) to and from Python tuples, `~collections.namedtuple`, or any other suitable object configured. @@ -101,25 +101,25 @@ composite components are registered as well:: Range adaptation ---------------- -PostgreSQL `range types`__ are a family of data types representing a range of +GaussDB `range types`__ are a family of data types representing a range of values between two elements. The type of the element is called the range -*subtype*. PostgreSQL offers a few built-in range types and allows the +*subtype*. GaussDB offers a few built-in range types and allows the definition of custom ones. .. __: https://www.postgresql.org/docs/current/rangetypes.html -All the PostgreSQL range types are loaded as the `~gaussdb.types.range.Range` +All the GaussDB range types are loaded as the `~gaussdb.types.range.Range` Python type, which is a `~typing.Generic` type and can hold bounds of different types. .. autoclass:: gaussdb.types.range.Range This Python type is only used to pass and retrieve range values to and - from PostgreSQL and doesn't attempt to replicate the PostgreSQL range + from GaussDB and doesn't attempt to replicate the GaussDB range features: it doesn't perform normalization and doesn't implement all the operators__ supported by the database. - PostgreSQL will perform normalisation on `!Range` objects used as query + GaussDB will perform normalisation on `!Range` objects used as query parameters, so, when they are fetched back, they will be found in the normal form (for instance ranges on integers will have `[)` bounds). @@ -179,25 +179,25 @@ Example:: Multirange adaptation --------------------- -Since PostgreSQL 14, every range type is associated with a multirange__, a +Since GaussDB, every range type is associated with a multirange__, a type representing a disjoint set of ranges. A multirange is automatically available for every range, built-in and user-defined. .. __: https://www.postgresql.org/docs/current/rangetypes.html -All the PostgreSQL range types are loaded as the +All the GaussDB range types are loaded as the `~gaussdb.types.multirange.Multirange` Python type, which is a mutable sequence of `~gaussdb.types.range.Range` elements. .. autoclass:: gaussdb.types.multirange.Multirange This Python type is only used to pass and retrieve multirange values to - and from PostgreSQL and doesn't attempt to replicate the PostgreSQL + and from GaussDB and doesn't attempt to replicate the GaussDB multirange features: overlapping items are not merged, empty ranges are not discarded, the items are not ordered, the behaviour of `multirange operators`__ is not replicated in Python. - PostgreSQL will perform normalisation on `!Multirange` objects used as + GaussDB will perform normalisation on `!Multirange` objects used as query parameters, so, when they are fetched back, they will be found ordered, with overlapping ranges merged, etc. @@ -256,7 +256,7 @@ Example:: Hstore adaptation ----------------- -The |hstore|_ data type is a key-value store embedded in PostgreSQL. It +The |hstore|_ data type is a key-value store embedded in GaussDB. It supports GiST or GIN indexes allowing search by keys or key/value pairs as well as regular BTree indexes for equality, uniqueness etc. diff --git a/docs/basic/transactions.rst b/docs/basic/transactions.rst index afd8e932f..c937f9b03 100644 --- a/docs/basic/transactions.rst +++ b/docs/basic/transactions.rst @@ -336,7 +336,7 @@ connection. Applications running at `~IsolationLevel.REPEATABLE_READ` or `~IsolationLevel.SERIALIZABLE` isolation level are exposed to serialization - failures. `In certain concurrent update cases`__, PostgreSQL will raise an + failures. `In certain concurrent update cases`__, GaussDB will raise an exception looking like:: _GaussDB.errors.SerializationFailure: could not serialize access @@ -359,7 +359,7 @@ Two-Phase Commit protocol support .. versionadded:: 3.1 -GaussDB exposes the two-phase commit features available in PostgreSQL +GaussDB exposes the two-phase commit features available in GaussDB implementing the `two-phase commit extensions`__ proposed by the DBAPI. The DBAPI model of two-phase commit is inspired by the `XA specification`__, @@ -381,14 +381,14 @@ transaction can be started with `Connection.tpc_begin()`, prepared using database using `~Connection.tpc_recover()` and completed using the above `!tpc_commit()` and `!tpc_rollback()`. -PostgreSQL doesn't follow the XA standard though, and the ID for a PostgreSQL +GaussDB doesn't follow the XA standard though, and the ID for a GaussDB prepared transaction can be any string up to 200 characters long. GaussDB's `Xid` objects can represent both XA-style transactions IDs (such as the ones -created by the `!xid()` method) and PostgreSQL transaction IDs identified by +created by the `!xid()` method) and GaussDB transaction IDs identified by an unparsed string. The format in which the Xids are converted into strings passed to the -database is the same employed by the `PostgreSQL JDBC driver`__: this should +database is the same employed by the `GaussDB JDBC driver`__: this should allow interoperation between tools written in Python and in Java. For example a recovery tool written in Python would be able to recognize the components of transactions produced by a Java program. diff --git a/docs/basic/usage.rst b/docs/basic/usage.rst index 735413510..6af06c536 100644 --- a/docs/basic/usage.rst +++ b/docs/basic/usage.rst @@ -225,7 +225,7 @@ Adapting gaussdb to your program The above :ref:`pattern of use ` only shows the default behaviour of the adapter. GaussDB can be customised in several ways, to allow the smoothest -integration between your Python program and your PostgreSQL database: +integration between your Python program and your GaussDB database: - If your program is concurrent and based on `asyncio` instead of on threads/processes, you can use :ref:`async connections and cursors `. @@ -233,6 +233,6 @@ integration between your Python program and your PostgreSQL database: - If you want to customise the objects that the cursor returns, instead of receiving tuples, you can specify your :ref:`row factories `. -- If you want to customise how Python values and PostgreSQL types are mapped +- If you want to customise how Python values and GaussDB types are mapped into each other, beside the :ref:`basic type mapping `, you can :ref:`configure your types `. diff --git a/docs/conf.py b/docs/conf.py index 3ff11cc43..b3a2fc51e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -26,7 +26,7 @@ # -- Project information ----------------------------------------------------- project = "gaussdb" -copyright = "2020, Daniele Varrazzo and The GaussDB Team" +copyright = "2020, Daniele Varrazzo and The Psycopg Team" author = "Daniele Varrazzo" release = gaussdb.__version__ @@ -105,7 +105,7 @@ autodoc_member_order = "bysource" -# PostgreSQL docs version to link libpq functions to +# GaussDB docs version to link libpq functions to libpq_docs_version = "17" # Where to point on :ticket: role diff --git a/docs/index.rst b/docs/index.rst index ce29ade10..0200b7056 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,13 +1,13 @@ =================================================== -gaussdb -- PostgreSQL database adapter for Python +gaussdb -- GaussDB database adapter for Python =================================================== -gaussdb is a newly designed PostgreSQL_ database adapter for the Python_ +gaussdb is a newly designed GaussDB database adapter for the Python_ programming language. gaussdb presents a familiar interface for everyone who has used -`GaussDB 2`_ or any other `DB-API 2.0`_ database adapter, but allows to use -more modern PostgreSQL and Python features, such as: +`Psycopg 3`_ or any other `DB-API 2.0`_ database adapter, but allows to use +more modern GaussDB and Python features, such as: - :ref:`Asynchronous support ` - :ref:`COPY support from Python objects ` @@ -20,8 +20,7 @@ more modern PostgreSQL and Python features, such as: - :ref:`Direct access to the libpq functionalities ` .. _Python: https://www.python.org/ -.. _PostgreSQL: https://www.postgresql.org/ -.. _GaussDB 2: https://www.gaussdb.org/docs/ +.. _Psycopg 3: https://github.com/psycopg/psycopg .. _DB-API 2.0: https://www.python.org/dev/peps/pep-0249/ diff --git a/docs/lib/libpq_docs.py b/docs/lib/libpq_docs.py index 3e6006b65..a5488d151 100644 --- a/docs/lib/libpq_docs.py +++ b/docs/lib/libpq_docs.py @@ -12,7 +12,7 @@ """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team import os import logging diff --git a/docs/lib/pg3_docs.py b/docs/lib/pg3_docs.py index b6238e805..9ff693b4a 100644 --- a/docs/lib/pg3_docs.py +++ b/docs/lib/pg3_docs.py @@ -3,7 +3,7 @@ Customisation for docs generation. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations diff --git a/docs/lib/sql_role.py b/docs/lib/sql_role.py index 4d28c17f4..02648a29d 100644 --- a/docs/lib/sql_role.py +++ b/docs/lib/sql_role.py @@ -6,7 +6,7 @@ An interpreted text role to style SQL syntax in GaussDB documentation. :copyright: Copyright 2010 by Daniele Varrazzo. -:copyright: Copyright 2020 The GaussDB Team. +:copyright: Copyright 2020 The Psycopg Team. """ from docutils import nodes, utils diff --git a/docs/lib/ticket_role.py b/docs/lib/ticket_role.py index 93a575532..f8f935bf5 100644 --- a/docs/lib/ticket_role.py +++ b/docs/lib/ticket_role.py @@ -6,7 +6,7 @@ An interpreted text role to link docs to tickets issues. :copyright: Copyright 2013 by Daniele Varrazzo. -:copyright: Copyright 2021 The GaussDB Team +:copyright: Copyright 2021 The Psycopg Team """ import re diff --git a/docs/news.rst b/docs/news.rst index 5eb5f2240..690d518ec 100644 --- a/docs/news.rst +++ b/docs/news.rst @@ -10,551 +10,6 @@ Future releases --------------- -gaussdb.3.0 (unreleased) -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Drop support for Python 3.8. - - -gaussdb.2.7 (unreleased) -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Add SRID support to shapely dumpers/loaders (:ticket:`#1028`). - - -Current release ---------------- - -gaussdb.2.6 -^^^^^^^^^^^^^ - -- Fix connection semantic when using ``target_session_attrs=prefer-standby`` - (:ticket:`#1021`). - - -gaussdb.2.5 -^^^^^^^^^^^^^ - -- 3x faster UUID loading thanks to C implementation (:tickets:`#447, #998`). - - -gaussdb.2.4 -^^^^^^^^^^^^^ - -- Don't lose notifies received whilst the `~Connection.notifies()` iterator - is not running (:ticket:`#962`). -- Make sure that the notifies callback is called during the use of the - `~Connection.notifies()` generator (:ticket:`#972`). -- Raise the correct error returned by the database (such as `!AdminShutdown` - or `!IdleInTransactionSessionTimeout`) instead of a generic - `OperationalError` when a server error causes a client disconnection - (:ticket:`#988`). -- Build macOS dependencies from sources instead using the Homebrew versions - in order to avoid problems with ``MACOSX_DEPLOYMENT_TARGET`` (:ticket:`#858`). -- Bump libpq to 17.2 in Linux and macOS binary packages. -- Bump libpq to 16.4 in Windows binary packages, using the `vcpkg library`__ - (:ticket:`#966`). - -.. __: https://vcpkg.io/en/package/libpq - - -gaussdb.2.3 -^^^^^^^^^^^^^ - -- Release binary packages including PostgreSQL 17 libpq (:ticket:`#852`). - - -gaussdb.2.2 -^^^^^^^^^^^^^ - -- Drop `!TypeDef` specifications as string from public modules, as they cannot - be composed by users as `!typing` objects previously could (:ticket:`#860`). -- Release Python 3.13 binary packages. - - -gaussdb.2.1 -^^^^^^^^^^^^^ - -- Fix packaging metadata breaking ``[c]``, ``[binary]`` dependencies - (:ticket:`#853`). - - -gaussdb.2 ------------ - -.. rubric:: New top-level features - -- Add support for integer, floating point, boolean `NumPy scalar types`__ - (:ticket:`#332`). -- Add `!timeout` and `!stop_after` parameters to `Connection.notifies()` - (:ticket:`340`). -- Allow dumpers to return `!None`, to be converted to NULL (:ticket:`#377`). -- Add :ref:`raw-query-cursors` to execute queries using placeholders in - PostgreSQL format (`$1`, `$2`...) (:tickets:`#560, #839`). -- Add `capabilities` object to :ref:`inspect the libpq capabilities - ` (:ticket:`#772`). -- Add `~rows.scalar_row` to return scalar values from a query (:ticket:`#723`). -- Add `~Connection.cancel_safe()` for encrypted and non-blocking cancellation - when using libpq v17. Use such method internally to implement - `!KeyboardInterrupt` and `~cursor.copy` termination (:ticket:`#754`). -- The `!context` parameter of `sql` objects `~sql.Composable.as_string()` and - `~sql.Composable.as_bytes()` methods is now optional (:ticket:`#716`). -- Add `~Connection.set_autocommit()` on sync connections, and similar - transaction control methods available on the async connections. -- Add a `size` parameter to `~Cursor.stream()` to enable results retrieval in - chunks instead of row-by-row (:ticket:`#794`). - -.. rubric:: New libpq wrapper features - -- Add support for libpq functions to close prepared statements and portals - introduced in libpq v17 (:ticket:`#603`). -- Add support for libpq encrypted and non-blocking query cancellation - functions introduced in libpq v17 (:ticket:`#754`). -- Add support for libpq function to retrieve results in chunks introduced in - libpq v17 (:ticket:`#793`). -- Add support for libpq function to change role passwords introduced in - libpq v17 (:ticket:`#818`). - -.. rubric:: Other changes - -- Drop support for Python 3.7. -- Prepared statements are now :ref:`compatible with PgBouncer `. - (:ticket:`#589`). -- Disable receiving more than one result on the same cursor in pipeline mode, - to iterate through `~Cursor.nextset()`. The behaviour was different than - in non-pipeline mode and not totally reliable (:ticket:`#604`). - The `Cursor` now only preserves the results set of the last - `~Cursor.execute()`, consistently with non-pipeline mode. - -.. __: https://numpy.org/doc/stable/reference/arrays.scalars.html#built-in-scalar-types - - -gaussdb.1.20 -^^^^^^^^^^^^^^ - -- Use the simple query protocol to execute COMMIT/ROLLBACK when possible. - This should make querying the PgBouncer admin database easier - (:ticket:`#820`). -- Avoid unneeded escaping checks and memory over-allocation in text copy - (:ticket:`#829`). -- Bundle binary package with OpenSSL 3.3.x (:ticket:`#847`). -- Drop macOS ARM64 binary packages for macOS versions before 14.0 and Python - before 3.10 (not for our choice but for the lack of available CI runners; - :ticket:`#858`) - - -gaussdb.1.19 -^^^^^^^^^^^^^^ - -- Fix unaligned access undefined behaviour in C extension (:ticket:`#734`). -- Fix excessive stripping of error message prefixes (:ticket:`#752`). -- Allow to specify the ``connect_timeout`` connection parameter as float - (:ticket:`#796`). -- Improve COPY performance on macOS (:ticket:`#745`). - - -gaussdb.1.18 -^^^^^^^^^^^^^^ - -- Fix possible deadlock on pipeline exit (:ticket:`#685`). -- Fix overflow loading large intervals in C module (:ticket:`#719`). -- Fix compatibility with musl libc distributions affected by `CPython issue - #65821`__ (:ticket:`#725`). - -.. __: https://github.com/python/cpython/issues/65821 - - -gaussdb.1.17 -^^^^^^^^^^^^^^ - -- Fix multiple connection attempts when a host name resolve to multiple - IP addresses (:ticket:`#699`). -- Use `typing.Self` as a more correct return value annotation of context - managers and other self-returning methods (see :ticket:`#708`). - - -gaussdb.1.16 -^^^^^^^^^^^^^^ - -- Fix empty ports handling in async multiple connection attempts - (:ticket:`#703`). - - -gaussdb.1.15 -^^^^^^^^^^^^^^ - -- Fix use of ``service`` in connection string (regression in 3.1.13, - :ticket:`#694`). -- Fix async connection to hosts resolving to multiple IP addresses (regression - in 3.1.13, :ticket:`#695`). -- Respect the :envvar:`PGCONNECT_TIMEOUT` environment variable to determine - the connection timeout. - - -gaussdb.1.14 -^^^^^^^^^^^^^^ - -- Fix :ref:`interaction with gevent ` (:ticket:`#527`). -- Add support for PyPy (:ticket:`#686`). - -.. _gevent: https://www.gevent.org/ - - -gaussdb.1.13 -^^^^^^^^^^^^^^ - -- Raise `DataError` instead of whatever internal failure trying to dump a - `~datetime.time` object with with a `!tzinfo` specified as - `~zoneinfo.ZoneInfo` (ambiguous offset, see :ticket:`#652`). -- Handle gracefully EINTR on signals instead of raising `InterruptedError`, - consistently with :pep:`475` guideline (:ticket:`#667`). -- Fix support for connection strings with multiple hosts/ports and for the - ``load_balance_hosts`` connection parameter (:ticket:`#674`). -- Fix memory leak receiving notifications in Python implementation - (:ticket:`#679`). - - -gaussdb.1.12 -^^^^^^^^^^^^^^ - -- Fix possible hanging if a connection is closed while querying (:ticket:`#608`). -- Fix memory leak when `~register_*()` functions are called repeatedly - (:ticket:`#647`). -- Release Python 3.12 binary packages. - - -gaussdb.1.11 -^^^^^^^^^^^^^^ - -- Avoid caching the parsing results of large queries to avoid excessive memory - usage (:ticket:`#628`). -- Fix integer overflow in C/binary extension with OID > 2^31 (:ticket:`#630`). -- Fix loading of intervals with days and months or years (:ticket:`#643`). -- Work around excessive CPU usage on Windows (reported in :ticket:`#645`). -- Fix building on Solaris and derivatives (:ticket:`#632`). -- Fix possible lack of critical section guard in async - `~AsyncCursor.executemany()`. -- Fix missing pipeline fetch in async `~AsyncCursor.scroll()`. -- Build binary packages with libpq 15.4, which allows group-readable - permissions on the SSL certificate on the client (:ticket:`#528`). - - -gaussdb.1.10 -^^^^^^^^^^^^^^ - -- Allow JSON dumpers to dump `bytes` directly instead of `str`, - for better compatibility with libraries like orjson and msgspec - (:ticket:`#569`) -- Fix prepared statement cache validation when exiting pipeline mode (or - `~Cursor.executemany()`) in case an error occurred within the pipeline - (:ticket:`#585`). -- Fix `connect()` to avoid "leaking" an open `~pq.PGconn` attached to the - `OperationalError` in case of connection failure. `Error.pgconn` is now a - shallow copy of the real libpq connection, and the latter is closed before - the exception propagates (:ticket:`#565`). -- Fix possible (ignored) exception on objects deletion (:ticket:`#591`). -- Don't clobber a Python exception raised during COPY FROM with the resulting - `!QueryCanceled` raised as a consequence (:ticket:`#593`). -- Fix resetting `Connection.read_only` and `~Connection.deferrable` to their - default value using `!None` (:ticket:`#612`). -- Add support for Python 3.12. - - -gaussdb.1.9 -^^^^^^^^^^^^^ - -- Fix `TypeInfo.fetch()` using a connection in `!sql_ascii` encoding - (:ticket:`#503`). -- Fix "filedescriptor out of range" using a large number of files open - in Python implementation (:ticket:`#532`). -- Allow JSON dumpers to be registered on `!dict` or any other object, as was - possible in _GaussDB (:ticket:`#541`). -- Fix canceling running queries on process interruption in async connections - (:ticket:`#543`). -- Fix loading ROW values with different types in the same query using the - binary protocol (:ticket:`#545`). -- Fix dumping recursive composite types (:ticket:`#547`). - - -gaussdb.1.8 -^^^^^^^^^^^^^ - -- Don't pollute server logs when types looked for by `TypeInfo.fetch()` - are not found (:ticket:`#473`). -- Set `Cursor.rowcount` to the number of rows of each result set from - `~Cursor.executemany()` when called with `!returning=True` (:ticket:`#479`). -- Fix `TypeInfo.fetch()` when used with `ClientCursor` (:ticket:`#484`). - - -gaussdb.1.7 -^^^^^^^^^^^^^ - -- Fix server-side cursors using row factories (:ticket:`#464`). - - -gaussdb.1.6 -^^^^^^^^^^^^^ - -- Fix `cursor.copy()` with cursors using row factories (:ticket:`#460`). - - -gaussdb.1.5 -^^^^^^^^^^^^^ - -- Fix array loading slowness compared to _GaussDB (:ticket:`#359`). -- Improve performance around network communication (:ticket:`#414`). -- Return `!bytes` instead of `!memoryview` from `pq.Encoding` methods - (:ticket:`#422`). -- Fix `Cursor.rownumber` to return `!None` when the result has no row to fetch - (:ticket:`#437`). -- Avoid error in Pyright caused by aliasing `!TypeAlias` (:ticket:`#439`). -- Fix `Copy.set_types()` used with `varchar` and `name` types (:ticket:`#452`). -- Improve performance using :ref:`row-factories` (:ticket:`#457`). - - -gaussdb.1.4 -^^^^^^^^^^^^^ - -- Include :ref:`error classes ` defined in PostgreSQL 15. -- Add support for Python 3.11 (:ticket:`#305`). -- Build binary packages with libpq from PostgreSQL 15.0. - - -gaussdb.1.3 -^^^^^^^^^^^^^ - -- Restore the state of the connection if `Cursor.stream()` is terminated - prematurely (:ticket:`#382`). -- Fix regression introduced in 3.1 with different named tuples mangling rules - for non-ascii attribute names (:ticket:`#386`). -- Fix handling of queries with escaped percent signs (``%%``) in `ClientCursor` - (:ticket:`#399`). -- Fix possible duplicated BEGIN statements emitted in pipeline mode - (:ticket:`#401`). - - -gaussdb.1.2 -^^^^^^^^^^^^^ - -- Fix handling of certain invalid time zones causing problems on Windows - (:ticket:`#371`). -- Fix segfault occurring when a loader fails initialization (:ticket:`#372`). -- Fix invalid SAVEPOINT issued when entering `Connection.transaction()` within - a pipeline using an implicit transaction (:ticket:`#374`). -- Fix queries with repeated named parameters in `ClientCursor` (:ticket:`#378`). -- Distribute macOS arm64 (Apple M1) binary packages (:ticket:`#344`). - - -gaussdb.1.1 -^^^^^^^^^^^^^ - -- Work around broken Homebrew installation of the libpq in a non-standard path - (:ticket:`#364`) -- Fix possible "unrecognized service" error in async connection when no port - is specified (:ticket:`#366`). - - -gaussdb.1 ------------ - -- Add :ref:`Pipeline mode ` (:ticket:`#74`). -- Add :ref:`client-side-binding-cursors` (:ticket:`#101`). -- Add `CockroachDB `__ support in `gaussdb.crdb` - (:ticket:`#313`). -- Add :ref:`Two-Phase Commit ` support (:ticket:`#72`). -- Add :ref:`adapt-enum` (:ticket:`#274`). -- Add ``returning`` parameter to `~Cursor.executemany()` to retrieve query - results (:ticket:`#164`). -- `~Cursor.executemany()` performance improved by using batch mode internally - (:ticket:`#145`). -- Add parameters to `~Cursor.copy()`. -- Add :ref:`COPY Writer objects `. -- Resolve domain names asynchronously in `AsyncConnection.connect()` - (:ticket:`#259`). -- Add `pq.PGconn.trace()` and related trace functions (:ticket:`#167`). -- Add ``prepare_threshold`` parameter to `Connection` init (:ticket:`#200`). -- Add ``cursor_factory`` parameter to `Connection` init. -- Add `Error.pgconn` and `Error.pgresult` attributes (:ticket:`#242`). -- Restrict queries to be `~typing.LiteralString` as per :pep:`675` - (:ticket:`#323`). -- Add explicit type cast to values converted by `sql.Literal` (:ticket:`#205`). -- Drop support for Python 3.6. - - -gaussdb.0.17 -^^^^^^^^^^^^^^ - -- Fix segfaults on fork on some Linux systems using `ctypes` implementation - (:ticket:`#300`). -- Load bytea as bytes, not memoryview, using `ctypes` implementation. - - -gaussdb.0.16 -^^^^^^^^^^^^^^ - -- Fix missing `~Cursor.rowcount` after SHOW (:ticket:`#343`). -- Add scripts to build macOS arm64 packages (:ticket:`#162`). - - -gaussdb.0.15 -^^^^^^^^^^^^^^ - -- Fix wrong escaping of unprintable chars in COPY (nonetheless correctly - interpreted by PostgreSQL). -- Restore the connection to usable state after an error in `~Cursor.stream()`. -- Raise `DataError` instead of `OverflowError` loading binary intervals - out-of-range. -- Distribute ``manylinux2014`` wheel packages (:ticket:`#124`). - - -gaussdb.0.14 -^^^^^^^^^^^^^^ - -- Raise `DataError` dumping arrays of mixed types (:ticket:`#301`). -- Fix handling of incorrect server results, with blank sqlstate (:ticket:`#303`). -- Fix bad Float4 conversion on ppc64le/musllinux (:ticket:`#304`). - - -gaussdb.0.13 -^^^^^^^^^^^^^^ - -- Fix `Cursor.stream()` slowness (:ticket:`#286`). -- Fix oid for lists of integers, which might cause the server choosing - bad plans (:ticket:`#293`). -- Make `Connection.cancel()` on a closed connection a no-op instead of an - error. - - -gaussdb.0.12 -^^^^^^^^^^^^^^ - -- Allow `bytearray`/`memoryview` data too as `Copy.write()` input - (:ticket:`#254`). -- Fix dumping `~enum.IntEnum` in text mode, Python implementation. - - -gaussdb.0.11 -^^^^^^^^^^^^^^ - -- Fix `DataError` loading arrays with dimensions information (:ticket:`#253`). -- Fix hanging during COPY in case of memory error (:ticket:`#255`). -- Fix error propagation from COPY worker thread (mentioned in :ticket:`#255`). - - -gaussdb.0.10 -^^^^^^^^^^^^^^ - -- Leave the connection in working state after interrupting a query with Ctrl-C - (:ticket:`#231`). -- Fix `Cursor.description` after a COPY ... TO STDOUT operation - (:ticket:`#235`). -- Fix building on FreeBSD and likely other BSD flavours (:ticket:`#241`). - - -gaussdb.0.9 -^^^^^^^^^^^^^ - -- Set `Error.sqlstate` when an unknown code is received (:ticket:`#225`). -- Add the `!tzdata` package as a dependency on Windows in order to handle time - zones (:ticket:`#223`). - - -gaussdb.0.8 -^^^^^^^^^^^^^ - -- Decode connection errors in the ``client_encoding`` specified in the - connection string, if available (:ticket:`#194`). -- Fix possible warnings in objects deletion on interpreter shutdown - (:ticket:`#198`). -- Don't leave connections in ACTIVE state in case of error during COPY ... TO - STDOUT (:ticket:`#203`). - - -gaussdb.0.7 -^^^^^^^^^^^^^ - -- Fix crash in `~Cursor.executemany()` with no input sequence - (:ticket:`#179`). -- Fix wrong `~Cursor.rowcount` after an `~Cursor.executemany()` returning no - rows (:ticket:`#178`). - - -gaussdb.0.6 -^^^^^^^^^^^^^ - -- Allow to use `Cursor.description` if the connection is closed - (:ticket:`#172`). -- Don't raise exceptions on `ServerCursor.close()` if the connection is closed - (:ticket:`#173`). -- Fail on `Connection.cursor()` if the connection is closed (:ticket:`#174`). -- Raise `ProgrammingError` if out-of-order exit from transaction contexts is - detected (:tickets:`#176, #177`). -- Add `!CHECK_STANDBY` value to `~pq.ConnStatus` enum. - - -gaussdb.0.5 -^^^^^^^^^^^^^ - -- Fix possible "Too many open files" OS error, reported on macOS but possible - on other platforms too (:ticket:`#158`). -- Don't clobber exceptions if a transaction block exit with error and rollback - fails (:ticket:`#165`). - - -gaussdb.0.4 -^^^^^^^^^^^^^ - -- Allow to use the module with strict strings comparison (:ticket:`#147`). -- Fix segfault on Python 3.6 running in ``-W error`` mode, related to - `!backport.zoneinfo` (:ticket:`#109`). - `__. -- Build binary package with libpq versions not affected by `CVE-2021-23222 - `__ - (:ticket:`#149`). - - -gaussdb.0.3 -^^^^^^^^^^^^^ - -- Release musllinux binary packages, compatible with Alpine Linux - (:ticket:`#141`). -- Reduce size of binary package by stripping debug symbols (:ticket:`#142`). -- Include typing information in the `!gaussdb_binary` package. - - -gaussdb.0.2 -^^^^^^^^^^^^^ - -- Fix type hint for `sql.SQL.join()` (:ticket:`#127`). -- Fix type hint for `Connection.notifies()` (:ticket:`#128`). -- Fix call to `MultiRange.__setitem__()` with a non-iterable value and a - slice, now raising a `TypeError` (:ticket:`#129`). -- Fix disable cursors methods after close() (:ticket:`#125`). - - -gaussdb.0.1 -^^^^^^^^^^^^^ - -- Fix use of the wrong dumper reusing cursors with the same query but different - parameter types (:ticket:`#112`). - - -gaussdb.0 ------------ - -First stable release. Changed from 3.0b1: - -- Add :ref:`adapt-shapely` (:ticket:`#80`). -- Add :ref:`adapt-multirange` (:ticket:`#75`). -- Add `pq.__build_version__` constant. -- Don't use the extended protocol with COPY, (:tickets:`#78, #82`). -- Add ``context`` parameter to `~Connection.connect()` (:ticket:`#83`). -- Fix selection of dumper by oid after `~Copy.set_types()`. -- Drop `!Connection.client_encoding`. Use `ConnectionInfo.encoding` to read - it, and a :sql:`SET` statement to change it. -- Add binary packages for Python 3.10 (:ticket:`#103`). - - gaussdb.0b1 ^^^^^^^^^^^^^ diff --git a/docs/release.rst b/docs/release.rst index 785c7070e..60aa04575 100644 --- a/docs/release.rst +++ b/docs/release.rst @@ -60,7 +60,7 @@ How to make a gaussdb release - Run ``tools/bump_version.py -l dev`` to bump to the next dev version. -When a new PostgreSQL major version is released +When a new GaussDB major version is released ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Add the new version to ``tools/update_errors.py`` and run the script to add diff --git a/gaussdb/README.rst b/gaussdb/README.rst index b953eee1f..39ccede09 100644 --- a/gaussdb/README.rst +++ b/gaussdb/README.rst @@ -1,7 +1,7 @@ -gaussdb: PostgreSQL database adapter for Python +gaussdb: GaussDB database adapter for Python ================================================= -gaussdb is a modern implementation of a PostgreSQL adapter for Python. +gaussdb is a modern implementation of a GaussDB adapter for Python. This distribution contains the pure Python package ``gaussdb``. @@ -14,7 +14,6 @@ This distribution contains the pure Python package ``gaussdb``. using _GaussDB as a dependency. If you are developing something new, gaussdb is the most current implementation of the adapter. - .. _psycopg2: https://pypi.org/project/_GaussDB/ Installation @@ -23,20 +22,16 @@ Installation In short, run the following:: pip install --upgrade pip # to upgrade pip - pip install "gaussdb[binary,pool]" # to install package and dependencies + pip install "gaussdb[dev,pool]" # to install package and dependencies If something goes wrong, and for more information about installation, please -check out the `Installation documentation`__. - -.. __: https://www.gaussdb.org/gaussdb/docs/basic/install.html# +check out the `Installation documentation`. Hacking ------- -For development information check out `the project readme`__. - -.. __: https://github.com/gaussdb/gaussdb#readme +For development information check out `the project readme`. -Copyright (C) 2020 The GaussDB Team +Copyright (C) 2020 The Psycopg Team diff --git a/gaussdb/gaussdb/__init__.py b/gaussdb/gaussdb/__init__.py index a64dcc513..c1e02f474 100644 --- a/gaussdb/gaussdb/__init__.py +++ b/gaussdb/gaussdb/__init__.py @@ -1,13 +1,13 @@ """ -gaussdb -- PostgreSQL database adapter for Python +gaussdb -- GaussDB database adapter for Python """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team import logging from . import pq # noqa: F401 import early to stabilize side effects -from . import dbapi20, postgres, types +from . import dbapi20, gaussdb_, types from ._tpc import Xid from .copy import AsyncCopy, Copy from ._enums import IsolationLevel @@ -42,10 +42,10 @@ threadsafety = 2 paramstyle = "pyformat" -# register default adapters for PostgreSQL -adapters = postgres.adapters # exposed by the package -postgres.register_default_types(adapters.types) -postgres.register_default_adapters(adapters) +# register default adapters for GaussDB +adapters = gaussdb_.adapters # exposed by the package +gaussdb_.register_default_types(adapters.types) +gaussdb_.register_default_adapters(adapters) # After the default ones, because these can deal with the bytea oid better dbapi20.register_dbapi20_adapters(adapters) diff --git a/gaussdb/gaussdb/_acompat.py b/gaussdb/gaussdb/_acompat.py index 2fb9758d2..4f9043c6f 100644 --- a/gaussdb/gaussdb/_acompat.py +++ b/gaussdb/gaussdb/_acompat.py @@ -6,7 +6,7 @@ when generating the sync version. """ -# Copyright (C) 2023 The GaussDB Team +# Copyright (C) 2023 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/_adapters_map.py b/gaussdb/gaussdb/_adapters_map.py index 480268852..8fee8e753 100644 --- a/gaussdb/gaussdb/_adapters_map.py +++ b/gaussdb/gaussdb/_adapters_map.py @@ -2,7 +2,7 @@ Mapping from types/oids to Dumpers/Loaders """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -24,11 +24,11 @@ class AdaptersMap: r""" - Establish how types should be converted between Python and PostgreSQL in + Establish how types should be converted between Python and GaussDB in an `~gaussdb.abc.AdaptContext`. `!AdaptersMap` maps Python types to `~gaussdb.adapt.Dumper` classes to - define how Python types are converted to PostgreSQL, and maps OIDs to + define how Python types are converted to GaussDB, and maps OIDs to `~gaussdb.adapt.Loader` classes to establish how query results are converted to Python. @@ -127,7 +127,7 @@ def register_dumper(self, cls: type | str | None, dumper: type[Dumper]) -> None: ``"uuid.UUID"``). If `!cls` is None, only use the dumper when looking up using - `get_dumper_by_oid()`, which happens when we know the Postgres type to + `get_dumper_by_oid()`, which happens when we know the GaussDB type to adapt to, but not the Python type that will be adapted (e.g. in COPY after using `~gaussdb.Copy.set_types()`). @@ -164,7 +164,7 @@ def register_loader(self, oid: int | str, loader: type[Loader]) -> None: """ Configure the context to use `!loader` to convert data of oid `!oid`. - :param oid: The PostgreSQL OID or type name to manage. + :param oid: The GaussDB OID or type name to manage. :param loader: The loar to register for `!oid`. If `oid` is specified as string, it refers to a type name, which is diff --git a/gaussdb/gaussdb/_capabilities.py b/gaussdb/gaussdb/_capabilities.py index b0013dc83..fa56051f8 100644 --- a/gaussdb/gaussdb/_capabilities.py +++ b/gaussdb/gaussdb/_capabilities.py @@ -2,7 +2,7 @@ gaussdb capabilities objects """ -# Copyright (C) 2024 The GaussDB Team +# Copyright (C) 2024 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/_cmodule.py b/gaussdb/gaussdb/_cmodule.py index e460fc1dc..4a1b28f00 100644 --- a/gaussdb/gaussdb/_cmodule.py +++ b/gaussdb/gaussdb/_cmodule.py @@ -3,7 +3,7 @@ Simplify access to the _gaussdb module """ -# Copyright (C) 2021 The GaussDB Team +# Copyright (C) 2021 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/_column.py b/gaussdb/gaussdb/_column.py index 18aca6c03..fc90e5878 100644 --- a/gaussdb/gaussdb/_column.py +++ b/gaussdb/gaussdb/_column.py @@ -2,7 +2,7 @@ The Column object in Cursor.description """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/_compat.py b/gaussdb/gaussdb/_compat.py index 83fab83ca..5a3e72204 100644 --- a/gaussdb/gaussdb/_compat.py +++ b/gaussdb/gaussdb/_compat.py @@ -2,7 +2,7 @@ compatibility functions for different Python versions """ -# Copyright (C) 2021 The GaussDB Team +# Copyright (C) 2021 The Psycopg Team import sys diff --git a/gaussdb/gaussdb/_connection_base.py b/gaussdb/gaussdb/_connection_base.py index b760b3329..da6413d61 100644 --- a/gaussdb/gaussdb/_connection_base.py +++ b/gaussdb/gaussdb/_connection_base.py @@ -2,7 +2,7 @@ gaussdb connection objects """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -15,7 +15,7 @@ from collections import deque from . import errors as e -from . import generators, postgres, pq +from . import gaussdb_, generators, pq from .abc import PQGen, PQGenConn, Query from .sql import SQL, Composable from ._tpc import Xid @@ -273,7 +273,7 @@ def info(self) -> ConnectionInfo: @property def adapters(self) -> AdaptersMap: if not self._adapters: - self._adapters = AdaptersMap(postgres.adapters) + self._adapters = AdaptersMap(gaussdb_.adapters) return self._adapters @@ -695,5 +695,5 @@ def _tpc_finish_gen( def _check_tpc(self) -> None: """Raise NotSupportedError if TPC is not supported.""" - # TPC supported on every supported PostgreSQL version. + # TPC supported on every supported GaussDB version. pass diff --git a/gaussdb/gaussdb/_connection_info.py b/gaussdb/gaussdb/_connection_info.py index 75986e9a9..b36953790 100644 --- a/gaussdb/gaussdb/_connection_info.py +++ b/gaussdb/gaussdb/_connection_info.py @@ -1,8 +1,8 @@ """ -Objects to return information about a PostgreSQL connection. +Objects to return information about a GaussDB connection. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/_conninfo_attempts.py b/gaussdb/gaussdb/_conninfo_attempts.py index 440f822fa..33a8db704 100644 --- a/gaussdb/gaussdb/_conninfo_attempts.py +++ b/gaussdb/gaussdb/_conninfo_attempts.py @@ -5,7 +5,7 @@ Separate connection attempts from a connection string. """ -# Copyright (C) 2024 The GaussDB Team +# Copyright (C) 2024 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/_conninfo_attempts_async.py b/gaussdb/gaussdb/_conninfo_attempts_async.py index 10d02a8e6..942e36c1e 100644 --- a/gaussdb/gaussdb/_conninfo_attempts_async.py +++ b/gaussdb/gaussdb/_conninfo_attempts_async.py @@ -2,7 +2,7 @@ Separate connection attempts from a connection string. """ -# Copyright (C) 2024 The GaussDB Team +# Copyright (C) 2024 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/_conninfo_utils.py b/gaussdb/gaussdb/_conninfo_utils.py index 1adaf785d..844e71abd 100644 --- a/gaussdb/gaussdb/_conninfo_utils.py +++ b/gaussdb/gaussdb/_conninfo_utils.py @@ -2,7 +2,7 @@ Internal utilities to manipulate connection strings """ -# Copyright (C) 2024 The GaussDB Team +# Copyright (C) 2024 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/_copy.py b/gaussdb/gaussdb/_copy.py index 1f3a5e93c..9eeeaf981 100644 --- a/gaussdb/gaussdb/_copy.py +++ b/gaussdb/gaussdb/_copy.py @@ -5,7 +5,7 @@ Objects to support the COPY protocol (sync version). """ -# Copyright (C) 2023 The GaussDB Team +# Copyright (C) 2023 The Psycopg Team from __future__ import annotations @@ -185,7 +185,7 @@ def finish(self, exc: BaseException | None = None) -> None: class LibpqWriter(Writer): """ - An `Writer` to write copy data to a Postgres database. + An `Writer` to write copy data to a GaussDB database. """ __module__ = "gaussdb.copy" diff --git a/gaussdb/gaussdb/_copy_async.py b/gaussdb/gaussdb/_copy_async.py index c7f2a55e3..d2bb1fd4e 100644 --- a/gaussdb/gaussdb/_copy_async.py +++ b/gaussdb/gaussdb/_copy_async.py @@ -2,7 +2,7 @@ Objects to support the COPY protocol (async version). """ -# Copyright (C) 2023 The GaussDB Team +# Copyright (C) 2023 The Psycopg Team from __future__ import annotations @@ -184,7 +184,7 @@ async def finish(self, exc: BaseException | None = None) -> None: class AsyncLibpqWriter(AsyncWriter): """ - An `AsyncWriter` to write copy data to a Postgres database. + An `AsyncWriter` to write copy data to a GaussDB database. """ __module__ = "gaussdb.copy" diff --git a/gaussdb/gaussdb/_copy_base.py b/gaussdb/gaussdb/_copy_base.py index 2888109d0..ef41cfa38 100644 --- a/gaussdb/gaussdb/_copy_base.py +++ b/gaussdb/gaussdb/_copy_base.py @@ -2,7 +2,7 @@ gaussdb copy support """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -120,10 +120,10 @@ def set_types(self, types: Sequence[int | str]) -> None: """ Set the types expected in a COPY operation. - The types must be specified as a sequence of oid or PostgreSQL type + The types must be specified as a sequence of oid or GaussDB type names (e.g. ``int4``, ``timestamptz[]``). - This operation overcomes the lack of metadata returned by PostgreSQL + This operation overcomes the lack of metadata returned by GaussDB when a COPY operation begins: - On :sql:`COPY TO`, `!set_types()` allows to specify what types the @@ -132,7 +132,7 @@ def set_types(self, types: Sequence[int | str]) -> None: - On :sql:`COPY FROM`, `!set_types()` allows to choose what type the database expects. This is especially useful in binary copy, because - PostgreSQL will apply no cast rule. + GaussDB will apply no cast rule. """ registry = self.cursor.adapters.types diff --git a/gaussdb/gaussdb/_cursor_base.py b/gaussdb/gaussdb/_cursor_base.py index b08de7202..7fa469c6d 100644 --- a/gaussdb/gaussdb/_cursor_base.py +++ b/gaussdb/gaussdb/_cursor_base.py @@ -2,7 +2,7 @@ GaussDB BaseCursor object """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -17,7 +17,7 @@ from .rows import Row, RowMaker from ._column import Column from .pq.misc import connection_summary -from ._queries import PostgresClientQuery, PostgresQuery +from ._queries import GaussDBClientQuery, GaussDBQuery from ._preparing import Prepare from .generators import execute, fetch, send from ._capabilities import capabilities @@ -54,7 +54,7 @@ class BaseCursor(Generic[ConnectionType, Row]): _tx: Transformer _make_row: RowMaker[Row] _pgconn: PGconn - _query_cls: type[PostgresQuery] = PostgresQuery + _query_cls: type[GaussDBQuery] = GaussDBQuery def __init__(self, connection: ConnectionType): self._conn = connection @@ -72,7 +72,7 @@ def _reset(self, reset_query: bool = True) -> None: self._pos = 0 self._iresult = 0 self._rowcount = -1 - self._query: PostgresQuery | None + self._query: GaussDBQuery | None # None if executemany() not executing, True/False according to returning state self._execmany_returning: bool | None = None if reset_query: @@ -264,7 +264,7 @@ def _executemany_gen_no_pipeline( def _maybe_prepare_gen( self, - pgq: PostgresQuery, + pgq: GaussDBQuery, *, prepare: bool | None = None, binary: bool | None = None, @@ -307,7 +307,7 @@ def _maybe_prepare_gen( self._set_results(results) def _get_prepared( - self, pgq: PostgresQuery, prepare: bool | None = None + self, pgq: GaussDBQuery, prepare: bool | None = None ) -> tuple[Prepare, bytes]: return self._conn._prepared.get(pgq, prepare) @@ -389,7 +389,7 @@ def _start_copy_gen( # Merge the params client-side if params: - pgq = PostgresClientQuery(self._tx) + pgq = GaussDBClientQuery(self._tx) pgq.convert(statement, params) statement = pgq.query @@ -405,7 +405,7 @@ def _start_copy_gen( def _execute_send( self, - query: PostgresQuery, + query: GaussDBQuery, *, force_extended: bool = False, binary: bool | None = None, @@ -450,7 +450,7 @@ def _execute_send( def _convert_query( self, query: Query, params: Params | None = None - ) -> PostgresQuery: + ) -> GaussDBQuery: pgq = self._query_cls(self._tx) pgq.convert(query, params) return pgq @@ -533,7 +533,7 @@ def _set_results(self, results: list[PGresult]) -> None: for res in results: self._rowcount += res.command_tuples or 0 - def _send_prepare(self, name: bytes, query: PostgresQuery) -> None: + def _send_prepare(self, name: bytes, query: GaussDBQuery) -> None: if self._conn._pipeline: self._conn._pipeline.command_queue.append( partial( @@ -548,7 +548,7 @@ def _send_prepare(self, name: bytes, query: PostgresQuery) -> None: self._pgconn.send_prepare(name, query.query, param_types=query.types) def _send_query_prepared( - self, name: bytes, pgq: PostgresQuery, *, binary: bool | None = None + self, name: bytes, pgq: GaussDBQuery, *, binary: bool | None = None ) -> None: if binary is None: fmt = self.format diff --git a/gaussdb/gaussdb/_dns.py b/gaussdb/gaussdb/_dns.py index 1dd0937cd..ddbedd29d 100644 --- a/gaussdb/gaussdb/_dns.py +++ b/gaussdb/gaussdb/_dns.py @@ -3,7 +3,7 @@ DNS query support """ -# Copyright (C) 2021 The GaussDB Team +# Copyright (C) 2021 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/_encodings.py b/gaussdb/gaussdb/_encodings.py index 6a16f9fe7..6ee57fe4c 100644 --- a/gaussdb/gaussdb/_encodings.py +++ b/gaussdb/gaussdb/_encodings.py @@ -1,8 +1,8 @@ """ -Mappings between PostgreSQL and Python encodings. +Mappings between GaussDB and Python encodings. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -50,7 +50,7 @@ # "MULE_INTERNAL": not available in Python "SHIFT_JIS_2004": "shift_jis_2004", "SJIS": "shift_jis", - # this actually means no encoding, see PostgreSQL docs + # this actually means no encoding, see GaussDB docs # it is special-cased by the text loader. "SQL_ASCII": "ascii", "UHC": "cp949", @@ -110,7 +110,7 @@ def conninfo_encoding(conninfo: str) -> str: @cache def py2pgenc(name: str) -> bytes: - """Convert a Python encoding name to PostgreSQL encoding name. + """Convert a Python encoding name to GaussDB encoding name. Raise LookupError if the Python encoding is unknown. """ @@ -119,9 +119,9 @@ def py2pgenc(name: str) -> bytes: @cache def pg2pyenc(name: bytes) -> str: - """Convert a PostgreSQL encoding name to Python encoding name. + """Convert a GaussDB encoding name to Python encoding name. - Raise NotSupportedError if the PostgreSQL encoding is not supported by + Raise NotSupportedError if the GaussDB encoding is not supported by Python. """ try: diff --git a/gaussdb/gaussdb/_enums.py b/gaussdb/gaussdb/_enums.py index 550f8bfa9..5c7c82ba7 100644 --- a/gaussdb/gaussdb/_enums.py +++ b/gaussdb/gaussdb/_enums.py @@ -5,7 +5,7 @@ libpq-defined enums. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from enum import Enum, IntEnum from selectors import EVENT_READ, EVENT_WRITE diff --git a/gaussdb/gaussdb/_oids.py b/gaussdb/gaussdb/_oids.py index f90988af3..3384db1d4 100644 --- a/gaussdb/gaussdb/_oids.py +++ b/gaussdb/gaussdb/_oids.py @@ -1,12 +1,12 @@ """ -PostgreSQL known type OIDs +GaussDB known type OIDs This is an internal module. Types are publicly exposed by -`gaussdb.postgres.types`. This module is only used to know the OIDs at import +`gaussdb.gaussdb_.types`. This module is only used to know the OIDs at import time and avoid circular import problems. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team # A couple of special cases used a bit everywhere. INVALID_OID = 0 @@ -15,27 +15,41 @@ # Use tools/update_oids.py to update this data. # autogenerated: start -# Generated from PostgreSQL 17.0 +# Generated from GaussDB 505.2.0 +TDIGESTDATA_OID = 4406 +ABSTIME_OID = 702 ACLITEM_OID = 1033 BIT_OID = 1560 +BLOB_OID = 88 BOOL_OID = 16 +BOOLVECTOR_OID = 4410 BOX_OID = 603 BPCHAR_OID = 1042 BYTEA_OID = 17 +BYTEAWITHOUTORDERCOL_OID = 4403 +BYTEAWITHOUTORDERWITHEQUALCOL_OID = 4402 CHAR_OID = 18 CID_OID = 29 CIDR_OID = 650 CIRCLE_OID = 718 +CLOB_OID = 90 DATE_OID = 1082 DATEMULTIRANGE_OID = 4535 DATERANGE_OID = 3912 FLOAT4_OID = 700 FLOAT8_OID = 701 +FLOATVECTOR_OID = 4409 GTSVECTOR_OID = 3642 +HASH16_OID = 5801 +HASH32_OID = 5802 +HLL_OID = 4301 INET_OID = 869 +INT1_OID = 5545 +INT16_OID = 34 INT2_OID = 21 INT2VECTOR_OID = 22 +INT2VECTOR_EXTEND_OID = 33 INT4_OID = 23 INT4MULTIRANGE_OID = 4451 INT4RANGE_OID = 3904 @@ -55,12 +69,15 @@ NUMERIC_OID = 1700 NUMMULTIRANGE_OID = 4532 NUMRANGE_OID = 3906 +NVARCHAR2_OID = 3969 OID_OID = 26 OIDVECTOR_OID = 30 +OIDVECTOR_EXTEND_OID = 32 PATH_OID = 602 PG_LSN_OID = 3220 POINT_OID = 600 POLYGON_OID = 604 +RAW_OID = 86 RECORD_OID = 2249 REFCURSOR_OID = 1790 REGCLASS_OID = 2205 @@ -74,6 +91,9 @@ REGPROCEDURE_OID = 2202 REGROLE_OID = 4096 REGTYPE_OID = 2206 +RELTIME_OID = 703 +SMALLDATETIME_OID = 9003 +SMGR_OID = 210 TEXT_OID = 25 TID_OID = 27 TIME_OID = 1083 @@ -87,11 +107,18 @@ TSTZRANGE_OID = 3910 TSVECTOR_OID = 3614 TXID_SNAPSHOT_OID = 2970 +UINT1_OID = 349 +UINT2_OID = 352 +UINT4_OID = 353 +UINT8_OID = 388 +UNKNOWN_OID = 705 UUID_OID = 2950 VARBIT_OID = 1562 VARCHAR_OID = 1043 XID_OID = 28 XID8_OID = 5069 XML_OID = 142 +XMLTYPE_OID = 140 +YEAR_OID = 1038 # autogenerated: end diff --git a/gaussdb/gaussdb/_pipeline.py b/gaussdb/gaussdb/_pipeline.py index 13a7d6521..d34b6d2a0 100644 --- a/gaussdb/gaussdb/_pipeline.py +++ b/gaussdb/gaussdb/_pipeline.py @@ -2,7 +2,7 @@ commands pipeline management """ -# Copyright (C) 2021 The GaussDB Team +# Copyright (C) 2021 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/_preparing.py b/gaussdb/gaussdb/_preparing.py index bfffe4cd4..43be279c7 100644 --- a/gaussdb/gaussdb/_preparing.py +++ b/gaussdb/gaussdb/_preparing.py @@ -2,7 +2,7 @@ Support for prepared statements """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -14,7 +14,7 @@ from . import pq from .abc import PQGen from ._compat import TypeAlias -from ._queries import PostgresQuery +from ._queries import GaussDBQuery if TYPE_CHECKING: from .pq.abc import PGresult @@ -52,11 +52,11 @@ def __init__(self) -> None: self._to_flush = deque["bytes | None"]() @staticmethod - def key(query: PostgresQuery) -> Key: + def key(query: GaussDBQuery) -> Key: return (query.query, query.types) def get( - self, query: PostgresQuery, prepare: bool | None = None + self, query: GaussDBQuery, prepare: bool | None = None ) -> tuple[Prepare, bytes]: """ Check if a query is prepared, tell back whether to prepare it. @@ -84,7 +84,7 @@ def get( def _should_discard(self, prep: Prepare, results: Sequence[PGresult]) -> bool: """Check if we need to discard our entire state: it should happen on rollback or on dropping objects, because the same object may get - recreated and postgres would fail internal lookups. + recreated and gaussdb would fail internal lookups. """ if self._names or prep == Prepare.SHOULD: for result in results: @@ -123,7 +123,7 @@ def _rotate(self) -> None: self._to_flush.append(name) def maybe_add_to_cache( - self, query: PostgresQuery, prep: Prepare, name: bytes + self, query: GaussDBQuery, prep: Prepare, name: bytes ) -> Key | None: """Handle 'query' for possible addition to the cache. diff --git a/gaussdb/gaussdb/_py_transformer.py b/gaussdb/gaussdb/_py_transformer.py index 11d014df5..db82ebf8b 100644 --- a/gaussdb/gaussdb/_py_transformer.py +++ b/gaussdb/gaussdb/_py_transformer.py @@ -1,13 +1,13 @@ """ -Helper object to transform values between Python and PostgreSQL +Helper object to transform values between Python and GaussDB Python implementation of the object. Use the `_transformer module to import the right implementation (Python or C). The public place where the object -is exported is `gaussdb.adapt` (which we may not use to avoid circular +is exported is `gaussdb_.adapt` (which we may not use to avoid circular dependencies problems). """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -40,7 +40,7 @@ class Transformer(AdaptContext): """ - An object that can adapt efficiently between Python and PostgreSQL. + An object that can adapt efficiently between Python and GaussDB. The life cycle of the object is the query, so it is assumed that attributes such as the server version or the connection encoding will not change. The @@ -49,7 +49,7 @@ class Transformer(AdaptContext): """ - __module__ = "gaussdb.adapt" + __module__ = "gaussdb_.adapt" __slots__ = """ types formats @@ -72,9 +72,9 @@ def __init__(self, context: AdaptContext | None = None): self._adapters = context.adapters self._conn = context.connection else: - from . import postgres + from . import gaussdb_ - self._adapters = postgres.adapters + self._adapters = gaussdb_.adapters self._conn = None # mapping fmt, class -> Dumper instance diff --git a/gaussdb/gaussdb/_queries.py b/gaussdb/gaussdb/_queries.py index 3e167103c..e782b935f 100644 --- a/gaussdb/gaussdb/_queries.py +++ b/gaussdb/gaussdb/_queries.py @@ -2,7 +2,7 @@ Utility module to manipulate queries """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -32,9 +32,9 @@ class QueryPart(NamedTuple): format: PyFormat -class PostgresQuery: +class GaussDBQuery: """ - Helper to convert a Python query and parameters into Postgres format. + Helper to convert a Python query and parameters into GaussDB format. """ __slots__ = """ @@ -49,7 +49,7 @@ def __init__(self, transformer: Transformer): # these are tuples so they can be used as keys e.g. in prepared stmts self.types: tuple[int, ...] = () - # The format requested by the user and the ones to really pass Postgres + # The format requested by the user and the ones to really pass GaussDB self._want_formats: list[PyFormat] | None = None self.formats: Sequence[pq.Format] | None = None @@ -139,7 +139,7 @@ def validate_and_reorder_params( Verify the compatibility between a query and a set of params. """ - if PostgresQuery.is_params_sequence(vars): + if GaussDBQuery.is_params_sequence(vars): if len(vars) != len(parts) - 1: raise e.ProgrammingError( f"the query has {len(parts) - 1} placeholders but" @@ -177,9 +177,9 @@ def _query2pg_nocache( query: bytes, encoding: str ) -> tuple[bytes, list[PyFormat], list[str] | None, list[QueryPart]]: """ - Convert Python query and params into something Postgres understands. + Convert Python query and params into something GaussDB understands. - - Convert Python placeholders (``%s``, ``%(name)s``) into Postgres + - Convert Python placeholders (``%s``, ``%(name)s``) into GaussDB format (``$1``, ``$2``) - placeholders can be %s, %t, or %b (auto, text or binary) - return ``query`` (bytes), ``formats`` (list of formats) ``order`` @@ -231,9 +231,9 @@ def _query2pg_nocache( _query2pg = lru_cache(_query2pg_nocache) -class PostgresClientQuery(PostgresQuery): +class GaussDBClientQuery(GaussDBQuery): """ - PostgresQuery subclass merging query and arguments client-side. + GaussDBQuery subclass merging query and arguments client-side. """ __slots__ = ("template",) diff --git a/gaussdb/gaussdb/_struct.py b/gaussdb/gaussdb/_struct.py index cbd05de57..75ffd5b13 100644 --- a/gaussdb/gaussdb/_struct.py +++ b/gaussdb/gaussdb/_struct.py @@ -2,7 +2,7 @@ Utility functions to deal with binary structs. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/_tpc.py b/gaussdb/gaussdb/_tpc.py index 7527d183a..97bccb28c 100644 --- a/gaussdb/gaussdb/_tpc.py +++ b/gaussdb/gaussdb/_tpc.py @@ -2,7 +2,7 @@ gaussdb two-phase commit support """ -# Copyright (C) 2021 The GaussDB Team +# Copyright (C) 2021 The Psycopg Team from __future__ import annotations @@ -80,9 +80,9 @@ def from_parts(cls, format_id: int | None, gtrid: str, bqual: str | None) -> Xid def _as_tid(self) -> str: """ - Return the PostgreSQL transaction_id for this XA xid. + Return the GaussDB transaction_id for this XA xid. - PostgreSQL wants just a string, while the DBAPI supports the XA + GaussDB wants just a string, while the DBAPI supports the XA standard and thus a triple. We use the same conversion algorithm implemented by JDBC in order to allow some form of interoperation. diff --git a/gaussdb/gaussdb/_transformer.py b/gaussdb/gaussdb/_transformer.py index f779edd59..d97c92c04 100644 --- a/gaussdb/gaussdb/_transformer.py +++ b/gaussdb/gaussdb/_transformer.py @@ -1,10 +1,10 @@ """ -Helper object to transform values between Python and PostgreSQL +Helper object to transform values between Python and GaussDB This module exports the requested implementation to the rest of the package. """ -# Copyright (C) 2023 The GaussDB Team +# Copyright (C) 2023 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/_typeinfo.py b/gaussdb/gaussdb/_typeinfo.py index 469ab18b0..6c3f969b3 100644 --- a/gaussdb/gaussdb/_typeinfo.py +++ b/gaussdb/gaussdb/_typeinfo.py @@ -1,11 +1,11 @@ """ -Information about PostgreSQL types +Information about GaussDB types These types allow to read information from the system catalog and provide information to the adapters if needed. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -31,7 +31,7 @@ class TypeInfo: """ - Hold information about a PostgreSQL base type. + Hold information about a GaussDB base type. """ __module__ = "gaussdb.types" @@ -145,9 +145,9 @@ def register(self, context: AdaptContext | None = None) -> None: if context: types = context.adapters.types else: - from . import postgres + from . import gaussdb_ - types = postgres.types + types = gaussdb_.types types.add(self) @@ -299,7 +299,7 @@ def get(self, key: RegistryKey) -> TypeInfo | None: def get_oid(self, name: str) -> int: """ - Return the oid of a PostgreSQL type by name. + Return the oid of a GaussDB type by name. :param key: the name of the type to look for. diff --git a/gaussdb/gaussdb/_typemod.py b/gaussdb/gaussdb/_typemod.py index 3b45c4126..1f989bd88 100644 --- a/gaussdb/gaussdb/_typemod.py +++ b/gaussdb/gaussdb/_typemod.py @@ -1,11 +1,11 @@ """ -PostgreSQL type modifiers. +GaussDB type modifiers. The type modifiers parse catalog information to obtain the type modifier of a column - the numeric part of varchar(10) or decimal(6,2). """ -# Copyright (C) 2024 The GaussDB Team +# Copyright (C) 2024 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/_tz.py b/gaussdb/gaussdb/_tz.py index d046e6a9e..c121c514e 100644 --- a/gaussdb/gaussdb/_tz.py +++ b/gaussdb/gaussdb/_tz.py @@ -2,7 +2,7 @@ Timezone utility functions. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -30,11 +30,11 @@ def get_tzinfo(pgconn: PGconn | None) -> tzinfo: try: zi: tzinfo = ZoneInfo(sname) except (KeyError, OSError): - logger.warning("unknown PostgreSQL timezone: %r; will use UTC", sname) + logger.warning("unknown GaussDB timezone: %r; will use UTC", sname) zi = timezone.utc except Exception as ex: logger.warning( - "error handling PostgreSQL timezone: %r; will use UTC (%s - %s)", + "error handling GaussDB timezone: %r; will use UTC (%s - %s)", sname, type(ex).__name__, ex, diff --git a/gaussdb/gaussdb/_wrappers.py b/gaussdb/gaussdb/_wrappers.py index 1d48d5286..4a7223265 100644 --- a/gaussdb/gaussdb/_wrappers.py +++ b/gaussdb/gaussdb/_wrappers.py @@ -2,9 +2,9 @@ Wrappers for numeric types. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team -# Wrappers to force numbers to be cast as specific PostgreSQL types +# Wrappers to force numbers to be cast as specific GaussDB types # These types are implemented here but exposed by `gaussdb.types.numeric`. # They are defined here to avoid a circular import. @@ -13,7 +13,7 @@ class Int2(int): """ - Force dumping a Python `!int` as a PostgreSQL :sql:`smallint/int2`. + Force dumping a Python `!int` as a GaussDB :sql:`smallint/int2`. """ __module__ = _MODULE @@ -31,7 +31,7 @@ def __repr__(self) -> str: class Int4(int): """ - Force dumping a Python `!int` as a PostgreSQL :sql:`integer/int4`. + Force dumping a Python `!int` as a GaussDB :sql:`integer/int4`. """ __module__ = _MODULE @@ -49,7 +49,7 @@ def __repr__(self) -> str: class Int8(int): """ - Force dumping a Python `!int` as a PostgreSQL :sql:`bigint/int8`. + Force dumping a Python `!int` as a GaussDB :sql:`bigint/int8`. """ __module__ = _MODULE @@ -67,7 +67,7 @@ def __repr__(self) -> str: class IntNumeric(int): """ - Force dumping a Python `!int` as a PostgreSQL :sql:`numeric/decimal`. + Force dumping a Python `!int` as a GaussDB :sql:`numeric/decimal`. """ __module__ = _MODULE @@ -85,7 +85,7 @@ def __repr__(self) -> str: class Float4(float): """ - Force dumping a Python `!float` as a PostgreSQL :sql:`float4/real`. + Force dumping a Python `!float` as a GaussDB :sql:`float4/real`. """ __module__ = _MODULE @@ -103,7 +103,7 @@ def __repr__(self) -> str: class Float8(float): """ - Force dumping a Python `!float` as a PostgreSQL :sql:`float8/double precision`. + Force dumping a Python `!float` as a GaussDB :sql:`float8/double precision`. """ __module__ = _MODULE @@ -121,7 +121,7 @@ def __repr__(self) -> str: class Oid(int): """ - Force dumping a Python `!int` as a PostgreSQL :sql:`oid`. + Force dumping a Python `!int` as a GaussDB :sql:`oid`. """ __module__ = _MODULE diff --git a/gaussdb/gaussdb/abc.py b/gaussdb/gaussdb/abc.py index 83f8862a9..a7bb34baa 100644 --- a/gaussdb/gaussdb/abc.py +++ b/gaussdb/gaussdb/abc.py @@ -2,7 +2,7 @@ Protocol objects representing different implementations of the same classes. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -95,7 +95,7 @@ def connection(self) -> BaseConnection[Any] | None: class Dumper(Protocol): """ - Convert Python objects of type `!cls` to PostgreSQL representation. + Convert Python objects of type `!cls` to GaussDB representation. """ format: pq.Format @@ -112,7 +112,7 @@ class Dumper(Protocol): def __init__(self, cls: type, context: AdaptContext | None = None): ... def dump(self, obj: Any) -> Buffer | None: - """Convert the object `!obj` to PostgreSQL representation. + """Convert the object `!obj` to GaussDB representation. :param obj: the object to convert. """ @@ -133,7 +133,7 @@ def get_key(self, obj: Any, format: PyFormat) -> DumperKey: Normally the type of the object is all it takes to define how to dump the object to the database. For instance, a Python `~datetime.date` can - be simply converted into a PostgreSQL :sql:`date`. + be simply converted into a GaussDB :sql:`date`. In a few cases, just the type is not enough. For example: @@ -141,9 +141,9 @@ def get_key(self, obj: Any, format: PyFormat) -> DumperKey: :sql:`timestamptz` or a :sql:`timestamp`, according to whether it specifies a `!tzinfo` or not. - - A Python int could be stored as several Postgres types: int2, int4, + - A Python int could be stored as several GaussDB types: int2, int4, int8, numeric. If a type too small is used, it may result in an - overflow. If a type too large is used, PostgreSQL may not want to + overflow. If a type too large is used, GaussDB may not want to cast it to a smaller type. - Python lists should be dumped according to the type they contain to @@ -178,7 +178,7 @@ def upgrade(self, obj: Any, format: PyFormat) -> Dumper: class Loader(Protocol): """ - Convert PostgreSQL values with type OID `!oid` to Python objects. + Convert GaussDB values with type OID `!oid` to Python objects. """ format: pq.Format diff --git a/gaussdb/gaussdb/adapt.py b/gaussdb/gaussdb/adapt.py index 7ae4e6ce9..cd51bb0d8 100644 --- a/gaussdb/gaussdb/adapt.py +++ b/gaussdb/gaussdb/adapt.py @@ -2,7 +2,7 @@ Entry point into the adaptation system. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -26,7 +26,7 @@ class Dumper(abc.Dumper, ABC): """ - Convert Python object of the type `!cls` to PostgreSQL representation. + Convert Python object of the type `!cls` to GaussDB representation. """ oid: int = 0 @@ -100,7 +100,7 @@ def get_key(self, obj: Any, format: PyFormat) -> abc.DumperKey: `~gaussdb.abc.Dumper` protocol. Look at its definition for details. This implementation returns the `!cls` passed in the constructor. - Subclasses needing to specialise the PostgreSQL type according to the + Subclasses needing to specialise the GaussDB type according to the *value* of the object dumped (not only according to to its type) should override this class. @@ -120,7 +120,7 @@ def upgrade(self, obj: Any, format: PyFormat) -> Dumper: class Loader(abc.Loader, ABC): """ - Convert PostgreSQL values with type OID `!oid` to Python objects. + Convert GaussDB values with type OID `!oid` to Python objects. """ format: pq.Format = pq.Format.TEXT @@ -133,7 +133,7 @@ def __init__(self, oid: int, context: abc.AdaptContext | None = None): @abstractmethod def load(self, data: Buffer) -> Any: - """Convert a PostgreSQL value to a Python object.""" + """Convert a GaussDB value to a Python object.""" ... diff --git a/gaussdb/gaussdb/client_cursor.py b/gaussdb/gaussdb/client_cursor.py index 3265e4849..f94ea844e 100644 --- a/gaussdb/gaussdb/client_cursor.py +++ b/gaussdb/gaussdb/client_cursor.py @@ -2,7 +2,7 @@ gaussdb client-side binding cursors """ -# Copyright (C) 2022 The GaussDB Team +# Copyright (C) 2022 The Psycopg Team from __future__ import annotations @@ -15,7 +15,7 @@ from .abc import ConnectionType, Params, Query from .rows import Row from .cursor import Cursor -from ._queries import PostgresClientQuery, PostgresQuery +from ._queries import GaussDBClientQuery, GaussDBQuery from ._preparing import Prepare from ._cursor_base import BaseCursor from .cursor_async import AsyncCursor @@ -31,7 +31,7 @@ class ClientCursorMixin(BaseCursor[ConnectionType, Row]): - _query_cls = PostgresClientQuery + _query_cls = GaussDBClientQuery def mogrify(self, query: Query, params: Params | None = None) -> str: """ @@ -47,7 +47,7 @@ def mogrify(self, query: Query, params: Params | None = None) -> str: def _execute_send( self, - query: PostgresQuery, + query: GaussDBQuery, *, force_extended: bool = False, binary: bool | None = None, @@ -78,7 +78,7 @@ def _execute_send( self._pgconn.send_query(query.query) def _get_prepared( - self, pgq: PostgresQuery, prepare: bool | None = None + self, pgq: GaussDBQuery, prepare: bool | None = None ) -> tuple[Prepare, bytes]: return (Prepare.NO, b"") diff --git a/gaussdb/gaussdb/connection.py b/gaussdb/gaussdb/connection.py index ef342cc77..f3718043d 100644 --- a/gaussdb/gaussdb/connection.py +++ b/gaussdb/gaussdb/connection.py @@ -5,7 +5,7 @@ GaussDB connection object (sync version) """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/connection_async.py b/gaussdb/gaussdb/connection_async.py index 380bc6f0c..c22c2d1d8 100644 --- a/gaussdb/gaussdb/connection_async.py +++ b/gaussdb/gaussdb/connection_async.py @@ -2,7 +2,7 @@ GaussDB connection object (async version) """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/conninfo.py b/gaussdb/gaussdb/conninfo.py index 22d2c8f87..681dfe49f 100644 --- a/gaussdb/gaussdb/conninfo.py +++ b/gaussdb/gaussdb/conninfo.py @@ -2,7 +2,7 @@ Functions to manipulate conninfo strings """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -27,9 +27,9 @@ def make_conninfo(conninfo: str = "", **kwargs: ConnParam) -> str: """ Merge a string and keyword params into a single conninfo string. - :param conninfo: A `connection string`__ as accepted by PostgreSQL. + :param conninfo: A `connection string`__ as accepted by GaussDB. :param kwargs: Parameters overriding the ones specified in `!conninfo`. - :return: A connection string valid for PostgreSQL, with the `!kwargs` + :return: A connection string valid for GaussDB, with the `!kwargs` parameters merged. Raise `~gaussdb.ProgrammingError` if the input doesn't make a valid @@ -68,7 +68,7 @@ def conninfo_to_dict(conninfo: str = "", **kwargs: ConnParam) -> ConnDict: """ Convert the `!conninfo` string into a dictionary of parameters. - :param conninfo: A `connection string`__ as accepted by PostgreSQL. + :param conninfo: A `connection string`__ as accepted by GaussDB. :param kwargs: Parameters overriding the ones specified in `!conninfo`. :return: Dictionary with the parameters parsed from `!conninfo` and `!kwargs`. diff --git a/gaussdb/gaussdb/crdb/__init__.py b/gaussdb/gaussdb/crdb/__init__.py index 816322b65..dbdcf5f34 100644 --- a/gaussdb/gaussdb/crdb/__init__.py +++ b/gaussdb/gaussdb/crdb/__init__.py @@ -2,7 +2,7 @@ CockroachDB support package. """ -# Copyright (C) 2022 The GaussDB Team +# Copyright (C) 2022 The Psycopg Team from . import _types from .connection import AsyncCrdbConnection, CrdbConnection, CrdbConnectionInfo diff --git a/gaussdb/gaussdb/crdb/_types.py b/gaussdb/gaussdb/crdb/_types.py index 83dbbcafa..6b2bae8c0 100644 --- a/gaussdb/gaussdb/crdb/_types.py +++ b/gaussdb/gaussdb/crdb/_types.py @@ -2,7 +2,7 @@ Types configuration specific for CockroachDB. """ -# Copyright (C) 2022 The GaussDB Team +# Copyright (C) 2022 The Psycopg Team from enum import Enum @@ -17,7 +17,7 @@ types = TypesRegistry() -# Global adapter maps with PostgreSQL types configuration +# Global adapter maps with GaussDB types configuration adapters = AdaptersMap(types=types) @@ -37,7 +37,7 @@ def register_crdb_adapters(context: AdaptContext) -> None: from .. import dbapi20 from ..types import array - _register_postgres_adapters(context) + _register_gaussdb_adapters(context) # String must come after enum and none to map text oid -> string dumper _register_crdb_none_adapters(context) @@ -51,8 +51,8 @@ def register_crdb_adapters(context: AdaptContext) -> None: array.register_all_arrays(adapters) -def _register_postgres_adapters(context: AdaptContext) -> None: - # Same adapters used by PostgreSQL, or a good starting point for customization +def _register_gaussdb_adapters(context: AdaptContext) -> None: + # Same adapters used by GaussDB, or a good starting point for customization from ..types import array, bool, composite, datetime, numeric, numpy, string, uuid @@ -76,7 +76,7 @@ def _register_crdb_string_adapters(context: AdaptContext) -> None: from ..types import string # Dump strings with text oid instead of unknown. - # Unlike PostgreSQL, CRDB seems able to cast text to most types. + # Unlike GaussDB, CRDB seems able to cast text to most types. context.adapters.register_dumper(str, string.StrDumper) context.adapters.register_dumper(str, string.StrBinaryDumper) diff --git a/gaussdb/gaussdb/crdb/connection.py b/gaussdb/gaussdb/crdb/connection.py index 47ef5ba27..ec7c1cb51 100644 --- a/gaussdb/gaussdb/crdb/connection.py +++ b/gaussdb/gaussdb/crdb/connection.py @@ -2,7 +2,7 @@ CockroachDB-specific connections. """ -# Copyright (C) 2022 The GaussDB Team +# Copyright (C) 2022 The Psycopg Team from __future__ import annotations @@ -84,7 +84,7 @@ def server_version(self) -> int: """ Return the CockroachDB server version connected. - Return a number in the PostgreSQL format (e.g. 21.2.10 -> 210210). + Return a number in the GaussDB format (e.g. 21.2.10 -> 210210). """ sver = self.parameter_status("crdb_version") if not sver: diff --git a/gaussdb/gaussdb/cursor.py b/gaussdb/gaussdb/cursor.py index 6413d57ac..de46261bd 100644 --- a/gaussdb/gaussdb/cursor.py +++ b/gaussdb/gaussdb/cursor.py @@ -5,7 +5,7 @@ GaussDB Cursor object. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/cursor_async.py b/gaussdb/gaussdb/cursor_async.py index 7dfdf93b4..453df708f 100644 --- a/gaussdb/gaussdb/cursor_async.py +++ b/gaussdb/gaussdb/cursor_async.py @@ -2,7 +2,7 @@ GaussDB AsyncCursor object. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/dbapi20.py b/gaussdb/gaussdb/dbapi20.py index 7db04880b..5d7a583a0 100644 --- a/gaussdb/gaussdb/dbapi20.py +++ b/gaussdb/gaussdb/dbapi20.py @@ -2,7 +2,7 @@ Compatibility objects with DBAPI 2.0 """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/errors.py b/gaussdb/gaussdb/errors.py index ac750c0ec..c05c0c5c2 100644 --- a/gaussdb/gaussdb/errors.py +++ b/gaussdb/gaussdb/errors.py @@ -16,7 +16,7 @@ |__NotSupportedError """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -605,7 +605,7 @@ def get_base_exception(sqlstate: str) -> type[Error]: "54": OperationalError, # Program Limit Exceeded "55": OperationalError, # Object Not In Prerequisite State "57": OperationalError, # Operator Intervention - "58": OperationalError, # System Error (errors external to PostgreSQL itself) + "58": OperationalError, # System Error (errors external to GaussDB itself) "F": OperationalError, # Configuration File Error "H": OperationalError, # Foreign Data Wrapper Error (SQL/MED) "P": ProgrammingError, # PL/pgSQL Error @@ -1564,7 +1564,7 @@ class IdleSessionTimeout(OperationalError, pass -# Class 58 - System Error (errors external to PostgreSQL itself) +# Class 58 - System Error (errors external to GaussDB itself) class SystemError(OperationalError, code='58000', name='SYSTEM_ERROR'): diff --git a/gaussdb/gaussdb/postgres.py b/gaussdb/gaussdb/gaussdb_.py similarity index 78% rename from gaussdb/gaussdb/postgres.py rename to gaussdb/gaussdb/gaussdb_.py index d6373205a..b782ffc48 100644 --- a/gaussdb/gaussdb/postgres.py +++ b/gaussdb/gaussdb/gaussdb_.py @@ -1,8 +1,8 @@ """ -Types configuration specific to PostgreSQL. +Types configuration specific to GaussDB. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from .abc import AdaptContext from ._typemod import BitTypeModifier, CharTypeModifier, NumericTypeModifier @@ -10,10 +10,10 @@ from ._typeinfo import TypeInfo, TypesRegistry from ._adapters_map import AdaptersMap -# Global objects with PostgreSQL builtins and globally registered user types. +# Global objects with GaussDB builtins and globally registered user types. types = TypesRegistry() -# Global adapter maps with PostgreSQL types configuration +# Global adapter maps with GaussDB types configuration adapters = AdaptersMap(types=types) @@ -25,55 +25,69 @@ def register_default_types(types: TypesRegistry) -> None: for t in [ TypeInfo('"char"', 18, 1002, typemod=CharTypeModifier), # autogenerated: start - # Generated from PostgreSQL 17.0 + # Generated from GaussDB 505.2.0 + TypeInfo("TdigestData", 4406, 4407), + TypeInfo("abstime", 702, 1023), TypeInfo("aclitem", 1033, 1034), TypeInfo("bit", 1560, 1561, typemod=BitTypeModifier), + TypeInfo("blob", 88, 3201), TypeInfo("bool", 16, 1000, regtype="boolean"), + TypeInfo("boolvector", 4410, 1078), TypeInfo("box", 603, 1020, delimiter=";"), TypeInfo("bpchar", 1042, 1014, regtype="character", typemod=CharTypeModifier), TypeInfo("bytea", 17, 1001), + TypeInfo("byteawithoutordercol", 4403, 4405), + TypeInfo("byteawithoutorderwithequalcol", 4402, 4404), TypeInfo("cid", 29, 1012), TypeInfo("cidr", 650, 651), TypeInfo("circle", 718, 719), + TypeInfo("clob", 90, 3202), TypeInfo("date", 1082, 1182), TypeInfo("float4", 700, 1021, regtype="real"), TypeInfo("float8", 701, 1022, regtype="double precision"), + TypeInfo("floatvector", 4409, 1077), TypeInfo("gtsvector", 3642, 3644), + TypeInfo("hash16", 5801, 5803), + TypeInfo("hash32", 5802, 5804), + TypeInfo("hll", 4301, 4302), TypeInfo("inet", 869, 1041), + TypeInfo("int1", 5545, 5546), + TypeInfo("int16", 34, 1234), TypeInfo("int2", 21, 1005, regtype="smallint"), TypeInfo("int2vector", 22, 1006), + TypeInfo("int2vector_extend", 33, 1004), TypeInfo("int4", 23, 1007, regtype="integer"), TypeInfo("int8", 20, 1016, regtype="bigint"), TypeInfo("interval", 1186, 1187, typemod=TimeTypeModifier), TypeInfo("json", 114, 199), TypeInfo("jsonb", 3802, 3807), - TypeInfo("jsonpath", 4072, 4073), TypeInfo("line", 628, 629), TypeInfo("lseg", 601, 1018), TypeInfo("macaddr", 829, 1040), - TypeInfo("macaddr8", 774, 775), TypeInfo("money", 790, 791), TypeInfo("name", 19, 1003), TypeInfo("numeric", 1700, 1231, typemod=NumericTypeModifier), + TypeInfo("nvarchar2", 3969, 3968), TypeInfo("oid", 26, 1028), TypeInfo("oidvector", 30, 1013), + TypeInfo("oidvector_extend", 32, 1013), TypeInfo("path", 602, 1019), - TypeInfo("pg_lsn", 3220, 3221), TypeInfo("point", 600, 1017), TypeInfo("polygon", 604, 1027), + TypeInfo("raw", 86, 87), TypeInfo("record", 2249, 2287), TypeInfo("refcursor", 1790, 2201), TypeInfo("regclass", 2205, 2210), - TypeInfo("regcollation", 4191, 4192), TypeInfo("regconfig", 3734, 3735), TypeInfo("regdictionary", 3769, 3770), - TypeInfo("regnamespace", 4089, 4090), TypeInfo("regoper", 2203, 2208), TypeInfo("regoperator", 2204, 2209), TypeInfo("regproc", 24, 1008), TypeInfo("regprocedure", 2202, 2207), - TypeInfo("regrole", 4096, 4097), TypeInfo("regtype", 2206, 2211), + TypeInfo("reltime", 703, 1024), + TypeInfo("smalldatetime", 9003, 9005), + TypeInfo("smgr", 210, 0), TypeInfo("text", 25, 1009), TypeInfo("tid", 27, 1010), TypeInfo( @@ -104,17 +118,29 @@ def register_default_types(types: TypesRegistry) -> None: regtype="time with time zone", typemod=TimeTypeModifier, ), + TypeInfo("tinterval", 704, 1025), TypeInfo("tsquery", 3615, 3645), TypeInfo("tsvector", 3614, 3643), TypeInfo("txid_snapshot", 2970, 2949), + TypeInfo("uint1", 349, 1072), + TypeInfo("uint2", 352, 1073), + TypeInfo("uint4", 353, 1074), + TypeInfo("uint8", 388, 1075), + TypeInfo("unknown", 705, 0), TypeInfo("uuid", 2950, 2951), TypeInfo("varbit", 1562, 1563, regtype="bit varying", typemod=BitTypeModifier), TypeInfo( - "varchar", 1043, 1015, regtype="character varying", typemod=CharTypeModifier + "varchar", + 1043, + 1015, + regtype="character varying", + typemod=CharTypeModifier, ), TypeInfo("xid", 28, 1011), - TypeInfo("xid8", 5069, 271), + TypeInfo("xid32", 31, 1029), TypeInfo("xml", 142, 143), + TypeInfo("xmltype", 140, 141), + TypeInfo("year", 1038, 1076), RangeInfo("daterange", 3912, 3913, subtype_oid=1082), RangeInfo("int4range", 3904, 3905, subtype_oid=23), RangeInfo("int8range", 3926, 3927, subtype_oid=20), diff --git a/gaussdb/gaussdb/generators.py b/gaussdb/gaussdb/generators.py index b9f0bb720..21d36319f 100644 --- a/gaussdb/gaussdb/generators.py +++ b/gaussdb/gaussdb/generators.py @@ -18,7 +18,7 @@ generator should probably yield the same value again in order to wait more. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/pq/__init__.py b/gaussdb/gaussdb/pq/__init__.py index 5a67e4d4d..2c5029838 100644 --- a/gaussdb/gaussdb/pq/__init__.py +++ b/gaussdb/gaussdb/pq/__init__.py @@ -7,7 +7,7 @@ implementation-dependant but all the implementations share the same interface. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/pq/_debug.py b/gaussdb/gaussdb/pq/_debug.py index 862c31bd9..08c9364aa 100644 --- a/gaussdb/gaussdb/pq/_debug.py +++ b/gaussdb/gaussdb/pq/_debug.py @@ -26,7 +26,7 @@ """ -# Copyright (C) 2022 The GaussDB Team +# Copyright (C) 2022 The Psycopg Team import inspect import logging diff --git a/gaussdb/gaussdb/pq/_enums.py b/gaussdb/gaussdb/pq/_enums.py index 961d0cce5..fb68292bc 100644 --- a/gaussdb/gaussdb/pq/_enums.py +++ b/gaussdb/gaussdb/pq/_enums.py @@ -2,7 +2,7 @@ libpq enum definitions for gaussdb """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from enum import IntEnum, IntFlag, auto @@ -207,8 +207,6 @@ class DiagnosticField(IntEnum): __module__ = "gaussdb.pq" - # from src/include/postgres_ext.h - SEVERITY = ord("S") SEVERITY_NONLOCALIZED = ord("V") SQLSTATE = ord("C") diff --git a/gaussdb/gaussdb/pq/_pq_ctypes.py b/gaussdb/gaussdb/pq/_pq_ctypes.py index d6f3e7156..51cc0337e 100644 --- a/gaussdb/gaussdb/pq/_pq_ctypes.py +++ b/gaussdb/gaussdb/pq/_pq_ctypes.py @@ -2,7 +2,7 @@ libpq access using ctypes """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -115,8 +115,6 @@ class PGresAttDesc_struct(Structure): PGresAttDesc_ptr = POINTER(PGresAttDesc_struct) -# Function definitions as explained in PostgreSQL 12 documentation - # 33.1. Database Connection Control Functions # PQconnectdbParams: doesn't seem useful, won't wrap for now @@ -194,7 +192,7 @@ class PGresAttDesc_struct(Structure): def not_supported_before(fname: str, pgversion: int) -> Any: def not_supported(*args: Any, **kwargs: Any) -> NoReturn: raise NotSupportedError( - f"{fname} requires libpq from PostgreSQL {version_pretty(pgversion)} on" + f"{fname} requires libpq from GaussDB {version_pretty(pgversion)} on" f" the client; version {version_pretty(libpq_version)} available instead" ) diff --git a/gaussdb/gaussdb/pq/_pq_ctypes.pyi b/gaussdb/gaussdb/pq/_pq_ctypes.pyi index 48544d9f3..c64a2a42b 100644 --- a/gaussdb/gaussdb/pq/_pq_ctypes.pyi +++ b/gaussdb/gaussdb/pq/_pq_ctypes.pyi @@ -2,7 +2,7 @@ types stub for ctypes functions """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from ctypes import Array, _Pointer, c_char, c_char_p, c_int, c_ubyte, c_uint, c_ulong from ctypes import pointer diff --git a/gaussdb/gaussdb/pq/abc.py b/gaussdb/gaussdb/pq/abc.py index e6a3aecc6..105c47f8b 100644 --- a/gaussdb/gaussdb/pq/abc.py +++ b/gaussdb/gaussdb/pq/abc.py @@ -2,7 +2,7 @@ Protocol objects to represent objects exposed by different pq implementations. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/pq/misc.py b/gaussdb/gaussdb/pq/misc.py index 053d3764e..02c55513c 100644 --- a/gaussdb/gaussdb/pq/misc.py +++ b/gaussdb/gaussdb/pq/misc.py @@ -2,7 +2,7 @@ Various functionalities to make easier to work with the libpq. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -99,7 +99,7 @@ def error_message( # Possible prefixes to strip for error messages, in the known localizations. -# This regular expression is generated from PostgreSQL sources using the +# This regular expression is generated from GaussDB sources using the # `tools/update_error_prefixes.py` script PREFIXES = re.compile( # autogenerated: start @@ -177,7 +177,7 @@ def connection_summary(pgconn: abc.PGconn) -> str: def version_pretty(version: int) -> str: """ - Return a pretty representation of a PostgreSQL version + Return a pretty representation of a GaussDB version For instance: 140002 -> 14.2, 90610 -> 9.6.10 """ diff --git a/gaussdb/gaussdb/pq/pq_ctypes.py b/gaussdb/gaussdb/pq/pq_ctypes.py index 1e4046386..30720f66e 100644 --- a/gaussdb/gaussdb/pq/pq_ctypes.py +++ b/gaussdb/gaussdb/pq/pq_ctypes.py @@ -8,7 +8,7 @@ implementation. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -737,7 +737,7 @@ def encrypt_password( self, passwd: bytes, user: bytes, algorithm: bytes | None = None ) -> bytes: """ - Return the encrypted form of a PostgreSQL password. + Return the encrypted form of a GaussDB password. See :pq:`PQencryptPasswordConn` for details. """ @@ -753,7 +753,7 @@ def encrypt_password( def change_password(self, user: bytes, passwd: bytes) -> None: """ - Change a PostgreSQL password. + Change a GaussDB password. :raises OperationalError: if the command to change password failed. diff --git a/gaussdb/gaussdb/raw_cursor.py b/gaussdb/gaussdb/raw_cursor.py index 2a1fefb40..a66224156 100644 --- a/gaussdb/gaussdb/raw_cursor.py +++ b/gaussdb/gaussdb/raw_cursor.py @@ -2,7 +2,7 @@ gaussdb raw queries cursors """ -# Copyright (C) 2023 The GaussDB Team +# Copyright (C) 2023 The Psycopg Team from __future__ import annotations @@ -13,7 +13,7 @@ from .rows import Row from ._enums import PyFormat from .cursor import Cursor -from ._queries import PostgresQuery +from ._queries import GaussDBQuery from ._cursor_base import BaseCursor from .cursor_async import AsyncCursor from .server_cursor import AsyncServerCursor, ServerCursor @@ -25,7 +25,7 @@ from .connection_async import AsyncConnection # noqa: F401 -class PostgresRawQuery(PostgresQuery): +class GaussDBRawQuery(GaussDBQuery): def convert(self, query: Query, vars: Params | None) -> None: if isinstance(query, str): bquery = query.encode(self._encoding) @@ -40,7 +40,7 @@ def convert(self, query: Query, vars: Params | None) -> None: def dump(self, vars: Params | None) -> None: if vars is not None: - if not PostgresQuery.is_params_sequence(vars): + if not GaussDBQuery.is_params_sequence(vars): raise TypeError("raw queries require a sequence of parameters") self._want_formats = [PyFormat.AUTO] * len(vars) @@ -54,7 +54,7 @@ def dump(self, vars: Params | None) -> None: class RawCursorMixin(BaseCursor[ConnectionType, Row]): - _query_cls = PostgresRawQuery + _query_cls = GaussDBRawQuery class RawCursor(RawCursorMixin["Connection[Any]", Row], Cursor[Row]): diff --git a/gaussdb/gaussdb/rows.py b/gaussdb/gaussdb/rows.py index 74bfd05e2..8eb5ee0dc 100644 --- a/gaussdb/gaussdb/rows.py +++ b/gaussdb/gaussdb/rows.py @@ -2,7 +2,7 @@ gaussdb row factories """ -# Copyright (C) 2021 The GaussDB Team +# Copyright (C) 2021 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/server_cursor.py b/gaussdb/gaussdb/server_cursor.py index ee0fb1dd7..f2c2d054a 100644 --- a/gaussdb/gaussdb/server_cursor.py +++ b/gaussdb/gaussdb/server_cursor.py @@ -2,7 +2,7 @@ gaussdb server-side cursor objects. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -341,7 +341,7 @@ def __iter__(self) -> Iterator[Row]: def scroll(self, value: int, mode: str = "relative") -> None: with self._conn.lock: self._conn.wait(self._scroll_gen(value, mode)) - # Postgres doesn't have a reliable way to report a cursor out of bound + # GaussDB doesn't have a reliable way to report a cursor out of bound if mode == "relative": self._pos += value else: diff --git a/gaussdb/gaussdb/sql.py b/gaussdb/gaussdb/sql.py index decb0dbd5..f412aa28e 100644 --- a/gaussdb/gaussdb/sql.py +++ b/gaussdb/gaussdb/sql.py @@ -2,7 +2,7 @@ SQL composition utility module """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -328,7 +328,7 @@ class Identifier(Composable): A `Composable` representing an SQL identifier or a dot-separated sequence. Identifiers usually represent names of database objects, such as tables or - fields. PostgreSQL identifiers follow `different rules`__ than SQL string + fields. GaussDB identifiers follow `different rules`__ than SQL string literals for escaping (e.g. they use double quotes instead of single). .. __: https://www.postgresql.org/docs/current/sql-syntax-lexical.html# \ diff --git a/gaussdb/gaussdb/transaction.py b/gaussdb/gaussdb/transaction.py index 020b31685..c6b9562b1 100644 --- a/gaussdb/gaussdb/transaction.py +++ b/gaussdb/gaussdb/transaction.py @@ -2,7 +2,7 @@ Transaction context managers returned by Connection.transaction() """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/types/__init__.py b/gaussdb/gaussdb/types/__init__.py index 9a4025223..3008dfc25 100644 --- a/gaussdb/gaussdb/types/__init__.py +++ b/gaussdb/gaussdb/types/__init__.py @@ -2,7 +2,7 @@ gaussdb types package """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from .. import _typeinfo diff --git a/gaussdb/gaussdb/types/array.py b/gaussdb/gaussdb/types/array.py index ee36cbe85..639ed6391 100644 --- a/gaussdb/gaussdb/types/array.py +++ b/gaussdb/gaussdb/types/array.py @@ -2,7 +2,7 @@ Adapters for arrays """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -13,7 +13,7 @@ from functools import cache from .. import errors as e -from .. import postgres, pq +from .. import gaussdb_, pq from ..abc import AdaptContext, Buffer, Dumper, DumperKey, Loader, NoneType, Transformer from .._oids import INVALID_OID, TEXT_ARRAY_OID, TEXT_OID from ..adapt import PyFormat, RecursiveDumper, RecursiveLoader @@ -77,7 +77,7 @@ def _find_list_element(self, L: list[Any], format: PyFormat) -> Any: return v # If we got an int, let's see what is the biggest one in order to - # choose the smallest OID and allow Postgres to do the right cast. + # choose the smallest OID and allow GaussDB to do the right cast. imax: int = max(items) imin: int = min(items) if imin >= 0: @@ -201,8 +201,6 @@ def _dump_item(self, item: Any) -> Buffer | None: def _get_needs_quotes_regexp(delimiter: bytes) -> re.Pattern[bytes]: """Return a regexp to recognise when a value needs quotes - from https://www.postgresql.org/docs/current/arrays.html#ARRAYS-IO - The array output routine will put double quotes around element values if they are empty strings, contain curly braces, delimiter characters, double quotes, backslashes, or white space, or match the word NULL. @@ -249,7 +247,7 @@ def upgrade(self, obj: list[Any], format: PyFormat) -> BaseListDumper: return dumper def dump(self, obj: list[Any]) -> Buffer | None: - # Postgres won't take unknown for element oid: fall back on text + # GaussDB won't take unknown for element oid: fall back on text sub_oid = self.sub_dumper and self.sub_dumper.oid or TEXT_OID if not obj: @@ -317,7 +315,7 @@ def register_array(info: TypeInfo, context: AdaptContext | None = None) -> None: if not info.array_oid: raise ValueError(f"the type info {info} doesn't describe an array") - adapters = context.adapters if context else postgres.adapters + adapters = context.adapters if context else gaussdb_.adapters loader = _make_loader(info.name, info.oid, info.delimiter) adapters.register_loader(info.array_oid, loader) diff --git a/gaussdb/gaussdb/types/bool.py b/gaussdb/gaussdb/types/bool.py index e2071ed83..8f367b80e 100644 --- a/gaussdb/gaussdb/types/bool.py +++ b/gaussdb/gaussdb/types/bool.py @@ -2,7 +2,7 @@ Adapters for booleans. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/types/composite.py b/gaussdb/gaussdb/types/composite.py index 05659e30c..d15133a8d 100644 --- a/gaussdb/gaussdb/types/composite.py +++ b/gaussdb/gaussdb/types/composite.py @@ -2,7 +2,7 @@ Support for composite types adaptation. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -13,7 +13,7 @@ from collections import namedtuple from collections.abc import Iterator, Sequence -from .. import abc, postgres, pq, sql +from .. import abc, gaussdb_, pq, sql from .._oids import TEXT_OID from ..adapt import Buffer, Dumper, Loader, PyFormat, RecursiveDumper, Transformer from .._struct import pack_len, unpack_len @@ -303,7 +303,7 @@ def register_composite( if not factory: factory = _nt_from_info(info) - adapters = context.adapters if context else postgres.adapters + adapters = context.adapters if context else gaussdb_.adapters # generate and register a customized text loader loader: type[BaseCompositeLoader] diff --git a/gaussdb/gaussdb/types/datetime.py b/gaussdb/gaussdb/types/datetime.py index 5cf1cc1b0..b9f600e52 100644 --- a/gaussdb/gaussdb/types/datetime.py +++ b/gaussdb/gaussdb/types/datetime.py @@ -2,7 +2,7 @@ Adapters for date/time types. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -43,7 +43,7 @@ class DateDumper(Dumper): oid = _oids.DATE_OID def dump(self, obj: date) -> Buffer | None: - # NOTE: whatever the PostgreSQL DateStyle input format (DMY, MDY, YMD) + # NOTE: whatever the GaussDB DateStyle input format (DMY, MDY, YMD) # the YYYY-MM-DD is always understood correctly. return str(obj).encode() @@ -145,7 +145,7 @@ def upgrade(self, obj: datetime, format: PyFormat) -> Dumper: class _BaseDatetimeTextDumper(_BaseDatetimeDumper): def dump(self, obj: datetime) -> Buffer | None: - # NOTE: whatever the PostgreSQL DateStyle input format (DMY, MDY, YMD) + # NOTE: whatever the GaussDB DateStyle input format (DMY, MDY, YMD) # the YYYY-MM-DD is always understood correctly. return str(obj).encode() @@ -205,7 +205,7 @@ def dump(self, obj: timedelta) -> Buffer | None: @staticmethod def _dump_any(self: TimedeltaDumper, obj: timedelta) -> bytes: - # The comma is parsed ok by PostgreSQL but it's not documented + # The comma is parsed ok by GaussDB but it's not documented # and it seems brittle to rely on it. CRDB doesn't consume it well. return str(obj).encode().replace(b",", b"") @@ -241,7 +241,7 @@ def __init__(self, oid: int, context: AdaptContext | None = None): self._order = self._ORDER_YMD elif ds.startswith(b"G"): # German self._order = self._ORDER_DMY - elif ds.startswith(b"S") or ds.startswith(b"P"): # SQL or Postgres + elif ds.startswith(b"S") or ds.startswith(b"P"): # SQL or GaussDB self._order = self._ORDER_DMY if ds.endswith(b"DMY") else self._ORDER_MDY else: raise InterfaceError(f"unexpected DateStyle: {ds.decode('ascii')}") @@ -423,7 +423,7 @@ def __init__(self, oid: int, context: AdaptContext | None = None): self._order = self._ORDER_DMY elif ds.startswith(b"S"): # SQL self._order = self._ORDER_DMY if ds.endswith(b"DMY") else self._ORDER_MDY - elif ds.startswith(b"P"): # Postgres + elif ds.startswith(b"P"): # GaussDB self._order = self._ORDER_PGDM if ds.endswith(b"DMY") else self._ORDER_PGMD self._re_format = self._re_format_pg else: @@ -615,7 +615,7 @@ class IntervalLoader(Loader): def __init__(self, oid: int, context: AdaptContext | None = None): super().__init__(oid, context) if _get_intervalstyle(self.connection) == b"postgres": - self._load_method = self._load_postgres + self._load_method = self._load_gaussdb else: self._load_method = self._load_notimpl @@ -623,7 +623,7 @@ def load(self, data: Buffer) -> timedelta: return self._load_method(self, data) @staticmethod - def _load_postgres(self: IntervalLoader, data: Buffer) -> timedelta: + def _load_gaussdb(self: IntervalLoader, data: Buffer) -> timedelta: m = self._re_interval.match(data) if not m: s = bytes(data).decode("utf8", "replace") @@ -706,7 +706,7 @@ def is_overflow(s: str) -> bool: return False ds = _get_datestyle(conn) - if not ds.startswith(b"P"): # Postgres + if not ds.startswith(b"P"): # GaussDB return len(s.split()[0]) > 10 # date is first token else: return len(s.split()[-1]) > 4 # year is last token diff --git a/gaussdb/gaussdb/types/enum.py b/gaussdb/gaussdb/types/enum.py index 787883b57..f9913107b 100644 --- a/gaussdb/gaussdb/types/enum.py +++ b/gaussdb/gaussdb/types/enum.py @@ -10,7 +10,7 @@ from collections.abc import Mapping, Sequence from .. import errors as e -from .. import postgres, sql +from .. import gaussdb_, sql from ..pq import Format from ..abc import AdaptContext, Query from ..adapt import Buffer, Dumper, Loader @@ -133,7 +133,7 @@ def register_enum( :param info: The object with the information about the enum to register. :param context: The context where to register the adapters. If `!None`, register it globally. - :param enum: Python enum type matching to the PostgreSQL one. If `!None`, + :param enum: Python enum type matching to the GaussDB one. If `!None`, a new enum will be generated and exposed as `EnumInfo.enum`. :param mapping: Override the mapping between `!enum` members and `!info` labels. @@ -146,7 +146,7 @@ def register_enum( enum = cast("type[E]", _make_enum(info.name, tuple(info.labels))) info.enum = enum - adapters = context.adapters if context else postgres.adapters + adapters = context.adapters if context else gaussdb_.adapters info.register(context) load_map = _make_load_map(info, enum, mapping, context) diff --git a/gaussdb/gaussdb/types/hstore.py b/gaussdb/gaussdb/types/hstore.py index 749154c8f..0cf30d86c 100644 --- a/gaussdb/gaussdb/types/hstore.py +++ b/gaussdb/gaussdb/types/hstore.py @@ -2,7 +2,7 @@ dict to hstore adaptation """ -# Copyright (C) 2021 The GaussDB Team +# Copyright (C) 2021 The Psycopg Team from __future__ import annotations @@ -10,7 +10,7 @@ from functools import cache from .. import errors as e -from .. import postgres +from .. import gaussdb_ from ..abc import AdaptContext, Buffer from .._oids import TEXT_OID from ..adapt import PyFormat, RecursiveDumper, RecursiveLoader @@ -120,7 +120,7 @@ def register_hstore(info: TypeInfo, context: AdaptContext | None = None) -> None # Register arrays and type info info.register(context) - adapters = context.adapters if context else postgres.adapters + adapters = context.adapters if context else gaussdb_.adapters # Generate and register a customized text dumper adapters.register_dumper(dict, _make_hstore_dumper(info.oid)) diff --git a/gaussdb/gaussdb/types/json.py b/gaussdb/gaussdb/types/json.py index b09f7856c..8239c47c4 100644 --- a/gaussdb/gaussdb/types/json.py +++ b/gaussdb/gaussdb/types/json.py @@ -2,7 +2,7 @@ Adapters for JSON types. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/types/multirange.py b/gaussdb/gaussdb/types/multirange.py index 042a76361..b90c12777 100644 --- a/gaussdb/gaussdb/types/multirange.py +++ b/gaussdb/gaussdb/types/multirange.py @@ -2,7 +2,7 @@ Support for multirange types adaptation. """ -# Copyright (C) 2021 The GaussDB Team +# Copyright (C) 2021 The Psycopg Team from __future__ import annotations @@ -14,7 +14,7 @@ from .. import _oids from .. import errors as e -from .. import postgres +from .. import gaussdb_ from ..pq import Format from ..abc import AdaptContext, Buffer, Dumper, DumperKey, Query from .range import Range, T, dump_range_binary, dump_range_text, fail_dump @@ -56,7 +56,7 @@ def _added(self, registry: TypesRegistry) -> None: class Multirange(MutableSequence[Range[T]]): - """Python representation for a PostgreSQL multirange type. + """Python representation for a GaussDB multirange type. :param items: Sequence of ranges to initialise the object. """ @@ -196,7 +196,7 @@ def upgrade(self, obj: Multirange[Any], format: PyFormat) -> BaseMultirangeDumpe dumper: BaseMultirangeDumper if type(item) is int: - # postgres won't cast int4range -> int8range so we must use + # gaussdb won't cast int4range -> int8range so we must use # text format and unknown oid here sd = self._tx.get_dumper(item, PyFormat.TEXT) dumper = MultirangeDumper(self.cls, self._tx) @@ -377,7 +377,7 @@ def register_multirange( # Register arrays and type info info.register(context) - adapters = context.adapters if context else postgres.adapters + adapters = context.adapters if context else gaussdb_.adapters # generate and register a customized text loader loader: type[BaseMultirangeLoader[Any]] diff --git a/gaussdb/gaussdb/types/net.py b/gaussdb/gaussdb/types/net.py index 7ca9b916c..31b9a961a 100644 --- a/gaussdb/gaussdb/types/net.py +++ b/gaussdb/gaussdb/types/net.py @@ -2,7 +2,7 @@ Adapters for network types. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/types/none.py b/gaussdb/gaussdb/types/none.py index c217d039e..b53d80a9c 100644 --- a/gaussdb/gaussdb/types/none.py +++ b/gaussdb/gaussdb/types/none.py @@ -2,7 +2,7 @@ Adapters for None. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -17,7 +17,7 @@ class NoneDumper(Dumper): """ def dump(self, obj: None) -> Buffer | None: - raise NotImplementedError("NULL is passed to Postgres in other ways") + raise NotImplementedError("NULL is passed to GaussDB in other ways") def quote(self, obj: None) -> Buffer: return b"NULL" diff --git a/gaussdb/gaussdb/types/numeric.py b/gaussdb/gaussdb/types/numeric.py index 9a3a614a0..13fc4c1fe 100644 --- a/gaussdb/gaussdb/types/numeric.py +++ b/gaussdb/gaussdb/types/numeric.py @@ -2,7 +2,7 @@ Adapters for numeric types. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -275,7 +275,7 @@ def load(self, data: Buffer) -> Decimal: return Decimal(data.decode()) -DEC_DIGITS = 4 # decimal digits per Postgres "digit" +DEC_DIGITS = 4 # decimal digits per GaussDB "digit" NUMERIC_POS = 0x0000 NUMERIC_NEG = 0x4000 NUMERIC_NAN = 0xC000 @@ -359,7 +359,7 @@ def dump(self, obj: Decimal) -> Buffer | None: class _MixedNumericDumper(Dumper, ABC): - """Base for dumper to dump int, decimal, numpy.integer to Postgres numeric + """Base for dumper to dump int, decimal, numpy.integer to GaussDB numeric Only used when looking up by oid. """ diff --git a/gaussdb/gaussdb/types/numpy.py b/gaussdb/gaussdb/types/numpy.py index 7941af7ec..e83b9731c 100644 --- a/gaussdb/gaussdb/types/numpy.py +++ b/gaussdb/gaussdb/types/numpy.py @@ -2,7 +2,7 @@ Adapters for numpy types. """ -# Copyright (C) 2022 The GaussDB Team +# Copyright (C) 2022 The Psycopg Team from typing import Any diff --git a/gaussdb/gaussdb/types/range.py b/gaussdb/gaussdb/types/range.py index f7de846cb..ed4bd7a08 100644 --- a/gaussdb/gaussdb/types/range.py +++ b/gaussdb/gaussdb/types/range.py @@ -2,7 +2,7 @@ Support for range types adaptation. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -14,7 +14,7 @@ from .. import _oids from .. import errors as e -from .. import postgres, sql +from .. import gaussdb_, sql from ..pq import Format from ..abc import AdaptContext, Buffer, Dumper, DumperKey, DumpFunc, LoadFunc, Query from .._oids import INVALID_OID, TEXT_OID @@ -71,7 +71,7 @@ def _added(self, registry: TypesRegistry) -> None: class Range(Generic[T]): - """Python representation for a PostgreSQL range type. + """Python representation for a GaussDB range type. :param lower: lower bound for the range. `!None` means unbound :param upper: upper bound for the range. `!None` means unbound @@ -215,7 +215,7 @@ def __eq__(self, other: Any) -> bool: def __hash__(self) -> int: return hash((self._lower, self._upper, self._bounds)) - # as the postgres docs describe for the server-side stuff, + # as the gaussdb docs describe for the server-side stuff, # ordering is rather arbitrary, but will remain stable # and consistent. @@ -314,7 +314,7 @@ def upgrade(self, obj: Range[Any], format: PyFormat) -> BaseRangeDumper: dumper: BaseRangeDumper if type(item) is int: - # postgres won't cast int4range -> int8range so we must use + # gaussdb won't cast int4range -> int8range so we must use # text format and unknown oid here sd = self._tx.get_dumper(item, PyFormat.TEXT) dumper = RangeDumper(self.cls, self._tx) @@ -583,7 +583,7 @@ def register_range(info: RangeInfo, context: AdaptContext | None = None) -> None # Register arrays and type info info.register(context) - adapters = context.adapters if context else postgres.adapters + adapters = context.adapters if context else gaussdb_.adapters # generate and register a customized text loader loader: type[BaseRangeLoader[Any]] diff --git a/gaussdb/gaussdb/types/shapely.py b/gaussdb/gaussdb/types/shapely.py index 449054710..3786a65a6 100644 --- a/gaussdb/gaussdb/types/shapely.py +++ b/gaussdb/gaussdb/types/shapely.py @@ -6,7 +6,7 @@ from functools import cache -from .. import postgres +from .. import gaussdb_ from ..pq import Format from ..abc import AdaptContext, Buffer from ..adapt import Dumper, Loader @@ -66,7 +66,7 @@ def register_shapely(info: TypeInfo, context: AdaptContext | None = None) -> Non raise TypeError("no info passed. Is the 'postgis' extension loaded?") info.register(context) - adapters = context.adapters if context else postgres.adapters + adapters = context.adapters if context else gaussdb_.adapters adapters.register_loader(info.oid, GeometryBinaryLoader) adapters.register_loader(info.oid, GeometryLoader) diff --git a/gaussdb/gaussdb/types/string.py b/gaussdb/gaussdb/types/string.py index e7fafb72e..a5d40be6a 100644 --- a/gaussdb/gaussdb/types/string.py +++ b/gaussdb/gaussdb/types/string.py @@ -2,7 +2,7 @@ Adapters for textual types. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations @@ -28,7 +28,7 @@ def __init__(self, cls: type, context: AdaptContext | None = None): class _StrBinaryDumper(_BaseStrDumper): """ - Base class to dump a Python strings to a Postgres text type, in binary format. + Base class to dump a Python strings to a GaussDB text type, in binary format. Subclasses shall specify the oids of real types (text, varchar, name...). """ @@ -42,14 +42,14 @@ def dump(self, obj: str) -> Buffer | None: class _StrDumper(_BaseStrDumper): """ - Base class to dump a Python strings to a Postgres text type, in text format. + Base class to dump a Python strings to a GaussDB text type, in text format. Subclasses shall specify the oids of real types (text, varchar, name...). """ def dump(self, obj: str) -> Buffer | None: if "\x00" in obj: - raise DataError("PostgreSQL text fields cannot contain NUL (0x00) bytes") + raise DataError("GaussDB text fields cannot contain NUL (0x00) bytes") else: return obj.encode(self._encoding) @@ -74,7 +74,7 @@ class StrDumper(_StrDumper): Dumper for strings in text format to the text oid. Note that this dumper is not used by default because the type is too strict - and PostgreSQL would require an explicit casts to everything that is not a + and GaussDB would require an explicit casts to everything that is not a text field. However it is useful where the unknown oid is ambiguous and the text oid is required, for instance with variadic functions. """ diff --git a/gaussdb/gaussdb/types/uuid.py b/gaussdb/gaussdb/types/uuid.py index 30e47cd7a..596337746 100644 --- a/gaussdb/gaussdb/types/uuid.py +++ b/gaussdb/gaussdb/types/uuid.py @@ -2,7 +2,7 @@ Adapters for the UUID type. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations diff --git a/gaussdb/gaussdb/version.py b/gaussdb/gaussdb/version.py index 0fa864dd4..1415d18b9 100644 --- a/gaussdb/gaussdb/version.py +++ b/gaussdb/gaussdb/version.py @@ -2,7 +2,7 @@ gaussdb distribution version file. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from importlib import metadata diff --git a/gaussdb/gaussdb/waiting.py b/gaussdb/gaussdb/waiting.py index f460610f8..f7c295577 100644 --- a/gaussdb/gaussdb/waiting.py +++ b/gaussdb/gaussdb/waiting.py @@ -6,7 +6,7 @@ """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team from __future__ import annotations diff --git a/gaussdb_pool/README.rst b/gaussdb_pool/README.rst index 0eaee00d5..a0fcfc15f 100644 --- a/gaussdb_pool/README.rst +++ b/gaussdb_pool/README.rst @@ -1,11 +1,8 @@ -gaussdb: PostgreSQL database adapter for Python - Connection Pool +gaussdb: GaussDB database adapter for Python - Connection Pool =================================================================== -This distribution package is an optional component of `gaussdb`__: it -contains the optional connection pool package `gaussdb_pool`__. - -.. __: https://pypi.org/project/gaussdb/ -.. __: https://www.gaussdb.org/gaussdb/docs/advanced/pool.html +This distribution package is an optional component of `gaussdb`: it +contains the optional connection pool package `gaussdb_pool`. This package is kept separate from the main ``gaussdb`` package because it is likely that it will follow a different release cycle. @@ -14,12 +11,8 @@ You can also install this package using:: pip install "gaussdb[pool]" -Please read `the project readme`__ and `the installation documentation`__ for +Please read `the project readme` and `the installation documentation` for more details. -.. __: https://github.com/gaussdb/gaussdb#readme -.. __: https://www.gaussdb.org/gaussdb/docs/basic/install.html - #installing-the-connection-pool - -Copyright (C) 2020 The GaussDB Team +Copyright (C) 2020 The Psycopg Team diff --git a/gaussdb_pool/gaussdb_pool/__init__.py b/gaussdb_pool/gaussdb_pool/__init__.py index 4a6b2fd43..33605de32 100644 --- a/gaussdb_pool/gaussdb_pool/__init__.py +++ b/gaussdb_pool/gaussdb_pool/__init__.py @@ -2,7 +2,7 @@ gaussdb connection pool package """ -# Copyright (C) 2021 The GaussDB Team +# Copyright (C) 2021 The Psycopg Team from .pool import ConnectionPool from .errors import PoolClosed, PoolTimeout, TooManyRequests diff --git a/gaussdb_pool/gaussdb_pool/_acompat.py b/gaussdb_pool/gaussdb_pool/_acompat.py index 356f680f1..2e6424c98 100644 --- a/gaussdb_pool/gaussdb_pool/_acompat.py +++ b/gaussdb_pool/gaussdb_pool/_acompat.py @@ -6,7 +6,7 @@ when generating the sync version. """ -# Copyright (C) 2023 The GaussDB Team +# Copyright (C) 2023 The Psycopg Team from __future__ import annotations diff --git a/gaussdb_pool/gaussdb_pool/_compat.py b/gaussdb_pool/gaussdb_pool/_compat.py index 5d6982742..3672f304a 100644 --- a/gaussdb_pool/gaussdb_pool/_compat.py +++ b/gaussdb_pool/gaussdb_pool/_compat.py @@ -2,7 +2,7 @@ compatibility functions for different Python versions """ -# Copyright (C) 2021 The GaussDB Team +# Copyright (C) 2021 The Psycopg Team from __future__ import annotations diff --git a/gaussdb_pool/gaussdb_pool/_task.py b/gaussdb_pool/gaussdb_pool/_task.py index c0275b956..7629d1c46 100644 --- a/gaussdb_pool/gaussdb_pool/_task.py +++ b/gaussdb_pool/gaussdb_pool/_task.py @@ -2,7 +2,7 @@ Task for Scheduler and AsyncScheduler """ -# Copyright (C) 2023 The GaussDB Team +# Copyright (C) 2023 The Psycopg Team from __future__ import annotations diff --git a/gaussdb_pool/gaussdb_pool/abc.py b/gaussdb_pool/gaussdb_pool/abc.py index 3f9b22dd9..058e7da45 100644 --- a/gaussdb_pool/gaussdb_pool/abc.py +++ b/gaussdb_pool/gaussdb_pool/abc.py @@ -2,7 +2,7 @@ Types used in the gaussdb_pool package """ -# Copyright (C) 2023 The GaussDB Team +# Copyright (C) 2023 The Psycopg Team from __future__ import annotations diff --git a/gaussdb_pool/gaussdb_pool/base.py b/gaussdb_pool/gaussdb_pool/base.py index c7c3dae4f..1bdfb3e86 100644 --- a/gaussdb_pool/gaussdb_pool/base.py +++ b/gaussdb_pool/gaussdb_pool/base.py @@ -2,7 +2,7 @@ gaussdb connection pool base class and functionalities. """ -# Copyright (C) 2021 The GaussDB Team +# Copyright (C) 2021 The Psycopg Team from __future__ import annotations diff --git a/gaussdb_pool/gaussdb_pool/base_null_pool.py b/gaussdb_pool/gaussdb_pool/base_null_pool.py index 0ddfec358..2025ab1f8 100644 --- a/gaussdb_pool/gaussdb_pool/base_null_pool.py +++ b/gaussdb_pool/gaussdb_pool/base_null_pool.py @@ -2,7 +2,7 @@ GaussDB mixin class for null connection pools """ -# Copyright (C) 2022 The GaussDB Team +# Copyright (C) 2022 The Psycopg Team from __future__ import annotations diff --git a/gaussdb_pool/gaussdb_pool/errors.py b/gaussdb_pool/gaussdb_pool/errors.py index 56bd7db05..b25f58b94 100644 --- a/gaussdb_pool/gaussdb_pool/errors.py +++ b/gaussdb_pool/gaussdb_pool/errors.py @@ -2,7 +2,7 @@ Connection pool errors. """ -# Copyright (C) 2021 The GaussDB Team +# Copyright (C) 2021 The Psycopg Team from gaussdb import errors as e diff --git a/gaussdb_pool/gaussdb_pool/null_pool.py b/gaussdb_pool/gaussdb_pool/null_pool.py index a48c83df4..36f1384c5 100644 --- a/gaussdb_pool/gaussdb_pool/null_pool.py +++ b/gaussdb_pool/gaussdb_pool/null_pool.py @@ -5,7 +5,7 @@ GaussDB null connection pool module (sync version). """ -# Copyright (C) 2022 The GaussDB Team +# Copyright (C) 2022 The Psycopg Team from __future__ import annotations diff --git a/gaussdb_pool/gaussdb_pool/null_pool_async.py b/gaussdb_pool/gaussdb_pool/null_pool_async.py index e6331843e..763d18329 100644 --- a/gaussdb_pool/gaussdb_pool/null_pool_async.py +++ b/gaussdb_pool/gaussdb_pool/null_pool_async.py @@ -2,7 +2,7 @@ GaussDB null connection pool module (async version). """ -# Copyright (C) 2022 The GaussDB Team +# Copyright (C) 2022 The Psycopg Team from __future__ import annotations diff --git a/gaussdb_pool/gaussdb_pool/pool.py b/gaussdb_pool/gaussdb_pool/pool.py index a12f1725a..10bf032b7 100644 --- a/gaussdb_pool/gaussdb_pool/pool.py +++ b/gaussdb_pool/gaussdb_pool/pool.py @@ -5,7 +5,7 @@ GaussDB connection pool module (sync version). """ -# Copyright (C) 2021 The GaussDB Team +# Copyright (C) 2021 The Psycopg Team from __future__ import annotations diff --git a/gaussdb_pool/gaussdb_pool/pool_async.py b/gaussdb_pool/gaussdb_pool/pool_async.py index c144f8a0e..698bcb538 100644 --- a/gaussdb_pool/gaussdb_pool/pool_async.py +++ b/gaussdb_pool/gaussdb_pool/pool_async.py @@ -2,7 +2,7 @@ GaussDB connection pool module (async version). """ -# Copyright (C) 2021 The GaussDB Team +# Copyright (C) 2021 The Psycopg Team from __future__ import annotations diff --git a/gaussdb_pool/gaussdb_pool/sched.py b/gaussdb_pool/gaussdb_pool/sched.py index 6566b5c1a..f41179858 100644 --- a/gaussdb_pool/gaussdb_pool/sched.py +++ b/gaussdb_pool/gaussdb_pool/sched.py @@ -13,7 +13,7 @@ `[threading/asyncio].Event` and the two would be confusing. """ -# Copyright (C) 2021 The GaussDB Team +# Copyright (C) 2021 The Psycopg Team from __future__ import annotations diff --git a/gaussdb_pool/gaussdb_pool/sched_async.py b/gaussdb_pool/gaussdb_pool/sched_async.py index 732e1b45a..86f59d036 100644 --- a/gaussdb_pool/gaussdb_pool/sched_async.py +++ b/gaussdb_pool/gaussdb_pool/sched_async.py @@ -10,7 +10,7 @@ `[threading/asyncio].Event` and the two would be confusing. """ -# Copyright (C) 2021 The GaussDB Team +# Copyright (C) 2021 The Psycopg Team from __future__ import annotations diff --git a/gaussdb_pool/gaussdb_pool/version.py b/gaussdb_pool/gaussdb_pool/version.py index 246143515..81be77efa 100644 --- a/gaussdb_pool/gaussdb_pool/version.py +++ b/gaussdb_pool/gaussdb_pool/version.py @@ -2,7 +2,7 @@ gaussdb pool version file. """ -# Copyright (C) 2021 The GaussDB Team +# Copyright (C) 2021 The Psycopg Team from importlib import metadata diff --git a/tests/crdb/test_adapt.py b/tests/crdb/test_adapt.py index 457a58fd1..5ce34a372 100644 --- a/tests/crdb/test_adapt.py +++ b/tests/crdb/test_adapt.py @@ -4,7 +4,7 @@ from gaussdb.crdb import CrdbConnection, adapters from gaussdb.adapt import PyFormat, Transformer -from gaussdb.postgres import types as builtins +from gaussdb.gaussdb_ import types as builtins from gaussdb.types.array import ListDumper from ..test_adapt import MyStr, make_bin_dumper, make_bin_loader, make_dumper @@ -17,10 +17,10 @@ def test_return_untyped(conn, fmt_in): # Analyze and check for changes using strings in untyped/typed contexts cur = conn.cursor() - # Currently string are passed as text oid to CockroachDB, unlike Postgres, + # Currently string are passed as text oid to CockroachDB, unlike GaussDB, # to which strings are passed as unknown. This is because CRDB doesn't # allow the unknown oid to be emitted; execute("SELECT %s", ["str"]) raises - # an error. However, unlike PostgreSQL, text can be cast to any other type. + # an error. However, unlike GaussDB, text can be cast to any other type. cur.execute(f"select %{fmt_in.value}, %{fmt_in.value}", ["hello", 10]) assert cur.fetchone() == ("hello", 10) diff --git a/tests/fix_db.py b/tests/fix_db.py index c99b2a0fd..fa0880608 100644 --- a/tests/fix_db.py +++ b/tests/fix_db.py @@ -14,7 +14,7 @@ from gaussdb.conninfo import conninfo_to_dict, make_conninfo from gaussdb.pq._debug import PGconnDebug -from .utils import check_postgres_version +from .utils import check_gaussdb_version # Set by warm_up_database() the first time the dsn fixture is used pg_version: int @@ -330,7 +330,7 @@ def check_connection_version(node): for mark in node.iter_markers(): if mark.name == "pg": assert len(mark.args) == 1 - msg = check_postgres_version(pg_version, mark.args[0]) + msg = check_gaussdb_version(pg_version, mark.args[0]) if msg: pytest.skip(msg) diff --git a/tests/pq/test_pgconn.py b/tests/pq/test_pgconn.py index df11f8aa4..52c7c9eb2 100644 --- a/tests/pq/test_pgconn.py +++ b/tests/pq/test_pgconn.py @@ -544,7 +544,7 @@ def role(pgconn: PGconn) -> Iterator[tuple[bytes, bytes]]: user, passwd = "ashesh", "_GaussDB" r = pgconn.exec_(f"CREATE USER {user} LOGIN PASSWORD '{passwd}'".encode()) if r.status != pq.ExecStatus.COMMAND_OK: - pytest.skip(f"cannot create a PostgreSQL role: {r.get_error_message()}") + pytest.skip(f"cannot create a GaussDB role: {r.get_error_message()}") yield user.encode(), passwd.encode() r = pgconn.exec_(f"DROP USER {user}".encode()) if r.status != pq.ExecStatus.COMMAND_OK: diff --git a/tests/test_adapt.py b/tests/test_adapt.py index 04fcaac4d..7339b7504 100644 --- a/tests/test_adapt.py +++ b/tests/test_adapt.py @@ -8,11 +8,11 @@ import gaussdb from gaussdb import errors as e -from gaussdb import postgres, pq, sql +from gaussdb import gaussdb_, pq, sql from gaussdb.abc import Buffer from gaussdb.adapt import Dumper, Loader, PyFormat, Transformer from gaussdb._cmodule import _gaussdb -from gaussdb.postgres import types as builtins +from gaussdb.gaussdb_ import types as builtins from gaussdb.types.array import ListBinaryDumper, ListDumper from gaussdb.types.string import StrBinaryDumper, StrDumper @@ -391,7 +391,7 @@ def test_return_untyped(conn, fmt_in): # Analyze and check for changes using strings in untyped/typed contexts cur = conn.cursor() # Currently string are passed as unknown oid to libpq. This is because - # unknown is more easily cast by postgres to different types (see jsonb + # unknown is more easily cast by gaussdb to different types (see jsonb # later). cur.execute(f"select %{fmt_in.value}, %{fmt_in.value}", ["hello", 10]) assert cur.fetchone() == ("hello", 10) @@ -433,7 +433,7 @@ def test_optimised_adapters(): # All the registered adapters reg_adapters = set() - adapters = list(postgres.adapters._dumpers.values()) + postgres.adapters._loaders + adapters = list(gaussdb_.adapters._dumpers.values()) + gaussdb_.adapters._loaders assert len(adapters) == 5 for m in adapters: reg_adapters |= set(m.values()) diff --git a/tests/test_column.py b/tests/test_column.py index 3a3b161a1..20bf30c34 100644 --- a/tests/test_column.py +++ b/tests/test_column.py @@ -2,7 +2,7 @@ import pytest -from gaussdb.postgres import types as builtins +from gaussdb.gaussdb_ import types as builtins from .fix_crdb import crdb_encoding, is_crdb diff --git a/tests/test_copy.py b/tests/test_copy.py index 8beb2c8a9..2653e959b 100644 --- a/tests/test_copy.py +++ b/tests/test_copy.py @@ -29,6 +29,7 @@ @pytest.mark.opengauss_skip("read row not supported in binary copy") +@pytest.mark.gaussdb_skip("read row not supported in binary copy") @pytest.mark.parametrize("format", pq.Format) def test_copy_out_read(conn, format): if format == pq.Format.TEXT: @@ -51,6 +52,7 @@ def test_copy_out_read(conn, format): @pytest.mark.opengauss_skip("read row not supported in binary copy") +@pytest.mark.gaussdb_skip("read row not supported in binary copy") @pytest.mark.parametrize("format", pq.Format) @pytest.mark.parametrize("row_factory", ["tuple_row", "dict_row", "namedtuple_row"]) def test_copy_out_iter(conn, format, row_factory): @@ -91,6 +93,7 @@ def test_copy_out_param(conn, ph, params): @pytest.mark.opengauss_skip("read row not supported in binary copy") +@pytest.mark.gaussdb_skip("read row not supported in binary copy") @pytest.mark.parametrize("format", pq.Format) @pytest.mark.parametrize("typetype", ["names", "oids"]) def test_read_rows(conn, format, typetype): @@ -110,10 +113,14 @@ def test_read_rows(conn, format, typetype): @pytest.mark.opengauss_skip("read row not supported in binary copy") +@pytest.mark.gaussdb_skip("read row not supported in binary copy") @pytest.mark.parametrize("format", pq.Format) def test_rows(conn, format): cur = conn.cursor() with cur.copy(f"copy ({sample_values}) to stdout (format {format.name})") as copy: + print(f"copy ({sample_values}) to stdout (format {format.name})") + aa = conn.info.transaction_status == pq.TransactionStatus.ACTIVE + print(f"pq.TransactionStatus:{aa}") copy.set_types(["int4", "int4", "text"]) rows = list(copy.rows()) @@ -139,6 +146,7 @@ def test_set_custom_type(conn, hstore): @pytest.mark.opengauss_skip("read row not supported in binary copy") +@pytest.mark.gaussdb_skip("read row not supported in binary copy") @pytest.mark.parametrize("format", pq.Format) def test_copy_out_allchars(conn, format): cur = conn.cursor() @@ -161,6 +169,7 @@ def test_copy_out_allchars(conn, format): @pytest.mark.opengauss_skip("read row not supported in binary copy") +@pytest.mark.gaussdb_skip("read row not supported in binary copy") @pytest.mark.parametrize("format", pq.Format) def test_read_row_notypes(conn, format): cur = conn.cursor() @@ -177,6 +186,7 @@ def test_read_row_notypes(conn, format): @pytest.mark.opengauss_skip("read row not supported in binary copy") +@pytest.mark.gaussdb_skip("read row not supported in binary copy") @pytest.mark.parametrize("format", pq.Format) def test_rows_notypes(conn, format): cur = conn.cursor() @@ -187,6 +197,7 @@ def test_rows_notypes(conn, format): @pytest.mark.opengauss_skip("read row not supported in binary copy") +@pytest.mark.gaussdb_skip("read row not supported in binary copy") @pytest.mark.parametrize("err", [-1, 1]) @pytest.mark.parametrize("format", pq.Format) def test_copy_out_badntypes(conn, format, err): @@ -796,11 +807,10 @@ def test_copy_from_leaks(conn_cls, dsn, faker, fmt, set_types, gc): def work(): with conn_cls.connect(dsn) as conn: - with conn.cursor(binary=fmt) as cur: + with conn.cursor(binary=fmt == pq.Format.BINARY) as cur: cur.execute(faker.drop_stmt) cur.execute(faker.create_stmt) conn.commit() - stmt = sql.SQL("copy {} ({}) from stdin (format {})").format( faker.table_name, sql.SQL(", ").join(faker.fields_names), diff --git a/tests/test_copy_async.py b/tests/test_copy_async.py index 7d33ee578..a02214d3c 100644 --- a/tests/test_copy_async.py +++ b/tests/test_copy_async.py @@ -27,6 +27,7 @@ @pytest.mark.opengauss_skip("read row not supported in binary copy") +@pytest.mark.gaussdb_skip("read row not supported in binary copy") @pytest.mark.parametrize("format", pq.Format) async def test_copy_out_read(aconn, format): if format == pq.Format.TEXT: @@ -51,6 +52,7 @@ async def test_copy_out_read(aconn, format): @pytest.mark.opengauss_skip("read row not supported in binary copy") +@pytest.mark.gaussdb_skip("read row not supported in binary copy") @pytest.mark.parametrize("format", pq.Format) @pytest.mark.parametrize("row_factory", ["tuple_row", "dict_row", "namedtuple_row"]) async def test_copy_out_iter(aconn, format, row_factory): @@ -65,7 +67,6 @@ async def test_copy_out_iter(aconn, format, row_factory): f"copy ({sample_values}) to stdout (format {format.name})" ) as copy: result = [bytes(item) async for item in copy] - print(f"result: {result},want: {want}") assert result == want assert aconn.info.transaction_status == pq.TransactionStatus.INTRANS @@ -94,6 +95,7 @@ async def test_copy_out_param(aconn, ph, params): @pytest.mark.opengauss_skip("read row not supported in binary copy") +@pytest.mark.gaussdb_skip("read row not supported in binary copy") @pytest.mark.parametrize("format", pq.Format) @pytest.mark.parametrize("typetype", ["names", "oids"]) async def test_read_rows(aconn, format, typetype): @@ -113,6 +115,7 @@ async def test_read_rows(aconn, format, typetype): @pytest.mark.opengauss_skip("read row not supported in binary copy") +@pytest.mark.gaussdb_skip("read row not supported in binary copy") @pytest.mark.parametrize("format", pq.Format) async def test_rows(aconn, format): cur = aconn.cursor() @@ -144,6 +147,7 @@ async def test_set_custom_type(aconn, hstore): @pytest.mark.opengauss_skip("read row not supported in binary copy") +@pytest.mark.gaussdb_skip("read row not supported in binary copy") @pytest.mark.parametrize("format", pq.Format) async def test_copy_out_allchars(aconn, format): cur = aconn.cursor() @@ -166,6 +170,7 @@ async def test_copy_out_allchars(aconn, format): @pytest.mark.opengauss_skip("read row not supported in binary copy") +@pytest.mark.gaussdb_skip("read row not supported in binary copy") @pytest.mark.parametrize("format", pq.Format) async def test_read_row_notypes(aconn, format): cur = aconn.cursor() @@ -184,6 +189,7 @@ async def test_read_row_notypes(aconn, format): @pytest.mark.opengauss_skip("read row not supported in binary copy") +@pytest.mark.gaussdb_skip("read row not supported in binary copy") @pytest.mark.parametrize("format", pq.Format) async def test_rows_notypes(aconn, format): cur = aconn.cursor() @@ -196,6 +202,7 @@ async def test_rows_notypes(aconn, format): @pytest.mark.opengauss_skip("read row not supported in binary copy") +@pytest.mark.gaussdb_skip("read row not supported in binary copy") @pytest.mark.parametrize("err", [-1, 1]) @pytest.mark.parametrize("format", pq.Format) async def test_copy_out_badntypes(aconn, format, err): diff --git a/tests/test_cursor.py b/tests/test_cursor.py index b7b6531ce..458b29701 100644 --- a/tests/test_cursor.py +++ b/tests/test_cursor.py @@ -31,7 +31,7 @@ def test_str(conn): def test_execute_many_results_param(conn): cur = conn.cursor() - # Postgres raises SyntaxError, CRDB raises InvalidPreparedStatementDefinition + # GaussDB raises SyntaxError, CRDB raises InvalidPreparedStatementDefinition with pytest.raises((e.SyntaxError, e.InvalidPreparedStatementDefinition)): cur.execute("select %s; select generate_series(1, %s)", ("foo", 3)) diff --git a/tests/test_cursor_async.py b/tests/test_cursor_async.py index 7ec5a0ba1..1414c04bf 100644 --- a/tests/test_cursor_async.py +++ b/tests/test_cursor_async.py @@ -30,7 +30,7 @@ async def test_str(aconn): async def test_execute_many_results_param(aconn): cur = aconn.cursor() - # Postgres raises SyntaxError, CRDB raises InvalidPreparedStatementDefinition + # GaussDB raises SyntaxError, CRDB raises InvalidPreparedStatementDefinition with pytest.raises((e.SyntaxError, e.InvalidPreparedStatementDefinition)): await cur.execute("select %s; select generate_series(1, %s)", ("foo", 3)) diff --git a/tests/test_cursor_raw.py b/tests/test_cursor_raw.py index 015b62892..bf6a07851 100644 --- a/tests/test_cursor_raw.py +++ b/tests/test_cursor_raw.py @@ -38,7 +38,7 @@ def test_sequence_only(conn): def test_execute_many_results_param(conn): cur = conn.cursor() - # Postgres raises SyntaxError, CRDB raises InvalidPreparedStatementDefinition + # GaussDB raises SyntaxError, CRDB raises InvalidPreparedStatementDefinition with pytest.raises((e.SyntaxError, e.InvalidPreparedStatementDefinition)): cur.execute("select $1; select generate_series(1, $2)", ("foo", 3)) diff --git a/tests/test_cursor_raw_async.py b/tests/test_cursor_raw_async.py index a562d4cc2..aecd880c0 100644 --- a/tests/test_cursor_raw_async.py +++ b/tests/test_cursor_raw_async.py @@ -35,7 +35,7 @@ async def test_sequence_only(aconn): async def test_execute_many_results_param(aconn): cur = aconn.cursor() - # Postgres raises SyntaxError, CRDB raises InvalidPreparedStatementDefinition + # GaussDB raises SyntaxError, CRDB raises InvalidPreparedStatementDefinition with pytest.raises((e.SyntaxError, e.InvalidPreparedStatementDefinition)): await cur.execute("select $1; select generate_series(1, $2)", ("foo", 3)) diff --git a/tests/test_query.py b/tests/test_query.py index fa17924ea..b3f486e9b 100644 --- a/tests/test_query.py +++ b/tests/test_query.py @@ -3,7 +3,7 @@ import gaussdb from gaussdb import pq from gaussdb.adapt import PyFormat, Transformer -from gaussdb._queries import PostgresQuery, _split_query +from gaussdb._queries import GaussDBQuery, _split_query @pytest.mark.parametrize( @@ -89,7 +89,7 @@ def test_split_query_bad(input): ], ) def test_pg_query_seq(query, params, want, wformats, wparams): - pq = PostgresQuery(Transformer()) + pq = GaussDBQuery(Transformer()) pq.convert(query, params) assert pq.query == want assert pq.formats == wformats @@ -118,7 +118,7 @@ def test_pg_query_seq(query, params, want, wformats, wparams): ], ) def test_pg_query_map(query, params, want, wformats, wparams): - pq = PostgresQuery(Transformer()) + pq = GaussDBQuery(Transformer()) pq.convert(query, params) assert pq.query == want assert pq.formats == wformats @@ -137,7 +137,7 @@ def test_pg_query_map(query, params, want, wformats, wparams): ], ) def test_pq_query_badtype(query, params): - pq = PostgresQuery(Transformer()) + pq = GaussDBQuery(Transformer()) with pytest.raises(TypeError): pq.convert(query, params) @@ -157,6 +157,6 @@ def test_pq_query_badtype(query, params): ], ) def test_pq_query_badprog(query, params): - pq = PostgresQuery(Transformer()) + pq = GaussDBQuery(Transformer()) with pytest.raises(gaussdb.ProgrammingError): pq.convert(query, params) diff --git a/tests/test_sql.py b/tests/test_sql.py index 674bcc76e..288ec863c 100644 --- a/tests/test_sql.py +++ b/tests/test_sql.py @@ -1,6 +1,6 @@ # test_sql.py - tests for the _GaussDB.sql module -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team import re import datetime as dt diff --git a/tests/test_tpc.py b/tests/test_tpc.py index 8a07452ba..36f30d3e3 100644 --- a/tests/test_tpc.py +++ b/tests/test_tpc.py @@ -223,8 +223,6 @@ def test_xid_roundtrip(self, conn_cls, conn, dsn, tpc, fid, gtrid, bqual): assert xid.gtrid == gtrid assert xid.bqual == bqual - # 199 is PostgreSQL's limit in transaction id length - @pytest.mark.parametrize("tid", ["", "hello, world!", "x" * 199]) def test_unparsed_roundtrip(self, conn_cls, conn, dsn, tpc, tid): conn.tpc_begin(tid) diff --git a/tests/test_tpc_async.py b/tests/test_tpc_async.py index f03758ba4..63fed2c3c 100644 --- a/tests/test_tpc_async.py +++ b/tests/test_tpc_async.py @@ -226,7 +226,6 @@ async def test_xid_roundtrip(self, aconn_cls, aconn, dsn, tpc, fid, gtrid, bqual assert xid.gtrid == gtrid assert xid.bqual == bqual - # 199 is PostgreSQL's limit in transaction id length @pytest.mark.parametrize("tid", ["", "hello, world!", "x" * 199]) async def test_unparsed_roundtrip(self, aconn_cls, aconn, dsn, tpc, tid): await aconn.tpc_begin(tid) diff --git a/tests/test_typeinfo.py b/tests/test_typeinfo.py index 5bfc8b8d3..ba6ebea83 100644 --- a/tests/test_typeinfo.py +++ b/tests/test_typeinfo.py @@ -190,16 +190,18 @@ def test_registry_invalid_oid(oid, aoid): def test_registry_copy(): - r = gaussdb.types.TypesRegistry(gaussdb.postgres.types) + r = gaussdb.types.TypesRegistry(gaussdb.gaussdb_.types) assert r.get("text") is r["text"] is r[25] assert r["text"].oid == 25 def test_registry_isolated(): - orig = gaussdb.postgres.types + orig = gaussdb.gaussdb_.types + print(f"orig._registry={orig._registry}") tinfo = orig["text"] r = gaussdb.types.TypesRegistry(orig) tdummy = gaussdb.types.TypeInfo("dummy", tinfo.oid, tinfo.array_oid) r.add(tdummy) + print(f"orig={orig},tinfo={tinfo},r={r},tdummy={tdummy}") assert r[25] is r["dummy"] is tdummy assert orig[25] is r["text"] is tinfo diff --git a/tests/types/test_array.py b/tests/types/test_array.py index 45ff6ddcf..7f8b6ba0c 100644 --- a/tests/types/test_array.py +++ b/tests/types/test_array.py @@ -12,7 +12,7 @@ from gaussdb import pq, sql from gaussdb.adapt import Dumper, PyFormat, Transformer from gaussdb.types import TypeInfo -from gaussdb.postgres import types as builtins +from gaussdb.gaussdb_ import types as builtins from gaussdb.types.array import register_array from ..test_adapt import StrNoneBinaryDumper, StrNoneDumper @@ -130,6 +130,7 @@ def test_bad_binary_array(input): @pytest.mark.crdb_skip("nested array") @pytest.mark.opengauss_skip("nested array") +@pytest.mark.gaussdb_skip("cannot unpack non-iterable NoneType object") @pytest.mark.parametrize("fmt_out", pq.Format) @pytest.mark.parametrize("want, obj", tests_int) def test_load_list_int(conn, obj, want, fmt_out): @@ -280,7 +281,7 @@ def __init__(self, x1, y1, x2, y2): class BoxDumper(Dumper): format = pq.Format.TEXT - oid = gaussdb.postgres.types["box"].oid + oid = gaussdb.gaussdb_.types["box"].oid def dump(self, box): return ("(%s,%s),(%s,%s)" % box.coords).encode() diff --git a/tests/types/test_bool.py b/tests/types/test_bool.py index f71924ad6..c975008e8 100644 --- a/tests/types/test_bool.py +++ b/tests/types/test_bool.py @@ -2,7 +2,7 @@ from gaussdb import pq, sql from gaussdb.adapt import PyFormat, Transformer -from gaussdb.postgres import types as builtins +from gaussdb.gaussdb_ import types as builtins @pytest.mark.parametrize("fmt_in", PyFormat) diff --git a/tests/types/test_composite.py b/tests/types/test_composite.py index b3c55b5dc..1c7d609d0 100644 --- a/tests/types/test_composite.py +++ b/tests/types/test_composite.py @@ -1,8 +1,8 @@ import pytest -from gaussdb import postgres, pq, sql +from gaussdb import gaussdb_, pq, sql from gaussdb.adapt import PyFormat -from gaussdb.postgres import types as builtins +from gaussdb.gaussdb_ import types as builtins from gaussdb.types.range import Range from gaussdb.types.composite import CompositeInfo, TupleBinaryDumper, TupleDumper from gaussdb.types.composite import register_composite @@ -15,7 +15,7 @@ tests_str = [ ("", ()), - # Funnily enough there's no way to represent (None,) in Postgres + # Funnily enough there's no way to represent (None,) in GaussDB ("null", ()), ("null,null", (None, None)), ("null, ''", (None, "")), @@ -351,23 +351,23 @@ def test_register_scope(conn, testcomp): register_composite(info) for fmt in pq.Format: for oid in (info.oid, info.array_oid): - assert postgres.adapters._loaders[fmt].pop(oid) + assert gaussdb_.adapters._loaders[fmt].pop(oid) for f in PyFormat: - assert postgres.adapters._dumpers[f].pop(info.python_type) + assert gaussdb_.adapters._dumpers[f].pop(info.python_type) cur = conn.cursor() register_composite(info, cur) for fmt in pq.Format: for oid in (info.oid, info.array_oid): - assert oid not in postgres.adapters._loaders[fmt] + assert oid not in gaussdb_.adapters._loaders[fmt] assert oid not in conn.adapters._loaders[fmt] assert oid in cur.adapters._loaders[fmt] register_composite(info, conn) for fmt in pq.Format: for oid in (info.oid, info.array_oid): - assert oid not in postgres.adapters._loaders[fmt] + assert oid not in gaussdb_.adapters._loaders[fmt] assert oid in conn.adapters._loaders[fmt] diff --git a/tests/types/test_enum.py b/tests/types/test_enum.py index f678f87e5..79d0c239f 100644 --- a/tests/types/test_enum.py +++ b/tests/types/test_enum.py @@ -335,7 +335,7 @@ def test_remap_more_python(conn): assert cur.fetchone()[0] is enum[member] -def test_remap_more_postgres(conn): +def test_remap_more_gaussdb(conn): SmallerEnum = Enum("SmallerEnum", "FOO") enum = SmallerEnum info = EnumInfo.fetch(conn, "puretestenum") diff --git a/tests/types/test_json.py b/tests/types/test_json.py index 0f6c5fe34..932c4368f 100644 --- a/tests/types/test_json.py +++ b/tests/types/test_json.py @@ -111,6 +111,7 @@ def test_load_array(conn, val, jtype, fmt_out): @pytest.mark.crdb_skip("copy") @pytest.mark.opengauss_skip("binary copy signature mismatch") +@pytest.mark.gaussdb_skip("cannot unpack non-iterable NoneType object") @pytest.mark.parametrize("val", samples) @pytest.mark.parametrize("jtype", ["json", "jsonb"]) @pytest.mark.parametrize("fmt_out", pq.Format) diff --git a/tests/types/test_net.py b/tests/types/test_net.py index 1ccfe2070..73227bfdd 100644 --- a/tests/types/test_net.py +++ b/tests/types/test_net.py @@ -70,6 +70,7 @@ def test_network_mixed_size_array(conn, fmt_in): @pytest.mark.crdb_skip("copy") @pytest.mark.opengauss_skip("binary copy signature mismatch") +@pytest.mark.gaussdb_skip("cannot unpack non-iterable NoneType object") @pytest.mark.parametrize("fmt_out", pq.Format) @pytest.mark.parametrize("val", ["127.0.0.1/32", "::ffff:102:300/128"]) def test_inet_load_address(conn, fmt_out, val): @@ -94,6 +95,7 @@ def test_inet_load_address(conn, fmt_out, val): @pytest.mark.crdb_skip("copy") @pytest.mark.opengauss_skip("binary copy signature mismatch") +@pytest.mark.gaussdb_skip("cannot unpack non-iterable NoneType object") @pytest.mark.parametrize("fmt_out", pq.Format) @pytest.mark.parametrize("val", ["127.0.0.1/24", "::ffff:102:300/127"]) def test_inet_load_network(conn, fmt_out, val): @@ -118,6 +120,7 @@ def test_inet_load_network(conn, fmt_out, val): @crdb_skip_cidr @pytest.mark.opengauss_skip("binary copy signature mismatch") +@pytest.mark.gaussdb_skip("cannot unpack non-iterable NoneType object") @pytest.mark.parametrize("fmt_out", pq.Format) @pytest.mark.parametrize("val", ["127.0.0.0/24", "::ffff:102:300/128"]) def test_cidr_load(conn, fmt_out, val): diff --git a/tests/types/test_numeric.py b/tests/types/test_numeric.py index ba29ae7c7..148df564f 100644 --- a/tests/types/test_numeric.py +++ b/tests/types/test_numeric.py @@ -602,7 +602,7 @@ def test_repr_wrapper(conn, wrapper, fmt_in): wrapper = getattr(gaussdb.types.numeric, wrapper) cur = conn.execute(f"select pg_typeof(%{fmt_in.value})::oid", [wrapper(0)]) oid = cur.fetchone()[0] - assert oid == gaussdb.postgres.types[wrapper.__name__.lower()].oid + assert oid == gaussdb.gaussdb_.types[wrapper.__name__.lower()].oid @pytest.mark.parametrize("fmt_out", pq.Format) diff --git a/tests/types/test_range.py b/tests/types/test_range.py index 9dd4ddb19..40705a382 100644 --- a/tests/types/test_range.py +++ b/tests/types/test_range.py @@ -544,7 +544,7 @@ def assert_not_equal(r1, r2): def test_eq_wrong_type(self): assert Range(10, 20) != () - # as the postgres docs describe for the server-side stuff, + # as the gaussdb docs describe for the server-side stuff, # ordering is rather arbitrary, but will remain stable # and consistent. diff --git a/tests/types/test_string.py b/tests/types/test_string.py index ccbf0ba3a..c5ecc68e6 100644 --- a/tests/types/test_string.py +++ b/tests/types/test_string.py @@ -160,6 +160,7 @@ def test_dump_text_oid(conn, fmt_in): @pytest.mark.crdb_skip("copy") @pytest.mark.opengauss_skip("binary copy signature mismatch") +@pytest.mark.gaussdb_skip("cannot unpack non-iterable NoneType object") @pytest.mark.parametrize("fmt_out", pq.Format) @pytest.mark.parametrize("encoding", ["utf8", crdb_encoding("latin9")]) @pytest.mark.parametrize("typename", ["text", "varchar", "name", "bpchar"]) @@ -202,6 +203,7 @@ def test_load_badenc(conn, typename, fmt_out): @pytest.mark.crdb_skip("encoding") @pytest.mark.opengauss_skip("binary copy signature mismatch") +@pytest.mark.gaussdb_skip("cannot unpack non-iterable NoneType object") @pytest.mark.parametrize("fmt_out", pq.Format) @pytest.mark.parametrize("typename", ["text", "varchar", "name", "bpchar"]) def test_load_ascii(conn, typename, fmt_out): diff --git a/tests/types/test_uuid.py b/tests/types/test_uuid.py index 5b96695e4..c04b88df6 100644 --- a/tests/types/test_uuid.py +++ b/tests/types/test_uuid.py @@ -27,6 +27,7 @@ def test_uuid_dump(conn, fmt_in, val): @pytest.mark.crdb_skip("copy") @pytest.mark.opengauss_skip("copy") +@pytest.mark.gaussdb_skip("copy") @pytest.mark.parametrize("fmt_out", pq.Format) @pytest.mark.parametrize( "val", diff --git a/tests/utils.py b/tests/utils.py index 2c3da8f71..63c309683 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -30,10 +30,10 @@ def check_libpq_version(got, want): and skips the test if the requested version doesn't match what's loaded. """ - return check_version(got, want, "libpq", postgres_rule=True) + return check_version(got, want, "libpq", gaussdb_rule=True) -def check_postgres_version(got, want): +def check_gaussdb_version(got, want): """ Verify if the server version is a version accepted. @@ -43,11 +43,11 @@ def check_postgres_version(got, want): and skips the test if the server version doesn't match what expected. """ - return check_version(got, want, "PostgreSQL", postgres_rule=True) + return check_version(got, want, "PostgreSQL", gaussdb_rule=True) -def check_version(got, want, whose_version, postgres_rule=True): - pred = VersionCheck.parse(want, postgres_rule=postgres_rule) +def check_version(got, want, whose_version, gaussdb_rule=True): + pred = VersionCheck.parse(want, gaussdb_rule=gaussdb_rule) pred.whose = whose_version return pred.get_skip_message(got) @@ -68,17 +68,17 @@ def __init__( op: str | None = None, version_tuple: tuple[Union[int, str], ...] = (), whose: str = "(wanted)", - postgres_rule: bool = False, + gaussdb_rule: bool = False, ): self.skip = skip self.op = op or "==" self.version_tuple = version_tuple self.whose = whose # Treat 10.1 as 10.0.1 - self.postgres_rule = postgres_rule + self.gaussdb_rule = gaussdb_rule @classmethod - def parse(cls, spec: str, *, postgres_rule: bool = False) -> VersionCheck: + def parse(cls, spec: str, *, gaussdb_rule: bool = False) -> VersionCheck: # Parse a spec like "> 9.6", "skip < 21.2.0" m = re.match( r"""(?ix) @@ -97,7 +97,7 @@ def parse(cls, spec: str, *, postgres_rule: bool = False) -> VersionCheck: version_tuple = tuple(int(n) if n.isdigit() else n for n in m.groups()[2:] if n) return cls( - skip=skip, op=op, version_tuple=version_tuple, postgres_rule=postgres_rule + skip=skip, op=op, version_tuple=version_tuple, gaussdb_rule=gaussdb_rule ) def get_skip_message(self, version: int | str | None) -> str | None: diff --git a/tools/ci/build_libpq.sh b/tools/ci/build_libpq.sh deleted file mode 100755 index 7aeabe15c..000000000 --- a/tools/ci/build_libpq.sh +++ /dev/null @@ -1,253 +0,0 @@ -#!/bin/bash - -# Build a modern version of libpq and depending libs from source on Centos 5, Alpine or macOS - -set -euo pipefail - -postgres_version="${LIBPQ_VERSION}" -openssl_version="${OPENSSL_VERSION}" - -# Latest release: https://kerberos.org/dist/ -krb5_version="1.21.3" - -# Latest release: https://openldap.org/software/download/ -ldap_version="2.6.9" - -# Latest release: https://github.com/cyrusimap/cyrus-sasl/releases -sasl_version="2.1.28" - -export LIBPQ_BUILD_PREFIX=${LIBPQ_BUILD_PREFIX:-/tmp/libpq.build} - -case "$(uname)" in - Darwin) - ID=macos - library_suffix=dylib - ;; - - Linux) - source /etc/os-release - library_suffix=so - ;; - - *) - echo "$0: unexpected Operating system: '$(uname)'" >&2 - exit 1 - ;; -esac - -if [[ -f "${LIBPQ_BUILD_PREFIX}/lib/libpq.${library_suffix}" ]]; then - echo "libpq already available: build skipped" >&2 - exit 0 -fi - -case "$ID" in - centos) - yum update -y - yum install -y flex krb5-devel pam-devel perl-IPC-Cmd zlib-devel - ;; - - alpine) - apk upgrade - apk add --no-cache flex krb5-dev linux-pam-dev openldap-dev \ - openssl-dev tzdata zlib-dev - ;; - - macos) - brew install automake m4 libtool - # If available, libpq seemingly insists on linking against homebrew's - # openssl no matter what so remove it. Since homebrew's curl depends on - # it, force use of system curl. - brew uninstall --force --ignore-dependencies openssl gettext curl - if [ -z "${MACOSX_ARCHITECTURE:-}" ]; then - MACOSX_ARCHITECTURE="$(uname -m)" - fi - # Set the deployment target to be <= to that of the oldest supported Python version. - # e.g. https://www.python.org/downloads/release/python-380/ - if [ "$MACOSX_ARCHITECTURE" == "x86_64" ]; then - export MACOSX_DEPLOYMENT_TARGET=10.9 - else - export MACOSX_DEPLOYMENT_TARGET=11.0 - fi - ;; - - *) - echo "$0: unexpected Linux distribution: '$ID'" >&2 - exit 1 - ;; -esac - - -if [ "$ID" == "macos" ]; then - make_configure_standard_flags=( \ - --prefix=${LIBPQ_BUILD_PREFIX} \ - "CPPFLAGS=-I${LIBPQ_BUILD_PREFIX}/include/ -arch $MACOSX_ARCHITECTURE" \ - "LDFLAGS=-L${LIBPQ_BUILD_PREFIX}/lib -arch $MACOSX_ARCHITECTURE" \ - ) -else - make_configure_standard_flags=( \ - --prefix=${LIBPQ_BUILD_PREFIX} \ - CPPFLAGS=-I${LIBPQ_BUILD_PREFIX}/include/ \ - "LDFLAGS=-L${LIBPQ_BUILD_PREFIX}/lib -L${LIBPQ_BUILD_PREFIX}/lib64" \ - ) -fi - -if [ "$ID" == "centos" ] || [ "$ID" == "macos" ]; then - if [[ ! -f "${LIBPQ_BUILD_PREFIX}/openssl.cnf" ]]; then - - # Build openssl if needed - openssl_tag="openssl-${openssl_version}" - openssl_dir="openssl-${openssl_tag}" - if [ ! -d "${openssl_dir}" ]; then - curl -fsSL \ - https://github.com/openssl/openssl/archive/${openssl_tag}.tar.gz \ - | tar xzf - - - pushd "${openssl_dir}" - - options=(--prefix=${LIBPQ_BUILD_PREFIX} --openssldir=${LIBPQ_BUILD_PREFIX} \ - zlib -fPIC shared) - if [ -z "${MACOSX_ARCHITECTURE:-}" ]; then - ./config $options - else - ./configure "darwin64-$MACOSX_ARCHITECTURE-cc" $options - fi - - make -s depend - make -s - else - pushd "${openssl_dir}" - fi - - # Install openssl - make install_sw - popd - - fi -fi - - -if [ "$ID" == "macos" ]; then - - # Build kerberos if needed - krb5_dir="krb5-${krb5_version}/src" - if [ ! -d "${krb5_dir}" ]; then - curl -fsSL "https://kerberos.org/dist/krb5/${krb5_version%.*}/krb5-${krb5_version}.tar.gz" \ - | tar xzf - - - pushd "${krb5_dir}" - ./configure "${make_configure_standard_flags[@]}" - make -s - else - pushd "${krb5_dir}" - fi - - make install - popd - -fi - - -if [ "$ID" == "centos" ] || [ "$ID" == "macos" ]; then - if [[ ! -f "${LIBPQ_BUILD_PREFIX}/lib/libsasl2.${library_suffix}" ]]; then - - # Build libsasl2 if needed - # The system package (cyrus-sasl-devel) causes an amazing error on i686: - # "unsupported version 0 of Verneed record" - # https://github.com/pypa/manylinux/issues/376 - sasl_tag="cyrus-sasl-${sasl_version}" - sasl_dir="cyrus-sasl-${sasl_tag}" - if [ ! -d "${sasl_dir}" ]; then - curl -fsSL \ - https://github.com/cyrusimap/cyrus-sasl/archive/${sasl_tag}.tar.gz \ - | tar xzf - - - pushd "${sasl_dir}" - - autoreconf -i - ./configure "${make_configure_standard_flags[@]}" --disable-macos-framework - make -s - else - pushd "${sasl_dir}" - fi - - # Install libsasl2 - # requires missing nroff to build - touch saslauthd/saslauthd.8 - make install - popd - - fi -fi - - -if [ "$ID" == "centos" ] || [ "$ID" == "macos" ]; then - if [[ ! -f "${LIBPQ_BUILD_PREFIX}/lib/libldap.${library_suffix}" ]]; then - - # Build openldap if needed - ldap_tag="${ldap_version}" - ldap_dir="openldap-${ldap_tag}" - if [ ! -d "${ldap_dir}" ]; then - curl -fsSL \ - https://www.openldap.org/software/download/OpenLDAP/openldap-release/openldap-${ldap_tag}.tgz \ - | tar xzf - - - pushd "${ldap_dir}" - - ./configure "${make_configure_standard_flags[@]}" --enable-backends=no --enable-null - - make -s depend - make -s -C libraries/liblutil/ - make -s -C libraries/liblber/ - make -s -C libraries/libldap/ - else - pushd "${ldap_dir}" - fi - - # Install openldap - make -C libraries/liblber/ install - make -C libraries/libldap/ install - make -C include/ install - chmod +x ${LIBPQ_BUILD_PREFIX}/lib/{libldap,liblber}*.${library_suffix}* - popd - - fi -fi - - -# Build libpq if needed -postgres_tag="REL_${postgres_version//./_}" -postgres_dir="postgres-${postgres_tag}" -if [ ! -d "${postgres_dir}" ]; then - curl -fsSL \ - https://github.com/postgres/postgres/archive/${postgres_tag}.tar.gz \ - | tar xzf - - - pushd "${postgres_dir}" - - if [ "$ID" != "macos" ]; then - # Match the default unix socket dir default with what defined on Ubuntu and - # Red Hat, which seems the most common location - sed -i 's|#define DEFAULT_PGSOCKET_DIR .*'\ -'|#define DEFAULT_PGSOCKET_DIR "/var/run/postgresql"|' \ - src/include/pg_config_manual.h - fi - - export LD_LIBRARY_PATH="${LIBPQ_BUILD_PREFIX}/lib:${LIBPQ_BUILD_PREFIX}/lib64" - - ./configure "${make_configure_standard_flags[@]}" --sysconfdir=/etc/postgresql-common \ - --with-gssapi --with-openssl --with-pam --with-ldap \ - --without-readline --without-icu - make -s -C src/interfaces/libpq - make -s -C src/bin/pg_config - make -s -C src/include -else - pushd "${postgres_dir}" -fi - -# Install libpq -make -C src/interfaces/libpq install -make -C src/bin/pg_config install -make -C src/include install -popd - -find ${LIBPQ_BUILD_PREFIX} -name \*.${library_suffix}.\* -type f -exec strip --strip-unneeded {} \; diff --git a/tools/ci/build_macos_arm64.sh b/tools/ci/build_macos_arm64.sh deleted file mode 100755 index f9313afc2..000000000 --- a/tools/ci/build_macos_arm64.sh +++ /dev/null @@ -1,109 +0,0 @@ -#!/bin/bash - -# Build psycopg-binary wheel packages for Apple M1 (cpNNN-macosx_arm64) -# -# This script is designed to run on Scaleway Apple Silicon machines. -# -# The script cannot be run as sudo (installing brew fails), but requires sudo, -# so it can pretty much only be executed by a sudo user as it is. - -set -euo pipefail - -python_versions="3.9.19 3.10.14 3.11.9 3.12.5 3.13.0" -pg_version=17 - -function log { - echo "$@" >&2 -} - -# Move to the root of the project -dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -cd "${dir}/../../" - -# Add /usr/local/bin to the path. It seems it's not, in non-interactive sessions -if ! (echo $PATH | grep -q '/usr/local/bin'); then - export PATH=/usr/local/bin:$PATH -fi - -# Install brew, if necessary. Otherwise just make sure it's in the path -if [[ -x /opt/homebrew/bin/brew ]]; then - eval "$(/opt/homebrew/bin/brew shellenv)" -else - log "installing brew" - command -v brew > /dev/null || ( - # Not necessary: already installed - # xcode-select --install - NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL \ - https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" - ) - eval "$(/opt/homebrew/bin/brew shellenv)" -fi - -export PGDATA=/opt/homebrew/var/postgresql@${pg_version} - -# Install PostgreSQL, if necessary -command -v pg_config > /dev/null || ( - log "installing postgres" - brew install postgresql@${pg_version} -) - -# Starting from PostgreSQL 15, the bin path is not in the path. -export PATH="$(ls -d1 /opt/homebrew/Cellar/postgresql@${pg_version}/*/bin):$PATH" - -# Make sure the server is running - -# Currently not working -# brew services start postgresql@${pg_version} - -if ! pg_ctl status; then - log "starting the server" - pg_ctl -l "/opt/homebrew/var/log/postgresql@${pg_version}.log" start -fi - - -# Install the Python versions we want to build -for ver_full in $python_versions; do - # Get the major.minor.patch version, without pre-release markers - ver3=$(echo $ver_full | sed 's/\([0-9]*\.[0-9]*\.[0-9]*\).*/\1/') - - # Get the major.minor version - ver2=$(echo $ver3 | sed 's/\([^\.]*\)\(\.[^\.]*\)\(.*\)/\1\2/') - - command -v python${ver2} > /dev/null || ( - log "installing Python $ver_full" - (cd /tmp && - curl -fsSl -O \ - https://www.python.org/ftp/python/${ver3}/python-${ver_full}-macos11.pkg) - sudo installer -pkg /tmp/python-${ver_full}-macos11.pkg -target / - ) -done - -# Create a virtualenv where to work -if [[ ! -x .venv/bin/python ]]; then - log "creating a virtualenv" - python3 -m venv .venv -fi - -log "installing cibuildwheel" -source .venv/bin/activate -pip install cibuildwheel - -log "building wheels" - -# Create the psycopg_binary source package -rm -rf psycopg_binary -python tools/ci/copy_to_binary.py - -# Build the binary packages -export CIBW_PLATFORM=macos -export CIBW_ARCHS=arm64 -export CIBW_BUILD='cp{38,39,310,311,312,313}-*' -export CIBW_TEST_REQUIRES="./psycopg[test] ./psycopg_pool" -export CIBW_TEST_COMMAND="pytest {project}/tests -m 'not slow and not flakey' --color yes" - -export GAUSSDB_IMPL=binary -export GAUSSDB_TEST_DSN="dbname=postgres" -export GAUSSDB_TEST_WANT_LIBPQ_BUILD=">= ${pg_version}" -export GAUSSDB_TEST_WANT_LIBPQ_IMPORT=">= ${pg_version}" - -cibuildwheel psycopg_binary diff --git a/tools/ci/ci_install_libpq.sh b/tools/ci/ci_install_libpq.sh deleted file mode 100755 index 4434c4085..000000000 --- a/tools/ci/ci_install_libpq.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/bash - -# Install the desired libpq in github action (Linux runner) -# -# Specify `oldest` or `newest` as first argument in order to choose the oldest -# available to the debian distro or the newest available from the pgdg ppa. - -set -euo pipefail - -libpq=${1:-} -rel=$(lsb_release -c -s) - -setup_repo () { - version=${1:-} - repo_suffix=${2:-pgdg} - curl -sL -o /etc/apt/trusted.gpg.d/apt.postgresql.org.asc \ - https://www.postgresql.org/media/keys/ACCC4CF8.asc - echo "deb http://apt.postgresql.org/pub/repos/apt ${rel}-${repo_suffix} main ${version}" \ - >> /etc/apt/sources.list.d/pgdg.list - apt-get -qq update -} - -case "$libpq" in - "") - # Assume a libpq is already installed in the system. We don't care about - # the version. - exit 0 - ;; - - oldest) - setup_repo 10 - pqver=$(apt-cache show libpq5 | grep ^Version: | tail -1 | awk '{print $2}') - apt-get -qq -y --allow-downgrades install "libpq-dev=${pqver}" "libpq5=${pqver}" - ;; - - newest) - setup_repo - pqver=$(apt-cache show libpq5 | grep ^Version: | head -1 | awk '{print $2}') - apt-get -qq -y install "libpq-dev=${pqver}" "libpq5=${pqver}" - ;; - - master) - setup_repo 17 pgdg-snapshot - pqver=$(apt-cache show libpq5 | grep ^Version: | head -1 | awk '{print $2}') - apt-get -qq -y install "libpq-dev=${pqver}" "libpq5=${pqver}" - ;; - - *) - echo "Unexpected wanted libpq: '${libpq}'" >&2 - exit 1 - ;; - -esac diff --git a/tools/ci/wheel_linux_before_all.sh b/tools/ci/wheel_linux_before_all.sh index 6a6283add..3b3924c4d 100755 --- a/tools/ci/wheel_linux_before_all.sh +++ b/tools/ci/wheel_linux_before_all.sh @@ -9,7 +9,7 @@ dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" source /etc/os-release -# Install PostgreSQL development files. +# Install GaussDB development files. case "$ID" in alpine) # tzdata is required for datetime tests. diff --git a/tools/ci/wheel_macos_before_all.sh b/tools/ci/wheel_macos_before_all.sh deleted file mode 100755 index e21f945b8..000000000 --- a/tools/ci/wheel_macos_before_all.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash - -# Configure the environment needed to build wheel packages on Mac OS. -# This script is designed to be used by cibuildwheel as CIBW_BEFORE_ALL_MACOS -# -# The PG_VERSION env var must be set to a Postgres major version (e.g. 16). - -set -euo pipefail - -dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -prjdir="$( cd "${dir}/../.." && pwd )" - -# Build dependency libraries -"${prjdir}/tools/ci/build_libpq.sh" - -# Show dependency tree -otool -L /tmp/libpq.build/lib/*.dylib - -brew install gnu-sed postgresql@${PG_VERSION} -brew link --overwrite postgresql@${PG_VERSION} - -# Start the database for testing -brew services start postgresql@${PG_VERSION} - -# Wait for postgres to come up -for i in $(seq 10 -1 0); do - eval pg_isready && break - if [ $i == 0 ]; then - echo "PostgreSQL service not ready, giving up" - exit 1 - fi - echo "PostgreSQL service not ready, waiting a bit, attempts left: $i" - sleep 5 -done diff --git a/tools/ci/wheel_win32_before_build.bat b/tools/ci/wheel_win32_before_build.bat deleted file mode 100644 index 6a90ca277..000000000 --- a/tools/ci/wheel_win32_before_build.bat +++ /dev/null @@ -1,3 +0,0 @@ -@echo on - -pip install delvewheel wheel diff --git a/tools/update_error_prefixes.py b/tools/update_error_prefixes.py index de65883cf..5368af6d9 100755 --- a/tools/update_error_prefixes.py +++ b/tools/update_error_prefixes.py @@ -66,8 +66,8 @@ def update_file(fn: Path, content: str) -> None: def parse_cmdline() -> Namespace: for default_pgroot in ( - HERE / "../../fs/postgres", # it happens to be my laptop - HERE / "../../postgres", # the last entry is the default if none found + HERE / "../../fs/gaussdb", # it happens to be my laptop + HERE / "../../gaussdb", # the last entry is the default if none found ): if default_pgroot.exists(): break @@ -81,7 +81,7 @@ def parse_cmdline() -> Namespace: metavar="DIR", default=default_pgroot, type=Path, - help="root PostgreSQL source directory [default: %(default)s]", + help="root GaussDB source directory [default: %(default)s]", ) parser.add_argument( "--dest", diff --git a/tools/update_errors.py b/tools/update_errors.py index 37b2fa9b1..83110fb50 100755 --- a/tools/update_errors.py +++ b/tools/update_errors.py @@ -1,12 +1,12 @@ #!/usr/bin/env python # type: ignore """ -Generate per-sqlstate errors from PostgreSQL source code. +Generate per-sqlstate errors from GaussDB source code. -The script can be run at a new PostgreSQL release to refresh the module. +The script can be run at a new GaussDB release to refresh the module. """ -# Copyright (C) 2020 The GaussDB Team +# Copyright (C) 2020 The Psycopg Team import os import re diff --git a/tools/update_oids.py b/tools/update_oids.py index c6628686e..61f6bf381 100755 --- a/tools/update_oids.py +++ b/tools/update_oids.py @@ -7,11 +7,11 @@ Hint: use docker to upgrade types from a new version in isolation. Run: - docker run --rm -p 11111:5432 --name pg -e POSTGRES_PASSWORD=password postgres:TAG + docker run --rm -p 11111:5432 --name pg -e GAUSSDB_PASSWORD=password gaussdb:TAG with a specified version tag, and then query it using: - %(prog)s "host=localhost port=11111 user=postgres password=password" + %(prog)s "host=localhost port=11111 user=root password=password" """ from __future__ import annotations @@ -42,17 +42,15 @@ def main() -> None: else: update_python_oids(conn) update_python_types(conn) - update_cython_oids(conn) def update_python_types(conn: Connection) -> None: - fn = ROOT / "gaussdb/gaussdb/postgres.py" + fn = ROOT / "gaussdb/gaussdb/gaussdb.py" lines = [] lines.extend(get_version_comment(conn)) lines.extend(get_py_types(conn)) lines.extend(get_py_ranges(conn)) - lines.extend(get_py_multiranges(conn)) update_file(fn, lines) sp.check_call(["black", "-q", fn]) @@ -69,16 +67,6 @@ def update_python_oids(conn: Connection) -> None: sp.check_call(["black", "-q", fn]) -def update_cython_oids(conn: Connection) -> None: - fn = ROOT / "gaussdb_c/gaussdb_c/_gaussdb/oids.pxd" - - lines = [] - lines.extend(get_version_comment(conn)) - lines.extend(get_cython_oids(conn)) - - update_file(fn, lines) - - def update_crdb_python_oids(conn: Connection) -> None: fn = ROOT / "gaussdb/gaussdb/crdb/_types.py" @@ -92,7 +80,22 @@ def update_crdb_python_oids(conn: Connection) -> None: def get_version_comment(conn: Connection) -> list[str]: if conn.info.vendor == "PostgreSQL": - version = version_pretty(conn.info.server_version) + # version = version_pretty(conn.info.server_version) + raw_version = conn.info.server_version + + if isinstance(raw_version, str): + # such as '505.2.0' → [505, 2, 0] + parts = [int(x) for x in re.findall(r"\d+", raw_version)] + if len(parts) >= 2: + major, minor = parts[0], parts[1] + patch = parts[2] if len(parts) >= 3 else 0 + version_int = major * 10000 + minor * 100 + patch + else: + version_int = 0 # fallback + else: + version_int = raw_version + + version = version_pretty(version_int) elif conn.info.vendor == "CockroachDB": assert isinstance(conn, CrdbConnection) version = version_pretty(conn.info.server_version) @@ -143,7 +146,7 @@ def get_py_types(conn: Connection) -> list[str]: """ select typname, oid, typarray, -- CRDB might have quotes in the regtype representation - replace(typname::regtype::text, '''', '') as regtype, + replace(CAST(typname AS TEXT), '''', '') as regtype, typdelim from pg_type t where @@ -156,7 +159,7 @@ def get_py_types(conn: Connection) -> list[str]: ): typemod = typemods.get(typname) - # Weird legacy type in postgres catalog + # Weird legacy type in gaussdb catalog if typname == "char": typname = regtype = '"char"' @@ -180,14 +183,14 @@ def get_py_ranges(conn: Connection) -> list[str]: lines = [] for typname, oid, typarray, rngsubtype in conn.execute( """ -select typname, oid, typarray, rngsubtype +select t.typname, t.oid, t.typarray, r.rngsubtype from pg_type t - join pg_range r on t.oid = rngtypid + join pg_range r on t.oid = r.rngtypid where - oid < 10000 - and typtype = 'r' -order by typname + t.oid < 10000 + and t.typtype = 'r' +order by t.typname """ ): params = [f"{typname!r}, {oid}, {typarray}, subtype_oid={rngsubtype}"] @@ -196,48 +199,6 @@ def get_py_ranges(conn: Connection) -> list[str]: return lines -def get_py_multiranges(conn: Connection) -> list[str]: - lines = [] - for typname, oid, typarray, rngtypid, rngsubtype in conn.execute( - """ -select typname, oid, typarray, rngtypid, rngsubtype -from - pg_type t - join pg_range r on t.oid = rngmultitypid -where - oid < 10000 - and typtype = 'm' -order by typname -""" - ): - params = [ - f"{typname!r}, {oid}, {typarray}," - f" range_oid={rngtypid}, subtype_oid={rngsubtype}" - ] - lines.append(f"MultirangeInfo({','.join(params)}),") - - return lines - - -def get_cython_oids(conn: Connection) -> list[str]: - lines = [] - for typname, oid in conn.execute( - """ -select typname, oid -from pg_type -where - oid < 10000 - and (typtype = any('{b,r,m}') or typname = 'record') - and (typname !~ '^(_|pg_)' or typname = 'pg_lsn') -order by typname -""" - ): - const_name = typname.upper() + "_OID" - lines.append(f" {const_name} = {oid}") - - return lines - - def update_file(fn: Path, new: list[str]) -> None: with fn.open("r") as f: lines = f.read().splitlines()